mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-06-07 13:24:16 +02:00
Compare commits
13 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8fec742da3 | ||
|
|
d030bfba34 | ||
|
|
a4428fd5be | ||
|
|
6312a171e2 | ||
|
|
3527fd7959 | ||
|
|
f0a7539018 | ||
|
|
5be79f4ab8 | ||
|
|
2fc5b01f09 | ||
|
|
52b81de11f | ||
|
|
c0c9095847 | ||
|
|
5ac4fc3b9c | ||
|
|
6747be49b2 | ||
|
|
77c5cfcbb7 |
128 changed files with 1238 additions and 908 deletions
|
|
@ -1,5 +1,6 @@
|
|||
[*]
|
||||
indent_size = 4
|
||||
indent_style = spaces
|
||||
end_of_line = lf
|
||||
[*.yml]
|
||||
indent_size = 2
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
FOUNDRY_MAIN_PATH=/path/to/foundry/resources/app/main.js
|
||||
FOUNDRY_DATA_PATH=/path/to/foundry/data
|
||||
FOUNDRY_DATA_PATH=/path/to/foundry/
|
||||
13
.prettierrc
13
.prettierrc
|
|
@ -1,13 +0,0 @@
|
|||
{
|
||||
"trailingComma": "none",
|
||||
"tabWidth": 4,
|
||||
"useTabs": false,
|
||||
"semi": true,
|
||||
"singleQuote": true,
|
||||
"quoteProps": "consistent",
|
||||
"bracketSpacing": true,
|
||||
"arrowParens": "avoid",
|
||||
"printWidth": 120,
|
||||
"endOfLine": "lf",
|
||||
"bracketSameLine": true
|
||||
}
|
||||
16
README.md
16
README.md
|
|
@ -38,11 +38,13 @@ You can find the documentation here: https://github.com/Foundryborne/daggerheart
|
|||
|
||||
3. **Configure your Foundry paths:**
|
||||
|
||||
```bash
|
||||
npm run setup:dev -- --foundry-path="/path/to/foundry/main.js" --data-path="/path/to/data"
|
||||
```
|
||||
Copy `.env.example` to `.env` and set up the foundry path and data path. The foundry path must point to main.js, and the data path must point the folder containing the Data folder itself (but not the `Data` folder itself).
|
||||
|
||||
4. **Start developing:**
|
||||
4. **Setup symlinks:**
|
||||
|
||||
In a shell with elevated privilages, run `npm run createSymlink`. It will add a foundry folder for types, and add a symlink to the daggerheart folder into your foundry data.
|
||||
|
||||
5. **Start developing:**
|
||||
```bash
|
||||
npm start
|
||||
```
|
||||
|
|
@ -51,7 +53,7 @@ You can find the documentation here: https://github.com/Foundryborne/daggerheart
|
|||
|
||||
- `npm start` - Start development with file watching and Foundry launching
|
||||
- `npm run build` - One-time build
|
||||
- `npm run setup:dev -- --foundry-path="<path>" --data-path="<path>"` - Configure development environment
|
||||
- `npm run createSymlink` - Setup types and output symlinks
|
||||
|
||||
### Notes
|
||||
|
||||
|
|
@ -66,6 +68,10 @@ You can find the documentation here: https://github.com/Foundryborne/daggerheart
|
|||
|
||||
Looking to contribute to the project? Look no further, check out our [contributing guide](CONTRIBUTING.md), and keep the [Code of Conduct](coc.md) in mind when working on things.
|
||||
|
||||
## AI Policy
|
||||
|
||||
The Foundryborne Daggerheart system does not make use of AI (generative or otherwise) for any area of its implementation. We expect all contributors to follow this same policy when contributing with a pull request; contributions made using AI will be rejected outright.
|
||||
|
||||
## Disclaimer:
|
||||
|
||||
**Daggerheart System**
|
||||
|
|
|
|||
24
daggerheart.d.ts
vendored
24
daggerheart.d.ts
vendored
|
|
@ -1,8 +1,11 @@
|
|||
import '@client/global.mjs';
|
||||
import '@common/global.mjs';
|
||||
import '@common/primitives/global.mjs';
|
||||
import Canvas from '@client/canvas/board.mjs';
|
||||
|
||||
// Foundry's use of `Object.assign(globalThis) means many globally available objects are not read as such
|
||||
// This declare global hopefully fixes that
|
||||
// Note: eslint is not aware of these, whatever is added here should go in the eslint's globals list
|
||||
declare global {
|
||||
/**
|
||||
* A simple event framework used throughout Foundry Virtual Tabletop.
|
||||
|
|
@ -12,9 +15,28 @@ declare global {
|
|||
class Hooks extends foundry.helpers.Hooks {}
|
||||
const fromUuid = foundry.utils.fromUuid;
|
||||
const fromUuidSync = foundry.utils.fromUuidSync;
|
||||
|
||||
/**
|
||||
* A representation of a color in hexadecimal format.
|
||||
* This class provides methods for transformations and manipulations of colors.
|
||||
*/
|
||||
class Color extends foundry.utils.Color {}
|
||||
/**
|
||||
* The singleton game canvas
|
||||
*/
|
||||
const canvas: Canvas;
|
||||
|
||||
const ActiveEffect: foundry.documents.ActiveEffect;
|
||||
const Actor: foundry.documents.Actor;
|
||||
const BaseScene: foundry.documents.BaseScene;
|
||||
const ChatMessage: foundry.documents.ChatMessage;
|
||||
const Combat: foundry.documents.Combat;
|
||||
const Combatant: foundry.documents.Combatant;
|
||||
const Item: foundry.documents.Item;
|
||||
const Macro: foundry.documents.Macro;
|
||||
const Scene: foundry.documents.Scene;
|
||||
const TokenDocument: foundry.documents.TokenDocument;
|
||||
|
||||
const Collection: foundry.utils.Collection;
|
||||
const FormDataExtended: foundry.applications.ux.FormDataExtended;
|
||||
const TextEditor: foundry.applications.ux.TextEditor;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,101 @@
|
|||
import globals from 'globals';
|
||||
import { defineConfig } from 'eslint/config';
|
||||
import prettier from 'eslint-plugin-prettier';
|
||||
import { defineConfig, globalIgnores } from 'eslint/config';
|
||||
import tseslint from 'typescript-eslint';
|
||||
import js from '@eslint/js';
|
||||
import stylistic from '@stylistic/eslint-plugin';
|
||||
|
||||
/** @type {Partial<RulesConfig>} */
|
||||
export const stylisticRules = {
|
||||
'@stylistic/indent': [
|
||||
'error',
|
||||
4,
|
||||
{
|
||||
SwitchCase: 1
|
||||
}
|
||||
],
|
||||
'@stylistic/max-len': ['error', {
|
||||
code: 120,
|
||||
ignoreComments: true,
|
||||
ignoreStrings: true,
|
||||
ignoreTemplateLiterals: true,
|
||||
ignoreRegExpLiterals: true
|
||||
}],
|
||||
'@stylistic/quotes': ['error', 'single', { allowTemplateLiterals: 'always' }],
|
||||
'@stylistic/arrow-parens': ['error', 'as-needed'],
|
||||
'@stylistic/quote-props': ['error', 'as-needed'],
|
||||
'@stylistic/array-bracket-newline': ['error', 'consistent'],
|
||||
'@stylistic/key-spacing': 'error',
|
||||
'@stylistic/comma-dangle': ['error', 'never'],
|
||||
'@stylistic/space-in-parens': ['error', 'never'],
|
||||
'@stylistic/space-infix-ops': 2,
|
||||
'@stylistic/keyword-spacing': 2,
|
||||
'@stylistic/semi-spacing': 2,
|
||||
'@stylistic/no-multi-spaces': 2,
|
||||
'@stylistic/no-extra-semi': 2,
|
||||
'@stylistic/no-whitespace-before-property': 2,
|
||||
'@stylistic/space-unary-ops': 2
|
||||
};
|
||||
|
||||
export default defineConfig([
|
||||
{ files: ['**/*.{js,mjs,cjs}'], languageOptions: { globals: globals.browser } },
|
||||
{ plugins: { prettier } },
|
||||
globalIgnores(['foundry/**/*', 'build/**/*']),
|
||||
{
|
||||
files: ['gulpfile.js', 'postcss.config.js'],
|
||||
languageOptions: { globals: globals.node }
|
||||
},
|
||||
{
|
||||
files: ['**/*.{js,mjs,cjs}'],
|
||||
rules: {
|
||||
'prettier/prettier': 'error'
|
||||
plugins: {
|
||||
'@stylistic': stylistic
|
||||
},
|
||||
languageOptions: {
|
||||
globals: {
|
||||
...globals.browser,
|
||||
CONFIG: 'readonly',
|
||||
CONST: 'readonly',
|
||||
// Global classes
|
||||
Color: 'readonly',
|
||||
Handlebars: 'readonly',
|
||||
Hooks: 'readonly',
|
||||
PIXI: 'readonly',
|
||||
ProseMirror: 'readonly',
|
||||
Roll: 'readonly',
|
||||
// global namespaces
|
||||
canvas: 'readonly',
|
||||
foundry: 'readonly',
|
||||
game: 'readonly',
|
||||
ui: 'readonly',
|
||||
// global functions
|
||||
fromUuid: 'readonly',
|
||||
fromUuidSync: 'readonly',
|
||||
getDocumentClass: 'readonly',
|
||||
_del: 'readonly',
|
||||
_replace: 'readonly',
|
||||
_loc: 'readonly',
|
||||
// Documents
|
||||
ActiveEffect: 'readonly',
|
||||
Actor: 'readonly',
|
||||
BaseScene: 'readonly',
|
||||
ChatMessage: 'readonly',
|
||||
Combat: 'readonly',
|
||||
Combatant: 'readonly',
|
||||
Item: 'readonly',
|
||||
Macro: 'readonly',
|
||||
Scene: 'readonly',
|
||||
TokenDocument: 'readonly',
|
||||
// Other
|
||||
Collection: 'readonly',
|
||||
FormDataExtended: 'readonly',
|
||||
TextEditor: 'readonly'
|
||||
}
|
||||
},
|
||||
rules: {
|
||||
'no-undef': 'error',
|
||||
// 'no-unused-vars': ['error', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
|
||||
...stylisticRules
|
||||
}
|
||||
},
|
||||
{
|
||||
files: ['**/*.ts'],
|
||||
extends: [js.configs.recommended, tseslint.configs.recommended]
|
||||
}
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"module": "ES6",
|
||||
"target": "ES6",
|
||||
"module": "es2022",
|
||||
"target": "es2022",
|
||||
"paths": {
|
||||
"@client/*": ["./foundry/client/*"],
|
||||
"@common/*": ["./foundry/common/*"]
|
||||
|
|
|
|||
|
|
@ -450,7 +450,7 @@ export default class DhCharacterCreation extends HandlebarsApplicationMixin(Appl
|
|||
if (equipment.includes(type))
|
||||
presets.filter = {
|
||||
'system.tier': { key: 'system.tier', value: 1 },
|
||||
'type': { key: 'type', value: type }
|
||||
type: { key: 'type', value: type }
|
||||
};
|
||||
|
||||
ui.compendiumBrowser.open(presets);
|
||||
|
|
|
|||
|
|
@ -138,12 +138,12 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap
|
|||
const stressReductionStress = this.availableStressReductions
|
||||
? stressReductions.reduce((acc, red) => acc + red.cost, 0)
|
||||
: 0;
|
||||
const stress = this.actor.system.resources.stress;
|
||||
context.stress =
|
||||
selectedStressMarks.length > 0 || this.availableStressReductions
|
||||
? {
|
||||
value:
|
||||
this.actor.system.resources.stress.value + selectedStressMarks.length + stressReductionStress,
|
||||
max: this.actor.system.resources.stress.max
|
||||
value: stress.value + selectedStressMarks.length + stressReductionStress,
|
||||
max: stress.max
|
||||
}
|
||||
: null;
|
||||
|
||||
|
|
|
|||
|
|
@ -135,192 +135,6 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2)
|
|||
context.tabs.advancements.progress = { selected: selections, max: currentLevel.maxSelections };
|
||||
context.showTabs = this.tabGroups.primary !== 'summary';
|
||||
break;
|
||||
|
||||
const actorArmor = this.actor.system.armor;
|
||||
const levelKeys = Object.keys(this.levelup.levels);
|
||||
let achivementProficiency = 0;
|
||||
const achievementCards = [];
|
||||
let achievementExperiences = [];
|
||||
for (var levelKey of levelKeys) {
|
||||
const level = this.levelup.levels[levelKey];
|
||||
if (Number(levelKey) < this.levelup.startLevel) continue;
|
||||
|
||||
achivementProficiency += level.achievements.proficiency ?? 0;
|
||||
const cards = level.achievements.domainCards ? Object.values(level.achievements.domainCards) : null;
|
||||
if (cards) {
|
||||
for (var card of cards) {
|
||||
const itemCard = await foundry.utils.fromUuid(card.uuid);
|
||||
achievementCards.push(itemCard);
|
||||
}
|
||||
}
|
||||
|
||||
achievementExperiences = level.achievements.experiences
|
||||
? Object.values(level.achievements.experiences).reduce((acc, experience) => {
|
||||
if (experience.name) acc.push(experience);
|
||||
return acc;
|
||||
}, [])
|
||||
: [];
|
||||
}
|
||||
|
||||
context.achievements = {
|
||||
proficiency: {
|
||||
old: this.actor.system.proficiency,
|
||||
new: this.actor.system.proficiency + achivementProficiency,
|
||||
shown: achivementProficiency > 0
|
||||
},
|
||||
damageThresholds: {
|
||||
major: {
|
||||
old: this.actor.system.damageThresholds.major,
|
||||
new: this.actor.system.damageThresholds.major + changedActorLevel - currentActorLevel
|
||||
},
|
||||
severe: {
|
||||
old: this.actor.system.damageThresholds.severe,
|
||||
new:
|
||||
this.actor.system.damageThresholds.severe +
|
||||
(actorArmor
|
||||
? changedActorLevel - currentActorLevel
|
||||
: (changedActorLevel - currentActorLevel) * 2)
|
||||
},
|
||||
unarmored: !actorArmor
|
||||
},
|
||||
domainCards: {
|
||||
values: achievementCards,
|
||||
shown: achievementCards.length > 0
|
||||
},
|
||||
experiences: {
|
||||
values: achievementExperiences
|
||||
}
|
||||
};
|
||||
|
||||
const advancement = {};
|
||||
for (var levelKey of levelKeys) {
|
||||
const level = this.levelup.levels[levelKey];
|
||||
if (Number(levelKey) < this.levelup.startLevel) continue;
|
||||
|
||||
for (var choiceKey of Object.keys(level.choices)) {
|
||||
const choice = level.choices[choiceKey];
|
||||
for (var checkbox of Object.values(choice)) {
|
||||
switch (choiceKey) {
|
||||
case 'proficiency':
|
||||
case 'hitPoint':
|
||||
case 'stress':
|
||||
case 'evasion':
|
||||
advancement[choiceKey] = advancement[choiceKey]
|
||||
? advancement[choiceKey] + Number(checkbox.value)
|
||||
: Number(checkbox.value);
|
||||
break;
|
||||
case 'trait':
|
||||
if (!advancement[choiceKey]) advancement[choiceKey] = {};
|
||||
for (var traitKey of checkbox.data) {
|
||||
if (!advancement[choiceKey][traitKey]) advancement[choiceKey][traitKey] = 0;
|
||||
advancement[choiceKey][traitKey] += 1;
|
||||
}
|
||||
break;
|
||||
case 'domainCard':
|
||||
if (!advancement[choiceKey]) advancement[choiceKey] = [];
|
||||
if (checkbox.data.length === 1) {
|
||||
const choiceItem = await foundry.utils.fromUuid(checkbox.data[0]);
|
||||
advancement[choiceKey].push(choiceItem.toObject());
|
||||
}
|
||||
break;
|
||||
case 'experience':
|
||||
if (!advancement[choiceKey]) advancement[choiceKey] = [];
|
||||
const data = checkbox.data.map(data => {
|
||||
const experience = Object.keys(this.actor.system.experiences).find(
|
||||
x => x === data
|
||||
);
|
||||
return this.actor.system.experiences[experience]?.description ?? '';
|
||||
});
|
||||
advancement[choiceKey].push({ data: data, value: checkbox.value });
|
||||
break;
|
||||
case 'subclass':
|
||||
if (checkbox.data[0]) {
|
||||
const subclassItem = await foundry.utils.fromUuid(checkbox.data[0]);
|
||||
if (!advancement[choiceKey]) advancement[choiceKey] = [];
|
||||
advancement[choiceKey].push({
|
||||
...subclassItem.toObject(),
|
||||
featureLabel: game.i18n.localize(
|
||||
subclassFeatureLabels[Number(checkbox.secondaryData.featureState)]
|
||||
)
|
||||
});
|
||||
}
|
||||
break;
|
||||
case 'multiclass':
|
||||
const multiclassItem = await foundry.utils.fromUuid(checkbox.data[0]);
|
||||
const subclass = multiclassItem
|
||||
? await foundry.utils.fromUuid(checkbox.secondaryData.subclass)
|
||||
: null;
|
||||
advancement[choiceKey] = multiclassItem
|
||||
? {
|
||||
...multiclassItem.toObject(),
|
||||
domain: checkbox.secondaryData.domain
|
||||
? game.i18n.localize(
|
||||
CONFIG.DH.DOMAIN.allDomains()[checkbox.secondaryData.domain]
|
||||
.label
|
||||
)
|
||||
: null,
|
||||
subclass: subclass ? subclass.name : null
|
||||
}
|
||||
: {};
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context.advancements = {
|
||||
statistics: {
|
||||
proficiency: {
|
||||
old: context.achievements.proficiency.new,
|
||||
new: context.achievements.proficiency.new + (advancement.proficiency ?? 0)
|
||||
},
|
||||
hitPoints: {
|
||||
old: this.actor.system.resources.hitPoints.max,
|
||||
new: this.actor.system.resources.hitPoints.max + (advancement.hitPoint ?? 0)
|
||||
},
|
||||
stress: {
|
||||
old: this.actor.system.resources.stress.max,
|
||||
new: this.actor.system.resources.stress.max + (advancement.stress ?? 0)
|
||||
},
|
||||
evasion: {
|
||||
old: this.actor.system.evasion,
|
||||
new: this.actor.system.evasion + (advancement.evasion ?? 0)
|
||||
}
|
||||
},
|
||||
traits: Object.keys(this.actor.system.traits).reduce((acc, traitKey) => {
|
||||
if (advancement.trait?.[traitKey]) {
|
||||
if (!acc) acc = {};
|
||||
acc[traitKey] = {
|
||||
label: game.i18n.localize(abilities[traitKey].label),
|
||||
old: this.actor.system.traits[traitKey].value,
|
||||
new: this.actor.system.traits[traitKey].value + advancement.trait[traitKey]
|
||||
};
|
||||
}
|
||||
return acc;
|
||||
}, null),
|
||||
domainCards: advancement.domainCard ?? [],
|
||||
experiences:
|
||||
advancement.experience?.flatMap(x => x.data.map(data => ({ name: data, modifier: x.value }))) ??
|
||||
[],
|
||||
multiclass: advancement.multiclass,
|
||||
subclass: advancement.subclass
|
||||
};
|
||||
|
||||
context.advancements.statistics.proficiency.shown =
|
||||
context.advancements.statistics.proficiency.new > context.advancements.statistics.proficiency.old;
|
||||
context.advancements.statistics.hitPoints.shown =
|
||||
context.advancements.statistics.hitPoints.new > context.advancements.statistics.hitPoints.old;
|
||||
context.advancements.statistics.stress.shown =
|
||||
context.advancements.statistics.stress.new > context.advancements.statistics.stress.old;
|
||||
context.advancements.statistics.evasion.shown =
|
||||
context.advancements.statistics.evasion.new > context.advancements.statistics.evasion.old;
|
||||
context.advancements.statistics.shown =
|
||||
context.advancements.statistics.proficiency.shown ||
|
||||
context.advancements.statistics.hitPoints.shown ||
|
||||
context.advancements.statistics.stress.shown ||
|
||||
context.advancements.statistics.evasion.shown;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
return context;
|
||||
|
|
@ -358,14 +172,14 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2)
|
|||
const experienceIncreaseTagify = htmlElement.querySelector('.levelup-experience-increases');
|
||||
if (experienceIncreaseTagify) {
|
||||
const allExperiences = {
|
||||
...this.actor.system.experiences,
|
||||
...Object.values(this.levelup.levels).reduce((acc, level) => {
|
||||
for (const key of Object.keys(level.achievements.experiences)) {
|
||||
acc[key] = level.achievements.experiences[key];
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, {})
|
||||
}, {}),
|
||||
...this.actor.system.experiences
|
||||
};
|
||||
tagifyElement(
|
||||
experienceIncreaseTagify,
|
||||
|
|
@ -384,9 +198,7 @@ export default class DhlevelUp extends HandlebarsApplicationMixin(ApplicationV2)
|
|||
this._dragDrop.forEach(d => d.bind(htmlElement));
|
||||
}
|
||||
|
||||
tagifyUpdate =
|
||||
type =>
|
||||
async (_, { option, removed }) => {
|
||||
tagifyUpdate = type => async (_, { option, removed }) => {
|
||||
const updatePath = Object.keys(this.levelup.levels[this.levelup.currentLevel].choices).reduce(
|
||||
(acc, choiceKey) => {
|
||||
const choice = this.levelup.levels[this.levelup.currentLevel].choices[choiceKey];
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli
|
|||
|
||||
switch (partId) {
|
||||
case 'domains':
|
||||
const selectedDomain = this.selected.domain ? this.settings.domains[this.selected.domain] : null;
|
||||
const selectedDomain = this.settings.domains[this.selected.domain] ?? null;
|
||||
const enrichedDescription = selectedDomain
|
||||
? await foundry.applications.ux.TextEditor.implementation.enrichHTML(selectedDomain.description)
|
||||
: null;
|
||||
|
|
|
|||
|
|
@ -204,7 +204,7 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2)
|
|||
};
|
||||
}
|
||||
|
||||
if (this.action.parent.metadata.isInventoryItem) {
|
||||
if (this.action.parent.metadata?.isInventoryItem) {
|
||||
options.quantity = {
|
||||
label: 'DAGGERHEART.GENERAL.itemQuantity',
|
||||
group: 'Global'
|
||||
|
|
|
|||
|
|
@ -306,7 +306,7 @@ export default class Party extends DHBaseActorSheet {
|
|||
|
||||
static async downtimeMoveQuery({ actorId, downtimeType }) {
|
||||
const actor = await foundry.utils.fromUuid(actorId);
|
||||
if (!actor || !actor?.isOwner) reject();
|
||||
if (!actor || !actor?.isOwner) return;
|
||||
new game.system.api.applications.dialogs.Downtime(actor, downtimeType === 'shortRest').render({
|
||||
force: true
|
||||
});
|
||||
|
|
|
|||
|
|
@ -377,7 +377,7 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) {
|
|||
action: 'update',
|
||||
documentName: 'Item',
|
||||
parent: targetActor,
|
||||
updates: [{ '_id': existing.id, 'system.quantity': existing.system.quantity + quantity }]
|
||||
updates: [{ _id: existing.id, 'system.quantity': existing.system.quantity + quantity }]
|
||||
});
|
||||
} else {
|
||||
const itemsToCreate = [];
|
||||
|
|
@ -410,7 +410,7 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) {
|
|||
action: 'update',
|
||||
documentName: 'Item',
|
||||
parent: originActor,
|
||||
updates: [{ '_id': item.id, 'system.quantity': item.system.quantity - quantity }]
|
||||
updates: [{ _id: item.id, 'system.quantity': item.system.quantity - quantity }]
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,16 +29,6 @@ export default function ItemAttachmentSheet(Base) {
|
|||
}
|
||||
};
|
||||
|
||||
async _preparePartContext(partId, context) {
|
||||
await super._preparePartContext(partId, context);
|
||||
|
||||
if (partId === 'attachments') {
|
||||
context.attachedItems = await prepareAttachmentContext(this.document);
|
||||
}
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
async _onDrop(event) {
|
||||
const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event);
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo
|
|||
const title =
|
||||
(flavor ?? traitValue)
|
||||
? game.i18n.format('DAGGERHEART.UI.Chat.dualityRoll.abilityCheckTitle', {
|
||||
ability: game.i18n.localize(SYSTEM.ACTOR.abilities[traitValue].label)
|
||||
ability: game.i18n.localize(CONFIG.DH.ACTOR.abilities[traitValue].label)
|
||||
})
|
||||
: game.i18n.localize('DAGGERHEART.GENERAL.duality');
|
||||
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ export default class CountdownEdit extends HandlebarsApplicationMixin(Applicatio
|
|||
}
|
||||
|
||||
async gmSetSetting(data) {
|
||||
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns, data),
|
||||
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns, data);
|
||||
game.socket.emit(`system.${CONFIG.DH.id}`, {
|
||||
action: socketEvent.Refresh,
|
||||
data: { refreshType: RefreshType.Countdown }
|
||||
|
|
|
|||
|
|
@ -31,9 +31,9 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application
|
|||
minimizable: false
|
||||
},
|
||||
actions: {
|
||||
toggleViewMode: DhCountdowns.#toggleViewMode,
|
||||
editCountdowns: DhCountdowns.#editCountdowns,
|
||||
loopCountdown: DhCountdowns.#loopCountdown,
|
||||
toggleViewMode: DhCountdowns.#onToggleViewMode,
|
||||
editCountdowns: DhCountdowns.#onEditCountdowns,
|
||||
loopCountdown: DhCountdowns.#onLoopCountdown,
|
||||
decreaseCountdown: (_, target) => this.editCountdown(false, target),
|
||||
increaseCountdown: (_, target) => this.editCountdown(true, target)
|
||||
},
|
||||
|
|
@ -147,7 +147,7 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application
|
|||
return true;
|
||||
}
|
||||
|
||||
static async #toggleViewMode() {
|
||||
static async #onToggleViewMode() {
|
||||
const currentMode = game.user.getFlag(CONFIG.DH.id, CONFIG.DH.FLAGS.userFlags.countdownMode);
|
||||
const appMode = CONFIG.DH.GENERAL.countdownAppMode;
|
||||
const newMode = currentMode === appMode.textIcon ? appMode.iconOnly : appMode.textIcon;
|
||||
|
|
@ -158,15 +158,16 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application
|
|||
this.render();
|
||||
}
|
||||
|
||||
static async #editCountdowns() {
|
||||
static async #onEditCountdowns() {
|
||||
new game.system.api.applications.ui.CountdownEdit().render(true);
|
||||
}
|
||||
|
||||
static async #loopCountdown(_, target) {
|
||||
static async #onLoopCountdown(_, target) {
|
||||
if (!DhCountdowns.canPerformEdit()) return;
|
||||
|
||||
const settings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns);
|
||||
const countdown = settings.countdowns[target.id];
|
||||
const countdownId = target.closest('[data-countdown]').dataset.countdown;
|
||||
const countdown = settings.countdowns[countdownId];
|
||||
|
||||
let progressMax = countdown.progress.start;
|
||||
let message = null;
|
||||
|
|
@ -185,7 +186,7 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application
|
|||
|
||||
await waitForDiceSoNice(message);
|
||||
await settings.updateSource({
|
||||
[`countdowns.${target.id}.progress`]: {
|
||||
[`countdowns.${countdownId}.progress`]: {
|
||||
current: newMax,
|
||||
start: newMax
|
||||
}
|
||||
|
|
@ -199,18 +200,19 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application
|
|||
if (!DhCountdowns.canPerformEdit()) return;
|
||||
|
||||
const settings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns);
|
||||
const countdown = settings.countdowns[target.id];
|
||||
const countdownId = target.closest('[data-countdown]').dataset.countdown;
|
||||
const countdown = settings.countdowns[countdownId];
|
||||
const newCurrent = increase
|
||||
? Math.min(countdown.progress.current + 1, countdown.progress.start)
|
||||
: Math.max(countdown.progress.current - 1, 0);
|
||||
await settings.updateSource({ [`countdowns.${target.id}.progress.current`]: newCurrent });
|
||||
await settings.updateSource({ [`countdowns.${countdownId}.progress.current`]: newCurrent });
|
||||
await emitGMUpdate(GMUpdateEvent.UpdateCountdowns, DhCountdowns.gmSetSetting.bind(settings), settings, null, {
|
||||
refreshType: RefreshType.Countdown
|
||||
});
|
||||
}
|
||||
|
||||
static async gmSetSetting(data) {
|
||||
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns, data),
|
||||
await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns, data);
|
||||
game.socket.emit(`system.${CONFIG.DH.id}`, {
|
||||
action: socketEvent.Refresh,
|
||||
data: { refreshType: RefreshType.Countdown }
|
||||
|
|
|
|||
|
|
@ -223,7 +223,7 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
|
|||
* @returns {object}
|
||||
*/
|
||||
async use(event, configOptions = {}) {
|
||||
if (!this.actor) throw new Error("An Action can't be used outside of an Actor context.");
|
||||
if (!this.actor) throw new Error('An Action can\'t be used outside of an Actor context.');
|
||||
|
||||
let config = this.prepareConfig(event, configOptions);
|
||||
if (!config) return;
|
||||
|
|
|
|||
|
|
@ -90,13 +90,13 @@ export default class BeastformEffect extends BaseEffect {
|
|||
...baseUpdate,
|
||||
x,
|
||||
y,
|
||||
'texture': {
|
||||
texture: {
|
||||
enabled: this.characterTokenData.usesDynamicToken,
|
||||
src: token.flags.daggerheart?.beastformTokenImg ?? this.characterTokenData.tokenImg,
|
||||
scaleX: this.characterTokenData.tokenSize.scale,
|
||||
scaleY: this.characterTokenData.tokenSize.scale
|
||||
},
|
||||
'ring': {
|
||||
ring: {
|
||||
subject: {
|
||||
texture:
|
||||
token.flags.daggerheart?.beastformSubjectTexture ?? this.characterTokenData.tokenRingImg
|
||||
|
|
|
|||
|
|
@ -520,12 +520,12 @@ export default class DhCharacter extends DhCreature {
|
|||
|
||||
if (armorSource.type === 'armor') {
|
||||
armorUpdates[armorSource.parent.id].updates.push({
|
||||
'_id': armorSource.id,
|
||||
_id: armorSource.id,
|
||||
'system.armor.current': armorSource.system.armor.current + usedArmorChange
|
||||
});
|
||||
} else {
|
||||
effectUpdates[armorSource.parent.id].updates.push({
|
||||
'_id': armorSource.id,
|
||||
_id: armorSource.id,
|
||||
'system.changes': armorSource.system.changes.map(change => ({
|
||||
...change,
|
||||
value:
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { calculateExpectedValue, parseTermsFromSimpleFormula } from '../../helpers/utils.mjs';
|
||||
import { adversaryExpectedDamage, adversaryScalingData } from '../../config/actorConfig.mjs';
|
||||
import { parseInlineParams } from '../../enrichers/parser.mjs';
|
||||
|
||||
export function getTierAdjustedAdversary(source, tier) {
|
||||
const currentTier = source.tier ?? 1;
|
||||
|
|
@ -60,8 +61,8 @@ export function getTierAdjustedAdversary(source, tier) {
|
|||
const descriptionFormulas = [];
|
||||
for (const withDescription of [item.system, ...Object.values(item.system.actions)]) {
|
||||
withDescription.description = withDescription.description.replace(damageRegex, (match, inner) => {
|
||||
const { value: formula } = parseInlineParams(inner);
|
||||
if (!formula || !type) return match;
|
||||
const { value: formula } = parseInlineParams(inner, { first: 'value' });
|
||||
if (!formula) return match;
|
||||
|
||||
try {
|
||||
const newFormula = calculateAdjustedDamage(formula, 'action', damageMeta)?.formula;
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ export default class CountdownField extends fields.ArrayField {
|
|||
CONFIG.DH.id,
|
||||
CONFIG.DH.SETTINGS.gameSettings.Countdowns,
|
||||
countdownSetting.toObject()
|
||||
),
|
||||
);
|
||||
game.socket.emit(`system.${CONFIG.DH.id}`, {
|
||||
action: socketEvent.Refresh,
|
||||
data: { refreshType: RefreshType.Countdown }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import BaseDataItem from './base.mjs';
|
||||
import ItemLinkFields from '../../data/fields/itemLinkFields.mjs';
|
||||
import { getFeaturesHTMLData } from '../../helpers/utils.mjs';
|
||||
import { fromUuids, getFeaturesHTMLData } from '../../helpers/utils.mjs';
|
||||
|
||||
export default class DHAncestry extends BaseDataItem {
|
||||
/** @inheritDoc */
|
||||
|
|
@ -45,6 +45,10 @@ export default class DHAncestry extends BaseDataItem {
|
|||
|
||||
/**@inheritdoc */
|
||||
async getDescriptionData() {
|
||||
// Preload all ancestry features for acquisition from the cache
|
||||
// todo: make feature acquisition async and replace feature helpers for methods
|
||||
await fromUuids(this._source.features.map(f => f.item));
|
||||
|
||||
const baseDescription = this.description;
|
||||
const features = await getFeaturesHTMLData(this.features);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { getFeaturesHTMLData } from '../../helpers/utils.mjs';
|
||||
import { fromUuids, getFeaturesHTMLData } from '../../helpers/utils.mjs';
|
||||
import ForeignDocumentUUIDArrayField from '../fields/foreignDocumentUUIDArrayField.mjs';
|
||||
import BaseDataItem from './base.mjs';
|
||||
|
||||
|
|
@ -27,6 +27,10 @@ export default class DHCommunity extends BaseDataItem {
|
|||
|
||||
/**@inheritdoc */
|
||||
async getDescriptionData() {
|
||||
// Preload all community features for acquisition from the cache
|
||||
// todo: make feature acquisition async and replace feature helpers for methods
|
||||
await fromUuids(this._source.features);
|
||||
|
||||
const baseDescription = this.description;
|
||||
const features = await getFeaturesHTMLData(this.features);
|
||||
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ export default class DHSubclass extends BaseDataItem {
|
|||
? game.i18n.localize(CONFIG.DH.ACTOR.abilities[this.spellcastingTrait].label)
|
||||
: null;
|
||||
|
||||
// Preload all class features for acquisition from the cache
|
||||
// Preload all subclass features for acquisition from the cache
|
||||
// todo: make feature acquisition async and replace feature helpers for methods
|
||||
await fromUuids(this._source.features.map(f => f.item));
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ export default class DHRoll extends Roll {
|
|||
static async buildConfigure(config = {}, message = {}) {
|
||||
config.hooks = [...this.getHooks(), ''];
|
||||
config.dialog ??= {};
|
||||
config.damageOptions ??= {};
|
||||
|
||||
for (const hook of config.hooks) {
|
||||
if (Hooks.call(`${CONFIG.DH.id}.preRoll${hook.capitalize()}`, config, message) === false) return null;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { ResourceUpdateMap } from '../data/action/baseAction.mjs';
|
||||
|
||||
export function updateResourcesForDualityReroll(oldDuality, newDuality, actor) {
|
||||
const { hopeFear } = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation);
|
||||
if (game.user.isGM ? !hopeFear.gm : !hopeFear.players) return;
|
||||
|
|
|
|||
|
|
@ -324,7 +324,7 @@ export default class DHToken extends CONFIG.Token.documentClass {
|
|||
}
|
||||
let x = 0.5 * bottom;
|
||||
let y = 0.25;
|
||||
for (let k = width - bottom; k--; ) {
|
||||
for (let k = width - bottom; k--;) {
|
||||
points.push(x, y);
|
||||
x += 0.5;
|
||||
y -= 0.25;
|
||||
|
|
@ -333,7 +333,7 @@ export default class DHToken extends CONFIG.Token.documentClass {
|
|||
y += 0.25;
|
||||
}
|
||||
points.push(x, y);
|
||||
for (let k = bottom; k--; ) {
|
||||
for (let k = bottom; k--;) {
|
||||
y += 0.5;
|
||||
points.push(x, y);
|
||||
x += 0.5;
|
||||
|
|
@ -341,14 +341,14 @@ export default class DHToken extends CONFIG.Token.documentClass {
|
|||
points.push(x, y);
|
||||
}
|
||||
y += 0.5;
|
||||
for (let k = top; k--; ) {
|
||||
for (let k = top; k--;) {
|
||||
points.push(x, y);
|
||||
x -= 0.5;
|
||||
y += 0.25;
|
||||
points.push(x, y);
|
||||
y += 0.5;
|
||||
}
|
||||
for (let k = width - top; k--; ) {
|
||||
for (let k = width - top; k--;) {
|
||||
points.push(x, y);
|
||||
x -= 0.5;
|
||||
y += 0.25;
|
||||
|
|
@ -357,7 +357,7 @@ export default class DHToken extends CONFIG.Token.documentClass {
|
|||
y -= 0.25;
|
||||
}
|
||||
points.push(x, y);
|
||||
for (let k = top; k--; ) {
|
||||
for (let k = top; k--;) {
|
||||
y -= 0.5;
|
||||
points.push(x, y);
|
||||
x -= 0.5;
|
||||
|
|
@ -365,7 +365,7 @@ export default class DHToken extends CONFIG.Token.documentClass {
|
|||
points.push(x, y);
|
||||
}
|
||||
y -= 0.5;
|
||||
for (let k = bottom; k--; ) {
|
||||
for (let k = bottom; k--;) {
|
||||
points.push(x, y);
|
||||
x += 0.5;
|
||||
y -= 0.25;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { parseInlineParams } from './parser.mjs';
|
||||
|
||||
export default function DhDamageEnricher(match, _options) {
|
||||
const { value, type, inline } = parseInlineParams(match[1]);
|
||||
const { value, type, inline } = parseInlineParams(match[1], { first: 'value' });
|
||||
if (!value || !type) return match[0];
|
||||
return getDamageMessage(value, type, inline, match[0]);
|
||||
}
|
||||
|
|
@ -59,7 +59,7 @@ export const renderDamageButton = async event => {
|
|||
{
|
||||
formula: value,
|
||||
applyTo: CONFIG.DH.GENERAL.healingTypes.hitPoints.id,
|
||||
type: type
|
||||
damageTypes: type
|
||||
}
|
||||
]
|
||||
};
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ export function parseInlineParams(paramString, { first } = {}) {
|
|||
const parts = paramString.split('|').map(x => x.trim());
|
||||
const params = {};
|
||||
for (const [idx, param] of parts.entries()) {
|
||||
if (first && idx === 0) {
|
||||
if (first && idx === 0 && !param.includes(':')) {
|
||||
params[first] = param;
|
||||
} else {
|
||||
const parts = param.split(':');
|
||||
|
|
|
|||
|
|
@ -879,6 +879,7 @@ export async function fromUuids(uuids) {
|
|||
const packEmbeddedEntries = entries.filter(
|
||||
e =>
|
||||
!(e.value instanceof Document) &&
|
||||
e.parsed &&
|
||||
e.parsed.collection instanceof foundry.documents.collections.CompendiumCollection &&
|
||||
e.parsed.embedded.length > 0
|
||||
);
|
||||
|
|
@ -895,7 +896,7 @@ export async function fromUuids(uuids) {
|
|||
const pack = game.packs.get(packGroup[0].value.pack);
|
||||
if (!pack) continue;
|
||||
|
||||
const ids = packGroup.map(p => p.parsed.id);
|
||||
const ids = packGroup.map(p => p.parsed?.id).filter(id => !!id);
|
||||
const documents = await pack.getDocuments({ _id__in: ids });
|
||||
for (const p of packGroup) {
|
||||
p.value = documents.find(d => d.id === p.parsed.id) ?? p.value;
|
||||
|
|
|
|||
551
package-lock.json
generated
551
package-lock.json
generated
|
|
@ -13,18 +13,20 @@
|
|||
"rollup": "^4.40.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^10.0.1",
|
||||
"@foundryvtt/foundryvtt-cli": "^1.0.2",
|
||||
"@rollup/plugin-commonjs": "^25.0.7",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@stylistic/eslint-plugin": "^5.10.0",
|
||||
"concurrently": "^8.2.2",
|
||||
"eslint": "^10.2.1",
|
||||
"eslint-plugin-prettier": "^5.5.5",
|
||||
"globals": "^17.5.0",
|
||||
"husky": "^9.1.7",
|
||||
"lint-staged": "^16.4.0",
|
||||
"postcss": "^8.4.32",
|
||||
"prettier": "^3.5.3",
|
||||
"rollup-plugin-postcss": "^4.0.2"
|
||||
"rollup-plugin-postcss": "^4.0.2",
|
||||
"typescript": "^6.0.3",
|
||||
"typescript-eslint": "^8.60.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/runtime": {
|
||||
|
|
@ -158,6 +160,27 @@
|
|||
"node": "^20.19.0 || ^22.13.0 || >=24"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/js": {
|
||||
"version": "10.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-10.0.1.tgz",
|
||||
"integrity": "sha512-zeR9k5pd4gxjZ0abRoIaxdc7I3nDktoXZk2qOv9gCNWx3mVwEn32VRhyLaRsDiJjTs0xq/T8mfPtyuXu7GWBcA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^20.19.0 || ^22.13.0 || >=24"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://eslint.org/donate"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^10.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"eslint": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/object-schema": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-3.0.5.tgz",
|
||||
|
|
@ -420,19 +443,6 @@
|
|||
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@pkgr/core": {
|
||||
"version": "0.2.9",
|
||||
"resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz",
|
||||
"integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.18.0 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/pkgr"
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/plugin-commonjs": {
|
||||
"version": "25.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.8.tgz",
|
||||
|
|
@ -761,6 +771,58 @@
|
|||
"util": "^0.12.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@stylistic/eslint-plugin": {
|
||||
"version": "5.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.10.0.tgz",
|
||||
"integrity": "sha512-nPK52ZHvot8Ju/0A4ucSX1dcPV2/1clx0kLcH5wDmrE4naKso7TUC/voUyU1O9OTKTrR6MYip6LP0ogEMQ9jPQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.9.1",
|
||||
"@typescript-eslint/types": "^8.56.0",
|
||||
"eslint-visitor-keys": "^4.2.1",
|
||||
"espree": "^10.4.0",
|
||||
"estraverse": "^5.3.0",
|
||||
"picomatch": "^4.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^9.0.0 || ^10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@stylistic/eslint-plugin/node_modules/eslint-visitor-keys": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
|
||||
"integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@stylistic/eslint-plugin/node_modules/espree": {
|
||||
"version": "10.4.0",
|
||||
"resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
|
||||
"integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
"acorn": "^8.15.0",
|
||||
"acorn-jsx": "^5.3.2",
|
||||
"eslint-visitor-keys": "^4.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@trysound/sax": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
|
||||
|
|
@ -795,6 +857,288 @@
|
|||
"integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||
"version": "8.60.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.60.1.tgz",
|
||||
"integrity": "sha512-JQ4S5GB0tfjO8BuJ4fcX+HodkzJjYBV+7OJ+wLygaX7OGQ7FudyHL4NSCA6ob+w3Yn+5MkKIozOwQhXeM7opVg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@eslint-community/regexpp": "^4.12.2",
|
||||
"@typescript-eslint/scope-manager": "8.60.1",
|
||||
"@typescript-eslint/type-utils": "8.60.1",
|
||||
"@typescript-eslint/utils": "8.60.1",
|
||||
"@typescript-eslint/visitor-keys": "8.60.1",
|
||||
"ignore": "^7.0.5",
|
||||
"natural-compare": "^1.4.0",
|
||||
"ts-api-utils": "^2.5.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@typescript-eslint/parser": "^8.60.1",
|
||||
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
|
||||
"typescript": ">=4.8.4 <6.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": {
|
||||
"version": "7.0.5",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
|
||||
"integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser": {
|
||||
"version": "8.60.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.60.1.tgz",
|
||||
"integrity": "sha512-A0M6ua6H252bVjPvvtSgl2QA4+ET9S5Mtkb2GDyTxIhH/C4qDItT7RQNO5PhMC6NXGYXOR9dIalcDDgBKT7oFA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "8.60.1",
|
||||
"@typescript-eslint/types": "8.60.1",
|
||||
"@typescript-eslint/typescript-estree": "8.60.1",
|
||||
"@typescript-eslint/visitor-keys": "8.60.1",
|
||||
"debug": "^4.4.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
|
||||
"typescript": ">=4.8.4 <6.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/project-service": {
|
||||
"version": "8.60.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.60.1.tgz",
|
||||
"integrity": "sha512-eXkTH2bxmXlqD1RnOPmLZ9ZM9D3VwSx04JOwBnP9RQ+yUA5a2Mu7SfW8uaV2Aon53NJzZlZYuX7tn91Izf+xaw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/tsconfig-utils": "^8.60.1",
|
||||
"@typescript-eslint/types": "^8.60.1",
|
||||
"debug": "^4.4.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=4.8.4 <6.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/scope-manager": {
|
||||
"version": "8.60.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.60.1.tgz",
|
||||
"integrity": "sha512-gvI5OQoptnxQnchOirukCuQ55svJSTuD/4k5+pC267xyBtYry748R9/c3tYUzb/iE6RZfllRz2lVulLCHkTm4w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "8.60.1",
|
||||
"@typescript-eslint/visitor-keys": "8.60.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/tsconfig-utils": {
|
||||
"version": "8.60.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.60.1.tgz",
|
||||
"integrity": "sha512-nh8w4qAteiKuZu3pSSzG/yGKpw0OlkrKnzFmbVRenKaD4qc+7i1GrmZaLVkr8rk4uipiPGMOW4YsM6WmKZ5CvA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=4.8.4 <6.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/type-utils": {
|
||||
"version": "8.60.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.60.1.tgz",
|
||||
"integrity": "sha512-sdwTrpjosW7ANQYJ39ZBF1ZyEMEGVB2UsikrserVM/30a/F1dTLnu9bGxEdosugyu5caigjLrR2qiD11asjI1A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "8.60.1",
|
||||
"@typescript-eslint/typescript-estree": "8.60.1",
|
||||
"@typescript-eslint/utils": "8.60.1",
|
||||
"debug": "^4.4.3",
|
||||
"ts-api-utils": "^2.5.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
|
||||
"typescript": ">=4.8.4 <6.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/types": {
|
||||
"version": "8.60.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.60.1.tgz",
|
||||
"integrity": "sha512-4h0tY8ppCkdCzcrl2YM5M3my0xsE1Tf8om3owEu5oPWmXwkKRmk0j0LGDzYBGUcAlesEbxBhazqu/K4cu3Ug7w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree": {
|
||||
"version": "8.60.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.60.1.tgz",
|
||||
"integrity": "sha512-alpRkfG8hlVE5kdJW2GkfgDgXxold3e8e4l6EnmhRmRLbekgAPCCGDVD++sABy9FcgPFroq+uFcCSM1vR57Cew==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/project-service": "8.60.1",
|
||||
"@typescript-eslint/tsconfig-utils": "8.60.1",
|
||||
"@typescript-eslint/types": "8.60.1",
|
||||
"@typescript-eslint/visitor-keys": "8.60.1",
|
||||
"debug": "^4.4.3",
|
||||
"minimatch": "^10.2.2",
|
||||
"semver": "^7.7.3",
|
||||
"tinyglobby": "^0.2.15",
|
||||
"ts-api-utils": "^2.5.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=4.8.4 <6.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
|
||||
"integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "18 || 20 || >=22"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
|
||||
"version": "5.0.6",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.6.tgz",
|
||||
"integrity": "sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^4.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "18 || 20 || >=22"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
|
||||
"version": "10.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz",
|
||||
"integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==",
|
||||
"dev": true,
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^5.0.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": "18 || 20 || >=22"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/semver": {
|
||||
"version": "7.8.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.8.2.tgz",
|
||||
"integrity": "sha512-c8jsqUZm3omBOI66G90z1Dyw5z622G8oLG+omfsHBJf3CWQTlOcwOjvOG6wtiNfW6anKm/eA39LMwMtMez2TiQ==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/utils": {
|
||||
"version": "8.60.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.60.1.tgz",
|
||||
"integrity": "sha512-h2MPBLoNtjc3qZWfY3Tl51yPorQ2McHn8pJfcMNTcIvrrZrr90Ykffit0yjrPFWQcRcUxzH20+6OcVdW4yHtUg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.9.1",
|
||||
"@typescript-eslint/scope-manager": "8.60.1",
|
||||
"@typescript-eslint/types": "8.60.1",
|
||||
"@typescript-eslint/typescript-estree": "8.60.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
|
||||
"typescript": ">=4.8.4 <6.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/visitor-keys": {
|
||||
"version": "8.60.1",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.60.1.tgz",
|
||||
"integrity": "sha512-EbGRQg4FhrmwLodl+t3JNAnXHWVr9Vp+Zl1QBZVPY4ByfkzIT8cX3K6QWODHtkIZqqJVEWvhHSx3v5PDHsaQag==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "8.60.1",
|
||||
"eslint-visitor-keys": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
}
|
||||
},
|
||||
"node_modules/@yaireo/tagify": {
|
||||
"version": "4.35.1",
|
||||
"resolved": "https://registry.npmjs.org/@yaireo/tagify/-/tagify-4.35.1.tgz",
|
||||
|
|
@ -1853,10 +2197,11 @@
|
|||
}
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "4.4.1",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
|
||||
"integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
|
||||
"version": "4.4.3",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
||||
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "^2.1.3"
|
||||
},
|
||||
|
|
@ -2241,37 +2586,6 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-plugin-prettier": {
|
||||
"version": "5.5.5",
|
||||
"resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.5.5.tgz",
|
||||
"integrity": "sha512-hscXkbqUZ2sPithAuLm5MXL+Wph+U7wHngPBv9OMWwlP8iaflyxpjTYZkmdgB4/vPIhemRlBEoLrH7UC1n7aUw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prettier-linter-helpers": "^1.0.1",
|
||||
"synckit": "^0.11.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.18.0 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/eslint-plugin-prettier"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/eslint": ">=8.0.0",
|
||||
"eslint": ">=8.0.0",
|
||||
"eslint-config-prettier": ">= 7.0.0 <10.0.0 || >=10.1.0",
|
||||
"prettier": ">=3.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/eslint": {
|
||||
"optional": true
|
||||
},
|
||||
"eslint-config-prettier": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-scope": {
|
||||
"version": "9.1.2",
|
||||
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-9.1.2.tgz",
|
||||
|
|
@ -2511,13 +2825,6 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fast-diff": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz",
|
||||
"integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/fast-fifo": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",
|
||||
|
|
@ -2554,6 +2861,24 @@
|
|||
"reusify": "^1.0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/fdir": {
|
||||
"version": "6.5.0",
|
||||
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
|
||||
"integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"picomatch": "^3 || ^4"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"picomatch": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/file-entry-cache": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
|
||||
|
|
@ -5217,34 +5542,6 @@
|
|||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.3.tgz",
|
||||
"integrity": "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"prettier": "bin/prettier.cjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/prettier-linter-helpers": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.1.tgz",
|
||||
"integrity": "sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fast-diff": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/process-nextick-args": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
|
|
@ -6053,22 +6350,6 @@
|
|||
"node": ">= 10"
|
||||
}
|
||||
},
|
||||
"node_modules/synckit": {
|
||||
"version": "0.11.12",
|
||||
"resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.12.tgz",
|
||||
"integrity": "sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@pkgr/core": "^0.2.9"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.18.0 || >=16.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/synckit"
|
||||
}
|
||||
},
|
||||
"node_modules/teex": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz",
|
||||
|
|
@ -6116,6 +6397,23 @@
|
|||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/tinyglobby": {
|
||||
"version": "0.2.17",
|
||||
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz",
|
||||
"integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fdir": "^6.5.0",
|
||||
"picomatch": "^4.0.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/SuperchupuDev"
|
||||
}
|
||||
},
|
||||
"node_modules/to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
|
|
@ -6147,6 +6445,19 @@
|
|||
"tree-kill": "cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-api-utils": {
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz",
|
||||
"integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18.12"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": ">=4.8.4"
|
||||
}
|
||||
},
|
||||
"node_modules/tslib": {
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||
|
|
@ -6171,6 +6482,44 @@
|
|||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "6.0.3",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz",
|
||||
"integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"tsc": "bin/tsc",
|
||||
"tsserver": "bin/tsserver"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/typescript-eslint": {
|
||||
"version": "8.60.1",
|
||||
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.60.1.tgz",
|
||||
"integrity": "sha512-6m5hkkRAp8lKvhVpcprAIn5KkehQEh+47oHH2VGnExEh7dhNxXlg6GPAOIu6TxbVQxhebrJDvjl3020ooiWCMA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/eslint-plugin": "8.60.1",
|
||||
"@typescript-eslint/parser": "8.60.1",
|
||||
"@typescript-eslint/typescript-estree": "8.60.1",
|
||||
"@typescript-eslint/utils": "8.60.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
|
||||
"typescript": ">=4.8.4 <6.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/unc-path-regex": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
|
||||
|
|
|
|||
|
|
@ -18,24 +18,25 @@
|
|||
"pullYMLtoLDB": "node ./tools/pullYMLtoLDB.mjs",
|
||||
"pullYMLtoLDBBuild": "node ./tools/pullYMLtoLDB.mjs --build",
|
||||
"createSymlink": "node ./tools/create-symlink.mjs",
|
||||
"setup:dev": "node ./tools/dev-setup.mjs",
|
||||
"lint": "eslint",
|
||||
"lint:fix": "eslint --fix",
|
||||
"prepare": "husky"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^10.0.1",
|
||||
"@foundryvtt/foundryvtt-cli": "^1.0.2",
|
||||
"@rollup/plugin-commonjs": "^25.0.7",
|
||||
"@rollup/plugin-node-resolve": "^15.2.3",
|
||||
"@stylistic/eslint-plugin": "^5.10.0",
|
||||
"concurrently": "^8.2.2",
|
||||
"eslint": "^10.2.1",
|
||||
"eslint-plugin-prettier": "^5.5.5",
|
||||
"globals": "^17.5.0",
|
||||
"husky": "^9.1.7",
|
||||
"lint-staged": "^16.4.0",
|
||||
"postcss": "^8.4.32",
|
||||
"prettier": "^3.5.3",
|
||||
"rollup-plugin-postcss": "^4.0.2"
|
||||
"rollup-plugin-postcss": "^4.0.2",
|
||||
"typescript": "^6.0.3",
|
||||
"typescript-eslint": "^8.60.1"
|
||||
},
|
||||
"lint-staged": {
|
||||
"**/*": "eslint --fix"
|
||||
|
|
|
|||
|
|
@ -1,19 +1,11 @@
|
|||
@import './less/sheets/index.less';
|
||||
@import './less/sheets-settings/index.less';
|
||||
|
||||
@import './less/dialog/index.less';
|
||||
|
||||
@import './less//hud/index.less';
|
||||
|
||||
@import './less/utils/colors.less';
|
||||
@import './less/utils/fonts.less';
|
||||
|
||||
@import './less/hud/index.less';
|
||||
@import './less/utils/index.less';
|
||||
@import './less/global/index.less';
|
||||
|
||||
@import './less/ui/index.less';
|
||||
|
||||
@import './less/ux/index.less';
|
||||
|
||||
@import '../build/tagify.css';
|
||||
|
||||
@import './less/utils/mixin.less';
|
||||
|
|
|
|||
1
styles/less/dialog/actions/index.less
Normal file
1
styles/less/dialog/actions/index.less
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import "./action-list.less";
|
||||
1
styles/less/dialog/attribution/index.less
Normal file
1
styles/less/dialog/attribution/index.less
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import "./sheet.less";
|
||||
1
styles/less/dialog/beastform/index.less
Normal file
1
styles/less/dialog/beastform/index.less
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import "./sheet.less";
|
||||
4
styles/less/dialog/character-creation/index.less
Normal file
4
styles/less/dialog/character-creation/index.less
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
@import "./sheet.less";
|
||||
@import "./creation-action-footer.less";
|
||||
@import "./selections-container.less";
|
||||
@import "./tab-navigation.less";
|
||||
1
styles/less/dialog/character-reset/index.less
Normal file
1
styles/less/dialog/character-reset/index.less
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import './sheet.less';
|
||||
|
|
@ -0,0 +1 @@
|
|||
@import './sheet.less';
|
||||
2
styles/less/dialog/damage-reduction/index.less
Normal file
2
styles/less/dialog/damage-reduction/index.less
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
@import './sheets.less';
|
||||
@import './damage-reduction-container.less';
|
||||
1
styles/less/dialog/damage-selection/index.less
Normal file
1
styles/less/dialog/damage-selection/index.less
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import './sheet.less';
|
||||
1
styles/less/dialog/death-move/index.less
Normal file
1
styles/less/dialog/death-move/index.less
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import './death-move-container.less';
|
||||
1
styles/less/dialog/dice-roll/index.less
Normal file
1
styles/less/dialog/dice-roll/index.less
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import './roll-selection.less';
|
||||
1
styles/less/dialog/downtime/index.less
Normal file
1
styles/less/dialog/downtime/index.less
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import './downtime-container.less';
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
h1 {
|
||||
color: @color-text-emphatic;
|
||||
font: 700 var(--font-size-24) var(--dh-font-subtitle);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
header {
|
||||
--bar-color: light-dark(@dark-blue, @golden);
|
||||
color: light-dark(@dark, @beige);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-top: var(--spacer-8);
|
||||
}
|
||||
|
||||
span {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
&:before {
|
||||
content: ' ';
|
||||
flex: 1;
|
||||
height: 1px;
|
||||
background: linear-gradient(90deg, rgba(0, 0, 0, 0) 0%, var(--bar-color) 100%);
|
||||
}
|
||||
|
||||
&:after {
|
||||
content: ' ';
|
||||
flex: 1;
|
||||
height: 1px;
|
||||
background: linear-gradient(90deg, var(--bar-color) 0%, rgba(0, 0, 0, 0) 100%);
|
||||
}
|
||||
}
|
||||
|
||||
img.portrait {
|
||||
border-radius: 50%;
|
||||
border: none;
|
||||
object-fit: cover;
|
||||
object-position: center top;
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
}
|
||||
|
|
@ -1,8 +1,3 @@
|
|||
.daggerheart.dialog.dh-style.views.group-roll-dialog {
|
||||
.window-content {
|
||||
@import "./_common.less";
|
||||
}
|
||||
}
|
||||
|
||||
@import "./initialization.less";
|
||||
@import "./main.less";
|
||||
@import './sheet.less';
|
||||
@import './initialization.less';
|
||||
@import './main.less';
|
||||
|
|
|
|||
48
styles/less/dialog/group-roll-dialog/sheet.less
Normal file
48
styles/less/dialog/group-roll-dialog/sheet.less
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
.daggerheart.dialog.dh-style.views.group-roll-dialog {
|
||||
.window-content {
|
||||
h1 {
|
||||
color: @color-text-emphatic;
|
||||
font: 700 var(--font-size-24) var(--dh-font-subtitle);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
header {
|
||||
--bar-color: light-dark(@dark-blue, @golden);
|
||||
color: light-dark(@dark, @beige);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-top: var(--spacer-8);
|
||||
}
|
||||
|
||||
span {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
&:before {
|
||||
content: ' ';
|
||||
flex: 1;
|
||||
height: 1px;
|
||||
background: linear-gradient(90deg, rgba(0, 0, 0, 0) 0%, var(--bar-color) 100%);
|
||||
}
|
||||
|
||||
&:after {
|
||||
content: ' ';
|
||||
flex: 1;
|
||||
height: 1px;
|
||||
background: linear-gradient(90deg, var(--bar-color) 0%, rgba(0, 0, 0, 0) 100%);
|
||||
}
|
||||
}
|
||||
|
||||
img.portrait {
|
||||
border-radius: 50%;
|
||||
border: none;
|
||||
object-fit: cover;
|
||||
object-position: center top;
|
||||
width: 2.5rem;
|
||||
height: 2.5rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
1
styles/less/dialog/image-select/index.less
Normal file
1
styles/less/dialog/image-select/index.less
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import './sheet.less';
|
||||
|
|
@ -1,42 +1,20 @@
|
|||
@import './attribution/sheet.less';
|
||||
@import './level-up/index.less';
|
||||
|
||||
@import './resource-dice/sheet.less';
|
||||
|
||||
@import './actions/action-list.less';
|
||||
|
||||
@import './damage-selection/sheet.less';
|
||||
|
||||
@import './downtime/downtime-container.less';
|
||||
|
||||
@import './death-move/death-move-container.less';
|
||||
|
||||
@import './beastform/sheet.less';
|
||||
|
||||
@import './character-creation/creation-action-footer.less';
|
||||
@import './character-creation/selections-container.less';
|
||||
@import './character-creation/sheet.less';
|
||||
@import './character-creation/tab-navigation.less';
|
||||
|
||||
@import './dice-roll/roll-selection.less';
|
||||
@import './damage-reduction/damage-reduction-container.less';
|
||||
@import './damage-reduction/sheets.less';
|
||||
|
||||
@import './multiclass-choice/sheet.less';
|
||||
|
||||
@import './tag-team-dialog/initialization.less';
|
||||
@import './tag-team-dialog/sheet.less';
|
||||
|
||||
@import './actions/index.less';
|
||||
@import './attribution/index.less';
|
||||
@import './beastform/index.less';
|
||||
@import './character-creation/index.less';
|
||||
@import './character-reset/index.less';
|
||||
@import './compendiumBrowserPackDialog/index.less';
|
||||
@import './damage-reduction/index.less';
|
||||
@import './damage-selection/index.less';
|
||||
@import './death-move/index.less';
|
||||
@import './dice-roll/index.less';
|
||||
@import './downtime/index.less';
|
||||
@import './group-roll-dialog/index.less';
|
||||
|
||||
@import './image-select/sheet.less';
|
||||
|
||||
@import './item-transfer/sheet.less';
|
||||
|
||||
@import './settings/change-currency-icon.less';
|
||||
|
||||
@import './risk-it-all/sheet.less';
|
||||
|
||||
@import './character-reset/sheet.less';
|
||||
|
||||
@import './compendiumBrowserPackDialog/sheet.less';
|
||||
@import './level-up/index.less';
|
||||
@import './resource-dice/index.less';
|
||||
@import './multiclass-choice/index.less';
|
||||
@import './tag-team-dialog/index.less';
|
||||
@import './image-select/index.less';
|
||||
@import './item-transfer/index.less';
|
||||
@import './settings/index.less';
|
||||
@import './risk-it-all/index.less';
|
||||
1
styles/less/dialog/item-transfer/index.less
Normal file
1
styles/less/dialog/item-transfer/index.less
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import './sheet.less';
|
||||
1
styles/less/dialog/multiclass-choice/index.less
Normal file
1
styles/less/dialog/multiclass-choice/index.less
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import './sheet.less';
|
||||
1
styles/less/dialog/resource-dice/index.less
Normal file
1
styles/less/dialog/resource-dice/index.less
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import './sheet.less';
|
||||
1
styles/less/dialog/risk-it-all/index.less
Normal file
1
styles/less/dialog/risk-it-all/index.less
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import './sheet.less';
|
||||
1
styles/less/dialog/settings/index.less
Normal file
1
styles/less/dialog/settings/index.less
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import './change-currency-icon.less';
|
||||
2
styles/less/dialog/tag-team-dialog/index.less
Normal file
2
styles/less/dialog/tag-team-dialog/index.less
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
@import './sheet.less';
|
||||
@import './initialization.less';
|
||||
|
|
@ -1 +1 @@
|
|||
@import './token-hud/token-hud.less';
|
||||
@import './token-hud/index.less';
|
||||
|
|
|
|||
1
styles/less/hud/token-hud/index.less
Normal file
1
styles/less/hud/token-hud/index.less
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import './token-hud.less';
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
@import './sheet.less';
|
||||
@import './experiences.less';
|
||||
@import './features.less';
|
||||
|
|
@ -0,0 +1 @@
|
|||
@import './sheet.less';
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
@import './adversaries.less';
|
||||
@import './features.less';
|
||||
|
|
@ -1,8 +1,4 @@
|
|||
@import './header.less';
|
||||
@import './adversary-settings/sheet.less';
|
||||
@import './adversary-settings/experiences.less';
|
||||
@import './adversary-settings/features.less';
|
||||
@import './character-settings/sheet.less';
|
||||
|
||||
@import './environment-settings/features.less';
|
||||
@import './environment-settings/adversaries.less';
|
||||
@import './adversary-settings/index.less';
|
||||
@import './character-settings/index.less';
|
||||
@import './environment-settings/index.less';
|
||||
|
|
|
|||
1
styles/less/sheets/actions/index.less
Normal file
1
styles/less/sheets/actions/index.less
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import './actions.less';
|
||||
1
styles/less/sheets/activeEffects/index.less
Normal file
1
styles/less/sheets/activeEffects/index.less
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import './activeEffects.less';
|
||||
7
styles/less/sheets/actors/index.less
Normal file
7
styles/less/sheets/actors/index.less
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
@import './actor-sheet-shared.less';
|
||||
@import './adversary/index.less';
|
||||
@import './character/index.less';
|
||||
@import './companion/index.less';
|
||||
@import './environment/index.less';
|
||||
@import './npc/index.less';
|
||||
@import './party/index.less';
|
||||
|
|
@ -1,22 +1,5 @@
|
|||
@import './actions/actions.less';
|
||||
|
||||
@import './actors/actor-sheet-shared.less';
|
||||
|
||||
@import './actors/adversary/index.less';
|
||||
@import './actors/character/index.less';
|
||||
@import './actors/companion/index.less';
|
||||
@import './actors/environment/index.less';
|
||||
@import './actors/npc/index.less';
|
||||
@import './actors/party/index.less';
|
||||
|
||||
@import './items/beastform.less';
|
||||
@import './items/class.less';
|
||||
@import './items/domain-card.less';
|
||||
@import './items/feature.less';
|
||||
@import './items/heritage.less';
|
||||
@import './items/item-sheet-shared.less';
|
||||
|
||||
@import './rollTables/sheet.less';
|
||||
@import './actions/actions.less';
|
||||
|
||||
@import './activeEffects/activeEffects.less';
|
||||
@import './activeEffects/index.less';
|
||||
@import './actions/index.less';
|
||||
@import './actors/index.less';
|
||||
@import './items/index.less';
|
||||
@import './rollTables/index.less';
|
||||
6
styles/less/sheets/items/index.less
Normal file
6
styles/less/sheets/items/index.less
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
@import './beastform.less';
|
||||
@import './class.less';
|
||||
@import './domain-card.less';
|
||||
@import './feature.less';
|
||||
@import './heritage.less';
|
||||
@import './item-sheet-shared.less';
|
||||
1
styles/less/sheets/rollTables/index.less
Normal file
1
styles/less/sheets/rollTables/index.less
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import './sheet.less';
|
||||
10
styles/less/ui/chat/index.less
Normal file
10
styles/less/ui/chat/index.less
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
@import './sheet.less';
|
||||
@import './ability-use.less';
|
||||
@import './action.less';
|
||||
@import './chat.less';
|
||||
@import './damage-summary.less';
|
||||
@import './deathmoves.less';
|
||||
@import './downtime.less';
|
||||
@import './effect-summary.less';
|
||||
@import './group-roll.less';
|
||||
@import './refresh-message.less';
|
||||
5
styles/less/ui/combat-sidebar/index.less
Normal file
5
styles/less/ui/combat-sidebar/index.less
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
@import './combat-sidebar.less';
|
||||
@import './combatant-controls.less';
|
||||
@import './encounter-controls.less';
|
||||
@import './spotlight-control.less';
|
||||
@import './token-actions.less';
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
border: 0;
|
||||
box-shadow: none;
|
||||
color: @color-text-primary;
|
||||
width: 300px;
|
||||
width: 18.75rem;
|
||||
pointer-events: all;
|
||||
align-self: flex-end;
|
||||
transition: 0.3s right ease-in-out;
|
||||
|
|
@ -36,7 +36,7 @@
|
|||
transition: opacity var(--ui-fade-duration);
|
||||
}
|
||||
|
||||
:not(.performance-low, .noblur) {
|
||||
&:not(.performance-low, .noblur) {
|
||||
backdrop-filter: blur(5px);
|
||||
}
|
||||
|
||||
|
|
@ -49,8 +49,7 @@
|
|||
}
|
||||
|
||||
&.icon-only {
|
||||
width: 180px;
|
||||
min-width: 180px;
|
||||
width: 12rem;
|
||||
}
|
||||
|
||||
.countdowns-header,
|
||||
|
|
@ -108,8 +107,8 @@
|
|||
gap: 16px;
|
||||
|
||||
img {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
width: 2.75rem;
|
||||
height: 2.75rem;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
|
|
@ -127,7 +126,7 @@
|
|||
.countdown-tool-controls {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
gap: var(--spacer-12);
|
||||
}
|
||||
|
||||
.progress-tag {
|
||||
|
|
|
|||
3
styles/less/ui/countdown/index.less
Normal file
3
styles/less/ui/countdown/index.less
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
@import './sheet.less';
|
||||
@import './countdown-edit.less';
|
||||
@import './countdown.less';
|
||||
1
styles/less/ui/effects-display/index.less
Normal file
1
styles/less/ui/effects-display/index.less
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import './sheet.less';
|
||||
|
|
@ -1,40 +1,11 @@
|
|||
@import './chat/ability-use.less';
|
||||
@import './chat/action.less';
|
||||
@import './chat/chat.less';
|
||||
@import './chat/damage-summary.less';
|
||||
@import './chat/downtime.less';
|
||||
@import './chat/effect-summary.less';
|
||||
@import './chat/group-roll.less';
|
||||
@import './chat/refresh-message.less';
|
||||
@import './chat/deathmoves.less';
|
||||
@import './chat/sheet.less';
|
||||
|
||||
@import './combat-sidebar/combat-sidebar.less';
|
||||
@import './combat-sidebar/combatant-controls.less';
|
||||
@import './combat-sidebar/encounter-controls.less';
|
||||
@import './combat-sidebar/spotlight-control.less';
|
||||
@import './combat-sidebar/token-actions.less';
|
||||
@import './item-browser/item-browser.less';
|
||||
|
||||
@import './countdown/countdown.less';
|
||||
@import './countdown/countdown-edit.less';
|
||||
@import './countdown/sheet.less';
|
||||
|
||||
@import './ownership-selection/ownership-selection.less';
|
||||
|
||||
@import './resources/resources.less';
|
||||
|
||||
@import './settings/settings.less';
|
||||
@import './settings/homebrew-settings/domains.less';
|
||||
@import './settings/homebrew-settings/types.less';
|
||||
@import './settings/homebrew-settings/resources.less';
|
||||
@import './settings/appearance-settings/diceSoNice.less';
|
||||
|
||||
@import './sidebar/tabs.less';
|
||||
@import './sidebar/daggerheartMenu.less';
|
||||
|
||||
@import './scene-config/scene-config.less';
|
||||
|
||||
@import './effects-display/sheet.less';
|
||||
|
||||
@import './scene-navigation/scene-navigation.less';
|
||||
@import './chat/index.less';
|
||||
@import './combat-sidebar/index.less';
|
||||
@import './countdown/index.less';
|
||||
@import './effects-display/index.less';
|
||||
@import './item-browser/index.less';
|
||||
@import './ownership-selection/index.less';
|
||||
@import './resources/index.less';
|
||||
@import './scene-config/index.less';
|
||||
@import './scene-navigation/index.less';
|
||||
@import './settings/index.less';
|
||||
@import './sidebar/index.less';
|
||||
1
styles/less/ui/item-browser/index.less
Normal file
1
styles/less/ui/item-browser/index.less
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import './item-browser.less';
|
||||
1
styles/less/ui/ownership-selection/index.less
Normal file
1
styles/less/ui/ownership-selection/index.less
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import './ownership-selection.less';
|
||||
1
styles/less/ui/resources/index.less
Normal file
1
styles/less/ui/resources/index.less
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import './resources.less';
|
||||
1
styles/less/ui/scene-config/index.less
Normal file
1
styles/less/ui/scene-config/index.less
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import './scene-config.less';
|
||||
1
styles/less/ui/scene-navigation/index.less
Normal file
1
styles/less/ui/scene-navigation/index.less
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import './scene-navigation.less';
|
||||
1
styles/less/ui/settings/appearance-settings/index.less
Normal file
1
styles/less/ui/settings/appearance-settings/index.less
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import './diceSoNice.less';
|
||||
3
styles/less/ui/settings/homebrew-settings/index.less
Normal file
3
styles/less/ui/settings/homebrew-settings/index.less
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
@import './domains.less';
|
||||
@import './resources.less';
|
||||
@import './types.less';
|
||||
3
styles/less/ui/settings/index.less
Normal file
3
styles/less/ui/settings/index.less
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
@import './settings.less';
|
||||
@import './appearance-settings/index.less';
|
||||
@import './homebrew-settings/index.less';
|
||||
2
styles/less/ui/sidebar/index.less
Normal file
2
styles/less/ui/sidebar/index.less
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
@import './daggerheartMenu.less';
|
||||
@import './tabs.less';
|
||||
4
styles/less/utils/index.less
Normal file
4
styles/less/utils/index.less
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
@import './colors.less';
|
||||
@import './fonts.less';
|
||||
@import './mixin.less';
|
||||
@import './spacing.less';
|
||||
1
styles/less/ux/autocomplete/index.less
Normal file
1
styles/less/ux/autocomplete/index.less
Normal file
|
|
@ -0,0 +1 @@
|
|||
@import './autocomplete.less';
|
||||
|
|
@ -1,10 +1,2 @@
|
|||
@import './tooltip/sheet.less';
|
||||
@import './tooltip/tooltip.less';
|
||||
@import './tooltip/armorManagement.less';
|
||||
@import './tooltip/battlepoints.less';
|
||||
@import './tooltip/bordered-tooltip.less';
|
||||
@import './tooltip/domain-cards.less';
|
||||
|
||||
@import './autocomplete/autocomplete.less';
|
||||
|
||||
@import './tooltip/resource-management.less';
|
||||
@import './autocomplete/index.less';
|
||||
@import './tooltip/index.less';
|
||||
7
styles/less/ux/tooltip/index.less
Normal file
7
styles/less/ux/tooltip/index.less
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
@import './sheet.less';
|
||||
@import './armorManagement.less';
|
||||
@import './battlepoints.less';
|
||||
@import './bordered-tooltip.less';
|
||||
@import './domain-cards.less';
|
||||
@import './resource-management.less';
|
||||
@import './tooltip.less';
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
"id": "daggerheart",
|
||||
"title": "Daggerheart",
|
||||
"description": "An unofficial implementation of the Daggerheart system",
|
||||
"version": "2.3.1",
|
||||
"version": "2.3.2",
|
||||
"compatibility": {
|
||||
"minimum": "14.361",
|
||||
"verified": "14.363",
|
||||
|
|
@ -10,7 +10,7 @@
|
|||
},
|
||||
"url": "https://github.com/Foundryborne/daggerheart",
|
||||
"manifest": "https://raw.githubusercontent.com/Foundryborne/daggerheart/v14/system.json",
|
||||
"download": "https://github.com/Foundryborne/daggerheart/releases/download/2.3.1/system.zip",
|
||||
"download": "https://github.com/Foundryborne/daggerheart/releases/download/2.3.2/system.zip",
|
||||
"authors": [
|
||||
{
|
||||
"name": "WBHarry"
|
||||
|
|
|
|||
|
|
@ -2,27 +2,31 @@
|
|||
<header class="countdowns-header">
|
||||
<i class="fa-solid fa-clock-rotate-left" inert></i>
|
||||
<span class="window-title">{{localize "DAGGERHEART.UI.Countdowns.title"}}</span>
|
||||
{{#if isGM}}
|
||||
<a class="header-control" data-tooltip aria-label="DAGGERHEART.APPLICATIONS.CountdownEdit.editTitle" data-action="editCountdowns">
|
||||
<i class="fa-solid fa-wrench" inert></i>
|
||||
</a>
|
||||
{{/if}}
|
||||
<a class="header-control" data-tooltip aria-label="DAGGERHEART.UI.Countdowns.toggleIconMode" data-action="toggleViewMode">
|
||||
<i class="fa-solid fa-down-left-and-up-right-to-center" inert></i>
|
||||
</a>
|
||||
</header>
|
||||
<div class="countdowns-container">
|
||||
{{#each countdowns as | countdown id |}}
|
||||
<div class="countdown-container {{#if ../iconOnly}}icon-only{{/if}}">
|
||||
<div class="countdown-container {{#if ../iconOnly}}icon-only{{/if}}" data-countdown="{{id}}">
|
||||
<div class="countdown-main-container">
|
||||
<img src="{{countdown.img}}" {{#if ../iconOnly}}data-tooltip="{{countdown.name}}"{{/if}}/>
|
||||
<div class="countdown-content">
|
||||
{{#unless ../iconOnly}}<label>{{countdown.name}}</label>{{/unless}}
|
||||
{{#unless ../iconOnly}}
|
||||
<header>{{countdown.name}}</header>
|
||||
{{/unless}}
|
||||
<div class="countdown-tools">
|
||||
<div class="countdown-tool-controls">
|
||||
{{#if countdown.editable}}<a data-action="decreaseCountdown" id="{{id}}"><i class="fa-solid fa-minus"></i></a>{{/if}}
|
||||
{{#if countdown.editable}}<a data-action="decreaseCountdown"><i class="fa-solid fa-minus"></i></a>{{/if}}
|
||||
<div class="progress-tag">
|
||||
{{countdown.progress.current}}/{{countdown.progress.start}}
|
||||
</div>
|
||||
{{#if countdown.editable}}<a data-action="increaseCountdown" id="{{id}}"><i class="fa-solid fa-plus"></i></a>{{/if}}
|
||||
{{#if countdown.editable}}<a data-action="increaseCountdown"><i class="fa-solid fa-plus"></i></a>{{/if}}
|
||||
</div>
|
||||
<div class="countdown-tool-icons">
|
||||
{{#if (not ../iconOnly)}}
|
||||
|
|
@ -31,7 +35,7 @@
|
|||
{{/if}}
|
||||
{{#unless (eq countdown.progress.looping "noLooping")}}
|
||||
<span data-tooltip="{{countdown.loopTooltip}}">
|
||||
<a class="looping-container {{#if countdown.shouldLoop}}should-loop{{/if}}" {{#if countdown.loopDisabled}}disabled{{/if}} data-action="loopCountdown" id="{{id}}">
|
||||
<a class="looping-container {{#if countdown.shouldLoop}}should-loop{{/if}}" {{#if countdown.loopDisabled}}disabled{{/if}} data-action="loopCountdown">
|
||||
<i class="loop-marker fa-solid fa-repeat"></i>
|
||||
{{#if (eq countdown.progress.looping "increasing")}}
|
||||
<i class="direction-marker fa-solid fa-angles-up" data-tooltip="{{localize "DAGGERHEART.UI.Countdowns.increasingLoop"}}"></i>
|
||||
|
|
|
|||
|
|
@ -82,7 +82,7 @@ function getMean(numbers) {
|
|||
}
|
||||
|
||||
function getMedianAverageDeviation(numbers, { median }) {
|
||||
const residuals = allDamage.map(d => Math.abs(d - median));
|
||||
const residuals = numbers.map(d => Math.abs(d - median));
|
||||
return getMedian(residuals);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,45 +1,70 @@
|
|||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import readline from 'readline';
|
||||
import { isContainedPath, readEnvFile } from './util.mjs';
|
||||
|
||||
const askQuestion = question => {
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout
|
||||
});
|
||||
const projectRoot = path.resolve(import.meta.dirname, '../')
|
||||
const { foundryRoot, dataPath } = readEnvFile();
|
||||
|
||||
return new Promise(resolve =>
|
||||
rl.question(question, answer => {
|
||||
rl.close();
|
||||
resolve(answer);
|
||||
})
|
||||
);
|
||||
};
|
||||
async function createFoundrySymlink() {
|
||||
// If foundry already exists, exit and inform the user. This operation can't complete correctly otherwise.
|
||||
// If the folder is empty, its fine. It may have failed due to perms
|
||||
const foundryDestPath = path.join(projectRoot, 'foundry');
|
||||
if (fs.existsSync(foundryDestPath) && fs.readdirSync(foundryDestPath).length) {
|
||||
console.log('"foundry" folder already exists in this project');
|
||||
return;
|
||||
}
|
||||
|
||||
const installPath = await askQuestion('Enter your Foundry install path: ');
|
||||
|
||||
// Determine if it's an Electron install (nested structure)
|
||||
const nested = fs.existsSync(path.join(installPath, 'resources', 'app'));
|
||||
const fileRoot = nested ? path.join(installPath, 'resources', 'app') : installPath;
|
||||
|
||||
try {
|
||||
await fs.promises.mkdir('foundry');
|
||||
} catch (e) {
|
||||
if (e.code !== 'EEXIST') throw e;
|
||||
}
|
||||
|
||||
// JavaScript files
|
||||
for (const p of ['client', 'common', 'tsconfig.json']) {
|
||||
console.log('Creating "foundry" symlinks for types');
|
||||
try {
|
||||
await fs.promises.symlink(path.join(fileRoot, p), path.join('foundry', p));
|
||||
await fs.promises.mkdir(foundryDestPath);
|
||||
console.log('Root foundry folder created');
|
||||
} catch (e) {
|
||||
if (e.code !== 'EEXIST') throw e;
|
||||
}
|
||||
|
||||
// JavaScript files
|
||||
for (const p of ['client', 'common', 'tsconfig.json']) {
|
||||
try {
|
||||
await fs.promises.symlink(path.join(foundryRoot, p), path.join(foundryDestPath, p));
|
||||
console.log(`${p} folder created`);
|
||||
} catch (e) {
|
||||
if (e.code !== 'EEXIST') throw e;
|
||||
}
|
||||
}
|
||||
|
||||
// Language files
|
||||
try {
|
||||
await fs.promises.symlink(path.join(foundryRoot, 'public', 'lang'), path.join(foundryDestPath, 'lang'));
|
||||
console.log(`lang folder created`);
|
||||
} catch (e) {
|
||||
if (e.code !== 'EEXIST') throw e;
|
||||
console.log(`lang folder already exists`);
|
||||
}
|
||||
}
|
||||
|
||||
// Language files
|
||||
try {
|
||||
await fs.promises.symlink(path.join(fileRoot, 'public', 'lang'), path.join('foundry', 'lang'));
|
||||
} catch (e) {
|
||||
async function createDaggerheartSymlink() {
|
||||
if (isContainedPath(dataPath, projectRoot)) {
|
||||
console.log('The Daggerheart project repo is in foundry data, so a symlink won\'t be created');
|
||||
return;
|
||||
}
|
||||
|
||||
const destination = path.join(dataPath, 'Data', 'systems', 'daggerheart');
|
||||
if (fs.existsSync(destination)) {
|
||||
console.log('A Daggerheart folder already exists in Foundry data');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('Creating Daggerheart symlink in the foundry systems folder')
|
||||
try {
|
||||
await fs.promises.symlink(projectRoot, destination);
|
||||
console.log('Daggerheart system folder symlink created');
|
||||
} catch (e) {
|
||||
if (e.code !== 'EEXIST') throw e;
|
||||
console.log(`Daggerheart system folder already exists`);
|
||||
}
|
||||
}
|
||||
|
||||
await createFoundrySymlink();
|
||||
console.log(); // Add empty newline
|
||||
await createDaggerheartSymlink();
|
||||
|
|
|
|||
|
|
@ -1,18 +0,0 @@
|
|||
#!/usr/bin/env node
|
||||
import fs from 'fs';
|
||||
|
||||
const args = process.argv.slice(2);
|
||||
const foundryPath = args.find(arg => arg.startsWith('--foundry-path='))?.split('=')[1];
|
||||
const dataPath = args.find(arg => arg.startsWith('--data-path='))?.split('=')[1];
|
||||
|
||||
if (!foundryPath || !dataPath) {
|
||||
console.log('Usage: npm run setup:dev -- --foundry-path="/path/to/foundry/main.js" --data-path="/path/to/data"');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const envContent = `FOUNDRY_MAIN_PATH=${foundryPath}
|
||||
FOUNDRY_DATA_PATH=${dataPath}
|
||||
`;
|
||||
|
||||
fs.writeFileSync('.env', envContent);
|
||||
console.log(`✅ Development environment configured: ${foundryPath}, ${dataPath}`);
|
||||
20
tools/eslint.config.mjs
Normal file
20
tools/eslint.config.mjs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import globals from 'globals';
|
||||
import { defineConfig, globalIgnores } from 'eslint/config';
|
||||
import { stylisticRules } from '../eslint.config.mjs';
|
||||
import stylistic from '@stylistic/eslint-plugin';
|
||||
|
||||
export default defineConfig([
|
||||
globalIgnores(['foundry/**/*']),
|
||||
{
|
||||
files: ['**/*.{js,mjs,cjs}'],
|
||||
plugins: {
|
||||
'@stylistic': stylistic
|
||||
},
|
||||
languageOptions: { globals: globals.node },
|
||||
rules: {
|
||||
'no-undef': 'error',
|
||||
'no-unused-vars': 0,
|
||||
...stylisticRules
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
|
@ -1,21 +1,10 @@
|
|||
#!/usr/bin/env node
|
||||
import { spawn } from 'child_process';
|
||||
import { readEnvFile } from './util.mjs';
|
||||
import fs from 'fs';
|
||||
|
||||
// Load .env file if it exists
|
||||
if (fs.existsSync('.env')) {
|
||||
const envFile = fs.readFileSync('.env', 'utf8');
|
||||
envFile.split('\n').forEach(line => {
|
||||
const [key, value] = line.split('=');
|
||||
if (key && value) {
|
||||
process.env[key] = value;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Set defaults if not in environment
|
||||
const foundryPath = process.env.FOUNDRY_MAIN_PATH || '../../../../FoundryDev/main.js';
|
||||
const dataPath = process.env.FOUNDRY_DATA_PATH || '../../../';
|
||||
// Load .env file params
|
||||
const { foundryPath, dataPath } = readEnvFile();
|
||||
|
||||
// Run the original command with proper environment
|
||||
const args = ['rollup -c --watch', `node "\"${foundryPath}\"" --dataPath="${dataPath}" --noupnp`, 'gulp'];
|
||||
|
|
|
|||
39
tools/util.mjs
Normal file
39
tools/util.mjs
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
export function readEnvFile() {
|
||||
if (!fs.existsSync('.env')) {
|
||||
console.error('No configured .env file. Copy .env.example to .env and configure it.');
|
||||
process.exit();
|
||||
}
|
||||
|
||||
const envFile = fs.readFileSync('.env', 'utf8');
|
||||
envFile.split('\n').forEach(line => {
|
||||
const [key, value] = line.split('=');
|
||||
if (key && value) {
|
||||
process.env[key] = value;
|
||||
}
|
||||
});
|
||||
|
||||
// Determine foundry path, handling if its an electron install (nested structure)
|
||||
const foundryPath = path.normalize(process.env.FOUNDRY_MAIN_PATH);
|
||||
const dataPath = path.normalize(process.env.FOUNDRY_DATA_PATH);
|
||||
if (!foundryPath.endsWith(path.join('app', 'main.js'))) {
|
||||
console.error('Configured FOUNDRY_MAIN_PATH is invalid, it must end with app/main.js');
|
||||
process.exit();
|
||||
}
|
||||
if (/Data(\/|\\)?$/.test(dataPath) || !fs.existsSync(path.join(dataPath, 'Data'))) {
|
||||
console.error('Configured FOUNDRY_DATA_PATH is incorrect. This must be a folder that contains "Data"');
|
||||
}
|
||||
|
||||
return {
|
||||
foundryPath,
|
||||
foundryRoot: path.dirname(foundryPath),
|
||||
dataPath
|
||||
};
|
||||
}
|
||||
|
||||
export function isContainedPath(parent, child) {
|
||||
const relative = path.relative(parent, child);
|
||||
return relative && !relative.startsWith('..') && !path.isAbsolute(relative);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue