diff --git a/.gitignore b/.gitignore index e09a007..3fd1f05 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,6 @@ data.json # Exclude macOS Finder (System Explorer) View States .DS_Store +fantasy-content-generator.zip +fantasy-content-generator +fantasy-content-generator/styles.css diff --git a/editor/AutoComplete.ts b/editor/AutoComplete.ts new file mode 100644 index 0000000..d6aea46 --- /dev/null +++ b/editor/AutoComplete.ts @@ -0,0 +1,205 @@ +import { nameByRace } from "fantasy-name-generator"; +import { generateCityName } from "generators/city"; +import { generateDungeonName } from "generators/dungeon"; +import { generateInn } from "generators/inn"; +import { dwarfFamilyNames } from "lists/dwarvenFamilyNames"; +import { elfFamilyNames } from "lists/elvenFamilyNames"; +import { familyNameList } from "lists/humanFamilyNames"; +import { titleLastNames } from "lists/titleLastNames"; +import * as FCG from "fantasy-content-generator"; +import MyPlugin from "main"; +import { Editor, EditorPosition, EditorSuggest, EditorSuggestContext, EditorSuggestTriggerInfo, MarkdownView } from "obsidian"; +import { generatorAirships } from "generators/airship"; +import { generatorDrinks } from "generators/drink"; +import { generateMiscellaneousArtifacts } from "generators/artifact"; +import { generateLoot } from "generators/loot"; +import { generatorMetals } from "generators/metal"; +import { generatorMagical_trees } from "generators/magicalTrees"; +import { generateShipName } from "generators/ship"; +import { generatorAnimal_groups } from "generators/animalGroups"; +import { generatorGroups } from "generators/groups"; +import { generatorReligions } from "generators/religions"; +import { generatePathfinderName } from "generators/Pathfinder/pathfinderName"; +import { generatePlotHook } from "generators/plothook"; + +type Generator = () => string | Error; + +interface Generators { + [key: string]: Generator; +} + + +export class AutoComplete extends EditorSuggest { + private getCompletions: () => string[]; // function to retrieve completions + startChar: EditorPosition + endChar: EditorPosition + plugin: MyPlugin + + private generators: Generators = { + 'Gen-ElfMale': () => nameByRace("elf", { gender: "male" }), + 'Gen-ElfMaleLastname': () => nameByRace("elf", { gender: "male" }) + " " + elfFamilyNames[Math.floor(Math.random() * elfFamilyNames.length)], + 'Gen-ElfFemale': () => nameByRace("elf", { gender: "female" }), + 'Gen-ElfFemaleLastname': () => nameByRace("elf", { gender: "female" }) + " " + elfFamilyNames[Math.floor(Math.random() * elfFamilyNames.length)], + 'Gen-Orc': () => nameByRace("orc"), + 'Gen-OrcLastname': () => nameByRace("orc") + " " + titleLastNames[Math.floor(Math.random() * titleLastNames.length)], + 'Gen-DwarfMale': () => nameByRace("elf", { gender: "male" }), + 'Gen-DwarfMaleLastname': () => nameByRace("elf", { gender: "male" }) + " " + dwarfFamilyNames[Math.floor(Math.random() * dwarfFamilyNames.length)], + 'Gen-DwarfFemale': () => nameByRace("elf", { gender: "female" }), + 'Gen-DwarfFemaleLastname': () => nameByRace("elf", { gender: "female" }) + " " + dwarfFamilyNames[Math.floor(Math.random() * dwarfFamilyNames.length)], + 'Gen-HumanMale': () => nameByRace("elf", { gender: "male" }), + 'Gen-HumanFemale': () => nameByRace("elf", { gender: "female" }), + 'Gen-HumanMaleLastname': () => nameByRace("elf", { gender: "male" }) + " " + familyNameList[Math.floor(Math.random() * familyNameList.length)], + 'Gen-HumanFemaleLastname': () => nameByRace("elf", { gender: "female" }) + " " + familyNameList[Math.floor(Math.random() * familyNameList.length)], + "Gen-DungeonsLabryinths": () => generateDungeonName(this.plugin.settings.dungeonSettings), + "Gen-InnsTaverns": () => { + const innInfo = generateInn(this.plugin.settings.innSettings); + return innInfo.name + "\nDescription: " + innInfo.description + "\nRumors: " + innInfo.rumors; + }, + "Gen-Settlement": () => { + const CityInfo = FCG.Settlements.generate(); + const name = generateCityName(this.plugin.settings.citySettings); + return "Name: " + name + "\nPopulation: " + CityInfo.population + "\nType: " + CityInfo.type.split("_").map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()).join(" "); + }, + "Gen-Airships": () => generatorAirships(), + "Gen-Drinks": () => generatorDrinks(this.plugin.settings.drinkSettings), + "Gen-Artifacts": () => generateMiscellaneousArtifacts(), + "Gen-LootTreasure": () => generateLoot(this.plugin.settings.enableCurrency, this.plugin.settings.currencyFrequency, this.plugin.settings.currencyTypes, this.plugin.settings.lootSettings), + "Gen-Metals": () => generatorMetals(), + "Gen-MagicalTrees": () => generatorMagical_trees(), + "Gen-Ship": () => generateShipName(), + "Gen-AnimalGroups": () => generatorAnimal_groups(), + "Gen-Groups": () => generatorGroups(this.plugin.settings.groupSettings), + "Gen-Religion": () => generatorReligions(), + "Gen-AasimarsLastname": () => generatePathfinderName("aasimars", "male", true), + "Gen-CatfolkLastname": () => generatePathfinderName("catfolk", "male", true), + "Gen-FetchlingsLastname": () => generatePathfinderName("fetchlings", "male", true), + "Gen-HalfElfLastname": () => generatePathfinderName("halfelf", "male", true), + "Gen-HalfOrcLastname": () => generatePathfinderName("halforc", "male", true), + "Gen-HobgoblinLastname": () => generatePathfinderName("hobgoblin", "male", true), + "Gen-IfritsLastname": () => generatePathfinderName("ifrits", "male", true), + "Gen-KobaldsLastname": () => generatePathfinderName("kobalds", "male", true), + "Gen-OreadsLastname": () => generatePathfinderName("oreads", "male", true), + "Gen-RatfolkLastname": () => generatePathfinderName("ratfolk", "male", true), + "Gen-SylphsLastname": () => generatePathfinderName("sylphs", "male", true), + "Gen-TenguLastname": () => generatePathfinderName("tengu", "male", true), + "Gen-TiansLastname": () => generatePathfinderName("tians", "male", true), + "Gen-TieflingLastname": () => generatePathfinderName("tiefling", "male", true), + "Gen-UndinesLastname": () => generatePathfinderName("undines", "male", true), + "Gen-AngelMaleLastname": () => nameByRace("angel", { gender: "male" }) + " " + nameByRace("angel", { gender: "male" }), + "Gen-AngelFemaleLastname": () => nameByRace("angel", { gender: "female" }) + " " + nameByRace("angel", { gender: "female" }), + "Gen-CavePersonMaleLastname": () => nameByRace("cavePerson", { gender: "male" }) + " " + nameByRace("cavePerson", { gender: "male" }), + "Gen-CavePersonFemaleLastname": () => nameByRace("cavePerson", { gender: "female" }) + " " + nameByRace("cavePerson", { gender: "female" }), + "Gen-DarkElfMaleLastname": () => nameByRace("darkelf", { gender: "male" }) + " " + nameByRace("darkelf", { gender: "male" }), + "Gen-DarkElfFemaleLastname": () => nameByRace("darkelf", { gender: "female" }) + " " + nameByRace("darkelf", { gender: "female" }), + "Gen-DemonLastname": () => nameByRace("demon") + " " + nameByRace("demon"), + "Gen-DragonMaleLastname": () => nameByRace("dragon", { gender: "male" }) + " " + nameByRace("dragon", { gender: "male" }), + "Gen-DragonFemaleLastname": () => nameByRace("dragon", { gender: "female" }) + " " + nameByRace("dragon", { gender: "female" }), + "Gen-DrowMaleLastname": () => nameByRace("drow", { gender: "male" }) + " " + nameByRace("drow", { gender: "male" }), + "Gen-DrowFemaleLastname": () => nameByRace("drow", { gender: "female" }) + " " + nameByRace("drow", { gender: "female" }), + "Gen-FairyMaleLastname": () => nameByRace("fairy", { gender: "male" }) + " " + nameByRace("fairy", { gender: "male" }), + "Gen-FairyFemaleLastname": () => nameByRace("fairy", { gender: "female" }) + " " + nameByRace("fairy", { gender: "female" }), + "Gen-GnomeMaleLastname": () => nameByRace("gnome", { gender: "male" }) + " " + nameByRace("gnome", { gender: "male" }), + "Gen-GnomeFemaleLastname": () => nameByRace("gnome", { gender: "female" }) + " " + nameByRace("gnome", { gender: "female" }), + "Gen-GoblinLastname": () => nameByRace("goblin") + " " + nameByRace("goblin"), + "Gen-HalfDemonMaleLastname": () => nameByRace("halfdemon", { gender: "male" }) + " " + nameByRace("halfdemon", { gender: "male" }), + "Gen-HalfDemonFemaleLastname": () => nameByRace("halfdemon", { gender: "female" }) + " " + nameByRace("halfdemon", { gender: "female" }), + "Gen-HalflingMaleLastname": () => nameByRace("halfling", { gender: "male" }) + " " + nameByRace("halfling", { gender: "male" }), + "Gen-HalflingFemaleLastname": () => nameByRace("halfling", { gender: "female" }) + " " + nameByRace("halfling", { gender: "female" }), + "Gen-HighElfMaleLastname": () => nameByRace("highelf", { gender: "male" }) + " " + nameByRace("highelf", { gender: "male" }), + "Gen-HighElfFemaleLastname": () => nameByRace("highelf", { gender: "female" }) + " " + nameByRace("highelf", { gender: "female" }), + "Gen-HighFairyMaleLastname": () => nameByRace("highfairy", { gender: "male" }) + " " + nameByRace("highfairy", { gender: "male" }), + "Gen-HighFairyFemaleLastname": () => nameByRace("highfairy", { gender: "female" }) + " " + nameByRace("angel", { gender: "female" }), + "Gen-OgreLastname": () => nameByRace("ogre") + " " + nameByRace("ogre"), + "Gen-Aasimars": () => generatePathfinderName("aasimars", "male", false), + "Gen-Catfolk": () => generatePathfinderName("catfolk", "male", false), + "Gen-Fetchlings": () => generatePathfinderName("fetchlings", "male", false), + "Gen-HalfElf": () => generatePathfinderName("halfelf", "male", false), + "Gen-HalfOrc": () => generatePathfinderName("halforc", "male", false), + "Gen-Hobgoblin": () => generatePathfinderName("hobgoblin", "male", false), + "Gen-Ifrits": () => generatePathfinderName("ifrits", "male", false), + "Gen-Kobalds": () => generatePathfinderName("kobalds", "male", false), + "Gen-Oreads": () => generatePathfinderName("oreads", "male", false), + "Gen-Ratfolk": () => generatePathfinderName("ratfolk", "male", false), + "Gen-Sylphs": () => generatePathfinderName("sylphs", "male", false), + "Gen-Tengu": () => generatePathfinderName("tengu", "male", false), + "Gen-Tians": () => generatePathfinderName("tians", "male", false), + "Gen-Tiefling": () => generatePathfinderName("tiefling", "male", false), + "Gen-Undines": () => generatePathfinderName("undines", "male", false), + "Gen-AngelMale": () => nameByRace("angel", { gender: "male" }), + "Gen-CavePersonMale": () => nameByRace("cavePerson", { gender: "male" }), + "Gen-DarkElfMale": () => nameByRace("darkelf", { gender: "male" }), + "Gen-DragonMale": () => nameByRace("dragon", { gender: "male" }), + "Gen-DrowMale": () => nameByRace("drow", { gender: "male" }), + "Gen-FairyMale": () => nameByRace("fairy", { gender: "male" }), + "Gen-GnomeMale": () => nameByRace("Gnome", { gender: "male" }), + "Gen-HalfDemonMale": () => nameByRace("halfdemon", { gender: "male" }), + "Gen-HalflingMale": () => nameByRace("halfling", { gender: "male" }), + "Gen-HighElfMale": () => nameByRace("highelf", { gender: "male" }), + "Gen-HighFairyMale": () => nameByRace("highfairy", { gender: "male" }), + "Gen-Ogre": () => nameByRace("ogre"), + "Gen-AngelFemale": () => nameByRace("angel", { gender: "female" }), + "Gen-CavePersonFemale": () => nameByRace("cavePerson", { gender: "female" }), + "Gen-DarkElfFemale": () => nameByRace("darkelf", { gender: "female" }), + "Gen-Demon": () => nameByRace("demon"), + "Gen-DragonFemale": () => nameByRace("dragon", { gender: "female" }), + "Gen-DrowFemale": () => nameByRace("drow", { gender: "female" }), + "Gen-FairyFemale": () => nameByRace("fairy", { gender: "female" }), + "Gen-GnomeFemale": () => nameByRace("gnome", { gender: "female" }), + "Gen-Goblin": () => nameByRace("goblin"), + "Gen-HalfDemonFemale": () => nameByRace("halfdemon", { gender: "female" }), + "Gen-HalflingFemale": () => nameByRace("halfling", { gender: "female" }), + "Gen-HighElfFemale": () => nameByRace("highelf", { gender: "female" }), + "Gen-HighFairyFemale": () => nameByRace("highfairy", { gender: "female" }), + "Gen-PlotStoryHooks": () => generatePlotHook(), + } + + constructor(getCompletions: () => string[], plugin: MyPlugin) { + super(app); + this.getCompletions = getCompletions; + this.plugin = plugin; + } + + onTrigger( + cursor: EditorPosition, + editor: Editor + ): EditorSuggestTriggerInfo | null { + // check if the cursor is immediately following a "@" + const line = editor.getLine(cursor.line); + const match = line.slice(0, cursor.ch).match(/\$\$(\S*)/); + + if (!match) { + return null; + } + + const start = { line: cursor.line, ch: cursor.ch - match[1].length - 2 }; + const end = { line: cursor.line, ch: cursor.ch }; + + this.startChar = start; + this.endChar = end; + + return { start, end, query: match[1] }; + } + + getSuggestions(context: EditorSuggestContext): string[] { + return this.getCompletions().filter((s) => s.toLowerCase().startsWith(context.query.toLowerCase())); + } + + renderSuggestion(value: string, el: HTMLElement): void { + el.createEl("div", { text: value }); + } + + selectSuggestion(value: string, _evt: MouseEvent | KeyboardEvent): void { + // execute the selected function + //const result = executeFunction(value); + let result: string | Error = "Not Implemented"; + if (value in this.generators) { + result = this.generators[value](); + } + + // insert the result into the editor + const activeView = app.workspace.getActiveViewOfType(MarkdownView); + if (activeView) { + activeView.editor.replaceRange(result.toString(), this.startChar, this.endChar); + } + } +} diff --git a/esbuild.config.mjs b/esbuild.config.mjs index b13282b..08e2bcd 100644 --- a/esbuild.config.mjs +++ b/esbuild.config.mjs @@ -31,7 +31,8 @@ const context = await esbuild.context({ "@lezer/common", "@lezer/highlight", "@lezer/lr", - ...builtins], + ...builtins, + ], format: "cjs", target: "es2018", logLevel: "info", diff --git a/generators/plothook.ts b/generators/plothook.ts index 0b60990..2ecc7ee 100644 --- a/generators/plothook.ts +++ b/generators/plothook.ts @@ -6,14 +6,18 @@ export function generatePlotHook(): string { const locationsIndex = Math.floor(Math.random() * location.length); const promptArray = [ - { title: `The Lost ${location[locationsIndex]} Treasure`, description: `A valuable artifact has gone missing in the ${location[locationsIndex]}. It is said to be guarded by ${antagonist[antagonistsIndex]}. The artifact must be retrieved before it falls into the wrong hands.` }, { title: `The Cursed ${location[locationsIndex]}`, description: `A mysterious force has taken hold of the ${location[locationsIndex]}, causing strange and dangerous happenings. It is up to the brave adventurers to find out what is causing this and put an end to it.` }, - { title: `The ${antagonist[antagonistsIndex]} of the ${location[locationsIndex]}`, description: `The ${location[locationsIndex]} is being terrorized by a powerful ${antagonist[antagonistsIndex]}. The people of the ${location[locationsIndex]} are in need of heroes to take on the ${antagonist[antagonistsIndex]} and restore peace to the land.` }, - { title: `The Mystery of the ${location[locationsIndex]}`, description: `The ${location[locationsIndex]} is full of secrets and mysteries. It is up to the adventurers to explore the ${location[locationsIndex]} and uncover its hidden secrets.` }, - { title: `The ${antagonist[antagonistsIndex]}'s Lair`, description: `The ${antagonist[antagonistsIndex]} has taken refuge in a hidden lair deep in the ${location[locationsIndex]}. It is up to the adventurers to find the lair and put an end to the ${antagonist[antagonistsIndex]}'s reign of terror.` }, { title: `The ${antagonist[antagonistsIndex]}'s Revenge`, description: `The ${antagonist[antagonistsIndex]} has returned to the ${location[locationsIndex]} seeking revenge. The brave adventurers must face the ${antagonist[antagonistsIndex]} and save the ${location[locationsIndex]} from destruction.` }, { title: `The ${location[locationsIndex]}'s Last Hope`, description: `The ${location[locationsIndex]} is in dire need of help. The brave adventurers must put an end to the ${antagonist[antagonistsIndex]}'s evil plans and save the ${location[locationsIndex]} from destruction.` }, { title: `The Battle for the ${location[locationsIndex]}`, description: `The forces of evil are gathering in the ${location[locationsIndex]}. The brave adventurers must fight to protect the ${location[locationsIndex]} from the ${antagonist[antagonistsIndex]} and his minions.` }, { title: `The Search for the ${location[locationsIndex]}`, description: `The ${location[locationsIndex]} has been lost for centuries. It is up to the adventurers to search the ${location[locationsIndex]} and uncover its secrets.` }, { title: `The ${antagonist[antagonistsIndex]}'s Treasure`, description: `The ${antagonist[antagonistsIndex]} has hidden a great treasure in the ${location[locationsIndex]}. It is up to the adventurers to find the treasure and put an end to the ${antagonist[antagonistsIndex]}'s schemes.` }, { title: `The ${antagonist[antagonistsIndex]}'s Curse`, description: `The ${antagonist[antagonistsIndex]} has cursed the ${location[locationsIndex]}. It is up to the adventurers to break the curse and restore peace to the ${location[locationsIndex]}.` }, { title: `The ${location[locationsIndex]}'s Secret`, description: `The ${location[locationsIndex]} is full of secrets that are waiting to be discovered. It is up to the adventurers to explore the ${location[locationsIndex]} and uncover its secrets.` }, { title: `The Battle for the ${location[locationsIndex]}`, description: `The ${location[locationsIndex]} is under siege by the forces of the ${antagonist[antagonistsIndex]}. The brave adventurers must fight to protect the ${location[locationsIndex]} and put an end to the ${antagonist[antagonistsIndex]}'s reign of terror.` }, { title: `The ${antagonist[antagonistsIndex]}'s Scheme`, description: `The ${antagonist[antagonistsIndex]} is planning something sinister in the ${location[locationsIndex]}. It is up to the adventurers to stop the ${antagonist[antagonistsIndex]} before it is too late.` }, { title: `The ${location[locationsIndex]}'s Secret`, description: `The ${location[locationsIndex]} holds a secret that could change the world. It is up to the adventurers to find the secret and protect it from the ${antagonist[antagonistsIndex]}.` }, { title: `The ${antagonist[antagonistsIndex]}'s Wrath`, description: `The ${antagonist[antagonistsIndex]} is wreaking havoc in the ${location[locationsIndex]}. It is up to the adventurers to put an end to the ${antagonist[antagonistsIndex]}'s evil plans and restore peace to the ${location[locationsIndex]}.` }, { title: `The Return of the ${antagonist[antagonistsIndex]}`, description: `The ${antagonist[antagonistsIndex]} has returned to the ${location[locationsIndex]}. The brave adventurers must face the ${antagonist[antagonistsIndex]} and save the ${location[locationsIndex]} from destruction.` }, { title: `The ${antagonist[antagonistsIndex]}'s Demise`, description: `The ${antagonist[antagonistsIndex]} is threatening the ${location[locationsIndex]}. It is up to the adventurers to put an end to the ${antagonist[antagonistsIndex]} and save the ${location[locationsIndex]} from destruction.` }, { title: `The ${location[locationsIndex]}'s Rescue`, description: `The ${location[locationsIndex]} is in great danger. It is up to the brave adventurers to save the ${location[locationsIndex]} from the clutches of the ${antagonist[antagonistsIndex]}.` }, { title: `The ${location[locationsIndex]}'s Secret`, description: `A powerful secret lies hidden in the ${location[locationsIndex]}. It is up to the adventurers to find the secret and protect it from the ${antagonist[antagonistsIndex]}.` }, { title: `The ${antagonist[antagonistsIndex]}'s Challenge`, description: `The ${antagonist[antagonistsIndex]} has issued a challenge to the adventurers. It is up to the adventurers to face the ${antagonist[antagonistsIndex]} and save the ${location[locationsIndex]} from destruction.` }, { title: `The ${antagonist[antagonistsIndex]}'s Plan`, description: `The ${antagonist[antagonistsIndex]} is plotting something sinister in the ${location[locationsIndex]}. It is up to the adventurers to stop the ${antagonist[antagonistsIndex]} before it is too late.` }, { title: `The ${location[locationsIndex]}'s Rescue`, description: `The ${location[locationsIndex]} is in dire need of help. The brave adventurers must put an end to the ${antagonist[antagonistsIndex]}'s evil plans and save the ${location[locationsIndex]} from destruction.` }, { title: `The ${location[locationsIndex]}'s Treasure`, description: `A valuable treasure lies hidden in the ${location[locationsIndex]}. It is up to the adventurers to find the treasure and put an end to the ${antagonist[antagonistsIndex]}'s schemes.` }, { title: `The Lost ${location[locationsIndex]} Expedition`, description: `A group of adventurers have gone missing in the ${location[locationsIndex]}. It is up to the brave adventurers to find the expedition and discover what happened to them.` }, { title: `The ${location[locationsIndex]}'s Guardian`, description: `A powerful guardian has taken up residence in the ${location[locationsIndex]}. It is up to the adventurers to find the guardian and put an end to the ${antagonist[antagonistsIndex]}'s evil plans.` }, { title: `The ${antagonist[antagonistsIndex]}'s Shadow`, description: `The ${antagonist[antagonistsIndex]} is casting a dark shadow over the ${location[locationsIndex]}. It is up to the adventurers to put an end to the ${antagonist[antagonistsIndex]}'s reign of terror.` }, { title: `The ${location[locationsIndex]}'s Fate`, description: `The fate of the ${location[locationsIndex]} lies in the hands of the adventurers. It is up to them to save the ${location[locationsIndex]} from the clutches of the ${antagonist[antagonistsIndex]}.` }, { title: `The ${antagonist[antagonistsIndex]}'s Threat`, description: `The ${antagonist[antagonistsIndex]} is threatening the ${location[locationsIndex]}. It is up to the adventurers to put an end to the ${antagonist[antagonistsIndex]} and save the ${location[locationsIndex]} from destruction.` }, { title: `The ${antagonist[antagonistsIndex]}'s Ambition`, description: `The ${antagonist[antagonistsIndex]} has set his sights on the ${location[locationsIndex]}. It is up to the adventurers to stop the ${antagonist[antagonistsIndex]} and save the ${location[locationsIndex]} from destruction.` }, { title: `The ${location[locationsIndex]} Mystery`, description: `Rumors of strange occurrences in the ${location[locationsIndex]} have been spreading. People have been disappearing and strange creatures have been seen. You must investigate what is happening and put a stop to it.` }, { title: `The ${location[locationsIndex]} Escort`, description: `You have been hired to escort a VIP to a meeting in the ${location[locationsIndex]}. Along the way, you must protect them from ${antagonist[antagonistsIndex]} who are trying to disrupt the meeting.` }, { title: `The Kidnapped ${location[locationsIndex]} Princess`, description: `The princess of the ${location[locationsIndex]} kingdom has been kidnapped by ${antagonist[antagonistsIndex]}. You must journey to their hideout and rescue her.` }, { title: `The ${location[locationsIndex]} Heist`, description: `You have been hired to steal a valuable item from the ${location[locationsIndex]}. You must be stealthy and avoid detection from ${antagonist[antagonistsIndex]}.` }, { title: `The ${location[locationsIndex]} Curse`, description: `An ancient curse has been unleashed in the ${location[locationsIndex]}. You must find a way to break it before it is too late. ${antagonist[antagonistsIndex]} are guarding the source of the curse and must be defeated.` }, { title: `The ${location[locationsIndex]} Artifact`, description: `A powerful artifact is hidden in the ${location[locationsIndex]}. You must find it before ${antagonist[antagonistsIndex]} can get their hands on it.` }, { title: `The ${location[locationsIndex]} Rescue`, description: `Your friends have been captured by ${antagonist[antagonistsIndex]} in the ${location[locationsIndex]}. You must rescue them before it is too late.` }, { title: `The ${location[locationsIndex]} Showdown`, description: `You must face off against ${antagonist[antagonistsIndex]} in the ${location[locationsIndex]}. You must defeat them in order to restore peace.` }, { title: `The ${location[locationsIndex]} Revenge`, description: `You have been wronged by ${antagonist[antagonistsIndex]} in the ${location[locationsIndex]}. You must get revenge and restore your honor.` }, { title: `The ${location[locationsIndex]} Terror`, description: `${antagonist[antagonistsIndex]} have taken over the ${location[locationsIndex]}. You must find a way to stop them and restore peace.` }, { title: `The ${location[locationsIndex]} Hunt`, description: `You have been hired to hunt down ${antagonist[antagonistsIndex]} in the ${location[locationsIndex]}. You must find them and bring them to justice.` }, { title: `The ${location[locationsIndex]} Challenge`, description: `You have been challenged by ${antagonist[antagonistsIndex]} to a duel in the ${location[locationsIndex]}. You must accept the challenge and prove your worth.` }, - { title: `The ${location[locationsIndex]} Race`, description: `You have been challenged to a race by ${antagonist[antagonistsIndex]} in the ${location[locationsIndex]}. You must win the race to prove your superiority.` }, { title: `The ${location[locationsIndex]} Danger`, description: `The ${location[locationsIndex]} is in danger from ${antagonist[antagonistsIndex]}. You must find a way to save it before it is too late.` }, { title: `The ${location[locationsIndex]} Mysteries`, description: `Strange things are happening in the ${location[locationsIndex]}. You must investigate and uncover the truth behind the mysteries.` }, { title: `The ${location[locationsIndex]} Showdown`, description: `You must face off against ${antagonist[antagonistsIndex]} in the ${location[locationsIndex]}. You must defeat them in order to save the day.` }, { title: `The ${location[locationsIndex]} Invasion`, description: `${antagonist[antagonistsIndex]} have invaded the ${location[locationsIndex]}. You must find a way to drive them out and restore peace.` }, { title: `The ${location[locationsIndex]} Showdown`, description: `You must face off against ${antagonist[antagonistsIndex]} in the ${location[locationsIndex]}. You must defeat them in order to save the world.` }, { title: `The ${location[locationsIndex]} Discovery`, description: `You have been hired to explore the ${location[locationsIndex]}. Along the way, you must fend off ${antagonist[antagonistsIndex]} and uncover ancient secrets.` }, { title: `The ${location[locationsIndex]} Showdown`, description: `You must face off against ${antagonist[antagonistsIndex]} in the ${location[locationsIndex]}. You must defeat them in order to save the kingdom.` }, { title: `The ${location[locationsIndex]} Prison`, description: `You have been hired to break someone out of a prison in the ${location[locationsIndex]}. Along the way, you must avoid detection from ${antagonist[antagonistsIndex]}.` }, { title: `The ${location[locationsIndex]} Rescue`, description: `You have been hired to rescue someone from the ${location[locationsIndex]}. Along the way, you must avoid detection from ${antagonist[antagonistsIndex]}.` }, { title: `The ${location[locationsIndex]} Treasure`, description: `A valuable treasure is hidden in the ${location[locationsIndex]}. You must find it before ${antagonist[antagonistsIndex]} can get their hands on it.` }, { title: `The ${location[locationsIndex]} Challenge`, description: `You have been challenged by ${antagonist[antagonistsIndex]} to a battle in the ${location[locationsIndex]}. You must accept the challenge and prove your worth.` }, { title: `The ${location[locationsIndex]} Showdown`, description: `You must face off against ${antagonist[antagonistsIndex]} in the ${location[locationsIndex]}. You must defeat them in order to save the city.` }, { title: `The ${location[locationsIndex]} Quest`, description: `You have been sent on a quest to the ${location[locationsIndex]}. Along the way, you must fend off ${antagonist[antagonistsIndex]} and discover ancient secrets.` }, { title: `The ${location[locationsIndex]} Mission`, description: `You have been hired to complete a mission in the ${location[locationsIndex]}. Along the way, you must avoid detection from ${antagonist[antagonistsIndex]}.` }, { title: `The ${location[locationsIndex]} Spy`, description: `You have been hired to spy on ${antagonist[antagonistsIndex]} in the ${location[locationsIndex]}. You must find out what they are up to and report back.` }, { title: `The ${location[locationsIndex]} Adventure`, description: `You have been hired to explore the ${location[locationsIndex]}. Along the way, you must fend off ${antagonist[antagonistsIndex]} and uncover ancient secrets.` }, { title: `The ${location[locationsIndex]} Sabotage`, description: `You have been hired to sabotage a plan by ${antagonist[antagonistsIndex]} in the ${location[locationsIndex]}. You must find a way to stop them before they succeed.` }, { title: `The ${location[locationsIndex]} Showdown`, description: `You must face off against ${antagonist[antagonistsIndex]} in the ${location[locationsIndex]}. You must defeat them in order to protect the innocent.` }, { title: `The ${location[locationsIndex]} Thief`, description: `A thief has stolen something valuable from the ${location[locationsIndex]}. You must find them before they can escape with it.` }, { title: `The ${location[locationsIndex]} Struggle`, description: `The people of the ${location[locationsIndex]} are struggling against the oppression of ${antagonist[antagonistsIndex]}. You must find a way to help them and restore freedom.` }, { title: `The ${location[locationsIndex]} Showdown`, description: `You must face off against ${antagonist[antagonistsIndex]} in the ${location[locationsIndex]}. You must defeat them in order to save your friends.` }, { title: `The ${location[locationsIndex]} Escape`, description: `You have been captured by ${antagonist[antagonistsIndex]} in the ${location[locationsIndex]}. You must escape before it is too late.` }, { title: `The ${location[locationsIndex]} Challenge`, description: `You have been challenged by ${antagonist[antagonistsIndex]} to a game in the ${location[locationsIndex]}. You must accept the challenge and prove your worth.` }, { title: `The ${location[locationsIndex]} Conflict`, description: `A conflict has broken out in the ${location[locationsIndex]}. You must find a way to stop it before it is too late.` }, { title: `The ${location[locationsIndex]} Rescue`, description: `Your friends have been taken hostage by ${antagonist[antagonistsIndex]} in the ${location[locationsIndex]}. You must rescue them before it is too late.` }, { title: `The ${location[locationsIndex]} Retrieval`, description: `You have been hired to retrieve a valuable item from the ${location[locationsIndex]}. You must be stealthy and avoid detection from ${antagonist[antagonistsIndex]}.` }, { title: `The ${location[locationsIndex]} Discovery`, description: `Strange things are happening in the ${location[locationsIndex]}. You must investigate and uncover the truth behind them.` }, { title: `The ${antagonist[antagonistsIndex]} Discovery`, description: `Strange things are happening in the ${location[locationsIndex]}. You must investigate and uncover the truth behind them.` }, { title: `The ${location[locationsIndex]} Conspiracy`, description: `You have uncovered a conspiracy in the ${location[locationsIndex]}. You must find a way to stop it before it is too late.` }, { title: `The ${location[locationsIndex]} Showdown`, description: `You must face off against ${antagonist[antagonistsIndex]} in the ${location[locationsIndex]}. You must defeat them in order to restore justice.` }, { title: `The ${location[locationsIndex]} Battle`, description: `A battle has broken out in the ${location[locationsIndex]}. You must find a way to win it and restore peace.` }, { title: `The ${location[locationsIndex]} Rescue`, description: `You have been hired to rescue a VIP from the ${location[locationsIndex]}. Along the way, you must protect them from ${antagonist[antagonistsIndex]} who are trying to stop you.` } + { title: `The Lost ${capitalizeFirstLetter(location[locationsIndex])} Treasure`, description: `A valuable artifact has gone missing in the ${capitalizeFirstLetter(location[locationsIndex])}. It is said to be guarded by ${antagonist[antagonistsIndex]}. The artifact must be retrieved before it falls into the wrong hands.` }, { title: `The Cursed ${capitalizeFirstLetter(location[locationsIndex])}`, description: `A mysterious force has taken hold of the ${capitalizeFirstLetter(location[locationsIndex])}, causing strange and dangerous happenings. It is up to the brave adventurers to find out what is causing this and put an end to it.` }, + { title: `The ${antagonist[antagonistsIndex]} of the ${capitalizeFirstLetter(location[locationsIndex])}`, description: `The ${capitalizeFirstLetter(location[locationsIndex])} is being terrorized by a powerful ${antagonist[antagonistsIndex]}. The people of the ${capitalizeFirstLetter(location[locationsIndex])} are in need of heroes to take on the ${antagonist[antagonistsIndex]} and restore peace to the land.` }, + { title: `The Mystery of the ${capitalizeFirstLetter(location[locationsIndex])}`, description: `The ${capitalizeFirstLetter(location[locationsIndex])} is full of secrets and mysteries. It is up to the adventurers to explore the ${capitalizeFirstLetter(location[locationsIndex])} and uncover its hidden secrets.` }, + { title: `The ${antagonist[antagonistsIndex]}'s Lair`, description: `The ${antagonist[antagonistsIndex]} has taken refuge in a hidden lair deep in the ${capitalizeFirstLetter(location[locationsIndex])}. It is up to the adventurers to find the lair and put an end to the ${antagonist[antagonistsIndex]}'s reign of terror.` }, { title: `The ${antagonist[antagonistsIndex]}'s Revenge`, description: `The ${antagonist[antagonistsIndex]} has returned to the ${capitalizeFirstLetter(location[locationsIndex])} seeking revenge. The brave adventurers must face the ${antagonist[antagonistsIndex]} and save the ${capitalizeFirstLetter(location[locationsIndex])} from destruction.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])}'s Last Hope`, description: `The ${capitalizeFirstLetter(location[locationsIndex])} is in dire need of help. The brave adventurers must put an end to the ${antagonist[antagonistsIndex]}'s evil plans and save the ${capitalizeFirstLetter(location[locationsIndex])} from destruction.` }, { title: `The Battle for the ${capitalizeFirstLetter(location[locationsIndex])}`, description: `The forces of evil are gathering in the ${capitalizeFirstLetter(location[locationsIndex])}. The brave adventurers must fight to protect the ${capitalizeFirstLetter(location[locationsIndex])} from the ${antagonist[antagonistsIndex]} and his minions.` }, { title: `The Search for the ${capitalizeFirstLetter(location[locationsIndex])}`, description: `The ${capitalizeFirstLetter(location[locationsIndex])} has been lost for centuries. It is up to the adventurers to search the ${capitalizeFirstLetter(location[locationsIndex])} and uncover its secrets.` }, { title: `The ${antagonist[antagonistsIndex]}'s Treasure`, description: `The ${antagonist[antagonistsIndex]} has hidden a great treasure in the ${capitalizeFirstLetter(location[locationsIndex])}. It is up to the adventurers to find the treasure and put an end to the ${antagonist[antagonistsIndex]}'s schemes.` }, { title: `The ${antagonist[antagonistsIndex]}'s Curse`, description: `The ${antagonist[antagonistsIndex]} has cursed the ${capitalizeFirstLetter(location[locationsIndex])}. It is up to the adventurers to break the curse and restore peace to the ${capitalizeFirstLetter(location[locationsIndex])}.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])}'s Secret`, description: `The ${capitalizeFirstLetter(location[locationsIndex])} is full of secrets that are waiting to be discovered. It is up to the adventurers to explore the ${capitalizeFirstLetter(location[locationsIndex])} and uncover its secrets.` }, { title: `The Battle for the ${capitalizeFirstLetter(location[locationsIndex])}`, description: `The ${capitalizeFirstLetter(location[locationsIndex])} is under siege by the forces of the ${antagonist[antagonistsIndex]}. The brave adventurers must fight to protect the ${capitalizeFirstLetter(location[locationsIndex])} and put an end to the ${antagonist[antagonistsIndex]}'s reign of terror.` }, { title: `The ${antagonist[antagonistsIndex]}'s Scheme`, description: `The ${antagonist[antagonistsIndex]} is planning something sinister in the ${capitalizeFirstLetter(location[locationsIndex])}. It is up to the adventurers to stop the ${antagonist[antagonistsIndex]} before it is too late.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])}'s Secret`, description: `The ${capitalizeFirstLetter(location[locationsIndex])} holds a secret that could change the world. It is up to the adventurers to find the secret and protect it from the ${antagonist[antagonistsIndex]}.` }, { title: `The ${antagonist[antagonistsIndex]}'s Wrath`, description: `The ${antagonist[antagonistsIndex]} is wreaking havoc in the ${capitalizeFirstLetter(location[locationsIndex])}. It is up to the adventurers to put an end to the ${antagonist[antagonistsIndex]}'s evil plans and restore peace to the ${capitalizeFirstLetter(location[locationsIndex])}.` }, { title: `The Return of the ${antagonist[antagonistsIndex]}`, description: `The ${antagonist[antagonistsIndex]} has returned to the ${capitalizeFirstLetter(location[locationsIndex])}. The brave adventurers must face the ${antagonist[antagonistsIndex]} and save the ${capitalizeFirstLetter(location[locationsIndex])} from destruction.` }, { title: `The ${antagonist[antagonistsIndex]}'s Demise`, description: `The ${antagonist[antagonistsIndex]} is threatening the ${capitalizeFirstLetter(location[locationsIndex])}. It is up to the adventurers to put an end to the ${antagonist[antagonistsIndex]} and save the ${capitalizeFirstLetter(location[locationsIndex])} from destruction.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])}'s Rescue`, description: `The ${capitalizeFirstLetter(location[locationsIndex])} is in great danger. It is up to the brave adventurers to save the ${capitalizeFirstLetter(location[locationsIndex])} from the clutches of the ${antagonist[antagonistsIndex]}.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])}'s Secret`, description: `A powerful secret lies hidden in the ${capitalizeFirstLetter(location[locationsIndex])}. It is up to the adventurers to find the secret and protect it from the ${antagonist[antagonistsIndex]}.` }, { title: `The ${antagonist[antagonistsIndex]}'s Challenge`, description: `The ${antagonist[antagonistsIndex]} has issued a challenge to the adventurers. It is up to the adventurers to face the ${antagonist[antagonistsIndex]} and save the ${capitalizeFirstLetter(location[locationsIndex])} from destruction.` }, { title: `The ${antagonist[antagonistsIndex]}'s Plan`, description: `The ${antagonist[antagonistsIndex]} is plotting something sinister in the ${capitalizeFirstLetter(location[locationsIndex])}. It is up to the adventurers to stop the ${antagonist[antagonistsIndex]} before it is too late.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])}'s Rescue`, description: `The ${capitalizeFirstLetter(location[locationsIndex])} is in dire need of help. The brave adventurers must put an end to the ${antagonist[antagonistsIndex]}'s evil plans and save the ${capitalizeFirstLetter(location[locationsIndex])} from destruction.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])}'s Treasure`, description: `A valuable treasure lies hidden in the ${capitalizeFirstLetter(location[locationsIndex])}. It is up to the adventurers to find the treasure and put an end to the ${antagonist[antagonistsIndex]}'s schemes.` }, { title: `The Lost ${capitalizeFirstLetter(location[locationsIndex])} Expedition`, description: `A group of adventurers have gone missing in the ${capitalizeFirstLetter(location[locationsIndex])}. It is up to the brave adventurers to find the expedition and discover what happened to them.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])}'s Guardian`, description: `A powerful guardian has taken up residence in the ${capitalizeFirstLetter(location[locationsIndex])}. It is up to the adventurers to find the guardian and put an end to the ${antagonist[antagonistsIndex]}'s evil plans.` }, { title: `The ${antagonist[antagonistsIndex]}'s Shadow`, description: `The ${antagonist[antagonistsIndex]} is casting a dark shadow over the ${capitalizeFirstLetter(location[locationsIndex])}. It is up to the adventurers to put an end to the ${antagonist[antagonistsIndex]}'s reign of terror.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])}'s Fate`, description: `The fate of the ${capitalizeFirstLetter(location[locationsIndex])} lies in the hands of the adventurers. It is up to them to save the ${capitalizeFirstLetter(location[locationsIndex])} from the clutches of the ${antagonist[antagonistsIndex]}.` }, { title: `The ${antagonist[antagonistsIndex]}'s Threat`, description: `The ${antagonist[antagonistsIndex]} is threatening the ${capitalizeFirstLetter(location[locationsIndex])}. It is up to the adventurers to put an end to the ${antagonist[antagonistsIndex]} and save the ${capitalizeFirstLetter(location[locationsIndex])} from destruction.` }, { title: `The ${antagonist[antagonistsIndex]}'s Ambition`, description: `The ${antagonist[antagonistsIndex]} has set his sights on the ${capitalizeFirstLetter(location[locationsIndex])}. It is up to the adventurers to stop the ${antagonist[antagonistsIndex]} and save the ${capitalizeFirstLetter(location[locationsIndex])} from destruction.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Mystery`, description: `Rumors of strange occurrences in the ${capitalizeFirstLetter(location[locationsIndex])} have been spreading. People have been disappearing and strange creatures have been seen. You must investigate what is happening and put a stop to it.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Escort`, description: `You have been hired to escort a VIP to a meeting in the ${capitalizeFirstLetter(location[locationsIndex])}. Along the way, you must protect them from ${antagonist[antagonistsIndex]} who are trying to disrupt the meeting.` }, { title: `The Kidnapped ${capitalizeFirstLetter(location[locationsIndex])} Princess`, description: `The princess of the ${capitalizeFirstLetter(location[locationsIndex])} kingdom has been kidnapped by ${antagonist[antagonistsIndex]}. You must journey to their hideout and rescue her.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Heist`, description: `You have been hired to steal a valuable item from the ${capitalizeFirstLetter(location[locationsIndex])}. You must be stealthy and avoid detection from ${antagonist[antagonistsIndex]}.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Curse`, description: `An ancient curse has been unleashed in the ${capitalizeFirstLetter(location[locationsIndex])}. You must find a way to break it before it is too late. ${antagonist[antagonistsIndex]} are guarding the source of the curse and must be defeated.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Artifact`, description: `A powerful artifact is hidden in the ${capitalizeFirstLetter(location[locationsIndex])}. You must find it before ${antagonist[antagonistsIndex]} can get their hands on it.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Rescue`, description: `Your friends have been captured by ${antagonist[antagonistsIndex]} in the ${capitalizeFirstLetter(location[locationsIndex])}. You must rescue them before it is too late.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Showdown`, description: `You must face off against ${antagonist[antagonistsIndex]} in the ${capitalizeFirstLetter(location[locationsIndex])}. You must defeat them in order to restore peace.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Revenge`, description: `You have been wronged by ${antagonist[antagonistsIndex]} in the ${capitalizeFirstLetter(location[locationsIndex])}. You must get revenge and restore your honor.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Terror`, description: `${antagonist[antagonistsIndex]} have taken over the ${capitalizeFirstLetter(location[locationsIndex])}. You must find a way to stop them and restore peace.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Hunt`, description: `You have been hired to hunt down ${antagonist[antagonistsIndex]} in the ${capitalizeFirstLetter(location[locationsIndex])}. You must find them and bring them to justice.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Challenge`, description: `You have been challenged by ${antagonist[antagonistsIndex]} to a duel in the ${capitalizeFirstLetter(location[locationsIndex])}. You must accept the challenge and prove your worth.` }, + { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Race`, description: `You have been challenged to a race by ${antagonist[antagonistsIndex]} in the ${capitalizeFirstLetter(location[locationsIndex])}. You must win the race to prove your superiority.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Danger`, description: `The ${capitalizeFirstLetter(location[locationsIndex])} is in danger from ${antagonist[antagonistsIndex]}. You must find a way to save it before it is too late.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Mysteries`, description: `Strange things are happening in the ${capitalizeFirstLetter(location[locationsIndex])}. You must investigate and uncover the truth behind the mysteries.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Showdown`, description: `You must face off against ${antagonist[antagonistsIndex]} in the ${capitalizeFirstLetter(location[locationsIndex])}. You must defeat them in order to save the day.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Invasion`, description: `${antagonist[antagonistsIndex]} have invaded the ${capitalizeFirstLetter(location[locationsIndex])}. You must find a way to drive them out and restore peace.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Showdown`, description: `You must face off against ${antagonist[antagonistsIndex]} in the ${capitalizeFirstLetter(location[locationsIndex])}. You must defeat them in order to save the world.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Discovery`, description: `You have been hired to explore the ${capitalizeFirstLetter(location[locationsIndex])}. Along the way, you must fend off ${antagonist[antagonistsIndex]} and uncover ancient secrets.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Showdown`, description: `You must face off against ${antagonist[antagonistsIndex]} in the ${capitalizeFirstLetter(location[locationsIndex])}. You must defeat them in order to save the kingdom.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Prison`, description: `You have been hired to break someone out of a prison in the ${capitalizeFirstLetter(location[locationsIndex])}. Along the way, you must avoid detection from ${antagonist[antagonistsIndex]}.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Rescue`, description: `You have been hired to rescue someone from the ${capitalizeFirstLetter(location[locationsIndex])}. Along the way, you must avoid detection from ${antagonist[antagonistsIndex]}.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Treasure`, description: `A valuable treasure is hidden in the ${capitalizeFirstLetter(location[locationsIndex])}. You must find it before ${antagonist[antagonistsIndex]} can get their hands on it.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Challenge`, description: `You have been challenged by ${antagonist[antagonistsIndex]} to a battle in the ${capitalizeFirstLetter(location[locationsIndex])}. You must accept the challenge and prove your worth.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Showdown`, description: `You must face off against ${antagonist[antagonistsIndex]} in the ${capitalizeFirstLetter(location[locationsIndex])}. You must defeat them in order to save the city.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Quest`, description: `You have been sent on a quest to the ${capitalizeFirstLetter(location[locationsIndex])}. Along the way, you must fend off ${antagonist[antagonistsIndex]} and discover ancient secrets.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Mission`, description: `You have been hired to complete a mission in the ${capitalizeFirstLetter(location[locationsIndex])}. Along the way, you must avoid detection from ${antagonist[antagonistsIndex]}.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Spy`, description: `You have been hired to spy on ${antagonist[antagonistsIndex]} in the ${capitalizeFirstLetter(location[locationsIndex])}. You must find out what they are up to and report back.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Adventure`, description: `You have been hired to explore the ${capitalizeFirstLetter(location[locationsIndex])}. Along the way, you must fend off ${antagonist[antagonistsIndex]} and uncover ancient secrets.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Sabotage`, description: `You have been hired to sabotage a plan by ${antagonist[antagonistsIndex]} in the ${capitalizeFirstLetter(location[locationsIndex])}. You must find a way to stop them before they succeed.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Showdown`, description: `You must face off against ${antagonist[antagonistsIndex]} in the ${capitalizeFirstLetter(location[locationsIndex])}. You must defeat them in order to protect the innocent.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Thief`, description: `A thief has stolen something valuable from the ${capitalizeFirstLetter(location[locationsIndex])}. You must find them before they can escape with it.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Struggle`, description: `The people of the ${capitalizeFirstLetter(location[locationsIndex])} are struggling against the oppression of ${antagonist[antagonistsIndex]}. You must find a way to help them and restore freedom.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Showdown`, description: `You must face off against ${antagonist[antagonistsIndex]} in the ${capitalizeFirstLetter(location[locationsIndex])}. You must defeat them in order to save your friends.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Escape`, description: `You have been captured by ${antagonist[antagonistsIndex]} in the ${capitalizeFirstLetter(location[locationsIndex])}. You must escape before it is too late.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Challenge`, description: `You have been challenged by ${antagonist[antagonistsIndex]} to a game in the ${capitalizeFirstLetter(location[locationsIndex])}. You must accept the challenge and prove your worth.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Conflict`, description: `A conflict has broken out in the ${capitalizeFirstLetter(location[locationsIndex])}. You must find a way to stop it before it is too late.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Rescue`, description: `Your friends have been taken hostage by ${antagonist[antagonistsIndex]} in the ${capitalizeFirstLetter(location[locationsIndex])}. You must rescue them before it is too late.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Retrieval`, description: `You have been hired to retrieve a valuable item from the ${capitalizeFirstLetter(location[locationsIndex])}. You must be stealthy and avoid detection from ${antagonist[antagonistsIndex]}.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Discovery`, description: `Strange things are happening in the ${capitalizeFirstLetter(location[locationsIndex])}. You must investigate and uncover the truth behind them.` }, { title: `The ${antagonist[antagonistsIndex]} Discovery`, description: `Strange things are happening in the ${capitalizeFirstLetter(location[locationsIndex])}. You must investigate and uncover the truth behind them.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Conspiracy`, description: `You have uncovered a conspiracy in the ${capitalizeFirstLetter(location[locationsIndex])}. You must find a way to stop it before it is too late.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Showdown`, description: `You must face off against ${antagonist[antagonistsIndex]} in the ${capitalizeFirstLetter(location[locationsIndex])}. You must defeat them in order to restore justice.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Battle`, description: `A battle has broken out in the ${capitalizeFirstLetter(location[locationsIndex])}. You must find a way to win it and restore peace.` }, { title: `The ${capitalizeFirstLetter(location[locationsIndex])} Rescue`, description: `You have been hired to rescue a VIP from the ${capitalizeFirstLetter(location[locationsIndex])}. Along the way, you must protect them from ${antagonist[antagonistsIndex]} who are trying to stop you.` } ] const promptIndex = Math.floor(Math.random() * promptArray.length); return `${promptArray[promptIndex].title},\n${promptArray[promptIndex].description}`; +} + +function capitalizeFirstLetter(string: string) { + return string.charAt(0).toUpperCase() + string.slice(1); } \ No newline at end of file diff --git a/main.ts b/main.ts index ea6744b..a75f48d 100644 --- a/main.ts +++ b/main.ts @@ -1,7 +1,118 @@ import { GeneratorModal } from 'modal'; -import { App, Notice, Plugin, PluginSettingTab, Setting } from 'obsidian'; +import { App, MarkdownView, Notice, Plugin, PluginSettingTab, Setting } from 'obsidian'; +import { AutoComplete } from "editor/AutoComplete"; -// Remember to rename these classes and interfaces! +// Define the list of possible options +const possibleOptions = [ + 'Gen-ElfMale', + 'Gen-ElfMaleLastname', + 'Gen-ElfFemale', + 'Gen-ElfFemaleLastname', + 'Gen-Orc', + 'Gen-OrcLastname', + 'Gen-DwarfMale', + 'Gen-DwarfMaleLastname', + 'Gen-DwarfFemale', + 'Gen-DwarfFemaleLastname', + 'Gen-HumanMale', + 'Gen-HumanFemale', + 'Gen-HumanMaleLastname', + 'Gen-HumanFemaleLastname', + "Gen-DungeonsLabryinths", + "Gen-InnsTaverns", + "Gen-Settlement", + "Gen-Airships", + "Gen-Drinks", + "Gen-Artifacts", + "Gen-LootTreasure", + "Gen-Metals", + "Gen-MagicalTrees", + "Gen-Ship", + "Gen-AnimalGroups", + "Gen-Groups", + "Gen-Religion", + "Gen-AasimarsLastname", + "Gen-CatfolkLastname", + "Gen-FetchlingsLastname", + "Gen-HalfElfLastname", + "Gen-HalfOrcLastname", + "Gen-HobgoblinLastname", + "Gen-IfritsLastname", + "Gen-KobaldsLastname", + "Gen-OreadsLastname", + "Gen-RatfolkLastname", + "Gen-SylphsLastname", + "Gen-TenguLastname", + "Gen-TiansLastname", + "Gen-TieflingLastname", + "Gen-UndinesLastname", + "Gen-AngelMaleLastname", + "Gen-AngelFemaleLastname", + "Gen-CavePersonMaleLastname", + "Gen-CavePersonFemaleLastname", + "Gen-DarkElfMaleLastname", + "Gen-DarkElfFemaleLastname", + "Gen-DemonLastname", + "Gen-DragonMaleLastname", + "Gen-DragonFemaleLastname", + "Gen-DrowMaleLastname", + "Gen-DrowFemaleLastname", + "Gen-FairyMaleLastname", + "Gen-FairyFemaleLastname", + "Gen-GnomeMaleLastname", + "Gen-GnomeFemaleLastname", + "Gen-GoblinLastname", + "Gen-HalfDemonMaleLastname", + "Gen-HalfDemonFemaleLastname", + "Gen-HalflingMaleLastname", + "Gen-HalflingFemaleLastname", + "Gen-HighElfMaleLastname", + "Gen-HighElfFemaleLastname", + "Gen-HighFairyMaleLastname", + "Gen-HighFairyFemaleLastname", + "Gen-OgreLastname", + "Gen-Aasimars", + "Gen-Catfolk", + "Gen-Fetchlings", + "Gen-HalfElf", + "Gen-HalfOrc", + "Gen-Hobgoblin", + "Gen-Ifrits", + "Gen-Kobalds", + "Gen-Oreads", + "Gen-Ratfolk", + "Gen-Sylphs", + "Gen-Tengu", + "Gen-Tians", + "Gen-Tiefling", + "Gen-Undines", + "Gen-AngelMale", + "Gen-CavePersonMale", + "Gen-DarkElfMale", + "Gen-DragonMale", + "Gen-DrowMale", + "Gen-FairyMale", + "Gen-GnomeMale", + "Gen-HalfDemonMale", + "Gen-HalflingMale", + "Gen-HighElfMale", + "Gen-HighFairyMale", + "Gen-Ogre", + "Gen-AngelFemale", + "Gen-CavePersonFemale", + "Gen-DarkElfFemale", + "Gen-Demon", + "Gen-DragonFemale", + "Gen-DrowFemale", + "Gen-FairyFemale", + "Gen-GnomeFemale", + "Gen-Goblin", + "Gen-HalfDemonFemale", + "Gen-HalflingFemale", + "Gen-HighElfFemale", + "Gen-HighFairyFemale", + "Gen-PlotStoryHooks" +]; export type currency = { name: string, @@ -225,9 +336,25 @@ const DEFAULT_SETTINGS: MyPluginSettings = { export default class MyPlugin extends Plugin { settings: MyPluginSettings; + getOptionsForSuggest(): string[] { + return possibleOptions; + } + async onload() { await this.loadSettings(); + console.log("loaded Fantasy Content Generator"); + + app.workspace.onLayoutReady(() => { + const view = this.app.workspace.getActiveViewOfType(MarkdownView); + // Make sure the user is editing a Markdown file. + if (view) { + this.registerEditorSuggest(new AutoComplete(this.getOptionsForSuggest, this)); + } + }); + + + //console.log(this.registerEditorSuggest(new AutoComplete(this.getOptionsForSuggest))); // This creates an icon in the left ribbon. const ribbonIconEl = this.addRibbonIcon('book', 'Fantasy Generators', (evt: MouseEvent) => { // Called when the user clicks the icon. diff --git a/package-lock.json b/package-lock.json index a9053ae..3efdc26 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,14 +1,19 @@ { - "name": "obsidian-sample-plugin", - "version": "1.0.0", + "name": "fantasy-content-generator", + "version": "1.0.1-a", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "obsidian-sample-plugin", - "version": "1.0.0", + "name": "fantasy-content-generator", + "version": "1.0.1-a", "license": "MIT", "dependencies": { + "@codemirror/autocomplete": "^6.4.1", + "@codemirror/commands": "^6.2.1", + "@codemirror/lang-markdown": "^6.0.5", + "@codemirror/lint": "^6.1.1", + "@codemirror/stream-parser": "^0.19.9", "fantasy-content-generator": "^4.9.1", "fantasy-name-generator": "^2.0.0", "react": "^18.2.0", @@ -27,19 +32,261 @@ "typescript": "4.7.4" } }, + "node_modules/@codemirror/autocomplete": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.4.1.tgz", + "integrity": "sha512-06yAmj0FjPZzYOpNeugJtG28GNqU2/CPr34m91Q+fKSyTOR6+hDFiatkPcIkxOlU0K5yP7WH6KoLg3fTqIUgaw==", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.6.0", + "@lezer/common": "^1.0.0" + }, + "peerDependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@codemirror/commands": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.2.1.tgz", + "integrity": "sha512-FFiNKGuHA5O8uC6IJE5apI5rT9gyjlw4whqy4vlcX0wE/myxL6P1s0upwDhY4HtMWLOwzwsp0ap3bjdQhvfDOA==", + "dependencies": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.2.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@codemirror/highlight": { + "version": "0.19.8", + "resolved": "https://registry.npmjs.org/@codemirror/highlight/-/highlight-0.19.8.tgz", + "integrity": "sha512-v/lzuHjrYR8MN2mEJcUD6fHSTXXli9C1XGYpr+ElV6fLBIUhMTNKR3qThp611xuWfXfwDxeL7ppcbkM/MzPV3A==", + "deprecated": "As of 0.20.0, this package has been split between @lezer/highlight and @codemirror/language", + "dependencies": { + "@codemirror/language": "^0.19.0", + "@codemirror/rangeset": "^0.19.0", + "@codemirror/state": "^0.19.3", + "@codemirror/view": "^0.19.39", + "@lezer/common": "^0.15.0", + "style-mod": "^4.0.0" + } + }, + "node_modules/@codemirror/highlight/node_modules/@codemirror/language": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-0.19.10.tgz", + "integrity": "sha512-yA0DZ3RYn2CqAAGW62VrU8c4YxscMQn45y/I9sjBlqB1e2OTQLg4CCkMBuMSLXk4xaqjlsgazeOQWaJQOKfV8Q==", + "dependencies": { + "@codemirror/state": "^0.19.0", + "@codemirror/text": "^0.19.0", + "@codemirror/view": "^0.19.0", + "@lezer/common": "^0.15.5", + "@lezer/lr": "^0.15.0" + } + }, + "node_modules/@codemirror/highlight/node_modules/@codemirror/state": { + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-0.19.9.tgz", + "integrity": "sha512-psOzDolKTZkx4CgUqhBQ8T8gBc0xN5z4gzed109aF6x7D7umpDRoimacI/O6d9UGuyl4eYuDCZmDFr2Rq7aGOw==", + "dependencies": { + "@codemirror/text": "^0.19.0" + } + }, + "node_modules/@codemirror/highlight/node_modules/@codemirror/view": { + "version": "0.19.48", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-0.19.48.tgz", + "integrity": "sha512-0eg7D2Nz4S8/caetCTz61rK0tkHI17V/d15Jy0kLOT8dTLGGNJUponDnW28h2B6bERmPlVHKh8MJIr5OCp1nGw==", + "dependencies": { + "@codemirror/rangeset": "^0.19.5", + "@codemirror/state": "^0.19.3", + "@codemirror/text": "^0.19.0", + "style-mod": "^4.0.0", + "w3c-keyname": "^2.2.4" + } + }, + "node_modules/@codemirror/highlight/node_modules/@lezer/common": { + "version": "0.15.12", + "resolved": "https://registry.npmjs.org/@lezer/common/-/common-0.15.12.tgz", + "integrity": "sha512-edfwCxNLnzq5pBA/yaIhwJ3U3Kz8VAUOTRg0hhxaizaI1N+qxV7EXDv/kLCkLeq2RzSFvxexlaj5Mzfn2kY0Ig==" + }, + "node_modules/@codemirror/highlight/node_modules/@lezer/lr": { + "version": "0.15.8", + "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-0.15.8.tgz", + "integrity": "sha512-bM6oE6VQZ6hIFxDNKk8bKPa14hqFrV07J/vHGOeiAbJReIaQXmkVb6xQu4MR+JBTLa5arGRyAAjJe1qaQt3Uvg==", + "dependencies": { + "@lezer/common": "^0.15.0" + } + }, + "node_modules/@codemirror/lang-css": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.0.2.tgz", + "integrity": "sha512-4V4zmUOl2Glx0GWw0HiO1oGD4zvMlIQ3zx5hXOE6ipCjhohig2bhWRAasrZylH9pRNTcl1VMa59Lsl8lZWlTzw==", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@lezer/css": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-html": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-html/-/lang-html-6.4.2.tgz", + "integrity": "sha512-bqCBASkteKySwtIbiV/WCtGnn/khLRbbiV5TE+d9S9eQJD7BA4c5dTRm2b3bVmSpilff5EYxvB4PQaZzM/7cNw==", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/lang-css": "^6.0.0", + "@codemirror/lang-javascript": "^6.0.0", + "@codemirror/language": "^6.4.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.2.2", + "@lezer/common": "^1.0.0", + "@lezer/css": "^1.1.0", + "@lezer/html": "^1.3.0" + } + }, + "node_modules/@codemirror/lang-javascript": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.1.4.tgz", + "integrity": "sha512-OxLf7OfOZBTMRMi6BO/F72MNGmgOd9B0vetOLvHsDACFXayBzW8fm8aWnDM0yuy68wTK03MBf4HbjSBNRG5q7A==", + "dependencies": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.6.0", + "@codemirror/lint": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.0.0", + "@lezer/javascript": "^1.0.0" + } + }, + "node_modules/@codemirror/lang-markdown": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/@codemirror/lang-markdown/-/lang-markdown-6.0.5.tgz", + "integrity": "sha512-qH0THRYc2M7pIJoAp6jstXZkv8ZMVhNaBm7Bs4+0SLHhHlwX53txFy98AcPwrfq0Sh8Zi6RAuj9j/GyL8E1MKw==", + "dependencies": { + "@codemirror/lang-html": "^6.0.0", + "@codemirror/language": "^6.3.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.0.0", + "@lezer/markdown": "^1.0.0" + } + }, + "node_modules/@codemirror/language": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.6.0.tgz", + "integrity": "sha512-cwUd6lzt3MfNYOobdjf14ZkLbJcnv4WtndYaoBkbor/vF+rCNguMPK0IRtvZJG4dsWiaWPcK8x1VijhvSxnstg==", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.0.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0", + "style-mod": "^4.0.0" + } + }, + "node_modules/@codemirror/lint": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.1.1.tgz", + "integrity": "sha512-e+M543x0NVHGayNHQzLP4XByJsvbu/ojY6+0VF2Y4Uu66Rt1nADuxNflZwECLf7gS009smIsptSUa6bUj/U/rw==", + "dependencies": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "crelt": "^1.0.5" + } + }, + "node_modules/@codemirror/rangeset": { + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@codemirror/rangeset/-/rangeset-0.19.9.tgz", + "integrity": "sha512-V8YUuOvK+ew87Xem+71nKcqu1SXd5QROMRLMS/ljT5/3MCxtgrRie1Cvild0G/Z2f1fpWxzX78V0U4jjXBorBQ==", + "deprecated": "As of 0.20.0, this package has been merged into @codemirror/state", + "dependencies": { + "@codemirror/state": "^0.19.0" + } + }, + "node_modules/@codemirror/rangeset/node_modules/@codemirror/state": { + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-0.19.9.tgz", + "integrity": "sha512-psOzDolKTZkx4CgUqhBQ8T8gBc0xN5z4gzed109aF6x7D7umpDRoimacI/O6d9UGuyl4eYuDCZmDFr2Rq7aGOw==", + "dependencies": { + "@codemirror/text": "^0.19.0" + } + }, "node_modules/@codemirror/state": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.2.0.tgz", - "integrity": "sha512-69QXtcrsc3RYtOtd+GsvczJ319udtBf1PTrr2KbLWM/e2CXUPnh0Nz9AUo8WfhSQ7GeL8dPVNUmhQVgpmuaNGA==", - "dev": true, - "peer": true + "integrity": "sha512-69QXtcrsc3RYtOtd+GsvczJ319udtBf1PTrr2KbLWM/e2CXUPnh0Nz9AUo8WfhSQ7GeL8dPVNUmhQVgpmuaNGA==" + }, + "node_modules/@codemirror/stream-parser": { + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@codemirror/stream-parser/-/stream-parser-0.19.9.tgz", + "integrity": "sha512-WTmkEFSRCetpk8xIOvV2yyXdZs3DgYckM0IP7eFi4ewlxWnJO/H4BeJZLs4wQaydWsAqTQoDyIwNH1BCzK5LUQ==", + "deprecated": "As of 0.20.0, this package has been merged into @codemirror/language", + "dependencies": { + "@codemirror/highlight": "^0.19.0", + "@codemirror/language": "^0.19.0", + "@codemirror/state": "^0.19.0", + "@codemirror/text": "^0.19.0", + "@lezer/common": "^0.15.0", + "@lezer/lr": "^0.15.0" + } + }, + "node_modules/@codemirror/stream-parser/node_modules/@codemirror/language": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-0.19.10.tgz", + "integrity": "sha512-yA0DZ3RYn2CqAAGW62VrU8c4YxscMQn45y/I9sjBlqB1e2OTQLg4CCkMBuMSLXk4xaqjlsgazeOQWaJQOKfV8Q==", + "dependencies": { + "@codemirror/state": "^0.19.0", + "@codemirror/text": "^0.19.0", + "@codemirror/view": "^0.19.0", + "@lezer/common": "^0.15.5", + "@lezer/lr": "^0.15.0" + } + }, + "node_modules/@codemirror/stream-parser/node_modules/@codemirror/state": { + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-0.19.9.tgz", + "integrity": "sha512-psOzDolKTZkx4CgUqhBQ8T8gBc0xN5z4gzed109aF6x7D7umpDRoimacI/O6d9UGuyl4eYuDCZmDFr2Rq7aGOw==", + "dependencies": { + "@codemirror/text": "^0.19.0" + } + }, + "node_modules/@codemirror/stream-parser/node_modules/@codemirror/view": { + "version": "0.19.48", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-0.19.48.tgz", + "integrity": "sha512-0eg7D2Nz4S8/caetCTz61rK0tkHI17V/d15Jy0kLOT8dTLGGNJUponDnW28h2B6bERmPlVHKh8MJIr5OCp1nGw==", + "dependencies": { + "@codemirror/rangeset": "^0.19.5", + "@codemirror/state": "^0.19.3", + "@codemirror/text": "^0.19.0", + "style-mod": "^4.0.0", + "w3c-keyname": "^2.2.4" + } + }, + "node_modules/@codemirror/stream-parser/node_modules/@lezer/common": { + "version": "0.15.12", + "resolved": "https://registry.npmjs.org/@lezer/common/-/common-0.15.12.tgz", + "integrity": "sha512-edfwCxNLnzq5pBA/yaIhwJ3U3Kz8VAUOTRg0hhxaizaI1N+qxV7EXDv/kLCkLeq2RzSFvxexlaj5Mzfn2kY0Ig==" + }, + "node_modules/@codemirror/stream-parser/node_modules/@lezer/lr": { + "version": "0.15.8", + "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-0.15.8.tgz", + "integrity": "sha512-bM6oE6VQZ6hIFxDNKk8bKPa14hqFrV07J/vHGOeiAbJReIaQXmkVb6xQu4MR+JBTLa5arGRyAAjJe1qaQt3Uvg==", + "dependencies": { + "@lezer/common": "^0.15.0" + } + }, + "node_modules/@codemirror/text": { + "version": "0.19.6", + "resolved": "https://registry.npmjs.org/@codemirror/text/-/text-0.19.6.tgz", + "integrity": "sha512-T9jnREMIygx+TPC1bOuepz18maGq/92q2a+n4qTqObKwvNMg+8cMTslb8yxeEDEq7S3kpgGWxgO1UWbQRij0dA==", + "deprecated": "As of 0.20.0, this package has been merged into @codemirror/state" }, "node_modules/@codemirror/view": { "version": "6.7.3", "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.7.3.tgz", "integrity": "sha512-Lt+4POnhXrZFfHOdPzXEHxrzwdy7cjqYlMkOWvoFGi6/bAsjzlFfr0NY3B15B/PGx+cDFgM1hlc12wvYeZbGLw==", - "dev": true, - "peer": true, "dependencies": { "@codemirror/state": "^6.1.4", "style-mod": "^4.0.0", @@ -458,6 +705,64 @@ "dev": true, "peer": true }, + "node_modules/@lezer/common": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.0.2.tgz", + "integrity": "sha512-SVgiGtMnMnW3ActR8SXgsDhw7a0w0ChHSYAyAUxxrOiJ1OqYWEKk/xJd84tTSPo1mo6DXLObAJALNnd0Hrv7Ng==" + }, + "node_modules/@lezer/css": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.1.1.tgz", + "integrity": "sha512-mSjx+unLLapEqdOYDejnGBokB5+AiJKZVclmud0MKQOKx3DLJ5b5VTCstgDDknR6iIV4gVrN6euzsCnj0A2gQA==", + "dependencies": { + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/highlight": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.1.3.tgz", + "integrity": "sha512-3vLKLPThO4td43lYRBygmMY18JN3CPh9w+XS2j8WC30vR4yZeFG4z1iFe4jXE43NtGqe//zHW5q8ENLlHvz9gw==", + "dependencies": { + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@lezer/html": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@lezer/html/-/html-1.3.2.tgz", + "integrity": "sha512-LKGyDdqqDugXR/lKM9FwaKEfMerbZ/aqvhLf0P1FLLK/pVP7wKHXGcg6g3cJ7ckvFidn0tXA8jioG0irVsCBAQ==", + "dependencies": { + "@lezer/common": "^1.0.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "node_modules/@lezer/javascript": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.4.1.tgz", + "integrity": "sha512-Hqx36DJeYhKtdpc7wBYPR0XF56ZzIp0IkMO/zNNj80xcaFOV4Oj/P7TQc/8k2TxNhzl7tV5tXS8ZOCPbT4L3nA==", + "dependencies": { + "@lezer/highlight": "^1.1.3", + "@lezer/lr": "^1.3.0" + } + }, + "node_modules/@lezer/lr": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.3.3.tgz", + "integrity": "sha512-JPQe3mwJlzEVqy67iQiiGozhcngbO8QBgpqZM6oL1Wj/dXckrEexpBLeFkq0edtW5IqnPRFxA24BHJni8Js69w==", + "dependencies": { + "@lezer/common": "^1.0.0" + } + }, + "node_modules/@lezer/markdown": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@lezer/markdown/-/markdown-1.0.2.tgz", + "integrity": "sha512-8CY0OoZ6V5EzPjSPeJ4KLVbtXdLBd8V6sRCooN5kHnO28ytreEGTyrtU/zUwo/XLRzGr/e1g44KlzKi3yWGB5A==", + "dependencies": { + "@lezer/common": "^1.0.0", + "@lezer/highlight": "^1.0.0" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -991,6 +1296,11 @@ "dev": true, "peer": true }, + "node_modules/crelt": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.5.tgz", + "integrity": "sha512-+BO9wPPi+DWTDcNYhr/W90myha8ptzftZT+LwcmUbbok0rcP/fequmFYCw8NMoH7pkAZQzU78b3kYrlua5a9eA==" + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -2208,9 +2518,7 @@ "node_modules/style-mod": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.0.0.tgz", - "integrity": "sha512-OPhtyEjyyN9x3nhPsu76f52yUGXiZcgvsrFVtvTkyGRQJ0XK+GPc6ov1z+lRpbeabka+MYEQxOYRnt5nF30aMw==", - "dev": true, - "peer": true + "integrity": "sha512-OPhtyEjyyN9x3nhPsu76f52yUGXiZcgvsrFVtvTkyGRQJ0XK+GPc6ov1z+lRpbeabka+MYEQxOYRnt5nF30aMw==" }, "node_modules/supports-color": { "version": "7.2.0", @@ -2302,9 +2610,7 @@ "node_modules/w3c-keyname": { "version": "2.2.6", "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.6.tgz", - "integrity": "sha512-f+fciywl1SJEniZHD6H+kUO8gOnwIr7f4ijKA6+ZvJFjeGi1r4PDLl53Ayud9O/rk64RqgoQine0feoeOU0kXg==", - "dev": true, - "peer": true + "integrity": "sha512-f+fciywl1SJEniZHD6H+kUO8gOnwIr7f4ijKA6+ZvJFjeGi1r4PDLl53Ayud9O/rk64RqgoQine0feoeOU0kXg==" }, "node_modules/which": { "version": "2.0.2", @@ -2360,19 +2666,257 @@ } }, "dependencies": { + "@codemirror/autocomplete": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.4.1.tgz", + "integrity": "sha512-06yAmj0FjPZzYOpNeugJtG28GNqU2/CPr34m91Q+fKSyTOR6+hDFiatkPcIkxOlU0K5yP7WH6KoLg3fTqIUgaw==", + "requires": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.6.0", + "@lezer/common": "^1.0.0" + } + }, + "@codemirror/commands": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.2.1.tgz", + "integrity": "sha512-FFiNKGuHA5O8uC6IJE5apI5rT9gyjlw4whqy4vlcX0wE/myxL6P1s0upwDhY4HtMWLOwzwsp0ap3bjdQhvfDOA==", + "requires": { + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.2.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.0.0" + } + }, + "@codemirror/highlight": { + "version": "0.19.8", + "resolved": "https://registry.npmjs.org/@codemirror/highlight/-/highlight-0.19.8.tgz", + "integrity": "sha512-v/lzuHjrYR8MN2mEJcUD6fHSTXXli9C1XGYpr+ElV6fLBIUhMTNKR3qThp611xuWfXfwDxeL7ppcbkM/MzPV3A==", + "requires": { + "@codemirror/language": "^0.19.0", + "@codemirror/rangeset": "^0.19.0", + "@codemirror/state": "^0.19.3", + "@codemirror/view": "^0.19.39", + "@lezer/common": "^0.15.0", + "style-mod": "^4.0.0" + }, + "dependencies": { + "@codemirror/language": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-0.19.10.tgz", + "integrity": "sha512-yA0DZ3RYn2CqAAGW62VrU8c4YxscMQn45y/I9sjBlqB1e2OTQLg4CCkMBuMSLXk4xaqjlsgazeOQWaJQOKfV8Q==", + "requires": { + "@codemirror/state": "^0.19.0", + "@codemirror/text": "^0.19.0", + "@codemirror/view": "^0.19.0", + "@lezer/common": "^0.15.5", + "@lezer/lr": "^0.15.0" + } + }, + "@codemirror/state": { + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-0.19.9.tgz", + "integrity": "sha512-psOzDolKTZkx4CgUqhBQ8T8gBc0xN5z4gzed109aF6x7D7umpDRoimacI/O6d9UGuyl4eYuDCZmDFr2Rq7aGOw==", + "requires": { + "@codemirror/text": "^0.19.0" + } + }, + "@codemirror/view": { + "version": "0.19.48", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-0.19.48.tgz", + "integrity": "sha512-0eg7D2Nz4S8/caetCTz61rK0tkHI17V/d15Jy0kLOT8dTLGGNJUponDnW28h2B6bERmPlVHKh8MJIr5OCp1nGw==", + "requires": { + "@codemirror/rangeset": "^0.19.5", + "@codemirror/state": "^0.19.3", + "@codemirror/text": "^0.19.0", + "style-mod": "^4.0.0", + "w3c-keyname": "^2.2.4" + } + }, + "@lezer/common": { + "version": "0.15.12", + "resolved": "https://registry.npmjs.org/@lezer/common/-/common-0.15.12.tgz", + "integrity": "sha512-edfwCxNLnzq5pBA/yaIhwJ3U3Kz8VAUOTRg0hhxaizaI1N+qxV7EXDv/kLCkLeq2RzSFvxexlaj5Mzfn2kY0Ig==" + }, + "@lezer/lr": { + "version": "0.15.8", + "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-0.15.8.tgz", + "integrity": "sha512-bM6oE6VQZ6hIFxDNKk8bKPa14hqFrV07J/vHGOeiAbJReIaQXmkVb6xQu4MR+JBTLa5arGRyAAjJe1qaQt3Uvg==", + "requires": { + "@lezer/common": "^0.15.0" + } + } + } + }, + "@codemirror/lang-css": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-css/-/lang-css-6.0.2.tgz", + "integrity": "sha512-4V4zmUOl2Glx0GWw0HiO1oGD4zvMlIQ3zx5hXOE6ipCjhohig2bhWRAasrZylH9pRNTcl1VMa59Lsl8lZWlTzw==", + "requires": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@lezer/css": "^1.0.0" + } + }, + "@codemirror/lang-html": { + "version": "6.4.2", + "resolved": "https://registry.npmjs.org/@codemirror/lang-html/-/lang-html-6.4.2.tgz", + "integrity": "sha512-bqCBASkteKySwtIbiV/WCtGnn/khLRbbiV5TE+d9S9eQJD7BA4c5dTRm2b3bVmSpilff5EYxvB4PQaZzM/7cNw==", + "requires": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/lang-css": "^6.0.0", + "@codemirror/lang-javascript": "^6.0.0", + "@codemirror/language": "^6.4.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.2.2", + "@lezer/common": "^1.0.0", + "@lezer/css": "^1.1.0", + "@lezer/html": "^1.3.0" + } + }, + "@codemirror/lang-javascript": { + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/@codemirror/lang-javascript/-/lang-javascript-6.1.4.tgz", + "integrity": "sha512-OxLf7OfOZBTMRMi6BO/F72MNGmgOd9B0vetOLvHsDACFXayBzW8fm8aWnDM0yuy68wTK03MBf4HbjSBNRG5q7A==", + "requires": { + "@codemirror/autocomplete": "^6.0.0", + "@codemirror/language": "^6.6.0", + "@codemirror/lint": "^6.0.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.0.0", + "@lezer/javascript": "^1.0.0" + } + }, + "@codemirror/lang-markdown": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/@codemirror/lang-markdown/-/lang-markdown-6.0.5.tgz", + "integrity": "sha512-qH0THRYc2M7pIJoAp6jstXZkv8ZMVhNaBm7Bs4+0SLHhHlwX53txFy98AcPwrfq0Sh8Zi6RAuj9j/GyL8E1MKw==", + "requires": { + "@codemirror/lang-html": "^6.0.0", + "@codemirror/language": "^6.3.0", + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.0.0", + "@lezer/markdown": "^1.0.0" + } + }, + "@codemirror/language": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.6.0.tgz", + "integrity": "sha512-cwUd6lzt3MfNYOobdjf14ZkLbJcnv4WtndYaoBkbor/vF+rCNguMPK0IRtvZJG4dsWiaWPcK8x1VijhvSxnstg==", + "requires": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "@lezer/common": "^1.0.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0", + "style-mod": "^4.0.0" + } + }, + "@codemirror/lint": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.1.1.tgz", + "integrity": "sha512-e+M543x0NVHGayNHQzLP4XByJsvbu/ojY6+0VF2Y4Uu66Rt1nADuxNflZwECLf7gS009smIsptSUa6bUj/U/rw==", + "requires": { + "@codemirror/state": "^6.0.0", + "@codemirror/view": "^6.0.0", + "crelt": "^1.0.5" + } + }, + "@codemirror/rangeset": { + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@codemirror/rangeset/-/rangeset-0.19.9.tgz", + "integrity": "sha512-V8YUuOvK+ew87Xem+71nKcqu1SXd5QROMRLMS/ljT5/3MCxtgrRie1Cvild0G/Z2f1fpWxzX78V0U4jjXBorBQ==", + "requires": { + "@codemirror/state": "^0.19.0" + }, + "dependencies": { + "@codemirror/state": { + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-0.19.9.tgz", + "integrity": "sha512-psOzDolKTZkx4CgUqhBQ8T8gBc0xN5z4gzed109aF6x7D7umpDRoimacI/O6d9UGuyl4eYuDCZmDFr2Rq7aGOw==", + "requires": { + "@codemirror/text": "^0.19.0" + } + } + } + }, "@codemirror/state": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.2.0.tgz", - "integrity": "sha512-69QXtcrsc3RYtOtd+GsvczJ319udtBf1PTrr2KbLWM/e2CXUPnh0Nz9AUo8WfhSQ7GeL8dPVNUmhQVgpmuaNGA==", - "dev": true, - "peer": true + "integrity": "sha512-69QXtcrsc3RYtOtd+GsvczJ319udtBf1PTrr2KbLWM/e2CXUPnh0Nz9AUo8WfhSQ7GeL8dPVNUmhQVgpmuaNGA==" + }, + "@codemirror/stream-parser": { + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@codemirror/stream-parser/-/stream-parser-0.19.9.tgz", + "integrity": "sha512-WTmkEFSRCetpk8xIOvV2yyXdZs3DgYckM0IP7eFi4ewlxWnJO/H4BeJZLs4wQaydWsAqTQoDyIwNH1BCzK5LUQ==", + "requires": { + "@codemirror/highlight": "^0.19.0", + "@codemirror/language": "^0.19.0", + "@codemirror/state": "^0.19.0", + "@codemirror/text": "^0.19.0", + "@lezer/common": "^0.15.0", + "@lezer/lr": "^0.15.0" + }, + "dependencies": { + "@codemirror/language": { + "version": "0.19.10", + "resolved": "https://registry.npmjs.org/@codemirror/language/-/language-0.19.10.tgz", + "integrity": "sha512-yA0DZ3RYn2CqAAGW62VrU8c4YxscMQn45y/I9sjBlqB1e2OTQLg4CCkMBuMSLXk4xaqjlsgazeOQWaJQOKfV8Q==", + "requires": { + "@codemirror/state": "^0.19.0", + "@codemirror/text": "^0.19.0", + "@codemirror/view": "^0.19.0", + "@lezer/common": "^0.15.5", + "@lezer/lr": "^0.15.0" + } + }, + "@codemirror/state": { + "version": "0.19.9", + "resolved": "https://registry.npmjs.org/@codemirror/state/-/state-0.19.9.tgz", + "integrity": "sha512-psOzDolKTZkx4CgUqhBQ8T8gBc0xN5z4gzed109aF6x7D7umpDRoimacI/O6d9UGuyl4eYuDCZmDFr2Rq7aGOw==", + "requires": { + "@codemirror/text": "^0.19.0" + } + }, + "@codemirror/view": { + "version": "0.19.48", + "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-0.19.48.tgz", + "integrity": "sha512-0eg7D2Nz4S8/caetCTz61rK0tkHI17V/d15Jy0kLOT8dTLGGNJUponDnW28h2B6bERmPlVHKh8MJIr5OCp1nGw==", + "requires": { + "@codemirror/rangeset": "^0.19.5", + "@codemirror/state": "^0.19.3", + "@codemirror/text": "^0.19.0", + "style-mod": "^4.0.0", + "w3c-keyname": "^2.2.4" + } + }, + "@lezer/common": { + "version": "0.15.12", + "resolved": "https://registry.npmjs.org/@lezer/common/-/common-0.15.12.tgz", + "integrity": "sha512-edfwCxNLnzq5pBA/yaIhwJ3U3Kz8VAUOTRg0hhxaizaI1N+qxV7EXDv/kLCkLeq2RzSFvxexlaj5Mzfn2kY0Ig==" + }, + "@lezer/lr": { + "version": "0.15.8", + "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-0.15.8.tgz", + "integrity": "sha512-bM6oE6VQZ6hIFxDNKk8bKPa14hqFrV07J/vHGOeiAbJReIaQXmkVb6xQu4MR+JBTLa5arGRyAAjJe1qaQt3Uvg==", + "requires": { + "@lezer/common": "^0.15.0" + } + } + } + }, + "@codemirror/text": { + "version": "0.19.6", + "resolved": "https://registry.npmjs.org/@codemirror/text/-/text-0.19.6.tgz", + "integrity": "sha512-T9jnREMIygx+TPC1bOuepz18maGq/92q2a+n4qTqObKwvNMg+8cMTslb8yxeEDEq7S3kpgGWxgO1UWbQRij0dA==" }, "@codemirror/view": { "version": "6.7.3", "resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.7.3.tgz", "integrity": "sha512-Lt+4POnhXrZFfHOdPzXEHxrzwdy7cjqYlMkOWvoFGi6/bAsjzlFfr0NY3B15B/PGx+cDFgM1hlc12wvYeZbGLw==", - "dev": true, - "peer": true, "requires": { "@codemirror/state": "^6.1.4", "style-mod": "^4.0.0", @@ -2577,6 +3121,64 @@ "dev": true, "peer": true }, + "@lezer/common": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.0.2.tgz", + "integrity": "sha512-SVgiGtMnMnW3ActR8SXgsDhw7a0w0ChHSYAyAUxxrOiJ1OqYWEKk/xJd84tTSPo1mo6DXLObAJALNnd0Hrv7Ng==" + }, + "@lezer/css": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@lezer/css/-/css-1.1.1.tgz", + "integrity": "sha512-mSjx+unLLapEqdOYDejnGBokB5+AiJKZVclmud0MKQOKx3DLJ5b5VTCstgDDknR6iIV4gVrN6euzsCnj0A2gQA==", + "requires": { + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "@lezer/highlight": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.1.3.tgz", + "integrity": "sha512-3vLKLPThO4td43lYRBygmMY18JN3CPh9w+XS2j8WC30vR4yZeFG4z1iFe4jXE43NtGqe//zHW5q8ENLlHvz9gw==", + "requires": { + "@lezer/common": "^1.0.0" + } + }, + "@lezer/html": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@lezer/html/-/html-1.3.2.tgz", + "integrity": "sha512-LKGyDdqqDugXR/lKM9FwaKEfMerbZ/aqvhLf0P1FLLK/pVP7wKHXGcg6g3cJ7ckvFidn0tXA8jioG0irVsCBAQ==", + "requires": { + "@lezer/common": "^1.0.0", + "@lezer/highlight": "^1.0.0", + "@lezer/lr": "^1.0.0" + } + }, + "@lezer/javascript": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@lezer/javascript/-/javascript-1.4.1.tgz", + "integrity": "sha512-Hqx36DJeYhKtdpc7wBYPR0XF56ZzIp0IkMO/zNNj80xcaFOV4Oj/P7TQc/8k2TxNhzl7tV5tXS8ZOCPbT4L3nA==", + "requires": { + "@lezer/highlight": "^1.1.3", + "@lezer/lr": "^1.3.0" + } + }, + "@lezer/lr": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.3.3.tgz", + "integrity": "sha512-JPQe3mwJlzEVqy67iQiiGozhcngbO8QBgpqZM6oL1Wj/dXckrEexpBLeFkq0edtW5IqnPRFxA24BHJni8Js69w==", + "requires": { + "@lezer/common": "^1.0.0" + } + }, + "@lezer/markdown": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@lezer/markdown/-/markdown-1.0.2.tgz", + "integrity": "sha512-8CY0OoZ6V5EzPjSPeJ4KLVbtXdLBd8V6sRCooN5kHnO28ytreEGTyrtU/zUwo/XLRzGr/e1g44KlzKi3yWGB5A==", + "requires": { + "@lezer/common": "^1.0.0", + "@lezer/highlight": "^1.0.0" + } + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -2955,6 +3557,11 @@ "dev": true, "peer": true }, + "crelt": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.5.tgz", + "integrity": "sha512-+BO9wPPi+DWTDcNYhr/W90myha8ptzftZT+LwcmUbbok0rcP/fequmFYCw8NMoH7pkAZQzU78b3kYrlua5a9eA==" + }, "cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -3866,9 +4473,7 @@ "style-mod": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.0.0.tgz", - "integrity": "sha512-OPhtyEjyyN9x3nhPsu76f52yUGXiZcgvsrFVtvTkyGRQJ0XK+GPc6ov1z+lRpbeabka+MYEQxOYRnt5nF30aMw==", - "dev": true, - "peer": true + "integrity": "sha512-OPhtyEjyyN9x3nhPsu76f52yUGXiZcgvsrFVtvTkyGRQJ0XK+GPc6ov1z+lRpbeabka+MYEQxOYRnt5nF30aMw==" }, "supports-color": { "version": "7.2.0", @@ -3938,9 +4543,7 @@ "w3c-keyname": { "version": "2.2.6", "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.6.tgz", - "integrity": "sha512-f+fciywl1SJEniZHD6H+kUO8gOnwIr7f4ijKA6+ZvJFjeGi1r4PDLl53Ayud9O/rk64RqgoQine0feoeOU0kXg==", - "dev": true, - "peer": true + "integrity": "sha512-f+fciywl1SJEniZHD6H+kUO8gOnwIr7f4ijKA6+ZvJFjeGi1r4PDLl53Ayud9O/rk64RqgoQine0feoeOU0kXg==" }, "which": { "version": "2.0.2", diff --git a/package.json b/package.json index 848b90e..82e56ed 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,11 @@ "typescript": "4.7.4" }, "dependencies": { + "@codemirror/autocomplete": "^6.4.1", + "@codemirror/commands": "^6.2.1", + "@codemirror/lang-markdown": "^6.0.5", + "@codemirror/lint": "^6.1.1", + "@codemirror/stream-parser": "^0.19.9", "fantasy-content-generator": "^4.9.1", "fantasy-name-generator": "^2.0.0", "react": "^18.2.0",