From 0c7e42b052f1b2f3918bfe709d2e79c4dc0b55b0 Mon Sep 17 00:00:00 2001 From: Mike Ammerlaan Date: Mon, 9 Sep 2024 14:13:09 -0700 Subject: [PATCH] fix(general): Refactor autogeneration code, change package attributes (#35) * fix(general): Refactor autogeneration code, change package attributes - Fix some samples issues - Add report an issue link - Fix issues with array processing of items (work on a copy) - Project generation will update .env files and others * Remove unused elements * fix(ci): Updates to workflow for publishing * Update license and publisher notes --- .github/workflows/create-release.yml | 6 +- app/jsnode/package.json | 19 +- .../data/forms/entity_type_resource.form.json | 34 + app/public/data/forms/loot_table.form.json | 106 + .../data/forms/spawn_rules_header.form.json | 15 + app/public/data/gallery.json | 29 +- app/src/UX/AddGitHubReference.css | 19 - app/src/UX/AddGitHubReference.tsx | 156 - app/src/UX/App.tsx | 277 +- app/src/UX/CartoSettings.css | 8 +- app/src/UX/CartoSettings.tsx | 10 +- app/src/UX/CartoSettingsPanel.css | 20 +- app/src/UX/CartoSettingsPanel.tsx | 42 +- app/src/UX/ComponentSetEditor.tsx | 8 - app/src/UX/DedicatedServerSettingsPanel.tsx | 9 +- app/src/UX/EntityTypeEditor.css | 4 + app/src/UX/EntityTypeEditor.tsx | 180 +- app/src/UX/EntityTypeResourceEditor.css | 24 + app/src/UX/EntityTypeResourceEditor.tsx | 217 + app/src/UX/FileExplorer.css | 24 +- app/src/UX/FileExplorer.tsx | 59 +- app/src/UX/Home.css | 2 +- app/src/UX/Home.tsx | 93 +- app/src/UX/IntegrateItem.css | 6 +- app/src/UX/IntegrateItem.tsx | 29 +- app/src/UX/ItemGallery.tsx | 33 - app/src/UX/ItemTileButton.css | 3 +- app/src/UX/LootTableEditor.css | 24 + app/src/UX/LootTableEditor.tsx | 197 + app/src/UX/NewBlockType.css | 1 + app/src/UX/NewEntityType.css | 1 + ...ageJsonEditor.css => NpmPackageEditor.css} | 0 ...ageJsonEditor.tsx => NpmPackageEditor.tsx} | 34 +- app/src/UX/ProjectEditor.tsx | 260 +- app/src/UX/ProjectEditorUtilities.ts | 42 +- app/src/UX/ProjectGallery.tsx | 2 +- app/src/UX/ProjectItemEditor.tsx | 66 +- app/src/UX/ProjectItemList.tsx | 141 +- app/src/UX/ProjectPropertyEditor.css | 37 +- app/src/UX/ProjectPropertyEditor.tsx | 33 +- app/src/UX/SpawnRulesEditor.css | 24 + app/src/UX/SpawnRulesEditor.tsx | 203 + app/src/UX/StatusArea.css | 2 +- app/src/UX/WebUtilities.ts | 4 +- app/src/app/Carto.ts | 30 +- app/src/app/ICartoData.ts | 2 +- app/src/app/IProjectData.ts | 3 + app/src/app/IProjectItemData.ts | 6 +- app/src/app/IProjectItemRelationship.ts | 6 + app/src/app/Project.ts | 101 +- app/src/app/ProjectAutogeneration.ts | 409 ++ app/src/app/ProjectExporter.ts | 100 +- app/src/app/ProjectItem.ts | 362 +- app/src/app/ProjectItemManager.ts | 11 +- app/src/app/ProjectItemRelations.ts | 29 + app/src/app/ProjectItemUtilities.ts | 28 +- app/src/app/ProjectStandard.ts | 74 + app/src/app/ProjectUtilities.ts | 75 +- app/src/dataform/DataForm.css | 9 +- app/src/dataform/DataForm.tsx | 18 +- app/src/dataform/IField.ts | 1 + app/src/dataform/StringArray.css | 4 +- app/src/devproject/EnvFile.ts | 139 - app/src/devproject/EnvSettings.ts | 170 + app/src/devproject/EslintConfig.ts | 138 + app/src/devproject/IVsCodeExtensions.ts | 6 + app/src/devproject/JustConfig.ts | 174 + app/src/devproject/NpmPackageDefinition.ts | 263 + app/src/devproject/NpmPackageJson.ts | 122 - app/src/devproject/PrettierRcConfig.ts | 157 + .../devproject/VsCodeExtensionsDefinition.ts | 160 + ...aunchJson.ts => VsCodeLaunchDefinition.ts} | 28 +- .../devproject/VsCodeSettingsDefinition.ts | 180 + ...eTasksJson.ts => VsCodeTasksDefinition.ts} | 20 +- app/src/info/AddOnRequirementsGenerator.ts | 4 +- .../info/AnimationResourceInfoGenerator.ts | 4 +- app/src/info/ItemCountsInfoGenerator.ts | 8 +- app/src/info/LineSizeInfoGenerator.ts | 6 +- app/src/info/PackInfoGenerator.ts | 6 +- app/src/info/ProjectInfoSet.ts | 6 +- app/src/info/StrictPlatformInfoGenerator.ts | 6 +- app/src/info/TextureImageInfoGenerator.ts | 4 +- app/src/info/TextureInfoGenerator.ts | 14 +- app/src/manager/BaseGameVersionManager.ts | 12 +- .../manager/BehaviorPackEntityTypeManager.ts | 12 +- .../manager/BehaviorPackItemTypeManager.ts | 12 +- app/src/manager/FormatVersionManager.ts | 16 +- app/src/manager/MinEngineVersionManager.ts | 12 +- app/src/manager/ScriptModuleManager.ts | 17 +- app/src/manager/VsCodeFileManager.ts | 36 +- .../minecraft/BehaviorManifestDefinition.ts | 103 +- app/src/minecraft/Database.ts | 15 +- app/src/minecraft/EntityTypeDefinition.ts | 107 + .../minecraft/EntityTypeResourceDefinition.ts | 26 +- ...ntEntityType.ts => IEntityTypeResource.ts} | 14 +- app/src/minecraft/ILootTableBehavior.ts | 6 + app/src/minecraft/ISpawnRulesBehavior.ts | 10 + app/src/minecraft/LocManager.ts | 4 +- .../minecraft/LootTableBehaviorDefinition.ts | 91 + app/src/minecraft/ManagedComponentGroup.ts | 5 +- app/src/minecraft/MinecraftUtilities.ts | 7 +- .../minecraft/SpawnRulesBehaviorDefinition.ts | 33 +- app/src/storage/BrowserStorage.ts | 22 +- app/src/storage/StorageUtilities.ts | 1 + app/src/test/CommandLineTest.ts | 13 +- .../scenarios/createCommandAddonStarter/.env | 4 +- .../eslint.config.mjs | 3 +- .../createCommandAddonStarter/just.config.ts | 21 +- .../package-lock.json | 4633 ----------------- .../DownloadResources.js | 49 +- package.json | 14 +- .../behavior_packs/deployJs/manifest.json | 2 +- 112 files changed, 4407 insertions(+), 6279 deletions(-) create mode 100644 app/public/data/forms/entity_type_resource.form.json create mode 100644 app/public/data/forms/loot_table.form.json create mode 100644 app/public/data/forms/spawn_rules_header.form.json delete mode 100644 app/src/UX/AddGitHubReference.css delete mode 100644 app/src/UX/AddGitHubReference.tsx create mode 100644 app/src/UX/EntityTypeResourceEditor.css create mode 100644 app/src/UX/EntityTypeResourceEditor.tsx create mode 100644 app/src/UX/LootTableEditor.css create mode 100644 app/src/UX/LootTableEditor.tsx rename app/src/UX/{NpmPackageJsonEditor.css => NpmPackageEditor.css} (100%) rename app/src/UX/{NpmPackageJsonEditor.tsx => NpmPackageEditor.tsx} (83%) create mode 100644 app/src/UX/SpawnRulesEditor.css create mode 100644 app/src/UX/SpawnRulesEditor.tsx create mode 100644 app/src/app/IProjectItemRelationship.ts create mode 100644 app/src/app/ProjectAutogeneration.ts create mode 100644 app/src/app/ProjectItemRelations.ts create mode 100644 app/src/app/ProjectStandard.ts delete mode 100644 app/src/devproject/EnvFile.ts create mode 100644 app/src/devproject/EnvSettings.ts create mode 100644 app/src/devproject/EslintConfig.ts create mode 100644 app/src/devproject/IVsCodeExtensions.ts create mode 100644 app/src/devproject/JustConfig.ts create mode 100644 app/src/devproject/NpmPackageDefinition.ts delete mode 100644 app/src/devproject/NpmPackageJson.ts create mode 100644 app/src/devproject/PrettierRcConfig.ts create mode 100644 app/src/devproject/VsCodeExtensionsDefinition.ts rename app/src/devproject/{VsCodeLaunchJson.ts => VsCodeLaunchDefinition.ts} (87%) create mode 100644 app/src/devproject/VsCodeSettingsDefinition.ts rename app/src/devproject/{VsCodeTasksJson.ts => VsCodeTasksDefinition.ts} (88%) rename app/src/minecraft/{IClientEntityType.ts => IEntityTypeResource.ts} (61%) create mode 100644 app/src/minecraft/ILootTableBehavior.ts create mode 100644 app/src/minecraft/LootTableBehaviorDefinition.ts delete mode 100644 app/test/scenarios/createCommandAddonStarter/package-lock.json diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index 8aa9eabb..89b95680 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -3,6 +3,9 @@ name: Create Release on: workflow_dispatch: +permissions: + contents: read + jobs: build-and-publish: runs-on: windows-latest @@ -16,7 +19,7 @@ jobs: pull-requests: write security-events: none checks: none - id-token: none + id-token: write issues: write repository-projects: none statuses: none @@ -59,6 +62,7 @@ jobs: run: npx semantic-release env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + NPM_TOKEN: ${{ secrets.NPM_TOKEN }} - name: Deploy to GitHub Pages if: success() diff --git a/app/jsnode/package.json b/app/jsnode/package.json index efafd089..3cc3c484 100644 --- a/app/jsnode/package.json +++ b/app/jsnode/package.json @@ -1,9 +1,24 @@ { "name": "@minecraft/creator-tools", - "version": "0.2.9", + "version": "0.0.0-semantically-released", "productName": "Minecraft Creator Tools", "description": "Minecraft Creator Tools command line and libraries.", - "private": true, + "publisher": "mojang-studios", + "author": { + "name": "Mojang Studios" + }, + "keywords": [ + "minecraft", + "tools", + "bedrock", + "add-on", + "creator" + ], + "bugs": { + "url": "https://aka.ms/mctbugs" + }, + "license": "MIT", + "homepage": "https://aka.ms/mcthomepage", "bin": { "mct": "./cli/index.js" }, diff --git a/app/public/data/forms/entity_type_resource.form.json b/app/public/data/forms/entity_type_resource.form.json new file mode 100644 index 00000000..8552ec41 --- /dev/null +++ b/app/public/data/forms/entity_type_resource.form.json @@ -0,0 +1,34 @@ +{ + "fields": [ + { + "id": "identifier", + "title": "Id", + "dataType": 2 + }, + { + "id": "materials", + "title": "Materials", + "dataType": 24 + }, + { + "id": "textures", + "title": "Textures", + "dataType": 24 + }, + { + "id": "geometry", + "title": "Geometry", + "dataType": 24 + }, + { + "id": "animations", + "title": "Animations", + "dataType": 24 + }, + { + "id": "render_controllers", + "title": "Render Controllers", + "dataType": 17 + } + ] +} diff --git a/app/public/data/forms/loot_table.form.json b/app/public/data/forms/loot_table.form.json new file mode 100644 index 00000000..91076add --- /dev/null +++ b/app/public/data/forms/loot_table.form.json @@ -0,0 +1,106 @@ +{ + "fields": [ + { + "id": "pools", + "description": "A set of loot table outcomes.", + "dataType": 15, + "defaultValue": false, + "newItemPrototype": { + "pool": 1, + "entries": [] + }, + "noun": "Pool", + "subForm": { + "fields": [ + { + "id": "rolls", + "description": "How many times the pool will be rolled to select an entry.", + "dataType": 0 + }, + { + "id": "conditions", + "dataType": 15, + "defaultValue": false, + "newItemPrototype": { + "condition": "random_difficulty_change", + "default_chance": 0.5, + "peaceful": 0, + "hard": 6 + }, + "noun": "Condition", + "subForm": { + "fields": [ + { + "id": "default_chance", + "description": "Default percent chance.", + "dataType": 3 + }, + { + "id": "peaceful", + "description": "Percent chance under peaceful mode.", + "dataType": 3 + }, + { + "id": "hard", + "description": "Percent chance under hard mode.", + "dataType": 3 + }, + { + "id": "condition", + "description": "How this condition is evaluated.", + "dataType": 5, + "choices": [ + { + "id": "random_difficulty_chance", + "title": "Random Difficulty Chance" + }, + { + "id": "default_chance", + "title": "Default Chance" + } + ] + } + ] + }, + "description": "Conditions for this item to be considered." + }, + { + "id": "entries", + "dataType": 15, + "defaultValue": false, + "newItemPrototype": { + "id": "newfield", + "dataType": 2 + }, + "description": "The sub-items within this form.", + "noun": "Choice", + "subForm": { + "fields": [ + { + "id": "name", + "description": "Item in the loot table.", + "dataType": 2 + }, + { + "id": "type", + "description": "Type of choice.", + "dataType": 5, + "choices": [ + { + "id": "item", + "title": "Item" + }, + { + "id": "loot_table", + "title": "Loot Table" + } + ] + } + ] + } + } + ] + } + } + ] +} diff --git a/app/public/data/forms/spawn_rules_header.form.json b/app/public/data/forms/spawn_rules_header.form.json new file mode 100644 index 00000000..999357f2 --- /dev/null +++ b/app/public/data/forms/spawn_rules_header.form.json @@ -0,0 +1,15 @@ +{ + "fields": [ + { + "id": "identifier", + "title": "Id", + "dataType": 2 + }, + { + "id": "population_control", + "title": "Population group", + "description": "Specifies a group that this mob is connected with, of which only so many mobs in the group can be spawned", + "dataType": 2 + } + ] +} diff --git a/app/public/data/gallery.json b/app/public/data/gallery.json index c709c11d..c821eeea 100644 --- a/app/public/data/gallery.json +++ b/app/public/data/gallery.json @@ -82,14 +82,6 @@ "id": "customComponents", "type": 0 }, - { - "title": "Beautiful natural shapes for your building adventures", - "description": "Trees, trees, and more trees!", - "gitHubOwner": "scriptVillager", - "gitHubRepoName": "NaturalStructures", - "id": "naturalStructures", - "type": 1 - }, { "title": "Solid Cube Block with Textures", "description": "The dice block is a simple solid cube.", @@ -511,7 +503,15 @@ "id": "allay", "type": 4, "logoLocation": { "x": 5, "y": 5, "width": 5, "height": 5, "imageWidth": 32 }, - "fileList": ["allay", "allay", "allay", "allay/allay", "allay", "allay"] + "fileList": [ + "allay", + "allay", + "allay", + "allay/allay", + "allay", + "allay", + "allay" + ] }, { "title": "Axolotl", @@ -551,6 +551,8 @@ "cat", "cat", "cat", + "cat", + "cat", "cat", "cat/allblackcat", "cat/allblackcat_tame.tga", @@ -597,6 +599,7 @@ "cow", "cow", "cow", + "cow", "cow", "cow/cow", "cow/brown_mooshroom", @@ -617,6 +620,7 @@ "creeper", "creeper", "creeper", + "creeper", "creeper", "creeper", "creeper", @@ -639,6 +643,7 @@ "enderman", "enderman", "enderman", + "enderman", "enderman/enderman.tga", "enderman", "enderman" @@ -660,6 +665,7 @@ "rabbit", "rabbit", "rabbit", + "rabbit", "rabbit", "rabbit/blackrabbit", "rabbit/brown", @@ -684,6 +690,7 @@ "pig", "pig", "pig", + "pig", "pig", "pig", "pig/pig", @@ -707,6 +714,7 @@ "sheep", "sheep", "sheep/sheep.tga", + "sheep", "sheep", "sheep" ] @@ -726,6 +734,7 @@ "skeleton", "skeleton", "skeleton", + "skeleton", "skeleton", "skeleton", "skeleton/skeleton", @@ -749,6 +758,7 @@ "wolf", "wolf", "wolf", + "wolf", "wolf", "wolf", "wolf/wolf", @@ -801,6 +811,7 @@ "zombie", "zombie", "zombie", + "zombie", "zombie", "zombie", "zombie", diff --git a/app/src/UX/AddGitHubReference.css b/app/src/UX/AddGitHubReference.css deleted file mode 100644 index a33d5d08..00000000 --- a/app/src/UX/AddGitHubReference.css +++ /dev/null @@ -1,19 +0,0 @@ -.aghr-outer { - padding: 8px; - padding-top: 2px; - width: 100%; - min-height: 450px; -} - -.aghr-gallery { - overflow-y: auto; - max-height: 280px; - min-height: 280px; - background-color: #202020; -} - -.aghr-selectedProject -{ - padding-top: 20px; - padding-left: 30px; -} \ No newline at end of file diff --git a/app/src/UX/AddGitHubReference.tsx b/app/src/UX/AddGitHubReference.tsx deleted file mode 100644 index 2c6a5b5a..00000000 --- a/app/src/UX/AddGitHubReference.tsx +++ /dev/null @@ -1,156 +0,0 @@ -import { Component, SyntheticEvent } from "react"; -import IAppProps from "./IAppProps"; -import Project from "../app/Project"; -import "./AddGitHubReference.css"; -import GitHubManager from "../github/GitHubManager"; -import { InputProps, Input, Accordion, ThemeInput } from "@fluentui/react-northstar"; -import { GitHubPropertyType } from "./ProjectPropertyEditor"; -import IGalleryItem, { GalleryItemType } from "../app/IGalleryItem"; -import ProjectTile, { ProjectTileDisplayMode } from "./ProjectTile"; -import { GalleryProjectCommand } from "./ProjectGallery"; -import IGallery from "../app/IGallery"; - -interface IAddGitHubReferenceProps extends IAppProps { - project: Project; - theme: ThemeInput; - onGitHubProjectUpdated: (propertyType: GitHubPropertyType, value?: string) => void; -} - -interface IAddGitHubReferenceState { - gitHub: GitHubManager | undefined; - selectedProject?: IGalleryItem; - gallery: IGallery | undefined; -} - -export default class AddGitHubReference extends Component { - constructor(props: IAddGitHubReferenceProps) { - super(props); - - this._handleGalleryItemCommand = this._handleGalleryItemCommand.bind(this); - this._handleOwnerUpdate = this._handleOwnerUpdate.bind(this); - this._handleProjectUpdate = this._handleProjectUpdate.bind(this); - this._onGalleryLoaded = this._onGalleryLoaded.bind(this); - - this.state = { - gitHub: this.props.carto.anonGitHub, - gallery: this.props.carto.gallery, - }; - - if (!this.props.carto.gallery) { - this.props.carto.onGalleryLoaded.subscribe(this._onGalleryLoaded); - this.props.carto.loadGallery(); - } - } - - private _onGalleryLoaded() { - this.setState({ - gitHub: this.props.carto.anonGitHub, - gallery: this.props.carto.gallery, - }); - } - - _handleGalleryItemCommand(command: GalleryProjectCommand, project: IGalleryItem) { - if (this.props && this.props.onGitHubProjectUpdated !== undefined) { - this.props.onGitHubProjectUpdated(GitHubPropertyType.owner, project.gitHubOwner); - this.props.onGitHubProjectUpdated(GitHubPropertyType.mode, "existing"); - this.props.onGitHubProjectUpdated(GitHubPropertyType.repoName, project.gitHubRepoName); - this.props.onGitHubProjectUpdated(GitHubPropertyType.branch, project.gitHubBranch); - this.props.onGitHubProjectUpdated(GitHubPropertyType.folder, project.gitHubFolder); - this.props.onGitHubProjectUpdated(GitHubPropertyType.title, project.title); - - this.setState({ - gitHub: this.state.gitHub, - selectedProject: project, - }); - } - } - - _handleOwnerUpdate(e: SyntheticEvent, data: (InputProps & { value: string }) | undefined) { - if (data === undefined || this.props.project === null || this.state == null) { - return; - } - - if (this.props && this.props.onGitHubProjectUpdated !== undefined) { - this.props.onGitHubProjectUpdated(GitHubPropertyType.mode, "new"); - this.props.onGitHubProjectUpdated(GitHubPropertyType.repoName, data.value); - } - } - - _handleProjectUpdate(e: SyntheticEvent, data: (InputProps & { value: string }) | undefined) { - if (data === undefined || this.props.project === null || this.state == null) { - return; - } - - if (this.props && this.props.onGitHubProjectUpdated !== undefined) { - this.props.onGitHubProjectUpdated(GitHubPropertyType.mode, "new"); - - this.props.onGitHubProjectUpdated(GitHubPropertyType.newDescription, data.value); - } - } - - render() { - if (this.state === null || this.state.gitHub === undefined) { - return
Loading...
; - } - - const galleries = []; - - const gal = this.props.carto.gallery; - - if (gal === undefined) { - return
Loading gallery...
; - } - - for (let i = 0; i < gal.items.length; i++) { - const galItem = gal.items[i]; - - if (galItem.type === GalleryItemType.chunk) { - galleries.push( - - ); - } - } - - return ( -
- - {galleries} -
- ), - }, - { - title: "Custom repository", - content: ( -
-
GitHub Owner:
-
- -
-
GitHub Project Name:
-
- -
-
- ), - }, - ]} - /> - - ); - } -} diff --git a/app/src/UX/App.tsx b/app/src/UX/App.tsx index afc4737f..4d57d0ea 100644 --- a/app/src/UX/App.tsx +++ b/app/src/UX/App.tsx @@ -9,16 +9,19 @@ import IFolder from "../storage/IFolder"; import { GalleryProjectCommand } from "./ProjectGallery"; import Log from "../core/Log"; import { ProjectFocus, ProjectScriptLanguage } from "../app/IProjectData"; -import CartoApp, { HostType } from "../app/CartoApp"; +import CartoApp from "../app/CartoApp"; import StorageUtilities from "../storage/StorageUtilities"; import { ThemeInput } from "@fluentui/react-northstar"; import { CartoEditorViewMode } from "../app/ICartoData"; +import MCWorld from "../minecraft/MCWorld"; import ProjectItem from "../app/ProjectItem"; +import ZipStorage from "../storage/ZipStorage"; import ProjectUtilities from "../app/ProjectUtilities"; +import { LocalFolderType, LocalGalleryCommand } from "./LocalGalleryCommand"; import WebUtilities from "./WebUtilities"; import ProjectEditorUtilities, { ProjectEditorMode } from "./ProjectEditorUtilities"; import HttpStorage from "../storage/HttpStorage"; -import Utilities from "../core/Utilities"; +import { ProjectImportExclusions } from "../app/ProjectExporter"; export enum NewProjectTemplateType { empty, @@ -31,16 +34,6 @@ export enum AppMode { project = 3, codeToolbox = 4, projectReadOnly = 5, - exporterTool = 6, - remoteServerManager = 7, - companion = 8, - codeStartPage = 9, - companionPlusBack = 10, - companionMinusTitlebar = 11, - codeStartPageForceNewProject = 12, - codeLandingForceNewProject = 13, - codeMinecraftView = 14, - search = 15, } interface AppProps { @@ -135,13 +128,7 @@ export default class App extends Component { let selectedItem = undefined; - if ( - (CartoApp.hostType === HostType.vsCodeWebWeb || CartoApp.hostType === HostType.vsCodeMainWeb) && - CartoApp.projectPath && - (initialAppMode === AppMode.codeToolbox || initialAppMode === AppMode.codeStartPage) - ) { - this._loadLocalStorageProject(); - } else if (CartoApp.modeParameter && CartoApp.modeParameter.startsWith("project/")) { + if (CartoApp.modeParameter && CartoApp.modeParameter.startsWith("project/")) { const segments = CartoApp.modeParameter.split("/"); if (segments.length === 2) { @@ -385,11 +372,9 @@ export default class App extends Component { if (firstSlash > 1) { const openToken = openQuery.substring(0, firstSlash).toLowerCase(); - let openData = openQuery.substring(firstSlash + 1, openQuery.length); + const openData = openQuery.substring(firstSlash + 1, openQuery.length); if (openToken === "gp") { - openData = Utilities.ensureNotEndsWithSlash(openData); - this._ensureProjectFromGalleryId(openData, updateContent); } } @@ -434,31 +419,6 @@ export default class App extends Component { selectedItem: segments[0], }; } - } else if (commandToken === "codestartpage") { - return { - mode: AppMode.codeStartPage, - activeProject: null, - }; - } else if (commandToken === "codestartpageforcenewproject") { - return { - mode: AppMode.codeStartPageForceNewProject, - activeProject: null, - }; - } else if (commandToken === "codelandingforcenewproject") { - return { - mode: AppMode.codeLandingForceNewProject, - activeProject: null, - }; - } else if (commandToken === "companion") { - return { - mode: AppMode.companion, - activeProject: null, - }; - } else if (commandToken === "companionht") { - return { - mode: AppMode.companionMinusTitlebar, - activeProject: null, - }; } } else { const commandToken = hash.substring(1).toLowerCase(); @@ -662,7 +622,7 @@ export default class App extends Component { } private async _ensureProjectFromGalleryId(galleryId: string, updateContent?: string) { - if (!this.state || this.state.carto === undefined) { + if (this.state.carto === undefined) { return; } @@ -676,24 +636,22 @@ export default class App extends Component { this._ensureProjectFromGallery(gp, updateContent); } - private async _ensureProjectFromGallery(galleryItem: IGalleryItem, updateContent?: string) { + private async _ensureProjectFromGallery(project: IGalleryItem, updateContent?: string) { if (this.state === null || this.state.carto === undefined) { return; } this._ensureProjectFromGitHubTemplate( - galleryItem.title, - galleryItem.gitHubOwner, - galleryItem.gitHubRepoName, + project.title, + project.gitHubOwner, + project.gitHubRepoName, false, - galleryItem.gitHubBranch, - galleryItem.gitHubFolder, - galleryItem.fileList, - galleryItem.id, - galleryItem.type !== GalleryItemType.project ? galleryItem.id : undefined, - updateContent, - undefined, - galleryItem.type + project.gitHubBranch, + project.gitHubFolder, + project.fileList, + project.id, + project.type === GalleryItemType.codeSample ? project.id : undefined, + updateContent ); } @@ -708,13 +666,11 @@ export default class App extends Component { projectId?: string, sampleId?: string, updateContent?: string, - description?: string, - galleryItemType?: GalleryItemType + description?: string ) { const carto = CartoApp.carto; - // don't load if we're already actively loading something. - if (this.state === null || carto === undefined || this._loadingMessage || this.state.loadingMessage) { + if (this.state === null || carto === undefined) { return; } @@ -745,16 +701,17 @@ export default class App extends Component { for (let i = 0; i < projects.length; i++) { const proj = projects[i]; - await proj.loadFromFile(); + await proj.ensureLoadedFromFile(); if ( proj.originalGitHubOwner === gitHubOwner && proj.originalGitHubRepoName === gitHubRepoName && proj.originalGitHubBranch === gitHubBranch && proj.originalGitHubFolder === gitHubFolder && - proj.originalSampleId === sampleId && updateContent === undefined ) { + await proj.ensureInflated(); + this._updateWindowTitle(newMode, proj); this.initProject(proj); @@ -782,11 +739,7 @@ export default class App extends Component { projectId, sampleId, updateContent, - undefined, - undefined, - undefined, - description, - galleryItemType + description ); } @@ -922,7 +875,7 @@ export default class App extends Component { false, false, false, - ["build", "node_modules", "/dist", "/.git", "/lib", "/out", "/node_modules"], + ProjectImportExclusions, undefined, this._gitHubAddingMessageUpdater ); @@ -974,6 +927,36 @@ export default class App extends Component { } } + if (updateContent !== undefined && newProject.projectFolder !== null) { + try { + const zs = new ZipStorage(); + + await zs.loadFromBase64(updateContent); + + if (zs.errorStatus) { + this.setHomeWithError( + "Error processing compressed content from URL." + (zs.errorMessage ? "Details: " + zs.errorMessage : "") + ); + return; + } + + await StorageUtilities.syncFolderTo( + zs.rootFolder, + newProject.projectFolder, + false, + false, + false, + ["package.json", "package.lock.json", "gulpfile.js", "just.config.ts"], + ["*.ts", "*.js", "*.json"] + ); + } catch (e) { + this.setHomeWithError( + "Could not process updated content from URL. Check to make sure your shared URL is valid. (" + e + ")" + ); + return; + } + } + description = description ? description : title; await ProjectUtilities.processNewProject(newProject, suggestedName, description, suggestedShortName); @@ -1020,6 +1003,125 @@ export default class App extends Component { }); } + private async _newProjectFromMinecraftFolder(folderType: LocalFolderType, folder: IFolder) { + if (this.state === null || this.state.carto === undefined) { + return; + } + + let proposedProjectName = StorageUtilities.getBaseFromName(folder.fullPath); + const mcw = await MCWorld.ensureMCWorldOnFolder(folder); + + if (mcw && mcw.name) { + proposedProjectName = mcw.name; + } + + const newProject = await this.state.carto.ensureProjectForFolder(folder.fullPath, proposedProjectName); + + newProject.save(); + this.state.carto.save(); + + this._updateWindowTitle(AppMode.project, newProject); + this.initProject(newProject); + + this.setState({ + mode: AppMode.project, + isPersisted: this.state.isPersisted, + hasBanner: this.state.hasBanner, + visualSeed: this.state.visualSeed, + activeProject: newProject, + }); + } + + private async _ensureProjectFromMinecraftFolder(folderType: LocalFolderType, folder: IFolder, isReadOnly: boolean) { + const carto = CartoApp.carto; + + if (this.state === null || carto === undefined) { + return; + } + + this._loadingMessage = "opening folder " + folder.fullPath + "..."; + + let newMode = AppMode.project; + + if (isReadOnly) { + newMode = AppMode.projectReadOnly; + } + + this._updateWindowTitle(AppMode.loading, null); + + this.setState({ + mode: AppMode.loading, + activeProject: null, + isPersisted: this.state.isPersisted, + hasBanner: this.state.hasBanner, + visualSeed: this.state.visualSeed, + loadingMessage: this._loadingMessage, + }); + + await carto.load(); + + const projects = carto.projects; + const canonPath = StorageUtilities.canonicalizePath(folder.fullPath); + + for (let i = 0; i < projects.length; i++) { + const proj = projects[i]; + + await proj.ensureLoadedFromFile(); + + if (proj.originalFullPath === canonPath) { + await proj.ensureInflated(); + + this._updateWindowTitle(newMode, proj); + this.initProject(proj); + + this.setState({ + mode: newMode, + isPersisted: this.state.isPersisted, + hasBanner: this.state.hasBanner, + visualSeed: this.state.visualSeed, + activeProject: proj, + }); + + return; + } + } + + const folderName = StorageUtilities.getLeafName(canonPath); + + const operId = await carto.notifyOperationStarted("Creating new project from '" + canonPath + "'"); + + if (folderName !== undefined) { + let projName = "my-" + folderName; + + const newProjectName = await carto.getNewProjectName(projName); + + let newFocus = ProjectFocus.focusedCodeSnippet; + + if (folderType === LocalFolderType.world) { + newFocus = ProjectFocus.world; + } + + projName = projName.replace(/_/gi, ""); + projName = projName.replace(/\//gi, ""); + projName = projName.replace(/\\/gi, ""); + projName = projName.replace(/ /gi, ""); + + const newProject = await carto.createNewProject(newProjectName, folder.fullPath, newFocus, false); + + await newProject.ensureProjectFolder(); + + await newProject.inferProjectItemsFromFiles(); + + newProject.save(); + + carto.save(); + + this._setProject(newProject); + } + + await carto.notifyOperationEnded(operId, "New project '" + folderName + "' created. Have fun!"); + } + private initProject(newProject: Project) { newProject.onItemChanged.subscribe(this._handleItemChanged); newProject.onSaved.subscribe(this._handleSaved); @@ -1029,10 +1131,6 @@ export default class App extends Component { let title = "Minecraft Creator Tools"; switch (newMode) { - case AppMode.exporterTool: - title = "Export - " + title; - break; - case AppMode.project: case AppMode.projectReadOnly: if (activeProject !== null) { @@ -1133,8 +1231,17 @@ export default class App extends Component { } } + private _handleLocalGalleryCommand(command: LocalGalleryCommand, folderType: LocalFolderType, folder: IFolder) { + switch (command) { + case LocalGalleryCommand.ensureAndOpenProjectFromFolder: + this._newProjectFromMinecraftFolder(folderType, folder); + break; + } + } + private async _handleProjectSelected(project: Project) { - await project.loadFromFile(); + await project.ensureLoadedFromFile(); + await project.ensureInflated(); this._updateWindowTitle(AppMode.project, project); @@ -1217,14 +1324,13 @@ export default class App extends Component { { key="app-pe" heightOffset={heightOffset} statusAreaMode={ProjectStatusAreaMode.hidden} + isPersisted={this.state.isPersisted} + onPersistenceUpgraded={this._handlePersistenceUpgraded} project={this.state.activeProject} selectedItem={this.state.selectedItem} viewMode={CartoEditorViewMode.mainFocus} @@ -1258,6 +1366,8 @@ export default class App extends Component { hideMainToolbar={true} key="app-pea" heightOffset={heightOffset} + isPersisted={this.state.isPersisted} + onPersistenceUpgraded={this._handlePersistenceUpgraded} statusAreaMode={ProjectStatusAreaMode.hidden} project={this.state.activeProject} mode={ProjectEditorMode.inspector} @@ -1292,10 +1402,7 @@ export default class App extends Component { onProjectSelected={this._handleProjectSelected} /> ); - } else if ( - this.state.activeProject.originalSampleId && - this.state.activeProject.getItemByProjectPath("/scripts/ScriptBox.ts") - ) { + } else if (this.state.activeProject.originalSampleId) { // show main view (no sidebar) if it's a code sample. interior = ( { heightOffset={heightOffset} viewMode={CartoEditorViewMode.mainFocus} project={this.state.activeProject} + isPersisted={this.state.isPersisted} + onPersistenceUpgraded={this._handlePersistenceUpgraded} mode={this.state.initialProjectEditorMode ? this.state.initialProjectEditorMode : undefined} selectedItem={this.state.selectedItem} readOnly={isReadOnly} @@ -1319,6 +1428,8 @@ export default class App extends Component { key="app-pef" heightOffset={heightOffset} project={this.state.activeProject} + isPersisted={this.state.isPersisted} + onPersistenceUpgraded={this._handlePersistenceUpgraded} mode={this.state.initialProjectEditorMode ? this.state.initialProjectEditorMode : undefined} selectedItem={this.state.selectedItem} readOnly={isReadOnly} diff --git a/app/src/UX/CartoSettings.css b/app/src/UX/CartoSettings.css index a7f0cb60..4708b4cb 100644 --- a/app/src/UX/CartoSettings.css +++ b/app/src/UX/CartoSettings.css @@ -6,10 +6,10 @@ } .cs-header { - font-size: 20pt; - padding-top: 8px; - padding-left: 30px; - padding-bottom: 12px; + font-size: 16pt; + padding-top: 15px; + padding-left: 18px; + padding-bottom: 16px; margin: 0px; } diff --git a/app/src/UX/CartoSettings.tsx b/app/src/UX/CartoSettings.tsx index c55fbd50..dc2f44fc 100644 --- a/app/src/UX/CartoSettings.tsx +++ b/app/src/UX/CartoSettings.tsx @@ -48,18 +48,18 @@ export default class CartoSettings extends Component

- App Settings + Creator Tools Settings

; @@ -18,6 +28,8 @@ interface ICartoSettingsPanelState { formatBeforeSave: boolean; } +export const CartoTargetStrings = ["Latest Minecraft release", "Latest Minecraft preview"]; + export default class CartoSettingsPanel extends Component { private _activeEditorPersistable?: IPersistable; @@ -30,6 +42,7 @@ export default class CartoSettingsPanel extends Component | React.KeyboardEvent | null, + data: DropdownProps + ) { + if (data.value === CartoTargetStrings[1]) { + this.props.carto.track = MinecraftTrack.preview; + } else { + this.props.carto.track = MinecraftTrack.main; + } + + await this.props.carto.save(); + } + _handleAutoStartChanged(e: SyntheticEvent, data: (CheckboxProps & { checked: boolean }) | undefined) { if (data === undefined || this.props.carto === null || this.state == null) { return; @@ -124,6 +150,20 @@ export default class CartoSettingsPanel extends ComponentTarget Minecraft
); + coreProps.push( +
+ +
+ ); + coreProps.push(
Format JSON and script on open and save diff --git a/app/src/UX/ComponentSetEditor.tsx b/app/src/UX/ComponentSetEditor.tsx index a890e202..f71f05a2 100644 --- a/app/src/UX/ComponentSetEditor.tsx +++ b/app/src/UX/ComponentSetEditor.tsx @@ -234,14 +234,6 @@ export default class ComponentSetEditor extends Component; - /* - if (this.props.componentSetItem instanceof EntityType) { - title =
Component
; - } else if (this.props.componentSetItem instanceof ManagedComponentGroup) { - const mcgTitle = (this.props.componentSetItem as ManagedComponentGroup).id; - title =
{mcgTitle} Group
; - }*/ - const areaHeight = "calc(100vh - " + String(this.props.heightOffset + 34) + "px)"; return ( diff --git a/app/src/UX/DedicatedServerSettingsPanel.tsx b/app/src/UX/DedicatedServerSettingsPanel.tsx index f56d5fa5..680284b3 100644 --- a/app/src/UX/DedicatedServerSettingsPanel.tsx +++ b/app/src/UX/DedicatedServerSettingsPanel.tsx @@ -104,9 +104,9 @@ export default class DedicatedServerSettingsPanel extends Component< _handleUsePreview(e: SyntheticEvent, data: (CheckboxProps & { checked: boolean }) | undefined) { if (data) { if (data.checked) { - this.props.carto.processHostedMinecraftTrack = MinecraftTrack.preview; + this.props.carto.track = MinecraftTrack.preview; } else { - this.props.carto.processHostedMinecraftTrack = MinecraftTrack.main; + this.props.carto.track = MinecraftTrack.main; } this.props.carto.save(); @@ -286,10 +286,7 @@ export default class DedicatedServerSettingsPanel extends Component< serverProps.push(
- +
); diff --git a/app/src/UX/EntityTypeEditor.css b/app/src/UX/EntityTypeEditor.css index 0b50d5cc..0424ba49 100644 --- a/app/src/UX/EntityTypeEditor.css +++ b/app/src/UX/EntityTypeEditor.css @@ -28,6 +28,10 @@ grid-template-rows: 55px 1fr; } +.ete-componentEditorInteriorFull { + grid-row: 2; +} + .ete-select { padding: 8px; } diff --git a/app/src/UX/EntityTypeEditor.tsx b/app/src/UX/EntityTypeEditor.tsx index f1202704..66b30357 100644 --- a/app/src/UX/EntityTypeEditor.tsx +++ b/app/src/UX/EntityTypeEditor.tsx @@ -10,21 +10,31 @@ import { List, ListProps, Toolbar, selectableListBehavior } from "@fluentui/reac import ManagedComponentGroup from "../minecraft/ManagedComponentGroup"; import { CustomTabLabel } from "./Labels"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { faBolt, faSliders } from "@fortawesome/free-solid-svg-icons"; +import { faBolt, faBone, faCow, faEgg, faSliders } from "@fortawesome/free-solid-svg-icons"; import WebUtilities from "./WebUtilities"; import Log from "../core/Log"; import Utilities from "../core/Utilities"; import ManagedEvent from "../minecraft/ManagedEvent"; import EventActionDesign from "./EventActionDesign"; +import SpawnRulesEditor from "./SpawnRulesEditor"; +import ProjectItem from "../app/ProjectItem"; +import { ProjectItemType } from "../app/IProjectItemData"; +import LootTableEditor from "./LootTableEditor"; +import EntityTypeResourceEditor from "./EntityTypeResourceEditor"; export enum EntityTypeEditorMode { properties = 0, actions = 1, + visuals = 2, + audio = 3, + spawnRules = 4, + loot = 5, } interface IEntityTypeEditorProps extends IFileProps { heightOffset: number; readOnly: boolean; + item: ProjectItem; theme: ThemeInput; } @@ -46,6 +56,11 @@ export default class EntityTypeEditor extends Component} - text={"Properties"} + text={"Properties & Behavior"} isCompact={isButtonCompact} isSelected={this.state.mode === EntityTypeEditorMode.properties} theme={this.props.theme} /> ), - key: "typesMode", + key: "etePropertiesTab", onClick: this._setPropertiesMode, title: "Edit documentation by types", }); @@ -321,11 +351,56 @@ export default class EntityTypeEditor extends Component ), - key: "typesNeedingEditsMode", + key: "eteActionsTab", onClick: this._setActionsMode, title: "Edit documentation by types that need edits", }); + toolbarItems.push({ + icon: ( + } + text={"Visuals"} + isCompact={isButtonCompact} + isSelected={this.state.mode === EntityTypeEditorMode.visuals} + theme={this.props.theme} + /> + ), + key: "eteVisualsTab", + onClick: this._setVisualsMode, + title: "Edit documentation by types that need edits", + }); + + toolbarItems.push({ + icon: ( + } + text={"Spawn"} + isCompact={isButtonCompact} + isSelected={this.state.mode === EntityTypeEditorMode.spawnRules} + theme={this.props.theme} + /> + ), + key: "eteSpawnRulesTab", + onClick: this._setSpawnRulesMode, + title: "Spawn behavior", + }); + + toolbarItems.push({ + icon: ( + } + text={"Loot Table"} + isCompact={isButtonCompact} + isSelected={this.state.mode === EntityTypeEditorMode.loot} + theme={this.props.theme} + /> + ), + key: "eteLootTableTab", + onClick: this._setLootMode, + title: "Loot", + }); + const et = this.state.fileToEdit.manager as EntityTypeDefinition; if (et.data === undefined) { @@ -465,6 +540,89 @@ export default class EntityTypeEditor extends Component
); + } else if (this.state.mode === EntityTypeEditorMode.spawnRules) { + let spawnItem = undefined; + if (this.props.item && this.props.item.childItems) { + for (const childItem of this.props.item.childItems) { + if (childItem.childItem.itemType === ProjectItemType.spawnRuleBehavior) { + spawnItem = childItem.childItem; + } + } + } + + if (spawnItem && spawnItem.file) { + modeArea = ( +
+ +
+ ); + } + } else if (this.state.mode === EntityTypeEditorMode.visuals) { + let resourceItem = undefined; + if (this.props.item && this.props.item.childItems) { + for (const childItem of this.props.item.childItems) { + if (childItem.childItem.itemType === ProjectItemType.entityTypeResource) { + resourceItem = childItem.childItem; + } + } + } + + if (resourceItem && resourceItem.file) { + modeArea = ( +
+ +
+ ); + } + } else if (this.state.mode === EntityTypeEditorMode.loot) { + let lootTableItem = undefined; + if (this.props.item && this.props.item.childItems) { + for (const childItem of this.props.item.childItems) { + if (childItem.childItem.itemType === ProjectItemType.lootTableBehaviorJson) { + lootTableItem = childItem.childItem; + } + } + } + + if (lootTableItem && lootTableItem.file) { + modeArea = ( +
+ +
+ ); + } } return ( diff --git a/app/src/UX/EntityTypeResourceEditor.css b/app/src/UX/EntityTypeResourceEditor.css new file mode 100644 index 00000000..ac6cb5ee --- /dev/null +++ b/app/src/UX/EntityTypeResourceEditor.css @@ -0,0 +1,24 @@ +.etre-area { + width: calc(100% - 2px); + min-width: calc(100% - 2px); + max-width: calc(100% - 2px); + overflow-y: auto; +} + +.etre-headerTransition { + background-position-x: left; + background-repeat: repeat-x; + height: 40px; +} + +.etre-header { + font-size: 16pt; + padding-top: 10px; + padding-left: 30px; + padding-bottom: 13px; +} + +.etre-form { + padding-top: 20px; + padding-left: 20px; +} diff --git a/app/src/UX/EntityTypeResourceEditor.tsx b/app/src/UX/EntityTypeResourceEditor.tsx new file mode 100644 index 00000000..93a4e328 --- /dev/null +++ b/app/src/UX/EntityTypeResourceEditor.tsx @@ -0,0 +1,217 @@ +import { Component } from "react"; +import IFileProps from "./IFileProps"; +import IFile from "../storage/IFile"; +import "./EntityTypeResourceEditor.css"; +import Database from "../minecraft/Database"; +import { ThemeInput } from "@fluentui/styles"; +import DataForm, { IDataFormProps } from "../dataform/DataForm"; +import IProperty from "../dataform/IProperty"; +import EntityTypeResourceDefinition from "../minecraft/EntityTypeResourceDefinition"; + +interface IEntityTypeResourceEditorProps extends IFileProps { + heightOffset: number; + readOnly: boolean; + displayHeader?: boolean; + theme: ThemeInput; +} + +interface IEntityTypeResourceEditorState { + fileToEdit: IFile; + isLoaded: boolean; + selectedItem: EntityTypeResourceDefinition | undefined; +} + +export default class EntityTypeResourceEditor extends Component< + IEntityTypeResourceEditorProps, + IEntityTypeResourceEditorState +> { + private _lastFileEdited?: IFile; + + constructor(props: IEntityTypeResourceEditorProps) { + super(props); + + this._definitionLoaded = this._definitionLoaded.bind(this); + this._handleDataFormPropertyChange = this._handleDataFormPropertyChange.bind(this); + + this.state = { + fileToEdit: props.file, + isLoaded: false, + selectedItem: undefined, + }; + + this._updateManager(true); + } + + static getDerivedStateFromProps(props: IEntityTypeResourceEditorProps, state: IEntityTypeResourceEditorState) { + if (state === undefined || state === null) { + state = { + fileToEdit: props.file, + isLoaded: false, + selectedItem: undefined, + }; + + return state; + } + + if (props.file !== state.fileToEdit) { + state.fileToEdit = props.file; + state.isLoaded = false; + + return state; + } + + return null; + } + + componentDidUpdate(prevProps: IEntityTypeResourceEditorProps, prevState: IEntityTypeResourceEditorState) { + this._updateManager(true); + } + + async _updateManager(setState: boolean) { + if (this.state !== undefined && this.state.fileToEdit !== undefined) { + if (this.state.fileToEdit !== this._lastFileEdited) { + this._lastFileEdited = this.state.fileToEdit; + + await EntityTypeResourceDefinition.ensureOnFile(this.state.fileToEdit, this._definitionLoaded); + } + } + + await Database.ensureFormLoaded("entity_type_resource"); + + if ( + this.state.fileToEdit && + this.state.fileToEdit.manager !== undefined && + this.state.fileToEdit.manager instanceof EntityTypeResourceDefinition && + (this.state.fileToEdit.manager as EntityTypeResourceDefinition).isLoaded && + !this.state.isLoaded + ) { + this._doUpdate(setState); + } + } + + _definitionLoaded(defA: EntityTypeResourceDefinition, defB: EntityTypeResourceDefinition) { + this._doUpdate(true); + } + + async _doUpdate(setState: boolean) { + let selItem = this.state.selectedItem; + + if (selItem === undefined && this.state && this.state.fileToEdit && this.state.fileToEdit.manager) { + selItem = this.state.fileToEdit.manager as EntityTypeResourceDefinition; + } + + if (setState) { + this.setState({ + fileToEdit: this.state.fileToEdit, + isLoaded: true, + selectedItem: this.state.selectedItem, + }); + } else { + this.state = { + fileToEdit: this.props.file, + isLoaded: true, + selectedItem: this.state.selectedItem, + }; + } + } + + async persist() { + if (this.state !== undefined && this.state.fileToEdit != null) { + const file = this.state.fileToEdit; + + if (file.manager !== null) { + const srbd = file.manager as EntityTypeResourceDefinition; + + srbd.persist(); + } + } + } + + _handleDataFormPropertyChange(props: IDataFormProps, property: IProperty, newValue: any) { + if (props.tagData && props.directObject) { + const file = props.tagData as IFile; + + const newData = JSON.stringify(props.directObject, null, 2); + + file.setContent(newData); + } + } + + render() { + const height = "calc(100vh - " + this.props.heightOffset + "px)"; + + if ( + this.state === null || + this.state.fileToEdit === null || + this.state.fileToEdit.manager === undefined || + Database.uxCatalog === null + ) { + if (this.state.fileToEdit !== null) { + if (this.state.fileToEdit.manager === undefined) { + this._updateManager(true); + } + } + + return
Loading...
; + } + + if (this.props.setActivePersistable !== undefined) { + this.props.setActivePersistable(this); + } + + const definitionFile = this.state.fileToEdit.manager as EntityTypeResourceDefinition; + const def = definitionFile.dataWrapper; + + if (def === undefined) { + return
Loading definition...
; + } + + let defInner = def["minecraft:client_entity"]; + if (defInner === undefined) { + defInner = { + description: { + identifier: "", + materials: {}, + textures: {}, + geometry: {}, + particle_effects: {}, + animations: {}, + render_controllers: [], + scripts: {}, + }, + }; + def["minecraft:client_entity"] = defInner; + } + + const form = Database.getForm("entity_type_resource"); + + let header = <>; + if (this.props.displayHeader === undefined || this.props.displayHeader) { + header =
Entity Type Resources
; + } + + return ( +
+ {header} +
+
+ +
+
+
+ ); + } +} diff --git a/app/src/UX/FileExplorer.css b/app/src/UX/FileExplorer.css index c1ac157c..4feb392c 100644 --- a/app/src/UX/FileExplorer.css +++ b/app/src/UX/FileExplorer.css @@ -1,26 +1,40 @@ .fex-area { width: 100%; height: 100%; + min-height: 200px; overflow: auto; padding: 2px; } +.fex-folderArea { + border: solid 1px; + padding: 4px; +} + +.fex-newFolderIcon { + padding: 6px 6px 8px 2px; + grid-column: 1; + vertical-align: middle; +} + .fex-newFolderArea { display: grid; margin-top: 10px; - grid-template-columns: 1fr 194px 100px; + padding: 8px 4px 8px 4px; + border: solid 1px; + grid-template-columns: 26px 1fr 194px 100px; } .fex-newFolderLabel { - grid-column: 1; + grid-column: 2; overflow-x: hidden; - padding-top: 5px; + padding-top: 6px; } .fex-newFolderName { - grid-column: 2; + grid-column: 3; } .fex-newFolderGo { - grid-column: 3; + grid-column: 4; } diff --git a/app/src/UX/FileExplorer.tsx b/app/src/UX/FileExplorer.tsx index 475d48c1..90e718c3 100644 --- a/app/src/UX/FileExplorer.tsx +++ b/app/src/UX/FileExplorer.tsx @@ -8,6 +8,8 @@ import ItemAnnotationCollection from "./ItemAnnotationCollection"; import IFile from "../storage/IFile"; import StorageUtilities from "../storage/StorageUtilities"; import WebUtilities from "./WebUtilities"; +import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; +import { faFolderPlus } from "@fortawesome/free-solid-svg-icons"; export enum FileExplorerMode { explorer = 0, @@ -131,17 +133,23 @@ export default class FileExplorer extends Component this.props.heightOffset + 100 - ? "calc(100vh - " + Math.max(this.props.heightOffset - 10) + "px)" - : "inherit"; + let explorerHeight = + height > this.props.heightOffset + 100 ? "calc(100vh - " + (this.props.heightOffset - 10) + "px)" : "inherit"; let accessoryArea = <>; if (this.props.mode === FileExplorerMode.folderPicker && this.state.selectedItem) { const label = "Create a new folder at " + this.state.selectedItem.name + ":"; accessoryArea = ( -
+
+
+ +
{label}
@@ -149,10 +157,16 @@ export default class FileExplorer extends Component
-
); + explorerHeight = + height > this.props.heightOffset + 100 ? "calc(100vh - " + (this.props.heightOffset + 50) + "px)" : "inherit"; } return ( @@ -163,19 +177,26 @@ export default class FileExplorer extends Component - +
+ +
{accessoryArea} ); diff --git a/app/src/UX/Home.css b/app/src/UX/Home.css index 336017a0..e574eaf2 100644 --- a/app/src/UX/Home.css +++ b/app/src/UX/Home.css @@ -148,7 +148,7 @@ } .home-legal { - padding-bottom: 30px; + padding-bottom: 80px; } .home-dialog { diff --git a/app/src/UX/Home.tsx b/app/src/UX/Home.tsx index a6f5d099..d16c6c14 100644 --- a/app/src/UX/Home.tsx +++ b/app/src/UX/Home.tsx @@ -33,7 +33,7 @@ import AppServiceProxy, { AppServiceProxyCommands } from "../core/AppServiceProx import ProjectGallery from "./ProjectGallery"; import { constants } from "../core/Constants"; import StorageUtilities from "../storage/StorageUtilities"; -import { LocalFolderLabel, ConnectLabel, ExportBackupLabel } from "./Labels"; +import { LocalFolderLabel, ExportBackupLabel } from "./Labels"; import FileSystemStorage from "../storage/FileSystemStorage"; import CartoApp, { CartoThemeStyle } from "../app/CartoApp"; import UrlUtilities from "../core/UrlUtilities"; @@ -58,10 +58,9 @@ enum HomeDialogMode { interface IHomeProps extends IAppProps { theme: ThemeInput; errorMessage: string | undefined; - isPersisted?: boolean; heightOffset: number; visualSeed?: number; - onPersistenceUpgraded?: () => void; + isPersisted?: boolean; onModeChangeRequested?: (mode: AppMode) => void; onProjectSelected?: (project: Project) => void; onLog: (message: string) => Promise; @@ -159,13 +158,9 @@ export default class Home extends Component { this._handleNewProjectCreatorChange = this._handleNewProjectCreatorChange.bind(this); this._handleNewProjectDescriptionChange = this._handleNewProjectDescriptionChange.bind(this); this._handleSelectFolderClick = this._handleSelectFolderClick.bind(this); - this._handleExportToolClick = this._handleExportToolClick.bind(this); - this._handleUpgradeStorageKey = this._handleUpgradeStorageKey.bind(this); - this._handleUpgradeStorageClick = this._handleUpgradeStorageClick.bind(this); this._handleExportAllKey = this._handleExportAllKey.bind(this); this._handleExportAllClick = this._handleExportAllClick.bind(this); this._handleNewSearch = this._handleNewSearch.bind(this); - this._handleConnectClick = this._handleConnectClick.bind(this); this._onGalleryLoaded = this._onGalleryLoaded.bind(this); this._handleFileUpload = this._handleFileUpload.bind(this); this._handleInspectFileUpload = this._handleInspectFileUpload.bind(this); @@ -450,42 +445,6 @@ export default class Home extends Component { this.setCarto(this.props.carto); } - async _handleConnectClick() { - if (this.props.onModeChangeRequested) { - this.props.onModeChangeRequested(AppMode.companionPlusBack); - } - } - - _handleExportToolClick() { - if (this.props.onModeChangeRequested === undefined) { - Log.unexpectedUndefined("HETC"); - return; - } - - this.props.onModeChangeRequested(AppMode.exporterTool); - } - - async _handleUpgradeStorageKey(event: React.KeyboardEvent) { - if (event.key === "Enter") { - await this._handleUpgradeStorageClick(); - } - } - - async _handleUpgradeStorageClick() { - const result = await WebUtilities.requestPersistence(); - - if (result && this.props.onPersistenceUpgraded) { - this.props.onPersistenceUpgraded(); - } else { - this.setState({ - errorMessage: "Could not change the browser's storage for this site from temporary to a more persistent state.", - dialogMode: HomeDialogMode.errorMessage, - isDeployingToComMojang: this.props.carto.isDeployingToComMojang, - }); - return; - } - } - async _handleExportAllKey(event: React.KeyboardEvent) { if (event.key === "Enter") { await this._handleExportAllClick(); @@ -791,7 +750,7 @@ export default class Home extends Component { if (safeMessage !== undefined) { this.setState({ errorMessage: - "Folder could not be read - please choose a folder on your device that only has Minecraft files in it (no .exes, .bat files, etc.)\r\n\r\nDetails: " + + "Folder has unsupported files within it. Please choose a folder on your device that only has Minecraft asset files in it (.json, .png, .mcfunction, etc.)\r\n\r\nDetails: " + safeMessage, dialogMode: HomeDialogMode.errorMessage, isDeployingToComMojang: this.props.carto.isDeployingToComMojang, @@ -1305,26 +1264,16 @@ export default class Home extends Component { Projects ); - - if (!this.props.isPersisted) { + if (this.props.isPersisted) { introArea.push( -
- (stored in temporary browser storage.){" "} - - Make persistent - +
+ (stored in this device browser's storage.)
); } else { introArea.push(
- (stored in this device's browser storage.) + (stored in this device browser's temporary storage.)
); } @@ -1386,21 +1335,7 @@ export default class Home extends Component { let accessoryToolArea = <>; const actionsToolbar = []; - if (AppServiceProxy.hasAppService) { - actionsToolbar.push({ - icon: , - key: "openFolder", - onClick: this._handleOpenFolderClick, - title: "Open folder on this device", - }); - - actionsToolbar.push({ - icon: , - key: "connect", - onClick: this._handleConnectClick, - title: "Connect", - }); - } else if (window.showDirectoryPicker !== undefined) { + if (window.showDirectoryPicker !== undefined) { actionsToolbar.push({ icon: , key: "openFolderA", @@ -1663,6 +1598,18 @@ export default class Home extends Component { GitHub repo . + + Report an issue + + .
-
Name
+
File Name
@@ -283,7 +294,7 @@ export default class IntegrateItem extends Component diff --git a/app/src/UX/ItemGallery.tsx b/app/src/UX/ItemGallery.tsx index f83b6120..c0e53ce5 100644 --- a/app/src/UX/ItemGallery.tsx +++ b/app/src/UX/ItemGallery.tsx @@ -7,7 +7,6 @@ import IGallery from "../app/IGallery"; import IGalleryItem, { GalleryItemType } from "../app/IGalleryItem"; import { ThemeInput } from "@fluentui/react-northstar"; import Project from "../app/Project"; -import Log from "../core/Log"; import ItemTileButton, { ItemTileButtonDisplayMode } from "./ItemTileButton"; export enum GalleryItemCommand { @@ -45,7 +44,6 @@ export default class ItemGallery extends Component; +} + +interface ILootTableEditorState { + fileToEdit: IFile; + isLoaded: boolean; + selectedItem: LootTableBehaviorDefinition | undefined; +} + +export default class LootTableEditor extends Component { + private _lastFileEdited?: IFile; + + constructor(props: ILootTableEditorProps) { + super(props); + + this._definitionLoaded = this._definitionLoaded.bind(this); + this._handleDataFormPropertyChange = this._handleDataFormPropertyChange.bind(this); + + this.state = { + fileToEdit: props.file, + isLoaded: false, + selectedItem: undefined, + }; + + this._updateManager(true); + } + + static getDerivedStateFromProps(props: ILootTableEditorProps, state: ILootTableEditorState) { + if (state === undefined || state === null) { + state = { + fileToEdit: props.file, + isLoaded: false, + selectedItem: undefined, + }; + + return state; + } + + if (props.file !== state.fileToEdit) { + state.fileToEdit = props.file; + state.isLoaded = false; + + return state; + } + + return null; + } + + componentDidUpdate(prevProps: ILootTableEditorProps, prevState: ILootTableEditorState) { + this._updateManager(true); + } + + async _updateManager(setState: boolean) { + if (this.state !== undefined && this.state.fileToEdit !== undefined) { + if (this.state.fileToEdit !== this._lastFileEdited) { + this._lastFileEdited = this.state.fileToEdit; + + await LootTableBehaviorDefinition.ensureOnFile(this.state.fileToEdit, this._definitionLoaded); + } + } + + await Database.ensureFormLoaded("loot_table"); + + if ( + this.state.fileToEdit && + this.state.fileToEdit.manager !== undefined && + this.state.fileToEdit.manager instanceof LootTableBehaviorDefinition && + (this.state.fileToEdit.manager as LootTableBehaviorDefinition).isLoaded && + !this.state.isLoaded + ) { + this._doUpdate(setState); + } + } + + _definitionLoaded(defA: LootTableBehaviorDefinition, defB: LootTableBehaviorDefinition) { + this._doUpdate(true); + } + + async _doUpdate(setState: boolean) { + let selItem = this.state.selectedItem; + + if (selItem === undefined && this.state && this.state.fileToEdit && this.state.fileToEdit.manager) { + selItem = this.state.fileToEdit.manager as LootTableBehaviorDefinition; + } + + if (setState) { + this.setState({ + fileToEdit: this.state.fileToEdit, + isLoaded: true, + selectedItem: this.state.selectedItem, + }); + } else { + this.state = { + fileToEdit: this.props.file, + isLoaded: true, + selectedItem: this.state.selectedItem, + }; + } + } + + async persist() { + if (this.state !== undefined && this.state.fileToEdit != null) { + const file = this.state.fileToEdit; + + if (file.manager !== null) { + const srbd = file.manager as LootTableBehaviorDefinition; + + srbd.persist(); + } + } + } + + _handleDataFormPropertyChange(props: IDataFormProps, property: IProperty, newValue: any) { + if (props.tagData && props.directObject) { + const file = props.tagData as IFile; + + const newData = JSON.stringify(props.directObject, null, 2); + + file.setContent(newData); + } + } + + render() { + const height = "calc(100vh - " + this.props.heightOffset + "px)"; + + if ( + this.state === null || + this.state.fileToEdit === null || + this.state.fileToEdit.manager === undefined || + Database.uxCatalog === null + ) { + if (this.state.fileToEdit !== null) { + if (this.state.fileToEdit.manager === undefined) { + this._updateManager(true); + } + } + + return
Loading...
; + } + + if (this.props.setActivePersistable !== undefined) { + this.props.setActivePersistable(this); + } + + const definitionFile = this.state.fileToEdit.manager as LootTableBehaviorDefinition; + const def = definitionFile.data; + + if (def === undefined) { + return
Loading definition...
; + } + + const form = Database.getForm("loot_table"); + + let header = <>; + if (this.props.displayHeader === undefined || this.props.displayHeader) { + header =
Loot Table
; + } + + return ( +
+ {header} +
+
+ +
+
+
+ ); + } +} diff --git a/app/src/UX/NewBlockType.css b/app/src/UX/NewBlockType.css index 5eb10ee5..5ff63df9 100644 --- a/app/src/UX/NewBlockType.css +++ b/app/src/UX/NewBlockType.css @@ -15,6 +15,7 @@ .nbt-projectGallery { height: 360px; + overflow-y: auto; } .nbt-selectedProject { diff --git a/app/src/UX/NewEntityType.css b/app/src/UX/NewEntityType.css index 303566b1..471b988d 100644 --- a/app/src/UX/NewEntityType.css +++ b/app/src/UX/NewEntityType.css @@ -14,6 +14,7 @@ .net-projectGallery { height: 360px; + overflow-y: auto; } .net-galleryHeader { diff --git a/app/src/UX/NpmPackageJsonEditor.css b/app/src/UX/NpmPackageEditor.css similarity index 100% rename from app/src/UX/NpmPackageJsonEditor.css rename to app/src/UX/NpmPackageEditor.css diff --git a/app/src/UX/NpmPackageJsonEditor.tsx b/app/src/UX/NpmPackageEditor.tsx similarity index 83% rename from app/src/UX/NpmPackageJsonEditor.tsx rename to app/src/UX/NpmPackageEditor.tsx index a82945d0..78ddf000 100644 --- a/app/src/UX/NpmPackageJsonEditor.tsx +++ b/app/src/UX/NpmPackageEditor.tsx @@ -1,8 +1,8 @@ import { Component } from "react"; import IFileProps from "./IFileProps"; import IFile from "../storage/IFile"; -import "./NpmPackageJsonEditor.css"; -import NpmPackageJson from "../devproject/NpmPackageJson"; +import "./NpmPackageEditor.css"; +import NpmPackageDefinition from "../devproject/NpmPackageDefinition"; import Database from "../minecraft/Database"; import { ThemeInput } from "@fluentui/styles"; import { ListProps } from "@fluentui/react-northstar"; @@ -10,22 +10,22 @@ import ManagedComponentGroup from "../minecraft/ManagedComponentGroup"; import DataForm, { IDataFormProps } from "../dataform/DataForm"; import IProperty from "../dataform/IProperty"; -interface INpmPackageJsonEditorProps extends IFileProps { +interface INpmPackageEditorProps extends IFileProps { heightOffset: number; readOnly: boolean; theme: ThemeInput; } -interface INpmPackageJsonEditorState { +interface INpmPackageEditorState { fileToEdit: IFile; isLoaded: boolean; - selectedItem: NpmPackageJson | ManagedComponentGroup | undefined; + selectedItem: NpmPackageDefinition | ManagedComponentGroup | undefined; } -export default class NpmPackageJsonEditor extends Component { +export default class NpmPackageEditor extends Component { private _lastFileEdited?: IFile; - constructor(props: INpmPackageJsonEditorProps) { + constructor(props: INpmPackageEditorProps) { super(props); this._handleNpmPackageJsonLoaded = this._handleNpmPackageJsonLoaded.bind(this); @@ -41,7 +41,7 @@ export default class NpmPackageJsonEditor extends Component void; @@ -90,6 +91,8 @@ interface IProjectEditorProps extends IAppProps { isHosted?: boolean; visualSeed?: number; theme: ThemeInput; + isPersisted?: boolean; + onPersistenceUpgraded?: () => void; selectedItem?: string; heightOffset: number; mode?: ProjectEditorMode; @@ -185,6 +188,7 @@ export default class ProjectEditor extends Component { + this.setState({ + activeProjectItem: this.state.activeProjectItem, + tentativeProjectItem: this.state.tentativeProjectItem, + activeReference: this.state.activeReference, + menuState: this.state.menuState, + mode: this.state.mode, + viewMode: this.state.viewMode, + allInfoSet: this.props.project.infoSet, + allInfoSetGenerated: this.props.project.infoSet.completedGeneration, + displayFileView: this.state.displayFileView, + forceRawView: this.state.forceRawView, + filteredItems: this.state.filteredItems, + searchFilter: this.state.searchFilter, + effectMode: this.state.effectMode, + dragStyle: this.state.dragStyle, + visualSeed: this.state.visualSeed, + dialog: ProjectEditorDialog.webLocalDeploy, + dialogData: this.state.dialogData, + dialogActiveItem: this.state.dialogActiveItem, + statusAreaMode: this.state.statusAreaMode, + lastDeployKey: (data.icon as any).key, + lastExportKey: this.state.lastExportKey, + lastDeployFunction: this._handleWebLocalDeployClick, + lastExportFunction: this.state.lastExportFunction, + lastDeployData: data, + lastExportData: this.state.lastExportData, + }); + }, 2); + } + private async _handleChangeWorldSettingsClick(e: SyntheticEvent | undefined, data: MenuItemProps | undefined) { if (this.props.project == null || !data || !data.icon) { return; @@ -1620,6 +1709,8 @@ export default class ProjectEditor extends Component, + content: "Deploy to local Minecraft folder", + onClick: this._handleWebLocalDeployClick, + title: "Deploys this to a remote Dev Tools server", + }; + deployMenu.push(deployKeys[deployWebLocalKey]); + } + for (let i = 0; i < this.props.project.items.length; i++) { const pi = this.props.project.items[i]; @@ -3011,10 +3124,10 @@ export default class ProjectEditor extends Component, content: title + " world", @@ -3022,7 +3135,7 @@ export default class ProjectEditor extends Component, + content: title + " and test assets to Minecraft", + onClick: this._handleDeployWorldAndTestAssetsLocalClick, + title: "Deploys " + title + " and test assets in a zip", + }; + deployMenu.push(deployKeys[miKeyA]); + } } } @@ -3282,15 +3405,13 @@ export default class ProjectEditor extends Component, - key: "save", - content: , - onClick: this._handleSaveClick, - title: "Save", - }); - } + toolbarItems.push({ + icon: , + key: "save", + content: , + onClick: this._handleSaveClick, + title: "Save", + }); if (viewMode === CartoEditorViewMode.mainFocus) { toolbarItems.push({ @@ -3455,14 +3576,14 @@ export default class ProjectEditor extends Component, - key: "settings", - onClick: this._showSettingsClick, - title: "Settings", - }); + toolbarItems.push({ + icon: , + key: "settings", + onClick: this._showSettingsClick, + title: "Settings", + }); + if (Utilities.isPreview) { if ( this.props.project.role !== ProjectRole.documentation && this.props.project.role !== ProjectRole.meta && @@ -3493,36 +3614,23 @@ export default class ProjectEditor extends Component, - key: exportItem.key + "I", - onClick: exportItem.onClick, - active: true, - title: exportItem.title, - }); + toolbarItems.push({ + icon: , + key: exportItem.key + "I", + onClick: exportItem.onClick, + active: true, + title: exportItem.title, + }); - toolbarItems.push({ - icon: , - key: "export", - onMenuOpenChange: this._handleExportMenuOpen, - menuOpen: this.state.menuState === ProjectEditorMenuState.exportMenu, - menu: exportMenu, - active: true, - title: "Export Options", - }); - } else { - toolbarItems.push({ - key: "export", - icon: , - content: "Export", - title: isButtonCompact ? "" : "Export", - active: true, - menuOpen: this.state.menuState === ProjectEditorMenuState.exportMenu, - onMenuOpenChange: this._handleExportMenuOpen, - menu: exportMenu, - }); - } + toolbarItems.push({ + icon: , + key: "export", + onMenuOpenChange: this._handleExportMenuOpen, + menuOpen: this.state.menuState === ProjectEditorMenuState.exportMenu, + menu: exportMenu, + active: true, + title: "Export Options", + }); } if ( @@ -3673,7 +3781,7 @@ export default class ProjectEditor extends Component ); + } else if ( + file.type === "json" && + projItem.itemType === ProjectItemType.entityTypeBehaviorJson && + !(this.props.forceRawView || ep === ProjectEditPreference.raw) + ) { + Log.verbose("Showing entity type editor for '" + file.storageRelativePath + "'"); + interior = ( + + ); } else if ( file.type === "json" && projItem.itemType === ProjectItemType.scriptTypesJson && @@ -299,7 +319,7 @@ export default class ProjectItemEditor extends Component ); + } else if ( + file.type === "json" && + projItem.itemType === ProjectItemType.spawnRuleBehavior && + !(this.props.forceRawView || ep === ProjectEditPreference.raw) + ) { + interior = ( + + ); + } else if ( + file.type === "json" && + projItem.itemType === ProjectItemType.lootTableBehaviorJson && + !(this.props.forceRawView || ep === ProjectEditPreference.raw) + ) { + interior = ( + + ); + } else if ( + file.type === "json" && + projItem.itemType === ProjectItemType.entityTypeResource && + !(this.props.forceRawView || ep === ProjectEditPreference.raw) + ) { + interior = ( + + ); } else if ( file.type === "json" && projItem.itemType === ProjectItemType.commandSetDefinitionJson && diff --git a/app/src/UX/ProjectItemList.tsx b/app/src/UX/ProjectItemList.tsx index a9e786d1..24f8a05f 100644 --- a/app/src/UX/ProjectItemList.tsx +++ b/app/src/UX/ProjectItemList.tsx @@ -32,9 +32,7 @@ import { import { AssetsLabel, EyeSlashLabel, FunctionsLabel, TypesLabel } from "./Labels"; import { GitHubPropertyType } from "./ProjectPropertyEditor"; -import AddGitHubReference from "./AddGitHubReference"; import NewEntityType from "./NewEntityType"; -import ProjectExporter from "../app/ProjectExporter"; import ProjectUtilities, { NewEntityTypeAddMode } from "../app/ProjectUtilities"; import IGitHubInfo from "../app/IGitHubInfo"; import ProjectItemManager from "../app/ProjectItemManager"; @@ -168,11 +166,9 @@ export default class ProjectItemList extends Component ); - } else if ( - this.state !== null && - this.props.project !== null && - this.state.dialogMode === ProjectItemListDialogType.addGitHubReferenceDialog - ) { - dialogArea = ( - - } - header={"Add GitHub Reference"} - /> - ); } let splitButton = <>; diff --git a/app/src/UX/ProjectPropertyEditor.css b/app/src/UX/ProjectPropertyEditor.css index 5f24af44..001852d3 100644 --- a/app/src/UX/ProjectPropertyEditor.css +++ b/app/src/UX/ProjectPropertyEditor.css @@ -33,7 +33,7 @@ font-size: 16pt; margin: 0px; padding-top: 15px; - padding-left: 30px; + padding-left: 18px; padding-bottom: 16px; font-weight: bold; } @@ -169,33 +169,44 @@ grid-column-end: 3; padding-bottom: 20px; } +.ppe-tracklabel { + grid-row: 9; + grid-column: 1; +} -.ppe-focuslabel { +.ppe-trackinput { grid-row: 9; + grid-column-start: 2; + grid-column-end: 3; + padding-bottom: 20px; +} + +.ppe-focuslabel { + grid-row: 10; grid-column: 1; } .ppe-focusinput { - grid-row: 9; + grid-row: 10; grid-column-start: 2; grid-column-end: 3; padding-bottom: 20px; } .ppe-scriptVersionlabel { - grid-row: 10; + grid-row: 11; grid-column: 1; } .ppe-scriptVersioninput { - grid-row: 10; + grid-row: 11; grid-column-start: 2; grid-column-end: 3; padding-bottom: 20px; } .ppe-versionlabel { - grid-row: 11; + grid-row: 12; grid-column-start: 1; grid-column-end: 3; } @@ -214,7 +225,7 @@ } .ppe-versioninput { - grid-row: 11; + grid-row: 12; grid-column: 2; padding-bottom: 20px; } @@ -229,20 +240,20 @@ } .ppe-ghlabel { - grid-row: 12; + grid-row: 13; grid-column: 1; padding-top: 27px; } .ppe-ghinput { - grid-row: 12; + grid-row: 13; grid-column: 2; padding-top: 26px; padding-bottom: 20px; } .ppe-ghbutton { - grid-row: 11; + grid-row: 12; grid-column: 3; padding-top: 30px; padding-bottom: 20px; @@ -250,7 +261,7 @@ .ppe-statusArea { font-size: 14pt; - grid-row: 13; + grid-row: 14; grid-column-start: 1; grid-column-end: 5; padding-top: 30px; @@ -258,14 +269,14 @@ .ppe-advancedArea { font-size: 14pt; - grid-row: 14; + grid-row: 15; grid-column-start: 1; grid-column-end: 5; padding-top: 10px; } .ppe-bedrock { - grid-row: 14; + grid-row: 15; font-size: 2; line-height: 0.5; min-height: 16px; diff --git a/app/src/UX/ProjectPropertyEditor.tsx b/app/src/UX/ProjectPropertyEditor.tsx index 7e005546..0bd317c8 100644 --- a/app/src/UX/ProjectPropertyEditor.tsx +++ b/app/src/UX/ProjectPropertyEditor.tsx @@ -25,6 +25,7 @@ import { ProjectEditPreference, ProjectScriptLanguage, ProjectScriptVersion } fr import CartoApp, { HostType } from "../app/CartoApp"; import ProjectUtilities from "../app/ProjectUtilities"; import StatusList from "./StatusList"; +import { MinecraftTrack } from "../app/ICartoData"; interface IProjectPropertyEditorProps extends IAppProps { project: Project; @@ -53,6 +54,8 @@ export enum GitHubPropertyType { export const ProjectFocusStrings = ["General", "GameTests", "World", "Sample Behavior", "Editor Extension"]; +export const ProjectTargetStrings = ["", "Latest Minecraft release", "Latest Minecraft preview"]; + export default class ProjectPropertyEditor extends Component { private tentativeGitHubMode: string = "existing"; private tentativeGitHubRepoName?: string; @@ -98,6 +101,7 @@ export default class ProjectPropertyEditor extends Component | React.KeyboardEvent | null, + data: DropdownProps + ) { + if (data.value === ProjectTargetStrings[1]) { + this.props.project.track = MinecraftTrack.main; + } else if (data.value === ProjectTargetStrings[2]) { + this.props.project.track = MinecraftTrack.preview; + } else { + this.props.project.track = undefined; + } + } + _handleEditPreferenceChange( event: React.MouseEvent | React.KeyboardEvent | null, data: DropdownProps @@ -438,7 +455,6 @@ export default class ProjectPropertyEditor extends Component
+
Target Minecraft
+
+ +
Type
; +} + +interface ISpawnRulesEditorState { + fileToEdit: IFile; + isLoaded: boolean; + selectedItem: SpawnRulesBehaviorDefinition | undefined; +} + +export default class SpawnRulesEditor extends Component { + private _lastFileEdited?: IFile; + + constructor(props: ISpawnRulesEditorProps) { + super(props); + + this._definitionLoaded = this._definitionLoaded.bind(this); + this._handleDataFormPropertyChange = this._handleDataFormPropertyChange.bind(this); + + this.state = { + fileToEdit: props.file, + isLoaded: false, + selectedItem: undefined, + }; + + this._updateManager(true); + } + + static getDerivedStateFromProps(props: ISpawnRulesEditorProps, state: ISpawnRulesEditorState) { + if (state === undefined || state === null) { + state = { + fileToEdit: props.file, + isLoaded: false, + selectedItem: undefined, + }; + + return state; + } + + if (props.file !== state.fileToEdit) { + state.fileToEdit = props.file; + state.isLoaded = false; + + return state; + } + + return null; // No change to state + } + + componentDidUpdate(prevProps: ISpawnRulesEditorProps, prevState: ISpawnRulesEditorState) { + this._updateManager(true); + } + + async _updateManager(setState: boolean) { + if (this.state !== undefined && this.state.fileToEdit !== undefined) { + if (this.state.fileToEdit !== this._lastFileEdited) { + this._lastFileEdited = this.state.fileToEdit; + + await SpawnRulesBehaviorDefinition.ensureOnFile(this.state.fileToEdit, this._definitionLoaded); + } + } + + await Database.ensureFormLoaded("spawn_rules_header"); + + if ( + this.state.fileToEdit && + this.state.fileToEdit.manager !== undefined && + this.state.fileToEdit.manager instanceof SpawnRulesBehaviorDefinition && + (this.state.fileToEdit.manager as SpawnRulesBehaviorDefinition).isLoaded && + !this.state.isLoaded + ) { + this._doUpdate(setState); + } + } + + _definitionLoaded(defA: SpawnRulesBehaviorDefinition, defB: SpawnRulesBehaviorDefinition) { + this._doUpdate(true); + } + + async _doUpdate(setState: boolean) { + let selItem = this.state.selectedItem; + + if (selItem === undefined && this.state && this.state.fileToEdit && this.state.fileToEdit.manager) { + selItem = this.state.fileToEdit.manager as SpawnRulesBehaviorDefinition; + } + + if (setState) { + this.setState({ + fileToEdit: this.state.fileToEdit, + isLoaded: true, + selectedItem: this.state.selectedItem, + }); + } else { + this.state = { + fileToEdit: this.props.file, + isLoaded: true, + selectedItem: this.state.selectedItem, + }; + } + } + + async persist() { + if (this.state !== undefined && this.state.fileToEdit != null) { + const file = this.state.fileToEdit; + + if (file.manager !== null) { + const srbd = file.manager as SpawnRulesBehaviorDefinition; + + srbd.persist(); + } + } + } + + _handleDataFormPropertyChange(props: IDataFormProps, property: IProperty, newValue: any) { + if (props.tagData && props.directObject) { + const file = props.tagData as IFile; + + const newData = JSON.stringify(props.directObject, null, 2); + + file.setContent(newData); + } + } + + render() { + const height = "calc(100vh - " + this.props.heightOffset + "px)"; + + if ( + this.state === null || + this.state.fileToEdit === null || + this.state.fileToEdit.manager === undefined || + Database.uxCatalog === null + ) { + if (this.state.fileToEdit !== null) { + if (this.state.fileToEdit.manager === undefined) { + this._updateManager(true); + } + } + + return
Loading...
; + } + + if (this.props.setActivePersistable !== undefined) { + this.props.setActivePersistable(this); + } + + const definitionFile = this.state.fileToEdit.manager as SpawnRulesBehaviorDefinition; + const def = definitionFile.data; + + if (def === undefined) { + return
Loading definition...
; + } + + let defInner = def["minecraft:spawn_rules"]; + if (defInner === undefined) { + defInner = {}; + def["minecraft:spawn_rules"] = defInner; + } + + const form = Database.getForm("spawn_rules_header"); + + let header = <>; + if (this.props.displayHeader === undefined || this.props.displayHeader) { + header =
Spawn Rules
; + } + + return ( +
+ {header} +
+
+ +
+
+
+ ); + } +} diff --git a/app/src/UX/StatusArea.css b/app/src/UX/StatusArea.css index 2b9f244b..3286f6f6 100644 --- a/app/src/UX/StatusArea.css +++ b/app/src/UX/StatusArea.css @@ -10,7 +10,7 @@ } .sa-singleline { - padding-bottom: 4px; + padding-bottom: 6px; overflow-x: hidden; overflow-y: hidden; text-overflow: clip; diff --git a/app/src/UX/WebUtilities.ts b/app/src/UX/WebUtilities.ts index 6f2e97cc..24517b77 100644 --- a/app/src/UX/WebUtilities.ts +++ b/app/src/UX/WebUtilities.ts @@ -21,7 +21,7 @@ export default class WebUtilities { static async requestPersistence() { if (!navigator.storage || !navigator.storage.persist) { - return; + return false; } return await navigator.storage.persist(); @@ -29,7 +29,7 @@ export default class WebUtilities { static async getIsPersisted() { if (!navigator.storage || !navigator.storage.persist) { - return; + return false; } return await navigator.storage.persisted(); diff --git a/app/src/app/Carto.ts b/app/src/app/Carto.ts index 47df06a8..01a8d227 100644 --- a/app/src/app/Carto.ts +++ b/app/src/app/Carto.ts @@ -231,16 +231,25 @@ export default class Carto { this.#data.preferredSuite = newValue; } - public get processHostedMinecraftTrack() { - return this.#data.processHostedMinecraftTrack; + get track(): MinecraftTrack | undefined { + return this.#data.track; } - public set processHostedMinecraftTrack(newMinecraftTrack: MinecraftTrack | undefined) { - if (newMinecraftTrack !== this.#data.processHostedMinecraftTrack) { - this.#data.processHostedMinecraftTrack = newMinecraftTrack; + set track(newTrack: MinecraftTrack | undefined) { + if (newTrack !== this.#data.track) { + this.#data.track = newTrack; + this._onPropertyChanged.dispatch(this, "track"); } } + get effectiveTrack(): MinecraftTrack { + if (this.#data.track !== undefined) { + return this.#data.track; + } + + return MinecraftTrack.main; + } + public get useEditor() { return this.#data.useEditor; } @@ -1399,10 +1408,11 @@ export default class Carto { const canonPath = StorageUtilities.canonicalizePath(messageProjectPath); if (project !== undefined) { - await project.loadFromFile(); + await project.ensureLoadedFromFile(); if (project.mainDeployFolderPath !== undefined) { if (canonPath === StorageUtilities.canonicalizePath(project.mainDeployFolderPath)) { + await project.ensureInflated(); await project.inferProjectItemsFromFiles(); return project; @@ -1466,10 +1476,11 @@ export default class Carto { } if (project !== undefined && !openDirect) { - await project.loadFromFile(); + await project.ensureLoadedFromFile(); if (project.mainDeployFolderPath !== undefined) { if (canonPath === StorageUtilities.canonicalizePath(project.mainDeployFolderPath)) { + await project.ensureInflated(); await project.inferProjectItemsFromFiles(); return project; @@ -1497,10 +1508,11 @@ export default class Carto { for (let i = 0; i < this.projects.length; i++) { project = this.projects[i]; - await project.loadFromFile(); + await project.ensureLoadedFromFile(); if (project.mainDeployFolderPath !== undefined) { if (canonPath === StorageUtilities.canonicalizePath(project.mainDeployFolderPath)) { + await project.ensureInflated(); await project.inferProjectItemsFromFiles(); return project; @@ -1544,7 +1556,7 @@ export default class Carto { for (let i = 0; i < this.projects.length; i++) { const project = this.projects[i]; - await project.loadFromFile(); + await project.ensureLoadedFromFile(); await project.ensureProjectFolder(); diff --git a/app/src/app/ICartoData.ts b/app/src/app/ICartoData.ts index 0dba2ecb..6b965d1b 100644 --- a/app/src/app/ICartoData.ts +++ b/app/src/app/ICartoData.ts @@ -52,13 +52,13 @@ export default interface ICartoData { successfullyConnectedWebSocketToMinecraft: boolean; successfullyConnectedToRemoteMinecraft: boolean; successfullyStartedMinecraftServer: boolean; - processHostedMinecraftTrack?: MinecraftTrack; worldSettings?: IWorldSettings; editorWorldSettings?: IWorldSettings; autoStartMinecraft: boolean; showScreenOnConnect: boolean; useEditor?: boolean; creator?: string; + track?: MinecraftTrack; formatBeforeSave?: boolean; itemSidePaneWidth?: number; preferredTextSize?: number; diff --git a/app/src/app/IProjectData.ts b/app/src/app/IProjectData.ts index eef84744..80f2b39d 100644 --- a/app/src/app/IProjectData.ts +++ b/app/src/app/IProjectData.ts @@ -6,6 +6,7 @@ import IGitHubInfo from "./IGitHubInfo"; import ITool from "./ITool"; import { IWorldSettings } from "../minecraft/IWorldSettings"; import IStatus from "./Status"; +import { MinecraftTrack } from "./ICartoData"; export enum ProjectDataType { localStorage = 0, @@ -56,6 +57,8 @@ export default interface IProjectData { focus: ProjectFocus; role?: ProjectRole; + track?: MinecraftTrack; + editPreference: ProjectEditPreference; gitHubReferences?: IGitHubInfo[]; diff --git a/app/src/app/IProjectItemData.ts b/app/src/app/IProjectItemData.ts index 02bc265f..5dcbee4b 100644 --- a/app/src/app/IProjectItemData.ts +++ b/app/src/app/IProjectItemData.ts @@ -47,7 +47,7 @@ export enum ProjectItemType { soundsCatalogResourceJson = 27, animationResourceJson = 28, animationControllerResourceJson = 29, - entityTypeResourceJson = 30, + entityTypeResource = 30, fogResourceJson = 31, modelGeometryJson = 32, particleJson = 33, @@ -61,7 +61,7 @@ export enum ProjectItemType { featureBehaviorJson = 41, functionEventJson = 42, recipeBehaviorJson = 43, - spawnRuleBehaviorJson = 44, + spawnRuleBehavior = 44, tradingBehaviorJson = 45, volumeBehaviorJson = 46, attachableResourceJson = 47, @@ -136,7 +136,7 @@ export enum ProjectItemType { levelDbManifest = 117, levelDat = 118, justConfigTs = 119, - esLintMjs = 120, + esLintConfigMjs = 120, env = 121, prettierRcJson = 122, skinCatalogJson = 123, diff --git a/app/src/app/IProjectItemRelationship.ts b/app/src/app/IProjectItemRelationship.ts new file mode 100644 index 00000000..c7a9c93c --- /dev/null +++ b/app/src/app/IProjectItemRelationship.ts @@ -0,0 +1,6 @@ +import ProjectItem from "./ProjectItem"; + +export default interface IProjectItemRelationship { + parentItem: ProjectItem; + childItem: ProjectItem; +} diff --git a/app/src/app/Project.ts b/app/src/app/Project.ts index c58b7083..3fafb4b8 100644 --- a/app/src/app/Project.ts +++ b/app/src/app/Project.ts @@ -37,6 +37,8 @@ import { ProjectInfoSuite } from "../info/IProjectInfoData"; import Pack, { PackType } from "../minecraft/Pack"; import { IErrorable } from "../core/IErrorable"; import ProjectDeploySync from "./ProjectDeploySync"; +import { MinecraftTrack } from "./ICartoData"; +import ProjectItemRelations from "./ProjectItemRelations"; export enum ProjectAutoDeploymentMode { deployOnSave = 0, @@ -149,6 +151,8 @@ export default class Project { public changedFilesSinceLastSaved: { [storagePath: string]: IFile | undefined } = {}; #isLoaded = false; + #isInflated = false; + #isProjectFolderEnsured = false; #useProjectNameInProjectStorage = false; @@ -159,6 +163,7 @@ export default class Project { private _onPropertyChanged = new EventDispatcher(); private _onLoaded = new EventDispatcher(); + private _onInflated = new EventDispatcher(); private _onSaved = new EventDispatcher(); private _onNeedsSaveChanged = new EventDispatcher(); private _onItemChanged = new EventDispatcher(); @@ -418,6 +423,10 @@ export default class Project { return this.#isLoaded; } + public get isInflated() { + return this.#isInflated; + } + public get distBuildFolder() { return this.#distBuildFolder; } @@ -450,6 +459,10 @@ export default class Project { return this._onLoaded.asEvent(); } + public get onInflated() { + return this._onLoaded.asEvent(); + } + public get onSaved() { return this._onSaved.asEvent(); } @@ -603,6 +616,10 @@ export default class Project { return val; } + getItemsCopy(): ProjectItem[] { + return this.#items.slice(); + } + public initializeWorldSettings() { if (this.#data.worldSettings === undefined) { this.#data.worldSettings = { @@ -879,6 +896,25 @@ export default class Project { } } + get track(): MinecraftTrack | undefined { + return this.#data.track; + } + + set track(newTrack: MinecraftTrack | undefined) { + if (newTrack !== this.#data.track) { + this.#data.track = newTrack; + this._onPropertyChanged.dispatch(this, "track"); + } + } + + get effectiveTrack(): MinecraftTrack { + if (this.#data.track !== undefined) { + return this.#data.track; + } + + return this.#carto.effectiveTrack; + } + set originalFullPath(newOriginalPath: string | undefined) { if (this.#data.originalFullPath !== newOriginalPath) { this.#data.originalFullPath = newOriginalPath; @@ -1306,7 +1342,7 @@ export default class Project { this._handleDeployUpdated = this._handleDeployUpdated.bind(this); this._handleProjectFileContentsUpdated = this._handleProjectFileContentsUpdated.bind(this); this.applyUpdate = this.applyUpdate.bind(this); - this.loadFromFile = this.loadFromFile.bind(this); + this.ensureLoadedFromFile = this.ensureLoadedFromFile.bind(this); this.ensureProjectFolder = this.ensureProjectFolder.bind(this); this._handleProjectFolderMoved = this._handleProjectFolderMoved.bind(this); @@ -1351,13 +1387,6 @@ export default class Project { this._onItemChanged.dispatch(this, item); } - clearProjectItems() { - this.#hasInferredFiles = false; - this.#items = []; - this.#itemsByProjectPath = {}; - this.#data.items = []; - } - clearFolders() { this._unapplyFromProjectFolder(); @@ -1435,6 +1464,8 @@ export default class Project { ); } } + + await ProjectItemRelations.calculate(this); } } @@ -1467,18 +1498,6 @@ export default class Project { this.#hasInferredFiles = true; } - async updateAutogeneratedItems() { - for (let i = 0; i < this.#items.length; i++) { - const item = this.#items[i]; - - if (item.creationType === ProjectItemCreationType.generated) { - await item.updateAutogenerated(); - } - - await item.updateAutogeneratedSideFiles(); - } - } - async ensureWorldContainer() { if (!this.#worldContainer) { const pf = await this.ensureProjectFolder(); @@ -2054,7 +2073,7 @@ export default class Project { projectPath, ProjectItemStorageType.singleFile, candidateFile.name, - ProjectItemType.esLintMjs, + ProjectItemType.esLintConfigMjs, source, ProjectItemCreationType.normal, candidateFile, @@ -2251,7 +2270,7 @@ export default class Project { folderContext === FolderContext.behaviorPack && folderPathLower.indexOf("/spawn_rules/") >= 0 ) { - newJsonType = ProjectItemType.spawnRuleBehaviorJson; + newJsonType = ProjectItemType.spawnRuleBehavior; } else if (folderContext === FolderContext.behaviorPack && folderPathLower.indexOf("/cameras/") >= 0) { newJsonType = ProjectItemType.cameraJson; } else if (folderContext === FolderContext.behaviorPack && folderPathLower.indexOf("/trading/") >= 0) { @@ -2299,7 +2318,7 @@ export default class Project { folderContext === FolderContext.resourcePack && (folderPathLower.indexOf("/entities/") >= 0 || folderPathLower.indexOf("/entity/") >= 0) ) { - newJsonType = ProjectItemType.entityTypeResourceJson; + newJsonType = ProjectItemType.entityTypeResource; } else if (folderContext === FolderContext.resourcePack && folderPathLower.indexOf("/fogs/") >= 0) { newJsonType = ProjectItemType.fogResourceJson; } else if (folderContext === FolderContext.resourcePack && folderPathLower.indexOf("/particles/") >= 0) { @@ -2945,7 +2964,7 @@ export default class Project { return pi; } - async loadFromFile() { + async ensureLoadedFromFile() { Log.assert(!this.#isDisposed, "PLF"); if (this.#isLoaded) { @@ -2958,13 +2977,37 @@ export default class Project { await this.#file.loadContent(false); - this.clearProjectItems(); + this.#hasInferredFiles = false; + this.#items = []; + this.#itemsByProjectPath = {}; + this.#data.items = []; if (Utilities.isString(this.#file.content) && this.#file.content != null) { this.#data = JSON.parse(this.#file.content as string); await this.ensureProjectFolder(true); + } else { + await this.ensureProjectFolder(); + } + + this._onLoaded.dispatch(this, this); + + this.#isLoaded = true; + } + + async ensureInflated() { + Log.assert(!this.#isDisposed, "PLINF"); + + if (this.#isInflated) { + return; + } + + await this.ensureLoadedFromFile(); + + this.#items = []; + this.#itemsByProjectPath = {}; + if (this.#data) { for (let i = 0; i < this.#data.items.length; i++) { const projectItemData = this.#data.items[i]; @@ -2974,16 +3017,16 @@ export default class Project { this._onItemAdded.dispatch(this, projectItem); } - } else { - await this.ensureProjectFolder(); } - this._onLoaded.dispatch(this, this); + this._onInflated.dispatch(this, this); this.initializeWorldSettings(); this.ensureDefaultWorldName(); - this.#isLoaded = true; + await ProjectItemRelations.calculate(this); + + this.#isInflated = true; } async deleteThisProject() { diff --git a/app/src/app/ProjectAutogeneration.ts b/app/src/app/ProjectAutogeneration.ts new file mode 100644 index 00000000..b7ad51b5 --- /dev/null +++ b/app/src/app/ProjectAutogeneration.ts @@ -0,0 +1,409 @@ +import { ProjectItemCreationType, ProjectItemStorageType, ProjectItemType } from "./IProjectItemData"; +import Project, { AUTOGENERATED_CONTENT_TOKEN, AUTOGENERATED_JS_SEPARATOR } from "./Project"; +import ProjectItem from "./ProjectItem"; +import Log from "../core/Log"; +import { ProjectScriptLanguage } from "./IProjectData"; +import StorageUtilities from "../storage/StorageUtilities"; +import EntityTypeDefinition from "../minecraft/EntityTypeDefinition"; +import BehaviorManifestDefinition from "../minecraft/BehaviorManifestDefinition"; +import EnvSettings from "../devproject/EnvSettings"; +import VsCodeLaunchDefinition from "../devproject/VsCodeLaunchDefinition"; +import VsCodeTasksDefinition from "../devproject/VsCodeTasksDefinition"; +import VsCodeExtensionsDefinition from "../devproject/VsCodeExtensionsDefinition"; +import VsCodeSettingsDefinition from "../devproject/VsCodeSettingsDefinition"; +import PrettierRcConfig from "../devproject/PrettierRcConfig"; +import JustConfig from "../devproject/JustConfig"; + +export default class ProjectAutogeneration { + static async updateProjectAutogeneration(project: Project) { + let packageItems = 0; + let envItems = 0; + let justConfigItems = 0; + let needsJustConfig = false; + let needsEslintConfig = false; + let eslintConfigItems = 0; + let vsCodeLaunchItems = 0; + let vsCodeExtensionsItems = 0; + let vsCodeSettingsItems = 0; + let vsCodeTasksItems = 0; + let prettierRcItems = 0; + + const items = project.getItemsCopy(); + + for (let i = 0; i < items.length; i++) { + const item = items[i]; + + if (item.itemType === ProjectItemType.packageJson) { + packageItems++; + + if (item.file) { + await item.file.loadContent(); + + if (item.file.content && typeof item.file.content === "string") { + if (item.file.content.indexOf("just-scripts") > 0) { + needsJustConfig = true; + } + if (item.file.content.indexOf("eslint") > 0) { + needsEslintConfig = true; + } + } + } + } else if (item.itemType === ProjectItemType.env) { + envItems++; + } else if (item.itemType === ProjectItemType.vsCodeLaunchJson) { + vsCodeLaunchItems++; + } else if (item.itemType === ProjectItemType.prettierRcJson) { + prettierRcItems++; + } else if (item.itemType === ProjectItemType.esLintConfigMjs) { + eslintConfigItems++; + } else if (item.itemType === ProjectItemType.justConfigTs) { + justConfigItems++; + } + } + + if (envItems === 0 && (justConfigItems > 0 || needsJustConfig)) { + project.ensureItemByProjectPath( + "/.env", + ProjectItemStorageType.singleFile, + ".env", + ProjectItemType.env, + undefined, + ProjectItemCreationType.generated + ); + } + + if (prettierRcItems === 0 && packageItems > 0) { + project.ensureItemByProjectPath( + "/.prettierrc.json", + ProjectItemStorageType.singleFile, + ".prettierrc.json", + ProjectItemType.prettierRcJson, + undefined, + ProjectItemCreationType.generated + ); + } + + if (justConfigItems === 0 && needsJustConfig) { + project.ensureItemByProjectPath( + "/just.config.ts", + ProjectItemStorageType.singleFile, + "just.config.ts", + ProjectItemType.justConfigTs, + undefined, + ProjectItemCreationType.generated + ); + } + + if (eslintConfigItems === 0 && needsEslintConfig) { + project.ensureItemByProjectPath( + "/eslint.config.mjs", + ProjectItemStorageType.singleFile, + "eslint.config.mjs", + ProjectItemType.esLintConfigMjs, + undefined, + ProjectItemCreationType.generated + ); + } + + if (vsCodeLaunchItems === 0 && packageItems > 0 && project.projectFolder) { + project.ensureItemByProjectPath( + "/.vscode/launch.json", + ProjectItemStorageType.singleFile, + "launch.json", + ProjectItemType.vsCodeLaunchJson, + undefined, + ProjectItemCreationType.generated + ); + } + + if (vsCodeSettingsItems === 0 && packageItems > 0 && project.projectFolder) { + project.ensureItemByProjectPath( + "/.vscode/settings.json", + ProjectItemStorageType.singleFile, + "settings.json", + ProjectItemType.vsCodeSettingsJson, + undefined, + ProjectItemCreationType.generated + ); + } + + if (vsCodeTasksItems === 0 && packageItems > 0 && project.projectFolder) { + project.ensureItemByProjectPath( + "/.vscode/tasks.json", + ProjectItemStorageType.singleFile, + "tasks.json", + ProjectItemType.vsCodeTasksJson, + undefined, + ProjectItemCreationType.generated + ); + } + + if (vsCodeExtensionsItems === 0 && packageItems > 0 && project.projectFolder) { + project.ensureItemByProjectPath( + "/.vscode/extensions.json", + ProjectItemStorageType.singleFile, + "extensions.json", + ProjectItemType.vsCodeExtensionsJson, + undefined, + ProjectItemCreationType.generated + ); + } + + for (let i = 0; i < items.length; i++) { + const item = items[i]; + + if (item.creationType === ProjectItemCreationType.generated) { + await ProjectAutogeneration.updateItemAutogeneration(item); + } + + await ProjectAutogeneration.updateItemAutogeneratedSideFiles(item); + } + } + + static async updateItemAutogeneratedSideFiles(item: ProjectItem) { + if (!item.file || !item.project) { + return; + } + } + + static async updateItemAutogeneration(item: ProjectItem, contentOnlyUpdate?: boolean) { + if (!contentOnlyUpdate) { + await item.load(); + } + + if (item.file == null || item.creationType !== ProjectItemCreationType.generated) { + return; + } + + if (item.itemType === ProjectItemType.catalogIndexJs) { + await item.file.loadContent(); + + ProjectAutogeneration.updateCatalogJsContent(item, await ProjectAutogeneration.getCatalogJsContent(item.project)); + } else if (item.itemType === ProjectItemType.env) { + item.file.setContent( + await EnvSettings.getContent( + item.project, + typeof item.file.content === "string" ? item.file.content : undefined + ) + ); + } else if (item.itemType === ProjectItemType.justConfigTs) { + const justConfigTs = await JustConfig.ensureOnFile(item.file); + + if (justConfigTs) { + await justConfigTs.ensureDefault(); + await justConfigTs.save(); + } + } else if (item.itemType === ProjectItemType.vsCodeLaunchJson) { + const vscodelaunch = await VsCodeLaunchDefinition.ensureOnFile(item.file); + + if (vscodelaunch) { + await vscodelaunch.ensureMinContent(); + await vscodelaunch.save(); + } + } else if (item.itemType === ProjectItemType.vsCodeTasksJson) { + const vscodetasks = await VsCodeTasksDefinition.ensureOnFile(item.file); + + if (vscodetasks) { + await vscodetasks.ensureMinContent(); + await vscodetasks.save(); + } + } else if (item.itemType === ProjectItemType.vsCodeExtensionsJson) { + const vscodeextensions = await VsCodeExtensionsDefinition.ensureOnFile(item.file); + + if (vscodeextensions) { + await vscodeextensions.ensureMinContent(); + await vscodeextensions.save(); + } + } else if (item.itemType === ProjectItemType.vsCodeSettingsJson) { + const vscodesettings = await VsCodeSettingsDefinition.ensureOnFile(item.file); + + if (vscodesettings) { + await vscodesettings.ensureMinContent(); + await vscodesettings.save(); + } + } else if (item.itemType === ProjectItemType.prettierRcJson) { + const prettierrc = await PrettierRcConfig.ensureOnFile(item.file); + + if (prettierrc) { + await prettierrc.ensureMinContent(); + await prettierrc.save(); + } + } else if (item.itemType === ProjectItemType.behaviorPackManifestJson) { + item.file.setContent(await BehaviorManifestDefinition.getContent(item.project, contentOnlyUpdate)); + } else if (item.itemType === ProjectItemType.entityTypeBaseJs) { + const content = await ProjectAutogeneration.getGeneratedTypeJavaScript(item); + + if (content.javaScript !== undefined) { + item.file.setContent(content.javaScript); + } + if ( + item.project.preferredScriptLanguage === ProjectScriptLanguage.typeScript && + content.typeScript !== undefined + ) { + const file = item.file.parentFolder.ensureFile(StorageUtilities.getBaseFromName(item.file.name) + ".ts"); + + file.setContent(content.typeScript); + } + + if ( + item.project.preferredScriptLanguage === ProjectScriptLanguage.typeScript && + content.typeScript !== undefined + ) { + const file = item.file.parentFolder.ensureFile(StorageUtilities.getBaseFromName(item.file.name) + ".ts"); + + file.setContent(content.typeScript); + } + } else if (item.itemType === ProjectItemType.entityTypeBaseTs) { + const content = await ProjectAutogeneration.getGeneratedTypeJavaScript(item); + + if (content.typeScript !== undefined) { + item.file.setContent(content.typeScript); + } + } + } + + static async getCatalogJsContent(project: Project) { + const content: string[] = []; + + const behaviorPackRootFolder = await project.ensureDefaultBehaviorPackFolder(); + + const items = project.getItemsCopy(); + + for (let i = 0; i < items.length; i++) { + const projectItem = items[i]; + + if (projectItem.itemType === ProjectItemType.worldTest) { + const file = await projectItem.ensureFileStorage(); + + if (file) { + const newFileName = StorageUtilities.getBaseFromName(file.name) + ".gen.js"; + + content.push('import "scripts/' + newFileName + '";'); + } + } else if ( + projectItem.itemType === ProjectItemType.js || + projectItem.itemType === ProjectItemType.buildProcessedJs || + projectItem.itemType === ProjectItemType.entityTypeBaseJs || + projectItem.itemType === ProjectItemType.testJs + ) { + const file = await projectItem.ensureFileStorage(); + + if (file) { + let filePath = file.getFolderRelativePath(behaviorPackRootFolder); + + if (!file.isContentLoaded) { + await file.loadContent(false); + } + + if ((file.content !== null || filePath !== null) && filePath !== undefined) { + if (filePath.startsWith("/scripts/")) { + filePath = filePath.substring(9, filePath.length); + } + + if (filePath.startsWith("/")) { + filePath = filePath.substring(1, filePath.length); + } + + content.push('import "' + filePath + '";'); + } + } + } + } + + return AUTOGENERATED_JS_SEPARATOR + "\r\n\r\n" + content.join("\r\n"); + } + + static async updateCatalogJsContent(item: ProjectItem, newContent: string) { + if (item.file == null || item.file.content instanceof Uint8Array) { + Log.unexpectedContentState(); + return; + } + + if (item.file.content === undefined || item.file.content === null || item.file.content.trim() === "") { + item.file.setContent(newContent); + return; + } + + let updatedContent = item.file.content; + + const autogenToken = updatedContent.indexOf(AUTOGENERATED_CONTENT_TOKEN); + + if (autogenToken >= 0) { + let previous = updatedContent.lastIndexOf("\r", autogenToken); + + if (previous < 0) { + previous = updatedContent.lastIndexOf("\n", autogenToken); + + if (previous < 0) { + previous = 0; + } + } + + const previousComment = updatedContent.lastIndexOf("//", autogenToken); + + // we expect \r\n//, but if for some reason the comment has moved, let's only strip from the comment forward. + if (previousComment > previous + 2) { + previous = previousComment; + } + + if (previous >= 0) { + updatedContent = updatedContent.substring(0, previous); + } + } + + updatedContent += newContent; + + item.file.setContent(updatedContent); + } + + static async getGeneratedTypeJavaScript(item: ProjectItem) { + if (item.projectPath === null || item.projectPath === undefined) { + return { javaScript: "", typeScript: undefined }; + } + + let typeName = StorageUtilities.getBaseFromName(StorageUtilities.getLeafName(item.projectPath)); + + if (typeName.endsWith(".base")) { + typeName = typeName.substring(0, typeName.length - 5); + } + + const items = item.project.getItemsCopy(); + + for (let i = 0; i < items.length; i++) { + const candItem = items[i]; + + if ( + candItem.itemType === ProjectItemType.entityTypeBehaviorJson && + candItem.projectPath !== null && + candItem.projectPath !== undefined + ) { + const jsonName = StorageUtilities.getBaseFromName(StorageUtilities.getLeafName(candItem.projectPath)); + + if (jsonName === typeName) { + const jsonFile = await candItem.ensureFileStorage(); + + if (jsonFile !== undefined && jsonFile !== null) { + if (jsonFile.manager === undefined) { + await EntityTypeDefinition.ensureOnFile(jsonFile); + } + + if (jsonFile.manager) { + const et = jsonFile.manager as EntityTypeDefinition; + + const js = et.getScript(false); + let ts = undefined; + + if (item.project.preferredScriptLanguage === ProjectScriptLanguage.typeScript) { + ts = et.getScript(true); + } + + return { javaScript: js, typeScript: ts }; + } + } + } + } + } + + return { javaScript: "", typeScript: undefined }; + } +} diff --git a/app/src/app/ProjectExporter.ts b/app/src/app/ProjectExporter.ts index a296e68a..ec673bdc 100644 --- a/app/src/app/ProjectExporter.ts +++ b/app/src/app/ProjectExporter.ts @@ -12,7 +12,6 @@ import Log from "../core/Log"; import Carto from "./Carto"; import GitHubStorage from "./../github/GitHubStorage"; import AppServiceProxy, { AppServiceProxyCommands } from "./../core/AppServiceProxy"; -import IGitHubInfo from "./IGitHubInfo"; import ZipStorage from "../storage/ZipStorage"; import { ProjectFocus } from "../app/IProjectData"; import { IWorldSettings } from "../minecraft/IWorldSettings"; @@ -30,6 +29,19 @@ export const enum FolderDeploy { noFolders = 2, } +export const ProjectImportExclusions = [ + "build", + "node_modules", + "dist", + "lib", + ".env", + "*/.*", + "out", + "*just.config*", + "*package-lock*", + "*.mjs*", +]; + export default class ProjectExporter { static async generateFlatBetaApisWorldWithPacksZipBytes(carto: Carto, project: Project, name: string) { await Database.loadContent(); @@ -113,7 +125,7 @@ export default class ProjectExporter { false, false, false, - ["build", "node_modules", "dist", "lib", "/.git", "out"], + ProjectImportExclusions, undefined, messageUpdater, dontOverwriteExistingFiles @@ -167,90 +179,6 @@ export default class ProjectExporter { } } - static async addGitHubReference( - carto: Carto, - project: Project, - gitHubOwner: string, - gitHubRepoName: string, - gitHubBranch?: string, - gitHubFolder?: string, - commit?: string, - title?: string - ) { - const gh = new GitHubStorage(carto.anonGitHub, gitHubRepoName, gitHubOwner, gitHubBranch, gitHubFolder); - - await gh.rootFolder.load(); - - const info: IGitHubInfo = { - owner: gitHubOwner, - repoName: gitHubRepoName, - branch: gitHubBranch, - folder: gitHubFolder, - commit: commit, - title: title, - }; - - const sig = ProjectItem.getGitHubSignature(info); - let foundReference = false; - - for (let i = 0; i < project.gitHubReferences.length; i++) { - const ghr = project.gitHubReferences[i]; - - const sigCandidate = ProjectItem.getGitHubSignature(ghr); - - if (sigCandidate === sig) { - foundReference = true; - - project.gitHubReferences[i] = info; - } - } - - if (!foundReference) { - project.gitHubReferences.push(info); - } - - const bpFolder = await project.ensureDefaultBehaviorPackFolder(); - - // run infer project items before we add the project items just to catch up on anything that might be out there. - await project.inferProjectItemsFromFiles(); - - const existingProjects: string[] = []; - - for (let i = 0; i < project.items.length; i++) { - const spath = project.items[i].projectPath; - - if (spath !== undefined && spath !== null) { - existingProjects.push(spath); - } - } - - let ghFolder: IFolder = gh.rootFolder; - - const bpGhFolder = await ProjectExporter.getPackFolder(ghFolder, false); - - if (bpGhFolder !== undefined) { - ghFolder = bpGhFolder; - } - - await StorageUtilities.syncFolderTo(ghFolder, bpFolder, false, false, false, ["/.git"]); - - await bpFolder.saveAll(); - - await project.inferProjectItemsFromFiles(true); - - for (let i = 0; i < project.items.length; i++) { - const item = project.items[i]; - - const spath = item.projectPath; - - if (spath !== undefined && spath !== null && !existingProjects.includes(spath)) { - item.gitHubReference = info; - } - } - - await project.save(); - } - static async getPackFolder(folder: IFolder, seekingResource: boolean) { await folder.load(); diff --git a/app/src/app/ProjectItem.ts b/app/src/app/ProjectItem.ts index 3b43ebe6..7c5b6b2b 100644 --- a/app/src/app/ProjectItem.ts +++ b/app/src/app/ProjectItem.ts @@ -9,26 +9,23 @@ import IProjectItemData, { } from "./IProjectItemData"; import Log from "./../core/Log"; import { ProjectItemType } from "./IProjectItemData"; -import Project, { - AUTOGENERATED_CONTENT_TOKEN, - AUTOGENERATED_JS_SEPARATOR, - AUTOGENERATED_WHOLEFILE_GENERAL_SEPARATOR, - minecraftScriptModules, -} from "./Project"; +import Project from "./Project"; import { EventDispatcher } from "ste-events"; import IFile from "../storage/IFile"; import IFolder from "../storage/IFolder"; import StorageUtilities from "../storage/StorageUtilities"; -import IAddonManifest, { IAddonDependency, IAddonModule } from "../minecraft/IAddonManifest"; import IGitHubInfo from "./IGitHubInfo"; import EntityTypeDefinition from "../minecraft/EntityTypeDefinition"; -import { ProjectEditPreference, ProjectFocus, ProjectScriptLanguage } from "./IProjectData"; +import { ProjectEditPreference } from "./IProjectData"; import MCWorld from "../minecraft/MCWorld"; import ZipStorage from "../storage/ZipStorage"; import Utilities from "../core/Utilities"; import { StorageErrorStatus } from "../storage/IStorage"; import ProjectItemUtilities from "./ProjectItemUtilities"; import Pack from "../minecraft/Pack"; +import ProjectAutogeneration from "./ProjectAutogeneration"; +import ProjectItemRelationship from "./IProjectItemRelationship"; +import IProjectItemRelationship from "./IProjectItemRelationship"; export default class ProjectItem { private _data: IProjectItemData; @@ -45,6 +42,9 @@ export default class ProjectItem { private _imageUrlBase64Cache: string | undefined; private _pack: Pack | undefined; + public parentItems: ProjectItemRelationship[] | undefined; + public childItems: ProjectItemRelationship[] | undefined; + constructor(parent: Project, incomingData?: IProjectItemData) { this._project = parent; this._file = null; @@ -65,6 +65,22 @@ export default class ProjectItem { } } + public get parentItemCount() { + if (this.parentItems === undefined) { + return 0; + } + + return this.parentItems.length; + } + + public get childItemCount() { + if (this.childItems === undefined) { + return 0; + } + + return this.childItems.length; + } + public get isInWorld() { return this._data.isInWorld; } @@ -168,6 +184,23 @@ export default class ProjectItem { return undefined; } + addChildItem(childItem: ProjectItem) { + let pir: IProjectItemRelationship = { + parentItem: this, + childItem: childItem, + }; + if (this.childItems === undefined) { + this.childItems = []; + } + + if (childItem.parentItems === undefined) { + childItem.parentItems = []; + } + + this.childItems.push(pir); + childItem.parentItems.push(pir); + } + toString() { return this.itemType + ": " + this.projectPath; } @@ -288,7 +321,7 @@ export default class ProjectItem { return "resource/animations/actor_animation.json"; case ProjectItemType.animationControllerResourceJson: return "resource/animation_controllers/animation_controller.json"; - case ProjectItemType.entityTypeResourceJson: + case ProjectItemType.entityTypeResource: return "resource/entity/entity.json"; case ProjectItemType.fogResourceJson: return "resource/fog/fog.json"; @@ -312,7 +345,7 @@ export default class ProjectItem { return "behavior/functions/tick.json"; case ProjectItemType.recipeBehaviorJson: return "behavior/recipes/recipes.json"; - case ProjectItemType.spawnRuleBehaviorJson: + case ProjectItemType.spawnRuleBehavior: return "behavior/spawn_rules/spawn_rules.json"; case ProjectItemType.tradingBehaviorJson: return "behavior/trading/trading.json"; @@ -424,6 +457,10 @@ export default class ProjectItem { return this._data.creationType; } + set creationType(newCreationType: ProjectItemCreationType | undefined) { + this._data.creationType = newCreationType; + } + get itemType() { return this._data.itemType; } @@ -765,6 +802,14 @@ export default class ProjectItem { return undefined; } + async ensureStorage() { + if (this.storageType === ProjectItemStorageType.folder) { + await this.ensureFolderStorage(); + } else if (this.storageType === ProjectItemStorageType.singleFile) { + await this.ensureFileStorage(); + } + } + async ensureFileStorage() { if ( this.storageType === ProjectItemStorageType.singleFile && @@ -819,12 +864,12 @@ export default class ProjectItem { if (!this._isFileContentProcessed && this._file) { if (this._data.creationType === ProjectItemCreationType.generated) { - await this.updateAutogenerated(true); + await ProjectAutogeneration.updateItemAutogeneration(this, true); } else { await this._file.loadContent(); } - await this.updateAutogeneratedSideFiles(); + await ProjectAutogeneration.updateItemAutogeneratedSideFiles(this); this._isFileContentProcessed = true; @@ -906,11 +951,7 @@ export default class ProjectItem { } else { this._isLoading = true; - if (this.storageType === ProjectItemStorageType.folder) { - await this.ensureFolderStorage(); - } else if (this.storageType === ProjectItemStorageType.singleFile) { - await this.ensureFileStorage(); - } + await this.ensureStorage(); this._isLoading = false; @@ -925,99 +966,11 @@ export default class ProjectItem { } } - async updateAutogenerated(contentOnlyUpdate?: boolean) { - if (!this._isLoading) { - await this.load(); - } - - if (this._file == null || this._data.creationType !== ProjectItemCreationType.generated) { - return; - } - - if (this.itemType === ProjectItemType.catalogIndexJs) { - await this._file.loadContent(); - - this._updateAutogeneratedContent(await this.getCatalogJsContent()); - } else if (this.itemType === ProjectItemType.behaviorPackManifestJson) { - this._file.setContent(await this.getBehaviorPackManifestJsonContent(contentOnlyUpdate)); - } else if (this.itemType === ProjectItemType.entityTypeBaseJs) { - const content = await this.getGeneratedTypeJavaScript(); - - if (content.javaScript !== undefined) { - this._file.setContent(content.javaScript); - } - - if ( - this._project.preferredScriptLanguage === ProjectScriptLanguage.typeScript && - content.typeScript !== undefined - ) { - const file = this._file.parentFolder.ensureFile(StorageUtilities.getBaseFromName(this._file.name) + ".ts"); - - file.setContent(content.typeScript); - } - } else if (this.itemType === ProjectItemType.entityTypeBaseTs) { - const content = await this.getGeneratedTypeJavaScript(); - - if (content.typeScript !== undefined) { - this._file.setContent(content.typeScript); - } - } - } - - async updateAutogeneratedSideFiles() { - if (!this._file || !this._project) { - return; - } - } - - _updateAutogeneratedContent(newContent: string) { - if (this._file == null || this._file.content instanceof Uint8Array) { - Log.unexpectedContentState(); - return; - } - - if (this._file.content === undefined || this._file.content === null || this._file.content.trim() === "") { - this._file.setContent(newContent); - return; - } - - let updatedContent = this._file.content; - - const autogenToken = updatedContent.indexOf(AUTOGENERATED_CONTENT_TOKEN); - - if (autogenToken >= 0) { - let previous = updatedContent.lastIndexOf("\r", autogenToken); - - if (previous < 0) { - previous = updatedContent.lastIndexOf("\n", autogenToken); - - if (previous < 0) { - previous = 0; - } - } - - const previousComment = updatedContent.lastIndexOf("//", autogenToken); - - // we expect \r\n//, but if for some reason the comment has moved, let's only strip from the comment forward. - if (previousComment > previous + 2) { - previous = previousComment; - } - - if (previous >= 0) { - updatedContent = updatedContent.substring(0, previous); - } - } - - updatedContent += newContent; - - this._file.setContent(updatedContent); - } - async prepareToSave() { await this.load(); - await this.updateAutogenerated(); - await this.updateAutogeneratedSideFiles(); + await ProjectAutogeneration.updateItemAutogeneration(this); + await ProjectAutogeneration.updateItemAutogeneratedSideFiles(this); if ( !this.isInFileContainer && @@ -1115,199 +1068,4 @@ export default class ProjectItem { this.tags.push(name); } - - async getGeneratedTypeJavaScript() { - if (this.projectPath === null || this.projectPath === undefined) { - return { javaScript: "", typeScript: undefined }; - } - - let typeName = StorageUtilities.getBaseFromName(StorageUtilities.getLeafName(this.projectPath)); - - if (typeName.endsWith(".base")) { - typeName = typeName.substring(0, typeName.length - 5); - } - - for (let i = 0; i < this._project.items.length; i++) { - const item = this._project.items[i]; - - if ( - item.itemType === ProjectItemType.entityTypeBehaviorJson && - item.projectPath !== null && - item.projectPath !== undefined - ) { - const jsonName = StorageUtilities.getBaseFromName(StorageUtilities.getLeafName(item.projectPath)); - - if (jsonName === typeName) { - const jsonFile = await item.ensureFileStorage(); - - if (jsonFile !== undefined && jsonFile !== null) { - if (jsonFile.manager === undefined) { - await EntityTypeDefinition.ensureOnFile(jsonFile); - } - - if (jsonFile.manager) { - const et = jsonFile.manager as EntityTypeDefinition; - - const js = et.getScript(false); - let ts = undefined; - - if (this._project.preferredScriptLanguage === ProjectScriptLanguage.typeScript) { - ts = et.getScript(true); - } - - return { javaScript: js, typeScript: ts }; - } - } - } - } - } - - return { javaScript: "", typeScript: undefined }; - } - - async getBehaviorPackManifestJsonContent(contentOnlyUpdate?: boolean) { - let versionMajor = 0; - let versionMinor = 0; - let versionPatch = 1; - - if (this._project.versionMajor !== undefined) { - versionMajor = this._project.versionMajor; - } - - if (this._project.versionMinor !== undefined) { - versionMinor = this._project.versionMinor; - } - - if (this._project.versionPatch !== undefined) { - versionPatch = this._project.versionPatch; - } - - const modulesList: IAddonModule[] = []; - const dependenciesList: IAddonDependency[] = []; - let scriptFile = undefined; - let pi = this._project.getFirstItemByType(ProjectItemType.catalogIndexJs); - - if (pi !== undefined) { - scriptFile = pi.file; - } - - const behaviorPackRootFolder = await this._project.getDefaultBehaviorPackFolder(false, contentOnlyUpdate); - - if (scriptFile === undefined) { - pi = this._project.getFirstItemByType(ProjectItemType.js); - if (pi !== undefined) { - scriptFile = pi.file; - } - - if (scriptFile === undefined) { - pi = this._project.getFirstItemByType(ProjectItemType.testJs); - - if (pi !== undefined) { - scriptFile = pi.file; - } - } - } - - const scriptState = await this._project.getScriptState(); - - if (scriptState.hasScript && scriptFile !== null && scriptFile !== undefined && behaviorPackRootFolder !== null) { - let path = scriptFile.getFolderRelativePath(behaviorPackRootFolder); - - if (path !== undefined) { - if (path.startsWith("/")) { - path = path.substring(1, path.length); - } - - modulesList.push({ - description: this._project.title + " script", - language: "javascript", - type: "script", - uuid: this._project.defaultScriptModuleUniqueId, - version: [versionMajor, versionMinor, versionPatch], - entry: path, - }); - - for (let i = 0; i < minecraftScriptModules.length; i++) { - const mod = minecraftScriptModules[i]; - - if (scriptState.hasModule[mod.id]) { - dependenciesList.push({ - uuid: mod.uuid, - module_name: mod.module_name, - version: mod.preferredVersion, - }); - } - } - } - } - - const manifest: IAddonManifest = { - format_version: 2, - __comment__: AUTOGENERATED_WHOLEFILE_GENERAL_SEPARATOR, - header: { - description: this._project.description, - name: this._project.title, - uuid: this._project.defaultBehaviorPackUniqueId, - version: [versionMajor, versionMinor, versionPatch], - min_engine_version: [1, 20, 10], - }, - modules: modulesList, - dependencies: dependenciesList, - }; - - if (this.project.focus === ProjectFocus.editorExtension) { - manifest.capabilities = ["editorExtension"]; - } - - return JSON.stringify(manifest, null, 2); - } - - async getCatalogJsContent() { - const content: string[] = []; - - const behaviorPackRootFolder = await this._project.ensureDefaultBehaviorPackFolder(); - - for (let i = 0; i < this._project.items.length; i++) { - const projectItem = this._project.items[i]; - - if (projectItem.itemType === ProjectItemType.worldTest) { - const file = await projectItem.ensureFileStorage(); - - if (file) { - const newFileName = StorageUtilities.getBaseFromName(file.name) + ".gen.js"; - - content.push('import "scripts/' + newFileName + '";'); - } - } else if ( - projectItem.itemType === ProjectItemType.js || - projectItem.itemType === ProjectItemType.buildProcessedJs || - projectItem.itemType === ProjectItemType.entityTypeBaseJs || - projectItem.itemType === ProjectItemType.testJs - ) { - const file = await projectItem.ensureFileStorage(); - - if (file) { - let filePath = file.getFolderRelativePath(behaviorPackRootFolder); - - if (!file.isContentLoaded) { - await file.loadContent(false); - } - - if ((file.content !== null || filePath !== null) && filePath !== undefined) { - if (filePath.startsWith("/scripts/")) { - filePath = filePath.substring(9, filePath.length); - } - - if (filePath.startsWith("/")) { - filePath = filePath.substring(1, filePath.length); - } - - content.push('import "' + filePath + '";'); - } - } - } - } - - return AUTOGENERATED_JS_SEPARATOR + "\r\n\r\n" + content.join("\r\n"); - } } diff --git a/app/src/app/ProjectItemManager.ts b/app/src/app/ProjectItemManager.ts index 14315c3d..b902ee29 100644 --- a/app/src/app/ProjectItemManager.ts +++ b/app/src/app/ProjectItemManager.ts @@ -10,6 +10,7 @@ import ZipStorage from "../storage/ZipStorage"; import IProjectItemSeed from "./IProjectItemSeed"; import ProjectItemUtilities from "./ProjectItemUtilities"; import IFolder from "../storage/IFolder"; +import ProjectAutogeneration from "./ProjectAutogeneration"; export default class ProjectItemManager { private static async _getDefaultBehaviorPackPath(project: Project) { @@ -96,7 +97,7 @@ export default class ProjectItemManager { } } - await project.updateAutogeneratedItems(); + await ProjectAutogeneration.updateProjectAutogeneration(project); await project.save(); return pi; @@ -412,7 +413,7 @@ export default class ProjectItemManager { file.setContent(content); } - await project.updateAutogeneratedItems(); + await ProjectAutogeneration.updateProjectAutogeneration(project); } static async createNewDocumentedType(project: Project) { @@ -443,7 +444,7 @@ export default class ProjectItemManager { await pi.ensureFolderStorage(); - await project.updateAutogeneratedItems(); + await ProjectAutogeneration.updateProjectAutogeneration(project); await project.save(); } @@ -483,7 +484,7 @@ export default class ProjectItemManager { file.setContent(content); } - await project.updateAutogeneratedItems(); + await ProjectAutogeneration.updateProjectAutogeneration(project); await project.save(); } @@ -525,7 +526,7 @@ export default class ProjectItemManager { file.setContent(content); } - await project.updateAutogeneratedItems(); + await ProjectAutogeneration.updateProjectAutogeneration(project); await project.save(); } diff --git a/app/src/app/ProjectItemRelations.ts b/app/src/app/ProjectItemRelations.ts new file mode 100644 index 00000000..7d97258a --- /dev/null +++ b/app/src/app/ProjectItemRelations.ts @@ -0,0 +1,29 @@ +import EntityTypeDefinition from "../minecraft/EntityTypeDefinition"; +import { ProjectItemType } from "./IProjectItemData"; +import Project from "./Project"; + +export default class ProjectItemRelations { + static async calculate(project: Project) { + const items = project.getItemsCopy(); + + // clear all existing relations + for (const item of items) { + item.childItems = undefined; + item.parentItems = undefined; + } + + for (const item of items) { + if (item.itemType === ProjectItemType.entityTypeBehaviorJson) { + await item.ensureStorage(); + + if (item.file) { + const entityTypeBehavior = await EntityTypeDefinition.ensureOnFile(item.file); + + if (entityTypeBehavior) { + entityTypeBehavior.addChildItems(project, item); + } + } + } + } + } +} diff --git a/app/src/app/ProjectItemUtilities.ts b/app/src/app/ProjectItemUtilities.ts index 7983165a..46fc2fca 100644 --- a/app/src/app/ProjectItemUtilities.ts +++ b/app/src/app/ProjectItemUtilities.ts @@ -59,7 +59,7 @@ export default class ProjectItemUtilities { } else if (firstHundred.indexOf('"pools"') >= 0) { return { itemType: ProjectItemType.itemTypeBehaviorJson }; } else if (firstHundred.indexOf('"minecraft:spawn_rules"') >= 0) { - return { itemType: ProjectItemType.spawnRuleBehaviorJson }; + return { itemType: ProjectItemType.spawnRuleBehavior }; } else if (firstHundred.indexOf('"tiers"') >= 0) { return { itemType: ProjectItemType.tradingBehaviorJson }; } else if (firstHundred.indexOf('"animation_controllers"') >= 0) { @@ -71,7 +71,7 @@ export default class ProjectItemUtilities { } else if (firstHundred.indexOf('"minecraft:attachable"') >= 0) { return { itemType: ProjectItemType.attachableResourceJson, packType: PackType.resource }; } else if (firstHundred.indexOf('"minecraft:client_entity"') >= 0) { - return { itemType: ProjectItemType.entityTypeResourceJson, packType: PackType.resource }; + return { itemType: ProjectItemType.entityTypeResource, packType: PackType.resource }; } else if (firstHundred.indexOf('"minecraft:fog_settings"') >= 0) { return { itemType: ProjectItemType.fogResourceJson, packType: PackType.resource }; } else if (firstHundred.indexOf('"minecraft:geometry"') >= 0) { @@ -193,7 +193,7 @@ export default class ProjectItemUtilities { return ProjectItemCategory.assets; case ProjectItemType.entityTypeBehaviorJson: - case ProjectItemType.entityTypeResourceJson: + case ProjectItemType.entityTypeResource: case ProjectItemType.entityTypeBaseJs: case ProjectItemType.entityTypeBaseTs: case ProjectItemType.blockTypeBehaviorJson: @@ -208,7 +208,7 @@ export default class ProjectItemUtilities { case ProjectItemType.biomeBehaviorJson: case ProjectItemType.biomeResourceJson: case ProjectItemType.lootTableBehaviorJson: - case ProjectItemType.spawnRuleBehaviorJson: + case ProjectItemType.spawnRuleBehavior: case ProjectItemType.dialogueBehaviorJson: case ProjectItemType.MCWorld: case ProjectItemType.worldTemplateManifestJson: @@ -217,7 +217,7 @@ export default class ProjectItemUtilities { case ProjectItemType.featureRuleBehaviorJson: return ProjectItemCategory.types; - case ProjectItemType.esLintMjs: + case ProjectItemType.esLintConfigMjs: case ProjectItemType.env: case ProjectItemType.justConfigTs: case ProjectItemType.packageLockJson: @@ -300,7 +300,7 @@ export default class ProjectItemUtilities { case ProjectItemType.buildProcessedJs: case ProjectItemType.catalogIndexJs: case ProjectItemType.entityTypeBaseTs: - case ProjectItemType.esLintMjs: + case ProjectItemType.esLintConfigMjs: case ProjectItemType.blockTypeBaseJs: return ["application/javascript"]; @@ -331,7 +331,7 @@ export default class ProjectItemUtilities { case ProjectItemType.soundsCatalogResourceJson: case ProjectItemType.animationResourceJson: case ProjectItemType.animationControllerResourceJson: - case ProjectItemType.entityTypeResourceJson: + case ProjectItemType.entityTypeResource: case ProjectItemType.fogResourceJson: case ProjectItemType.modelGeometryJson: case ProjectItemType.particleJson: @@ -345,7 +345,7 @@ export default class ProjectItemUtilities { case ProjectItemType.featureBehaviorJson: case ProjectItemType.functionEventJson: case ProjectItemType.recipeBehaviorJson: - case ProjectItemType.spawnRuleBehaviorJson: + case ProjectItemType.spawnRuleBehavior: case ProjectItemType.tradingBehaviorJson: case ProjectItemType.volumeBehaviorJson: case ProjectItemType.attachableResourceJson: @@ -517,7 +517,7 @@ export default class ProjectItemUtilities { return "Animation"; case ProjectItemType.animationControllerResourceJson: return "Animation controller"; - case ProjectItemType.entityTypeResourceJson: + case ProjectItemType.entityTypeResource: return "Entity type resources"; case ProjectItemType.fogResourceJson: return "Fog"; @@ -545,7 +545,7 @@ export default class ProjectItemUtilities { return "Function event"; case ProjectItemType.recipeBehaviorJson: return "Recipe"; - case ProjectItemType.spawnRuleBehaviorJson: + case ProjectItemType.spawnRuleBehavior: return "Spawn rule"; case ProjectItemType.tradingBehaviorJson: return "Trading"; @@ -583,7 +583,7 @@ export default class ProjectItemUtilities { return "NPM package lock definition"; case ProjectItemType.env: return "Environment File"; - case ProjectItemType.esLintMjs: + case ProjectItemType.esLintConfigMjs: return "ESLint Config"; case ProjectItemType.justConfigTs: return "Just Config"; @@ -707,7 +707,7 @@ export default class ProjectItemUtilities { return "UI global variable sets"; case ProjectItemType.itemTypeResourceJson: return "Item type resource sets"; - case ProjectItemType.entityTypeResourceJson: + case ProjectItemType.entityTypeResource: return "Entity type resource sets"; case ProjectItemType.materialGeometry: return "Geometries"; @@ -752,7 +752,7 @@ export default class ProjectItemUtilities { return defaultBpFolder.ensureFolderFromRelativePath(path[0]); - case ProjectItemType.entityTypeResourceJson: + case ProjectItemType.entityTypeResource: case ProjectItemType.modelGeometryJson: const defaultRpFolder = await project.getDefaultResourcePackFolder(); @@ -834,7 +834,7 @@ export default class ProjectItemUtilities { return ["loot_tables"]; case ProjectItemType.recipeBehaviorJson: return ["recipes"]; - case ProjectItemType.spawnRuleBehaviorJson: + case ProjectItemType.spawnRuleBehavior: return ["spawn_rules"]; case ProjectItemType.particleJson: return ["particles"]; diff --git a/app/src/app/ProjectStandard.ts b/app/src/app/ProjectStandard.ts new file mode 100644 index 00000000..f9e27579 --- /dev/null +++ b/app/src/app/ProjectStandard.ts @@ -0,0 +1,74 @@ +import EslintConfig from "../devproject/EslintConfig"; +import JustConfig from "../devproject/JustConfig"; +import NpmPackageDefinition from "../devproject/NpmPackageDefinition"; +import { ProjectItemCreationType, ProjectItemStorageType, ProjectItemType } from "./IProjectItemData"; +import Project from "./Project"; + +export default class ProjectStandard { + static async ensureIsStandard(project: Project) { + await project.ensureProjectFolder(); + + if (project.projectFolder) { + const justFile = await project.projectFolder.getFileFromRelativePath("/just.config.ts"); + + if (justFile && (await justFile.exists())) { + justFile.setContent(JustConfig.getDefaultContent()); + justFile.saveContent(); + } + + const eslintFile = await project.projectFolder.getFileFromRelativePath("/eslint.config.mjs"); + + if (eslintFile && (await eslintFile.exists())) { + eslintFile.setContent(EslintConfig.getDefaultContent()); + eslintFile.saveContent(); + } + + const packageJson = await project.projectFolder.getFileFromRelativePath("/package.json"); + + if (packageJson && (await packageJson.exists())) { + project.ensureItemByProjectPath( + "/package.json", + ProjectItemStorageType.singleFile, + "package.json", + ProjectItemType.packageJson, + undefined, + ProjectItemCreationType.generated + ); + } + } + + const itemsCopy = project.getItemsCopy(); + for (let i = 0; i < itemsCopy.length; i++) { + const item = itemsCopy[i]; + + if (item.itemType === ProjectItemType.justConfigTs && item.file) { + item.creationType = ProjectItemCreationType.generated; + + const justConfig = await JustConfig.ensureOnFile(item.file); + + if (justConfig) { + justConfig.ensureDefault(); + await justConfig.save(); + } + } else if (item.itemType === ProjectItemType.esLintConfigMjs && item.file) { + item.creationType = ProjectItemCreationType.generated; + + const eslintConfig = await EslintConfig.ensureOnFile(item.file); + + if (eslintConfig) { + eslintConfig.ensureDefault(); + await eslintConfig.save(); + } + } else if (item.itemType === ProjectItemType.packageJson && item.file) { + item.creationType = ProjectItemCreationType.generated; + + const packageJson = await NpmPackageDefinition.ensureOnFile(item.file); + + if (packageJson) { + await packageJson.ensureStandardContent(); + await packageJson.save(); + } + } + } + } +} diff --git a/app/src/app/ProjectUtilities.ts b/app/src/app/ProjectUtilities.ts index 7cf59ba4..45d06e15 100644 --- a/app/src/app/ProjectUtilities.ts +++ b/app/src/app/ProjectUtilities.ts @@ -10,7 +10,7 @@ import Log from "../core/Log"; import Utilities from "../core/Utilities"; import { ProjectEditPreference } from "./IProjectData"; import BehaviorManifestDefinition from "../minecraft/BehaviorManifestDefinition"; -import NpmPackageJson from "../devproject/NpmPackageJson"; +import NpmPackageDefinition from "../devproject/NpmPackageDefinition"; import ResourceManifestDefinition from "../minecraft/ResourceManifestDefinition"; import ISnippet from "./ISnippet"; import IGalleryItem from "./IGalleryItem"; @@ -24,6 +24,8 @@ import HttpStorage from "../storage/HttpStorage"; import CartoApp from "./CartoApp"; import ProjectExporter from "./ProjectExporter"; import ProjectUpdateRunner from "../updates/ProjectUpdateRunner"; +import ProjectStandard from "./ProjectStandard"; +import ProjectAutogeneration from "./ProjectAutogeneration"; export enum NewEntityTypeAddMode { baseId, @@ -186,7 +188,9 @@ export default class ProjectUtilities { project.scriptEntryPoint = newScriptEntryPoint; if (project.editPreference === ProjectEditPreference.summarized && project.defaultBehaviorPackUniqueId) { - for (const projectItem of project.items) { + const itemsCopy = project.getItemsCopy(); + + for (const projectItem of itemsCopy) { if (projectItem.itemType === ProjectItemType.behaviorPackManifestJson) { await projectItem.ensureFileStorage(); @@ -214,12 +218,14 @@ export default class ProjectUtilities { project.description = newDescription; if (project.editPreference === ProjectEditPreference.summarized && project.defaultBehaviorPackUniqueId) { - for (const projectItem of project.items) { + const itemsCopy = project.getItemsCopy(); + + for (const projectItem of itemsCopy) { if (projectItem.itemType === ProjectItemType.packageJson) { await projectItem.ensureFileStorage(); if (projectItem.file) { - const npmPackageJson = await NpmPackageJson.ensureOnFile(projectItem.file); + const npmPackageJson = await NpmPackageDefinition.ensureOnFile(projectItem.file); if (npmPackageJson && npmPackageJson.definition) { npmPackageJson.definition.description = newDescription; @@ -280,9 +286,11 @@ export default class ProjectUtilities { project.title = newTitle; if (project.editPreference === ProjectEditPreference.summarized && project.defaultBehaviorPackUniqueId) { - for (const projectItem of project.items) { + const itemsCopy = project.getItemsCopy(); + + for (const projectItem of itemsCopy) { if (projectItem.file && projectItem.itemType === ProjectItemType.packageJson) { - const npmPackageJson = await NpmPackageJson.ensureOnFile(projectItem.file); + const npmPackageJson = await NpmPackageDefinition.ensureOnFile(projectItem.file); if (npmPackageJson && npmPackageJson.definition) { npmPackageJson.definition.name = newTitle; @@ -328,19 +336,6 @@ export default class ProjectUtilities { } } } - static async ensureStandardFiles(project: Project) { - project.ensureItemByProjectPath( - "/.env", - ProjectItemStorageType.singleFile, - ".env", - ProjectItemType.env, - undefined, - ProjectItemCreationType.normal, - undefined, - undefined, - false - ); - } static async applyBehaviorPackUniqueId(project: Project, newBehaviorPackId: string) { const oldBehaviorPackId = project.defaultBehaviorPackUniqueId; @@ -350,13 +345,15 @@ export default class ProjectUtilities { if (project.editPreference === ProjectEditPreference.summarized && project.defaultBehaviorPackUniqueId) { let bpackCount = 0; - for (const projectItem of project.items) { + const itemsCopy = project.getItemsCopy(); + + for (const projectItem of itemsCopy) { if (projectItem.itemType === ProjectItemType.behaviorPackManifestJson) { bpackCount++; } } - for (const projectItem of project.items) { + for (const projectItem of itemsCopy) { if (projectItem.itemType === ProjectItemType.behaviorPackManifestJson) { await projectItem.ensureFileStorage(); @@ -390,13 +387,15 @@ export default class ProjectUtilities { if (project.editPreference === ProjectEditPreference.summarized && project.defaultResourcePackUniqueId) { let rpackCount = 0; - for (const projectItem of project.items) { + const itemsCopy = project.getItemsCopy(); + + for (const projectItem of itemsCopy) { if (projectItem.itemType === ProjectItemType.resourcePackManifestJson) { rpackCount++; } } - for (const projectItem of project.items) { + for (const projectItem of itemsCopy) { if (projectItem.itemType === ProjectItemType.resourcePackManifestJson) { await projectItem.ensureFileStorage(); @@ -494,12 +493,15 @@ export default class ProjectUtilities { await ProjectExporter.renameDefaultFolders(project, suggestedShortName); } - await this.ensureStandardFiles(project); + await ProjectAutogeneration.updateProjectAutogeneration(project); + await ProjectUtilities.randomizeAllUids(project); await ProjectUtilities.applyTitle(project, title); await ProjectUtilities.applyDescription(project, description); + await ProjectStandard.ensureIsStandard(project); + const pur = new ProjectUpdateRunner(project); await pur.updateProject(); @@ -522,8 +524,10 @@ export default class ProjectUtilities { project.defaultDataUniqueId = Utilities.createUuid(); project.defaultScriptModuleUniqueId = Utilities.createUuid(); - for (let i = 0; i < project.items.length; i++) { - const pi = project.items[i]; + const itemsCopy = project.getItemsCopy(); + + for (let i = 0; i < itemsCopy.length; i++) { + const pi = itemsCopy[i]; if (pi.file) { if (pi.itemType === ProjectItemType.behaviorPackManifestJson && !setBehaviorPack) { @@ -573,8 +577,8 @@ export default class ProjectUtilities { await project.inferProjectItemsFromFiles(true); - /* - const defaultScriptsPath = await ProjectUtilities.getBaseScriptsPath(project); + /* const defaultScriptsPath = await ProjectUtilities.getBaseScriptsPath(project); + if (project.preferredScriptLanguage === ProjectScriptLanguage.javaScript) { const candidateJsFilePath = await ProjectUtilities.getFileName( project, @@ -594,7 +598,7 @@ export default class ProjectUtilities { ProjectItemCreationType.generated ); - piGenJs.updateAutogenerated(); + await ProjectAutogeneration.updateItemAutogeneration(piGenJs); } } else if (project.preferredScriptLanguage === ProjectScriptLanguage.typeScript) { const candidateJsFilePath = await ProjectUtilities.getFileName( @@ -615,7 +619,7 @@ export default class ProjectUtilities { ProjectItemCreationType.generated ); - piGenJs.updateAutogenerated(); + await ProjectAutogeneration.updateItemAutogeneration(piGenJs); } }*/ @@ -728,7 +732,6 @@ export default class ProjectUtilities { Log.debugAlert("Could not find file '" + subPath + "'"); } else { const targetFile = await targetBpFolder.ensureFileFromRelativePath(targetPath); - let update = true; if (dontOverwriteExistingFiles) { @@ -781,7 +784,6 @@ export default class ProjectUtilities { Log.debugAlert("Could not find file '" + subPath + "'"); } else { const targetFile = await targetRpFolder.ensureFileFromRelativePath(targetPath); - let update = true; if (update) { @@ -792,6 +794,7 @@ export default class ProjectUtilities { update = false; } } + await sourceFile.loadContent(); let content = sourceFile.content; @@ -834,6 +837,7 @@ export default class ProjectUtilities { // accomodate minecraft:suffocate content = Utilities.replaceAll(content, "suffo" + newName + "e", "suffo" + entityTypeProject.id + "e"); + content = Utilities.replaceAll(content, newName + "egory", "category"); return content; } @@ -896,6 +900,9 @@ export default class ProjectUtilities { "DisplaySlotId", "ObjectiveSortOrder", "TripWireAfterEvent", + "BlockComponentTypes", + "EntityComponentTypes", + "ItemComponentTypes", "LeverActionAfterEvent", "Vector3", ], @@ -1193,7 +1200,7 @@ export default class ProjectUtilities { ProjectItemCreationType.generated ); - piGenJs.updateAutogenerated(); + await ProjectAutogeneration.updateItemAutogeneration(piGenJs); } } else if (project.preferredScriptLanguage === ProjectScriptLanguage.typeScript) { const candidateJsFilePath = await ProjectUtilities.getFileName( @@ -1214,7 +1221,7 @@ export default class ProjectUtilities { ProjectItemCreationType.normal ); - piGenJs.updateAutogenerated(); + await ProjectAutogeneration.updateItemAutogeneration(piGenJs); } }*/ } diff --git a/app/src/dataform/DataForm.css b/app/src/dataform/DataForm.css index bdf73588..c5208fd0 100644 --- a/app/src/dataform/DataForm.css +++ b/app/src/dataform/DataForm.css @@ -63,7 +63,6 @@ margin-left: 1px; margin-top: 6px; margin-bottom: 2px; - padding-left: 90px; } .df-fieldTitle { @@ -82,9 +81,13 @@ .df-fieldWrap .ui-form__label { padding-bottom: 4px; vertical-align: bottom; - padding-right: 4px; + padding-right: 14px; display: inline-block !important; - min-width: 90px; + min-width: 136px; +} + +.df-fieldWrap input { + max-width: 136px; } .df-fieldWrap .ui-dropdown { diff --git a/app/src/dataform/DataForm.tsx b/app/src/dataform/DataForm.tsx index 0306f092..aaa2884d 100644 --- a/app/src/dataform/DataForm.tsx +++ b/app/src/dataform/DataForm.tsx @@ -1355,6 +1355,8 @@ export default class DataForm extends Component this.formComponents.push(headerElement); fieldTopper.push(headerElement); + fieldTopper.push(descriptionElement); + const toolbarItems = []; toolbarItems.push({ @@ -1447,8 +1449,17 @@ export default class DataForm extends Component } } else { for (const index in arrayOfDataVal) { + let visualIndex = 0; let title = index; + try { + visualIndex = parseInt(index); + } catch (e) {} + + if (!isNaN(visualIndex)) { + title = String(visualIndex + 1); + } + let objKey = field.id; if (this.props.objectKey) { @@ -1480,9 +1491,7 @@ export default class DataForm extends Component if (val) { title = val; } - } - - if (field.objectArrayToSubFieldKey) { + } else if (field.objectArrayToSubFieldKey) { const val = obj[field.objectArrayToSubFieldKey]; if (field.subFields && val) { @@ -1492,6 +1501,8 @@ export default class DataForm extends Component title = subField.title; } } + } else if (field.noun) { + title = field.noun + " " + title; } const subForm = ( @@ -1522,7 +1533,6 @@ export default class DataForm extends Component formInterior.push(
{fieldTopper} - {descriptionElement} {fieldInterior}
); diff --git a/app/src/dataform/IField.ts b/app/src/dataform/IField.ts index 3c491b77..40efde15 100644 --- a/app/src/dataform/IField.ts +++ b/app/src/dataform/IField.ts @@ -64,6 +64,7 @@ export default interface IField { lookupId?: string; maxLength?: number; newItemPrototype?: any; + noun?: string; allowCreateDelete?: boolean; readOnly?: boolean; forceString?: boolean; diff --git a/app/src/dataform/StringArray.css b/app/src/dataform/StringArray.css index 704cd571..467acf40 100644 --- a/app/src/dataform/StringArray.css +++ b/app/src/dataform/StringArray.css @@ -6,7 +6,8 @@ .sarr-add BUTTON { padding-left: 3px; padding-right: 3px; - margin-left: 200px; + margin-top: 4px; + margin-bottom: 6px; min-width: 30px; width: 30px; } @@ -27,6 +28,7 @@ padding-left: 6px !important; padding-right: 6px !important; min-width: 500px; + margin-bottom: 2px; } .sarr-none { diff --git a/app/src/devproject/EnvFile.ts b/app/src/devproject/EnvFile.ts deleted file mode 100644 index 8814fc8e..00000000 --- a/app/src/devproject/EnvFile.ts +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import IFile from "../storage/IFile"; -import { EventDispatcher, IEventHandler } from "ste-events"; -import Project from "../app/Project"; - -export default class EnvFile { - private _file?: IFile; - private _id?: string; - private _isLoaded: boolean = false; - - private _onLoaded = new EventDispatcher(); - - public project: Project | undefined = undefined; - - public get isLoaded() { - return this._isLoaded; - } - - public get file() { - return this._file; - } - - public set file(newFile: IFile | undefined) { - this._file = newFile; - } - - public get onLoaded() { - return this._onLoaded.asEvent(); - } - - public get id() { - return this._id; - } - - public set id(newId: string | undefined) { - this._id = newId; - } - - static async ensureOnFile(file: IFile, loadHandler?: IEventHandler) { - let envf: EnvFile | undefined; - - if (file.manager === undefined) { - envf = new EnvFile(); - - envf.file = file; - - file.manager = envf; - } - - if (file.manager !== undefined && file.manager instanceof EnvFile) { - envf = file.manager as EnvFile; - - if (!envf.isLoaded && loadHandler) { - envf.onLoaded.subscribe(loadHandler); - } - - await envf.load(); - - return envf; - } - - return envf; - } - - async ensureEnvFile(project: Project) { - if (this._file === undefined) { - return; - } - - await this.load(); - - let content = this._file?.content; - - if (content === null) { - content = ""; - } - - const folder = await project.getDefaultBehaviorPackFolder(); - - if (folder) { - if (content && typeof content === "string") { - let projectNameIndex = content.indexOf('PROJECT_NAME="'); - - if (projectNameIndex >= 0) { - let projectNameNewQuote = content.indexOf('"', 14); - - if (projectNameNewQuote > projectNameIndex) { - } - } else { - if (!content.endsWith("\n")) { - content += "\r\n"; - } - - content = content + 'PROJECT_NAME="' + folder.name + '"\r\n'; - } - - let minecraftProductIndex = content.indexOf('MINECRAFT_PRODUCT="'); - - if (minecraftProductIndex < 0) { - if (!content.endsWith("\n")) { - content += "\r\n"; - } - - content = content + 'MINECRAFT_PRODUCT="BedrockUWP"\r\n'; - } - } - } - } - - async persist() { - if (this._file === undefined) { - return; - } - } - - async save() { - if (this._file === undefined) { - return; - } - - await this._file.saveContent(false); - } - - async load() { - if (this._file === undefined || this._isLoaded) { - return; - } - - await this._file.loadContent(true); - - if (this._file.content === null || this._file.content instanceof Uint8Array) { - return; - } - - this._isLoaded = true; - } -} diff --git a/app/src/devproject/EnvSettings.ts b/app/src/devproject/EnvSettings.ts new file mode 100644 index 00000000..3dbf993f --- /dev/null +++ b/app/src/devproject/EnvSettings.ts @@ -0,0 +1,170 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import IFile from "../storage/IFile"; +import { EventDispatcher, IEventHandler } from "ste-events"; +import Project from "../app/Project"; +import { MinecraftTrack } from "../app/ICartoData"; + +export default class EnvSettings { + private _file?: IFile; + private _id?: string; + private _isLoaded: boolean = false; + + private _onLoaded = new EventDispatcher(); + + public project: Project | undefined = undefined; + + public get isLoaded() { + return this._isLoaded; + } + + public get file() { + return this._file; + } + + public set file(newFile: IFile | undefined) { + this._file = newFile; + } + + public get onLoaded() { + return this._onLoaded.asEvent(); + } + + public get id() { + return this._id; + } + + public set id(newId: string | undefined) { + this._id = newId; + } + + static async ensureOnFile(file: IFile, loadHandler?: IEventHandler) { + let envf: EnvSettings | undefined; + + if (file.manager === undefined) { + envf = new EnvSettings(); + + envf.file = file; + + file.manager = envf; + } + + if (file.manager !== undefined && file.manager instanceof EnvSettings) { + envf = file.manager as EnvSettings; + + if (!envf.isLoaded && loadHandler) { + envf.onLoaded.subscribe(loadHandler); + } + + await envf.load(); + + return envf; + } + + return envf; + } + + async ensureEnvFile(project: Project) { + if (this._file === undefined) { + return; + } + + await this.load(); + + let content = this._file?.content; + + if (content === null) { + content = ""; + } + + if (content && typeof content === "string") { + } + } + + async persist() { + if (this._file === undefined) { + return; + } + } + + async save() { + if (this._file === undefined) { + return; + } + + if (this._file.isContentLoaded && this.project && this._file.content && typeof this._file.content === "string") { + this._file.setContent(await EnvSettings.getContent(this.project, this._file.content)); + } + + await this._file.saveContent(false); + } + + async load() { + if (this._file === undefined || this._isLoaded) { + return; + } + + await this._file.loadContent(true); + + if (this._file.content === null || this._file.content instanceof Uint8Array) { + return; + } + + this._isLoaded = true; + } + + static async getContent(project: Project, content?: string) { + if (content === undefined) { + content = 'PROJECT_NAME=""\r\nMINECRAFT_PRODUCT="BedrockUWP"\r\nCUSTOM_DEPLOYMENT_PATH=""\r\n'; + } + + const folder = await project.getDefaultBehaviorPackFolder(); + + if (folder) { + let projectNameIndex = content.indexOf('PROJECT_NAME="'); + + if (projectNameIndex >= 0) { + let projectNameNewQuote = content.indexOf('"', projectNameIndex + 14); + + if (projectNameNewQuote > projectNameIndex) { + content = + content.substring(0, projectNameIndex) + + 'PROJECT_NAME="' + + folder.name + + "" + + content.substring(projectNameNewQuote); + } + } else { + if (!content.endsWith("\n")) { + content += "\r\n"; + } + + content = content + 'PROJECT_NAME="' + folder.name + '"\r\n'; + } + } + + let minecraftProductIndex = content.indexOf('MINECRAFT_PRODUCT="'); + const trackStr = project.track === MinecraftTrack.preview ? "PreviewURP" : "BedrockUWP"; + + if (minecraftProductIndex >= 0) { + let minecraftProductIndexNextQuote = content.indexOf('"', minecraftProductIndex + 19); + + if (minecraftProductIndexNextQuote > minecraftProductIndex) { + content = + content.substring(0, minecraftProductIndex) + + 'MINECRAFT_PRODUCT="' + + trackStr + + content.substring(minecraftProductIndexNextQuote); + } + } else { + if (!content.endsWith("\n")) { + content += "\r\n"; + } + + content = content + 'MINECRAFT_PRODUCT="' + trackStr + '"\r\n'; + } + + return content; + } +} diff --git a/app/src/devproject/EslintConfig.ts b/app/src/devproject/EslintConfig.ts new file mode 100644 index 00000000..e9ce5d58 --- /dev/null +++ b/app/src/devproject/EslintConfig.ts @@ -0,0 +1,138 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import IFile from "../storage/IFile"; +import { EventDispatcher, IEventHandler } from "ste-events"; +import Project from "../app/Project"; + +const EslintDefaultConfig = [ + "import minecraftLinting from 'eslint-plugin-minecraft-linting';", + "import tsParser from '@typescript-eslint/parser';", + "import ts from '@typescript-eslint/eslint-plugin';", + "export default [", + " {", + " files: ['scripts/**/*.ts'],", + " languageOptions: {", + " parser: tsParser,", + " ecmaVersion: 'latest',", + " },", + " plugins: {", + " ts,", + " 'minecraft-linting': minecraftLinting,", + " },", + " rules: {", + " 'minecraft-linting/avoid-unnecessary-command': 'error',", + " },", + " },", + "];", +]; + +export default class EslintConfig { + private _file?: IFile; + private _id?: string; + private _isLoaded: boolean = false; + + private _onLoaded = new EventDispatcher(); + + public project: Project | undefined = undefined; + + public get isLoaded() { + return this._isLoaded; + } + + public get file() { + return this._file; + } + + public set file(newFile: IFile | undefined) { + this._file = newFile; + } + + public get onLoaded() { + return this._onLoaded.asEvent(); + } + + public get id() { + return this._id; + } + + public set id(newId: string | undefined) { + this._id = newId; + } + + static async ensureOnFile(file: IFile, loadHandler?: IEventHandler) { + let justf: EslintConfig | undefined; + + if (file.manager === undefined) { + justf = new EslintConfig(); + + justf.file = file; + + file.manager = justf; + } + + if (file.manager !== undefined && file.manager instanceof EslintConfig) { + justf = file.manager as EslintConfig; + + if (!justf.isLoaded && loadHandler) { + justf.onLoaded.subscribe(loadHandler); + } + + await justf.load(); + + return justf; + } + + return justf; + } + + async ensureDefault() { + if (this._file === undefined) { + return; + } + + await this.load(); + + this._file.setContent(EslintConfig.getDefaultContent()); + } + + async ensureMin() { + if (this._file === undefined) { + return; + } + + await this.load(); + + if (!this._file.content || typeof this._file.content !== "string") { + this._file.setContent(EslintConfig.getDefaultContent()); + } + } + + async persist() {} + + async save() { + if (this._file === undefined) { + return; + } + + await this._file.saveContent(false); + } + + async load() { + if (this._file === undefined || this._isLoaded) { + return; + } + + await this._file.loadContent(true); + + if (this._file.content === null || this._file.content instanceof Uint8Array) { + return; + } + + this._isLoaded = true; + } + + static getDefaultContent() { + return EslintDefaultConfig.join("\r\n").replace(/'/gi, '"'); + } +} diff --git a/app/src/devproject/IVsCodeExtensions.ts b/app/src/devproject/IVsCodeExtensions.ts new file mode 100644 index 00000000..0e9c3d50 --- /dev/null +++ b/app/src/devproject/IVsCodeExtensions.ts @@ -0,0 +1,6 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +export interface IVsCodeExtensions { + recommendations?: string[]; +} diff --git a/app/src/devproject/JustConfig.ts b/app/src/devproject/JustConfig.ts new file mode 100644 index 00000000..7860a3ff --- /dev/null +++ b/app/src/devproject/JustConfig.ts @@ -0,0 +1,174 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import IFile from "../storage/IFile"; +import { EventDispatcher, IEventHandler } from "ste-events"; +import Project from "../app/Project"; + +const JustDefaultConfig = [ + "import { argv, parallel, series, task, tscTask } from 'just-scripts';", + "import {", + " BundleTaskParameters,", + " CopyTaskParameters,", + " bundleTask,", + " cleanTask,", + " cleanCollateralTask,", + " copyTask,", + " coreLint,", + " mcaddonTask,", + " setupEnvironment,", + " ZipTaskParameters,", + " STANDARD_CLEAN_PATHS,", + " DEFAULT_CLEAN_DIRECTORIES,", + " getOrThrowFromProcess,", + " watchTask,", + "} from '@minecraft/core-build-tasks';", + "import path from 'path';", + "setupEnvironment(path.resolve(__dirname, '.env'));", + "const projectName = getOrThrowFromProcess('PROJECT_NAME');", + "const bundleTaskOptions: BundleTaskParameters = {", + " entryPoint: path.join(__dirname, './scripts/main.ts'),", + " external: ['@minecraft/server', '@minecraft/server-ui'],", + " outfile: path.resolve(__dirname, './dist/scripts/main.js'),", + " minifyWhitespace: false,", + " sourcemap: true,", + " outputSourcemapPath: path.resolve(__dirname, './dist/debug'),", + "};", + "const copyTaskOptions: CopyTaskParameters = {", + " copyToBehaviorPacks: [`./behavior_packs/$_{projectName}`],", + " copyToScripts: ['./dist/scripts'],", + " copyToResourcePacks: [`./resource_packs/$_{projectName}`],", + "};", + "const mcaddonTaskOptions: ZipTaskParameters = {", + " ...copyTaskOptions,", + " outputFile: `./dist/packages/$_{projectName}.mcaddon`,", + "};", + "task('lint', coreLint(['scripts/**/*.ts'], argv().fix));", + "task('typescript', tscTask());", + "task('bundle', bundleTask(bundleTaskOptions));", + "task('build', series('typescript', 'bundle'));", + "task('clean-local', cleanTask(DEFAULT_CLEAN_DIRECTORIES));", + "task('clean-collateral', cleanCollateralTask(STANDARD_CLEAN_PATHS));", + "task('clean', parallel('clean-local', 'clean-collateral'));", + "task('copyArtifacts', copyTask(copyTaskOptions));", + "task('package', series('clean-collateral', 'copyArtifacts'));", + "task(", + " 'local-deploy',", + " watchTask(", + " ['scripts/**/*.ts', 'behavior_packs/**/*.{json,lang,tga,ogg,png}', 'resource_packs/**/*.{json,lang,tga,ogg,png}'],", + " series('clean-local', 'build', 'package')", + " )", + ");", + "task('createMcaddonFile', mcaddonTask(mcaddonTaskOptions));", + "task('mcaddon', series('clean-local', 'build', 'createMcaddonFile'));", +]; + +export default class JustConfig { + private _file?: IFile; + private _id?: string; + private _isLoaded: boolean = false; + + private _onLoaded = new EventDispatcher(); + + public project: Project | undefined = undefined; + + public get isLoaded() { + return this._isLoaded; + } + + public get file() { + return this._file; + } + + public set file(newFile: IFile | undefined) { + this._file = newFile; + } + + public get onLoaded() { + return this._onLoaded.asEvent(); + } + + public get id() { + return this._id; + } + + public set id(newId: string | undefined) { + this._id = newId; + } + + static async ensureOnFile(file: IFile, loadHandler?: IEventHandler) { + let justf: JustConfig | undefined; + + if (file.manager === undefined) { + justf = new JustConfig(); + + justf.file = file; + + file.manager = justf; + } + + if (file.manager !== undefined && file.manager instanceof JustConfig) { + justf = file.manager as JustConfig; + + if (!justf.isLoaded && loadHandler) { + justf.onLoaded.subscribe(loadHandler); + } + + await justf.load(); + + return justf; + } + + return justf; + } + + async ensureDefault() { + if (this._file === undefined) { + return; + } + + await this.load(); + + this._file.setContent(JustConfig.getDefaultContent()); + } + + async ensureMin() { + if (this._file === undefined) { + return; + } + + await this.load(); + + if (!this._file.content || typeof this._file.content !== "string") { + this._file.setContent(JustConfig.getDefaultContent()); + } + } + + async persist() {} + + async save() { + if (this._file === undefined) { + return; + } + + await this._file.saveContent(false); + } + + async load() { + if (this._file === undefined || this._isLoaded) { + return; + } + + await this._file.loadContent(true); + + if (this._file.content === null || this._file.content instanceof Uint8Array) { + return; + } + + this._isLoaded = true; + } + + static getDefaultContent() { + return JustDefaultConfig.join("\r\n").replace(/'/gi, '"').replace(/\$_{/gi, "${"); + } +} diff --git a/app/src/devproject/NpmPackageDefinition.ts b/app/src/devproject/NpmPackageDefinition.ts new file mode 100644 index 00000000..f9a745af --- /dev/null +++ b/app/src/devproject/NpmPackageDefinition.ts @@ -0,0 +1,263 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import IFile from "../storage/IFile"; +import { EventDispatcher, IEventHandler } from "ste-events"; +import { Dependencies, NpmScripts, PackageJson } from "@npm/types"; +import StorageUtilities from "../storage/StorageUtilities"; +import Log from "../core/Log"; + +export const DevDependenciesDefault: Dependencies = { + "@minecraft/core-build-tasks": "^1.1.3", + "eslint-plugin-minecraft-linting": "^1.2.2", + "source-map": "^0.7.4", + "ts-node": "^10.9.1", + typescript: "^5.5.4", +}; + +export const ScriptsDefault: NpmScripts = { + lint: "just-scripts lint", + build: "just-scripts build", + clean: "just-scripts clean", + "local-deploy": "just-scripts local-deploy", + mcaddon: "just-scripts mcaddon", + enablemcloopback: + "CheckNetIsolation.exe LoopbackExempt -a -p=S-1-15-2-1958404141-86561845-1752920682-3514627264-368642714-62675701-733520436", + enablemcpreviewloopback: + "CheckNetIsolation.exe LoopbackExempt -a -p=S-1-15-2-424268864-5579737-879501358-346833251-474568803-887069379-4040235476", +}; + +export const DependenciesDefault: Dependencies = { + "@minecraft/math": "^1.4.0", + "@minecraft/server": "^1.13.0", + "@minecraft/server-ui": "^1.2.0", + "@minecraft/vanilla-data": "^1.21.20", +}; + +export const OverridesDefault: { [name: string]: any } = { + "@minecraft/math": { + "@minecraft/server": "$@minecraft/server", + }, + "@minecraft/server-gametest": { + "@minecraft/server": "$@minecraft/server", + }, + "@minecraft/server-ui": { + "@minecraft/server": "$@minecraft/server", + }, +}; + +export const NpmPackageSettingAllowList = [ + "name", + "author", + "dependencies", + "devDependencies", + "contributors", + "license", + "overrides", + "version", + "productName", + "description", + "private", + "scripts", +]; + +export default class NpmPackageDefinition { + private _file?: IFile; + private _id?: string; + private _isLoaded: boolean = false; + + public definition?: PackageJson; + + private _onLoaded = new EventDispatcher(); + + public get isLoaded() { + return this._isLoaded; + } + + public get file() { + return this._file; + } + + public set file(newFile: IFile | undefined) { + this._file = newFile; + } + + public get onLoaded() { + return this._onLoaded.asEvent(); + } + + public get description() { + if (!this.definition) { + return undefined; + } + + return this.definition.description; + } + + public get name() { + if (this.definition) { + return this.definition.name; + } + + return undefined; + } + + public get id() { + return this._id; + } + + public set id(newId: string | undefined) { + this._id = newId; + } + + static async ensureOnFile(file: IFile, loadHandler?: IEventHandler) { + let dt: NpmPackageDefinition | undefined; + + if (file.manager === undefined) { + dt = new NpmPackageDefinition(); + + dt.file = file; + + file.manager = dt; + } + + if (file.manager !== undefined && file.manager instanceof NpmPackageDefinition) { + dt = file.manager as NpmPackageDefinition; + + if (!dt.isLoaded && loadHandler) { + dt.onLoaded.subscribe(loadHandler); + } + + await dt.load(); + + return dt; + } + + return dt; + } + + async persist() { + if (this._file === undefined) { + return; + } + + const pjString = JSON.stringify(this.definition, null, 2); + + this._file.setContent(pjString); + } + + async save() { + if (this._file === undefined) { + return; + } + + this.persist(); + + await this._file.saveContent(false); + } + + async ensureStandardContent() { + await this.load(); + + if (!this.definition) { + return; + } + + if (this.definition.devDependencies) { + let isValidDevDependencies = true; + + for (const devDepend in this.definition.devDependencies) { + if (DevDependenciesDefault[devDepend] === undefined) { + Log.debugAlert("Unexpected dev dependency '" + devDepend + "' found."); + isValidDevDependencies = false; + } + } + + if (!isValidDevDependencies) { + this.definition.devDependencies = DevDependenciesDefault; + } + } + + if (this.definition.dependencies) { + let isValidDependencies = true; + + for (const dependencyName in this.definition.dependencies) { + if (DependenciesDefault[dependencyName] === undefined) { + Log.debugAlert("Unexpected dependency '" + dependencyName + "' found."); + isValidDependencies = false; + } + } + + if (!isValidDependencies) { + this.definition.dependencies = DependenciesDefault; + } + } + + if ((this.definition as any).overrides) { + const overrides: { [name: string]: any } = (this.definition as any).overrides; + + let isOverrideValid = true; + + for (const overrideName in overrides) { + if (OverridesDefault[overrideName] === undefined) { + Log.debugAlert("Unexpected override '" + overrideName + "' found."); + isOverrideValid = false; + } else if (JSON.stringify(OverridesDefault[overrideName]) !== JSON.stringify(overrides[overrideName])) { + Log.debugAlert( + "Unexpected override '" + + overrideName + + "' is not in exepected form: " + + JSON.stringify(overrides[overrideName]) + ); + isOverrideValid = false; + } + } + + if (!isOverrideValid) { + (this.definition as any).overrides = OverridesDefault; + } + } + if (this.definition.scripts) { + let isValidScripts = true; + + for (const scriptName in this.definition.scripts) { + if (ScriptsDefault[scriptName] === undefined) { + Log.debugAlert("Unexpected script '" + scriptName + "' found."); + isValidScripts = false; + } else if (this.definition.scripts[scriptName] !== ScriptsDefault[scriptName]) { + Log.debugAlert("Script '" + scriptName + "' is in unexpected form: " + this.definition.scripts[scriptName]); + isValidScripts = false; + } + } + + if (!isValidScripts) { + this.definition.scripts = ScriptsDefault; + } + } + + for (const key in this.definition) { + if (!NpmPackageSettingAllowList.includes(key)) { + (this.definition as any)[key] = undefined; + Log.debugAlert("Unexpected setting '" + key + "' found in package.json."); + } + } + } + + async load() { + if (this._file === undefined || this._isLoaded) { + return; + } + + await this._file.loadContent(); + + if (this._file.content === null || this._file.content instanceof Uint8Array) { + return; + } + + this.id = this._file.name; + + this.definition = StorageUtilities.getJsonObject(this._file); + + this._isLoaded = true; + } +} diff --git a/app/src/devproject/NpmPackageJson.ts b/app/src/devproject/NpmPackageJson.ts deleted file mode 100644 index 3f460399..00000000 --- a/app/src/devproject/NpmPackageJson.ts +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT License. - -import IFile from "../storage/IFile"; -import { EventDispatcher, IEventHandler } from "ste-events"; -import { PackageJson } from "@npm/types"; -import StorageUtilities from "../storage/StorageUtilities"; - -export default class NpmPackageJson { - private _file?: IFile; - private _id?: string; - private _version?: string; - private _isLoaded: boolean = false; - - public definition?: PackageJson; - - private _onLoaded = new EventDispatcher(); - - public get isLoaded() { - return this._isLoaded; - } - - public get file() { - return this._file; - } - - public set file(newFile: IFile | undefined) { - this._file = newFile; - } - - public get onLoaded() { - return this._onLoaded.asEvent(); - } - - public get description() { - if (!this.definition) { - return undefined; - } - - return this.definition.description; - } - - public get name() { - if (this.definition) { - return this.definition.name; - } - - return undefined; - } - - public get id() { - return this._id; - } - - public set id(newId: string | undefined) { - this._id = newId; - } - - static async ensureOnFile(file: IFile, loadHandler?: IEventHandler) { - let dt: NpmPackageJson | undefined; - - if (file.manager === undefined) { - dt = new NpmPackageJson(); - - dt.file = file; - - file.manager = dt; - } - - if (file.manager !== undefined && file.manager instanceof NpmPackageJson) { - dt = file.manager as NpmPackageJson; - - if (!dt.isLoaded && loadHandler) { - dt.onLoaded.subscribe(loadHandler); - } - - await dt.load(); - - return dt; - } - - return dt; - } - - async persist() { - if (this._file === undefined) { - return; - } - - const pjString = JSON.stringify(this.definition, null, 2); - - this._file.setContent(pjString); - } - - async save() { - if (this._file === undefined) { - return; - } - - this.persist(); - - await this._file.saveContent(false); - } - - async load() { - if (this._file === undefined || this._isLoaded) { - return; - } - - await this._file.loadContent(); - - if (this._file.content === null || this._file.content instanceof Uint8Array) { - return; - } - - this.id = this._file.name; - - this.definition = StorageUtilities.getJsonObject(this._file); - - this._isLoaded = true; - } -} diff --git a/app/src/devproject/PrettierRcConfig.ts b/app/src/devproject/PrettierRcConfig.ts new file mode 100644 index 00000000..55f86b73 --- /dev/null +++ b/app/src/devproject/PrettierRcConfig.ts @@ -0,0 +1,157 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import IFile from "../storage/IFile"; +import Log from "../core/Log"; +import { EventDispatcher, IEventHandler } from "ste-events"; + +export const PrettierRcDefaultSettings: { [name: string]: any } = { + trailingComma: "es5", + tabWidth: 2, + semi: true, + singleQuote: false, + bracketSpacing: true, + arrowParens: "always", + printWidth: 120, + endOfLine: "auto", +}; + +export default class PrettierRcConfig { + private _file?: IFile; + private _id?: string; + private _isLoaded: boolean = false; + + public definition?: { [name: string]: any }; + + private _onLoaded = new EventDispatcher(); + + public get isLoaded() { + return this._isLoaded; + } + + public get file() { + return this._file; + } + + public set file(newFile: IFile | undefined) { + this._file = newFile; + } + + public get onLoaded() { + return this._onLoaded.asEvent(); + } + + public get id() { + return this._id; + } + + public set id(newId: string | undefined) { + this._id = newId; + } + + static async ensureOnFile(file: IFile, loadHandler?: IEventHandler) { + let dt: PrettierRcConfig | undefined; + + if (file.manager === undefined) { + dt = new PrettierRcConfig(); + + dt.file = file; + + file.manager = dt; + } + + if (file.manager !== undefined && file.manager instanceof PrettierRcConfig) { + dt = file.manager as PrettierRcConfig; + + if (!dt.isLoaded && loadHandler) { + dt.onLoaded.subscribe(loadHandler); + } + + await dt.load(); + + return dt; + } + + return dt; + } + + async persist() { + if (this._file === undefined) { + return; + } + + const prettierRcJsonString = JSON.stringify(this.definition, null, 2); + + this._file.setContent(prettierRcJsonString); + } + + async save() { + if (this._file === undefined) { + return; + } + + this.persist(); + + await this._file.saveContent(false); + } + + async hasMinContent() { + await this.load(); + + if (!this.definition) { + return false; + } + + for (const settingName in PrettierRcDefaultSettings) { + if (!this.definition[settingName]) { + return false; + } + } + + return true; + } + + async ensureMinContent() { + const hasSettings = await this.hasMinContent(); + + if (hasSettings) { + return true; + } + + if (!this.definition) { + this.definition = PrettierRcDefaultSettings; + } + + for (const settingName in PrettierRcDefaultSettings) { + if (!this.definition[settingName]) { + this.definition[settingName] = PrettierRcDefaultSettings[settingName]; + } + } + + return this.definition; + } + + async load() { + if (this._file === undefined || this._isLoaded) { + return; + } + + await this._file.loadContent(); + + if (this._file.content === null || this._file.content instanceof Uint8Array) { + return; + } + + this.id = this._file.name; + + try { + const data: any = JSON.parse(this._file.content); + + this.definition = data; + } catch (e) { + Log.fail("Could not parse vscode launch JSON " + e); + } + + this._isLoaded = true; + } +} diff --git a/app/src/devproject/VsCodeExtensionsDefinition.ts b/app/src/devproject/VsCodeExtensionsDefinition.ts new file mode 100644 index 00000000..3aa7199c --- /dev/null +++ b/app/src/devproject/VsCodeExtensionsDefinition.ts @@ -0,0 +1,160 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import IFile from "../storage/IFile"; +import Log from "../core/Log"; +import { EventDispatcher, IEventHandler } from "ste-events"; +import { IVsCodeExtensions } from "./IVsCodeExtensions"; + +export const VsCodeRecommendations = [ + "esbenp.prettier-vscode", + "blockceptionltd.blockceptionvscodeminecraftbedrockdevelopmentextension", + "mojang-studios.minecraft-debugger", +]; + +export default class VsCodeExtensionsDefinition { + private _file?: IFile; + private _id?: string; + private _isLoaded: boolean = false; + + public definition?: IVsCodeExtensions; + + private _onLoaded = new EventDispatcher(); + + public get isLoaded() { + return this._isLoaded; + } + + public get file() { + return this._file; + } + + public set file(newFile: IFile | undefined) { + this._file = newFile; + } + + public get onLoaded() { + return this._onLoaded.asEvent(); + } + + public get id() { + return this._id; + } + + public set id(newId: string | undefined) { + this._id = newId; + } + + static async ensureOnFile( + file: IFile, + loadHandler?: IEventHandler + ) { + let dt: VsCodeExtensionsDefinition | undefined; + + if (file.manager === undefined) { + dt = new VsCodeExtensionsDefinition(); + + dt.file = file; + + file.manager = dt; + } + + if (file.manager !== undefined && file.manager instanceof VsCodeExtensionsDefinition) { + dt = file.manager as VsCodeExtensionsDefinition; + + if (!dt.isLoaded && loadHandler) { + dt.onLoaded.subscribe(loadHandler); + } + + await dt.load(); + + return dt; + } + + return dt; + } + + async persist() { + if (this._file === undefined) { + return; + } + + const extensionsJsonString = JSON.stringify(this.definition, null, 2); + + this._file.setContent(extensionsJsonString); + } + + async save() { + if (this._file === undefined) { + return; + } + + this.persist(); + + await this._file.saveContent(false); + } + + async hasMinContent() { + await this.load(); + + if (!this.definition || !this.definition.recommendations) { + return false; + } + + for (const reco of VsCodeRecommendations) { + if (!this.definition.recommendations.includes(reco)) { + return false; + } + } + + return true; + } + + async ensureMinContent() { + const hasRecos = await this.hasMinContent(); + + if (hasRecos) { + return true; + } + + if (!this.definition) { + this.definition = { recommendations: [] }; + } + + if (!this.definition.recommendations) { + this.definition.recommendations = []; + } + + for (const reco of VsCodeRecommendations) { + if (!this.definition.recommendations.includes(reco)) { + this.definition.recommendations.push(reco); + } + } + + return this.definition; + } + + async load() { + if (this._file === undefined || this._isLoaded) { + return; + } + + await this._file.loadContent(); + + if (this._file.content === null || this._file.content instanceof Uint8Array) { + return; + } + + this.id = this._file.name; + + try { + const data: any = JSON.parse(this._file.content); + + this.definition = data; + } catch (e) { + Log.fail("Could not parse vscode launch JSON " + e); + } + + this._isLoaded = true; + } +} diff --git a/app/src/devproject/VsCodeLaunchJson.ts b/app/src/devproject/VsCodeLaunchDefinition.ts similarity index 87% rename from app/src/devproject/VsCodeLaunchJson.ts rename to app/src/devproject/VsCodeLaunchDefinition.ts index cd799920..f0427095 100644 --- a/app/src/devproject/VsCodeLaunchJson.ts +++ b/app/src/devproject/VsCodeLaunchDefinition.ts @@ -9,14 +9,14 @@ import StorageUtilities from "../storage/StorageUtilities"; import Project from "../app/Project"; import BehaviorManifestDefinition from "../minecraft/BehaviorManifestDefinition"; -export default class VsCodeLaunchJson { +export default class VsCodeLaunchDefinition { private _file?: IFile; private _id?: string; private _isLoaded: boolean = false; public definition?: IVsCodeLaunch; - private _onLoaded = new EventDispatcher(); + private _onLoaded = new EventDispatcher(); public project: Project | undefined = undefined; @@ -44,19 +44,19 @@ export default class VsCodeLaunchJson { this._id = newId; } - static async ensureOnFile(file: IFile, loadHandler?: IEventHandler) { - let dt: VsCodeLaunchJson | undefined; + static async ensureOnFile(file: IFile, loadHandler?: IEventHandler) { + let dt: VsCodeLaunchDefinition | undefined; if (file.manager === undefined) { - dt = new VsCodeLaunchJson(); + dt = new VsCodeLaunchDefinition(); dt.file = file; file.manager = dt; } - if (file.manager !== undefined && file.manager instanceof VsCodeLaunchJson) { - dt = file.manager as VsCodeLaunchJson; + if (file.manager !== undefined && file.manager instanceof VsCodeLaunchDefinition) { + dt = file.manager as VsCodeLaunchDefinition; if (!dt.isLoaded && loadHandler) { dt.onLoaded.subscribe(loadHandler); @@ -70,7 +70,11 @@ export default class VsCodeLaunchJson { return dt; } - async hasMinecraftDebugLaunch(debugSettings: IDebugSettings) { + async hasMinContent(debugSettings?: IDebugSettings) { + if (!debugSettings) { + debugSettings = { isServer: false }; + } + await this.load(); if (!this.definition || !this.definition.configurations) { @@ -98,8 +102,12 @@ export default class VsCodeLaunchJson { return false; } - async ensureMinecraftDebugLaunch(debugSettings: IDebugSettings) { - const hasDebug = await this.hasMinecraftDebugLaunch(debugSettings); + async ensureMinContent(debugSettings?: IDebugSettings) { + if (!debugSettings) { + debugSettings = { isServer: false }; + } + + const hasDebug = await this.hasMinContent(debugSettings); if (hasDebug) { return true; diff --git a/app/src/devproject/VsCodeSettingsDefinition.ts b/app/src/devproject/VsCodeSettingsDefinition.ts new file mode 100644 index 00000000..bd4ebc1f --- /dev/null +++ b/app/src/devproject/VsCodeSettingsDefinition.ts @@ -0,0 +1,180 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import IFile from "../storage/IFile"; +import Log from "../core/Log"; +import { EventDispatcher, IEventHandler } from "ste-events"; + +export const VsCodeDefaultSettings: { [name: string]: any } = { + "[javascript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + }, + "[typescript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + }, + "[typescriptreact]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + }, + "[json]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + }, + "git.ignoreLimitWarning": true, + "editor.formatOnSave": true, + "search.exclude": { + "**/.git": true, + "**/node_modules": true, + "**/dist": true, + "**/lib": true, + }, + "files.exclude": { + "**/.git": true, + "**/.DS_Store": true, + "**/node_modules": true, + }, + "cSpell.words": ["gametest", "gametests", "mcaddon"], + "editor.tabSize": 2, + "eslint.experimental.useFlatConfig": true, +}; + +export default class VsCodeSettingsDefinition { + private _file?: IFile; + private _id?: string; + private _isLoaded: boolean = false; + + public definition?: { [name: string]: any }; + + private _onLoaded = new EventDispatcher(); + + public get isLoaded() { + return this._isLoaded; + } + + public get file() { + return this._file; + } + + public set file(newFile: IFile | undefined) { + this._file = newFile; + } + + public get onLoaded() { + return this._onLoaded.asEvent(); + } + + public get id() { + return this._id; + } + + public set id(newId: string | undefined) { + this._id = newId; + } + + static async ensureOnFile( + file: IFile, + loadHandler?: IEventHandler + ) { + let dt: VsCodeSettingsDefinition | undefined; + + if (file.manager === undefined) { + dt = new VsCodeSettingsDefinition(); + + dt.file = file; + + file.manager = dt; + } + + if (file.manager !== undefined && file.manager instanceof VsCodeSettingsDefinition) { + dt = file.manager as VsCodeSettingsDefinition; + + if (!dt.isLoaded && loadHandler) { + dt.onLoaded.subscribe(loadHandler); + } + + await dt.load(); + + return dt; + } + + return dt; + } + + async persist() { + if (this._file === undefined) { + return; + } + + const extensionsJsonString = JSON.stringify(this.definition, null, 2); + + this._file.setContent(extensionsJsonString); + } + + async save() { + if (this._file === undefined) { + return; + } + + this.persist(); + + await this._file.saveContent(false); + } + + async hasMinContent() { + await this.load(); + + if (!this.definition) { + return false; + } + + for (const settingName in VsCodeDefaultSettings) { + if (!this.definition[settingName]) { + return false; + } + } + + return true; + } + + async ensureMinContent() { + const hasSettings = await this.hasMinContent(); + + if (hasSettings) { + return true; + } + + if (!this.definition) { + this.definition = VsCodeDefaultSettings; + } + + for (const settingName in VsCodeDefaultSettings) { + if (!this.definition[settingName]) { + this.definition[settingName] = VsCodeDefaultSettings[settingName]; + } + } + + return this.definition; + } + + async load() { + if (this._file === undefined || this._isLoaded) { + return; + } + + await this._file.loadContent(); + + if (this._file.content === null || this._file.content instanceof Uint8Array) { + return; + } + + this.id = this._file.name; + + try { + const data: any = JSON.parse(this._file.content); + + this.definition = data; + } catch (e) { + Log.fail("Could not parse vscode launch JSON " + e); + } + + this._isLoaded = true; + } +} diff --git a/app/src/devproject/VsCodeTasksJson.ts b/app/src/devproject/VsCodeTasksDefinition.ts similarity index 88% rename from app/src/devproject/VsCodeTasksJson.ts rename to app/src/devproject/VsCodeTasksDefinition.ts index 7ff56184..70785a92 100644 --- a/app/src/devproject/VsCodeTasksJson.ts +++ b/app/src/devproject/VsCodeTasksDefinition.ts @@ -7,7 +7,7 @@ import { EventDispatcher, IEventHandler } from "ste-events"; import IVsCodeTasks from "./IVsCodeTasks"; import Utilities from "../core/Utilities"; -export default class VsCodeTasksJson { +export default class VsCodeTasksDefinition { private _file?: IFile; private _id?: string; private _version?: string; @@ -15,7 +15,7 @@ export default class VsCodeTasksJson { public definition?: IVsCodeTasks; - private _onLoaded = new EventDispatcher(); + private _onLoaded = new EventDispatcher(); public get isLoaded() { return this._isLoaded; @@ -41,19 +41,19 @@ export default class VsCodeTasksJson { this._id = newId; } - static async ensureOnFile(file: IFile, loadHandler?: IEventHandler) { - let dt: VsCodeTasksJson | undefined; + static async ensureOnFile(file: IFile, loadHandler?: IEventHandler) { + let dt: VsCodeTasksDefinition | undefined; if (file.manager === undefined) { - dt = new VsCodeTasksJson(); + dt = new VsCodeTasksDefinition(); dt.file = file; file.manager = dt; } - if (file.manager !== undefined && file.manager instanceof VsCodeTasksJson) { - dt = file.manager as VsCodeTasksJson; + if (file.manager !== undefined && file.manager instanceof VsCodeTasksDefinition) { + dt = file.manager as VsCodeTasksDefinition; if (!dt.isLoaded && loadHandler) { dt.onLoaded.subscribe(loadHandler); @@ -87,7 +87,7 @@ export default class VsCodeTasksJson { await this._file.saveContent(false); } - async hasMinecraftTasks() { + async hasMinContent() { await this.load(); if (!this.definition || !this.definition.tasks) { @@ -109,8 +109,8 @@ export default class VsCodeTasksJson { return false; } - async ensureMinecraftTasks() { - const hasTasks = await this.hasMinecraftTasks(); + async ensureMinContent() { + const hasTasks = await this.hasMinContent(); if (hasTasks) { return true; diff --git a/app/src/info/AddOnRequirementsGenerator.ts b/app/src/info/AddOnRequirementsGenerator.ts index 306b0d6a..a2ba9fa3 100644 --- a/app/src/info/AddOnRequirementsGenerator.ts +++ b/app/src/info/AddOnRequirementsGenerator.ts @@ -202,7 +202,9 @@ export default class AddOnRequirementsGenerator implements IProjectInfoGenerator let resourcePackManifest: undefined | ResourceManifestDefinition = undefined; let resourcePackItem: undefined | ProjectItem = undefined; - for (const projectItem of project.items) { + const itemsCopy = project.getItemsCopy(); + + for (const projectItem of itemsCopy) { if (projectItem.file) { if (projectItem.itemType === ProjectItemType.behaviorPackManifestJson) { if (behaviorPackManifest) { diff --git a/app/src/info/AnimationResourceInfoGenerator.ts b/app/src/info/AnimationResourceInfoGenerator.ts index 7b7f0ae0..25ff570f 100644 --- a/app/src/info/AnimationResourceInfoGenerator.ts +++ b/app/src/info/AnimationResourceInfoGenerator.ts @@ -42,7 +42,9 @@ export default class AnimationResourceInfoGenerator implements IProjectInfoGener const boneCountPi = new ProjectInfoItem(InfoItemType.featureAggregate, this.id, 2, "Bones"); items.push(boneCountPi); - for (const projectItem of project.items) { + const itemsCopy = project.getItemsCopy(); + + for (const projectItem of itemsCopy) { if (projectItem.itemType === ProjectItemType.animationResourceJson) { await projectItem.ensureFileStorage(); diff --git a/app/src/info/ItemCountsInfoGenerator.ts b/app/src/info/ItemCountsInfoGenerator.ts index d0696304..3e3003c8 100644 --- a/app/src/info/ItemCountsInfoGenerator.ts +++ b/app/src/info/ItemCountsInfoGenerator.ts @@ -44,7 +44,7 @@ export default class ItemCountsInfoGenerator implements IProjectInfoGenerator { infoSet.getFirstNumberValue("ITEMS", 100 + ProjectItemType.MCWorld) + infoSet.getFirstNumberValue("ITEMS", 100 + ProjectItemType.worldFolder); - info.entityTypeResourceCount = infoSet.getFirstNumberValue("ITEMS", 100 + ProjectItemType.entityTypeResourceJson); + info.entityTypeResourceCount = infoSet.getFirstNumberValue("ITEMS", 100 + ProjectItemType.entityTypeResource); info.behaviorPackAnimationCount = infoSet.getFirstNumberValue("ITEMS", 100 + ProjectItemType.animationBehaviorJson); @@ -62,8 +62,10 @@ export default class ItemCountsInfoGenerator implements IProjectInfoGenerator { typeCounts[i] = 0; } - for (let i = 0; i < project.items.length; i++) { - const pi = project.items[i]; + const itemsCopy = project.getItemsCopy(); + + for (let i = 0; i < itemsCopy.length; i++) { + const pi = itemsCopy[i]; typeCounts[pi.itemType]++; diff --git a/app/src/info/LineSizeInfoGenerator.ts b/app/src/info/LineSizeInfoGenerator.ts index 3b972c47..b45d6000 100644 --- a/app/src/info/LineSizeInfoGenerator.ts +++ b/app/src/info/LineSizeInfoGenerator.ts @@ -39,8 +39,10 @@ export default class LineSizeInfoGenerator implements IProjectInfoGenerator { lineSizeCounts[i] = 0; } - for (let i = 0; i < project.items.length; i++) { - const pi = project.items[i]; + const itemsCopy = project.getItemsCopy(); + + for (let i = 0; i < itemsCopy.length; i++) { + const pi = itemsCopy[i]; let projInfoItem = undefined; if (itemsByType[pi.itemType] !== undefined) { diff --git a/app/src/info/PackInfoGenerator.ts b/app/src/info/PackInfoGenerator.ts index bf7073a2..d11f6f88 100644 --- a/app/src/info/PackInfoGenerator.ts +++ b/app/src/info/PackInfoGenerator.ts @@ -46,8 +46,10 @@ export default class PackInformationGenerator implements IProjectInfoGenerator { async generate(project: Project, contentIndex: ContentIndex): Promise { const items: ProjectInfoItem[] = []; - for (let i = 0; i < project.items.length; i++) { - const pi = project.items[i]; + const itemsCopy = project.getItemsCopy(); + + for (let i = 0; i < itemsCopy.length; i++) { + const pi = itemsCopy[i]; if (pi.itemType === ProjectItemType.iconImage) { if (pi.file) { diff --git a/app/src/info/ProjectInfoSet.ts b/app/src/info/ProjectInfoSet.ts index 5bbf3787..b85e6ed2 100644 --- a/app/src/info/ProjectInfoSet.ts +++ b/app/src/info/ProjectInfoSet.ts @@ -240,8 +240,10 @@ export default class ProjectInfoSet { } } - for (let i = 0; i < this.project.items.length; i++) { - const pi = this.project.items[i]; + const itemsCopy = this.project.getItemsCopy(); + + for (let i = 0; i < itemsCopy.length; i++) { + const pi = itemsCopy[i]; await pi.load(); diff --git a/app/src/info/StrictPlatformInfoGenerator.ts b/app/src/info/StrictPlatformInfoGenerator.ts index c58737a3..bfeea38e 100644 --- a/app/src/info/StrictPlatformInfoGenerator.ts +++ b/app/src/info/StrictPlatformInfoGenerator.ts @@ -38,8 +38,10 @@ export default class StrictPlatformInfoGenerator implements IProjectInfoGenerato async generate(project: Project, contentIndex: ContentIndex): Promise { const infoItems: ProjectInfoItem[] = []; - for (let i = 0; i < project.items.length; i++) { - const pi = project.items[i]; + const itemsCopy = project.getItemsCopy(); + + for (let i = 0; i < itemsCopy.length; i++) { + const pi = itemsCopy[i]; if (pi.itemType === ProjectItemType.entityTypeBehaviorJson) { await pi.ensureFileStorage(); diff --git a/app/src/info/TextureImageInfoGenerator.ts b/app/src/info/TextureImageInfoGenerator.ts index dd7c00bb..6c47e8f2 100644 --- a/app/src/info/TextureImageInfoGenerator.ts +++ b/app/src/info/TextureImageInfoGenerator.ts @@ -44,7 +44,9 @@ export default class TextureImageInfoGenerator implements IProjectInfoGenerator const rpFolder = await Database.loadDefaultResourcePack(); - for (const projectItem of project.items) { + const itemsCopy = project.getItemsCopy(); + + for (const projectItem of itemsCopy) { if (projectItem.itemType === ProjectItemType.texture) { await projectItem.ensureFileStorage(); diff --git a/app/src/info/TextureInfoGenerator.ts b/app/src/info/TextureInfoGenerator.ts index d204984d..63e4171d 100644 --- a/app/src/info/TextureInfoGenerator.ts +++ b/app/src/info/TextureInfoGenerator.ts @@ -109,7 +109,9 @@ export default class TextureInfoGenerator implements IProjectInfoGenerator { const rpFolder = await Database.loadDefaultResourcePack(); - for (const projectItem of project.items) { + const itemsCopy = project.getItemsCopy(); + + for (const projectItem of itemsCopy) { if (projectItem.itemType === ProjectItemType.blocksCatalogResourceJson) { await projectItem.ensureFileStorage(); @@ -355,7 +357,7 @@ export default class TextureInfoGenerator implements IProjectInfoGenerator { } } } - } else if (projectItem.itemType === ProjectItemType.entityTypeResourceJson) { + } else if (projectItem.itemType === ProjectItemType.entityTypeResource) { textureCountPi.incrementFeature("Entity Resource Count"); await projectItem.ensureFileStorage(); @@ -363,11 +365,11 @@ export default class TextureInfoGenerator implements IProjectInfoGenerator { const entityTypeResourceDef = await EntityTypeResourceDefinition.ensureOnFile(projectItem.file); if ( - entityTypeResourceDef?.clientEntityTypeWrapper && - entityTypeResourceDef?.clientEntityTypeWrapper["minecraft:client_entity"] && - entityTypeResourceDef?.clientEntityTypeWrapper["minecraft:client_entity"].description + entityTypeResourceDef?.dataWrapper && + entityTypeResourceDef?.dataWrapper["minecraft:client_entity"] && + entityTypeResourceDef?.dataWrapper["minecraft:client_entity"].description ) { - const desc = entityTypeResourceDef.clientEntityTypeWrapper["minecraft:client_entity"].description; + const desc = entityTypeResourceDef.dataWrapper["minecraft:client_entity"].description; const textures = desc.textures; if (textures) { diff --git a/app/src/manager/BaseGameVersionManager.ts b/app/src/manager/BaseGameVersionManager.ts index dc642aa1..5e0d9a8d 100644 --- a/app/src/manager/BaseGameVersionManager.ts +++ b/app/src/manager/BaseGameVersionManager.ts @@ -123,8 +123,10 @@ export default class BaseGameVersionManager implements IProjectInfoGenerator, IP const verShort = verSplit[0] + "." + verSplit[1] + "." + verSplit[2]; - for (let i = 0; i < project.items.length; i++) { - const pi = project.items[i]; + const itemsCopy = project.getItemsCopy(); + + for (let i = 0; i < itemsCopy.length; i++) { + const pi = itemsCopy[i]; if (pi.itemType === ProjectItemType.worldTemplateManifestJson) { await pi.ensureFileStorage(); @@ -318,8 +320,10 @@ export default class BaseGameVersionManager implements IProjectInfoGenerator, IP const minor = parseInt(verSplit[1]); const patch = parseInt(verSplit[2]); - for (let i = 0; i < project.items.length; i++) { - const pi = project.items[i]; + const itemsCopy = project.getItemsCopy(); + + for (let i = 0; i < itemsCopy.length; i++) { + const pi = itemsCopy[i]; if (pi.itemType === ProjectItemType.worldTemplateManifestJson) { await pi.ensureFileStorage(); diff --git a/app/src/manager/BehaviorPackEntityTypeManager.ts b/app/src/manager/BehaviorPackEntityTypeManager.ts index d0a74797..40ea222a 100644 --- a/app/src/manager/BehaviorPackEntityTypeManager.ts +++ b/app/src/manager/BehaviorPackEntityTypeManager.ts @@ -146,8 +146,10 @@ export default class BehaviorPackEntityTypeManager implements IProjectInfoGenera infoItems.push(piiMetadata); - for (let i = 0; i < project.items.length; i++) { - const pi = project.items[i]; + const itemsCopy = project.getItemsCopy(); + + for (let i = 0; i < itemsCopy.length; i++) { + const pi = itemsCopy[i]; if (pi.itemType === ProjectItemType.entityTypeBehaviorJson) { await pi.ensureFileStorage(); @@ -401,8 +403,10 @@ export default class BehaviorPackEntityTypeManager implements IProjectInfoGenera const minor = parseInt(verSplit[1]); const patch = parseInt(verSplit[2]); - for (let i = 0; i < project.items.length; i++) { - const pi = project.items[i]; + const itemsCopy = project.getItemsCopy(); + + for (let i = 0; i < itemsCopy.length; i++) { + const pi = itemsCopy[i]; if (pi.itemType === ProjectItemType.behaviorPackManifestJson) { await pi.ensureFileStorage(); diff --git a/app/src/manager/BehaviorPackItemTypeManager.ts b/app/src/manager/BehaviorPackItemTypeManager.ts index b7aad091..9c39b482 100644 --- a/app/src/manager/BehaviorPackItemTypeManager.ts +++ b/app/src/manager/BehaviorPackItemTypeManager.ts @@ -135,8 +135,10 @@ export default class BehaviorPackItemTypeManager implements IProjectInfoGenerato infoItems.push(piiCategory); - for (let i = 0; i < project.items.length; i++) { - const pi = project.items[i]; + const itemsCopy = project.getItemsCopy(); + + for (let i = 0; i < itemsCopy.length; i++) { + const pi = itemsCopy[i]; if (pi.itemType === ProjectItemType.itemTypeBehaviorJson) { await pi.ensureFileStorage(); @@ -350,8 +352,10 @@ export default class BehaviorPackItemTypeManager implements IProjectInfoGenerato const minor = parseInt(verSplit[1]); const patch = parseInt(verSplit[2]); - for (let i = 0; i < project.items.length; i++) { - const pi = project.items[i]; + const itemsCopy = project.getItemsCopy(); + + for (let i = 0; i < itemsCopy.length; i++) { + const pi = itemsCopy[i]; if (pi.itemType === ProjectItemType.behaviorPackManifestJson) { await pi.ensureFileStorage(); diff --git a/app/src/manager/FormatVersionManager.ts b/app/src/manager/FormatVersionManager.ts index 4203695e..e910adb0 100644 --- a/app/src/manager/FormatVersionManager.ts +++ b/app/src/manager/FormatVersionManager.ts @@ -197,8 +197,10 @@ export default class FormatVersionManager implements IProjectInfoGenerator, IPro return infoItems; } - for (let i = 0; i < project.items.length; i++) { - const pi = project.items[i]; + const itemsCopy = project.getItemsCopy(); + + for (let i = 0; i < itemsCopy.length; i++) { + const pi = itemsCopy[i]; if (pi.itemType === ProjectItemType.blockTypeBehaviorJson) { await pi.ensureFileStorage(); @@ -298,7 +300,7 @@ export default class FormatVersionManager implements IProjectInfoGenerator, IPro } } } - } else if (pi.itemType === ProjectItemType.spawnRuleBehaviorJson) { + } else if (pi.itemType === ProjectItemType.spawnRuleBehavior) { await pi.ensureFileStorage(); if (pi.file) { @@ -326,7 +328,7 @@ export default class FormatVersionManager implements IProjectInfoGenerator, IPro } } } - } else if (pi.itemType === ProjectItemType.entityTypeResourceJson) { + } else if (pi.itemType === ProjectItemType.entityTypeResource) { await pi.ensureFileStorage(); if (pi.file) { @@ -538,8 +540,10 @@ export default class FormatVersionManager implements IProjectInfoGenerator, IPro const minor = parseInt(verSplit[1]); const patch = parseInt(verSplit[2]); - for (let i = 0; i < project.items.length; i++) { - const pi = project.items[i]; + const itemsCopy = project.getItemsCopy(); + + for (let i = 0; i < itemsCopy.length; i++) { + const pi = itemsCopy[i]; if (pi.itemType === ProjectItemType.worldTemplateManifestJson) { await pi.ensureFileStorage(); diff --git a/app/src/manager/MinEngineVersionManager.ts b/app/src/manager/MinEngineVersionManager.ts index 2b492fb1..0859d204 100644 --- a/app/src/manager/MinEngineVersionManager.ts +++ b/app/src/manager/MinEngineVersionManager.ts @@ -166,8 +166,10 @@ export default class MinEngineVersionManager implements IProjectInfoGenerator, I const verShort = verSplit[0] + "." + verSplit[1] + "." + verSplit[2]; - for (let i = 0; i < project.items.length; i++) { - const pi = project.items[i]; + const itemsCopy = project.getItemsCopy(); + + for (let i = 0; i < itemsCopy.length; i++) { + const pi = itemsCopy[i]; if (pi.itemType === ProjectItemType.behaviorPackManifestJson) { await pi.ensureFileStorage(); @@ -494,8 +496,10 @@ export default class MinEngineVersionManager implements IProjectInfoGenerator, I const minor = parseInt(verSplit[1]); const patch = parseInt(verSplit[2]); - for (let i = 0; i < project.items.length; i++) { - const pi = project.items[i]; + const itemsCopy = project.getItemsCopy(); + + for (let i = 0; i < itemsCopy.length; i++) { + const pi = itemsCopy[i]; if (pi.itemType === ProjectItemType.behaviorPackManifestJson) { await pi.ensureFileStorage(); diff --git a/app/src/manager/ScriptModuleManager.ts b/app/src/manager/ScriptModuleManager.ts index 66f058e2..07d741ec 100644 --- a/app/src/manager/ScriptModuleManager.ts +++ b/app/src/manager/ScriptModuleManager.ts @@ -7,7 +7,7 @@ import IProjectInfoGenerator from "../info/IProjectInfoGenerator"; import { ProjectItemType } from "../app/IProjectItemData"; import { InfoItemType } from "../info/IInfoItemData"; import BehaviorManifestDefinition from "../minecraft/BehaviorManifestDefinition"; -import NpmPackageJson from "../devproject/NpmPackageJson"; +import NpmPackageDefinition from "../devproject/NpmPackageDefinition"; import Database from "../minecraft/Database"; import ProjectItem from "../app/ProjectItem"; import IProjectUpdater from "../updates/IProjectUpdater"; @@ -16,14 +16,15 @@ import { UpdateResultType } from "../updates/IUpdateResult"; import { IProjectInfoTopicData } from "../info/IProjectInfoGeneratorBase"; import ProjectInfoSet from "../info/ProjectInfoSet"; import ContentIndex from "../core/ContentIndex"; -import EnvFile from "../devproject/EnvFile"; +import EnvSettings from "../devproject/EnvSettings"; export default class ScriptModuleManager implements IProjectInfoGenerator, IProjectUpdater { id = "SCRIPTMODULE"; title = "Script Modules"; modulesInUse: { [name: string]: { version: string; manifest: BehaviorManifestDefinition; item: ProjectItem }[] } = {}; - packRegsInUse: { [name: string]: { package: NpmPackageJson; isDevDependency: boolean; version: string }[] } = {}; + packRegsInUse: { [name: string]: { package: NpmPackageDefinition; isDevDependency: boolean; version: string }[] } = + {}; getTopicData(topicId: number): IProjectInfoTopicData | undefined { return { @@ -44,8 +45,10 @@ export default class ScriptModuleManager implements IProjectInfoGenerator, IProj this.modulesInUse = {}; this.packRegsInUse = {}; - for (let i = 0; i < project.items.length; i++) { - const pi = project.items[i]; + const itemsCopy = project.getItemsCopy(); + + for (let i = 0; i < itemsCopy.length; i++) { + const pi = itemsCopy[i]; if (pi.itemType === ProjectItemType.behaviorPackManifestJson) { await pi.ensureFileStorage(); @@ -92,7 +95,7 @@ export default class ScriptModuleManager implements IProjectInfoGenerator, IProj await pi.ensureFileStorage(); if (pi.file) { - const npmPackageJson = await NpmPackageJson.ensureOnFile(pi.file); + const npmPackageJson = await NpmPackageDefinition.ensureOnFile(pi.file); if (npmPackageJson && npmPackageJson.definition) { const deps = npmPackageJson.definition.dependencies; @@ -159,7 +162,7 @@ export default class ScriptModuleManager implements IProjectInfoGenerator, IProj await pi.ensureFileStorage(); if (pi.file) { - const envFile = await EnvFile.ensureOnFile(pi.file); + const envFile = await EnvSettings.ensureOnFile(pi.file); await envFile?.ensureEnvFile(project); } diff --git a/app/src/manager/VsCodeFileManager.ts b/app/src/manager/VsCodeFileManager.ts index 18a2ce87..3fc72a0a 100644 --- a/app/src/manager/VsCodeFileManager.ts +++ b/app/src/manager/VsCodeFileManager.ts @@ -8,9 +8,9 @@ import { ProjectItemStorageType, ProjectItemType } from "../app/IProjectItemData import { InfoItemType } from "../info/IInfoItemData"; import IProjectUpdater from "../updates/IProjectUpdater"; import ProjectUpdateResult from "../updates/ProjectUpdateResult"; -import VsCodeTasksJson from "../devproject/VsCodeTasksJson"; +import VsCodeTasksDefinition from "../devproject/VsCodeTasksDefinition"; import { UpdateResultType } from "../updates/IUpdateResult"; -import VsCodeLaunchJson from "../devproject/VsCodeLaunchJson"; +import VsCodeLaunchDefinition from "../devproject/VsCodeLaunchDefinition"; import { IProjectInfoTopicData } from "../info/IProjectInfoGeneratorBase"; import ProjectInfoSet from "../info/ProjectInfoSet"; import ContentIndex from "../core/ContentIndex"; @@ -37,15 +37,17 @@ export default class VsCodeFileManager implements IProjectInfoGenerator, IProjec async generate(project: Project, contentIndex: ContentIndex): Promise { const infoItems: ProjectInfoItem[] = []; - for (const pi of project.items) { + const itemsCopy = project.getItemsCopy(); + + for (const pi of itemsCopy) { if (pi.itemType === ProjectItemType.vsCodeTasksJson && pi.storageType === ProjectItemStorageType.singleFile) { await pi.ensureFileStorage(); if (pi.file) { - const vscodeTasksJson = await VsCodeTasksJson.ensureOnFile(pi.file); + const vscodeTasksJson = await VsCodeTasksDefinition.ensureOnFile(pi.file); if (vscodeTasksJson) { - const hasMinecraftTasks = await vscodeTasksJson.hasMinecraftTasks(); + const hasMinecraftTasks = await vscodeTasksJson.hasMinContent(); if (!hasMinecraftTasks) { infoItems.push( @@ -69,11 +71,11 @@ export default class VsCodeFileManager implements IProjectInfoGenerator, IProjec await pi.ensureFileStorage(); if (pi.file) { - const vscodeLaunchJson = await VsCodeLaunchJson.ensureOnFile(pi.file); + const vscodeLaunchJson = await VsCodeLaunchDefinition.ensureOnFile(pi.file); if (vscodeLaunchJson) { vscodeLaunchJson.project = project; - const hasMinecraftDebugConfig = await vscodeLaunchJson.hasMinecraftDebugLaunch({ isServer: true }); + const hasMinecraftDebugConfig = await vscodeLaunchJson.hasMinContent({ isServer: true }); if (!hasMinecraftDebugConfig) { infoItems.push( @@ -118,18 +120,20 @@ export default class VsCodeFileManager implements IProjectInfoGenerator, IProjec async ensureMinecraftLaunchTasks(project: Project) { const results: ProjectUpdateResult[] = []; - for (const pi of project.items) { + const itemsCopy = project.getItemsCopy(); + + for (const pi of itemsCopy) { if (pi.itemType === ProjectItemType.vsCodeTasksJson && pi.storageType === ProjectItemStorageType.singleFile) { await pi.ensureFileStorage(); if (pi.file) { - const vscodeTasksJson = await VsCodeTasksJson.ensureOnFile(pi.file); + const vscodeTasksJson = await VsCodeTasksDefinition.ensureOnFile(pi.file); if (vscodeTasksJson) { - const hasTasks = await vscodeTasksJson.hasMinecraftTasks(); + const hasTasks = await vscodeTasksJson.hasMinContent(); if (!hasTasks) { - const result = await vscodeTasksJson.ensureMinecraftTasks(); + const result = await vscodeTasksJson.ensureMinContent(); if (result) { await vscodeTasksJson.save(); @@ -149,12 +153,14 @@ export default class VsCodeFileManager implements IProjectInfoGenerator, IProjec async ensureMinecraftDebugConfig(project: Project) { const results: ProjectUpdateResult[] = []; - for (const pi of project.items) { + const itemsCopy = project.getItemsCopy(); + + for (const pi of itemsCopy) { if (pi.itemType === ProjectItemType.vsCodeLaunchJson && pi.storageType === ProjectItemStorageType.singleFile) { await pi.ensureFileStorage(); if (pi.file) { - const vscodeLaunchJson = await VsCodeLaunchJson.ensureOnFile(pi.file); + const vscodeLaunchJson = await VsCodeLaunchDefinition.ensureOnFile(pi.file); const pack = await project.getDefaultBehaviorPack(); @@ -165,10 +171,10 @@ export default class VsCodeFileManager implements IProjectInfoGenerator, IProjec } if (vscodeLaunchJson) { - const hasConfig = await vscodeLaunchJson.hasMinecraftDebugLaunch(debugSettings); + const hasConfig = await vscodeLaunchJson.hasMinContent(debugSettings); if (!hasConfig) { - const result = await vscodeLaunchJson.ensureMinecraftDebugLaunch(debugSettings); + const result = await vscodeLaunchJson.ensureMinContent(debugSettings); if (result) { await vscodeLaunchJson.save(); diff --git a/app/src/minecraft/BehaviorManifestDefinition.ts b/app/src/minecraft/BehaviorManifestDefinition.ts index 565ef9db..279b153e 100644 --- a/app/src/minecraft/BehaviorManifestDefinition.ts +++ b/app/src/minecraft/BehaviorManifestDefinition.ts @@ -3,10 +3,12 @@ import IFile from "../storage/IFile"; import { EventDispatcher, IEventHandler } from "ste-events"; -import IAddonManifest, { IAddonManifestHeader, IAddonModule } from "./IAddonManifest"; +import IAddonManifest, { IAddonDependency, IAddonManifestHeader, IAddonModule } from "./IAddonManifest"; import Utilities from "../core/Utilities"; -import Project from "../app/Project"; +import Project, { AUTOGENERATED_WHOLEFILE_GENERAL_SEPARATOR, minecraftScriptModules } from "../app/Project"; import StorageUtilities from "../storage/StorageUtilities"; +import { ProjectItemType } from "../app/IProjectItemData"; +import { ProjectFocus } from "../app/IProjectData"; export default class BehaviorManifestDefinition { private _file?: IFile; @@ -338,4 +340,101 @@ export default class BehaviorManifestDefinition { this._isLoaded = true; } + + static async getContent(project: Project, contentOnlyUpdate?: boolean) { + let versionMajor = 0; + let versionMinor = 0; + let versionPatch = 1; + + if (project.versionMajor !== undefined) { + versionMajor = project.versionMajor; + } + + if (project.versionMinor !== undefined) { + versionMinor = project.versionMinor; + } + + if (project.versionPatch !== undefined) { + versionPatch = project.versionPatch; + } + + const modulesList: IAddonModule[] = []; + const dependenciesList: IAddonDependency[] = []; + let scriptFile = undefined; + let pi = project.getFirstItemByType(ProjectItemType.catalogIndexJs); + + if (pi !== undefined) { + scriptFile = pi.file; + } + + const behaviorPackRootFolder = await project.getDefaultBehaviorPackFolder(false, contentOnlyUpdate); + + if (scriptFile === undefined) { + pi = project.getFirstItemByType(ProjectItemType.js); + if (pi !== undefined) { + scriptFile = pi.file; + } + + if (scriptFile === undefined) { + pi = project.getFirstItemByType(ProjectItemType.testJs); + + if (pi !== undefined) { + scriptFile = pi.file; + } + } + } + + const scriptState = await project.getScriptState(); + + if (scriptState.hasScript && scriptFile !== null && scriptFile !== undefined && behaviorPackRootFolder !== null) { + let path = scriptFile.getFolderRelativePath(behaviorPackRootFolder); + + if (path !== undefined) { + if (path.startsWith("/")) { + path = path.substring(1, path.length); + } + + modulesList.push({ + description: project.title + " script", + language: "javascript", + type: "script", + uuid: project.defaultScriptModuleUniqueId, + version: [versionMajor, versionMinor, versionPatch], + entry: path, + }); + + for (let i = 0; i < minecraftScriptModules.length; i++) { + const mod = minecraftScriptModules[i]; + + if (scriptState.hasModule[mod.id]) { + dependenciesList.push({ + uuid: mod.uuid, + module_name: mod.module_name, + version: mod.preferredVersion, + }); + } + } + } + } + + const manifest: IAddonManifest = { + format_version: 2, + __comment__: AUTOGENERATED_WHOLEFILE_GENERAL_SEPARATOR, + header: { + description: project.description, + name: project.title, + uuid: project.defaultBehaviorPackUniqueId, + version: [versionMajor, versionMinor, versionPatch], + min_engine_version: [1, 20, 10], + }, + modules: modulesList, + dependencies: dependenciesList, + }; + + if (project.focus === ProjectFocus.editorExtension) { + manifest.capabilities = ["editorExtension"]; + } + + return JSON.stringify(manifest, null, 2); + } } diff --git a/app/src/minecraft/Database.ts b/app/src/minecraft/Database.ts index bef8c2be..fb75fd82 100644 --- a/app/src/minecraft/Database.ts +++ b/app/src/minecraft/Database.ts @@ -256,21 +256,10 @@ export default class Database { versionUrl = "https://raw.githubusercontent.com/Mojang/bedrock-samples/preview/version.json"; } - // Log.message("Retrieving " + (preview ? "preview" : "retail") + " version data."); - - /*Log.verbose( - "Getting latest version info from '" + - versionUrl + - "' " + - this.#usePreview + - "|" + - (this.carto && this.carto.processHostedMinecraftTrack === MinecraftTrack.preview) - );*/ - try { minecraftInfoResponse = await axios.get(versionUrl); } catch (e: any) { - console.log("Could not access Bedrock Dedicated Server details." + e); + console.log("Could not access Minecraft version details." + e); throw new Error(e.toString()); } @@ -307,7 +296,7 @@ export default class Database { } } } catch (e: any) { - Log.error("Could not access Bedrock Dedicated Server details." + e); + Log.error("Could not process Minecraft version details." + e); throw new Error(e.toString()); } diff --git a/app/src/minecraft/EntityTypeDefinition.ts b/app/src/minecraft/EntityTypeDefinition.ts index 9449fc6d..90b74763 100644 --- a/app/src/minecraft/EntityTypeDefinition.ts +++ b/app/src/minecraft/EntityTypeDefinition.ts @@ -16,6 +16,11 @@ import ManagedEvent from "./ManagedEvent"; import StorageUtilities from "../storage/StorageUtilities"; import Database from "./Database"; import MinecraftUtilities from "./MinecraftUtilities"; +import Project from "../app/Project"; +import ProjectItem from "../app/ProjectItem"; +import { ProjectItemType } from "../app/IProjectItemData"; +import EntityTypeResourceDefinition from "./EntityTypeResourceDefinition"; +import SpawnRulesBehaviorDefinition from "./SpawnRulesBehaviorDefinition"; export default class EntityTypeDefinition implements IManagedComponentSetItem { public behaviorPackWrapper?: IEntityTypeWrapper; @@ -141,6 +146,33 @@ export default class EntityTypeDefinition implements IManagedComponentSetItem { return this._managedComponents[id]; } + getComponentsInBaseAndGroups(id: string): IManagedComponent[] { + if (this.data === undefined) { + return []; + } + + let results: IManagedComponent[] = []; + + let comp = this.getComponent(id); + + if (comp) { + results.push(comp); + } + + for (const componentGroupName in this._componentGroups) { + const group = this._componentGroups[componentGroupName]; + if (group) { + comp = group.getComponent(id); + + if (comp) { + results.push(comp); + } + } + } + + return results; + } + get behaviorPackFormatVersion() { if (!this.behaviorPackWrapper || !this.behaviorPackWrapper.format_version) { return undefined; @@ -321,6 +353,60 @@ export default class EntityTypeDefinition implements IManagedComponentSetItem { } } + async addChildItems(project: Project, item: ProjectItem) { + let lootTablePaths: string[] = []; + + const comps = this.getComponentsInBaseAndGroups("minecraft:loot"); + + for (const comp of comps) { + let lootTablePath = comp.getProperty("table"); + + if (lootTablePath) { + lootTablePaths.push(lootTablePath); + } + } + + const itemsCopy = project.getItemsCopy(); + + for (const candItem of itemsCopy) { + if (candItem.itemType === ProjectItemType.entityTypeResource) { + await candItem.ensureStorage(); + + if (candItem.file) { + const etrd = await EntityTypeResourceDefinition.ensureOnFile(candItem.file); + + if (etrd) { + const id = etrd.id; + + if (id === this.id) { + item.addChildItem(candItem); + } + } + } + } else if (candItem.itemType === ProjectItemType.spawnRuleBehavior) { + await candItem.ensureStorage(); + + if (candItem.file) { + const srb = await SpawnRulesBehaviorDefinition.ensureOnFile(candItem.file); + + if (srb) { + const id = srb.id; + + if (id === this.id) { + item.addChildItem(candItem); + } + } + } + } else if (candItem.itemType === ProjectItemType.lootTableBehaviorJson) { + for (const lootTablePath of lootTablePaths) { + if (candItem.projectPath?.endsWith(lootTablePath)) { + item.addChildItem(candItem); + } + } + } + } + } + static async ensureOnFile( behaviorPackFile: IFile, loadHandler?: IEventHandler @@ -477,6 +563,27 @@ export default class EntityTypeDefinition implements IManagedComponentSetItem { this.data = entity; + if (this.data) { + if (this.data.components) { + for (const compName in this.data.components) { + const comp = this.data.components[compName]; + + if (comp) { + this._managedComponents[compName] = new ManagedComponent(compName, comp); + } + } + } + if (this.data.component_groups) { + for (const compGroupName in this.data.component_groups) { + const compGroup = this.data.component_groups[compGroupName]; + + if (compGroup) { + this._componentGroups[compGroupName] = new ManagedComponentGroup(compGroup, compGroupName); + } + } + } + } + this._isLoaded = true; this._onLoaded.dispatch(this, this); diff --git a/app/src/minecraft/EntityTypeResourceDefinition.ts b/app/src/minecraft/EntityTypeResourceDefinition.ts index e9424b25..a5204a4b 100644 --- a/app/src/minecraft/EntityTypeResourceDefinition.ts +++ b/app/src/minecraft/EntityTypeResourceDefinition.ts @@ -5,10 +5,10 @@ import IFile from "../storage/IFile"; import Log from "../core/Log"; import { EventDispatcher, IEventHandler } from "ste-events"; import StorageUtilities from "../storage/StorageUtilities"; -import { IClientEntityTypeWrapper } from "./IClientEntityType"; +import { IEntityTypeResourceWrapper } from "./IEntityTypeResource"; export default class EntityTypeResourceDefinition { - public clientEntityTypeWrapper?: IClientEntityTypeWrapper; + public dataWrapper?: IEntityTypeResourceWrapper; private _file?: IFile; private _isLoaded: boolean = false; @@ -31,29 +31,29 @@ export default class EntityTypeResourceDefinition { public get id() { if ( - !this.clientEntityTypeWrapper || - !this.clientEntityTypeWrapper["minecraft:client_entity"] || - !this.clientEntityTypeWrapper["minecraft:client_entity"].description + !this.dataWrapper || + !this.dataWrapper["minecraft:client_entity"] || + !this.dataWrapper["minecraft:client_entity"].description ) { return undefined; } - return this.clientEntityTypeWrapper["minecraft:client_entity"].description.identifier; + return this.dataWrapper["minecraft:client_entity"].description.identifier; } public getFormatVersion(): number[] | undefined { - if (!this.clientEntityTypeWrapper) { + if (!this.dataWrapper) { return undefined; } - const fv = this.clientEntityTypeWrapper.format_version; + const fv = this.dataWrapper.format_version; if (typeof fv === "number") { return [fv]; } if (typeof fv === "string") { - let fvarr = this.clientEntityTypeWrapper.format_version.split("."); + let fvarr = this.dataWrapper.format_version.split("."); let fvarrInt: number[] = []; for (let i = 0; i < fvarr.length; i++) { @@ -69,11 +69,11 @@ export default class EntityTypeResourceDefinition { } get formatVersion() { - if (!this.clientEntityTypeWrapper || !this.clientEntityTypeWrapper.format_version) { + if (!this.dataWrapper || !this.dataWrapper.format_version) { return undefined; } - return this.clientEntityTypeWrapper.format_version; + return this.dataWrapper.format_version; } static async ensureOnFile( @@ -108,7 +108,7 @@ export default class EntityTypeResourceDefinition { return; } - const defString = JSON.stringify(this.clientEntityTypeWrapper, null, 2); + const defString = JSON.stringify(this.dataWrapper, null, 2); this._file.setContent(defString); } @@ -137,7 +137,7 @@ export default class EntityTypeResourceDefinition { data = result; } - this.clientEntityTypeWrapper = data; + this.dataWrapper = data; this._isLoaded = true; diff --git a/app/src/minecraft/IClientEntityType.ts b/app/src/minecraft/IEntityTypeResource.ts similarity index 61% rename from app/src/minecraft/IClientEntityType.ts rename to app/src/minecraft/IEntityTypeResource.ts index 6852306f..d1d0da3f 100644 --- a/app/src/minecraft/IClientEntityType.ts +++ b/app/src/minecraft/IEntityTypeResource.ts @@ -1,16 +1,16 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -export interface IClientEntityTypeWrapper { +export interface IEntityTypeResourceWrapper { format_version: string; - "minecraft:client_entity": IClientEntityType; + "minecraft:client_entity": IEntityTypeResource; } -export interface IClientEntityType { - description: IClientEntityTypeDescription; +export interface IEntityTypeResource { + description: IEntityTypeResourceDescription; } -export interface IClientEntityTypeDescription { +export interface IEntityTypeResourceDescription { identifier: string; materials: { [identifier: string]: string }; textures: { [identifier: string]: string }; @@ -20,10 +20,10 @@ export interface IClientEntityTypeDescription { animations: { [identifier: string]: string }; scripts: { [identifier: string]: string[] }; render_controllers: string[]; - spawn_egg?: IClientEntitySpawnEgg; + spawn_egg?: IEntityResourceSpawnEgg; } -export interface IClientEntitySpawnEgg { +export interface IEntityResourceSpawnEgg { texture?: string; texture_index?: number; } diff --git a/app/src/minecraft/ILootTableBehavior.ts b/app/src/minecraft/ILootTableBehavior.ts new file mode 100644 index 00000000..0f06f973 --- /dev/null +++ b/app/src/minecraft/ILootTableBehavior.ts @@ -0,0 +1,6 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +export default interface ILootTableBehavior { + pools: any[]; +} diff --git a/app/src/minecraft/ISpawnRulesBehavior.ts b/app/src/minecraft/ISpawnRulesBehavior.ts index 89daf915..5afba773 100644 --- a/app/src/minecraft/ISpawnRulesBehavior.ts +++ b/app/src/minecraft/ISpawnRulesBehavior.ts @@ -3,4 +3,14 @@ export default interface ISpawnRulesBehavior { format_version?: string; + "minecraft:spawn_rules": ISpawnRulesInner; +} + +export interface ISpawnRulesInner { + description?: ISpawnRulesDescription; +} + +export interface ISpawnRulesDescription { + identifier: string; + population_control?: string; } diff --git a/app/src/minecraft/LocManager.ts b/app/src/minecraft/LocManager.ts index a9c7c995..0e428175 100644 --- a/app/src/minecraft/LocManager.ts +++ b/app/src/minecraft/LocManager.ts @@ -87,7 +87,9 @@ export default class LocManager { this.tokens = {}; - for (const pi of this._project.items) { + const itemsCopy = this._project.getItemsCopy(); + + for (const pi of itemsCopy) { if (pi.itemType === ProjectItemType.lang) { await pi.ensureFileStorage(); diff --git a/app/src/minecraft/LootTableBehaviorDefinition.ts b/app/src/minecraft/LootTableBehaviorDefinition.ts new file mode 100644 index 00000000..9f7535f5 --- /dev/null +++ b/app/src/minecraft/LootTableBehaviorDefinition.ts @@ -0,0 +1,91 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +import IFile from "../storage/IFile"; +import { EventDispatcher, IEventHandler } from "ste-events"; +import StorageUtilities from "../storage/StorageUtilities"; +import ILootTableBehavior from "./ILootTableBehavior"; + +export default class LootTableBehaviorDefinition { + private _file?: IFile; + private _isLoaded: boolean = false; + + public data?: ILootTableBehavior; + + private _onLoaded = new EventDispatcher(); + + public get isLoaded() { + return this._isLoaded; + } + + public get file() { + return this._file; + } + + public get onLoaded() { + return this._onLoaded.asEvent(); + } + + public set file(newFile: IFile | undefined) { + this._file = newFile; + } + + _ensureDataInitialized() { + if (this.data === undefined) { + this.data = { pools: [] }; + } + } + + static async ensureOnFile( + file: IFile, + loadHandler?: IEventHandler + ) { + let ltb: LootTableBehaviorDefinition | undefined; + + if (file.manager === undefined) { + ltb = new LootTableBehaviorDefinition(); + + ltb.file = file; + + file.manager = ltb; + } + + if (file.manager !== undefined && file.manager instanceof LootTableBehaviorDefinition) { + ltb = file.manager as LootTableBehaviorDefinition; + + if (!ltb.isLoaded && loadHandler) { + ltb.onLoaded.subscribe(loadHandler); + } + + await ltb.load(); + } + + return ltb; + } + + persist() { + if (this._file === undefined) { + return; + } + + const bpString = JSON.stringify(this.data, null, 2); + + this._file.setContent(bpString); + } + + async load() { + if (this._file === undefined || this._isLoaded) { + return; + } + + await this._file.loadContent(); + + if (this._file.content === null || this._file.content instanceof Uint8Array) { + return; + } + + this.data = StorageUtilities.getJsonObject(this._file); + + this._isLoaded = true; + } +} diff --git a/app/src/minecraft/ManagedComponentGroup.ts b/app/src/minecraft/ManagedComponentGroup.ts index 461445e5..d1247882 100644 --- a/app/src/minecraft/ManagedComponentGroup.ts +++ b/app/src/minecraft/ManagedComponentGroup.ts @@ -68,8 +68,9 @@ export default class ManagedComponentGroup implements IManagedComponentSetItem { } if (!this._managed[id]) { - if (this._data[id]) { - this._managed[id] = new ManagedComponent(id, this._data); + const data = this._data[id]; + if (data) { + this._managed[id] = new ManagedComponent(id, data); } } diff --git a/app/src/minecraft/MinecraftUtilities.ts b/app/src/minecraft/MinecraftUtilities.ts index 77e6a3c3..bd36bda7 100644 --- a/app/src/minecraft/MinecraftUtilities.ts +++ b/app/src/minecraft/MinecraftUtilities.ts @@ -32,9 +32,11 @@ export default class MinecraftUtilities { } else if (tokenizePath.startsWith("")) { tokenizePath += ".entity.json"; } else if (tokenizePath.startsWith("")) { - tokenizePath += ".animation_controlllers.json"; + tokenizePath += ".animation_controllers.json"; + } else if (tokenizePath.startsWith("")) { + tokenizePath += ".render_controllers.json"; } else if (tokenizePath.startsWith("")) { - tokenizePath += ".animations.json"; + tokenizePath += ".animation.json"; } else if (tokenizePath.startsWith("")) { if (tokenizePath.indexOf(".") < 0) { tokenizePath += ".png"; @@ -43,6 +45,7 @@ export default class MinecraftUtilities { tokenizePath = tokenizePath.replace(//gi, "/resource_pack/textures/entity/"); tokenizePath = tokenizePath.replace(//gi, "/resource_pack/models/entity/"); tokenizePath = tokenizePath.replace(//gi, "/resource_pack/animation_controllers/"); + tokenizePath = tokenizePath.replace(//gi, "/resource_pack/render_controllers/"); tokenizePath = tokenizePath.replace(//gi, "/resource_pack/animations/"); tokenizePath = tokenizePath.replace(//gi, "/resource_pack/entity/"); tokenizePath = tokenizePath.replace(//gi, "/behavior_pack/entities/"); diff --git a/app/src/minecraft/SpawnRulesBehaviorDefinition.ts b/app/src/minecraft/SpawnRulesBehaviorDefinition.ts index 16f5e2cc..778c5acd 100644 --- a/app/src/minecraft/SpawnRulesBehaviorDefinition.ts +++ b/app/src/minecraft/SpawnRulesBehaviorDefinition.ts @@ -6,7 +6,7 @@ import { EventDispatcher, IEventHandler } from "ste-events"; import StorageUtilities from "../storage/StorageUtilities"; import Database from "./Database"; import MinecraftUtilities from "./MinecraftUtilities"; -import ISpawnRulesBehavior from "./ISpawnRulesBehavior"; +import ISpawnRulesBehavior, { ISpawnRulesInner } from "./ISpawnRulesBehavior"; export default class SpawnRulesBehaviorDefinition { private _file?: IFile; @@ -14,6 +14,7 @@ export default class SpawnRulesBehaviorDefinition { private _isLoaded: boolean = false; public data?: ISpawnRulesBehavior; + public dataInner?: ISpawnRulesInner; private _onLoaded = new EventDispatcher(); @@ -39,6 +40,10 @@ export default class SpawnRulesBehaviorDefinition { public set id(newId: string | undefined) { this._id = newId; + + if (this.dataInner && this.dataInner.description && newId) { + this.dataInner.description.identifier = newId; + } } public get shortId() { @@ -81,7 +86,7 @@ export default class SpawnRulesBehaviorDefinition { _ensureDataInitialized() { if (this.data === undefined) { - this.data = {}; + this.data = { "minecraft:spawn_rules": { description: { identifier: this._id ? this._id : "" } } }; } } @@ -89,27 +94,27 @@ export default class SpawnRulesBehaviorDefinition { file: IFile, loadHandler?: IEventHandler ) { - let rbd: SpawnRulesBehaviorDefinition | undefined; + let srb: SpawnRulesBehaviorDefinition | undefined; if (file.manager === undefined) { - rbd = new SpawnRulesBehaviorDefinition(); + srb = new SpawnRulesBehaviorDefinition(); - rbd.file = file; + srb.file = file; - file.manager = rbd; + file.manager = srb; } if (file.manager !== undefined && file.manager instanceof SpawnRulesBehaviorDefinition) { - rbd = file.manager as SpawnRulesBehaviorDefinition; + srb = file.manager as SpawnRulesBehaviorDefinition; - if (!rbd.isLoaded && loadHandler) { - rbd.onLoaded.subscribe(loadHandler); + if (!srb.isLoaded && loadHandler) { + srb.onLoaded.subscribe(loadHandler); } - await rbd.load(); + await srb.load(); } - return rbd; + return srb; } persist() { @@ -135,6 +140,12 @@ export default class SpawnRulesBehaviorDefinition { this.data = StorageUtilities.getJsonObject(this._file); + this.dataInner = this.data?.["minecraft:spawn_rules"]; + + if (this.dataInner && this.dataInner.description) { + this._id = this.dataInner.description.identifier; + } + this._isLoaded = true; } } diff --git a/app/src/storage/BrowserStorage.ts b/app/src/storage/BrowserStorage.ts index 6b6d7a37..a7868e32 100644 --- a/app/src/storage/BrowserStorage.ts +++ b/app/src/storage/BrowserStorage.ts @@ -12,15 +12,7 @@ export default class BrowserStorage extends StorageBase implements IStorage { static readonly folderDelimiter = "/"; - constructor(name: string | null) { - super(); - - if (name == null) { - name = ""; - } else { - name = "." + name; - } - + static ensureConfigured() { if (!BrowserStorage.isConfigured) { localforage.config({ name: "Minecraft Creator Tools", @@ -30,6 +22,18 @@ export default class BrowserStorage extends StorageBase implements IStorage { BrowserStorage.isConfigured = true; } + } + + constructor(name: string | null) { + super(); + + if (name == null) { + name = ""; + } else { + name = "." + name; + } + + BrowserStorage.ensureConfigured(); this.rootFolder = new BrowserFolder(this, null, "fs" + name, "root"); } diff --git a/app/src/storage/StorageUtilities.ts b/app/src/storage/StorageUtilities.ts index de157ca4..50593266 100644 --- a/app/src/storage/StorageUtilities.ts +++ b/app/src/storage/StorageUtilities.ts @@ -726,6 +726,7 @@ export default class StorageUtilities { folderName.startsWith(".") || folderName === "lib" || folderName === "node_modules" || + folderName === ".git" || folderName === "dist" || folderName === "build" ) { diff --git a/app/src/test/CommandLineTest.ts b/app/src/test/CommandLineTest.ts index 0c52d825..f590e715 100644 --- a/app/src/test/CommandLineTest.ts +++ b/app/src/test/CommandLineTest.ts @@ -106,10 +106,15 @@ function removeResultFolder(scenarioName: string) { // guard against being called at a "more root" file path if (fs.existsSync(path) && Utilities.countChar(path, NodeStorage.folderDelimiter) > 5) - // @ts-ignore - fs.rmSync(path, { - recursive: true, - }); + try { + fs.rmSync(path, { + recursive: true, + }); + } catch (e) { + console.log("Error occurred during rmSync on '" + path + "'"); + + throw e; + } } } diff --git a/app/test/scenarios/createCommandAddonStarter/.env b/app/test/scenarios/createCommandAddonStarter/.env index bafce30d..0b3094b3 100644 --- a/app/test/scenarios/createCommandAddonStarter/.env +++ b/app/test/scenarios/createCommandAddonStarter/.env @@ -1,3 +1,3 @@ -PROJECT_NAME="aop_mobs" +PROJECT_NAME="cn_test" MINECRAFT_PRODUCT="BedrockUWP" -CUSTOM_DEPLOYMENT_PATH="" \ No newline at end of file +CUSTOM_DEPLOYMENT_PATH="" diff --git a/app/test/scenarios/createCommandAddonStarter/eslint.config.mjs b/app/test/scenarios/createCommandAddonStarter/eslint.config.mjs index 0c863ca9..ba76efd9 100644 --- a/app/test/scenarios/createCommandAddonStarter/eslint.config.mjs +++ b/app/test/scenarios/createCommandAddonStarter/eslint.config.mjs @@ -1,7 +1,6 @@ import minecraftLinting from "eslint-plugin-minecraft-linting"; import tsParser from "@typescript-eslint/parser"; import ts from "@typescript-eslint/eslint-plugin"; - export default [ { files: ["scripts/**/*.ts"], @@ -17,4 +16,4 @@ export default [ "minecraft-linting/avoid-unnecessary-command": "error", }, }, -]; +]; \ No newline at end of file diff --git a/app/test/scenarios/createCommandAddonStarter/just.config.ts b/app/test/scenarios/createCommandAddonStarter/just.config.ts index 543c5694..a66c34af 100644 --- a/app/test/scenarios/createCommandAddonStarter/just.config.ts +++ b/app/test/scenarios/createCommandAddonStarter/just.config.ts @@ -16,11 +16,8 @@ import { watchTask, } from "@minecraft/core-build-tasks"; import path from "path"; - -// Setup env variables setupEnvironment(path.resolve(__dirname, ".env")); const projectName = getOrThrowFromProcess("PROJECT_NAME"); - const bundleTaskOptions: BundleTaskParameters = { entryPoint: path.join(__dirname, "./scripts/main.ts"), external: ["@minecraft/server", "@minecraft/server-ui"], @@ -29,44 +26,30 @@ const bundleTaskOptions: BundleTaskParameters = { sourcemap: true, outputSourcemapPath: path.resolve(__dirname, "./dist/debug"), }; - const copyTaskOptions: CopyTaskParameters = { copyToBehaviorPacks: [`./behavior_packs/${projectName}`], copyToScripts: ["./dist/scripts"], copyToResourcePacks: [`./resource_packs/${projectName}`], }; - const mcaddonTaskOptions: ZipTaskParameters = { ...copyTaskOptions, outputFile: `./dist/packages/${projectName}.mcaddon`, }; - -// Lint task("lint", coreLint(["scripts/**/*.ts"], argv().fix)); - -// Build task("typescript", tscTask()); task("bundle", bundleTask(bundleTaskOptions)); task("build", series("typescript", "bundle")); - -// Clean task("clean-local", cleanTask(DEFAULT_CLEAN_DIRECTORIES)); task("clean-collateral", cleanCollateralTask(STANDARD_CLEAN_PATHS)); task("clean", parallel("clean-local", "clean-collateral")); - -// Package task("copyArtifacts", copyTask(copyTaskOptions)); task("package", series("clean-collateral", "copyArtifacts")); - -// Local Deploy used for deploying local changes directly to output via the bundler. It does a full build and package first just in case. task( "local-deploy", watchTask( - ["scripts/**/*.ts", "behavior_packs/**/*.{json,lang,png}", "resource_packs/**/*.{json,lang,png}"], + ["scripts/**/*.ts", "behavior_packs/**/*.{json,lang,tga,ogg,png}", "resource_packs/**/*.{json,lang,tga,ogg,png}"], series("clean-local", "build", "package") ) ); - -// Mcaddon task("createMcaddonFile", mcaddonTask(mcaddonTaskOptions)); -task("mcaddon", series("clean-local", "build", "createMcaddonFile")); +task("mcaddon", series("clean-local", "build", "createMcaddonFile")); \ No newline at end of file diff --git a/app/test/scenarios/createCommandAddonStarter/package-lock.json b/app/test/scenarios/createCommandAddonStarter/package-lock.json deleted file mode 100644 index 5391d075..00000000 --- a/app/test/scenarios/createCommandAddonStarter/package-lock.json +++ /dev/null @@ -1,4633 +0,0 @@ -{ - "name": "addon_starter", - "version": "0.1.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "addon_starter", - "version": "0.1.0", - "dependencies": { - "@minecraft/math": "^1.1.0", - "@minecraft/server": "^1.8.0", - "@minecraft/server-ui": "^1.1.0", - "@minecraft/vanilla-data": "^1.20.60" - }, - "devDependencies": { - "@minecraft/core-build-tasks": "^1.1.3", - "eslint-plugin-minecraft-linting": "^1.2.1", - "source-map": "^0.7.4", - "ts-node": "^10.9.1", - "typescript": "^5.0.2" - } - }, - "node_modules/@aashutoshrathi/word-wrap": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", - "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", - "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", - "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", - "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", - "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", - "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", - "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", - "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", - "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", - "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", - "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", - "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", - "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", - "cpu": [ - "loong64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", - "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", - "cpu": [ - "mips64el" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", - "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", - "cpu": [ - "ppc64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", - "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", - "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", - "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", - "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", - "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", - "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", - "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", - "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.20.2.tgz", - "integrity": "sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=12" - } - }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", - "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" - } - }, - "node_modules/@eslint-community/regexpp": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", - "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", - "dev": true, - "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" - } - }, - "node_modules/@eslint/eslintrc": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", - "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.6.0", - "globals": "^13.19.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/@eslint/js": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", - "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.14", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", - "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^2.0.2", - "debug": "^4.3.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "node_modules/@humanwhocodes/object-schema": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", - "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", - "dev": true - }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", - "dev": true, - "dependencies": { - "@sinclair/typebox": "^0.27.8" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", - "dev": true - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "node_modules/@microsoft/api-extractor": { - "version": "7.42.3", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.42.3.tgz", - "integrity": "sha512-JNLJFpGHz6ekjS6bvYXxUBeRGnSHeCMFNvRbCQ+7XXB/ZFrgLSMPwWtEq40AiWAy+oyG5a4RSNwdJTp0B2USvQ==", - "dev": true, - "dependencies": { - "@microsoft/api-extractor-model": "7.28.13", - "@microsoft/tsdoc": "0.14.2", - "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "4.0.2", - "@rushstack/rig-package": "0.5.2", - "@rushstack/terminal": "0.10.0", - "@rushstack/ts-command-line": "4.19.1", - "lodash": "~4.17.15", - "minimatch": "~3.0.3", - "resolve": "~1.22.1", - "semver": "~7.5.4", - "source-map": "~0.6.1", - "typescript": "5.3.3" - }, - "bin": { - "api-extractor": "bin/api-extractor" - } - }, - "node_modules/@microsoft/api-extractor-model": { - "version": "7.28.13", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.28.13.tgz", - "integrity": "sha512-39v/JyldX4MS9uzHcdfmjjfS6cYGAoXV+io8B5a338pkHiSt+gy2eXQ0Q7cGFJ7quSa1VqqlMdlPrB6sLR/cAw==", - "dev": true, - "dependencies": { - "@microsoft/tsdoc": "0.14.2", - "@microsoft/tsdoc-config": "~0.16.1", - "@rushstack/node-core-library": "4.0.2" - } - }, - "node_modules/@microsoft/api-extractor-model/node_modules/@rushstack/node-core-library": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.0.2.tgz", - "integrity": "sha512-hyES82QVpkfQMeBMteQUnrhASL/KHPhd7iJ8euduwNJG4mu2GSOKybf0rOEjOm1Wz7CwJEUm9y0yD7jg2C1bfg==", - "dev": true, - "dependencies": { - "fs-extra": "~7.0.1", - "import-lazy": "~4.0.0", - "jju": "~1.4.0", - "resolve": "~1.22.1", - "semver": "~7.5.4", - "z-schema": "~5.0.2" - }, - "peerDependencies": { - "@types/node": "*" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@microsoft/api-extractor/node_modules/@rushstack/node-core-library": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.0.2.tgz", - "integrity": "sha512-hyES82QVpkfQMeBMteQUnrhASL/KHPhd7iJ8euduwNJG4mu2GSOKybf0rOEjOm1Wz7CwJEUm9y0yD7jg2C1bfg==", - "dev": true, - "dependencies": { - "fs-extra": "~7.0.1", - "import-lazy": "~4.0.0", - "jju": "~1.4.0", - "resolve": "~1.22.1", - "semver": "~7.5.4", - "z-schema": "~5.0.2" - }, - "peerDependencies": { - "@types/node": "*" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@microsoft/api-extractor/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==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@microsoft/api-extractor/node_modules/typescript": { - "version": "5.3.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", - "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/@microsoft/tsdoc": { - "version": "0.14.2", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.14.2.tgz", - "integrity": "sha512-9b8mPpKrfeGRuhFH5iO1iwCLeIIsV6+H1sRfxbkoGXIyQE2BTsPd9zqSqQJ+pv5sJ/hT5M1zvOFL02MnEezFug==", - "dev": true - }, - "node_modules/@microsoft/tsdoc-config": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.16.2.tgz", - "integrity": "sha512-OGiIzzoBLgWWR0UdRJX98oYO+XKGf7tiK4Zk6tQ/E4IJqGCe7dvkTvgDZV5cFJUzLGDOjeAXrnZoA6QkVySuxw==", - "dev": true, - "dependencies": { - "@microsoft/tsdoc": "0.14.2", - "ajv": "~6.12.6", - "jju": "~1.4.0", - "resolve": "~1.19.0" - } - }, - "node_modules/@microsoft/tsdoc-config/node_modules/resolve": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", - "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", - "dev": true, - "dependencies": { - "is-core-module": "^2.1.0", - "path-parse": "^1.0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/@minecraft/common": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@minecraft/common/-/common-1.2.0.tgz", - "integrity": "sha512-JdmEq4P3Z/FtoBzhLijFgMSVFnFRrUoLwY8DHHrgtFo0mfLTOLTB1RErYjLMsA6b7BGVNxkX/pfFRiH7QZ0XwQ==" - }, - "node_modules/@minecraft/core-build-tasks": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@minecraft/core-build-tasks/-/core-build-tasks-1.1.3.tgz", - "integrity": "sha512-gjNYm9XNYP0eAirUuo3LfKLpZKQG+PLaFbpwXIvi/lCiN0rctOlC450POV8GdyOP4vkJKbKE0iwjhVpD+03XVw==", - "dev": true, - "dependencies": { - "@microsoft/api-extractor": "^7.38.3", - "@rushstack/node-core-library": "^3.59.6", - "dotenv": "^16.0.2", - "esbuild": "^0.20.1", - "just-scripts": "^2.2.1", - "prettier": "^2.8.2", - "rimraf": "^3.0.2", - "vitest": "^0.34.6", - "zip-lib": "^0.7.3" - } - }, - "node_modules/@minecraft/math": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/@minecraft/math/-/math-1.3.4.tgz", - "integrity": "sha512-QoVkHVoA8oAsTmQoGnFpm7n4UHx+t9o2D7O4Tiy4xMokv38HczwRT9x/LzUyvFu0felF1nRVBTH/d8QxW1GhoA==", - "peerDependencies": { - "@minecraft/server": "^1.6.0" - } - }, - "node_modules/@minecraft/server": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@minecraft/server/-/server-1.9.0.tgz", - "integrity": "sha512-PhOLfCYM83t24TY3+8WA5zCRGCyG/89VC6ZSi4Ye92QZORC/0Td5JIh2ctJtUhAiYCbct/Ph/Of3BCi8/itr6A==", - "dependencies": { - "@minecraft/common": "^1.1.0" - } - }, - "node_modules/@minecraft/server-ui": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@minecraft/server-ui/-/server-ui-1.1.0.tgz", - "integrity": "sha512-Gnf+GHjjT4VFoXEt7qjrfDRipDgc93YcXbgTmdPTQ5Og3DIRD003ahH97tGMZmeNdsB+ymvAquf+o2o9W2pDjw==", - "dependencies": { - "@minecraft/server": "^1.2.0" - } - }, - "node_modules/@minecraft/vanilla-data": { - "version": "1.20.70", - "resolved": "https://registry.npmjs.org/@minecraft/vanilla-data/-/vanilla-data-1.20.70.tgz", - "integrity": "sha512-t6NGlfaI7d/HyQFrHe2rvqPujdlRkTz7futtKoFilC7bh/9ZjA8Hu4LTPI597zJd3SdR1I9Rp8dwooK2apDLSg==" - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.13.0.tgz", - "integrity": "sha512-5ZYPOuaAqEH/W3gYsRkxQATBW3Ii1MfaT4EQstTnLKViLi2gLSQmlmtTpGucNP3sXEpOiI5tdGhjdE111ekyEg==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-android-arm64": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.13.0.tgz", - "integrity": "sha512-BSbaCmn8ZadK3UAQdlauSvtaJjhlDEjS5hEVVIN3A4bbl3X+otyf/kOJV08bYiRxfejP3DXFzO2jz3G20107+Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "android" - ] - }, - "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.13.0.tgz", - "integrity": "sha512-Ovf2evVaP6sW5Ut0GHyUSOqA6tVKfrTHddtmxGQc1CTQa1Cw3/KMCDEEICZBbyppcwnhMwcDce9ZRxdWRpVd6g==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.13.0.tgz", - "integrity": "sha512-U+Jcxm89UTK592vZ2J9st9ajRv/hrwHdnvyuJpa5A2ngGSVHypigidkQJP+YiGL6JODiUeMzkqQzbCG3At81Gg==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.13.0.tgz", - "integrity": "sha512-8wZidaUJUTIR5T4vRS22VkSMOVooG0F4N+JSwQXWSRiC6yfEsFMLTYRFHvby5mFFuExHa/yAp9juSphQQJAijQ==", - "cpu": [ - "arm" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.13.0.tgz", - "integrity": "sha512-Iu0Kno1vrD7zHQDxOmvweqLkAzjxEVqNhUIXBsZ8hu8Oak7/5VTPrxOEZXYC1nmrBVJp0ZcL2E7lSuuOVaE3+w==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.13.0.tgz", - "integrity": "sha512-C31QrW47llgVyrRjIwiOwsHFcaIwmkKi3PCroQY5aVq4H0A5v/vVVAtFsI1nfBngtoRpeREvZOkIhmRwUKkAdw==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.13.0.tgz", - "integrity": "sha512-Oq90dtMHvthFOPMl7pt7KmxzX7E71AfyIhh+cPhLY9oko97Zf2C9tt/XJD4RgxhaGeAraAXDtqxvKE1y/j35lA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.13.0.tgz", - "integrity": "sha512-yUD/8wMffnTKuiIsl6xU+4IA8UNhQ/f1sAnQebmE/lyQ8abjsVyDkyRkWop0kdMhKMprpNIhPmYlCxgHrPoXoA==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.13.0.tgz", - "integrity": "sha512-9RyNqoFNdF0vu/qqX63fKotBh43fJQeYC98hCaf89DYQpv+xu0D8QFSOS0biA7cGuqJFOc1bJ+m2rhhsKcw1hw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.13.0.tgz", - "integrity": "sha512-46ue8ymtm/5PUU6pCvjlic0z82qWkxv54GTJZgHrQUuZnVH+tvvSP0LsozIDsCBFO4VjJ13N68wqrKSeScUKdA==", - "cpu": [ - "arm64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.13.0.tgz", - "integrity": "sha512-P5/MqLdLSlqxbeuJ3YDeX37srC8mCflSyTrUsgbU1c/U9j6l2g2GiIdYaGD9QjdMQPMSgYm7hgg0551wHyIluw==", - "cpu": [ - "ia32" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.13.0.tgz", - "integrity": "sha512-UKXUQNbO3DOhzLRwHSpa0HnhhCgNODvfoPWv2FCXme8N/ANFfhIPMGuOT+QuKd16+B5yxZ0HdpNlqPvTMS1qfw==", - "cpu": [ - "x64" - ], - "dev": true, - "optional": true, - "os": [ - "win32" - ] - }, - "node_modules/@rushstack/node-core-library": { - "version": "3.66.1", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-3.66.1.tgz", - "integrity": "sha512-ker69cVKAoar7MMtDFZC4CzcDxjwqIhFzqEnYI5NRN/8M3om6saWCVx/A7vL2t/jFCJsnzQplRDqA7c78pytng==", - "dev": true, - "dependencies": { - "colors": "~1.2.1", - "fs-extra": "~7.0.1", - "import-lazy": "~4.0.0", - "jju": "~1.4.0", - "resolve": "~1.22.1", - "semver": "~7.5.4", - "z-schema": "~5.0.2" - }, - "peerDependencies": { - "@types/node": "*" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@rushstack/package-deps-hash": { - "version": "4.1.39", - "resolved": "https://registry.npmjs.org/@rushstack/package-deps-hash/-/package-deps-hash-4.1.39.tgz", - "integrity": "sha512-uIP1drAVJk/njhACBnD/kPI7vyM8mVbSBs+igiRiedeR9cf5Dp7ChLOfaBq5pJFHOHrLVtXVIjECZxrX5WeQRQ==", - "dev": true, - "dependencies": { - "@rushstack/node-core-library": "4.0.2" - } - }, - "node_modules/@rushstack/package-deps-hash/node_modules/@rushstack/node-core-library": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.0.2.tgz", - "integrity": "sha512-hyES82QVpkfQMeBMteQUnrhASL/KHPhd7iJ8euduwNJG4mu2GSOKybf0rOEjOm1Wz7CwJEUm9y0yD7jg2C1bfg==", - "dev": true, - "dependencies": { - "fs-extra": "~7.0.1", - "import-lazy": "~4.0.0", - "jju": "~1.4.0", - "resolve": "~1.22.1", - "semver": "~7.5.4", - "z-schema": "~5.0.2" - }, - "peerDependencies": { - "@types/node": "*" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@rushstack/rig-package": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.2.tgz", - "integrity": "sha512-mUDecIJeH3yYGZs2a48k+pbhM6JYwWlgjs2Ca5f2n1G2/kgdgP9D/07oglEGf6mRyXEnazhEENeYTSNDRCwdqA==", - "dev": true, - "dependencies": { - "resolve": "~1.22.1", - "strip-json-comments": "~3.1.1" - } - }, - "node_modules/@rushstack/terminal": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.10.0.tgz", - "integrity": "sha512-UbELbXnUdc7EKwfH2sb8ChqNgapUOdqcCIdQP4NGxBpTZV2sQyeekuK3zmfQSa/MN+/7b4kBogl2wq0vpkpYGw==", - "dev": true, - "dependencies": { - "@rushstack/node-core-library": "4.0.2", - "supports-color": "~8.1.1" - }, - "peerDependencies": { - "@types/node": "*" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@rushstack/terminal/node_modules/@rushstack/node-core-library": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-4.0.2.tgz", - "integrity": "sha512-hyES82QVpkfQMeBMteQUnrhASL/KHPhd7iJ8euduwNJG4mu2GSOKybf0rOEjOm1Wz7CwJEUm9y0yD7jg2C1bfg==", - "dev": true, - "dependencies": { - "fs-extra": "~7.0.1", - "import-lazy": "~4.0.0", - "jju": "~1.4.0", - "resolve": "~1.22.1", - "semver": "~7.5.4", - "z-schema": "~5.0.2" - }, - "peerDependencies": { - "@types/node": "*" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/@rushstack/ts-command-line": { - "version": "4.19.1", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-4.19.1.tgz", - "integrity": "sha512-J7H768dgcpG60d7skZ5uSSwyCZs/S2HrWP1Ds8d1qYAyaaeJmpmmLr9BVw97RjFzmQPOYnoXcKA4GkqDCkduQg==", - "dev": true, - "dependencies": { - "@rushstack/terminal": "0.10.0", - "@types/argparse": "1.0.38", - "argparse": "~1.0.9", - "string-argv": "~0.3.1" - } - }, - "node_modules/@sinclair/typebox": { - "version": "0.27.8", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", - "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", - "dev": true - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", - "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", - "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", - "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.4.tgz", - "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", - "dev": true - }, - "node_modules/@types/argparse": { - "version": "1.0.38", - "resolved": "https://registry.npmjs.org/@types/argparse/-/argparse-1.0.38.tgz", - "integrity": "sha512-ebDJ9b0e702Yr7pWgB0jzm+CX4Srzz8RcXtLJDJB+BSccqMa36uyH/zUsSYao5+BD1ytv3k3rPYCq4mAE1hsXA==", - "dev": true - }, - "node_modules/@types/chai": { - "version": "4.3.12", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.12.tgz", - "integrity": "sha512-zNKDHG/1yxm8Il6uCCVsm+dRdEsJlFoDu73X17y09bId6UwoYww+vFBsAcRzl8knM1sab3Dp1VRikFQwDOtDDw==", - "dev": true - }, - "node_modules/@types/chai-subset": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/chai-subset/-/chai-subset-1.3.5.tgz", - "integrity": "sha512-c2mPnw+xHtXDoHmdtcCXGwyLMiauiAyxWMzhGpqHC4nqI/Y5G2XhTampslK2rb59kpcuHon03UH8W6iYUzw88A==", - "dev": true, - "dependencies": { - "@types/chai": "*" - } - }, - "node_modules/@types/chokidar": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@types/chokidar/-/chokidar-2.1.3.tgz", - "integrity": "sha512-6qK3xoLLAhQVTucQGHTySwOVA1crHRXnJeLwqK6KIFkkKa2aoMFXh+WEi8PotxDtvN6MQJLyYN9ag9P6NLV81w==", - "deprecated": "This is a stub types definition. chokidar provides its own type definitions, so you do not need this installed.", - "dev": true, - "dependencies": { - "chokidar": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", - "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", - "dev": true - }, - "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 - }, - "node_modules/@types/node": { - "version": "20.11.28", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.28.tgz", - "integrity": "sha512-M/GPWVS2wLkSkNHVeLkrF2fD5Lx5UC4PxA0uZcKc6QqbIQUJyW1jVjueJYi1z8n0I5PxYrtpnPnWglE+y9A0KA==", - "dev": true, - "dependencies": { - "undici-types": "~5.26.4" - } - }, - "node_modules/@types/semver": { - "version": "7.5.8", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", - "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", - "dev": true - }, - "node_modules/@types/undertaker": { - "version": "1.2.11", - "resolved": "https://registry.npmjs.org/@types/undertaker/-/undertaker-1.2.11.tgz", - "integrity": "sha512-j1Z0V2ByRHr8ZK7eOeGq0LGkkdthNFW0uAZGY22iRkNQNL9/vAV0yFPr1QN3FM/peY5bxs9P+1f0PYJTQVa5iA==", - "dev": true, - "dependencies": { - "@types/node": "*", - "@types/undertaker-registry": "*", - "async-done": "~1.3.2" - } - }, - "node_modules/@types/undertaker-registry": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@types/undertaker-registry/-/undertaker-registry-1.0.4.tgz", - "integrity": "sha512-tW77pHh2TU4uebWXWeEM5laiw8BuJ7pyJYDh6xenOs75nhny2kVgwYbegJ4BoLMYsIrXaBpKYaPdYO3/udG+hg==", - "dev": true - }, - "node_modules/@types/yargs-parser": { - "version": "20.2.5", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-20.2.5.tgz", - "integrity": "sha512-pAJfNtUhU/xDwMKb3rR8MnEUSqHIfsmo3vw09baYY0rEp6AzM6Mb5ZzTuZbe/YXiYL04E6coxe+3qhVOVG98dA==", - "dev": true - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.3.0.tgz", - "integrity": "sha512-e65ii0Y/jkqX3GXSBM7v9qt9ufxd4omcWyPVVC/msq/hP+hYC6CddLRvlvclni+u7UcaNYT/QhBYlaMHaR2ixw==", - "dev": true, - "dependencies": { - "@eslint-community/regexpp": "^4.5.1", - "@typescript-eslint/scope-manager": "7.3.0", - "@typescript-eslint/type-utils": "7.3.0", - "@typescript-eslint/utils": "7.3.0", - "@typescript-eslint/visitor-keys": "7.3.0", - "debug": "^4.3.4", - "graphemer": "^1.4.0", - "ignore": "^5.2.4", - "natural-compare": "^1.4.0", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^7.0.0", - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.3.0.tgz", - "integrity": "sha512-OZcvH8zipGILuxJmtFgzjAJ+bOpWidzEppIRsT2P4ZUrizU0EsPt4hhzDn3lNfM1Hv7slZPTEQGKjUEn/ftQYA==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "7.3.0", - "@typescript-eslint/types": "7.3.0", - "@typescript-eslint/typescript-estree": "7.3.0", - "@typescript-eslint/visitor-keys": "7.3.0", - "debug": "^4.3.4" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.3.0.tgz", - "integrity": "sha512-KlG7xH3J/+nHpZRcYeskO5QVJCnnssxYKBlrj3MoyMONihn3P4xu5jIelrS5YWvBjbytgHmFkzjDApranoYkNA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.3.0", - "@typescript-eslint/visitor-keys": "7.3.0" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.3.0.tgz", - "integrity": "sha512-TyQ19ydo248eFjTfHFSvZbxalFUOxU9o2M6SUk3wOA0yRF1ZiB2VP5iaoLrGKcg7TyUxS4knYIHnE55ih82Cfg==", - "dev": true, - "dependencies": { - "@typescript-eslint/typescript-estree": "7.3.0", - "@typescript-eslint/utils": "7.3.0", - "debug": "^4.3.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.3.0.tgz", - "integrity": "sha512-oYCBkD0xVxzmZZmYiIWVewyy/q/ugq7PPm4pHhE1IgcT062i96G0Ww3gd8BvUYpk2yvg95q00Hj2CHRLjAuZBA==", - "dev": true, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.3.0.tgz", - "integrity": "sha512-UF85+bInQZ3olhI/zxv0c2b2SMuymn3t6/lkRkSB239HHxFmPSlmcggOKAjYzqRCdtqhPDftpsV1LlDH66AXrA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.3.0", - "@typescript-eslint/visitor-keys": "7.3.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "minimatch": "9.0.3", - "semver": "^7.5.4", - "ts-api-utils": "^1.0.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", - "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.3.0.tgz", - "integrity": "sha512-7PKIDoe2ppR1SK56TLv7WQXrdHqEiueVwLVIjdSR4ROY2LprmJenf4+tT8iJIfxrsPzjSJGNeQ7GVmfoYbqrhw==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.4.0", - "@types/json-schema": "^7.0.12", - "@types/semver": "^7.5.0", - "@typescript-eslint/scope-manager": "7.3.0", - "@typescript-eslint/types": "7.3.0", - "@typescript-eslint/typescript-estree": "7.3.0", - "semver": "^7.5.4" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^8.56.0" - } - }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "7.3.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.3.0.tgz", - "integrity": "sha512-Gz8Su+QjOI5qP8UQ74VqKaTt/BLy23IhCCHLbYxhmNzHCGFHrvfgq4hISZvuqQ690ubkD0746qLcWC647nScuQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "7.3.0", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^18.18.0 || >=20.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@ungap/structured-clone": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true - }, - "node_modules/@vitest/expect": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-0.34.6.tgz", - "integrity": "sha512-QUzKpUQRc1qC7qdGo7rMK3AkETI7w18gTCUrsNnyjjJKYiuUB9+TQK3QnR1unhCnWRC0AbKv2omLGQDF/mIjOw==", - "dev": true, - "dependencies": { - "@vitest/spy": "0.34.6", - "@vitest/utils": "0.34.6", - "chai": "^4.3.10" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/runner": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-0.34.6.tgz", - "integrity": "sha512-1CUQgtJSLF47NnhN+F9X2ycxUP0kLHQ/JWvNHbeBfwW8CzEGgeskzNnHDyv1ieKTltuR6sdIHV+nmR6kPxQqzQ==", - "dev": true, - "dependencies": { - "@vitest/utils": "0.34.6", - "p-limit": "^4.0.0", - "pathe": "^1.1.1" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/runner/node_modules/p-limit": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", - "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^1.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@vitest/runner/node_modules/yocto-queue": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.0.0.tgz", - "integrity": "sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==", - "dev": true, - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@vitest/snapshot": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-0.34.6.tgz", - "integrity": "sha512-B3OZqYn6k4VaN011D+ve+AA4whM4QkcwcrwaKwAbyyvS/NB1hCWjFIBQxAQQSQir9/RtyAAGuq+4RJmbn2dH4w==", - "dev": true, - "dependencies": { - "magic-string": "^0.30.1", - "pathe": "^1.1.1", - "pretty-format": "^29.5.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/spy": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-0.34.6.tgz", - "integrity": "sha512-xaCvneSaeBw/cz8ySmF7ZwGvL0lBjfvqc1LpQ/vcdHEvpLn3Ff1vAvjw+CoGn0802l++5L/pxb7whwcWAw+DUQ==", - "dev": true, - "dependencies": { - "tinyspy": "^2.1.1" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/@vitest/utils": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-0.34.6.tgz", - "integrity": "sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A==", - "dev": true, - "dependencies": { - "diff-sequences": "^29.4.3", - "loupe": "^2.3.6", - "pretty-format": "^29.5.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/acorn": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.3.tgz", - "integrity": "sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.2.tgz", - "integrity": "sha512-cjkyv4OtNCIeqhHrfS81QWXoCBPExR/J62oyEqepVw8WaQeSqpW2uhuLPh1m9eWhDuOo/jUXVTlifvesOWp/4A==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "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, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/arr-filter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz", - "integrity": "sha512-A2BETWCqhsecSvCkWAeVBFLH6sXEUGASuzkpjL3GR1SlL/PWL6M3J8EAAld2Uubmh39tvkJTqC9LeLHCUKmFXA==", - "dev": true, - "dependencies": { - "make-iterator": "^1.0.0" - }, - "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==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz", - "integrity": "sha512-tVqVTHt+Q5Xb09qRkbu+DidW1yYzz5izWS2Xm2yFm7qJnmUfz4HPzNxbHkdRJbz2lrqI7S+z17xNYdFcBBO8Hw==", - "dev": true, - "dependencies": { - "make-iterator": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", - "integrity": "sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-initial": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz", - "integrity": "sha512-BC4Yl89vneCYfpLrs5JU2aAu9/a+xWbeKhvISg9PT7eWFB9UlRvI+rKEtk6mgxWr3dSkk9gQ8hCrdqt06NXPdw==", - "dev": true, - "dependencies": { - "array-slice": "^1.0.0", - "is-number": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-initial/node_modules/is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-last": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz", - "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==", - "dev": true, - "dependencies": { - "is-number": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-last/node_modules/is-number": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-slice": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", - "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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, - "engines": { - "node": ">=8" - } - }, - "node_modules/assertion-error": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/async-done": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz", - "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.2", - "process-nextick-args": "^2.0.0", - "stream-exhaust": "^1.0.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/async-settle": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-2.0.0.tgz", - "integrity": "sha512-Obu/KE8FurfQRN6ODdHN9LuXqwC+JFIM9NRyZqJJ4ZfLJmIYN9Rg0/kb+wF70VV5+fJusTMQlJ1t5rF7J/ETdg==", - "dev": true, - "dependencies": { - "async-done": "^2.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/async-settle/node_modules/async-done": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/async-done/-/async-done-2.0.0.tgz", - "integrity": "sha512-j0s3bzYq9yKIVLKGE/tWlCpa3PfFLcrDZLTSVdnnCTGagXuXBJO4SsY9Xdk/fQBirCkH4evW5xOeJXqlAQFdsw==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.4.4", - "once": "^1.4.0", - "stream-exhaust": "^1.0.2" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/bach": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/bach/-/bach-2.0.1.tgz", - "integrity": "sha512-A7bvGMGiTOxGMpNupYl9HQTf0FFDNF4VCmks4PJpFyN1AX2pdKuxuwdvUz2Hu388wcgp+OvGFNsumBfFNkR7eg==", - "dev": true, - "dependencies": { - "async-done": "^2.0.0", - "async-settle": "^2.0.0", - "now-and-later": "^3.0.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/bach/node_modules/async-done": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/async-done/-/async-done-2.0.0.tgz", - "integrity": "sha512-j0s3bzYq9yKIVLKGE/tWlCpa3PfFLcrDZLTSVdnnCTGagXuXBJO4SsY9Xdk/fQBirCkH4evW5xOeJXqlAQFdsw==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.4.4", - "once": "^1.4.0", - "stream-exhaust": "^1.0.2" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "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==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/cac": { - "version": "6.7.14", - "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", - "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/chai": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.4.1.tgz", - "integrity": "sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==", - "dev": true, - "dependencies": { - "assertion-error": "^1.1.0", - "check-error": "^1.0.3", - "deep-eql": "^4.1.3", - "get-func-name": "^2.0.2", - "loupe": "^2.3.6", - "pathval": "^1.1.1", - "type-detect": "^4.0.8" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/chalk/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/check-error": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", - "integrity": "sha512-iKEoDYaRmd1mxM90a2OEfWhjsjPpYPuQ+lMYsoxB126+t8fw7ySEO48nmDg5COTjxDI65/Y2OWpeEHk3ZOe8zg==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "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==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/collection-map": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz", - "integrity": "sha512-5D2XXSpkOnleOI21TG7p3T0bGAsZ/XknZpKBmGYyluO8pw4zA3K8ZlrBIbC4FXg3m6z/RNFiUFfT2sQK01+UHA==", - "dev": true, - "dependencies": { - "arr-map": "^2.0.2", - "for-own": "^1.0.0", - "make-iterator": "^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", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/colors": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", - "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", - "dev": true, - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/commander": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz", - "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==", - "dev": true, - "optional": true, - "engines": { - "node": "^12.20.0 || >=14" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true - }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "node_modules/cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/d": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz", - "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==", - "dev": true, - "dependencies": { - "es5-ext": "^0.10.64", - "type": "^2.7.2" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/deep-eql": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.3.tgz", - "integrity": "sha512-WaEtAOpRA1MQ0eohqZjpGD8zdI0Ovsm8mmFhaDN8dvDZzyoUMcYDnf5Y6iu7HTXxf8JDS23qWa4a+hKCDyOPzw==", - "dev": true, - "dependencies": { - "type-detect": "^4.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true - }, - "node_modules/default-resolution": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz", - "integrity": "sha512-2xaP6GiwVwOEbXCGoJ4ufgC76m8cj805jrghScewJC2ZDsb9U0b4BIrba+xt/Uytyd0HvQ6+WymSRTfnYj59GQ==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/diff-match-patch": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/diff-match-patch/-/diff-match-patch-1.0.5.tgz", - "integrity": "sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==", - "dev": true - }, - "node_modules/diff-sequences": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", - "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", - "dev": true, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "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, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dotenv": { - "version": "16.4.5", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", - "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dev": true, - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/es5-ext": { - "version": "0.10.64", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz", - "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "esniff": "^2.0.1", - "next-tick": "^1.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/es6-iterator": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", - "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", - "dev": true, - "dependencies": { - "d": "1", - "es5-ext": "^0.10.35", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/es6-symbol": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz", - "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==", - "dev": true, - "dependencies": { - "d": "^1.0.2", - "ext": "^1.7.0" - }, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/es6-weak-map": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz", - "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", - "dev": true, - "dependencies": { - "d": "1", - "es5-ext": "^0.10.46", - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.1" - } - }, - "node_modules/esbuild": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.20.2.tgz", - "integrity": "sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==", - "dev": true, - "hasInstallScript": true, - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.20.2", - "@esbuild/android-arm": "0.20.2", - "@esbuild/android-arm64": "0.20.2", - "@esbuild/android-x64": "0.20.2", - "@esbuild/darwin-arm64": "0.20.2", - "@esbuild/darwin-x64": "0.20.2", - "@esbuild/freebsd-arm64": "0.20.2", - "@esbuild/freebsd-x64": "0.20.2", - "@esbuild/linux-arm": "0.20.2", - "@esbuild/linux-arm64": "0.20.2", - "@esbuild/linux-ia32": "0.20.2", - "@esbuild/linux-loong64": "0.20.2", - "@esbuild/linux-mips64el": "0.20.2", - "@esbuild/linux-ppc64": "0.20.2", - "@esbuild/linux-riscv64": "0.20.2", - "@esbuild/linux-s390x": "0.20.2", - "@esbuild/linux-x64": "0.20.2", - "@esbuild/netbsd-x64": "0.20.2", - "@esbuild/openbsd-x64": "0.20.2", - "@esbuild/sunos-x64": "0.20.2", - "@esbuild/win32-arm64": "0.20.2", - "@esbuild/win32-ia32": "0.20.2", - "@esbuild/win32-x64": "0.20.2" - } - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/eslint": { - "version": "8.57.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", - "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", - "dev": true, - "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.6.1", - "@eslint/eslintrc": "^2.1.4", - "@eslint/js": "8.57.0", - "@humanwhocodes/config-array": "^0.11.14", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "@ungap/structured-clone": "^1.2.0", - "ajv": "^6.12.4", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.2.2", - "eslint-visitor-keys": "^3.4.3", - "espree": "^9.6.1", - "esquery": "^1.4.2", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.19.0", - "graphemer": "^1.4.0", - "ignore": "^5.2.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.3", - "strip-ansi": "^6.0.1", - "text-table": "^0.2.0" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-plugin-minecraft-linting": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-minecraft-linting/-/eslint-plugin-minecraft-linting-1.2.1.tgz", - "integrity": "sha512-BhWQmo3MHA7/wn0Jl8C8Qexb20ug7xNWqZpFdWIk9FlbMPkUZZsNsf81F0QBU6Ng7Cy+K+OG4R4fqCoG4Zk2eQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/eslint-plugin": "^7.2.0", - "@typescript-eslint/parser": "^7.2.0", - "@typescript-eslint/utils": "^7.2.0", - "eslint": "^8.53.0" - } - }, - "node_modules/eslint-scope": { - "version": "7.2.2", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", - "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/esniff": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", - "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==", - "dev": true, - "dependencies": { - "d": "^1.0.1", - "es5-ext": "^0.10.62", - "event-emitter": "^0.3.5", - "type": "^2.7.2" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/esquery": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", - "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, - "dependencies": { - "estraverse": "^5.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", - "dev": true, - "dependencies": { - "d": "1", - "es5-ext": "~0.10.14" - } - }, - "node_modules/ext": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz", - "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==", - "dev": true, - "dependencies": { - "type": "^2.7.2" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", - "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/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==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true - }, - "node_modules/fastq": { - "version": "1.17.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", - "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "dev": true, - "dependencies": { - "pend": "~1.2.0" - } - }, - "node_modules/file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "bin": { - "flat": "cli.js" - } - }, - "node_modules/flat-cache": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", - "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, - "dependencies": { - "flatted": "^3.2.9", - "keyv": "^4.5.3", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", - "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", - "dev": true - }, - "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==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/for-own": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", - "integrity": "sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==", - "dev": true, - "dependencies": { - "for-in": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/fs-extra": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", - "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-func-name": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.2.tgz", - "integrity": "sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "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/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/globals": { - "version": "13.24.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", - "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "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" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true - }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/ignore": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", - "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-lazy": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", - "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "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==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-core-module": { - "version": "2.13.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", - "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", - "dev": true, - "dependencies": { - "hasown": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "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, - "engines": { - "node": ">=8" - } - }, - "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==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/jju": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/jju/-/jju-1.4.0.tgz", - "integrity": "sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==", - "dev": true - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/js-yaml/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "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", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true - }, - "node_modules/jsonc-parser": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", - "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", - "dev": true - }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/just-scripts": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/just-scripts/-/just-scripts-2.2.3.tgz", - "integrity": "sha512-hL/Xx5zuQRWBWwlFFBZfjKCzhG/gPs3s8HWFPbwa56ieGdvbANkLE0XPpqV1lTDgftg6qKc8mfPGeaCibKwskA==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "diff-match-patch": "1.0.5", - "fs-extra": "^11.0.0", - "glob": "^7.1.3", - "just-scripts-utils": "^2.0.1", - "just-task": ">=1.9.0 <2.0.0", - "prompts": "^2.4.0", - "run-parallel-limit": "^1.0.6", - "semver": "^7.0.0", - "supports-color": "^8.1.0", - "webpack-merge": "^5.7.3" - }, - "bin": { - "just-scripts": "bin/just-scripts.js" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/just-scripts-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/just-scripts-utils/-/just-scripts-utils-2.0.1.tgz", - "integrity": "sha512-1w/XxLA/m90Dx7xZu1+TnBm16wZxOe55Izsi/fH3EIaNOutAYMPwmZiKUrjEAk9qgZUj3t+QMU0Geap0zaM4/g==", - "dev": true, - "dependencies": { - "fs-extra": "^11.0.0", - "just-task-logger": ">=1.2.1 <2.0.0", - "semver": "^7.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/just-scripts-utils/node_modules/fs-extra": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/just-scripts-utils/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/just-scripts-utils/node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/just-scripts/node_modules/fs-extra": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/just-scripts/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/just-scripts/node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/just-task": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/just-task/-/just-task-1.9.0.tgz", - "integrity": "sha512-L04cusZ4XAoCRTwARF1CksFM07geurx2M6ccOtxROc9D/OiXsoOXyV2KMsMHmxVIPbFP8wRRVGf2z68UsrBX0g==", - "dev": true, - "dependencies": { - "@rushstack/package-deps-hash": "^4.0.0", - "@types/chokidar": "^2.1.3", - "@types/undertaker": "^1.2.8", - "@types/yargs-parser": "^20.2.2", - "bach": "^2.0.0", - "chalk": "^4.0.0", - "chokidar": "^3.5.2", - "fs-extra": "^11.0.0", - "just-task-logger": ">=1.2.1 <2.0.0", - "resolve": "^1.19.0", - "undertaker": "^1.3.0", - "undertaker-registry": "^2.0.0", - "yargs-parser": "^20.2.3" - }, - "bin": { - "just": "bin/just.js" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/just-task-logger": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/just-task-logger/-/just-task-logger-1.2.1.tgz", - "integrity": "sha512-OnVvMTqOC44cDzIrQ3F43FCYY3OyBscanV6GzKvm3SlaUj0Pvc2F39jNMARrstg7ILIdWkeNg1+iWRxsOfKxeA==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "yargs-parser": "^20.2.3" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/just-task/node_modules/fs-extra": { - "version": "11.2.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", - "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=14.14" - } - }, - "node_modules/just-task/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/just-task/node_modules/universalify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/keyv": { - "version": "4.5.4", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", - "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/last-run": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz", - "integrity": "sha512-U/VxvpX4N/rFvPzr3qG5EtLKEnNI0emvIQB3/ecEwv+8GHaUKbIB8vxv1Oai5FAF0d0r7LXHhLLe5K/yChm5GQ==", - "dev": true, - "dependencies": { - "default-resolution": "^2.0.0", - "es6-weak-map": "^2.0.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/local-pkg": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.4.3.tgz", - "integrity": "sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==", - "dev": true, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true - }, - "node_modules/lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", - "dev": true - }, - "node_modules/lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==", - "dev": true - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true - }, - "node_modules/loupe": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.7.tgz", - "integrity": "sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==", - "dev": true, - "dependencies": { - "get-func-name": "^2.0.1" - } - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/magic-string": { - "version": "0.30.8", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.8.tgz", - "integrity": "sha512-ISQTe55T2ao7XtlAStud6qwYPZjE4GK1S/BeVPus4jrq6JuOnQ00YKQC581RWhR122W7msZV263KzVeLoqidyQ==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "node_modules/make-iterator": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", - "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/minimatch": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", - "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/mlly": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.6.1.tgz", - "integrity": "sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==", - "dev": true, - "dependencies": { - "acorn": "^8.11.3", - "pathe": "^1.1.2", - "pkg-types": "^1.0.3", - "ufo": "^1.3.2" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - }, - "node_modules/nanoid": { - "version": "3.3.7", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", - "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true - }, - "node_modules/next-tick": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", - "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==", - "dev": true - }, - "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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/now-and-later": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-3.0.0.tgz", - "integrity": "sha512-pGO4pzSdaxhWTGkfSfHx3hVzJVslFPwBp2Myq9MYN/ChfJZF87ochMAXnvz6/58RJSf5ik2q9tXprBBrk2cpcg==", - "dev": true, - "dependencies": { - "once": "^1.4.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/object.defaults": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", - "integrity": "sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA==", - "dev": true, - "dependencies": { - "array-each": "^1.0.1", - "array-slice": "^1.0.0", - "for-own": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.reduce": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz", - "integrity": "sha512-naLhxxpUESbNkRqc35oQ2scZSJueHGQNUfMW/0U37IgN6tE2dgDWg3whf+NEliy3F/QysrO48XKUz/nGPe+AQw==", - "dev": true, - "dependencies": { - "for-own": "^1.0.0", - "make-iterator": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/optionator": { - "version": "0.9.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", - "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", - "dev": true, - "dependencies": { - "@aashutoshrathi/word-wrap": "^1.2.3", - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "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, - "engines": { - "node": ">=8" - } - }, - "node_modules/pathe": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", - "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", - "dev": true - }, - "node_modules/pathval": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", - "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pkg-types": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.0.3.tgz", - "integrity": "sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==", - "dev": true, - "dependencies": { - "jsonc-parser": "^3.2.0", - "mlly": "^1.2.0", - "pathe": "^1.1.0" - } - }, - "node_modules/postcss": { - "version": "8.4.38", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", - "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "dependencies": { - "nanoid": "^3.3.7", - "picocolors": "^1.0.0", - "source-map-js": "^1.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "2.8.8", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", - "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", - "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "node_modules/pretty-format": { - "version": "29.7.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", - "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.6.3", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "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==", - "dev": true - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/punycode": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", - "dev": true, - "dependencies": { - "is-core-module": "^2.13.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rollup": { - "version": "4.13.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.13.0.tgz", - "integrity": "sha512-3YegKemjoQnYKmsBlOHfMLVPPA5xLkQ8MHLLSw/fBrFaVkEayL51DilPpNNLq1exr98F2B1TzrV0FUlN3gWRPg==", - "dev": true, - "dependencies": { - "@types/estree": "1.0.5" - }, - "bin": { - "rollup": "dist/bin/rollup" - }, - "engines": { - "node": ">=18.0.0", - "npm": ">=8.0.0" - }, - "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.13.0", - "@rollup/rollup-android-arm64": "4.13.0", - "@rollup/rollup-darwin-arm64": "4.13.0", - "@rollup/rollup-darwin-x64": "4.13.0", - "@rollup/rollup-linux-arm-gnueabihf": "4.13.0", - "@rollup/rollup-linux-arm64-gnu": "4.13.0", - "@rollup/rollup-linux-arm64-musl": "4.13.0", - "@rollup/rollup-linux-riscv64-gnu": "4.13.0", - "@rollup/rollup-linux-x64-gnu": "4.13.0", - "@rollup/rollup-linux-x64-musl": "4.13.0", - "@rollup/rollup-win32-arm64-msvc": "4.13.0", - "@rollup/rollup-win32-ia32-msvc": "4.13.0", - "@rollup/rollup-win32-x64-msvc": "4.13.0", - "fsevents": "~2.3.2" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/run-parallel-limit": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.1.0.tgz", - "integrity": "sha512-jJA7irRNM91jaKc3Hcl1npHsFLOXOoTkPCUL1JEa1R82O2miplXXRaGdjW/KM/98YQWDhJLiSs793CnXfblJUw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/siginfo": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", - "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", - "dev": true - }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/source-map-js": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", - "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", - "dev": true, - "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", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - }, - "node_modules/stackback": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", - "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", - "dev": true - }, - "node_modules/std-env": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.7.0.tgz", - "integrity": "sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==", - "dev": true - }, - "node_modules/stream-exhaust": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", - "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==", - "dev": true - }, - "node_modules/string-argv": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", - "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", - "dev": true, - "engines": { - "node": ">=0.6.19" - } - }, - "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, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/strip-literal": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-1.3.0.tgz", - "integrity": "sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==", - "dev": true, - "dependencies": { - "acorn": "^8.10.0" - }, - "funding": { - "url": "https://github.com/sponsors/antfu" - } - }, - "node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "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", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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 - }, - "node_modules/tinybench": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.6.0.tgz", - "integrity": "sha512-N8hW3PG/3aOoZAN5V/NSAEDz0ZixDSSt5b/a05iqtpgfLWMSVuCo7w0k2vVvEjdrIoeGqZzweX2WlyioNIHchA==", - "dev": true - }, - "node_modules/tinypool": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-0.7.0.tgz", - "integrity": "sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==", - "dev": true, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/tinyspy": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-2.2.1.tgz", - "integrity": "sha512-KYad6Vy5VDWV4GH3fjpseMQ/XU2BhIYP7Vzd0LG44qRWm/Yt2WCOTicFdvmgo6gWaqooMQCawTtILVQJupKu7A==", - "dev": true, - "engines": { - "node": ">=14.0.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, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/ts-api-utils": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", - "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", - "dev": true, - "engines": { - "node": ">=16" - }, - "peerDependencies": { - "typescript": ">=4.2.0" - } - }, - "node_modules/ts-node": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz", - "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", - "dev": true, - "dependencies": { - "@cspotcode/source-map-support": "^0.8.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.1", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/type": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/type/-/type-2.7.2.tgz", - "integrity": "sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==", - "dev": true - }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/typescript": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.2.tgz", - "integrity": "sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/ufo": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.2.tgz", - "integrity": "sha512-eiutMaL0J2MKdhcOM1tUy13pIrYnyR87fEd8STJQFrrAwImwvlXkxlZEjaKah8r2viPohld08lt73QfLG1NxMg==", - "dev": true - }, - "node_modules/undertaker": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.3.0.tgz", - "integrity": "sha512-/RXwi5m/Mu3H6IHQGww3GNt1PNXlbeCuclF2QYR14L/2CHPz3DFZkvB5hZ0N/QUkiXWCACML2jXViIQEQc2MLg==", - "dev": true, - "dependencies": { - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "bach": "^1.0.0", - "collection-map": "^1.0.0", - "es6-weak-map": "^2.0.1", - "fast-levenshtein": "^1.0.0", - "last-run": "^1.1.0", - "object.defaults": "^1.0.0", - "object.reduce": "^1.0.0", - "undertaker-registry": "^1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/undertaker-registry": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-2.0.0.tgz", - "integrity": "sha512-+hhVICbnp+rlzZMgxXenpvTxpuvA67Bfgtt+O9WOE5jo7w/dyiF1VmoZVIHvP2EkUjsyKyTwYKlLhA+j47m1Ew==", - "dev": true, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/undertaker/node_modules/async-settle": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz", - "integrity": "sha512-VPXfB4Vk49z1LHHodrEQ6Xf7W4gg1w0dAPROHngx7qgDjqmIQ+fXmwgGXTW/ITLai0YLSvWepJOP9EVpMnEAcw==", - "dev": true, - "dependencies": { - "async-done": "^1.2.2" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/undertaker/node_modules/bach": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", - "integrity": "sha512-bZOOfCb3gXBXbTFXq3OZtGR88LwGeJvzu6szttaIzymOTS4ZttBNOWSv7aLZja2EMycKtRYV0Oa8SNKH/zkxvg==", - "dev": true, - "dependencies": { - "arr-filter": "^1.1.1", - "arr-flatten": "^1.0.1", - "arr-map": "^2.0.0", - "array-each": "^1.0.0", - "array-initial": "^1.0.0", - "array-last": "^1.1.1", - "async-done": "^1.2.2", - "async-settle": "^1.0.0", - "now-and-later": "^2.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/undertaker/node_modules/fast-levenshtein": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.1.4.tgz", - "integrity": "sha512-Ia0sQNrMPXXkqVFt6w6M1n1oKo3NfKs+mvaV811Jwir7vAk9a6PVV9VPYf6X3BU97QiLEmuW3uXH9u87zDFfdw==", - "dev": true - }, - "node_modules/undertaker/node_modules/now-and-later": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", - "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", - "dev": true, - "dependencies": { - "once": "^1.3.2" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/undertaker/node_modules/undertaker-registry": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz", - "integrity": "sha512-UR1khWeAjugW3548EfQmL9Z7pGMlBgXteQpr1IZeZBtnkCJQJIJ1Scj0mb9wQaPvUZ9Q17XqW6TIaPchJkyfqw==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true - }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, - "node_modules/validator": { - "version": "13.11.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", - "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/vite": { - "version": "5.2.10", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.2.10.tgz", - "integrity": "sha512-PAzgUZbP7msvQvqdSD+ErD5qGnSFiGOoWmV5yAKUEI0kdhjbH6nMWVyZQC/hSc4aXwc0oJ9aEdIiF9Oje0JFCw==", - "dev": true, - "dependencies": { - "esbuild": "^0.20.1", - "postcss": "^8.4.38", - "rollup": "^4.13.0" - }, - "bin": { - "vite": "bin/vite.js" - }, - "engines": { - "node": "^18.0.0 || >=20.0.0" - }, - "funding": { - "url": "https://github.com/vitejs/vite?sponsor=1" - }, - "optionalDependencies": { - "fsevents": "~2.3.3" - }, - "peerDependencies": { - "@types/node": "^18.0.0 || >=20.0.0", - "less": "*", - "lightningcss": "^1.21.0", - "sass": "*", - "stylus": "*", - "sugarss": "*", - "terser": "^5.4.0" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - }, - "less": { - "optional": true - }, - "lightningcss": { - "optional": true - }, - "sass": { - "optional": true - }, - "stylus": { - "optional": true - }, - "sugarss": { - "optional": true - }, - "terser": { - "optional": true - } - } - }, - "node_modules/vite-node": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-0.34.6.tgz", - "integrity": "sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==", - "dev": true, - "dependencies": { - "cac": "^6.7.14", - "debug": "^4.3.4", - "mlly": "^1.4.0", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "vite": "^3.0.0 || ^4.0.0 || ^5.0.0-0" - }, - "bin": { - "vite-node": "vite-node.mjs" - }, - "engines": { - "node": ">=v14.18.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - } - }, - "node_modules/vitest": { - "version": "0.34.6", - "resolved": "https://registry.npmjs.org/vitest/-/vitest-0.34.6.tgz", - "integrity": "sha512-+5CALsOvbNKnS+ZHMXtuUC7nL8/7F1F2DnHGjSsszX8zCjWSSviphCb/NuS9Nzf4Q03KyyDRBAXhF/8lffME4Q==", - "dev": true, - "dependencies": { - "@types/chai": "^4.3.5", - "@types/chai-subset": "^1.3.3", - "@types/node": "*", - "@vitest/expect": "0.34.6", - "@vitest/runner": "0.34.6", - "@vitest/snapshot": "0.34.6", - "@vitest/spy": "0.34.6", - "@vitest/utils": "0.34.6", - "acorn": "^8.9.0", - "acorn-walk": "^8.2.0", - "cac": "^6.7.14", - "chai": "^4.3.10", - "debug": "^4.3.4", - "local-pkg": "^0.4.3", - "magic-string": "^0.30.1", - "pathe": "^1.1.1", - "picocolors": "^1.0.0", - "std-env": "^3.3.3", - "strip-literal": "^1.0.1", - "tinybench": "^2.5.0", - "tinypool": "^0.7.0", - "vite": "^3.1.0 || ^4.0.0 || ^5.0.0-0", - "vite-node": "0.34.6", - "why-is-node-running": "^2.2.2" - }, - "bin": { - "vitest": "vitest.mjs" - }, - "engines": { - "node": ">=v14.18.0" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "@edge-runtime/vm": "*", - "@vitest/browser": "*", - "@vitest/ui": "*", - "happy-dom": "*", - "jsdom": "*", - "playwright": "*", - "safaridriver": "*", - "webdriverio": "*" - }, - "peerDependenciesMeta": { - "@edge-runtime/vm": { - "optional": true - }, - "@vitest/browser": { - "optional": true - }, - "@vitest/ui": { - "optional": true - }, - "happy-dom": { - "optional": true - }, - "jsdom": { - "optional": true - }, - "playwright": { - "optional": true - }, - "safaridriver": { - "optional": true - }, - "webdriverio": { - "optional": true - } - } - }, - "node_modules/webpack-merge": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", - "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", - "dev": true, - "dependencies": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/why-is-node-running": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.2.2.tgz", - "integrity": "sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==", - "dev": true, - "dependencies": { - "siginfo": "^2.0.0", - "stackback": "0.0.2" - }, - "bin": { - "why-is-node-running": "cli.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/wildcard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", - "dev": true - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "dev": true, - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, - "node_modules/yazl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", - "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", - "dev": true, - "dependencies": { - "buffer-crc32": "~0.2.3" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/z-schema": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/z-schema/-/z-schema-5.0.5.tgz", - "integrity": "sha512-D7eujBWkLa3p2sIpJA0d1pr7es+a7m0vFAnZLlCEKq/Ij2k0MLi9Br2UPxoxdYystm5K1yeBGzub0FlYUEWj2Q==", - "dev": true, - "dependencies": { - "lodash.get": "^4.4.2", - "lodash.isequal": "^4.5.0", - "validator": "^13.7.0" - }, - "bin": { - "z-schema": "bin/z-schema" - }, - "engines": { - "node": ">=8.0.0" - }, - "optionalDependencies": { - "commander": "^9.4.1" - } - }, - "node_modules/zip-lib": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/zip-lib/-/zip-lib-0.7.3.tgz", - "integrity": "sha512-hp40KYzTJvoaCRr2t6hztlPnVmHYqDUDiIn0hlfAFwVBs3/jwkLy8aZ7NVGHECeWH2Tv8WPwWyR6QuWYarIjJQ==", - "dev": true, - "dependencies": { - "yauzl": "^2.10.0", - "yazl": "^2.5.1" - }, - "engines": { - "node": ">=8" - } - } - } -} \ No newline at end of file diff --git a/app/tools/gulp-downloadResources/DownloadResources.js b/app/tools/gulp-downloadResources/DownloadResources.js index 6017e1fc..5e14b0f7 100644 --- a/app/tools/gulp-downloadResources/DownloadResources.js +++ b/app/tools/gulp-downloadResources/DownloadResources.js @@ -15,6 +15,7 @@ class DownloadResources { // as an additional security defense, enforce an explicit allow list of file extensions (never extract .exes, say.) // note that LICENSE (no extension) is also allowed through special case code. fileExtensionAllowList = ["json", "js", "ts", "png", "tga", "jpg", "lang"]; + pathDisallowList = ["./", "/.", "just.config.ts"]; constructor(targetFilePath, excludeIfContents) { this._targetFilePath = targetFilePath; @@ -76,24 +77,24 @@ class DownloadResources { JSZip.loadAsync(content) .then(function (zip) { - const fileNamesToProcess = []; - const fileNamesWritten = []; + const filePathsToProcess = []; + const filePathsWritten = []; - for (const filename in zip.files) { + for (const filePath in zip.files) { let addFile = false; - const filenameCanon = filename.toLowerCase().replace(/\\/g, "/"); + const filePathCanon = filePath.toLowerCase().replace(/\\/g, "/"); - const extension = me.getTypeFromName(filenameCanon); + const extension = me.getTypeFromName(filePathCanon); if ( (extension === "" || extension === "md") && - (filenameCanon.endsWith("/notice") || - filenameCanon.endsWith("/readme") || - filenameCanon.endsWith("/readme.md") || - filenameCanon.endsWith("/license") || - filenameCanon.endsWith("/license.md") || - filenameCanon.endsWith("/notice.md")) + (filePathCanon.endsWith("/notice") || + filePathCanon.endsWith("/readme") || + filePathCanon.endsWith("/readme.md") || + filePathCanon.endsWith("/license") || + filePathCanon.endsWith("/license.md") || + filePathCanon.endsWith("/notice.md")) ) { addFile = true; } @@ -104,24 +105,30 @@ class DownloadResources { } } + for (const exclude of me.pathDisallowList) { + if (filePathCanon.indexOf(exclude) >= 0) { + addFile = false; + } + } + if (addFile) { - if (filenameCanon.indexOf("..") >= 0 || filenameCanon.indexOf("//") >= 0) { + if (filePathCanon.indexOf("..") >= 0 || filePathCanon.indexOf("//") >= 0) { addFile = false; } for (const exclusionPath of extraExcludeIfContents) { - if (filenameCanon.indexOf(exclusionPath.toLowerCase()) >= 0) { + if (filePathCanon.indexOf(exclusionPath.toLowerCase()) >= 0) { addFile = false; } } } if (addFile) { - fileNamesToProcess.push(filename); + filePathsToProcess.push(filePath); } } - for (const filename of fileNamesToProcess) { + for (const filename of filePathsToProcess) { let destFile = filename; if (ignoreSubfolder && destFile.toLowerCase().startsWith(ignoreSubfolder.toLowerCase())) { @@ -170,9 +177,9 @@ class DownloadResources { } if (content.dir) { - fileNamesWritten.push(filename); + filePathsWritten.push(filename); - if (fileNamesWritten.length >= fileNamesToProcess.length) { + if (filePathsWritten.length >= filePathsToProcess.length) { callback(null, null); return; } @@ -191,12 +198,12 @@ class DownloadResources { fs.writeFileSync(fileDest, contentBytes); - fileNamesWritten.push(filename); + filePathsWritten.push(filename); - if (fileNamesWritten.length >= fileNamesToProcess.length) { + if (filePathsWritten.length >= filePathsToProcess.length) { console.log( "Wrote " + - fileNamesWritten.length + + filePathsWritten.length + " files and folders to '" + path.join(me._targetFilePath, subfolder) + "'" @@ -214,7 +221,7 @@ class DownloadResources { } } - if (fileNamesWritten.length >= fileNamesToProcess.length) { + if (filePathsWritten.length >= filePathsToProcess.length) { callback(null, null); } }) diff --git a/package.json b/package.json index 163f83f4..ab062728 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,18 @@ "type": "git", "url": "https://github.com/Mojang/minecraft-creator-tools.git" }, - "private": true, + "keywords": [ + "minecraft", + "tools", + "bedrock", + "add-on", + "creator" + ], + "bugs": { + "url": "https://aka.ms/mctbugs" + }, + "license": "https://aka.ms/mctrlicense", + "homepage": "https://aka.ms/mcthomepage", "release": { "branches": [ "main" @@ -17,7 +28,6 @@ [ "@semantic-release/npm", { - "npmPublish": false, "pkgRoot": "./app/toolbuild/jsn", "tarballDir": "dist" } diff --git a/samplecontent/deployJs/behavior_packs/deployJs/manifest.json b/samplecontent/deployJs/behavior_packs/deployJs/manifest.json index 9117ac12..162c1d06 100644 --- a/samplecontent/deployJs/behavior_packs/deployJs/manifest.json +++ b/samplecontent/deployJs/behavior_packs/deployJs/manifest.json @@ -33,7 +33,7 @@ "dependencies": [ { "module_name": "@minecraft/server", - "version": "1.15.0-beta" + "version": "1.16.0-beta" }, { "module_name": "@minecraft/server-gametest",