intelligent-system-design-language 0.3.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/agents/langium-language-designer.md +38 -0
- package/.claude/agents/typescript-vscode-expert.md +29 -0
- package/.claude/agents/ui-ux-designer.md +36 -0
- package/.claude/settings.local.json +33 -0
- package/.idea/inspectionProfiles/Project_Default.xml +7 -0
- package/.idea/isdl.iml +14 -0
- package/.idea/modules.xml +9 -0
- package/.idea/vcs.xml +7 -0
- package/.idea/watcherTasks.xml +4 -0
- package/.vscodeignore +18 -0
- package/LICENSE +674 -0
- package/README.md +86 -0
- package/bin/cli.js +4 -0
- package/bin/lsp.js +8 -0
- package/isdl.png +0 -0
- package/out/_backgrounds.scss +91 -0
- package/out/_handlebars.scss +505 -0
- package/out/_isdlStyles.scss +1357 -0
- package/out/_vuetifyOverrides.scss +425 -0
- package/out/_vuetifyStyles.scss +31957 -0
- package/out/cli/cli-util.js +39 -0
- package/out/cli/cli-util.js.map +1 -0
- package/out/cli/components/_backgrounds.scss +91 -0
- package/out/cli/components/_handlebars.scss +505 -0
- package/out/cli/components/_isdlStyles.scss +1357 -0
- package/out/cli/components/_vuetifyOverrides.scss +425 -0
- package/out/cli/components/_vuetifyStyles.scss +31957 -0
- package/out/cli/components/active-effect-sheet-generator.js +643 -0
- package/out/cli/components/active-effect-sheet-generator.js.map +1 -0
- package/out/cli/components/base-actor-sheet-generator.js +125 -0
- package/out/cli/components/base-actor-sheet-generator.js.map +1 -0
- package/out/cli/components/base-sheet-generator.js +525 -0
- package/out/cli/components/base-sheet-generator.js.map +1 -0
- package/out/cli/components/chat-card-generator.js +683 -0
- package/out/cli/components/chat-card-generator.js.map +1 -0
- package/out/cli/components/css-generator.js +58 -0
- package/out/cli/components/css-generator.js.map +1 -0
- package/out/cli/components/damage-roll-generator.js +173 -0
- package/out/cli/components/damage-roll-generator.js.map +1 -0
- package/out/cli/components/datamodel-generator.js +672 -0
- package/out/cli/components/datamodel-generator.js.map +1 -0
- package/out/cli/components/derived-data-generator.js +1340 -0
- package/out/cli/components/derived-data-generator.js.map +1 -0
- package/out/cli/components/hotbar-drop-hook-generator.js +95 -0
- package/out/cli/components/hotbar-drop-hook-generator.js.map +1 -0
- package/out/cli/components/init-hook-generator.js +597 -0
- package/out/cli/components/init-hook-generator.js.map +1 -0
- package/out/cli/components/keywords-generator.js +220 -0
- package/out/cli/components/keywords-generator.js.map +1 -0
- package/out/cli/components/language-generator.js +110 -0
- package/out/cli/components/language-generator.js.map +1 -0
- package/out/cli/components/measured-template-preview.js +234 -0
- package/out/cli/components/measured-template-preview.js.map +1 -0
- package/out/cli/components/method-generator.js +1812 -0
- package/out/cli/components/method-generator.js.map +1 -0
- package/out/cli/components/ready-hook-generator.js +448 -0
- package/out/cli/components/ready-hook-generator.js.map +1 -0
- package/out/cli/components/token-generator.js +138 -0
- package/out/cli/components/token-generator.js.map +1 -0
- package/out/cli/components/utils.js +176 -0
- package/out/cli/components/utils.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-attribute.js +148 -0
- package/out/cli/components/vue/base-components/vue-attribute.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-boolean.js +77 -0
- package/out/cli/components/vue/base-components/vue-boolean.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-calculator.js +106 -0
- package/out/cli/components/vue/base-components/vue-calculator.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-damage-application.js +369 -0
- package/out/cli/components/vue/base-components/vue-damage-application.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-damage-bonuses.js +225 -0
- package/out/cli/components/vue/base-components/vue-damage-bonuses.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-damage-resistances.js +256 -0
- package/out/cli/components/vue/base-components/vue-damage-resistances.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-damage-track.js +134 -0
- package/out/cli/components/vue/base-components/vue-damage-track.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-date-time.js +55 -0
- package/out/cli/components/vue/base-components/vue-date-time.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-dice.js +111 -0
- package/out/cli/components/vue/base-components/vue-dice.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-die.js +86 -0
- package/out/cli/components/vue/base-components/vue-die.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-document-choice.js +172 -0
- package/out/cli/components/vue/base-components/vue-document-choice.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-document-choices.js +203 -0
- package/out/cli/components/vue/base-components/vue-document-choices.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-document-link.js +73 -0
- package/out/cli/components/vue/base-components/vue-document-link.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-extended-choice.js +101 -0
- package/out/cli/components/vue/base-components/vue-extended-choice.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-inventory.js +532 -0
- package/out/cli/components/vue/base-components/vue-inventory.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-macro-choice.js +150 -0
- package/out/cli/components/vue/base-components/vue-macro-choice.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-measured-template.js +543 -0
- package/out/cli/components/vue/base-components/vue-measured-template.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-money.js +496 -0
- package/out/cli/components/vue/base-components/vue-money.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-number.js +184 -0
- package/out/cli/components/vue/base-components/vue-number.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-paperdoll.js +56 -0
- package/out/cli/components/vue/base-components/vue-paperdoll.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-parent-property-reference.js +89 -0
- package/out/cli/components/vue/base-components/vue-parent-property-reference.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-prosemirror.js +31 -0
- package/out/cli/components/vue/base-components/vue-prosemirror.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-resource.js +149 -0
- package/out/cli/components/vue/base-components/vue-resource.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-roll-visualizer.js +121 -0
- package/out/cli/components/vue/base-components/vue-roll-visualizer.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-self-property-reference.js +75 -0
- package/out/cli/components/vue/base-components/vue-self-property-reference.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-string-choice.js +111 -0
- package/out/cli/components/vue/base-components/vue-string-choice.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-string-choices.js +216 -0
- package/out/cli/components/vue/base-components/vue-string-choices.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-string.js +73 -0
- package/out/cli/components/vue/base-components/vue-string.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-text-field.js +66 -0
- package/out/cli/components/vue/base-components/vue-text-field.js.map +1 -0
- package/out/cli/components/vue/base-components/vue-tracker.js +444 -0
- package/out/cli/components/vue/base-components/vue-tracker.js.map +1 -0
- package/out/cli/components/vue/vue-action-component-generator.js +88 -0
- package/out/cli/components/vue/vue-action-component-generator.js.map +1 -0
- package/out/cli/components/vue/vue-active-effect-sheet-generator.js +1016 -0
- package/out/cli/components/vue/vue-active-effect-sheet-generator.js.map +1 -0
- package/out/cli/components/vue/vue-base-components-generator.js +59 -0
- package/out/cli/components/vue/vue-base-components-generator.js.map +1 -0
- package/out/cli/components/vue/vue-datatable-component-generator.js +307 -0
- package/out/cli/components/vue/vue-datatable-component-generator.js.map +1 -0
- package/out/cli/components/vue/vue-datatable-sheet-class-generator.js +342 -0
- package/out/cli/components/vue/vue-datatable-sheet-class-generator.js.map +1 -0
- package/out/cli/components/vue/vue-datatable2-component-generator.js +939 -0
- package/out/cli/components/vue/vue-datatable2-component-generator.js.map +1 -0
- package/out/cli/components/vue/vue-document-creation-app.js +140 -0
- package/out/cli/components/vue/vue-document-creation-app.js.map +1 -0
- package/out/cli/components/vue/vue-document-creation-sheet.js +105 -0
- package/out/cli/components/vue/vue-document-creation-sheet.js.map +1 -0
- package/out/cli/components/vue/vue-generator.js +240 -0
- package/out/cli/components/vue/vue-generator.js.map +1 -0
- package/out/cli/components/vue/vue-mixin.js +338 -0
- package/out/cli/components/vue/vue-mixin.js.map +1 -0
- package/out/cli/components/vue/vue-pinned-datatable-component-generator.js +306 -0
- package/out/cli/components/vue/vue-pinned-datatable-component-generator.js.map +1 -0
- package/out/cli/components/vue/vue-prompt-generator.js +201 -0
- package/out/cli/components/vue/vue-prompt-generator.js.map +1 -0
- package/out/cli/components/vue/vue-prompt-sheet-class-generator.js +252 -0
- package/out/cli/components/vue/vue-prompt-sheet-class-generator.js.map +1 -0
- package/out/cli/components/vue/vue-sheet-application-generator.js +2008 -0
- package/out/cli/components/vue/vue-sheet-application-generator.js.map +1 -0
- package/out/cli/components/vue/vue-sheet-class-generator.js +484 -0
- package/out/cli/components/vue/vue-sheet-class-generator.js.map +1 -0
- package/out/cli/generator.js +659 -0
- package/out/cli/generator.js.map +1 -0
- package/out/cli/main.js +43 -0
- package/out/cli/main.js.map +1 -0
- package/out/datatables.min.css +54 -0
- package/out/datatables.min.js +178 -0
- package/out/extension/github/githubAuthProvider.js +345 -0
- package/out/extension/github/githubAuthProvider.js.map +1 -0
- package/out/extension/github/githubConfig.js +132 -0
- package/out/extension/github/githubConfig.js.map +1 -0
- package/out/extension/github/githubGistActions.js +251 -0
- package/out/extension/github/githubGistActions.js.map +1 -0
- package/out/extension/github/githubGistManager.js +255 -0
- package/out/extension/github/githubGistManager.js.map +1 -0
- package/out/extension/github/githubManager.js +1735 -0
- package/out/extension/github/githubManager.js.map +1 -0
- package/out/extension/github/githubQuickActions.js +659 -0
- package/out/extension/github/githubQuickActions.js.map +1 -0
- package/out/extension/github/githubTreeProvider.js +181 -0
- package/out/extension/github/githubTreeProvider.js.map +1 -0
- package/out/extension/github/system-workflow.yml +48 -0
- package/out/extension/main.cjs +70315 -0
- package/out/extension/main.cjs.map +7 -0
- package/out/extension/main.js +237 -0
- package/out/extension/main.js.map +1 -0
- package/out/extension/package.json +426 -0
- package/out/isdl.png +0 -0
- package/out/language/generated/ast.js +2992 -0
- package/out/language/generated/ast.js.map +1 -0
- package/out/language/generated/grammar.js +13970 -0
- package/out/language/generated/grammar.js.map +1 -0
- package/out/language/generated/module.js +20 -0
- package/out/language/generated/module.js.map +1 -0
- package/out/language/intelligent-system-design-language-formatter.js +85 -0
- package/out/language/intelligent-system-design-language-formatter.js.map +1 -0
- package/out/language/intelligent-system-design-language-module.js +69 -0
- package/out/language/intelligent-system-design-language-module.js.map +1 -0
- package/out/language/intelligent-system-design-language-quickfixes.js +37 -0
- package/out/language/intelligent-system-design-language-quickfixes.js.map +1 -0
- package/out/language/intelligent-system-design-language-validator.js +515 -0
- package/out/language/intelligent-system-design-language-validator.js.map +1 -0
- package/out/language/isdl-hover-provider.js +77 -0
- package/out/language/isdl-hover-provider.js.map +1 -0
- package/out/language/isdl-scope-provider.js +149 -0
- package/out/language/isdl-scope-provider.js.map +1 -0
- package/out/language/main.cjs +47655 -0
- package/out/language/main.cjs.map +7 -0
- package/out/language/main.js +11 -0
- package/out/language/main.js.map +1 -0
- package/out/missing-character.png +0 -0
- package/out/package.json +426 -0
- package/out/paperdoll_default.png +0 -0
- package/out/progressbar.min.js +7 -0
- package/out/styles.scss +722 -0
- package/out/test/formatting/formatter.test.js +46 -0
- package/out/test/formatting/formatter.test.js.map +1 -0
- package/out/vuetify.esm.js +30279 -0
- package/package.json +426 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { expandToNode, toString } from 'langium/generate';
|
|
2
|
+
import * as fs from 'node:fs';
|
|
3
|
+
import * as path from 'node:path';
|
|
4
|
+
export function generateCanvasToken(entry, id, destination) {
|
|
5
|
+
const generatedFileDir = path.join(destination, "system", "canvas");
|
|
6
|
+
const generatedFilePath = path.join(generatedFileDir, `token.mjs`);
|
|
7
|
+
if (!fs.existsSync(generatedFileDir)) {
|
|
8
|
+
fs.mkdirSync(generatedFileDir, { recursive: true });
|
|
9
|
+
}
|
|
10
|
+
const fileNode = expandToNode `
|
|
11
|
+
export default class ${entry.config.name}Token extends Token {
|
|
12
|
+
/** @inheritDoc */
|
|
13
|
+
_drawBar(number, bar, data) {
|
|
14
|
+
const resource = foundry.utils.getProperty(this.document.actor.system, data.attribute);
|
|
15
|
+
|
|
16
|
+
if (resource.temp <= 0) {
|
|
17
|
+
return super._drawBar(number, bar, data);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const displayMax = resource.max;
|
|
21
|
+
|
|
22
|
+
const tempPct = Math.clamp(resource.temp, 0, displayMax) / displayMax;
|
|
23
|
+
const colorPct = Math.clamp(resource.value, 0, displayMax) / displayMax;
|
|
24
|
+
|
|
25
|
+
// Determine the container size (logic borrowed from core)
|
|
26
|
+
const w = this.w;
|
|
27
|
+
let h = Math.max((canvas.dimensions.size / 12), 8);
|
|
28
|
+
if (this.document.height >= 2) h *= 1.6;
|
|
29
|
+
const bs = Math.clamp(h / 8, 1, 2);
|
|
30
|
+
const bs1 = bs + 1;
|
|
31
|
+
|
|
32
|
+
// Determine the color to use
|
|
33
|
+
const blk = 0x000000;
|
|
34
|
+
let color;
|
|
35
|
+
if ( number === 0 ) color = Color.fromRGB([(1-(colorPct/2)), colorPct, 0]);
|
|
36
|
+
else color = Color.fromRGB([(0.5 * colorPct), (0.7 * colorPct), 0.5 + (colorPct / 2)]);
|
|
37
|
+
|
|
38
|
+
// Overall bar container
|
|
39
|
+
bar.clear();
|
|
40
|
+
bar.beginFill(blk, 0.5).lineStyle(bs, blk, 1.0).drawRoundedRect(0, 0, w, h, 3);
|
|
41
|
+
|
|
42
|
+
// Health bar
|
|
43
|
+
bar.beginFill(color, 1.0).lineStyle(bs, blk, 1.0).drawRoundedRect(0, 0, colorPct*w, h, 2);
|
|
44
|
+
|
|
45
|
+
function getBlendedContrast(color, blendFactor = 0.3) {
|
|
46
|
+
// Convert color to hex string
|
|
47
|
+
let hex = color.toString(16).padStart(6, "0");
|
|
48
|
+
|
|
49
|
+
// Extract RGB components
|
|
50
|
+
let r = parseInt(hex.substring(0, 2), 16);
|
|
51
|
+
let g = parseInt(hex.substring(2, 4), 16);
|
|
52
|
+
let b = parseInt(hex.substring(4, 6), 16);
|
|
53
|
+
|
|
54
|
+
// Calculate luminance
|
|
55
|
+
let luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
|
|
56
|
+
|
|
57
|
+
// Determine base contrast color (black or white)
|
|
58
|
+
let baseContrast = luminance > 0.5 ? 0x000000 : 0xFFFFFF;
|
|
59
|
+
|
|
60
|
+
// Extract RGB from base contrast
|
|
61
|
+
let bcR = (baseContrast >> 16) & 0xFF;
|
|
62
|
+
let bcG = (baseContrast >> 8) & 0xFF;
|
|
63
|
+
let bcB = baseContrast & 0xFF;
|
|
64
|
+
|
|
65
|
+
// Blend original color with contrast color
|
|
66
|
+
let blendedR = Math.round(r * (1 - blendFactor) + bcR * blendFactor);
|
|
67
|
+
let blendedG = Math.round(g * (1 - blendFactor) + bcG * blendFactor);
|
|
68
|
+
let blendedB = Math.round(b * (1 - blendFactor) + bcB * blendFactor);
|
|
69
|
+
|
|
70
|
+
// Return new blended color
|
|
71
|
+
return (blendedR << 16) | (blendedG << 8) | blendedB;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Calculate a temporary color that is a lighter shade than color
|
|
75
|
+
const tempColor = number === 0 ? 0x33AAFF : getBlendedContrast(color);
|
|
76
|
+
|
|
77
|
+
// Temporary health bar
|
|
78
|
+
|
|
79
|
+
const blur = new PIXI.filters.BlurFilter();
|
|
80
|
+
blur.blur = 1; // Adjust for stronger glow
|
|
81
|
+
|
|
82
|
+
const colorMatrix = new PIXI.filters.ColorMatrixFilter();
|
|
83
|
+
colorMatrix.brightness(1.2); // Increase brightness
|
|
84
|
+
|
|
85
|
+
const tempBar = new PIXI.Graphics();
|
|
86
|
+
tempBar.filters = [blur, colorMatrix];
|
|
87
|
+
tempBar.beginFill(tempColor, 1.0).lineStyle(0).drawRoundedRect(bs1, bs1, (tempPct*w)-(2*bs1), h-(2*bs1), 1)
|
|
88
|
+
|
|
89
|
+
bar.addChild(tempBar);
|
|
90
|
+
|
|
91
|
+
// Animation - Flashing (Opacity Pulse)
|
|
92
|
+
canvas.app.ticker.add((delta) => {
|
|
93
|
+
tempBar.alpha = 0.7 + 0.3 * Math.sin(performance.now() / 1000);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
// Set position
|
|
97
|
+
let posY = number === 0 ? this.h - h : 0;
|
|
98
|
+
bar.position.set(0, posY);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/* -------------------------------------------- */
|
|
102
|
+
|
|
103
|
+
static onTargetToken(user, token, targeted) {
|
|
104
|
+
if ( !targeted ) return;
|
|
105
|
+
if ( !token.hasDynamicRing ) return;
|
|
106
|
+
const color = Color.from(user.color);
|
|
107
|
+
token.ring.flashColor(color, { duration: 500, easing: token.ring.constructor.easeTwoPeaks });
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
`.appendNewLineIfNotEmpty();
|
|
111
|
+
fs.writeFileSync(generatedFilePath, toString(fileNode), 'utf-8');
|
|
112
|
+
}
|
|
113
|
+
export function generateTokenDocument(entry, id, destination) {
|
|
114
|
+
const generatedFileDir = path.join(destination, "system", "documents");
|
|
115
|
+
const generatedFilePath = path.join(generatedFileDir, `token.mjs`);
|
|
116
|
+
if (!fs.existsSync(generatedFileDir)) {
|
|
117
|
+
fs.mkdirSync(generatedFileDir, { recursive: true });
|
|
118
|
+
}
|
|
119
|
+
const fileNode = expandToNode `
|
|
120
|
+
export default class ${entry.config.name}TokenDocument extends TokenDocument {
|
|
121
|
+
/** @inheritDoc */
|
|
122
|
+
getBarAttribute(barName, options={}) {
|
|
123
|
+
const data = super.getBarAttribute(barName, options);
|
|
124
|
+
if ( data === null ) return;
|
|
125
|
+
const resource = foundry.utils.getProperty(this.actor.system, data.attribute);
|
|
126
|
+
data.value += resource.temp;
|
|
127
|
+
return data;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
_onUpdateBaseActor(update={}, options={}) {
|
|
131
|
+
if (foundry.utils.isEmpty(update)) return;
|
|
132
|
+
if (!this.isEditable) return;
|
|
133
|
+
super._onUpdateBaseActor(update, options);
|
|
134
|
+
}
|
|
135
|
+
}`.appendNewLineIfNotEmpty();
|
|
136
|
+
fs.writeFileSync(generatedFilePath, toString(fileNode), 'utf-8');
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=token-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-generator.js","sourceRoot":"","sources":["../../../src/cli/components/token-generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAGlC,MAAM,UAAU,mBAAmB,CAAC,KAAY,EAAE,EAAU,EAAE,WAAmB;IAC7E,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACpE,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;IAEnE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE;QAClC,EAAE,CAAC,SAAS,CAAC,gBAAgB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;KACvD;IAED,MAAM,QAAQ,GAAG,YAAY,CAAA;2BACN,KAAK,CAAC,MAAM,CAAC,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAmGvC,CAAC,uBAAuB,EAAE,CAAC;IAE5B,EAAE,CAAC,aAAa,CAAC,iBAAiB,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAAY,EAAE,EAAU,EAAE,WAAmB;IAC/E,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;IACvE,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;IAEnE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE;QAClC,EAAE,CAAC,SAAS,CAAC,gBAAgB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;KACvD;IAED,MAAM,QAAQ,GAAG,YAAY,CAAA;2BACN,KAAK,CAAC,MAAM,CAAC,IAAI;;;;;;;;;;;;;;;MAetC,CAAC,uBAAuB,EAAE,CAAC;IAE7B,EAAE,CAAC,aAAa,CAAC,iBAAiB,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;AACrE,CAAC"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { AstUtils } from 'langium';
|
|
2
|
+
import { isDamageTypeChoiceField, } from '../../language/generated/ast.js';
|
|
3
|
+
import { isResourceExp, isAttributeExp, isPage, isInitiativeProperty, isDocument, isIfStatement, isParentTypeCheckExpression, isTrackerExp, isParentAccess, isTargetTypeCheckExpression, isLayout, isStringChoiceField, isTargetAccess, isDocumentChoiceExp, isDiceField, } from "../../language/generated/ast.js";
|
|
4
|
+
export function toMachineIdentifier(s) {
|
|
5
|
+
return s.replace(/[^a-zA-Z0-9]/g, '');
|
|
6
|
+
}
|
|
7
|
+
function getPropertyAccessorSuffix(property) {
|
|
8
|
+
if (isResourceExp(property) || isTrackerExp(property) || isStringChoiceField(property) || isDiceField(property) || isDamageTypeChoiceField(property)) {
|
|
9
|
+
return '.value';
|
|
10
|
+
}
|
|
11
|
+
else if (isAttributeExp(property)) {
|
|
12
|
+
return '.mod';
|
|
13
|
+
}
|
|
14
|
+
// For numbers and other types (string, boolean, etc.), no additional accessor needed
|
|
15
|
+
return '';
|
|
16
|
+
}
|
|
17
|
+
function appendPropertyAccessor(systemPath, document, propertyName, safeAccess = true) {
|
|
18
|
+
if (!document || !document.body) {
|
|
19
|
+
return systemPath;
|
|
20
|
+
}
|
|
21
|
+
const allProperties = getAllOfType(document.body, (p) => true);
|
|
22
|
+
const targetProperty = allProperties.find(prop => 'name' in prop && prop.name && prop.name.toLowerCase() === propertyName.toLowerCase());
|
|
23
|
+
if (targetProperty) {
|
|
24
|
+
const suffix = getPropertyAccessorSuffix(targetProperty);
|
|
25
|
+
if (suffix) {
|
|
26
|
+
const accessor = safeAccess ? '?' : '';
|
|
27
|
+
return `${systemPath}${accessor}${suffix}`;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return systemPath;
|
|
31
|
+
}
|
|
32
|
+
export function getSystemPath(reference, subProperties = [], generatingProperty = undefined, safeAccess = true) {
|
|
33
|
+
// Not all references are to the baseline - resources and attributes have sub-paths
|
|
34
|
+
if (reference == undefined) {
|
|
35
|
+
return "";
|
|
36
|
+
}
|
|
37
|
+
if (isInitiativeProperty(reference)) {
|
|
38
|
+
return "initiative";
|
|
39
|
+
}
|
|
40
|
+
// If the property is "name", that is at the base of the object, not system
|
|
41
|
+
if (reference.name.toLowerCase() === "name") {
|
|
42
|
+
return reference.name.toLowerCase();
|
|
43
|
+
}
|
|
44
|
+
let basePath = "system.";
|
|
45
|
+
// If we are accessing a sub-property of a resource or attribute, we need to use the appropriate sub-path
|
|
46
|
+
if (subProperties.length > 0) {
|
|
47
|
+
let systemPath = `${basePath}${reference.name.toLowerCase()}`;
|
|
48
|
+
// For dice fields with number/die subproperties, we access them directly on the dice object
|
|
49
|
+
// No need to add .value for these specific subproperties
|
|
50
|
+
if (subProperties.length > 0) {
|
|
51
|
+
if (isDocumentChoiceExp(reference) ||
|
|
52
|
+
isParentAccess(generatingProperty) || isTargetAccess(generatingProperty)) {
|
|
53
|
+
if (safeAccess) {
|
|
54
|
+
systemPath = `${systemPath}?.system`;
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
systemPath = `${systemPath}.system`;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
// Process all sub-properties except the last one
|
|
62
|
+
for (let i = 0; i < subProperties.length - 1; i++) {
|
|
63
|
+
const subProperty = subProperties[i];
|
|
64
|
+
if (safeAccess) {
|
|
65
|
+
systemPath = `${systemPath}?.${subProperty.toLowerCase()}`;
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
systemPath = `${systemPath}.${subProperty.toLowerCase()}`;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
// Handle the final sub-property - need to determine if it should have .value/.mod appended
|
|
72
|
+
if (subProperties.length > 0) {
|
|
73
|
+
const finalProperty = subProperties[subProperties.length - 1];
|
|
74
|
+
const finalPropertyLower = finalProperty.toLowerCase();
|
|
75
|
+
if (safeAccess) {
|
|
76
|
+
systemPath = `${systemPath}?.${finalPropertyLower}`;
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
systemPath = `${systemPath}.${finalPropertyLower}`;
|
|
80
|
+
}
|
|
81
|
+
// For document choice accesses, we need special handling
|
|
82
|
+
if (isDocumentChoiceExp(reference)) {
|
|
83
|
+
const referencedDocument = reference.document.ref;
|
|
84
|
+
if (referencedDocument) {
|
|
85
|
+
// For string choice fields, check if we're accessing a metadata property
|
|
86
|
+
if (isStringChoiceField(reference)) {
|
|
87
|
+
// Metadata properties are accessed directly (e.g., system.training.bonus)
|
|
88
|
+
// Choice value itself would be accessed as system.training.value
|
|
89
|
+
// Since we have subproperties, this must be a metadata access - don't append .value
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
// For non-choice fields, use normal property accessor logic
|
|
93
|
+
systemPath = appendPropertyAccessor(systemPath, referencedDocument, finalProperty, safeAccess);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// For parent/target accesses, use document-based property type detection
|
|
98
|
+
else if (isParentAccess(generatingProperty) || isTargetAccess(generatingProperty)) {
|
|
99
|
+
const referencedDocument = isParentAccess(generatingProperty)
|
|
100
|
+
? getParentDocument(generatingProperty)
|
|
101
|
+
: getTargetDocument(generatingProperty);
|
|
102
|
+
if (referencedDocument) {
|
|
103
|
+
systemPath = appendPropertyAccessor(systemPath, referencedDocument, finalProperty, safeAccess);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return systemPath;
|
|
108
|
+
}
|
|
109
|
+
const suffix = getPropertyAccessorSuffix(reference);
|
|
110
|
+
return `${basePath}${reference.name.toLowerCase()}${suffix}`;
|
|
111
|
+
}
|
|
112
|
+
export function getAllOfType(body, comparisonFunc, samePageOnly = false) {
|
|
113
|
+
if (!body)
|
|
114
|
+
return [];
|
|
115
|
+
let result = [];
|
|
116
|
+
const matchingResults = body.filter(x => comparisonFunc(x)).map(x => x);
|
|
117
|
+
result.push(...matchingResults);
|
|
118
|
+
if (!samePageOnly) {
|
|
119
|
+
for (let page of body.filter(x => isPage(x)).map(x => x)) {
|
|
120
|
+
if (page.body) {
|
|
121
|
+
result.push(...getAllOfType(page.body, comparisonFunc, samePageOnly));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
for (let layout of body.filter(x => isLayout(x) && !isPage(x)).map(x => x)) {
|
|
126
|
+
if (layout.body) {
|
|
127
|
+
result.push(...getAllOfType(layout.body, comparisonFunc, samePageOnly));
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
for (let document of body.filter(x => isDocument(x)).map(x => x)) {
|
|
131
|
+
if (document.body) {
|
|
132
|
+
result.push(...getAllOfType(document.body, comparisonFunc, samePageOnly));
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return result;
|
|
136
|
+
}
|
|
137
|
+
export function globalGetAllOfType(entry, comparisonFunc) {
|
|
138
|
+
let result = [];
|
|
139
|
+
for (let document of entry.documents) {
|
|
140
|
+
result.push(...getAllOfType(document.body, comparisonFunc, false));
|
|
141
|
+
}
|
|
142
|
+
return result;
|
|
143
|
+
}
|
|
144
|
+
export function getParentDocument(parentAccess) {
|
|
145
|
+
const ifStatement = AstUtils.getContainerOfType(parentAccess.$container, (n) => {
|
|
146
|
+
const isIf = isIfStatement(n);
|
|
147
|
+
if (!isIf)
|
|
148
|
+
return false;
|
|
149
|
+
return isParentTypeCheckExpression(n.expression);
|
|
150
|
+
});
|
|
151
|
+
const parentTypeCheck = ifStatement.expression;
|
|
152
|
+
if (parentTypeCheck == undefined) {
|
|
153
|
+
console.error("Parent type check not found");
|
|
154
|
+
return undefined;
|
|
155
|
+
}
|
|
156
|
+
return parentTypeCheck.document.ref;
|
|
157
|
+
}
|
|
158
|
+
export function getTargetDocument(targetAccess) {
|
|
159
|
+
const ifStatement = AstUtils.getContainerOfType(targetAccess.$container, (n) => {
|
|
160
|
+
const isIf = isIfStatement(n);
|
|
161
|
+
if (!isIf)
|
|
162
|
+
return false;
|
|
163
|
+
return isTargetTypeCheckExpression(n.expression);
|
|
164
|
+
});
|
|
165
|
+
const targetTypeCheck = ifStatement.expression;
|
|
166
|
+
if (targetTypeCheck == undefined) {
|
|
167
|
+
console.error("Target type check not found");
|
|
168
|
+
return undefined;
|
|
169
|
+
}
|
|
170
|
+
return targetTypeCheck.document.ref;
|
|
171
|
+
}
|
|
172
|
+
export function getDocument(property) {
|
|
173
|
+
const document = AstUtils.getContainerOfType(property.$container, isDocument);
|
|
174
|
+
return document;
|
|
175
|
+
}
|
|
176
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/cli/components/utils.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import * as path from 'node:path';
|
|
2
|
+
import * as fs from 'node:fs';
|
|
3
|
+
import { expandToNode, toString } from 'langium/generate';
|
|
4
|
+
export default function generateAttributeComponent(destination) {
|
|
5
|
+
const generatedFileDir = path.join(destination, "system", "templates", "vue", "components");
|
|
6
|
+
const generatedFilePath = path.join(generatedFileDir, `attribute.vue`);
|
|
7
|
+
if (!fs.existsSync(generatedFileDir)) {
|
|
8
|
+
fs.mkdirSync(generatedFileDir, { recursive: true });
|
|
9
|
+
}
|
|
10
|
+
const fileNode = expandToNode `
|
|
11
|
+
<script setup>
|
|
12
|
+
import { ref, computed, inject } from "vue";
|
|
13
|
+
|
|
14
|
+
const props = defineProps({
|
|
15
|
+
label: String,
|
|
16
|
+
icon: String,
|
|
17
|
+
hasMod: Boolean,
|
|
18
|
+
mod: Number,
|
|
19
|
+
systemPath: String,
|
|
20
|
+
context: Object,
|
|
21
|
+
min: Number,
|
|
22
|
+
disabled: Boolean,
|
|
23
|
+
primaryColor: String,
|
|
24
|
+
secondaryColor: String,
|
|
25
|
+
editMode: Boolean,
|
|
26
|
+
attributeStyle: String, // plain or box
|
|
27
|
+
roll: Function,
|
|
28
|
+
hasRoll: Boolean
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const document = inject("rawDocument");
|
|
32
|
+
|
|
33
|
+
const value = computed({
|
|
34
|
+
get: () => foundry.utils.getProperty(props.context, props.systemPath),
|
|
35
|
+
set: (newValue) => foundry.utils.setProperty(props.context, props.systemPath, newValue)
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// Vuetify's up/down stepper buttons update the model without firing a
|
|
39
|
+
// native change event, so Foundry's submitOnChange form handler never
|
|
40
|
+
// persists them. When the value changes while focus is NOT on a text
|
|
41
|
+
// input (i.e. a stepper click, not typing), persist directly. Typing
|
|
42
|
+
// still persists via the input's native change on blur/enter.
|
|
43
|
+
// ('document' is the injected Foundry document; DOM access uses window.)
|
|
44
|
+
const persistOnStep = (path, newValue) => {
|
|
45
|
+
if (document && window.document.activeElement?.tagName !== 'INPUT') {
|
|
46
|
+
document.update({ [path]: newValue });
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const getStyle = computed(() => {
|
|
51
|
+
const p = props.primaryColor || "#92aed9";
|
|
52
|
+
|
|
53
|
+
// Get either black or white text color based on the primary color brightness
|
|
54
|
+
const brightness = (parseInt(p.slice(1, 3), 16) * 299 + parseInt(p.slice(3, 5), 16) * 587 + parseInt(p.slice(5, 7), 16) * 114) / 1000;
|
|
55
|
+
let textColor = "#ffffff"; // Default to white text
|
|
56
|
+
if (brightness > 128) {
|
|
57
|
+
textColor = "#000000"; // Use black text for brighter colors
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
backgroundColor: p,
|
|
62
|
+
color: textColor,
|
|
63
|
+
borderColor: p
|
|
64
|
+
};
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const getLabel = computed(() => {
|
|
68
|
+
const localized = game.i18n.localize(props.label);
|
|
69
|
+
if (props.icon) {
|
|
70
|
+
return \`<i class="fa-solid \${props.icon}"></i> \${localized}\`;
|
|
71
|
+
}
|
|
72
|
+
return localized;
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
const isHovering = ref(false);
|
|
76
|
+
|
|
77
|
+
const handleRoll = () => {
|
|
78
|
+
if (props.roll) {
|
|
79
|
+
props.roll();
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
</script>
|
|
83
|
+
|
|
84
|
+
<template>
|
|
85
|
+
<div class="dice-container"
|
|
86
|
+
@mouseenter="isHovering = true"
|
|
87
|
+
@mouseleave="isHovering = false"
|
|
88
|
+
>
|
|
89
|
+
<div v-if="attributeStyle == 'plain'">
|
|
90
|
+
<v-number-input v-if="attributeStyle == 'plain' && editMode" :model-value="value" @update:model-value="(v) => { value = v; persistOnStep(systemPath, v); }" :name="systemPath" :min="props.min" :disabled="disabled" type="number" variant="outlined" density="compact" :hide-details="true" data-tooltip="Value">
|
|
91
|
+
<template #label>
|
|
92
|
+
<span v-html="getLabel" />
|
|
93
|
+
</template>
|
|
94
|
+
</v-number-input>
|
|
95
|
+
<v-number-input v-if="attributeStyle == 'plain' && !editMode" :model-value="mod" :name="systemPath" :disabled="true" type="number" controlVariant="hidden" variant="outlined" density="compact" :hide-details="true" data-tooltip="Mod">
|
|
96
|
+
<template #label>
|
|
97
|
+
<span v-html="getLabel" />
|
|
98
|
+
</template>
|
|
99
|
+
</v-number-input>
|
|
100
|
+
<!-- Overlay with dice icon - appears on hover when roll function is available -->
|
|
101
|
+
<div
|
|
102
|
+
v-if="hasRoll && isHovering && !editMode"
|
|
103
|
+
class="dice-overlay plain"
|
|
104
|
+
@click="handleRoll"
|
|
105
|
+
>
|
|
106
|
+
<v-btn
|
|
107
|
+
icon
|
|
108
|
+
size="x-small"
|
|
109
|
+
:color="primaryColor"
|
|
110
|
+
class="dice-roll-btn"
|
|
111
|
+
variant="elevated"
|
|
112
|
+
elevation="4"
|
|
113
|
+
>
|
|
114
|
+
<v-icon size="small">fa-solid fa-dice</v-icon>
|
|
115
|
+
</v-btn>
|
|
116
|
+
</div>
|
|
117
|
+
</div>
|
|
118
|
+
<v-container
|
|
119
|
+
:class="['isdl-property', 'attributeExp', { 'no-mod': !hasMod }]"
|
|
120
|
+
v-if="attributeStyle == 'box'"
|
|
121
|
+
|
|
122
|
+
>
|
|
123
|
+
<v-label :style="getStyle"><v-icon v-if="icon" size="x-small" :icon="icon" style="padding-right: 0.5rem;"></v-icon>{{ game.i18n.localize(label) }}</v-label>
|
|
124
|
+
<div class="mod" v-if="hasMod">{{ mod }}</div>
|
|
125
|
+
<v-number-input :model-value="value" @update:model-value="(v) => { value = v; persistOnStep(systemPath, v); }" inset :min="props.min" :disabled="disabled" :name="systemPath" :controlVariant="disabled ? 'hidden' : 'split'" :step="1" type="number" variant="outlined" density="compact" :hide-details="true" :tile="true"></v-number-input>
|
|
126
|
+
<!-- Overlay with dice icon - appears on hover when roll function is available -->
|
|
127
|
+
<div
|
|
128
|
+
v-if="hasRoll && isHovering && !editMode"
|
|
129
|
+
class="dice-overlay"
|
|
130
|
+
@click="handleRoll"
|
|
131
|
+
>
|
|
132
|
+
<v-btn
|
|
133
|
+
icon
|
|
134
|
+
:color="primaryColor"
|
|
135
|
+
class="dice-roll-btn"
|
|
136
|
+
variant="elevated"
|
|
137
|
+
elevation="4"
|
|
138
|
+
>
|
|
139
|
+
<v-icon>fa-solid fa-dice</v-icon>
|
|
140
|
+
</v-btn>
|
|
141
|
+
</div>
|
|
142
|
+
</v-container>
|
|
143
|
+
</div>
|
|
144
|
+
</template>
|
|
145
|
+
`;
|
|
146
|
+
fs.writeFileSync(generatedFilePath, toString(fileNode));
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=vue-attribute.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vue-attribute.js","sourceRoot":"","sources":["../../../../../src/cli/components/vue/base-components/vue-attribute.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAC,YAAY,EAAE,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAExD,MAAM,CAAC,OAAO,UAAU,0BAA0B,CAAC,WAAmB;IAClE,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;IAC5F,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,eAAe,CAAC,CAAC;IAEvE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE;QAClC,EAAE,CAAC,SAAS,CAAC,gBAAgB,EAAE,EAAC,SAAS,EAAE,IAAI,EAAC,CAAC,CAAC;KACrD;IAED,MAAM,QAAQ,GAAG,YAAY,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAuI5B,CAAC;IAEF,EAAE,CAAC,aAAa,CAAC,iBAAiB,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC5D,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import * as path from 'node:path';
|
|
2
|
+
import * as fs from 'node:fs';
|
|
3
|
+
import { expandToNode, toString } from 'langium/generate';
|
|
4
|
+
export default function generateBooleanComponent(destination, entry) {
|
|
5
|
+
const generatedFileDir = path.join(destination, "system", "templates", "vue", "components");
|
|
6
|
+
const generatedFilePath = path.join(generatedFileDir, `boolean.vue`);
|
|
7
|
+
if (!fs.existsSync(generatedFileDir)) {
|
|
8
|
+
fs.mkdirSync(generatedFileDir, { recursive: true });
|
|
9
|
+
}
|
|
10
|
+
const fileNode = expandToNode `
|
|
11
|
+
<script setup>
|
|
12
|
+
import { ref, computed, inject } from "vue";
|
|
13
|
+
|
|
14
|
+
const props = defineProps({
|
|
15
|
+
label: String,
|
|
16
|
+
systemPath: String,
|
|
17
|
+
context: Object,
|
|
18
|
+
visibility: String,
|
|
19
|
+
editMode: Boolean,
|
|
20
|
+
icon: String,
|
|
21
|
+
color: String,
|
|
22
|
+
disabled: Boolean
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const document = inject("rawDocument");
|
|
26
|
+
|
|
27
|
+
const value = computed({
|
|
28
|
+
get: () => foundry.utils.getProperty(props.context, props.systemPath),
|
|
29
|
+
set: (newValue) => foundry.utils.setProperty(props.context, props.systemPath, newValue)
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
const isHidden = computed(() => {
|
|
33
|
+
if (props.visibility === "hidden") {
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
if (props.visibility === "gm" && !game.user.isGM) {
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
return false;
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const isDisabled = computed(() => {
|
|
43
|
+
return props.disabled ||
|
|
44
|
+
props.visibility === "locked" ||
|
|
45
|
+
props.visibility === "readonly" ||
|
|
46
|
+
(props.visibility === "gmOnly" && !game.user.isGM);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
const checkboxColor = computed(() => {
|
|
50
|
+
return props.color || 'primary';
|
|
51
|
+
});
|
|
52
|
+
</script>
|
|
53
|
+
|
|
54
|
+
<template>
|
|
55
|
+
<div v-if="!isHidden" class="isdl-boolean single-wide">
|
|
56
|
+
<v-checkbox
|
|
57
|
+
v-model="value"
|
|
58
|
+
:name="props.systemPath"
|
|
59
|
+
:disabled="isDisabled"
|
|
60
|
+
:color="checkboxColor"
|
|
61
|
+
density="compact"
|
|
62
|
+
class="single-wide"
|
|
63
|
+
variant="outlined"
|
|
64
|
+
>
|
|
65
|
+
<template #label>
|
|
66
|
+
<span class="field-label">
|
|
67
|
+
<v-icon v-if="props.icon" :icon="props.icon" size="small" class="me-1"></v-icon>
|
|
68
|
+
{{ game.i18n.localize(props.label) }}
|
|
69
|
+
</span>
|
|
70
|
+
</template>
|
|
71
|
+
</v-checkbox>
|
|
72
|
+
</div>
|
|
73
|
+
</template>
|
|
74
|
+
`.appendNewLine();
|
|
75
|
+
fs.writeFileSync(generatedFilePath, toString(fileNode));
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=vue-boolean.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vue-boolean.js","sourceRoot":"","sources":["../../../../../src/cli/components/vue/base-components/vue-boolean.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAC,YAAY,EAAE,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAGxD,MAAM,CAAC,OAAO,UAAU,wBAAwB,CAAC,WAAmB,EAAE,KAAa;IAC/E,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;IAC5F,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,aAAa,CAAC,CAAC;IAErE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE;QAClC,EAAE,CAAC,SAAS,CAAC,gBAAgB,EAAE,EAAC,SAAS,EAAE,IAAI,EAAC,CAAC,CAAC;KACrD;IAED,MAAM,QAAQ,GAAG,YAAY,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAgE5B,CAAC,aAAa,EAAE,CAAC;IAElB,EAAE,CAAC,aAAa,CAAC,iBAAiB,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC5D,CAAC"}
|