Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@bscotch/gcdata

Package Overview
Dependencies
Maintainers
0
Versions
20
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@bscotch/gcdata - npm Package Compare versions

Comparing version 0.20.1 to 0.21.0

dist/cl2.character.pointers.d.ts

6

dist/cl2.comfort.d.ts

@@ -1,4 +0,4 @@

export { parseStringifiedStoryline, updateChangesFromParsedStoryline, } from './cl2.comfort.parse.js';
export { stringifyStoryline } from './cl2.comfort.stringify.js';
export { isComfortMote as isStorylineMote, listComforts as listStorylines, comfortSchemaId as storylineSchemaId, type ComfortData as StorylineData, type ComfortMote as StorylineMote, type StorylineUpdateResult, } from './cl2.comfort.types.js';
export { parseStringifiedComfort, updateChangesFromParsedComfort, } from './cl2.comfort.parse.js';
export { stringifyComfort } from './cl2.comfort.stringify.js';
export { isComfortMote, listComforts, type ComfortUpdateResult, } from './cl2.comfort.types.js';
//# sourceMappingURL=cl2.comfort.d.ts.map

@@ -1,4 +0,4 @@

export { parseStringifiedStoryline, updateChangesFromParsedStoryline, } from './cl2.comfort.parse.js';
export { stringifyStoryline } from './cl2.comfort.stringify.js';
export { isComfortMote as isStorylineMote, listComforts as listStorylines, comfortSchemaId as storylineSchemaId, } from './cl2.comfort.types.js';
export { parseStringifiedComfort, updateChangesFromParsedComfort, } from './cl2.comfort.parse.js';
export { stringifyComfort } from './cl2.comfort.stringify.js';
export { isComfortMote, listComforts, } from './cl2.comfort.types.js';
//# sourceMappingURL=cl2.comfort.js.map
import type { GameChanger } from './GameChanger.js';
import { type StorylineUpdateResult } from './cl2.storyline.types.js';
export declare function parseStringifiedStoryline(text: string, packed: GameChanger, options?: {
import { type ComfortUpdateResult } from './cl2.comfort.types.js';
export declare function parseStringifiedComfort(text: string, packed: GameChanger, options?: {
checkSpelling?: boolean;
}): StorylineUpdateResult;
export declare function updateChangesFromParsedStoryline(parsed: StorylineUpdateResult['parsed'], moteId: string, packed: GameChanger): Promise<void>;
}): ComfortUpdateResult;
export declare function updateChangesFromParsedComfort(parsed: ComfortUpdateResult['parsed'], moteId: string, packed: GameChanger): Promise<void>;
//# sourceMappingURL=cl2.comfort.parse.d.ts.map
import { assert } from './assert.js';
import { getStagingOptions } from './cl2.quest.utils.js';
import { arrayTagPattern, getStorylineMote, getStorylineSchema, lineIsArrayItem, linePatterns, parseIfMatch, storylineSchemaId, } from './cl2.storyline.types.js';
import { bsArrayToArray, createBsArrayKey, updateBsArrayOrder, } from './helpers.js';
import { checkWords, includes } from './util.js';
export function parseStringifiedStoryline(text, packed, options = {}) {
import { getComfortSchema, linePatterns, } from './cl2.comfort.types.js';
import { isCommentLine, isStageLine, prepareParserHelpers, updateWipChangesFromParsed, } from './cl2.shared.parse.js';
import { comfortSchemaId } from './cl2.shared.types.js';
export function parseStringifiedComfort(text, packed, options = {}) {
const result = {

@@ -17,120 +16,26 @@ diagnostics: [],

};
const availableGlobalLabels = new Set([
'Name',
'Description',
'Stage',
]);
const stagingOptions = getStagingOptions(packed.working);
/** Terms from the glossary for use in autocompletes */
const glossaryTerms = (packed.glossary?.relevantTerms() || []).map((t) => t.text);
const checkSpelling = (item) => {
if (!item || !options.checkSpelling)
return;
result.words.push(...checkWords(item, packed.glossary));
};
const lines = text.split(/(\r?\n)/g);
let index = 0;
let lineNumber = 0;
for (const line of lines) {
const helpers = prepareParserHelpers(text, packed, {
...options,
globalLabels: new Set([
'Name',
'Description',
'Unlocked Description',
'Stage',
]),
}, result);
for (const line of helpers.lines) {
const trace = [];
try {
// Is this just a newline?
if (line.match(/\r?\n/)) {
// Then we just need to increment the index
index += line.length;
lineNumber++;
continue;
}
const lineRange = {
start: {
index,
line: lineNumber,
character: 0,
},
end: {
index: index + line.length,
line: lineNumber,
character: line.length,
},
};
// Is this just a blank line?
if (!line) {
// Add global autocompletes
result.completions.push({
type: 'labels',
start: lineRange.start,
end: lineRange.end,
options: availableGlobalLabels,
});
continue;
}
const lineRange = helpers.currentLineRange;
// Find the first matching pattern and pull the values from it.
let parsedLine = null;
for (const pattern of linePatterns) {
parsedLine = parseIfMatch(pattern, line, lineRange.start);
if (parsedLine)
break;
}
if (!parsedLine) {
// Then this is likely the result of uncommenting something
// that was commented out, resulting in a line that starts with
// the comment's array tag. Provide a deletion edit!
parsedLine = parseIfMatch(`^${arrayTagPattern} +(?<text>.*)$`, line, lineRange.start);
if (parsedLine) {
result.edits.push({
start: lineRange.start,
end: lineRange.end,
newText: parsedLine.text.value,
});
}
else {
result.diagnostics.push({
message: `Unfamiliar syntax: ${line}`,
...lineRange,
});
}
index += line.length;
const parsedLine = helpers.parseCurrentLine(linePatterns);
if (!parsedLine)
continue;
}
// Ensure the array tag. It goes right after the label or indicator.
if (!parsedLine.arrayTag?.value && lineIsArrayItem(line)) {
const arrayTag = createBsArrayKey();
const start = parsedLine.indicator?.end || parsedLine.label?.end;
result.edits.push({
start,
end: start,
newText: `#${arrayTag}`,
});
parsedLine.arrayTag = {
start,
end: start,
value: arrayTag,
};
}
// If this has a label, remove it from the list of available labels
if (parsedLine.label?.value &&
availableGlobalLabels.has(parsedLine.label.value)) {
availableGlobalLabels.delete(parsedLine.label.value);
}
// If this has a text section, provide glossary autocompletes
if ('text' in parsedLine) {
const start = parsedLine.text.start;
const end = parsedLine.text.end;
result.completions.push({
type: 'glossary',
start,
end,
options: glossaryTerms,
});
}
// Work through each line type to add diagnostics and completions
const labelLower = parsedLine.label?.value?.toLowerCase();
const indicator = parsedLine.indicator?.value;
if (indicator === '//') {
// Then this is a comment/note
result.parsed.comments.push({
id: parsedLine.arrayTag?.value?.trim(),
text: parsedLine.text?.value?.trim(),
});
checkSpelling(parsedLine.text);
if (isCommentLine(parsedLine)) {
helpers.addComment(parsedLine);
}

@@ -148,23 +53,11 @@ else if (labelLower === 'name') {

result.parsed.description = parsedLine.text?.value?.trim();
checkSpelling(parsedLine.text);
helpers.checkSpelling(parsedLine.text);
}
else if (labelLower === 'stage') {
const stage = parsedLine.text?.value?.trim();
if (includes(stagingOptions, stage)) {
result.parsed.stage = stage;
}
else {
result.diagnostics.push({
message: `Stage must be one of: ${stagingOptions.join(', ')}`,
...lineRange,
});
// Provide autocomplete options
result.completions.push({
type: 'stages',
options: stagingOptions,
start: parsedLine.labelGroup.end,
end: lineRange.end,
});
}
else if (labelLower === 'unlocked description') {
result.parsed.unlockedDescription = parsedLine.text?.value?.trim();
helpers.checkSpelling(parsedLine.text);
}
else if (isStageLine(parsedLine)) {
helpers.addStage(parsedLine);
}
else {

@@ -184,7 +77,7 @@ // Then we're in an error state on this line!

}
index += line.length;
helpers.index += line.length;
}
return result;
}
export async function updateChangesFromParsedStoryline(parsed, moteId, packed) {
export async function updateChangesFromParsedComfort(parsed, moteId, packed) {
const _traceLogs = [];

@@ -197,6 +90,4 @@ const trace = (log) => _traceLogs.push(log);

packed.clearMoteChanges(moteId);
const storylineMoteBase = getStorylineMote(packed.base, moteId);
const storylineMoteWorking = getStorylineMote(packed.working, moteId);
const schema = getStorylineSchema(packed.working);
assert(schema, `${storylineSchemaId} schema not found in working copy`);
const schema = getComfortSchema(packed.working);
assert(schema, `${comfortSchemaId} schema not found in working copy`);
assert(schema.name, 'Quest mote must have a name pointer');

@@ -208,43 +99,4 @@ const updateMote = (path, value) => {

updateMote('data/description/text', parsed.description);
if (parsed.stage) {
updateMote('data/wip/staging', parsed.stage);
}
else if (storylineMoteWorking?.data.wip) {
updateMote('data/wip/staging', null);
}
const parsedComments = parsed.comments.filter((c) => !!c.text);
//#region COMMENTS
// Add/Update COMMENTS
trace(`Updating comments`);
for (const comment of parsedComments) {
trace(`Updating comment ${comment.id} with text "${comment.text}"`);
updateMote(`data/wip/notes/${comment.id}/element/text`, comment.text);
}
// Remove deleted comments
for (const existingComment of bsArrayToArray(storylineMoteBase?.data.wip?.notes || {})) {
if (!parsedComments.find((c) => c.id === existingComment.id)) {
trace(`Deleting comment ${existingComment.id}`);
updateMote(`data/wip/notes/${existingComment.id}`, null);
}
}
// Get the BASE order of the comments (if any) and use those
// as the starting point for an up to date order.
const comments = parsedComments.map((c) => {
// Look up the base comment
let comment = storylineMoteBase?.data.wip?.notes?.[c.id];
if (!comment) {
comment = storylineMoteWorking?.data.wip?.notes?.[c.id];
// @ts-expect-error - order is a required field, but it'll be re-added
delete comment?.order;
}
assert(comment, `Comment ${c.id} not found in base or working mote`);
return { ...comment, id: c.id };
});
trace('Updating comment order');
updateBsArrayOrder(comments);
comments.forEach((comment) => {
trace(`Updating comment ${comment.id} order to ${comment.order}`);
updateMote(`data/wip/notes/${comment.id}/order`, comment.order);
});
//#endregion
updateMote('data/unlocked_description/text', parsed.unlockedDescription);
updateWipChangesFromParsed(parsed, moteId, packed, trace);
trace(`Writing changes`);

@@ -251,0 +103,0 @@ await packed.writeChanges();

@@ -1,3 +0,3 @@

export type StorylineMoteDataPointer = `data/${StorylineMotePointer}`;
export type StorylineMotePointer = `` | `description/description` | `description/skip` | `description/text` | `description` | `icon` | `name/description` | `name/skip` | `name/text` | `name` | `order` | `wip/notes/${string}/element/author` | `wip/notes/${string}/element/text` | `wip/notes/${string}/element/timestamp` | `wip/notes/${string}/element` | `wip/notes/${string}/order` | `wip/notes/${string}` | `wip/notes` | `wip/staging` | `wip`;
export type ComfortMoteDataPointer = `data/${ComfortMotePointer}`;
export type ComfortMotePointer = `` | `artisan_id` | `description/description` | `description/skip` | `description/text` | `description` | `ignore_in_progression_map` | `name/description` | `name/skip` | `name/text` | `name` | `order` | `priors/${string}/element` | `priors/${string}/order` | `priors/${string}` | `priors` | `uicon` | `unlocked_by` | `unlocked_description/description` | `unlocked_description/skip` | `unlocked_description/text` | `unlocked_description` | `wip/notes/${string}/element/author` | `wip/notes/${string}/element/text` | `wip/notes/${string}/element/timestamp` | `wip/notes/${string}/element` | `wip/notes/${string}/order` | `wip/notes/${string}` | `wip/notes` | `wip/staging` | `wip`;
//# sourceMappingURL=cl2.comfort.pointers.d.ts.map

@@ -0,4 +1,4 @@

import { ComfortMote } from './cl2.shared.types.js';
import type { GameChanger } from './GameChanger.js';
import { type StorylineMote } from './cl2.storyline.types.js';
export declare function stringifyStoryline(mote: StorylineMote, packed: GameChanger): string;
export declare function stringifyComfort(mote: ComfortMote, packed: GameChanger): string;
//# sourceMappingURL=cl2.comfort.stringify.d.ts.map
import { bsArrayToArray, toArrayTag } from './helpers.js';
export function stringifyStoryline(mote, packed) {
import { cleanGameChangerString } from './util.js';
export function stringifyComfort(mote, packed) {
// METADATA
const blocks = [
`Name: ${packed.working.getMoteName(mote)}`,
`Description: ${mote.data.description?.text || ''}\n`,
`Name: ${cleanGameChangerString(packed.working.getMoteName(mote))}`,
`Description: ${cleanGameChangerString(mote.data.description?.text)}\n`,
`Unlocked Description: ${cleanGameChangerString(mote.data.unlocked_description?.text)}\n`,
];

@@ -8,0 +10,0 @@ if (mote.data.wip?.staging) {

import type { Gcdata } from './GameChanger.js';
import type { ParsedLine } from './cl2.shared.types.js';
import type { Crashlands2 } from './cl2.types.auto.js';
import type { ParsedBase, ParserResult } from './cl2.types.editor.js';
import type { Position, Range } from './types.editor.js';
import type { BschemaRoot, Mote } from './types.js';
export declare const comfortSchemaId = "cl2_artisan_glads";
export type ComfortData = Crashlands2.Schemas['cl2_artisan_glads'];
export type ComfortMote = Mote<ComfortData>;
type CompletionsData = {
type: 'glossary';
options: string[];
} | {
type: 'stages';
options: string[];
} | {
type: 'labels';
options: Set<string>;
};
export interface StorylineUpdateResult extends ParserResult {
parsed: ParsedBase & {
description?: string;
};
completions: (Range & CompletionsData)[];
import { ComfortMote, ParserResult } from './cl2.shared.types.js';
import type { BschemaRoot } from './types.js';
export interface ComfortUpdateResult extends ParserResult<{
description?: string;
unlockedDescription?: string;
}> {
}

@@ -29,9 +12,4 @@ export declare function listComforts(gcData: Gcdata): ComfortMote[];

export declare function getComfortMote(gcData: Gcdata, moteId: string): ComfortMote | undefined;
export declare function getComfortMotes(gcData: Gcdata): ComfortMote[];
export declare function getComfortSchema(gcData: Gcdata): BschemaRoot | undefined;
export declare const arrayTagPattern = "(?:#(?<arrayTag>[a-z0-9]+))";
export declare const linePatterns: string[];
export declare function parseIfMatch(pattern: string, line: string, startPosition: Position): ParsedLine | null;
export declare function lineIsArrayItem(line: string): boolean;
export {};
//# sourceMappingURL=cl2.comfort.types.d.ts.map

@@ -1,4 +0,3 @@

import { z } from 'zod';
import { assert } from './assert.js';
export const comfortSchemaId = 'cl2_artisan_glads';
import { arrayTagPattern, comfortSchemaId, } from './cl2.shared.types.js';
export function listComforts(gcData) {

@@ -12,77 +11,14 @@ return gcData.listMotesBySchema(comfortSchemaId);

const mote = gcData.getMote(moteId);
assert(!mote || isComfortMote(mote), `Mote ${moteId} is not a comfort`);
assert(!mote || isComfortMote(mote), `Mote ${moteId} is not a storyline`);
return mote;
}
export function getComfortMotes(gcData) {
const motes = gcData.listMotesBySchema(comfortSchemaId);
return motes;
}
export function getComfortSchema(gcData) {
return gcData.getSchema(comfortSchemaId);
}
// PATTERNS
// Note: These patterns are defined so that they'll work on partial lines
// as much as possible, so their group names should always be checked for existence.
const linePartsSchema = z.object({
indicator: z
.string()
.optional()
.describe('The symbol prefixing the line to indicate what the line type is'),
arrayTag: z
.string()
.regex(/^[a-z0-9]+$/)
.optional()
.describe("BsArrayElement identifier (without the '#' prefix)"),
labelGroup: z.string().optional().describe('The label, including the `:`'),
label: z.string().optional().describe('For `Label:Value` elements'),
text: z
.string()
.optional()
.describe('For dialog and similar, the text content'),
});
export const arrayTagPattern = '(?:#(?<arrayTag>[a-z0-9]+))';
export const linePatterns = [
/** Label:Text */
`^(?<labelGroup>(?<label>Name|Description|Stage)\\s*:)\\s*(?<text>.*?)\\s*$`,
`^(?<labelGroup>(?<label>Name|Description|Unlocked Description|Stage)\\s*:)\\s*(?<text>.*?)\\s*$`,
/** Comment Line */
`^(?<indicator>//)\\s*?${arrayTagPattern}?\\s*(?<text>.*?)\\s*$`,
];
export function parseIfMatch(pattern, line, startPosition) {
const rawMatch = line.match(new RegExp(pattern));
if (!rawMatch)
return null;
const parsedLine = linePartsSchema.parse(rawMatch.groups);
const result = {
_: {
start: startPosition,
end: { ...startPosition },
value: line,
},
};
result._.end.character += line.length;
result._.end.index += line.length;
for (const [key, value] of Object.entries(parsedLine)) {
if (typeof value !== 'undefined') {
// Figure out where this is in the matches so we
// can get the start and end positions.
const startChar = line.indexOf(`${value}`);
const endChar = startChar + `${value}`.length;
const start = { ...startPosition };
start.character += startChar;
start.index += startChar;
const end = { ...startPosition };
end.character += endChar;
end.index += endChar;
result[key] = {
start,
end,
value: value,
};
}
}
return result;
}
export function lineIsArrayItem(line) {
return /^\/\//.test(line);
}
//# sourceMappingURL=cl2.comfort.types.js.map
export { parseStringifiedQuest, updateChangesFromParsedQuest, } from './cl2.quest.parse.js';
export { stringifyQuest } from './cl2.quest.stringify.js';
export { isQuestMote, listQuests, questSchemaId, type QuestData, type QuestMote, type QuestUpdateResult, } from './cl2.quest.types.js';
export { isQuestMote, listQuests, type QuestUpdateResult, } from './cl2.quest.types.js';
//# sourceMappingURL=cl2.quest.d.ts.map
export { parseStringifiedQuest, updateChangesFromParsedQuest, } from './cl2.quest.parse.js';
export { stringifyQuest } from './cl2.quest.stringify.js';
export { isQuestMote, listQuests, questSchemaId, } from './cl2.quest.types.js';
export { isQuestMote, listQuests, } from './cl2.quest.types.js';
//# sourceMappingURL=cl2.quest.js.map

@@ -1,2 +0,2 @@

import { GameChanger } from './GameChanger.js';
import type { GameChanger } from './GameChanger.js';
import { QuestUpdateResult } from './cl2.quest.types.js';

@@ -3,0 +3,0 @@ export declare function parseStringifiedQuest(text: string, packed: GameChanger, options?: {

import { assert } from './assert.js';
import { linePatterns, } from './cl2.quest.types.js';
import { getMomentStyleNames, getMoteLists, getRequirementQuestStatuses, getRequirementStyleNames, getStagingOptions, isEmoteMoment, } from './cl2.quest.utils.js';
import { arrayTagPattern, lineIsArrayItem, parseIfMatch, } from './cl2.shared.types.js';
import { bsArrayToArray, changedPosition, createBsArrayKey, updateBsArrayOrder, } from './helpers.js';
import { checkWords, includes } from './util.js';
import { getMomentStyleNames, getMoteLists, getRequirementQuestStatuses, getRequirementStyleNames, isEmoteMoment, } from './cl2.quest.utils.js';
import { isCommentLine, isStageLine, prepareParserHelpers, updateWipChangesFromParsed, } from './cl2.shared.parse.js';
import { bsArrayToArray, changedPosition, updateBsArrayOrder, } from './helpers.js';
export function parseStringifiedQuest(text, packed, options = {}) {

@@ -15,3 +14,2 @@ const motes = getMoteLists(packed.working);

const requirementStyles = getRequirementStyleNames(packed.working);
const stagingOptions = getStagingOptions(packed.working);
const requirementQuestStatuses = getRequirementQuestStatuses(packed.working);

@@ -21,22 +19,2 @@ const requirementCompletions = [...requirementStyles];

requirementCompletions.push(...requirementQuestStatuses.map((s) => `Quest ${s}`));
/**
* Shared list of keywords that can be used at the start of any line,
* with required-unique entries removed when found.
*/
const nonUniqueGlobalLabels = new Set(['Clue']);
const availableGlobalLabels = new Set([
'Stage',
'Name',
'Storyline',
'Giver',
'Receiver',
'Clue',
'Start Requirements',
'Start Moments',
'End Requirements',
'End Moments',
'Log',
]);
/** Terms from the glossary for use in autocompletes */
const glossaryTerms = (packed.glossary?.relevantTerms() || []).map((t) => t.text);
const result = {

@@ -57,18 +35,19 @@ diagnostics: [],

};
const lines = text.split(/(\r?\n)/g);
let index = 0;
let lineNumber = 0;
const emojiIdFromName = (name) => {
if (!name) {
return undefined;
}
const emoji = motes.emojis.find((e) => packed.working.getMoteName(e)?.toLowerCase() ===
name?.trim().toLowerCase() || e.id === name?.trim());
return emoji?.id;
};
const checkSpelling = (item) => {
if (!item || !options.checkSpelling || !packed.glossary)
return;
result.words.push(...checkWords(item, packed.glossary));
};
const helpers = prepareParserHelpers(text, packed, {
...options,
globalNonUniqueLabels: new Set(['Clue']),
globalLabels: new Set([
'Stage',
'Name',
'Storyline',
'Giver',
'Receiver',
'Clue',
'Start Requirements',
'Start Moments',
'End Requirements',
'End Moments',
'Log',
]),
}, result);
/** The MoteId for the last speaker we saw. Used to figure out who to assign stuff to */

@@ -79,33 +58,13 @@ let lastSpeaker;

let lastEmojiGroup;
for (const line of lines) {
for (const line of helpers.lines) {
const trace = [];
try {
// Is this just a newline?
if (line.match(/\r?\n/)) {
// Then we just need to increment the index
index += line.length;
lineNumber++;
continue;
}
const lineRange = {
start: {
index,
line: lineNumber,
character: 0,
},
end: {
index: index + line.length,
line: lineNumber,
character: line.length,
},
};
const lineRange = helpers.currentLineRange;
// Is this just a blank line?
if (!line) {
// Add global autocompletes
result.completions.push({
type: 'labels',
const pos = {
start: lineRange.start,
end: lineRange.end,
options: availableGlobalLabels,
});
};
if (isQuestMomentLabel(lastSectionGroup)) {

@@ -115,4 +74,3 @@ result.completions.push({

options: momentStyles,
start: lineRange.start,
end: lineRange.end,
...pos,
});

@@ -124,4 +82,3 @@ }

options: requirementCompletions,
start: lineRange.start,
end: lineRange.end,
...pos,
});

@@ -132,61 +89,5 @@ }

// Find the first matching pattern and pull the values from it.
let parsedLine = null;
for (const pattern of linePatterns) {
parsedLine = parseIfMatch(pattern, line, lineRange.start);
if (parsedLine)
break;
}
if (!parsedLine) {
// Then this is likely the result of uncommenting something
// that was commented out, resulting in a line that starts with
// the comment's array tag. Provide a deletion edit!
parsedLine = parseIfMatch(`^${arrayTagPattern} +(?<text>.*)$`, line, lineRange.start);
if (parsedLine) {
result.edits.push({
start: lineRange.start,
end: lineRange.end,
newText: parsedLine.text.value,
});
}
else {
result.diagnostics.push({
message: `Unfamiliar syntax: ${line}`,
...lineRange,
});
}
index += line.length;
const parsedLine = helpers.parseCurrentLine(linePatterns);
if (!parsedLine)
continue;
}
// Ensure the array tag. It goes right after the label or indicator.
if (!parsedLine.arrayTag?.value && lineIsArrayItem(line)) {
const arrayTag = createBsArrayKey();
const start = parsedLine.indicator?.end || parsedLine.label?.end;
result.edits.push({
start,
end: start,
newText: `#${arrayTag}`,
});
parsedLine.arrayTag = {
start,
end: start,
value: arrayTag,
};
}
// If this has a label, remove it from the list of available labels
if (parsedLine.label?.value &&
availableGlobalLabels.has(parsedLine.label.value) &&
!nonUniqueGlobalLabels.has(parsedLine.label.value)) {
availableGlobalLabels.delete(parsedLine.label.value);
}
// If this has a text section, provide glossary autocompletes
if ('text' in parsedLine) {
const start = parsedLine.text.start;
const end = parsedLine.text.end;
result.completions.push({
type: 'glossary',
start,
end,
options: glossaryTerms,
});
}
// Track common problems so that we don't need to repeat logic

@@ -245,3 +146,3 @@ /** The character where a mote should exist. */

// Then this is a dialog line, either within a Clue or a Dialog Moment
const emoji = emojiIdFromName(parsedLine.emojiName?.value);
const emoji = helpers.emojiIdFromName(parsedLine.emojiName?.value);
if (parsedLine.emojiGroup) {

@@ -252,6 +153,6 @@ // Emojis are optional. If we see a "group" (parentheses) then

at: changedPosition(parsedLine.emojiGroup.start, { characters: 1 }),
options: motes.emojis,
options: helpers.emojis,
};
}
checkSpelling(parsedLine.text);
helpers.checkSpelling(parsedLine.text);
const moment = {

@@ -287,24 +188,8 @@ kind: 'dialogue',

}
else if (labelLower === 'stage') {
const stage = parsedLine.text?.value?.trim();
if (includes(stagingOptions, stage)) {
result.parsed.stage = stage;
}
else {
result.diagnostics.push({
message: `Stage must be one of: ${stagingOptions.join(', ')}`,
...lineRange,
});
// Provide autocomplete options
result.completions.push({
type: 'stages',
options: stagingOptions,
start: parsedLine.labelGroup.end,
end: lineRange.end,
});
}
else if (isStageLine(parsedLine)) {
helpers.addStage(parsedLine);
}
else if (labelLower === 'log') {
result.parsed.quest_start_log = parsedLine.text?.value?.trim();
checkSpelling(parsedLine.text);
helpers.checkSpelling(parsedLine.text);
}

@@ -372,3 +257,3 @@ else if (labelLower === 'storyline') {

}),
options: motes.emojis,
options: helpers.emojis,
};

@@ -385,3 +270,3 @@ }

speaker: parsedLine.moteTag?.value?.trim(),
emoji: emojiIdFromName(parsedLine.emojiName?.value),
emoji: helpers.emojiIdFromName(parsedLine.emojiName?.value),
});

@@ -504,9 +389,4 @@ }

}
else if (indicator === '//') {
// Then this is a comment/note
result.parsed.comments.push({
id: parsedLine.arrayTag?.value?.trim(),
text: parsedLine.text?.value?.trim(),
});
checkSpelling(parsedLine.text);
else if (isCommentLine(parsedLine)) {
helpers.addComment(parsedLine);
}

@@ -525,3 +405,3 @@ if (requiresEmoji) {

}
else if (!emojiIdFromName(parsedLine.emojiName?.value)) {
else if (!helpers.emojiIdFromName(parsedLine.emojiName?.value)) {
result.diagnostics.push({

@@ -565,3 +445,3 @@ message: `Emoji "${parsedLine.emojiName?.value}" not found!`,

}
index += line.length;
helpers.index += line.length;
}

@@ -603,44 +483,4 @@ return result;

updateMote('data/storyline', parsed.storyline);
if (parsed.stage) {
updateMote('data/wip/staging', parsed.stage);
}
else if (questMoteWorking?.data.wip) {
updateMote('data/wip/staging', null);
}
const parsedComments = parsed.comments.filter((c) => !!c.text);
updateWipChangesFromParsed(parsed, moteId, packed, trace);
const parsedClues = parsed.clues.filter((c) => !!c.id && !!c.speaker);
//#region COMMENTS
// Add/Update COMMENTS
trace(`Updating comments`);
for (const comment of parsedComments) {
trace(`Updating comment ${comment.id} with text "${comment.text}"`);
updateMote(`data/wip/notes/${comment.id}/element/text`, comment.text);
}
// Remove deleted comments
for (const existingComment of bsArrayToArray(questMoteBase?.data.wip?.notes || {})) {
if (!parsedComments.find((c) => c.id === existingComment.id)) {
trace(`Deleting comment ${existingComment.id}`);
updateMote(`data/wip/notes/${existingComment.id}`, null);
}
}
// Get the BASE order of the comments (if any) and use those
// as the starting point for an up to date order.
const comments = parsedComments.map((c) => {
// Look up the base comment
let comment = questMoteBase?.data.wip?.notes?.[c.id];
if (!comment) {
comment = questMoteWorking?.data.wip?.notes?.[c.id];
// @ts-expect-error - order is a required field, but it'll be re-added
delete comment?.order;
}
assert(comment, `Comment ${c.id} not found in base or working mote`);
return { ...comment, id: c.id };
});
trace('Updating comment order');
updateBsArrayOrder(comments);
comments.forEach((comment) => {
trace(`Updating comment ${comment.id} order to ${comment.order}`);
updateMote(`data/wip/notes/${comment.id}/order`, comment.order);
});
//#endregion
//#region CLUES

@@ -647,0 +487,0 @@ // Add/update clues

import type { Gcdata } from './GameChanger.js';
import { CompletionsData } from './cl2.shared.types.js';
import { ParserResult, QuestMote } from './cl2.shared.types.js';
import type { Crashlands2 } from './cl2.types.auto.js';
import { ParsedComment, ParserResult } from './cl2.types.editor.js';
import type { Range } from './types.editor.js';
import type { Mote } from './types.js';
export declare const questSchemaId = "cl2_quest";
export type QuestData = Crashlands2.Schemas['cl2_quest'];
export type QuestMote = Mote<QuestData>;
export declare function listQuests(gcData: Gcdata): QuestMote[];

@@ -70,21 +65,16 @@ export declare function isQuestMote(mote: any): mote is Mote<Crashlands2.Quest>;

export type QuestRequirementsLabel = `quest_${'start' | 'end'}_requirements`;
export interface QuestUpdateResult extends ParserResult {
completions: (Range & CompletionsData)[];
parsed: {
name?: string;
/** The moteId for the storyline */
storyline?: string;
/** The moteId for the quest giver */
quest_giver?: string;
/** The moteId for the quest receiver */
quest_receiver?: string;
clues: ParsedClue[];
quest_start_log?: string;
stage?: Crashlands2.Staging;
comments: ParsedComment[];
} & {
[K in QuestMomentsLabel]: ParsedMoment[];
} & {
[K in QuestRequirementsLabel]: ParsedRequirement[];
};
export interface QuestUpdateResult extends ParserResult<{
/** The moteId for the storyline */
storyline?: string;
/** The moteId for the quest giver */
quest_giver?: string;
/** The moteId for the quest receiver */
quest_receiver?: string;
clues: ParsedClue[];
quest_start_log?: string;
} & {
[K in QuestMomentsLabel]: ParsedMoment[];
} & {
[K in QuestRequirementsLabel]: ParsedRequirement[];
}> {
}

@@ -91,0 +81,0 @@ export type Section = (typeof sections)[number];

@@ -1,3 +0,2 @@

import { arrayTagPattern } from './cl2.shared.types.js';
export const questSchemaId = 'cl2_quest';
import { arrayTagPattern, questSchemaId, } from './cl2.shared.types.js';
export function listQuests(gcData) {

@@ -4,0 +3,0 @@ return gcData.listMotesBySchema(questSchemaId);

@@ -8,5 +8,3 @@ import type { Gcdata } from './GameChanger.js';

quests: import("./types.js").Mote<Crashlands2.Quest, string>[];
emojis: import("./types.js").Mote<Crashlands2.Emoji11, string>[];
};
export declare function getStagingOptions(packed: Gcdata): Crashlands2.Staging[];
export declare function getRequirementQuestStatuses(packed: Gcdata): string[];

@@ -13,0 +11,0 @@ export declare function getRequirementStyleNames(packed: Gcdata): string[];

@@ -12,4 +12,2 @@ import { assert } from './assert.js';

assert(quests.length > 0, 'Should have at least one quest mote');
const emojis = packed.listMotesBySchema('cl2_emoji');
assert(emojis.length > 0, 'Should have at least one emoji mote');
return {

@@ -20,16 +18,4 @@ allowedSpeakers,

quests,
emojis,
};
}
export function getStagingOptions(packed) {
const stagingSubchema = resolvePointerInSchema(['wip', 'staging'], {
schema_id: 'cl2_quest',
data: {
wip: {
staging: 'any',
},
},
}, packed);
return stagingSubchema.enum;
}
function getAllowedSpeakers(packed) {

@@ -36,0 +22,0 @@ const speakerSubchema = resolvePointerInSchema(['quest_start_moments', 'anykey', 'element', 'speech', 'speaker'], {

import { z } from 'zod';
import type { Crashlands2 } from './cl2.types.auto.js';
import type { Position } from './types.editor.js';
import type { Gcdata } from './GameChanger.js';
import type { ParsedLineItem, ParsedWord, Position, Range } from './types.editor.js';
import type { Mote } from './types.js';
export declare const questSchemaId = "cl2_quest";
export type QuestData = Crashlands2.Schemas['cl2_quest'];
export type QuestMote = Mote<QuestData>;
export declare const chatSchemaId = "cl2_chat";
export type ChatData = Crashlands2.Schemas['cl2_chat'];
export type ChatMote = Mote<ChatData>;
export declare const buddySchemaId = "artisan";
export type BuddyData = Crashlands2.Schemas['artisan'];
export type BuddyMote = Mote<BuddyData>;
export declare const npcSchemaId = "cl2_npc";
export type NpcData = Crashlands2.Schemas['cl2_npc'];
export type NpcMote = Mote<NpcData>;
export declare const comfortSchemaId = "cl2_artisan_glads";
export type ComfortData = Crashlands2.Schemas['cl2_artisan_glads'];
export type ComfortMote = Mote<ComfortData>;
export declare const storylineSchemaId = "cl2_storyline";
export type StorylineData = Crashlands2.Schemas['cl2_storyline'];
export type StorylineMote = Mote<StorylineData>;
export interface ParsedComment {
/** arrayId */
id: string | undefined;
text: string | undefined;
}
export interface ParsedBase {
name?: string;
stage?: Crashlands2.Staging;
comments: ParsedComment[];
}
export interface ParserResult<P extends Record<string, any>> {
diagnostics: (Range & {
message: string;
})[];
hovers: (Range & {
title?: string;
description?: string;
})[];
edits: (Range & {
newText: string;
})[];
completions: (Range & CompletionsData)[];
words: ParsedWord[];
parsed: ParsedBase & P;
}
export type CompletionsData = {

@@ -27,7 +71,2 @@ type: 'motes';

};
export interface ParsedLineItem<V = string> {
start: Position;
end: Position;
value: V;
}
export type ParsedLine = {

@@ -58,5 +97,2 @@ [K in keyof LineParts]?: ParsedLineItem<LineParts[K]>;

}, "strip", z.ZodTypeAny, {
status?: string | undefined;
text?: string | undefined;
style?: string | undefined;
indicator?: string | undefined;

@@ -71,6 +107,6 @@ arrayTag?: string | undefined;

sep?: string | undefined;
}, {
status?: string | undefined;
text?: string | undefined;
style?: string | undefined;
status?: string | undefined;
}, {
indicator?: string | undefined;

@@ -85,5 +121,10 @@ arrayTag?: string | undefined;

sep?: string | undefined;
text?: string | undefined;
style?: string | undefined;
status?: string | undefined;
}>;
export declare function parseIfMatch(pattern: string, line: string, startPosition: Position): ParsedLine | null;
export declare function lineIsArrayItem(line: string): boolean;
export declare function getStagingOptions(packed: Gcdata): Crashlands2.Staging[];
export declare function getEmojis(packed: Gcdata): Mote<Crashlands2.Schemas['cl2_emoji']>[];
//# sourceMappingURL=cl2.shared.types.d.ts.map
import { z } from 'zod';
import { assert } from './assert.js';
import { resolvePointerInSchema } from './util.js';
export const questSchemaId = 'cl2_quest';
export const chatSchemaId = 'cl2_chat';
export const buddySchemaId = 'artisan';
export const npcSchemaId = 'cl2_npc';
export const comfortSchemaId = 'cl2_artisan_glads';
export const storylineSchemaId = 'cl2_storyline';
export const arrayTagPattern = '(?:#(?<arrayTag>[a-z0-9]+))';

@@ -79,3 +87,3 @@ export const linePartsSchema = z.object({

export function lineIsArrayItem(line) {
if (line.match(/^(\t|name|stage|storyline|(start|end) (moments|requirements)|log|giver|receiver|description)/i)) {
if (line.match(/^(\t|name|stage|storyline|(start|end) (moments|requirements)|log|giver|receiver|description|unlocked description)/i)) {
return false;

@@ -85,2 +93,18 @@ }

}
export function getStagingOptions(packed) {
const stagingSubchema = resolvePointerInSchema(['wip', 'staging'], {
schema_id: 'cl2_quest',
data: {
wip: {
staging: 'any',
},
},
}, packed);
return stagingSubchema.enum;
}
export function getEmojis(packed) {
const emojis = packed.listMotesBySchema('cl2_emoji');
assert(emojis.length > 0, 'Should have at least one emoji mote');
return emojis;
}
//# sourceMappingURL=cl2.shared.types.js.map
export { parseStringifiedStoryline, updateChangesFromParsedStoryline, } from './cl2.storyline.parse.js';
export { stringifyStoryline } from './cl2.storyline.stringify.js';
export { isStorylineMote, listStorylines, storylineSchemaId, type StorylineData, type StorylineMote, type StorylineUpdateResult, } from './cl2.storyline.types.js';
export { isStorylineMote, listStorylines, type StorylineUpdateResult, } from './cl2.storyline.types.js';
//# sourceMappingURL=cl2.storyline.d.ts.map
export { parseStringifiedStoryline, updateChangesFromParsedStoryline, } from './cl2.storyline.parse.js';
export { stringifyStoryline } from './cl2.storyline.stringify.js';
export { isStorylineMote, listStorylines, storylineSchemaId, } from './cl2.storyline.types.js';
export { isStorylineMote, listStorylines, } from './cl2.storyline.types.js';
//# sourceMappingURL=cl2.storyline.js.map
import { assert } from './assert.js';
import { getStagingOptions } from './cl2.quest.utils.js';
import { arrayTagPattern, lineIsArrayItem, parseIfMatch, } from './cl2.shared.types.js';
import { getStorylineMote, getStorylineSchema, linePatterns, storylineSchemaId, } from './cl2.storyline.types.js';
import { bsArrayToArray, createBsArrayKey, updateBsArrayOrder, } from './helpers.js';
import { checkWords, includes } from './util.js';
import { isCommentLine, isStageLine, prepareParserHelpers, updateWipChangesFromParsed, } from './cl2.shared.parse.js';
import { storylineSchemaId } from './cl2.shared.types.js';
import { getStorylineSchema, linePatterns, } from './cl2.storyline.types.js';
export function parseStringifiedStoryline(text, packed, options = {}) {

@@ -18,120 +16,21 @@ const result = {

};
const availableGlobalLabels = new Set([
'Name',
'Description',
'Stage',
]);
const stagingOptions = getStagingOptions(packed.working);
/** Terms from the glossary for use in autocompletes */
const glossaryTerms = (packed.glossary?.relevantTerms() || []).map((t) => t.text);
const checkSpelling = (item) => {
if (!item || !options.checkSpelling)
return;
result.words.push(...checkWords(item, packed.glossary));
};
const lines = text.split(/(\r?\n)/g);
let index = 0;
let lineNumber = 0;
for (const line of lines) {
const helpers = prepareParserHelpers(text, packed, {
...options,
globalLabels: new Set(['Name', 'Description', 'Stage']),
}, result);
for (const line of helpers.lines) {
const trace = [];
try {
// Is this just a newline?
if (line.match(/\r?\n/)) {
// Then we just need to increment the index
index += line.length;
lineNumber++;
continue;
}
const lineRange = {
start: {
index,
line: lineNumber,
character: 0,
},
end: {
index: index + line.length,
line: lineNumber,
character: line.length,
},
};
// Is this just a blank line?
if (!line) {
// Add global autocompletes
result.completions.push({
type: 'labels',
start: lineRange.start,
end: lineRange.end,
options: availableGlobalLabels,
});
continue;
}
const lineRange = helpers.currentLineRange;
// Find the first matching pattern and pull the values from it.
let parsedLine = null;
for (const pattern of linePatterns) {
parsedLine = parseIfMatch(pattern, line, lineRange.start);
if (parsedLine)
break;
}
if (!parsedLine) {
// Then this is likely the result of uncommenting something
// that was commented out, resulting in a line that starts with
// the comment's array tag. Provide a deletion edit!
parsedLine = parseIfMatch(`^${arrayTagPattern} +(?<text>.*)$`, line, lineRange.start);
if (parsedLine) {
result.edits.push({
start: lineRange.start,
end: lineRange.end,
newText: parsedLine.text.value,
});
}
else {
result.diagnostics.push({
message: `Unfamiliar syntax: ${line}`,
...lineRange,
});
}
index += line.length;
const parsedLine = helpers.parseCurrentLine(linePatterns);
if (!parsedLine)
continue;
}
// Ensure the array tag. It goes right after the label or indicator.
if (!parsedLine.arrayTag?.value && lineIsArrayItem(line)) {
const arrayTag = createBsArrayKey();
const start = parsedLine.indicator?.end || parsedLine.label?.end;
result.edits.push({
start,
end: start,
newText: `#${arrayTag}`,
});
parsedLine.arrayTag = {
start,
end: start,
value: arrayTag,
};
}
// If this has a label, remove it from the list of available labels
if (parsedLine.label?.value &&
availableGlobalLabels.has(parsedLine.label.value)) {
availableGlobalLabels.delete(parsedLine.label.value);
}
// If this has a text section, provide glossary autocompletes
if ('text' in parsedLine) {
const start = parsedLine.text.start;
const end = parsedLine.text.end;
result.completions.push({
type: 'glossary',
start,
end,
options: glossaryTerms,
});
}
// Work through each line type to add diagnostics and completions
const labelLower = parsedLine.label?.value?.toLowerCase();
const indicator = parsedLine.indicator?.value;
if (indicator === '//') {
// Then this is a comment/note
result.parsed.comments.push({
id: parsedLine.arrayTag?.value?.trim(),
text: parsedLine.text?.value?.trim(),
});
checkSpelling(parsedLine.text);
if (isCommentLine(parsedLine)) {
helpers.addComment(parsedLine);
}

@@ -149,22 +48,6 @@ else if (labelLower === 'name') {

result.parsed.description = parsedLine.text?.value?.trim();
checkSpelling(parsedLine.text);
helpers.checkSpelling(parsedLine.text);
}
else if (labelLower === 'stage') {
const stage = parsedLine.text?.value?.trim();
if (includes(stagingOptions, stage)) {
result.parsed.stage = stage;
}
else {
result.diagnostics.push({
message: `Stage must be one of: ${stagingOptions.join(', ')}`,
...lineRange,
});
// Provide autocomplete options
result.completions.push({
type: 'stages',
options: stagingOptions,
start: parsedLine.labelGroup.end,
end: lineRange.end,
});
}
else if (isStageLine(parsedLine)) {
helpers.addStage(parsedLine);
}

@@ -185,3 +68,3 @@ else {

}
index += line.length;
helpers.index += line.length;
}

@@ -198,4 +81,2 @@ return result;

packed.clearMoteChanges(moteId);
const storylineMoteBase = getStorylineMote(packed.base, moteId);
const storylineMoteWorking = getStorylineMote(packed.working, moteId);
const schema = getStorylineSchema(packed.working);

@@ -209,43 +90,3 @@ assert(schema, `${storylineSchemaId} schema not found in working copy`);

updateMote('data/description/text', parsed.description);
if (parsed.stage) {
updateMote('data/wip/staging', parsed.stage);
}
else if (storylineMoteWorking?.data.wip) {
updateMote('data/wip/staging', null);
}
const parsedComments = parsed.comments.filter((c) => !!c.text);
//#region COMMENTS
// Add/Update COMMENTS
trace(`Updating comments`);
for (const comment of parsedComments) {
trace(`Updating comment ${comment.id} with text "${comment.text}"`);
updateMote(`data/wip/notes/${comment.id}/element/text`, comment.text);
}
// Remove deleted comments
for (const existingComment of bsArrayToArray(storylineMoteBase?.data.wip?.notes || {})) {
if (!parsedComments.find((c) => c.id === existingComment.id)) {
trace(`Deleting comment ${existingComment.id}`);
updateMote(`data/wip/notes/${existingComment.id}`, null);
}
}
// Get the BASE order of the comments (if any) and use those
// as the starting point for an up to date order.
const comments = parsedComments.map((c) => {
// Look up the base comment
let comment = storylineMoteBase?.data.wip?.notes?.[c.id];
if (!comment) {
comment = storylineMoteWorking?.data.wip?.notes?.[c.id];
// @ts-expect-error - order is a required field, but it'll be re-added
delete comment?.order;
}
assert(comment, `Comment ${c.id} not found in base or working mote`);
return { ...comment, id: c.id };
});
trace('Updating comment order');
updateBsArrayOrder(comments);
comments.forEach((comment) => {
trace(`Updating comment ${comment.id} order to ${comment.order}`);
updateMote(`data/wip/notes/${comment.id}/order`, comment.order);
});
//#endregion
updateWipChangesFromParsed(parsed, moteId, packed, trace);
trace(`Writing changes`);

@@ -252,0 +93,0 @@ await packed.writeChanges();

@@ -0,4 +1,4 @@

import { StorylineMote } from './cl2.shared.types.js';
import type { GameChanger } from './GameChanger.js';
import { type StorylineMote } from './cl2.storyline.types.js';
export declare function stringifyStoryline(mote: StorylineMote, packed: GameChanger): string;
//# sourceMappingURL=cl2.storyline.stringify.d.ts.map
import type { Gcdata } from './GameChanger.js';
import type { Crashlands2 } from './cl2.types.auto.js';
import type { ParsedBase, ParserResult } from './cl2.types.editor.js';
import type { Range } from './types.editor.js';
import type { BschemaRoot, Mote } from './types.js';
export declare const storylineSchemaId = "cl2_storyline";
export type StorylineData = Crashlands2.Schemas['cl2_storyline'];
export type StorylineMote = Mote<StorylineData>;
type CompletionsData = {
type: 'glossary';
options: string[];
} | {
type: 'stages';
options: string[];
} | {
type: 'labels';
options: Set<string>;
};
export interface StorylineUpdateResult extends ParserResult {
parsed: ParsedBase & {
description?: string;
};
completions: (Range & CompletionsData)[];
import { ParserResult, StorylineMote } from './cl2.shared.types.js';
import type { BschemaRoot } from './types.js';
export interface StorylineUpdateResult extends ParserResult<{
description?: string;
}> {
}

@@ -28,6 +11,4 @@ export declare function listStorylines(gcData: Gcdata): StorylineMote[];

export declare function getStorylineMote(gcData: Gcdata, moteId: string): StorylineMote | undefined;
export declare function getStorylineMotes(gcData: Gcdata): StorylineMote[];
export declare function getStorylineSchema(gcData: Gcdata): BschemaRoot | undefined;
export declare const linePatterns: string[];
export {};
//# sourceMappingURL=cl2.storyline.types.d.ts.map
import { assert } from './assert.js';
import { arrayTagPattern } from './cl2.shared.types.js';
export const storylineSchemaId = 'cl2_storyline';
import { arrayTagPattern, storylineSchemaId, } from './cl2.shared.types.js';
export function listStorylines(gcData) {

@@ -15,6 +14,2 @@ return gcData.listMotesBySchema(storylineSchemaId);

}
export function getStorylineMotes(gcData) {
const motes = gcData.listMotesBySchema(storylineSchemaId);
return motes;
}
export function getStorylineSchema(gcData) {

@@ -21,0 +16,0 @@ return gcData.getSchema(storylineSchemaId);

@@ -1,5 +0,7 @@

export * from './GameChanger.js';
export * from './cl2.comfort.js';
export * from './cl2.quest.js';
export * from './cl2.shared.types.js';
export * from './cl2.storyline.js';
export * from './cl2.types.auto.js';
export * from './GameChanger.js';
export * from './helpers.js';

@@ -6,0 +8,0 @@ export * from './types.cl2.rumpus.js';

@@ -1,5 +0,7 @@

export * from './GameChanger.js';
export * from './cl2.comfort.js';
export * from './cl2.quest.js';
export * from './cl2.shared.types.js';
export * from './cl2.storyline.js';
export * from './cl2.types.auto.js';
export * from './GameChanger.js';
export * from './helpers.js';

@@ -6,0 +8,0 @@ export * from './types.cl2.rumpus.js';

@@ -25,2 +25,12 @@ export interface Range {

}
export type ParsedWord = Range & {
value: string;
suggestions?: string[];
valid: boolean;
};
export interface ParsedLineItem<V = string> {
start: Position;
end: Position;
value: V;
}
//# sourceMappingURL=types.editor.d.ts.map
import type { Glossary } from '@bscotch/cl2-string-server-shared';
import type { Gcdata } from './GameChanger.js';
import { ParsedLineItem } from './cl2.shared.types.js';
import { ParsedWord } from './cl2.types.editor.js';
import type { ParsedLineItem, ParsedWord } from './types.editor.js';
import { type Bschema, type Mote } from './types.js';

@@ -47,2 +46,3 @@ export declare function sizeOf(thing: any): number;

export declare function includes<T>(arr: T[], value: any): value is T;
export declare function cleanGameChangerString(str: string | undefined): string;
//# sourceMappingURL=util.d.ts.map

@@ -312,2 +312,5 @@ import { assert } from './assert.js';

}
export function cleanGameChangerString(str) {
return (str || '').replace(/\r?\n/g, ' / ').trim();
}
//# sourceMappingURL=util.js.map
{
"name": "@bscotch/gcdata",
"version": "0.20.1",
"version": "0.21.0",
"license": "MIT",

@@ -5,0 +5,0 @@ "type": "module",

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc