Fixed a lot broken with nested sets

This commit is contained in:
ThaumRystra
2023-12-18 23:12:39 +02:00
parent a891f26b63
commit 4a349ea906
32 changed files with 435 additions and 284 deletions

View File

@@ -51,3 +51,4 @@ typescript@4.9.4
seba:minifiers-autoprefixer
mixmax:smart-disconnect
zodern:types
zodern:fix-async-stubs

View File

@@ -125,4 +125,5 @@ url@1.3.2
webapp@1.13.5
webapp-hashing@1.1.1
zer0th:meteor-vuetify-loader@0.1.41
zodern:fix-async-stubs@1.0.2
zodern:types@1.0.9

View File

@@ -162,6 +162,12 @@ for (const key in propertySchemasIndex) {
schema.extend(ColorSchema);
schema.extend(ChildSchema);
schema.extend(SoftRemovableSchema);
// Use the any schema as a default schema for the collection
if (key === 'any') {
// @ts-expect-error don't have types for .attachSchema
CreatureProperties.attachSchema(schema);
}
// TODO make this an else branch and remove all {selector: {type: any}} options
// @ts-expect-error don't have types for .attachSchema
CreatureProperties.attachSchema(schema, {
selector: { type: key }

View File

@@ -36,7 +36,7 @@ const equipItem = new ValidatedMethod({
let parentRef = getParentRefByTag(creature._id, tag);
if (!parentRef) parentRef = { id: creature._id, collection: 'creatures' };
organizeDoc.call({
organizeDoc.callAsync({
docRef: {
id: _id,
collection: 'creatureProperties',

View File

@@ -18,7 +18,7 @@ interface Ammo extends Item {
adjustment: number
}
export default function applyAction(node: TreeNode<Action>, actionContext) {
export default async function applyAction(node: TreeNode<Action>, actionContext) {
applyNodeTriggers(node, 'before', actionContext);
const prop = node.doc;
if (prop.target === 'self') actionContext.targets = [actionContext.creature];
@@ -198,7 +198,7 @@ function applyCrits(value, scope) {
return { criticalHit, criticalMiss };
}
function spendResources(prop: Action, actionContext) {
async function spendResources(prop: Action, actionContext) {
// Check Uses
if (!prop.usesLeft || prop.usesLeft <= 0) {
if (!prop.silent) actionContext.addLog({

View File

@@ -2,7 +2,7 @@ import recalculateInlineCalculations from './shared/recalculateInlineCalculation
import applyChildren from '/imports/api/engine/actions/applyPropertyByType/shared/applyChildren';
import { applyNodeTriggers } from '/imports/api/engine/actions/applyTriggers';
export default function applyNote(node, actionContext) {
export default async function applyNote(node, actionContext) {
applyNodeTriggers(node, 'before', actionContext);
const prop = node.doc

View File

@@ -6,7 +6,7 @@ import applyProperty from '/imports/api/engine/actions/applyProperty';
import { difference, intersection } from 'lodash';
import getEffectivePropTags from '/imports/api/engine/computation/utility/getEffectivePropTags';
export function applyNodeTriggers(node: TreeNode<any>, timing, actionContext) {
export async function applyNodeTriggers(node: TreeNode<any>, timing, actionContext) {
const prop = node.doc;
const type = prop.type;
const triggers = actionContext.triggers?.doActionProperty?.[type]?.[timing];

View File

@@ -1,4 +1,4 @@
import { docsToForest } from '/imports/api/parenting/parentingFunctions';
import { applyNestedSetProperties, calculateNestedSetOperations } from '/imports/api/parenting/parentingFunctions';
import { DenormalisedOnlyCreaturePropertySchema as denormSchema }
from '/imports/api/creature/creatureProperties/CreatureProperties';
import { getProperties, getCreature, getVariables } from '/imports/api/engine/loadCreatures';
@@ -85,8 +85,14 @@ export function buildComputationFromProps(properties, creature, variables) {
});
// Get all the properties as trees based on their ancestors
let forest = docsToForest(properties);
// Get all the properties as a forest, with their nested set properties set
const forest = applyNestedSetProperties(properties);
const ops = calculateNestedSetOperations(properties);
if (ops.length > 20) {
console.log(ops.length + ' operations to get fixed nested sets');
} else {
console.log(JSON.stringify(ops, null, 2));
}
// Walk the property trees computing things that need to be inherited
walkDown(forest, node => {
computeInactiveStatus(node);

View File

@@ -7,6 +7,7 @@ import propertySlot from './computeByType/computeSlot';
import container from './computeByType/computeContainer';
import spellList from './computeByType/computeSpellList';
import toggle from './computeByType/computeToggle';
import trigger from './computeByType/computeTrigger';
import _calculation from './computeByType/computeCalculation';
export default Object.freeze({

View File

@@ -23,6 +23,9 @@ export default function writeAlteredProperties(computation) {
'deactivatingToggleId',
'damage',
'dirty',
'left',
'right',
'parentId',
...schema.objectKeys(),
];
op = addChangedKeysToOp(op, keys, original, changed);

View File

@@ -56,6 +56,7 @@ export function getProperties(creatureId) {
const creature = loadedCreatures.get(creatureId);
if (creature) {
const props = Array.from(creature.properties.values());
props.sort((a, b) => a.left - b.left);
return EJSON.clone(props);
}
// console.time(`Cache miss on creature properties: ${creatureId}`)
@@ -78,6 +79,7 @@ export function getPropertiesOfType(creatureId, propType) {
props.push(prop);
}
}
props.sort((a, b) => a.left - b.left);
return EJSON.clone(props);
}
// console.time(`Cache miss on creature properties: ${creatureId}`)

View File

@@ -0,0 +1,118 @@
import SimpleSchema from 'simpl-schema';
import { ValidatedMethod } from 'meteor/mdg:validated-method';
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
import { RefSchema } from '/imports/api/parenting/ChildSchema';
import { assertDocEditPermission } from '/imports/api/sharing/sharingPermissions.js';
import Creatures from '/imports/api/creature/creatures/Creatures.js';
import { changeParent, fetchDocByRefAsync, getCollectionByName, rebuildNestedSets } from '/imports/api/parenting/parentingFunctions';
const organizeDoc = new ValidatedMethod({
name: 'organize.organizeDoc',
validate: new SimpleSchema({
docRef: RefSchema,
parentRef: RefSchema,
order: {
type: Number,
// Should end in 0.5 to place it reliably between two existing documents
},
skipRecompute: {
type: Boolean,
optional: true,
},
skipClient: {
type: Boolean,
optional: true,
},
}).validator(),
mixins: [RateLimiterMixin],
rateLimit: {
numRequests: 5,
timeInterval: 5000,
},
async run({ docRef, parentRef, order, skipRecompute, skipClient }) {
if (skipClient && this.isSimulation) {
return;
}
let doc = await fetchDocByRefAsync(docRef);
let collection = getCollectionByName(docRef.collection);
// The user must be able to edit both the doc and its parent to move it
// successfully
assertDocEditPermission(doc, this.userId);
let parent;
parent = await fetchDocByRefAsync(parentRef);
assertDocEditPermission(parent, this.userId);
// Moving the doc to the root level means changing its parent to undefined
if (doc.root.id === parent._id) {
parent = null;
}
// Change the doc's parent
await changeParent(doc, parent, collection, order);
// Figure out which creatures need to be recalculated after this move
const docCreature = getCreatureAncestorId(doc);
const parentCreature = getCreatureAncestorId(parent);
// Mark the creatures for recompute
if (!skipRecompute) {
if (docCreature) {
Creatures.updateAsync({
_id: docCreature,
}, {
$set: { dirty: true },
});
}
if (parentCreature && parentCreature !== docCreature) {
Creatures.updateAsync({
_id: parentCreature,
}, {
$set: { dirty: true },
});
}
}
},
});
const reorderDoc = new ValidatedMethod({
name: 'organize.reorderDoc',
validate: new SimpleSchema({
docRef: RefSchema,
order: {
type: Number,
// Should end in 0.5 to place it reliably between two existing documents
},
}).validator(),
mixins: [RateLimiterMixin],
rateLimit: {
numRequests: 5,
timeInterval: 5000,
},
async run({ docRef, order }) {
const doc = await fetchDocByRefAsync(docRef);
assertDocEditPermission(doc, this.userId);
let collection = getCollectionByName(docRef.collection);
console.log('setting doc left to ', order);
await collection.updateAsync(doc._id, { $set: { left: order } });
// Recompute the affected creatures
const creatureId = getCreatureAncestorId(doc);
if (creatureId) {
return Creatures.updateAsync({
_id: creatureId
}, {
$set: { dirty: true },
});
}
},
});
function getCreatureAncestorId(doc) {
if (doc.type === 'pc' || doc.type === 'npc' || doc.type === 'monster') {
return doc._id;
}
if (doc?.root?.collection === 'creatures') {
return doc.root.id;
}
}
export { organizeDoc, reorderDoc };

View File

@@ -1,5 +1,7 @@
import { chain, reverse } from 'lodash';
import { TreeDoc, treeDocFields, Reference } from '/imports/api/parenting/ChildSchema';
import { getProperties } from '/imports/api/engine/loadCreatures';
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
export function getCollectionByName(name: string): Mongo.Collection<TreeDoc> {
const collection = Mongo.Collection.get(name)
@@ -11,7 +13,7 @@ export function getCollectionByName(name: string): Mongo.Collection<TreeDoc> {
return collection;
}
function assertDocFound(doc) {
function assertDocFound(doc, ref) {
if (!doc) {
throw new Meteor.Error('document-not-found',
`No document could be found with id: ${ref.id} in ${ref.collection}`
@@ -21,13 +23,13 @@ function assertDocFound(doc) {
export function fetchDocByRefAsync(ref: Reference, options?: Mongo.Options<object>): Promise<TreeDoc> {
const doc = getCollectionByName(ref.collection).findOneAsync(ref.id, options);
assertDocFound(doc);
assertDocFound(doc, ref);
return doc;
}
export function fetchDocByRef(ref: Reference, options?: Mongo.Options<object>): TreeDoc {
const doc: TreeDoc = getCollectionByName(ref.collection).findOne(ref.id, options);
assertDocFound(doc);
assertDocFound(doc, ref);
return doc;
}
@@ -87,7 +89,9 @@ type FilteredDoc = {
_ancestorOfMatchedDocument?: boolean,
} & TreeDoc;
export async function filterToForest(
let filterToForest: undefined | ((...any) => TreeNode<FilteredDoc>[]) = undefined;
if (Meteor.isClient) filterToForest = function (
collection: Mongo.Collection<TreeDoc>,
rootId: string,
filter: Mongo.Selector<TreeDoc>,
@@ -96,7 +100,7 @@ export async function filterToForest(
includeFilteredDocAncestors = false,
includeFilteredDocDescendants = false
} = {}
): Promise<TreeNode<FilteredDoc>[]> {
): TreeNode<FilteredDoc>[] {
// Setup the filter
let collectionFilter = {
'root.id': rootId,
@@ -128,8 +132,8 @@ export async function filterToForest(
}
}
// Find all the docs that match the filter
const docs: TreeDoc[] = await collection.find(collectionFilter, collectionOptions)
.mapAsync(doc => {
const docs: TreeDoc[] = collection.find(collectionFilter, collectionOptions)
.map(doc => {
if (!filter) return doc;
// Mark the docs that were found by the custom filter
doc._matchedDocumentFilter = true;
@@ -139,7 +143,7 @@ export async function filterToForest(
// Get the doc ancestors
let ancestors: object[] = [];
if (filter && includeFilteredDocAncestors) {
ancestors = await collection.find(getFilter.ancestorsOfAll(docs), collectionOptions).mapAsync(doc => {
ancestors = collection.find(getFilter.ancestorsOfAll(docs), collectionOptions).map(doc => {
// Mark that the nodes are ancestors of the found nodes
doc._ancestorOfMatchedDocument = true;
return doc;
@@ -149,19 +153,19 @@ export async function filterToForest(
// Get the doc descendants
let descendants: FilteredDoc[] = [];
if (filter && includeFilteredDocDescendants) {
descendants = await collection.find({
descendants = collection.find({
'removed': { $ne: true },
...getFilter.descendantsOfAll(docs),
}).mapAsync((doc: FilteredDoc) => {
}).map((doc: FilteredDoc) => {
// Mark that the nodes are descendants of the found nodes
doc._descendantOfMatchedDocument = true;
return doc;
});
}
const nodes = chain([
ancestors,
docs,
descendants
...ancestors,
...docs,
...descendants
]).uniqBy('_id')
.sortBy('left')
.value();
@@ -169,6 +173,8 @@ export async function filterToForest(
return docsToForest(nodes);
}
export { filterToForest };
type ForestAndOrphans = { forest: TreeNode<TreeDoc>[], orphanIds: string[] }
/**
* Takes a complete set of documents and builds a forest using just their `.parentIds`
@@ -339,32 +345,41 @@ export function renewDocIds({ docArray, collectionMap = {}, idMap = {} }) {
* Changes the doc to be a child of the parent, and then rebuilds the nested sets of the roots
* of both doc and parent
* @param doc The doc to move
* @param parent The new parent of the doc
* @param parent The new parent of the doc, null to move the doc to the root of the tree
* @param collection
* @returns
*/
export async function changeParent(doc: TreeDoc, parent: TreeDoc, collection: Mongo.Collection<TreeDoc>, order?: number) {
export async function changeParent(doc: TreeDoc, parent: TreeDoc | null, collection: Mongo.Collection<TreeDoc>, order?: number) {
// Skip if we aren't changing the parent id
if (doc.parentId === parent._id) return;
if (doc.parentId === parent?._id) return;
// Store the original roots
const rootChange = doc.root.id !== parent.root.id;
const rootChange = parent && doc.root.id !== parent.root?.id;
// Check that the doc isn't becoming its own ancestor
if (parent.left > doc.left && parent.right < doc.right) {
if (parent && parent.left > doc.left && parent.right < doc.right) {
throw new Meteor.Error('invalid parenting', 'A doc can\'t be its own ancestor');
}
// update the document's parenting and root if necessary
const update: Mongo.Modifier<TreeDoc> = {
$set: { parentId: parent._id }
};
let update: Mongo.Modifier<TreeDoc>;
if (!parent) {
update = {
$unset: { parentId: 1 }
};
} else {
update = {
$set: { parentId: parent?._id }
};
}
if (rootChange && update.$set) {
update.$set.root = parent.root;
}
if (order && update.$set) {
if (order) {
if (!update.$set) update.$set = {};
update.$set.left = order;
}
await collection.updateAsync(doc._id, update);
// Rebuild the nested sets of everything on the root document(s)
@@ -403,7 +418,8 @@ export function hasAncestorRelationship(propA: TreeDoc, propB: TreeDoc): boolean
/**
* Returns true if A is a direct ancestor of B, assuming their roots are equal
*/
export function isAncestor(propA: TreeDoc, propB: TreeDoc): boolean {
export function isAncestor(propA?: TreeDoc, propB?: TreeDoc): boolean {
if (!propA || !propB) return false;
return propA.left < propB.left && propA.right > propB.right;
}
@@ -415,7 +431,7 @@ export function setDocToLastOrder(collection: Mongo.Collection<TreeDoc>, doc: Tr
}
export async function rebuildNestedSets(collection: Mongo.Collection<TreeDoc>, rootId: string) {
const docs = collection.find({
const docs = await collection.find({
'root.id': rootId,
removed: { $ne: true }
}, {
@@ -424,11 +440,16 @@ export async function rebuildNestedSets(collection: Mongo.Collection<TreeDoc>, r
//Reverse sorting so that arrays can be used as stacks with the first item on top
left: 1,
},
}).fetch();
}).fetchAsync();
const operations = calculateNestedSetOperations(docs);
return writeBulkOperations(collection, operations);
}
await writeBulkOperations(collection, operations);
export async function rebuildCreatureNestedSets(creatureId) {
const docs = getProperties(creatureId);
const operations = calculateNestedSetOperations(docs);
return writeBulkOperations(CreatureProperties as Mongo.Collection<TreeDoc, TreeDoc>, operations);
}
/** Calculates the operations needed to make a tree of nested sets
@@ -499,14 +520,14 @@ export function calculateNestedSetOperations(docs: TreeDoc[]) {
/**
* Same as calculateNestedSetOperations, but applies the ops to the properties
* Mostly used to create testing documents.
* @param docs
* @returns
* @param docs An array of documents that share a common root. Must already be sorted by `.left` in ascending order
* @returns The documents as a forest of tree nodes
*/
export function applyNestedSetProperties(docs: TreeDoc[]) {
// Walk around the tree numbering left on the way down and right on the way up like so:
const { forest: stack, orphanIds } = docsToForestByParentId(reverse([...docs]));
const { forest, orphanIds } = docsToForestByParentId(reverse([...docs]));
const stack = [...forest];
const visitedNodes = new Set();
const visitedChildren = new Set();
let count = 1;
@@ -540,6 +561,7 @@ export function applyNestedSetProperties(docs: TreeDoc[]) {
count += 1;
}
}
return forest;
}
/**

View File

@@ -1,5 +1,5 @@
import SimpleSchema from 'simpl-schema';
import ChildSchema from '/imports/api/parenting/ChildSchema.js';
import ChildSchema from '/imports/api/parenting/ChildSchema';
let TabletopMaps = new Mongo.Collection('tabletopmaps');

View File

@@ -1,5 +1,5 @@
import SimpleSchema from 'simpl-schema';
import ChildSchema from '/imports/api/parenting/ChildSchema.js';
import ChildSchema from '/imports/api/parenting/ChildSchema';
let TabletopObjects = new Mongo.Collection('tabletopObjects');

View File

@@ -37,11 +37,13 @@
:disabled="expanded"
/>
<!--{{node && node.order}}-->
<span>{{ node.left }}</span>
<tree-node-view
:model="node"
:selected="selected"
:show-external-details="showExternalDetails"
/>
<span>{{ node.right }}</span>
</div>
</div>
<v-expand-transition>
@@ -83,7 +85,6 @@
* the tree view shows off the full character structure, and where each part of
* character comes from.
**/
import { canBeParent } from '/imports/api/parenting/parentingFunctions';
import { getPropertyIcon } from '/imports/constants/PROPERTIES';
import TreeNodeView from '/imports/client/ui/properties/treeNodeViews/TreeNodeView.vue';
import { isAncestor } from '/imports/api/parenting/parentingFunctions';
@@ -145,7 +146,7 @@ export default {
return children;
},
canExpand() {
return canBeParent(this.node.type);
return true;
},
},
watch: {

View File

@@ -12,13 +12,13 @@
>
<tree-node
v-for="child in displayedChildren"
:key="child.node._id"
:key="child.doc._id"
class="item"
:node="child.node"
:node="child.doc"
:children="child.children"
:group="group"
:selected-node="selectedNode"
:selected="selectedNode && selectedNode._id === child.node._id"
:selected="selectedNode && selectedNode._id === child.doc._id"
:ancestors-of-selected-node="ancestorsOfSelectedNode"
:organize="organize"
:lazy="lazy"
@@ -34,7 +34,6 @@
<script lang="js">
import draggable from 'vuedraggable';
import TreeNode from '/imports/client/ui/components/tree/TreeNode.vue';
import { isParentAllowed } from '/imports/api/parenting/parentingFunctions';
export default {
components: {
@@ -93,22 +92,21 @@ export default {
change({ added, moved }) {
let event = moved || added;
if (event) {
let doc = event.element.node;
let doc = event.element.doc;
let newIndex;
if (event.newIndex === 0) {
newIndex = -0.5;
newIndex = 0.5;
} else {
if (event.newIndex < this.children.length) {
let childAtNewIndex = this.children[event.newIndex];
let indexOrder = childAtNewIndex.node.order;
if (event.newIndex > event.oldIndex) {
newIndex = indexOrder + 0.5;
newIndex = childAtNewIndex.doc.right + 0.5;
} else {
newIndex = indexOrder - 0.5;
newIndex = childAtNewIndex.doc.left - 0.5;
}
} else {
let childBeforeNewIndex = this.children[event.newIndex - 1];
newIndex = childBeforeNewIndex.node.order + 0.5;
newIndex = childBeforeNewIndex.doc.right + 0.5;
}
}
if (moved) {
@@ -118,12 +116,8 @@ export default {
}
}
},
move(evt) {
let parentNode = evt.relatedContext.component.$parent.node
let parentType = parentNode && parentNode.type || 'root';
let childType = evt.draggedContext.element.node.type;
let allowed = isParentAllowed({ parentType, childType });
return allowed;
move() {
return true;
},
},
};

View File

@@ -99,7 +99,7 @@ export default {
// Create the undo function
const oldOrder = item.order;
const oldParent = item.parent;
const undo = () => organizeDoc.call({
const undo = () => organizeDoc.callAsync({
docRef,
parentRef: oldParent,
order: (oldOrder || 0) - 0.5,
@@ -112,7 +112,7 @@ export default {
});
// Move the doc
organizeDoc.call({
organizeDoc.callAsync({
docRef,
parentRef: { collection: 'creatures', id: this.model._id },
order: -0.5,

View File

@@ -47,8 +47,8 @@ export default {
expanded: Boolean,
},
meteor: {
async children() {
const children = await filterToForest(
children() {
const children = filterToForest?.(
getCollectionByName(this.collection),
this.root.id,
this.filter,
@@ -56,14 +56,15 @@ export default {
includeFilteredDocAncestors: true,
includeFilteredDocDescendants: true,
}
);
) || [];
console.log(children)
this.$emit('length', children.length);
return children;
},
},
methods: {
reordered({ doc, newIndex }) {
reorderDoc.call({
reorderDoc.callAsync({
docRef: {
id: doc._id,
collection: this.collection,
@@ -81,7 +82,7 @@ export default {
} else {
parentRef = this.root;
}
organizeDoc.call({
organizeDoc.callAsync({
docRef: {
id: doc._id,
collection: this.collection,

View File

@@ -19,7 +19,7 @@
</template>
<script lang="js">
import { nodeArrayToTree } from '/imports/api/parenting/nodesToTree.js';
import { docsToForest } from '/imports/api/parenting/parentingFunctions';
import TreeNodeList from '/imports/client/ui/components/tree/TreeNodeList.vue';
import { organizeDoc, reorderDoc } from '/imports/api/docs/Docs.js';
import Docs from '/imports/api/docs/Docs.js';
@@ -48,7 +48,7 @@ export default {
},
docs() {
const docs = Docs.find({ removed: {$ne: true} }, { sort: {order: 1} }).fetch();
return nodeArrayToTree(docs);
return docsToForest(docs);
},
},
methods: {
@@ -59,7 +59,7 @@ export default {
this.$router.push(doc.href);
},
reordered({ doc, newIndex }) {
reorderDoc.call({
reorderDoc.callAsync({
docId: doc._id,
order: newIndex,
});
@@ -70,7 +70,7 @@ export default {
console.error('Moving docs to root level isn\'t implemented');
return;
}
organizeDoc.call({
organizeDoc.callAsync({
docId: doc._id,
parentId: parent?._id,
order: newIndex,

View File

@@ -103,7 +103,7 @@ export default {
},
methods: {
reordered({ doc, newIndex }) {
reorderDoc.call({
reorderDoc.callAsync({
docRef: {
id: doc._id,
collection: 'libraryNodes',
@@ -124,7 +124,7 @@ export default {
collection: 'libraries',
};
}
organizeDoc.call({
organizeDoc.callAsync({
docRef: {
id: doc._id,
collection: 'libraryNodes',

View File

@@ -246,7 +246,7 @@ export default {
elementId: 'property-toolbar-menu-button',
callback(parentId){
if (!parentId) return;
organizeDoc.call({
organizeDoc.callAsync({
docRef: {
collection: 'libraryNodes',
id,

View File

@@ -95,7 +95,7 @@ export default {
order = -0.5;
}
let doc = event.element;
organizeDoc.call({
organizeDoc.callAsync({
docRef: {
id: doc._id,
collection: 'creatureProperties',

View File

@@ -113,7 +113,7 @@ export default {
order = -0.5;
}
let doc = event.element;
organizeDoc.call({
organizeDoc.callAsync({
docRef: {
id: doc._id,
collection: 'creatureProperties',

View File

@@ -162,8 +162,8 @@ import MarkdownText from '/imports/client/ui/components/MarkdownText.vue';
import { snackbar } from '/imports/client/ui/components/snackbars/SnackbarQueue.js';
import CardHighlight from '/imports/client/ui/components/CardHighlight.vue';
import TreeNodeList from '/imports/client/ui/components/tree/TreeNodeList.vue';
import { nodeArrayToTree } from '/imports/api/parenting/nodesToTree.js';
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
import { docsToForest } from '/imports/api/parenting/parentingFunctions';
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
import { some } from 'lodash';
export default {
@@ -267,7 +267,7 @@ export default {
return prop.ancestors[buffIndex.ancestorIndex]?.id === buffIndex.id;
});
});
return nodeArrayToTree(decendants);
return docsToForest(decendants);
},
},
methods: {

View File

@@ -99,7 +99,7 @@ import TabletopMap from '/imports/client/ui/tabletop/TabletopMap.vue';
import Creatures from '/imports/api/creature/creatures/Creatures.js';
import MiniCharacterSheet from '/imports/client/ui/creature/character/MiniCharacterSheet.vue';
import { snackbar } from '/imports/client/ui/components/snackbars/SnackbarQueue.js';
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
import { assertEditPermission } from '/imports/api/creature/creatures/creaturePermissions.js';
import ActionCard from '/imports/client/ui/tabletop/TabletopActionCard.vue';
import SelectedCreatureBar from '/imports/client/ui/tabletop/selectedCreatureBar/SelectedCreatureBar.vue';

View File

@@ -50,7 +50,7 @@
</template>
<script lang="js">
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
import CardHighlight from '/imports/client/ui/components/CardHighlight.vue';
import HealthBarProgress from '/imports/client/ui/properties/components/attributes/HealthBarProgress.vue';

View File

@@ -25,7 +25,7 @@
</template>
<script lang="js">
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
import PropertyIcon from '/imports/client/ui/properties/shared/PropertyIcon.vue';
export default {

View File

@@ -136,7 +136,7 @@
<script lang="js">
import Creatures from '/imports/api/creature/creatures/Creatures.js';
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties';
import TabletopActionCard from '/imports/client/ui/tabletop/TabletopActionCard.vue';
import CreatureBarIcon from '/imports/client/ui/tabletop/selectedCreatureBar/CreatureBarIcon.vue';

View File

@@ -8,6 +8,7 @@ import { assertViewPermission } from '/imports/api/creature/creatures/creaturePe
import computeCreature from '/imports/api/engine/computeCreature';
import VERSION from '/imports/constants/VERSION';
import { loadCreature } from '/imports/api/engine/loadCreatures';
import { rebuildCreatureNestedSets } from '/imports/api/parenting/parentingFunctions';
let schema = new SimpleSchema({
creatureId: {
@@ -35,7 +36,13 @@ Meteor.publish('singleCharacter', function (creatureId) {
loadCreature(creatureId, self);
if (permissionCreature.computeVersion !== VERSION && computation.firstRun) {
try {
computeCreature(creatureId)
rebuildCreatureNestedSets(creatureId).then(() => {
try {
computeCreature(creatureId)
} catch (e) {
console.error(e);
}
});
}
catch (e) { console.error(e) }
}

388
app/package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "dicecloud",
"version": "2.0.57",
"version": "2.0.59",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -777,6 +777,23 @@
"mime-types": "^2.1.12"
}
},
"@emnapi/runtime": {
"version": "0.44.0",
"resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-0.44.0.tgz",
"integrity": "sha512-ZX/etZEZw8DR7zAB1eVQT40lNo0jeqpb6dCgOvctB6FIQ5PoXfMuNY8+ayQfu8tNQbAB8gQWSSJupR8NxeiZXw==",
"optional": true,
"requires": {
"tslib": "^2.4.0"
},
"dependencies": {
"tslib": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==",
"optional": true
}
}
},
"@eslint-community/eslint-utils": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
@@ -842,6 +859,147 @@
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
"dev": true
},
"@img/sharp-darwin-arm64": {
"version": "0.33.1",
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.1.tgz",
"integrity": "sha512-esr2BZ1x0bo+wl7Gx2hjssYhjrhUsD88VQulI0FrG8/otRQUOxLWHMBd1Y1qo2Gfg2KUvXNpT0ASnV9BzJCexw==",
"optional": true,
"requires": {
"@img/sharp-libvips-darwin-arm64": "1.0.0"
}
},
"@img/sharp-darwin-x64": {
"version": "0.33.1",
"resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.1.tgz",
"integrity": "sha512-YrnuB3bXuWdG+hJlXtq7C73lF8ampkhU3tMxg5Hh+E7ikxbUVOU9nlNtVTloDXz6pRHt2y2oKJq7DY/yt+UXYw==",
"optional": true,
"requires": {
"@img/sharp-libvips-darwin-x64": "1.0.0"
}
},
"@img/sharp-libvips-darwin-arm64": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.0.tgz",
"integrity": "sha512-VzYd6OwnUR81sInf3alj1wiokY50DjsHz5bvfnsFpxs5tqQxESoHtJO6xyksDs3RIkyhMWq2FufXo6GNSU9BMw==",
"optional": true
},
"@img/sharp-libvips-darwin-x64": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.0.tgz",
"integrity": "sha512-dD9OznTlHD6aovRswaPNEy8dKtSAmNo4++tO7uuR4o5VxbVAOoEQ1uSmN4iFAdQneTHws1lkTZeiXPrcCkh6IA==",
"optional": true
},
"@img/sharp-libvips-linux-arm": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.0.tgz",
"integrity": "sha512-VwgD2eEikDJUk09Mn9Dzi1OW2OJFRQK+XlBTkUNmAWPrtj8Ly0yq05DFgu1VCMx2/DqCGQVi5A1dM9hTmxf3uw==",
"optional": true
},
"@img/sharp-libvips-linux-arm64": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.0.tgz",
"integrity": "sha512-xTYThiqEZEZc0PRU90yVtM3KE7lw1bKdnDQ9kCTHWbqWyHOe4NpPOtMGy27YnN51q0J5dqRrvicfPbALIOeAZA==",
"optional": true
},
"@img/sharp-libvips-linux-s390x": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.0.tgz",
"integrity": "sha512-o9E46WWBC6JsBlwU4QyU9578G77HBDT1NInd+aERfxeOPbk0qBZHgoDsQmA2v9TbqJRWzoBPx1aLOhprBMgPjw==",
"optional": true
},
"@img/sharp-libvips-linux-x64": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.0.tgz",
"integrity": "sha512-naldaJy4hSVhWBgEjfdBY85CAa4UO+W1nx6a1sWStHZ7EUfNiuBTTN2KUYT5dH1+p/xij1t2QSXfCiFJoC5S/Q==",
"optional": true
},
"@img/sharp-libvips-linuxmusl-arm64": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.0.tgz",
"integrity": "sha512-OdorplCyvmSAPsoJLldtLh3nLxRrkAAAOHsGWGDYfN0kh730gifK+UZb3dWORRa6EusNqCTjfXV4GxvgJ/nPDQ==",
"optional": true
},
"@img/sharp-libvips-linuxmusl-x64": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.0.tgz",
"integrity": "sha512-FW8iK6rJrg+X2jKD0Ajhjv6y74lToIBEvkZhl42nZt563FfxkCYacrXZtd+q/sRQDypQLzY5WdLkVTbJoPyqNg==",
"optional": true
},
"@img/sharp-linux-arm": {
"version": "0.33.1",
"resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.1.tgz",
"integrity": "sha512-Ii4X1vnzzI4j0+cucsrYA5ctrzU9ciXERfJR633S2r39CiD8npqH2GMj63uFZRCFt3E687IenAdbwIpQOJ5BNA==",
"optional": true,
"requires": {
"@img/sharp-libvips-linux-arm": "1.0.0"
}
},
"@img/sharp-linux-arm64": {
"version": "0.33.1",
"resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.1.tgz",
"integrity": "sha512-59B5GRO2d5N3tIfeGHAbJps7cLpuWEQv/8ySd9109ohQ3kzyCACENkFVAnGPX00HwPTQcaBNF7HQYEfZyZUFfw==",
"optional": true,
"requires": {
"@img/sharp-libvips-linux-arm64": "1.0.0"
}
},
"@img/sharp-linux-s390x": {
"version": "0.33.1",
"resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.1.tgz",
"integrity": "sha512-tRGrb2pHnFUXpOAj84orYNxHADBDIr0J7rrjwQrTNMQMWA4zy3StKmMvwsI7u3dEZcgwuMMooIIGWEWOjnmG8A==",
"optional": true,
"requires": {
"@img/sharp-libvips-linux-s390x": "1.0.0"
}
},
"@img/sharp-linux-x64": {
"version": "0.33.1",
"resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.1.tgz",
"integrity": "sha512-4y8osC0cAc1TRpy02yn5omBeloZZwS62fPZ0WUAYQiLhSFSpWJfY/gMrzKzLcHB9ulUV6ExFiu2elMaixKDbeg==",
"optional": true,
"requires": {
"@img/sharp-libvips-linux-x64": "1.0.0"
}
},
"@img/sharp-linuxmusl-arm64": {
"version": "0.33.1",
"resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.1.tgz",
"integrity": "sha512-D3lV6clkqIKUizNS8K6pkuCKNGmWoKlBGh5p0sLO2jQERzbakhu4bVX1Gz+RS4vTZBprKlWaf+/Rdp3ni2jLfA==",
"optional": true,
"requires": {
"@img/sharp-libvips-linuxmusl-arm64": "1.0.0"
}
},
"@img/sharp-linuxmusl-x64": {
"version": "0.33.1",
"resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.1.tgz",
"integrity": "sha512-LOGKNu5w8uu1evVqUAUKTix2sQu1XDRIYbsi5Q0c/SrXhvJ4QyOx+GaajxmOg5PZSsSnCYPSmhjHHsRBx06/wQ==",
"optional": true,
"requires": {
"@img/sharp-libvips-linuxmusl-x64": "1.0.0"
}
},
"@img/sharp-wasm32": {
"version": "0.33.1",
"resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.1.tgz",
"integrity": "sha512-vWI/sA+0p+92DLkpAMb5T6I8dg4z2vzCUnp8yvxHlwBpzN8CIcO3xlSXrLltSvK6iMsVMNswAv+ub77rsf25lA==",
"optional": true,
"requires": {
"@emnapi/runtime": "^0.44.0"
}
},
"@img/sharp-win32-ia32": {
"version": "0.33.1",
"resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.1.tgz",
"integrity": "sha512-/xhYkylsKL05R+NXGJc9xr2Tuw6WIVl2lubFJaFYfW4/MQ4J+dgjIo/T4qjNRizrqs/szF/lC9a5+updmY9jaQ==",
"optional": true
},
"@img/sharp-win32-x64": {
"version": "0.33.1",
"resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.1.tgz",
"integrity": "sha512-XaM69X0n6kTEsp9tVYYLhXdg7Qj32vYJlAKRutxUsm1UlgQNx6BOhHwZPwukCGXBU2+tH87ip2eV1I/E8MQnZg==",
"optional": true
},
"@mapbox/node-pre-gyp": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz",
@@ -2177,27 +2335,6 @@
}
}
},
"bl": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
"requires": {
"buffer": "^5.5.0",
"inherits": "^2.0.4",
"readable-stream": "^3.4.0"
},
"dependencies": {
"buffer": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
"requires": {
"base64-js": "^1.3.1",
"ieee754": "^1.1.13"
}
}
}
},
"bowser": {
"version": "2.11.0",
"resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz",
@@ -2532,14 +2669,6 @@
"ms": "2.1.2"
}
},
"decompress-response": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
"integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
"requires": {
"mimic-response": "^3.1.0"
}
},
"deep-eql": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-4.1.2.tgz",
@@ -2549,11 +2678,6 @@
"type-detect": "^4.0.0"
}
},
"deep-extend": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="
},
"deep-is": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
@@ -2632,14 +2756,6 @@
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
"end-of-stream": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
"requires": {
"once": "^1.4.0"
}
},
"enquirer": {
"version": "2.3.6",
"resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz",
@@ -2882,11 +2998,6 @@
"resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
"integrity": "sha512-kEcvvCBByWXGnZy6JUlgAp2gBIUjfCAV6P6TgT1/aaQKcmuAEC4OZTV1I4EWQLz2gxZw76atuVyvHhTxvi0Flw=="
},
"expand-template": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
"integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg=="
},
"extend": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
@@ -3001,11 +3112,6 @@
"mime-types": "^2.1.12"
}
},
"fs-constants": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
"integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="
},
"fs-minipass": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz",
@@ -3075,11 +3181,6 @@
"resolved": "https://registry.npmjs.org/gintersect/-/gintersect-0.1.0.tgz",
"integrity": "sha512-jps8Ckj6u8yLxOYzBVJbPqvRdeHOINQgRtufaLHkunwNQcSEdZU0ejPBapSimXJEQ9mdQW4hsEUN7DfJEcTvQQ=="
},
"github-from-package": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
"integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw=="
},
"glob": {
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
@@ -3275,11 +3376,6 @@
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"ini": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
},
"ip": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz",
@@ -3463,7 +3559,7 @@
"lodash.omit": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-4.5.0.tgz",
"integrity": "sha1-brGa5aHuHdnfC5aeZs4Lf6MLXmA="
"integrity": "sha512-XeqSp49hNGmlkj2EJlfrQFIzQ6lXdNro9sddtQzcJY8QaoC2GO0DT7xaIokHeyM+mIT0mPMlPvkYzg2xCuHdZg=="
},
"lodash.template": {
"version": "4.5.0",
@@ -4345,11 +4441,6 @@
"mime-db": "1.46.0"
}
},
"mimic-response": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
"integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="
},
"minify-css-string": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/minify-css-string/-/minify-css-string-1.0.0.tgz",
@@ -4363,11 +4454,6 @@
"brace-expansion": "^1.1.7"
}
},
"minimist": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz",
"integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g=="
},
"minipass": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.4.tgz",
@@ -4390,11 +4476,6 @@
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
"integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="
},
"mkdirp-classic": {
"version": "0.5.3",
"resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
"integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="
},
"mongo-object": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/mongo-object/-/mongo-object-0.1.4.tgz",
@@ -4455,11 +4536,6 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
},
"napi-build-utils": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
"integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg=="
},
"natural-compare": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
@@ -4627,14 +4703,6 @@
"resolved": "https://registry.npmjs.org/ngraph.tojson/-/ngraph.tojson-0.1.4.tgz",
"integrity": "sha512-Ii2BTqi8zBRMLH8vTc8pMUKQFJaqbgttG9DKUaazoPVpwC/ww4jyTOHe2ZKaGGZRepnGLqSZ27wZUm7n8MjIgA=="
},
"node-abi": {
"version": "3.26.0",
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.26.0.tgz",
"integrity": "sha512-jRVtMFTChbi2i/jqo/i2iP9634KMe+7K1v35mIdj3Mn59i5q27ZYhn+sW6npISM/PQg7HrP2kwtRBMmh5Uvzdg==",
"requires": {
"semver": "^7.3.5"
}
},
"node-addon-api": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-5.0.0.tgz",
@@ -4742,25 +4810,6 @@
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true
},
"prebuild-install": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz",
"integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==",
"requires": {
"detect-libc": "^2.0.0",
"expand-template": "^2.0.3",
"github-from-package": "0.0.0",
"minimist": "^1.2.3",
"mkdirp-classic": "^0.5.3",
"napi-build-utils": "^1.0.1",
"node-abi": "^3.3.0",
"pump": "^3.0.0",
"rc": "^1.2.7",
"simple-get": "^4.0.0",
"tar-fs": "^2.0.0",
"tunnel-agent": "^0.6.0"
}
},
"prelude-ls": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
@@ -4788,15 +4837,6 @@
"resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz",
"integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ=="
},
"pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
"requires": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
},
"punycode": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
@@ -4837,24 +4877,6 @@
"ret": "~0.1.10"
}
},
"rc": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
"integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
"requires": {
"deep-extend": "^0.6.0",
"ini": "~1.3.0",
"minimist": "^1.2.0",
"strip-json-comments": "~2.0.1"
},
"dependencies": {
"strip-json-comments": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
"integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="
}
}
},
"readable-stream": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
@@ -4983,27 +5005,38 @@
"integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
},
"sharp": {
"version": "0.30.7",
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.30.7.tgz",
"integrity": "sha512-G+MY2YW33jgflKPTXXptVO28HvNOo9G3j0MybYAHeEmby+QuD2U98dT6ueht9cv/XDqZspSpIhoSW+BAKJ7Hig==",
"version": "0.33.1",
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.1.tgz",
"integrity": "sha512-iAYUnOdTqqZDb3QjMneBKINTllCJDZ3em6WaWy7NPECM4aHncvqHRm0v0bN9nqJxMiwamv5KIdauJ6lUzKDpTQ==",
"requires": {
"@img/sharp-darwin-arm64": "0.33.1",
"@img/sharp-darwin-x64": "0.33.1",
"@img/sharp-libvips-darwin-arm64": "1.0.0",
"@img/sharp-libvips-darwin-x64": "1.0.0",
"@img/sharp-libvips-linux-arm": "1.0.0",
"@img/sharp-libvips-linux-arm64": "1.0.0",
"@img/sharp-libvips-linux-s390x": "1.0.0",
"@img/sharp-libvips-linux-x64": "1.0.0",
"@img/sharp-libvips-linuxmusl-arm64": "1.0.0",
"@img/sharp-libvips-linuxmusl-x64": "1.0.0",
"@img/sharp-linux-arm": "0.33.1",
"@img/sharp-linux-arm64": "0.33.1",
"@img/sharp-linux-s390x": "0.33.1",
"@img/sharp-linux-x64": "0.33.1",
"@img/sharp-linuxmusl-arm64": "0.33.1",
"@img/sharp-linuxmusl-x64": "0.33.1",
"@img/sharp-wasm32": "0.33.1",
"@img/sharp-win32-ia32": "0.33.1",
"@img/sharp-win32-x64": "0.33.1",
"color": "^4.2.3",
"detect-libc": "^2.0.1",
"node-addon-api": "^5.0.0",
"prebuild-install": "^7.1.1",
"semver": "^7.3.7",
"simple-get": "^4.0.1",
"tar-fs": "^2.1.1",
"tunnel-agent": "^0.6.0"
"detect-libc": "^2.0.2",
"semver": "^7.5.4"
},
"dependencies": {
"semver": {
"version": "7.5.4",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"requires": {
"lru-cache": "^6.0.0"
}
"detect-libc": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz",
"integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw=="
}
}
},
@@ -5037,21 +5070,6 @@
"mongo-object": "^0.1.4"
}
},
"simple-concat": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz",
"integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q=="
},
"simple-get": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz",
"integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==",
"requires": {
"decompress-response": "^6.0.0",
"once": "^1.3.1",
"simple-concat": "^1.0.0"
}
},
"simple-swizzle": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
@@ -5331,36 +5349,6 @@
"yallist": "^4.0.0"
}
},
"tar-fs": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
"integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
"requires": {
"chownr": "^1.1.1",
"mkdirp-classic": "^0.5.2",
"pump": "^3.0.0",
"tar-stream": "^2.1.4"
},
"dependencies": {
"chownr": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
"integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="
}
}
},
"tar-stream": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
"integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
"requires": {
"bl": "^4.0.3",
"end-of-stream": "^1.4.1",
"fs-constants": "^1.0.0",
"inherits": "^2.0.3",
"readable-stream": "^3.1.1"
}
},
"text-table": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",

View File

@@ -49,7 +49,7 @@
"pretty-bytes": "^6.1.0",
"qrcode.vue": "^1.7.0",
"request": "^2.88.2",
"sharp": "^0.30.7",
"sharp": "^0.33.1",
"simpl-schema": "^1.13.1",
"source-map-support": "^0.5.21",
"speakingurl": "^14.0.1",
@@ -128,4 +128,4 @@
"@typescript-eslint/no-this-alias": "off"
}
}
}
}