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.
Files changed (49) hide show
  1. package/README.md +1 -15
  2. package/dist/assets/searchPoolWorker-CGxhF1pC.js +2 -0
  3. package/dist/assets/searchPoolWorker-CGxhF1pC.js.map +1 -0
  4. package/dist/chunks/{motelyItemFormats-Dyq1BINO.js → runtime-CW7XHgOy.js} +465 -278
  5. package/dist/chunks/runtime-CW7XHgOy.js.map +1 -0
  6. package/dist/chunks/searchPoolWorker-CEdClSPb.js +11 -0
  7. package/dist/chunks/searchPoolWorker-CEdClSPb.js.map +1 -0
  8. package/dist/chunks/{ui-LfKBGL5-.js → ui-CyhuNM51.js} +736 -680
  9. package/dist/chunks/ui-CyhuNM51.js.map +1 -0
  10. package/dist/components/JamlAestheticSelector.d.ts +1 -1
  11. package/dist/components/JamlIdeToolbar.d.ts +2 -3
  12. package/dist/components/JimmolateEditor.d.ts +47 -0
  13. package/dist/components/SeedFinderApp.d.ts +1 -1
  14. package/dist/components/jamlMap/JokerPicker.d.ts +2 -2
  15. package/dist/components/jamlMap/MysterySlot.d.ts +2 -2
  16. package/dist/components/jamlMap/jokerRarity.d.ts +6 -0
  17. package/dist/decode/motelyItemDecoder.d.ts +0 -2
  18. package/dist/hooks/useSearch.d.ts +3 -3
  19. package/dist/hooks/useSearchPool.d.ts +1 -1
  20. package/dist/index.d.ts +1 -4
  21. package/dist/index.js +12835 -4177
  22. package/dist/index.js.map +1 -1
  23. package/dist/lib/jaml/jamlLangCodemirror.d.ts +13 -0
  24. package/dist/lib/motely/motelyCompatEnums.d.ts +349 -0
  25. package/dist/lib/motely/runtime.d.ts +7 -4
  26. package/dist/lib/types.d.ts +1 -1
  27. package/dist/motely.d.ts +3 -2
  28. package/dist/motely.js +48 -220
  29. package/dist/motely.js.map +1 -1
  30. package/dist/r3f/Card3D.d.ts +55 -0
  31. package/dist/r3f/CardTable.d.ts +35 -0
  32. package/dist/r3f.d.ts +2 -0
  33. package/dist/ui/JimboPicker.d.ts +28 -0
  34. package/dist/ui/hooks.d.ts +1 -3
  35. package/dist/ui/jimbo.css +1 -1
  36. package/dist/ui.d.ts +1 -0
  37. package/dist/ui.js +3 -2
  38. package/package.json +25 -19
  39. package/dist/assets/searchPoolWorker-DHh9a5GD.js +0 -40
  40. package/dist/assets/searchPoolWorker-DHh9a5GD.js.map +0 -1
  41. package/dist/chunks/motelyItemFormats-Dyq1BINO.js.map +0 -1
  42. package/dist/chunks/searchPoolWorker-DgRqVj_q.js +0 -8
  43. package/dist/chunks/searchPoolWorker-DgRqVj_q.js.map +0 -1
  44. package/dist/chunks/ui-LfKBGL5-.js.map +0 -1
  45. package/dist/components/JamlCurator.d.ts +0 -1
  46. package/dist/components/Jamlyzer.d.ts +0 -8
  47. package/dist/hooks/useAnalyzer.d.ts +0 -16
  48. package/dist/lib/hooks/useSeedAnalyzer.d.ts +0 -13
  49. 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 { i as a, n as o, t as s } from "./chunks/motelyItemFormats-Dyq1BINO.js";
4
- import { useCallback as c, useEffect as ee, useState as l } from "react";
5
- import u, { Motely as d, Motely as f, MotelyItemEdition as p, MotelyItemEnhancement as m, MotelyItemSeal as h, MotelyStandardcardRank as g, MotelyStandardcardSuit as _ } from "motely-wasm";
6
- import { IFileMounter as te, PermissionMode as v } from "motely-wasm/bootsharp/file-system";
7
- //#region src/decode/motelyItemDecoder.ts
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 V(a) {
162
- let o = L(a);
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 H(a, o = "unknown") {
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 U = f;
221
- function W(e, t) {
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 G(e) {
226
- return W(U.MotelyBossBlind, e & 255) ?? `boss#${e}`;
73
+ function N(e) {
74
+ return M(j.MotelyBossBlind, e & 255) ?? `boss#${e}`;
227
75
  }
228
- function K(e) {
76
+ function P(e) {
229
77
  return e;
230
78
  }
231
- function q(e) {
232
- return W(U.MotelyVoucher, e) ?? `voucher#${e}`;
79
+ function F(e) {
80
+ return M(j.MotelyVoucher, e) ?? `voucher#${e}`;
233
81
  }
234
- function J(e) {
82
+ function I(e) {
235
83
  return e;
236
84
  }
237
- function ae(e) {
238
- return W(U.MotelyTag, e) ?? `tag#${e}`;
85
+ function L(e) {
86
+ return M(j.MotelyTag, e) ?? `tag#${e}`;
239
87
  }
240
- function oe(e) {
88
+ function R(e) {
241
89
  return e;
242
90
  }
243
- function se(e) {
244
- return W(U.MotelyBoosterPack, e) ?? `pack#${e}`;
91
+ function z(e) {
92
+ return M(j.MotelyBoosterPack, e) ?? `pack#${e}`;
245
93
  }
246
- function ce(e) {
94
+ function B(e) {
247
95
  return `${e} Pack`;
248
96
  }
249
- function le(e) {
97
+ function V(e) {
250
98
  return e;
251
99
  }
252
- function ue(e) {
253
- return s[e & 65535]?.displayName ?? `item#${e}`;
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
- var Y = null, X = null, Z = null;
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 de() {
271
- let [e, t] = l("idle"), [n, r] = l(null), [i, o] = l([]), [s, u] = l(null);
272
- ee(() => {
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: c(async () => {
289
- if (await Q(), Y === null) {
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 a();
296
- let e = await f.pickRoot({
297
- mode: v.ReadWrite,
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 f.mountRoot(e, { mode: v.ReadWrite })), o([]), t("ready");
132
+ r(await T.mountRoot(e, { mode: O.ReadWrite })), a([]), t("ready");
305
133
  } catch (e) {
306
- t("error"), u($(e));
134
+ t("error"), c(U(e));
307
135
  }
308
136
  }, []),
309
- unmount: c(async () => {
310
- n && (await a(), await f.unmountRoot(n), r(null), o([]), t(d ? "idle" : "unsupported"));
311
- }, [d, n]),
312
- loadFile: c(async (e) => {
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 a(), await f.readTextFile(n, e);
142
+ return await g(), await T.readTextFile(n, e);
315
143
  }, [n]),
316
- saveFile: c(async (e, t) => {
144
+ saveFile: C(async (e, t) => {
317
145
  if (!n) throw Error("JAML library is not mounted.");
318
- await a(), await f.writeTextFile(n, e, t), o((t) => (t.includes(e) ? t : [...t, e]).sort((e, t) => e.localeCompare(t)));
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: p
148
+ refresh: l
321
149
  };
322
150
  }
323
151
  //#endregion
324
- export { o as MOTELY_BIN_PATH, d as Motely, u as bootsharp, L as decodeMotelyItem, ie as decodeMotelyItemName, R as decodeMotelyItemToJamlCard, a as ensureMotelyReady, H as getMotelySpriteByName, se as motelyBoosterPackDisplayName, ce as motelyBoosterPackDisplayNameFromKey, G as motelyBossDisplayName, K as motelyBossDisplayNameFromKey, B as motelyItemCacheSize, k as motelyItemCategory, re as motelyItemDisplayName, le as motelyItemDisplayNameFromKey, ue as motelyItemDisplayNameFromValue, M as motelyItemEditionName, P as motelyItemEnhancementName, A as motelyItemRenderCategory, N as motelyItemSealName, V as motelyItemToSprite, O as motelyItemTypeName, F as motelyStandardcardRankName, I as motelyStandardcardSuitName, ae as motelyTagDisplayName, oe as motelyTagDisplayNameFromKey, q as motelyVoucherDisplayName, J as motelyVoucherDisplayNameFromKey, D as resolveMotelyItemType, de as useJamlLibrary, z as warmMotelyItemCache };
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
@@ -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,2 @@
1
+ export { Card3D, type Card3DProps } from './r3f/Card3D.js';
2
+ export { CardTable, type CardTableProps, type CardTableItem } from './r3f/CardTable.js';
@@ -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;
@@ -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). For 3D/spring-physics button
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: {