jaml-ui 1.0.2 → 2.0.0
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/README.md +1 -15
- package/dist/assets/searchPoolWorker-CGxhF1pC.js +2 -0
- package/dist/assets/searchPoolWorker-CGxhF1pC.js.map +1 -0
- package/dist/chunks/{motelyItemFormats-Dyq1BINO.js → runtime-CW7XHgOy.js} +465 -278
- package/dist/chunks/runtime-CW7XHgOy.js.map +1 -0
- package/dist/chunks/searchPoolWorker-CEdClSPb.js +11 -0
- package/dist/chunks/searchPoolWorker-CEdClSPb.js.map +1 -0
- package/dist/chunks/{ui-LfKBGL5-.js → ui-CyhuNM51.js} +736 -680
- package/dist/chunks/ui-CyhuNM51.js.map +1 -0
- package/dist/components/JamlAestheticSelector.d.ts +1 -1
- package/dist/components/JamlIdeToolbar.d.ts +2 -3
- package/dist/components/JimmolateEditor.d.ts +47 -0
- package/dist/components/SeedFinderApp.d.ts +1 -1
- package/dist/components/jamlMap/JokerPicker.d.ts +2 -2
- package/dist/components/jamlMap/MysterySlot.d.ts +2 -2
- package/dist/components/jamlMap/jokerRarity.d.ts +6 -0
- package/dist/decode/motelyItemDecoder.d.ts +0 -2
- package/dist/hooks/useSearch.d.ts +3 -3
- package/dist/hooks/useSearchPool.d.ts +1 -1
- package/dist/index.d.ts +1 -4
- package/dist/index.js +12835 -4177
- package/dist/index.js.map +1 -1
- package/dist/lib/jaml/jamlLangCodemirror.d.ts +13 -0
- package/dist/lib/motely/motelyCompatEnums.d.ts +349 -0
- package/dist/lib/motely/runtime.d.ts +7 -4
- package/dist/lib/types.d.ts +1 -1
- package/dist/motely.d.ts +3 -2
- package/dist/motely.js +48 -220
- package/dist/motely.js.map +1 -1
- package/dist/r3f/Card3D.d.ts +55 -0
- package/dist/r3f/CardTable.d.ts +35 -0
- package/dist/r3f.d.ts +2 -0
- package/dist/ui/JimboPicker.d.ts +28 -0
- package/dist/ui/hooks.d.ts +1 -3
- package/dist/ui/jimbo.css +1 -1
- package/dist/ui.d.ts +1 -0
- package/dist/ui.js +3 -2
- package/package.json +25 -19
- package/dist/assets/searchPoolWorker-DHh9a5GD.js +0 -40
- package/dist/assets/searchPoolWorker-DHh9a5GD.js.map +0 -1
- package/dist/chunks/motelyItemFormats-Dyq1BINO.js.map +0 -1
- package/dist/chunks/searchPoolWorker-DgRqVj_q.js +0 -8
- package/dist/chunks/searchPoolWorker-DgRqVj_q.js.map +0 -1
- package/dist/chunks/ui-LfKBGL5-.js.map +0 -1
- package/dist/components/JamlCurator.d.ts +0 -1
- package/dist/components/Jamlyzer.d.ts +0 -8
- package/dist/hooks/useAnalyzer.d.ts +0 -16
- package/dist/lib/hooks/useSeedAnalyzer.d.ts +0 -13
- package/dist/lib/utils.d.ts +0 -2
package/dist/motely.js
CHANGED
|
@@ -1,165 +1,13 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { b as e, d as t, h as n, r, t as i } from "./chunks/spriteMapper-C2mqQHLj.js";
|
|
3
|
-
import {
|
|
4
|
-
import { useCallback as
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
|
|
8
|
-
var y = {
|
|
9
|
-
Standardcard: "playing",
|
|
10
|
-
SpectralCard: "spectral",
|
|
11
|
-
TarotCard: "tarot",
|
|
12
|
-
PlanetCard: "planet",
|
|
13
|
-
Joker: "joker",
|
|
14
|
-
Invalid: "unknown"
|
|
15
|
-
}, b = {
|
|
16
|
-
[p.None]: "Base",
|
|
17
|
-
[p.Foil]: "Foil",
|
|
18
|
-
[p.Holographic]: "Holographic",
|
|
19
|
-
[p.Polychrome]: "Polychrome",
|
|
20
|
-
[p.Negative]: "Negative"
|
|
21
|
-
}, ne = {
|
|
22
|
-
[h.None]: "None",
|
|
23
|
-
[h.Gold]: "Gold",
|
|
24
|
-
[h.Red]: "Red",
|
|
25
|
-
[h.Blue]: "Blue",
|
|
26
|
-
[h.Purple]: "Purple"
|
|
27
|
-
}, x = {
|
|
28
|
-
[m.None]: "None",
|
|
29
|
-
[m.Bonus]: "Bonus",
|
|
30
|
-
[m.Mult]: "Mult",
|
|
31
|
-
[m.Wild]: "Wild",
|
|
32
|
-
[m.Glass]: "Glass",
|
|
33
|
-
[m.Steel]: "Steel",
|
|
34
|
-
[m.Stone]: "Stone",
|
|
35
|
-
[m.Gold]: "Gold",
|
|
36
|
-
[m.Lucky]: "Lucky"
|
|
37
|
-
}, S = {
|
|
38
|
-
[g.Two]: "2",
|
|
39
|
-
[g.Three]: "3",
|
|
40
|
-
[g.Four]: "4",
|
|
41
|
-
[g.Five]: "5",
|
|
42
|
-
[g.Six]: "6",
|
|
43
|
-
[g.Seven]: "7",
|
|
44
|
-
[g.Eight]: "8",
|
|
45
|
-
[g.Nine]: "9",
|
|
46
|
-
[g.Ten]: "10",
|
|
47
|
-
[g.Jack]: "Jack",
|
|
48
|
-
[g.Queen]: "Queen",
|
|
49
|
-
[g.King]: "King",
|
|
50
|
-
[g.Ace]: "Ace"
|
|
51
|
-
}, C = {
|
|
52
|
-
[_.Clubs]: "Clubs",
|
|
53
|
-
[_.Diamonds]: "Diamonds",
|
|
54
|
-
[_.Hearts]: "Hearts",
|
|
55
|
-
[_.Spades]: "Spades"
|
|
56
|
-
};
|
|
57
|
-
function w(e) {
|
|
58
|
-
return s[e];
|
|
59
|
-
}
|
|
60
|
-
function T(e) {
|
|
61
|
-
return e.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2");
|
|
62
|
-
}
|
|
63
|
-
function E(e) {
|
|
64
|
-
return e == null ? null : typeof e == "number" ? Number.isFinite(e) ? e : null : e.value ?? e.type ?? null;
|
|
65
|
-
}
|
|
66
|
-
function D(e) {
|
|
67
|
-
let t = E(e);
|
|
68
|
-
return t === null ? null : t & 65535;
|
|
69
|
-
}
|
|
70
|
-
function O(e) {
|
|
71
|
-
let t = D(e);
|
|
72
|
-
return t === null ? "Unknown" : w(t)?.enumName ?? `item#${t}`;
|
|
73
|
-
}
|
|
74
|
-
function k(e) {
|
|
75
|
-
let t = w(e)?.category;
|
|
76
|
-
return t ? y[t] ?? "unknown" : "unknown";
|
|
77
|
-
}
|
|
78
|
-
function A(e) {
|
|
79
|
-
let t = D(e);
|
|
80
|
-
return t === null ? "unknown" : k(t);
|
|
81
|
-
}
|
|
82
|
-
function re(e) {
|
|
83
|
-
let t = D(e);
|
|
84
|
-
return t === null ? "Unknown" : w(t)?.displayName ?? T(O(e));
|
|
85
|
-
}
|
|
86
|
-
function j(e, t) {
|
|
87
|
-
let n = E(e);
|
|
88
|
-
return n === null ? !1 : (n & 1 << t) != 0;
|
|
89
|
-
}
|
|
90
|
-
function M(e) {
|
|
91
|
-
if (e == null) return null;
|
|
92
|
-
let t = typeof e == "number" ? f.decodeItemEdition(e) : e.edition;
|
|
93
|
-
return t == null || t === p.None ? null : b[t];
|
|
94
|
-
}
|
|
95
|
-
function N(e) {
|
|
96
|
-
if (e == null) return null;
|
|
97
|
-
let t = typeof e == "number" ? f.decodeItemSeal(e) : e.seal;
|
|
98
|
-
return t == null || t === h.None ? null : ne[t];
|
|
99
|
-
}
|
|
100
|
-
function P(e) {
|
|
101
|
-
if (e == null) return null;
|
|
102
|
-
let t = typeof e == "number" ? f.decodeItemEnhancement(e) : e.enhancement;
|
|
103
|
-
return t == null || t === m.None ? null : x[t] ?? null;
|
|
104
|
-
}
|
|
105
|
-
function F(e) {
|
|
106
|
-
if (e == null || A(e) !== "playing") return null;
|
|
107
|
-
let t = typeof e == "number" ? f.decodeStandardcardRank(e) : e.rank;
|
|
108
|
-
return t == null ? null : S[t] ?? null;
|
|
109
|
-
}
|
|
110
|
-
function I(e) {
|
|
111
|
-
if (e == null || A(e) !== "playing") return null;
|
|
112
|
-
let t = typeof e == "number" ? f.decodeStandardcardSuit(e) : e.suit;
|
|
113
|
-
return t == null ? null : C[t] ?? null;
|
|
114
|
-
}
|
|
115
|
-
function ie(e) {
|
|
116
|
-
return O(e);
|
|
117
|
-
}
|
|
118
|
-
function L(e) {
|
|
119
|
-
let t = D(e);
|
|
120
|
-
if (t === null) return null;
|
|
121
|
-
let n = w(t), r = n?.enumName ?? `Unknown_${t}`, i = k(t);
|
|
122
|
-
return {
|
|
123
|
-
itemType: t,
|
|
124
|
-
enumKey: r,
|
|
125
|
-
displayName: n?.displayName ?? T(r),
|
|
126
|
-
category: i,
|
|
127
|
-
edition: M(e),
|
|
128
|
-
seal: N(e),
|
|
129
|
-
enhancement: P(e),
|
|
130
|
-
rank: F(e),
|
|
131
|
-
suit: I(e),
|
|
132
|
-
isEternal: typeof e == "number" ? f.isEternal(e) : j(e, 30),
|
|
133
|
-
isPerishable: typeof e == "number" ? f.isPerishable(e) : j(e, 31),
|
|
134
|
-
isRental: typeof e == "number" ? f.isRental(e) : j(e, 29)
|
|
135
|
-
};
|
|
136
|
-
}
|
|
137
|
-
function R(e, t) {
|
|
138
|
-
let n = L(e);
|
|
139
|
-
return n ? {
|
|
140
|
-
type: n.category === "joker" ? "joker" : n.category === "playing" ? "playing" : "consumable",
|
|
141
|
-
card: {
|
|
142
|
-
name: n.displayName,
|
|
143
|
-
edition: n.edition ?? void 0,
|
|
144
|
-
seal: n.seal ?? void 0,
|
|
145
|
-
enhancements: n.enhancement ? [n.enhancement] : void 0,
|
|
146
|
-
rank: n.rank ?? void 0,
|
|
147
|
-
suit: n.suit ?? void 0,
|
|
148
|
-
isEternal: n.isEternal,
|
|
149
|
-
isPerishable: n.isPerishable,
|
|
150
|
-
isRental: n.isRental,
|
|
151
|
-
scale: t
|
|
152
|
-
}
|
|
153
|
-
} : null;
|
|
154
|
-
}
|
|
155
|
-
function z() {}
|
|
156
|
-
function B() {
|
|
157
|
-
return 0;
|
|
158
|
-
}
|
|
159
|
-
//#endregion
|
|
3
|
+
import { _ as a, a as o, c as s, d as c, f as l, g as u, h as d, i as f, l as p, m, p as h, r as g, s as _, t as v, u as y, v as b, w as x, y as S } from "./chunks/runtime-CW7XHgOy.js";
|
|
4
|
+
import { useCallback as C, useState as w } from "react";
|
|
5
|
+
import { Program as T, Program as E } from "motely-wasm/motely/wasm";
|
|
6
|
+
import D from "motely-wasm";
|
|
7
|
+
import { PermissionMode as O } from "motely-wasm/bootsharp/file-system";
|
|
160
8
|
//#region src/decode/motelySprite.ts
|
|
161
|
-
function
|
|
162
|
-
let o =
|
|
9
|
+
function k(a) {
|
|
10
|
+
let o = _(a);
|
|
163
11
|
if (!o) return null;
|
|
164
12
|
if (o.category === "playing" && o.rank && o.suit) {
|
|
165
13
|
let r = t[o.rank], i = n[o.suit];
|
|
@@ -186,7 +34,7 @@ function V(a) {
|
|
|
186
34
|
category: o.category
|
|
187
35
|
} : null;
|
|
188
36
|
}
|
|
189
|
-
function
|
|
37
|
+
function A(a, o = "unknown") {
|
|
190
38
|
if (o === "playing") {
|
|
191
39
|
let r = /^(.*?)\s+of\s+(.*?)$/i.exec(a);
|
|
192
40
|
if (r) {
|
|
@@ -217,110 +65,90 @@ function H(a, o = "unknown") {
|
|
|
217
65
|
}
|
|
218
66
|
//#endregion
|
|
219
67
|
//#region src/motelyDisplay.ts
|
|
220
|
-
var
|
|
221
|
-
function
|
|
68
|
+
var j = T;
|
|
69
|
+
function M(e, t) {
|
|
222
70
|
let n = e[String(t)];
|
|
223
71
|
return typeof n == "string" && n.length > 0 ? n : null;
|
|
224
72
|
}
|
|
225
|
-
function
|
|
226
|
-
return
|
|
73
|
+
function N(e) {
|
|
74
|
+
return M(j.MotelyBossBlind, e & 255) ?? `boss#${e}`;
|
|
227
75
|
}
|
|
228
|
-
function
|
|
76
|
+
function P(e) {
|
|
229
77
|
return e;
|
|
230
78
|
}
|
|
231
|
-
function
|
|
232
|
-
return
|
|
79
|
+
function F(e) {
|
|
80
|
+
return M(j.MotelyVoucher, e) ?? `voucher#${e}`;
|
|
233
81
|
}
|
|
234
|
-
function
|
|
82
|
+
function I(e) {
|
|
235
83
|
return e;
|
|
236
84
|
}
|
|
237
|
-
function
|
|
238
|
-
return
|
|
85
|
+
function L(e) {
|
|
86
|
+
return M(j.MotelyTag, e) ?? `tag#${e}`;
|
|
239
87
|
}
|
|
240
|
-
function
|
|
88
|
+
function R(e) {
|
|
241
89
|
return e;
|
|
242
90
|
}
|
|
243
|
-
function
|
|
244
|
-
return
|
|
91
|
+
function z(e) {
|
|
92
|
+
return M(j.MotelyBoosterPack, e) ?? `pack#${e}`;
|
|
245
93
|
}
|
|
246
|
-
function
|
|
94
|
+
function B(e) {
|
|
247
95
|
return `${e} Pack`;
|
|
248
96
|
}
|
|
249
|
-
function
|
|
97
|
+
function V(e) {
|
|
250
98
|
return e;
|
|
251
99
|
}
|
|
252
|
-
function
|
|
253
|
-
return
|
|
100
|
+
function H(e) {
|
|
101
|
+
return x[e & 65535]?.displayName ?? `item#${e}`;
|
|
254
102
|
}
|
|
255
103
|
//#endregion
|
|
256
104
|
//#region src/hooks/useJamlLibrary.ts
|
|
257
|
-
|
|
258
|
-
function Q() {
|
|
259
|
-
return Z || (Z = (async () => {
|
|
260
|
-
try {
|
|
261
|
-
Y = await import("@rewaffle/bootsharp-file-system"), Y.init(te);
|
|
262
|
-
} catch (e) {
|
|
263
|
-
X = e;
|
|
264
|
-
}
|
|
265
|
-
})(), Z);
|
|
266
|
-
}
|
|
267
|
-
function $(e) {
|
|
105
|
+
function U(e) {
|
|
268
106
|
return e instanceof Error ? e.message : String(e);
|
|
269
107
|
}
|
|
270
|
-
function
|
|
271
|
-
let [e, t] =
|
|
272
|
-
|
|
273
|
-
let e = !1;
|
|
274
|
-
return Q().then(() => {
|
|
275
|
-
e || Y === null && (t("unsupported"), u($(X ?? "Bootsharp FileSystem package is not available.")));
|
|
276
|
-
}), () => {
|
|
277
|
-
e = !0;
|
|
278
|
-
};
|
|
279
|
-
}, []);
|
|
280
|
-
let d = Y !== null, p = c(() => {
|
|
281
|
-
n && o((e) => [...e]);
|
|
108
|
+
function W() {
|
|
109
|
+
let [e, t] = w("idle"), [n, r] = w(null), [i, a] = w([]), [s, c] = w(null), l = C(() => {
|
|
110
|
+
n && a((e) => [...e]);
|
|
282
111
|
}, [n]);
|
|
283
112
|
return {
|
|
284
113
|
status: e,
|
|
285
114
|
rootId: n,
|
|
286
115
|
files: i,
|
|
287
116
|
error: s,
|
|
288
|
-
mount:
|
|
289
|
-
|
|
290
|
-
t("unsupported"), u($(X ?? "Bootsharp FileSystem package is not available."));
|
|
291
|
-
return;
|
|
292
|
-
}
|
|
293
|
-
t("mounting"), u(null);
|
|
117
|
+
mount: C(async () => {
|
|
118
|
+
t("mounting"), c(null);
|
|
294
119
|
try {
|
|
295
|
-
await
|
|
296
|
-
|
|
297
|
-
|
|
120
|
+
if (await g(), !o()) {
|
|
121
|
+
t("unsupported"), c(U(f() ?? "Bootsharp FileSystem package is not available."));
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
let e = await T.pickRoot({
|
|
125
|
+
mode: O.ReadWrite,
|
|
298
126
|
id: "jaml-library"
|
|
299
127
|
});
|
|
300
128
|
if (!e) {
|
|
301
129
|
t("idle");
|
|
302
130
|
return;
|
|
303
131
|
}
|
|
304
|
-
r(await
|
|
132
|
+
r(await T.mountRoot(e, { mode: O.ReadWrite })), a([]), t("ready");
|
|
305
133
|
} catch (e) {
|
|
306
|
-
t("error"),
|
|
134
|
+
t("error"), c(U(e));
|
|
307
135
|
}
|
|
308
136
|
}, []),
|
|
309
|
-
unmount:
|
|
310
|
-
n && (await
|
|
311
|
-
}, [
|
|
312
|
-
loadFile:
|
|
137
|
+
unmount: C(async () => {
|
|
138
|
+
n && (await g(), await T.unmountRoot(n), r(null), a([]), t(o() ? "idle" : "unsupported"));
|
|
139
|
+
}, [n]),
|
|
140
|
+
loadFile: C(async (e) => {
|
|
313
141
|
if (!n) throw Error("JAML library is not mounted.");
|
|
314
|
-
return await
|
|
142
|
+
return await g(), await T.readTextFile(n, e);
|
|
315
143
|
}, [n]),
|
|
316
|
-
saveFile:
|
|
144
|
+
saveFile: C(async (e, t) => {
|
|
317
145
|
if (!n) throw Error("JAML library is not mounted.");
|
|
318
|
-
await
|
|
146
|
+
await g(), await T.writeTextFile(n, e, t), a((t) => (t.includes(e) ? t : [...t, e]).sort((e, t) => e.localeCompare(t)));
|
|
319
147
|
}, [n]),
|
|
320
|
-
refresh:
|
|
148
|
+
refresh: l
|
|
321
149
|
};
|
|
322
150
|
}
|
|
323
151
|
//#endregion
|
|
324
|
-
export {
|
|
152
|
+
export { v as MOTELY_BIN_PATH, E as Motely, D as bootsharp, _ as decodeMotelyItem, s as decodeMotelyItemName, p as decodeMotelyItemToJamlCard, g as ensureMotelyReady, A as getMotelySpriteByName, z as motelyBoosterPackDisplayName, B as motelyBoosterPackDisplayNameFromKey, N as motelyBossDisplayName, P as motelyBossDisplayNameFromKey, y as motelyItemCategory, c as motelyItemDisplayName, V as motelyItemDisplayNameFromKey, H as motelyItemDisplayNameFromValue, l as motelyItemEditionName, h as motelyItemEnhancementName, m as motelyItemRenderCategory, d as motelyItemSealName, k as motelyItemToSprite, u as motelyItemTypeName, a as motelyStandardcardRankName, b as motelyStandardcardSuitName, L as motelyTagDisplayName, R as motelyTagDisplayNameFromKey, F as motelyVoucherDisplayName, I as motelyVoucherDisplayNameFromKey, S as resolveMotelyItemType, W as useJamlLibrary };
|
|
325
153
|
|
|
326
154
|
//# sourceMappingURL=motely.js.map
|
package/dist/motely.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"motely.js","names":[],"sources":["../src/decode/motelyItemDecoder.ts","../src/decode/motelySprite.ts","../src/motelyDisplay.ts","../src/hooks/useJamlLibrary.ts"],"sourcesContent":["import { MOTELY_ITEM_FORMATS_BY_VALUE } from \"./motelyItemFormats.js\";\nimport {\n MotelyItemEdition,\n MotelyItemSeal,\n MotelyItemEnhancement,\n MotelyStandardcardRank,\n MotelyStandardcardSuit,\n} from \"motely-wasm\";\n\ntype MotelyItemCategoryName = \"Standardcard\" | \"SpectralCard\" | \"TarotCard\" | \"PlanetCard\" | \"Joker\" | \"Invalid\";\n\nconst CATEGORY_MAP: Record<MotelyItemCategoryName, MotelyRenderableCategory> = {\n Standardcard: \"playing\",\n SpectralCard: \"spectral\",\n TarotCard: \"tarot\",\n PlanetCard: \"planet\",\n Joker: \"joker\",\n Invalid: \"unknown\",\n};\n\nconst EDITIONS: Record<MotelyItemEdition, string> = {\n [MotelyItemEdition.None]: \"Base\",\n [MotelyItemEdition.Foil]: \"Foil\",\n [MotelyItemEdition.Holographic]: \"Holographic\",\n [MotelyItemEdition.Polychrome]: \"Polychrome\",\n [MotelyItemEdition.Negative]: \"Negative\",\n};\n\nconst SEALS: Record<MotelyItemSeal, string> = {\n [MotelyItemSeal.None]: \"None\",\n [MotelyItemSeal.Gold]: \"Gold\",\n [MotelyItemSeal.Red]: \"Red\",\n [MotelyItemSeal.Blue]: \"Blue\",\n [MotelyItemSeal.Purple]: \"Purple\",\n};\n\nconst ENHANCEMENTS: Record<MotelyItemEnhancement, string> = {\n [MotelyItemEnhancement.None]: \"None\",\n [MotelyItemEnhancement.Bonus]: \"Bonus\",\n [MotelyItemEnhancement.Mult]: \"Mult\",\n [MotelyItemEnhancement.Wild]: \"Wild\",\n [MotelyItemEnhancement.Glass]: \"Glass\",\n [MotelyItemEnhancement.Steel]: \"Steel\",\n [MotelyItemEnhancement.Stone]: \"Stone\",\n [MotelyItemEnhancement.Gold]: \"Gold\",\n [MotelyItemEnhancement.Lucky]: \"Lucky\",\n};\n\nconst RANKS: Record<MotelyStandardcardRank, string> = {\n [MotelyStandardcardRank.Two]: \"2\",\n [MotelyStandardcardRank.Three]: \"3\",\n [MotelyStandardcardRank.Four]: \"4\",\n [MotelyStandardcardRank.Five]: \"5\",\n [MotelyStandardcardRank.Six]: \"6\",\n [MotelyStandardcardRank.Seven]: \"7\",\n [MotelyStandardcardRank.Eight]: \"8\",\n [MotelyStandardcardRank.Nine]: \"9\",\n [MotelyStandardcardRank.Ten]: \"10\",\n [MotelyStandardcardRank.Jack]: \"Jack\",\n [MotelyStandardcardRank.Queen]: \"Queen\",\n [MotelyStandardcardRank.King]: \"King\",\n [MotelyStandardcardRank.Ace]: \"Ace\",\n};\n\nconst SUITS: Record<MotelyStandardcardSuit, \"Clubs\" | \"Diamonds\" | \"Hearts\" | \"Spades\"> = {\n [MotelyStandardcardSuit.Clubs]: \"Clubs\",\n [MotelyStandardcardSuit.Diamonds]: \"Diamonds\",\n [MotelyStandardcardSuit.Hearts]: \"Hearts\",\n [MotelyStandardcardSuit.Spades]: \"Spades\",\n};\n\n\nexport type CardCategory = \"joker\" | \"consumable\" | \"playing\" | \"spectral\" | \"tarot\" | \"planet\";\nexport type MotelyRenderableCategory = CardCategory | \"unknown\";\n\nexport type MotelyItemInput = number | MotelyRuntimeItem | null | undefined;\n\nexport interface MotelyRuntimeItem {\n type?: number;\n value?: number;\n edition?: number;\n seal?: number;\n enhancement?: number;\n suit?: number;\n rank?: number;\n}\n\nexport interface DecodedMotelyItem {\n itemType: number;\n enumKey: string;\n displayName: string;\n category: MotelyRenderableCategory;\n edition: \"Foil\" | \"Holographic\" | \"Polychrome\" | \"Negative\" | null;\n seal: \"Gold\" | \"Red\" | \"Blue\" | \"Purple\" | null;\n enhancement: string | null;\n rank: string | null;\n suit: \"Clubs\" | \"Diamonds\" | \"Hearts\" | \"Spades\" | null;\n isEternal: boolean;\n isPerishable: boolean;\n isRental: boolean;\n}\n\n\nexport interface MotelyJamlCard {\n type: \"joker\" | \"consumable\" | \"playing\";\n card: {\n name: string;\n edition?: \"Foil\" | \"Holographic\" | \"Polychrome\" | \"Negative\";\n seal?: string;\n enhancements?: string[];\n rank?: string;\n suit?: string;\n isEternal?: boolean;\n isPerishable?: boolean;\n isRental?: boolean;\n scale?: number;\n };\n}\n\nfunction itemFormat(itemType: number) {\n return MOTELY_ITEM_FORMATS_BY_VALUE[itemType as keyof typeof MOTELY_ITEM_FORMATS_BY_VALUE];\n}\n\nfunction spaceSplit(value: string): string {\n return value.replace(/([a-z])([A-Z])/g, \"$1 $2\").replace(/([A-Z]+)([A-Z][a-z])/g, \"$1 $2\");\n}\n\nfunction resolvePackedValue(input: MotelyItemInput): number | null {\n if (input == null) return null;\n if (typeof input === \"number\") return Number.isFinite(input) ? input : null;\n return input.value ?? input.type ?? null;\n}\n\nexport function resolveMotelyItemType(input: MotelyItemInput): number | null {\n const val = resolvePackedValue(input);\n return val !== null ? val & 0xffff : null;\n}\n\nexport function motelyItemTypeName(input: MotelyItemInput): string {\n const itemType = resolveMotelyItemType(input);\n if (itemType === null) return \"Unknown\";\n return itemFormat(itemType)?.enumName ?? `item#${itemType}`;\n}\n\nexport function motelyItemCategory(itemType: number): MotelyRenderableCategory {\n const category = itemFormat(itemType)?.category as MotelyItemCategoryName | undefined;\n return category ? CATEGORY_MAP[category] ?? \"unknown\" : \"unknown\";\n}\n\nexport function motelyItemRenderCategory(input: MotelyItemInput): MotelyRenderableCategory {\n const itemType = resolveMotelyItemType(input);\n if (itemType === null) return \"unknown\";\n return motelyItemCategory(itemType);\n}\n\nexport function motelyItemDisplayName(input: MotelyItemInput): string {\n const itemType = resolveMotelyItemType(input);\n if (itemType === null) return \"Unknown\";\n return itemFormat(itemType)?.displayName ?? spaceSplit(motelyItemTypeName(input));\n}\n\nimport { Motely } from \"motely-wasm\";\n\nfunction isStickerSet(input: MotelyItemInput, bitOffset: number): boolean {\n const val = resolvePackedValue(input);\n if (val === null) return false;\n return (val & (1 << bitOffset)) !== 0;\n}\n\nexport function motelyItemEditionName(input: MotelyItemInput): \"Foil\" | \"Holographic\" | \"Polychrome\" | \"Negative\" | null {\n if (input == null) return null;\n const val = typeof input === \"number\" ? Motely.decodeItemEdition(input) : input.edition;\n if (val == null || val === MotelyItemEdition.None) return null;\n return EDITIONS[val] as \"Foil\" | \"Holographic\" | \"Polychrome\" | \"Negative\";\n}\n\nexport function motelyItemSealName(input: MotelyItemInput): \"Gold\" | \"Red\" | \"Blue\" | \"Purple\" | null {\n if (input == null) return null;\n const val = typeof input === \"number\" ? Motely.decodeItemSeal(input) : input.seal;\n if (val == null || val === MotelyItemSeal.None) return null;\n return SEALS[val] as \"Gold\" | \"Red\" | \"Blue\" | \"Purple\";\n}\n\nexport function motelyItemEnhancementName(input: MotelyItemInput): string | null {\n if (input == null) return null;\n const val = typeof input === \"number\" ? Motely.decodeItemEnhancement(input) : input.enhancement;\n if (val == null || val === MotelyItemEnhancement.None) return null;\n return ENHANCEMENTS[val] ?? null;\n}\n\n\nexport function motelyStandardcardRankName(input: MotelyItemInput): string | null {\n if (input == null) return null;\n if (motelyItemRenderCategory(input) !== \"playing\") return null;\n const val = typeof input === \"number\" ? Motely.decodeStandardcardRank(input) : input.rank;\n if (val == null) return null;\n return RANKS[val] ?? null;\n}\n\nexport function motelyStandardcardSuitName(input: MotelyItemInput): \"Clubs\" | \"Diamonds\" | \"Hearts\" | \"Spades\" | null {\n if (input == null) return null;\n if (motelyItemRenderCategory(input) !== \"playing\") return null;\n const val = typeof input === \"number\" ? Motely.decodeStandardcardSuit(input) : input.suit;\n if (val == null) return null;\n return SUITS[val] ?? null;\n}\n\nexport function decodeMotelyItemName(input: MotelyItemInput): string {\n return motelyItemTypeName(input);\n}\n\nexport function decodeMotelyItem(input: MotelyItemInput): DecodedMotelyItem | null {\n const itemType = resolveMotelyItemType(input);\n if (itemType === null) return null;\n\n const format = itemFormat(itemType);\n const enumKeyStr = format?.enumName ?? `Unknown_${itemType}`;\n const category = motelyItemCategory(itemType);\n const displayName = format?.displayName ?? spaceSplit(enumKeyStr);\n\n return {\n itemType,\n enumKey: enumKeyStr,\n displayName,\n category,\n edition: motelyItemEditionName(input),\n seal: motelyItemSealName(input),\n enhancement: motelyItemEnhancementName(input),\n rank: motelyStandardcardRankName(input),\n suit: motelyStandardcardSuitName(input),\n isEternal: typeof input === \"number\" ? Motely.isEternal(input) : isStickerSet(input, 30),\n isPerishable: typeof input === \"number\" ? Motely.isPerishable(input) : isStickerSet(input, 31),\n isRental: typeof input === \"number\" ? Motely.isRental(input) : isStickerSet(input, 29),\n };\n}\n\nexport function decodeMotelyItemToJamlCard(input: MotelyItemInput, scale?: number): MotelyJamlCard | null {\n const decoded = decodeMotelyItem(input);\n if (!decoded) return null;\n\n const type: \"joker\" | \"consumable\" | \"playing\" =\n decoded.category === \"joker\" ? \"joker\"\n : decoded.category === \"playing\" ? \"playing\"\n : \"consumable\";\n\n return {\n type,\n card: {\n name: decoded.displayName,\n edition: decoded.edition ?? undefined,\n seal: decoded.seal ?? undefined,\n enhancements: decoded.enhancement ? [decoded.enhancement] : undefined,\n rank: decoded.rank ?? undefined,\n suit: decoded.suit ?? undefined,\n isEternal: decoded.isEternal,\n isPerishable: decoded.isPerishable,\n isRental: decoded.isRental,\n scale,\n },\n };\n}\n\nexport function warmMotelyItemCache(): void { /* no-op */ }\nexport function motelyItemCacheSize(): number { return 0; }\n","import { decodeMotelyItem, type MotelyRenderableCategory } from \"./motelyItemDecoder.js\";\nimport { getSpriteData, SHEET_META } from \"../sprites/spriteMapper.js\";\nimport { RANK_MAP, SUIT_MAP } from \"../sprites/spriteData.js\";\nimport { resolveJamlAssetUrl } from \"../assets.js\";\n\nexport interface MotelySpriteData {\n atlasPath: string;\n gridCol: number;\n gridRow: number;\n gridCols: number;\n gridRows: number;\n displayName: string;\n category: MotelyRenderableCategory;\n}\n\n/**\n * Given a raw motely-wasm item value (which may be a bitpacked integer or raw MotelyItemType),\n * resolves it to a sprite atlas path and grid coordinates for rendering.\n */\nexport function motelyItemToSprite(rawValue: number): MotelySpriteData | null {\n const decoded = decodeMotelyItem(rawValue);\n if (!decoded) return null;\n\n if (decoded.category === \"playing\" && decoded.rank && decoded.suit) {\n const col = RANK_MAP[decoded.rank];\n const row = SUIT_MAP[decoded.suit];\n if (col !== undefined && row !== undefined) {\n return {\n atlasPath: resolveJamlAssetUrl('deck'),\n gridCol: col,\n gridRow: row,\n gridCols: 13,\n gridRows: 4,\n displayName: decoded.displayName,\n category: \"playing\"\n };\n }\n }\n\n const sprite = getSpriteData(decoded.displayName);\n if (!sprite) return null;\n\n const meta = SHEET_META[sprite.type];\n if (!meta) return null;\n\n return {\n atlasPath: resolveJamlAssetUrl(meta.assetKey),\n gridCol: sprite.pos.x,\n gridRow: sprite.pos.y,\n gridCols: meta.cols,\n gridRows: meta.rows,\n displayName: decoded.displayName,\n category: decoded.category\n };\n}\n\n/**\n * Resolves a sprite by name and category without needing a Motely integer.\n */\nexport function getMotelySpriteByName(name: string, category: MotelyRenderableCategory = \"unknown\"): MotelySpriteData | null {\n if (category === \"playing\") {\n // Attempt to parse \"Rank of Suit\"\n const match = /^(.*?)\\s+of\\s+(.*?)$/i.exec(name);\n if (match) {\n const rank = match[1];\n const suit = match[2];\n const col = RANK_MAP[rank];\n const row = SUIT_MAP[suit];\n if (col !== undefined && row !== undefined) {\n return {\n atlasPath: resolveJamlAssetUrl('deck'),\n gridCol: col,\n gridRow: row,\n gridCols: 13,\n gridRows: 4,\n displayName: name,\n category: \"playing\"\n };\n }\n }\n }\n\n const sprite = getSpriteData(name);\n if (!sprite) return null;\n\n const meta = SHEET_META[sprite.type];\n if (!meta) return null;\n\n return {\n atlasPath: resolveJamlAssetUrl(meta.assetKey),\n gridCol: sprite.pos.x,\n gridRow: sprite.pos.y,\n gridCols: meta.cols,\n gridRows: meta.rows,\n displayName: name,\n category\n };\n}\n","import { Motely } from \"motely-wasm\";\nimport { MOTELY_ITEM_FORMATS_BY_VALUE } from \"./decode/motelyItemFormats.js\";\n\ntype RuntimeEnum = Record<string, string | number>;\ntype MotelyRuntimeEnums = typeof Motely & Record<string, RuntimeEnum>;\n\nconst MotelyEnums = Motely as MotelyRuntimeEnums;\n\nfunction runtimeEnumKey(\n enumObject: Record<string, unknown>,\n value: number,\n): string | null {\n const key = enumObject[String(value)];\n return typeof key === \"string\" && key.length > 0 ? key : null;\n}\n\nexport function motelyBossDisplayName(value: number): string {\n const key = runtimeEnumKey(MotelyEnums.MotelyBossBlind, value & 0xff);\n return key ?? `boss#${value}`;\n}\n\nexport function motelyBossDisplayNameFromKey(key: string): string {\n return key;\n}\n\nexport function motelyVoucherDisplayName(value: number): string {\n const key = runtimeEnumKey(MotelyEnums.MotelyVoucher, value);\n return key ?? `voucher#${value}`;\n}\n\nexport function motelyVoucherDisplayNameFromKey(key: string): string {\n return key;\n}\n\nexport function motelyTagDisplayName(value: number): string {\n const key = runtimeEnumKey(MotelyEnums.MotelyTag, value);\n return key ?? `tag#${value}`;\n}\n\nexport function motelyTagDisplayNameFromKey(key: string): string {\n return key;\n}\n\nexport function motelyBoosterPackDisplayName(value: number): string {\n const key = runtimeEnumKey(MotelyEnums.MotelyBoosterPack, value);\n return key ?? `pack#${value}`;\n}\n\nexport function motelyBoosterPackDisplayNameFromKey(key: string): string {\n return `${key} Pack`;\n}\n\nexport function motelyItemDisplayNameFromKey(key: string): string {\n return key;\n}\n\nexport function motelyItemDisplayNameFromValue(value: number): string {\n const itemType = value & 0xffff;\n return MOTELY_ITEM_FORMATS_BY_VALUE[itemType as keyof typeof MOTELY_ITEM_FORMATS_BY_VALUE]?.displayName ?? `item#${value}`;\n}\n","\"use client\";\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { Motely } from \"motely-wasm\";\nimport { ensureMotelyReady } from \"../lib/motely/runtime.js\";\nimport { IFileMounter, PermissionMode } from \"motely-wasm/bootsharp/file-system\";\n\ntype FileSystemPackage = typeof import(\"@rewaffle/bootsharp-file-system\");\n\nlet fileSystemPackage: FileSystemPackage | null = null;\nlet fileSystemInitError: unknown = null;\nlet fileSystemInitPromise: Promise<void> | null = null;\n\nfunction initFileSystem(): Promise<void> {\n if (fileSystemInitPromise) return fileSystemInitPromise;\n fileSystemInitPromise = (async () => {\n try {\n fileSystemPackage = await import(\"@rewaffle/bootsharp-file-system\");\n fileSystemPackage.init(IFileMounter);\n } catch (error) {\n fileSystemInitError = error;\n }\n })();\n return fileSystemInitPromise;\n}\n\nexport type JamlLibraryStatus = \"idle\" | \"unsupported\" | \"mounting\" | \"ready\" | \"error\";\n\nexport interface UseJamlLibraryState {\n status: JamlLibraryStatus;\n rootId: string | null;\n files: string[];\n error: string | null;\n mount: () => Promise<void>;\n unmount: () => Promise<void>;\n loadFile: (uri: string) => Promise<string>;\n saveFile: (uri: string, content: string) => Promise<void>;\n refresh: () => void;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n\nexport function useJamlLibrary(): UseJamlLibraryState {\n const [status, setStatus] = useState<JamlLibraryStatus>(\"idle\");\n const [rootId, setRootId] = useState<string | null>(null);\n const [files, setFiles] = useState<string[]>([]);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n initFileSystem().then(() => {\n if (cancelled) return;\n if (fileSystemPackage === null) {\n setStatus(\"unsupported\");\n setError(errorMessage(fileSystemInitError ?? \"Bootsharp FileSystem package is not available.\"));\n }\n });\n return () => { cancelled = true; };\n }, []);\n\n const isFileSystemReady = fileSystemPackage !== null;\n\n const refresh = useCallback(() => {\n if (!rootId) return;\n setFiles((prev) => [...prev]);\n }, [rootId]);\n\n const mount = useCallback(async () => {\n await initFileSystem();\n if (fileSystemPackage === null) {\n setStatus(\"unsupported\");\n setError(errorMessage(fileSystemInitError ?? \"Bootsharp FileSystem package is not available.\"));\n return;\n }\n\n setStatus(\"mounting\");\n setError(null);\n\n try {\n await ensureMotelyReady();\n const pickedRoot = await Motely.pickRoot({ mode: PermissionMode.ReadWrite, id: \"jaml-library\" });\n if (!pickedRoot) {\n setStatus(\"idle\");\n return;\n }\n\n const mountedRoot = await Motely.mountRoot(pickedRoot, { mode: PermissionMode.ReadWrite });\n setRootId(mountedRoot);\n setFiles([]);\n setStatus(\"ready\");\n } catch (err) {\n setStatus(\"error\");\n setError(errorMessage(err));\n }\n }, []);\n\n const unmount = useCallback(async () => {\n if (!rootId) return;\n await ensureMotelyReady();\n await Motely.unmountRoot(rootId);\n setRootId(null);\n setFiles([]);\n setStatus(isFileSystemReady ? \"idle\" : \"unsupported\");\n }, [isFileSystemReady, rootId]);\n\n const loadFile = useCallback(async (uri: string) => {\n if (!rootId) throw new Error(\"JAML library is not mounted.\");\n await ensureMotelyReady();\n return await Motely.readTextFile(rootId, uri);\n }, [rootId]);\n\n const saveFile = useCallback(async (uri: string, content: string) => {\n if (!rootId) throw new Error(\"JAML library is not mounted.\");\n await ensureMotelyReady();\n await Motely.writeTextFile(rootId, uri, content);\n setFiles((prev) => (prev.includes(uri) ? prev : [...prev, uri]).sort((a, b) => a.localeCompare(b)));\n }, [rootId]);\n\n return { status, rootId, files, error, mount, unmount, loadFile, saveFile, refresh };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"motely.js","names":[],"sources":["../src/decode/motelySprite.ts","../src/motelyDisplay.ts","../src/hooks/useJamlLibrary.ts"],"sourcesContent":["import { decodeMotelyItem, type MotelyRenderableCategory } from \"./motelyItemDecoder.js\";\nimport { getSpriteData, SHEET_META } from \"../sprites/spriteMapper.js\";\nimport { RANK_MAP, SUIT_MAP } from \"../sprites/spriteData.js\";\nimport { resolveJamlAssetUrl } from \"../assets.js\";\n\nexport interface MotelySpriteData {\n atlasPath: string;\n gridCol: number;\n gridRow: number;\n gridCols: number;\n gridRows: number;\n displayName: string;\n category: MotelyRenderableCategory;\n}\n\n/**\n * Given a raw motely-wasm item value (which may be a bitpacked integer or raw MotelyItemType),\n * resolves it to a sprite atlas path and grid coordinates for rendering.\n */\nexport function motelyItemToSprite(rawValue: number): MotelySpriteData | null {\n const decoded = decodeMotelyItem(rawValue);\n if (!decoded) return null;\n\n if (decoded.category === \"playing\" && decoded.rank && decoded.suit) {\n const col = RANK_MAP[decoded.rank];\n const row = SUIT_MAP[decoded.suit];\n if (col !== undefined && row !== undefined) {\n return {\n atlasPath: resolveJamlAssetUrl('deck'),\n gridCol: col,\n gridRow: row,\n gridCols: 13,\n gridRows: 4,\n displayName: decoded.displayName,\n category: \"playing\"\n };\n }\n }\n\n const sprite = getSpriteData(decoded.displayName);\n if (!sprite) return null;\n\n const meta = SHEET_META[sprite.type];\n if (!meta) return null;\n\n return {\n atlasPath: resolveJamlAssetUrl(meta.assetKey),\n gridCol: sprite.pos.x,\n gridRow: sprite.pos.y,\n gridCols: meta.cols,\n gridRows: meta.rows,\n displayName: decoded.displayName,\n category: decoded.category\n };\n}\n\n/**\n * Resolves a sprite by name and category without needing a Motely integer.\n */\nexport function getMotelySpriteByName(name: string, category: MotelyRenderableCategory = \"unknown\"): MotelySpriteData | null {\n if (category === \"playing\") {\n // Attempt to parse \"Rank of Suit\"\n const match = /^(.*?)\\s+of\\s+(.*?)$/i.exec(name);\n if (match) {\n const rank = match[1];\n const suit = match[2];\n const col = RANK_MAP[rank];\n const row = SUIT_MAP[suit];\n if (col !== undefined && row !== undefined) {\n return {\n atlasPath: resolveJamlAssetUrl('deck'),\n gridCol: col,\n gridRow: row,\n gridCols: 13,\n gridRows: 4,\n displayName: name,\n category: \"playing\"\n };\n }\n }\n }\n\n const sprite = getSpriteData(name);\n if (!sprite) return null;\n\n const meta = SHEET_META[sprite.type];\n if (!meta) return null;\n\n return {\n atlasPath: resolveJamlAssetUrl(meta.assetKey),\n gridCol: sprite.pos.x,\n gridRow: sprite.pos.y,\n gridCols: meta.cols,\n gridRows: meta.rows,\n displayName: name,\n category\n };\n}\n","import { Program as Motely } from \"motely-wasm/motely/wasm\";\nimport { MOTELY_ITEM_FORMATS_BY_VALUE } from \"./decode/motelyItemFormats.js\";\n\ntype RuntimeEnum = Record<string, string | number>;\ntype MotelyRuntimeEnums = typeof Motely & Record<string, RuntimeEnum>;\n\nconst MotelyEnums = Motely as MotelyRuntimeEnums;\n\nfunction runtimeEnumKey(\n enumObject: Record<string, unknown>,\n value: number,\n): string | null {\n const key = enumObject[String(value)];\n return typeof key === \"string\" && key.length > 0 ? key : null;\n}\n\nexport function motelyBossDisplayName(value: number): string {\n const key = runtimeEnumKey(MotelyEnums.MotelyBossBlind, value & 0xff);\n return key ?? `boss#${value}`;\n}\n\nexport function motelyBossDisplayNameFromKey(key: string): string {\n return key;\n}\n\nexport function motelyVoucherDisplayName(value: number): string {\n const key = runtimeEnumKey(MotelyEnums.MotelyVoucher, value);\n return key ?? `voucher#${value}`;\n}\n\nexport function motelyVoucherDisplayNameFromKey(key: string): string {\n return key;\n}\n\nexport function motelyTagDisplayName(value: number): string {\n const key = runtimeEnumKey(MotelyEnums.MotelyTag, value);\n return key ?? `tag#${value}`;\n}\n\nexport function motelyTagDisplayNameFromKey(key: string): string {\n return key;\n}\n\nexport function motelyBoosterPackDisplayName(value: number): string {\n const key = runtimeEnumKey(MotelyEnums.MotelyBoosterPack, value);\n return key ?? `pack#${value}`;\n}\n\nexport function motelyBoosterPackDisplayNameFromKey(key: string): string {\n return `${key} Pack`;\n}\n\nexport function motelyItemDisplayNameFromKey(key: string): string {\n return key;\n}\n\nexport function motelyItemDisplayNameFromValue(value: number): string {\n const itemType = value & 0xffff;\n return MOTELY_ITEM_FORMATS_BY_VALUE[itemType as keyof typeof MOTELY_ITEM_FORMATS_BY_VALUE]?.displayName ?? `item#${value}`;\n}\n","\"use client\";\n\nimport { useCallback, useState } from \"react\";\nimport { Program as Motely } from \"motely-wasm/motely/wasm\";\nimport { ensureMotelyReady, isFileSystemReady, getFileSystemError } from \"../lib/motely/runtime.js\";\nimport { PermissionMode } from \"motely-wasm/bootsharp/file-system\";\n\n// The optional File System extension is bound pre-boot inside ensureMotelyReady()\n// (see runtime.ts) — that's the only place the init can win the boot race. Here we\n// just boot and read back whether the mounter actually bound.\n\nexport type JamlLibraryStatus = \"idle\" | \"unsupported\" | \"mounting\" | \"ready\" | \"error\";\n\nexport interface UseJamlLibraryState {\n status: JamlLibraryStatus;\n rootId: string | null;\n files: string[];\n error: string | null;\n mount: () => Promise<void>;\n unmount: () => Promise<void>;\n loadFile: (uri: string) => Promise<string>;\n saveFile: (uri: string, content: string) => Promise<void>;\n refresh: () => void;\n}\n\nfunction errorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\n\nexport function useJamlLibrary(): UseJamlLibraryState {\n const [status, setStatus] = useState<JamlLibraryStatus>(\"idle\");\n const [rootId, setRootId] = useState<string | null>(null);\n const [files, setFiles] = useState<string[]>([]);\n const [error, setError] = useState<string | null>(null);\n\n const refresh = useCallback(() => {\n if (!rootId) return;\n setFiles((prev) => [...prev]);\n }, [rootId]);\n\n const mount = useCallback(async () => {\n setStatus(\"mounting\");\n setError(null);\n\n try {\n await ensureMotelyReady();\n if (!isFileSystemReady()) {\n setStatus(\"unsupported\");\n setError(errorMessage(getFileSystemError() ?? \"Bootsharp FileSystem package is not available.\"));\n return;\n }\n const pickedRoot = await Motely.pickRoot({ mode: PermissionMode.ReadWrite, id: \"jaml-library\" });\n if (!pickedRoot) {\n setStatus(\"idle\");\n return;\n }\n\n const mountedRoot = await Motely.mountRoot(pickedRoot, { mode: PermissionMode.ReadWrite });\n setRootId(mountedRoot);\n setFiles([]);\n setStatus(\"ready\");\n } catch (err) {\n setStatus(\"error\");\n setError(errorMessage(err));\n }\n }, []);\n\n const unmount = useCallback(async () => {\n if (!rootId) return;\n await ensureMotelyReady();\n await Motely.unmountRoot(rootId);\n setRootId(null);\n setFiles([]);\n setStatus(isFileSystemReady() ? \"idle\" : \"unsupported\");\n }, [rootId]);\n\n const loadFile = useCallback(async (uri: string) => {\n if (!rootId) throw new Error(\"JAML library is not mounted.\");\n await ensureMotelyReady();\n return await Motely.readTextFile(rootId, uri);\n }, [rootId]);\n\n const saveFile = useCallback(async (uri: string, content: string) => {\n if (!rootId) throw new Error(\"JAML library is not mounted.\");\n await ensureMotelyReady();\n await Motely.writeTextFile(rootId, uri, content);\n setFiles((prev) => (prev.includes(uri) ? prev : [...prev, uri]).sort((a, b) => a.localeCompare(b)));\n }, [rootId]);\n\n return { status, rootId, files, error, mount, unmount, loadFile, saveFile, refresh };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { SpriteSheetType } from '../sprites/spriteMapper.js';
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import * as THREE from "three";
|
|
4
|
+
export declare const CARD_W = 1;
|
|
5
|
+
export declare const CARD_H: number;
|
|
6
|
+
/**
|
|
7
|
+
* Load a spritesheet PNG and crop it to a single item's cell via UV repeat/offset.
|
|
8
|
+
* Reuses jaml-ui/core's sprite metadata so the 3D card shows the *real* art,
|
|
9
|
+
* pixel-perfect (NearestFilter), not a placeholder.
|
|
10
|
+
*/
|
|
11
|
+
export declare function useSpriteTexture(itemName: string, fallbackSheet: SpriteSheetType): THREE.Texture;
|
|
12
|
+
/** Balatro-style finishes. The card catches light differently per edition. */
|
|
13
|
+
export type CardEdition = "base" | "foil" | "holo" | "polychrome";
|
|
14
|
+
export interface EditionMaterial {
|
|
15
|
+
roughness: number;
|
|
16
|
+
metalness: number;
|
|
17
|
+
emissiveIntensity: number;
|
|
18
|
+
/** Whether the emissive hue cycles per-frame (the holographic shimmer). */
|
|
19
|
+
animated: boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Material tuning per edition. Metalness stays 0 — without an env map, metal goes
|
|
23
|
+
* black — so "shine" comes from a low-roughness specular highlight that rakes
|
|
24
|
+
* across as the card tilts under the light. Holo/polychrome add a cycling
|
|
25
|
+
* emissive hue on top for the rainbow shimmer.
|
|
26
|
+
*/
|
|
27
|
+
export declare function editionMaterial(edition: CardEdition): EditionMaterial;
|
|
28
|
+
/** Drive the holographic emissive hue from time + tilt angle. No-op for base/foil. */
|
|
29
|
+
export declare function updateEditionEmissive(material: THREE.MeshStandardMaterial | null, edition: CardEdition, t: number, tiltY: number): void;
|
|
30
|
+
export declare const MAX_TILT = 0.3;
|
|
31
|
+
/** Off-axis key light + soft ambient: the specular that makes foil "catch." */
|
|
32
|
+
export declare function CardLighting(): import("react/jsx-runtime").JSX.Element;
|
|
33
|
+
export interface Card3DProps {
|
|
34
|
+
/** Item name to render — e.g. "Blueprint". Resolved against jaml-ui sprite metadata. */
|
|
35
|
+
itemName: string;
|
|
36
|
+
/** Which sheet to fall back to when the name doesn't resolve. Default "Jokers". */
|
|
37
|
+
fallbackSheet?: SpriteSheetType;
|
|
38
|
+
/** Finish — "base" | "foil" | "holo" | "polychrome". Default "base". */
|
|
39
|
+
edition?: CardEdition;
|
|
40
|
+
/** Pixel height of the canvas. Default 320. */
|
|
41
|
+
height?: number | string;
|
|
42
|
+
className?: string;
|
|
43
|
+
style?: React.CSSProperties;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* A floating, hover-reactive 3D Balatro card that catches the light.
|
|
47
|
+
*
|
|
48
|
+
* ```tsx
|
|
49
|
+
* import { Card3D } from "jaml-ui/r3f";
|
|
50
|
+
* <Card3D itemName="Blueprint" edition="holo" />
|
|
51
|
+
* ```
|
|
52
|
+
*
|
|
53
|
+
* Peer deps: `three`, `@react-three/fiber`, `@react-three/drei`, `@react-spring/three`.
|
|
54
|
+
*/
|
|
55
|
+
export declare function Card3D({ itemName, fallbackSheet, edition, height, className, style, }: Card3DProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { CardEdition } from './Card3D.js';
|
|
2
|
+
import { SpriteSheetType } from '../sprites/spriteMapper.js';
|
|
3
|
+
import * as React from "react";
|
|
4
|
+
export interface CardTableItem {
|
|
5
|
+
/** Item name — e.g. "Blueprint". Resolved against jaml-ui sprite metadata. */
|
|
6
|
+
itemName: string;
|
|
7
|
+
/** Sheet to fall back to when the name doesn't resolve. Default "Jokers". */
|
|
8
|
+
fallbackSheet?: SpriteSheetType;
|
|
9
|
+
/** Finish — "base" | "foil" | "holo" | "polychrome". Default "base". */
|
|
10
|
+
edition?: CardEdition;
|
|
11
|
+
}
|
|
12
|
+
export interface CardTableProps {
|
|
13
|
+
/** The cards to lay out in a row, left to right. */
|
|
14
|
+
items: CardTableItem[];
|
|
15
|
+
/** Pixel height of the canvas. Default 320. */
|
|
16
|
+
height?: number | string;
|
|
17
|
+
/** World-space distance between card centers. Default 1.25. */
|
|
18
|
+
gap?: number;
|
|
19
|
+
className?: string;
|
|
20
|
+
style?: React.CSSProperties;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* A row of floating, grabbable 3D Balatro cards in a single Canvas — the shop,
|
|
24
|
+
* not a swatch. Hover to lean a card toward the pointer; press to lift it off
|
|
25
|
+
* the felt and drag it; release to drop it back into its slot. Foil/holo cards
|
|
26
|
+
* catch and throw the light as they move.
|
|
27
|
+
*
|
|
28
|
+
* ```tsx
|
|
29
|
+
* import { CardTable } from "jaml-ui/r3f";
|
|
30
|
+
* <CardTable items={[{ itemName: "Blueprint", edition: "holo" }]} />
|
|
31
|
+
* ```
|
|
32
|
+
*
|
|
33
|
+
* Peer deps: `three`, `@react-three/fiber`, `@react-three/drei`.
|
|
34
|
+
*/
|
|
35
|
+
export declare function CardTable({ items, height, gap, className, style, }: CardTableProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/r3f.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { default as React } from 'react';
|
|
2
|
+
export type JimboPickerProps = React.HTMLAttributes<HTMLDivElement>;
|
|
3
|
+
/** The picker shell — vertical stack of sections/search/grid. */
|
|
4
|
+
export declare function JimboPicker({ className, ...props }: JimboPickerProps): import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
/** A titled grouping within a picker (e.g. the Legendary row). */
|
|
6
|
+
export declare function JimboPickerSection({ className, ...props }: JimboPickerProps): import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export interface JimboPickerGridProps extends JimboPickerProps {
|
|
8
|
+
/** Wider cells for the legendary row. */
|
|
9
|
+
legendary?: boolean;
|
|
10
|
+
/** Scrollable body with hidden scrollbar. */
|
|
11
|
+
scroll?: boolean;
|
|
12
|
+
}
|
|
13
|
+
/** The sprite grid. */
|
|
14
|
+
export declare function JimboPickerGrid({ legendary, scroll, className, ...props }: JimboPickerGridProps): import("react/jsx-runtime").JSX.Element;
|
|
15
|
+
export interface JimboPickerItemProps extends JimboPickerProps {
|
|
16
|
+
/** Dimmed (e.g. filtered-out half of a voucher pair). */
|
|
17
|
+
muted?: boolean;
|
|
18
|
+
}
|
|
19
|
+
/** A single clickable sprite cell. */
|
|
20
|
+
export declare function JimboPickerItem({ muted, className, ...props }: JimboPickerItemProps): import("react/jsx-runtime").JSX.Element;
|
|
21
|
+
/** Wrapper for the search field row. */
|
|
22
|
+
export declare function JimboPickerSearch({ className, ...props }: JimboPickerProps): import("react/jsx-runtime").JSX.Element;
|
|
23
|
+
/** A base/upgrade pair cell (vouchers). */
|
|
24
|
+
export declare function JimboPickerPair({ className, ...props }: JimboPickerProps): import("react/jsx-runtime").JSX.Element;
|
|
25
|
+
/** Empty / no-matches state inside the grid. */
|
|
26
|
+
export declare function JimboPickerEmpty({ className, ...props }: JimboPickerProps): import("react/jsx-runtime").JSX.Element;
|
|
27
|
+
/** Recessed hint panel above a grid. */
|
|
28
|
+
export declare function JimboPickerHint({ className, ...props }: JimboPickerProps): import("react/jsx-runtime").JSX.Element;
|
package/dist/ui/hooks.d.ts
CHANGED
|
@@ -113,9 +113,7 @@ export declare function useJamlIdeDrag(filter: JamlVisualFilter, onChange: (filt
|
|
|
113
113
|
};
|
|
114
114
|
/**
|
|
115
115
|
* Provides a magnetic 3D tilt effect for DOM elements, replicating the hover-follow
|
|
116
|
-
* of Balatro cards. Continuous (tracks the cursor).
|
|
117
|
-
* juice prefer `JimboButton3D` from `jaml-ui/r3f`, which uses the canonical
|
|
118
|
-
* pmndrs stack (@react-three/fiber + @react-spring/three).
|
|
116
|
+
* of Balatro cards. Continuous (tracks the cursor). Pure CSS transform — no 3D deps.
|
|
119
117
|
*/
|
|
120
118
|
export declare function useDOMMagneticTilt(enabled?: boolean): {
|
|
121
119
|
handlers: {
|