jaml-ui 0.24.20 → 0.25.2

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 (233) hide show
  1. package/README.md +0 -13
  2. package/assets/WeeJokerExampleDAilyGame.png +0 -0
  3. package/assets/balatro-stake-chips.png +0 -0
  4. package/dist/assets.d.ts +1 -2
  5. package/dist/chunks/Layer-BBPJFHfs.js +17 -0
  6. package/dist/chunks/Layer-BBPJFHfs.js.map +1 -0
  7. package/dist/chunks/assets-RWUiFSTc.js +37 -0
  8. package/dist/chunks/assets-RWUiFSTc.js.map +1 -0
  9. package/dist/chunks/motelyItemDecoder-CueyZ0XD.js +6039 -0
  10. package/dist/chunks/motelyItemDecoder-CueyZ0XD.js.map +1 -0
  11. package/dist/chunks/spriteMapper-CFjN0_TV.js +2415 -0
  12. package/dist/chunks/spriteMapper-CFjN0_TV.js.map +1 -0
  13. package/dist/chunks/tokens-B65Fzble.js +57 -0
  14. package/dist/chunks/tokens-B65Fzble.js.map +1 -0
  15. package/dist/chunks/ui-5cBy3zAm.js +1387 -0
  16. package/dist/chunks/ui-5cBy3zAm.js.map +1 -0
  17. package/dist/components/AnalyzerExplorer.d.ts +1 -1
  18. package/dist/components/CardFan.d.ts +1 -1
  19. package/dist/components/CardList.d.ts +1 -1
  20. package/dist/components/DeckSprite.d.ts +1 -1
  21. package/dist/components/JamlAestheticSelector.d.ts +1 -1
  22. package/dist/components/JamlAnalyzerFullscreen.d.ts +5 -5
  23. package/dist/components/JamlCurator.d.ts +1 -6
  24. package/dist/components/JamlIde.d.ts +5 -5
  25. package/dist/components/JamlSeedInput.d.ts +1 -1
  26. package/dist/components/JamlSpeedometer.d.ts +1 -1
  27. package/dist/components/MotelyVersionBadge.d.ts +1 -1
  28. package/dist/components/Standardcard.d.ts +1 -1
  29. package/dist/components/jamlMap/CategoryPicker.d.ts +3 -3
  30. package/dist/components/jamlMap/JamlMapEditor.d.ts +1 -1
  31. package/dist/components/jamlMap/JokerPicker.d.ts +1 -1
  32. package/dist/components/jamlMap/MysterySlot.d.ts +2 -2
  33. package/dist/components/jamlMap/index.d.ts +4 -4
  34. package/dist/core.d.ts +5 -5
  35. package/dist/core.js +27 -5
  36. package/dist/core.js.map +1 -0
  37. package/dist/decode/motelyItemDecoder.d.ts +0 -10
  38. package/dist/decode/motelySprite.d.ts +1 -1
  39. package/dist/fonts/m6x11plus.otf +0 -0
  40. package/dist/hooks/analyzerStreamRegistry.d.ts +2 -2
  41. package/dist/hooks/useAnalyzer.d.ts +3 -3
  42. package/dist/hooks/useSearch.d.ts +2 -2
  43. package/dist/index.d.ts +29 -31
  44. package/dist/index.js +16721 -34
  45. package/dist/index.js.map +1 -0
  46. package/dist/lib/const.d.ts +2 -2
  47. package/dist/lib/hooks/useDragScroll.d.ts +1 -1
  48. package/dist/lib/hooks/useJamlFilter.d.ts +2 -2
  49. package/dist/lib/hooks/useSeedAnalyzer.d.ts +2 -2
  50. package/dist/lib/utils.d.ts +1 -1
  51. package/dist/motely.d.ts +4 -3
  52. package/dist/motely.js +65 -3
  53. package/dist/motely.js.map +1 -0
  54. package/dist/motelyBoot.d.ts +2 -0
  55. package/dist/motelyDisplay.d.ts +0 -2
  56. package/dist/r3f/Card3D.d.ts +2 -2
  57. package/dist/r3f/JimboBillboard.d.ts +1 -1
  58. package/dist/r3f.js +235 -3
  59. package/dist/r3f.js.map +1 -0
  60. package/dist/render/CanvasRenderer.d.ts +1 -1
  61. package/dist/sprites/spriteData.d.ts +1 -6
  62. package/dist/sprites/spriteMapper.d.ts +1 -1
  63. package/dist/ui/JimboBadge.d.ts +1 -1
  64. package/dist/ui/JimboFloating.d.ts +1 -1
  65. package/dist/ui/JimboIconButton.d.ts +1 -1
  66. package/dist/ui/JimboSelect.d.ts +1 -1
  67. package/dist/ui/footer.d.ts +2 -3
  68. package/dist/ui/hooks.d.ts +1 -1
  69. package/dist/ui/ide/DeckSprite.d.ts +1 -1
  70. package/dist/ui/jimbo.css +2 -1856
  71. package/dist/ui/jimboApp.d.ts +1 -1
  72. package/dist/ui/jimboFilterBar.d.ts +1 -1
  73. package/dist/ui/jimboFlankNav.d.ts +1 -1
  74. package/dist/ui/jimboInfoCard.d.ts +1 -1
  75. package/dist/ui/jimboInset.d.ts +1 -1
  76. package/dist/ui/jimboStatGrid.d.ts +1 -1
  77. package/dist/ui/jimboText.d.ts +1 -1
  78. package/dist/ui/jimboTooltip.d.ts +2 -2
  79. package/dist/ui/mascot/SeedMascot.d.ts +2 -2
  80. package/dist/ui/panel.d.ts +1 -1
  81. package/dist/ui/radial/RadialBadge.d.ts +1 -2
  82. package/dist/ui/radial/RadialButton.d.ts +1 -2
  83. package/dist/ui/radial/RadialMenu.d.ts +2 -2
  84. package/dist/ui/radial/RadialPill.d.ts +1 -2
  85. package/dist/ui/radial/index.d.ts +16 -16
  86. package/dist/ui/radial/radialMenuStore.d.ts +1 -1
  87. package/dist/ui/showcase.d.ts +1 -1
  88. package/dist/ui/sprites.d.ts +2 -2
  89. package/dist/ui.d.ts +0 -1
  90. package/dist/ui.js +3 -36
  91. package/dist/utils/gameCardUtils.d.ts +1 -1
  92. package/dist/utils/jamlVisualFilter.d.ts +1 -7
  93. package/package.json +13 -25
  94. package/dist/assets.js +0 -48
  95. package/dist/components/AnalyzerExplorer.js +0 -391
  96. package/dist/components/CardFan.js +0 -80
  97. package/dist/components/CardList.js +0 -5
  98. package/dist/components/DeckSprite.js +0 -75
  99. package/dist/components/GameCard.js +0 -355
  100. package/dist/components/JamlAestheticSelector.js +0 -22
  101. package/dist/components/JamlAnalyzerFullscreen.js +0 -263
  102. package/dist/components/JamlCodeEditor.js +0 -137
  103. package/dist/components/JamlCurator.js +0 -64
  104. package/dist/components/JamlCurator.stories.d.ts +0 -6
  105. package/dist/components/JamlCurator.stories.js +0 -14
  106. package/dist/components/JamlIde.js +0 -193
  107. package/dist/components/JamlIdeToolbar.js +0 -23
  108. package/dist/components/JamlIdeVisual.js +0 -218
  109. package/dist/components/JamlMapPreview.js +0 -121
  110. package/dist/components/JamlSeedInput.js +0 -26
  111. package/dist/components/JamlSpeedometer.js +0 -70
  112. package/dist/components/Jimbolate.js +0 -17
  113. package/dist/components/MotelyVersionBadge.js +0 -19
  114. package/dist/components/PaginatedFilterBrowser.js +0 -54
  115. package/dist/components/RunConfigModal.js +0 -59
  116. package/dist/components/Standardcard.js +0 -80
  117. package/dist/components/jamlMap/CategoryPicker.js +0 -135
  118. package/dist/components/jamlMap/JamlMapEditor.js +0 -304
  119. package/dist/components/jamlMap/JamlMapEditor.stories.d.ts +0 -7
  120. package/dist/components/jamlMap/JamlMapEditor.stories.js +0 -26
  121. package/dist/components/jamlMap/JamlMapEditorDemo.d.ts +0 -8
  122. package/dist/components/jamlMap/JamlMapEditorDemo.js +0 -323
  123. package/dist/components/jamlMap/JokerPicker.js +0 -113
  124. package/dist/components/jamlMap/MysterySlot.js +0 -128
  125. package/dist/components/jamlMap/MysterySlot.stories.d.ts +0 -7
  126. package/dist/components/jamlMap/MysterySlot.stories.js +0 -31
  127. package/dist/components/jamlMap/index.js +0 -4
  128. package/dist/decode/motelyItemDecoder.js +0 -164
  129. package/dist/decode/motelySprite.js +0 -84
  130. package/dist/hooks/analyzerStreamRegistry.js +0 -96
  131. package/dist/hooks/searchWorker.d.ts +0 -1
  132. package/dist/hooks/searchWorker.js +0 -119
  133. package/dist/hooks/searchWorkerCode.d.ts +0 -1
  134. package/dist/hooks/searchWorkerCode.js +0 -85
  135. package/dist/hooks/useAnalyzer.js +0 -91
  136. package/dist/hooks/useIntersectionObserver.js +0 -52
  137. package/dist/hooks/useSearch.js +0 -161
  138. package/dist/hooks/useShopStream.js +0 -85
  139. package/dist/lib/SpriteMapper.js +0 -48
  140. package/dist/lib/cardParser.js +0 -67
  141. package/dist/lib/classes/BuyMetaData.js +0 -1
  142. package/dist/lib/config.js +0 -15
  143. package/dist/lib/const.js +0 -521
  144. package/dist/lib/data/constants.js +0 -14
  145. package/dist/lib/hooks/useDragScroll.js +0 -48
  146. package/dist/lib/hooks/useJamlFilter.js +0 -219
  147. package/dist/lib/hooks/useSeedAnalyzer.js +0 -50
  148. package/dist/lib/jaml/jamlCompletion.js +0 -13
  149. package/dist/lib/jaml/jamlData.js +0 -6
  150. package/dist/lib/jaml/jamlObjectives.js +0 -97
  151. package/dist/lib/jaml/jamlParser.js +0 -47
  152. package/dist/lib/jaml/jamlPresets.js +0 -61
  153. package/dist/lib/jaml/jamlSchema.js +0 -91
  154. package/dist/lib/parseDailyRitual.js +0 -70
  155. package/dist/lib/tts/getRevealPos.js +0 -16
  156. package/dist/lib/tts/splitTtsDisplay.js +0 -35
  157. package/dist/lib/types.js +0 -1
  158. package/dist/lib/utils.js +0 -5
  159. package/dist/motelyDisplay.js +0 -59
  160. package/dist/r3f/Card3D.js +0 -72
  161. package/dist/r3f/JimboBillboard.js +0 -32
  162. package/dist/r3f/JimboText3D.js +0 -8
  163. package/dist/render/CanvasRenderer.js +0 -11
  164. package/dist/render/Layer.js +0 -18
  165. package/dist/sprites/spriteData.js +0 -100
  166. package/dist/sprites/spriteMapper.js +0 -75
  167. package/dist/stories/Button.d.ts +0 -15
  168. package/dist/stories/Button.js +0 -7
  169. package/dist/stories/Button.stories.d.ts +0 -24
  170. package/dist/stories/Button.stories.js +0 -50
  171. package/dist/stories/Header.d.ts +0 -12
  172. package/dist/stories/Header.js +0 -4
  173. package/dist/stories/Header.stories.d.ts +0 -18
  174. package/dist/stories/Header.stories.js +0 -26
  175. package/dist/stories/Page.d.ts +0 -3
  176. package/dist/stories/Page.js +0 -8
  177. package/dist/stories/Page.stories.d.ts +0 -12
  178. package/dist/stories/Page.stories.js +0 -24
  179. package/dist/ui/Jimbo.stories.d.ts +0 -7
  180. package/dist/ui/Jimbo.stories.js +0 -28
  181. package/dist/ui/JimboBadge.js +0 -8
  182. package/dist/ui/JimboFloating.js +0 -17
  183. package/dist/ui/JimboIconButton.js +0 -28
  184. package/dist/ui/JimboInputModal.js +0 -66
  185. package/dist/ui/JimboSelect.js +0 -43
  186. package/dist/ui/JimboToggleList.js +0 -5
  187. package/dist/ui/PanelSplitter.js +0 -78
  188. package/dist/ui/codeBlock.js +0 -14
  189. package/dist/ui/footer.js +0 -20
  190. package/dist/ui/hooks.js +0 -634
  191. package/dist/ui/ide/AgnosticSeedCard.d.ts +0 -19
  192. package/dist/ui/ide/AgnosticSeedCard.js +0 -48
  193. package/dist/ui/ide/DeckSprite.js +0 -2
  194. package/dist/ui/ide/JamlBuilder.d.ts +0 -1
  195. package/dist/ui/ide/JamlBuilder.js +0 -112
  196. package/dist/ui/ide/JamlEditor.js +0 -486
  197. package/dist/ui/ide/JamlEditorMonaco.d.ts +0 -8
  198. package/dist/ui/ide/JamlEditorMonaco.js +0 -78
  199. package/dist/ui/ide/WasmStatus.d.ts +0 -1
  200. package/dist/ui/ide/WasmStatus.js +0 -42
  201. package/dist/ui/jimboApp.js +0 -15
  202. package/dist/ui/jimboBackground.js +0 -27
  203. package/dist/ui/jimboCopyRow.js +0 -18
  204. package/dist/ui/jimboFilterBar.js +0 -16
  205. package/dist/ui/jimboFlankNav.js +0 -18
  206. package/dist/ui/jimboInfoCard.js +0 -26
  207. package/dist/ui/jimboInset.js +0 -9
  208. package/dist/ui/jimboSectionHeader.js +0 -9
  209. package/dist/ui/jimboStatGrid.js +0 -9
  210. package/dist/ui/jimboTabs.js +0 -22
  211. package/dist/ui/jimboText.js +0 -33
  212. package/dist/ui/jimboTooltip.js +0 -39
  213. package/dist/ui/jimboWordmark.js +0 -9
  214. package/dist/ui/mascot/JammySpeechBox.js +0 -30
  215. package/dist/ui/mascot/SeedMascot.js +0 -17
  216. package/dist/ui/mascot/index.js +0 -3
  217. package/dist/ui/mascot/menuConfig.js +0 -12
  218. package/dist/ui/panel.js +0 -24
  219. package/dist/ui/radial/RadialBadge.js +0 -43
  220. package/dist/ui/radial/RadialBreadcrumb.js +0 -18
  221. package/dist/ui/radial/RadialButton.js +0 -102
  222. package/dist/ui/radial/RadialMenu.js +0 -168
  223. package/dist/ui/radial/RadialPill.js +0 -15
  224. package/dist/ui/radial/index.js +0 -18
  225. package/dist/ui/radial/radialMenuStore.js +0 -122
  226. package/dist/ui/radial/radialMenuViewport.js +0 -59
  227. package/dist/ui/radial/useRadialMenu.js +0 -107
  228. package/dist/ui/showcase.js +0 -20
  229. package/dist/ui/sprites.js +0 -77
  230. package/dist/ui/tokens.js +0 -64
  231. package/dist/utils/gameCardUtils.js +0 -15
  232. package/dist/utils/jamlMapPreview.js +0 -106
  233. package/dist/utils/jamlVisualFilter.js +0 -210
@@ -1,323 +0,0 @@
1
- "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useState, useCallback, useMemo } from "react";
4
- import { MysterySlot } from "./MysterySlot.js";
5
- import { JokerPicker } from "./JokerPicker.js";
6
- import { CategoryPicker, VOUCHER_PICKER_CONFIG, TAG_PICKER_CONFIG, BOSS_PICKER_CONFIG, TAROT_PICKER_CONFIG, PLANET_PICKER_CONFIG, SPECTRAL_PICKER_CONFIG, PACK_PICKER_CONFIG, } from "./CategoryPicker.js";
7
- import { JimboColorOption, withAlpha } from "../../ui/tokens.js";
8
- // ─── Category menu items ─────────────────────────────────────────────────────
9
- const C = JimboColorOption;
10
- const CATEGORIES = [
11
- { key: "joker", label: "Joker", icon: "🃏", color: C.BLUE, hint: "Shop, Buffoon Pack" },
12
- { key: "voucher", label: "Voucher", icon: "🎫", color: C.GOLD, hint: "1 per Ante in shop" },
13
- { key: "tarot", label: "Tarot Card", icon: "🔮", color: C.PURPLE, hint: "Arcana Pack, shop" },
14
- { key: "planet", label: "Planet Card", icon: "🪐", color: C.BLUE, hint: "Celestial Pack, shop" },
15
- { key: "spectral", label: "Spectral Card", icon: "👻", color: C.TEAL_GREY, hint: "Ghost Deck, Spectral Pack" },
16
- { key: "tag", label: "Tag", icon: "🏷️", color: C.GREEN, hint: "Skip blind reward" },
17
- { key: "boss", label: "Boss Blind", icon: "👁️", color: C.RED, hint: "End of each Ante" },
18
- { key: "pack", label: "Booster Pack", icon: "📦", color: C.ORANGE, hint: "Arcana, Celestial, etc." },
19
- ];
20
- // ─── Component ───────────────────────────────────────────────────────────────
21
- const INITIAL_SLOTS = 8;
22
- export function JamlMapEditorDemo({ zone: initialZone = "must", onChange, }) {
23
- const [zone, setZone] = useState(initialZone);
24
- const [slots, setSlots] = useState(Array(INITIAL_SLOTS).fill(null));
25
- const [activeSlot, setActiveSlot] = useState(null);
26
- const [pickerFlow, setPickerFlow] = useState("category");
27
- const handleSlotTap = useCallback((index) => {
28
- setActiveSlot(index);
29
- setPickerFlow("category");
30
- }, []);
31
- const handleSlotClear = useCallback((index) => {
32
- setSlots((prev) => {
33
- const next = [...prev];
34
- next[index] = null;
35
- onChange?.(next);
36
- return next;
37
- });
38
- }, [onChange]);
39
- const handleCategorySelect = useCallback((cat) => {
40
- if (cat === "joker") {
41
- setPickerFlow("joker");
42
- }
43
- else {
44
- setPickerFlow(cat);
45
- }
46
- }, []);
47
- const handleItemSelect = useCallback((selection) => {
48
- if (activeSlot === null)
49
- return;
50
- setSlots((prev) => {
51
- const next = [...prev];
52
- next[activeSlot] = selection;
53
- onChange?.(next);
54
- return next;
55
- });
56
- setActiveSlot(null);
57
- }, [activeSlot, onChange]);
58
- const handlePickerCancel = useCallback(() => {
59
- if (pickerFlow !== "category") {
60
- // Go back to category selection
61
- setPickerFlow("category");
62
- }
63
- else {
64
- setActiveSlot(null);
65
- }
66
- }, [pickerFlow]);
67
- const handleOverlayClose = useCallback(() => {
68
- setActiveSlot(null);
69
- }, []);
70
- const filledCount = slots.filter(Boolean).length;
71
- // Build the JSON tree from slots
72
- const jsonTree = useMemo(() => buildJsonTree(zone, slots), [zone, slots]);
73
- return (_jsxs("div", { style: styles.wrapper, children: [_jsx("div", { style: styles.zoneBar, children: ["must", "should", "mustnot"].map((z) => (_jsx("button", { onClick: () => setZone(z), style: {
74
- ...styles.zoneBtn,
75
- borderColor: zone === z ? ZONE_COLORS[z] : C.TEAL_GREY,
76
- color: zone === z ? ZONE_COLORS[z] : C.GREY,
77
- background: zone === z ? withAlpha(ZONE_COLORS[z], 0.1) : "transparent",
78
- }, children: z.toUpperCase() }, z))) }), _jsxs("div", { style: styles.sectionLabel, children: [_jsx("span", { style: { color: ZONE_COLORS[zone] }, children: "Shop Items" }), _jsxs("span", { style: { color: C.GREY, fontSize: 11 }, children: [filledCount, "/", INITIAL_SLOTS, " defined"] })] }), _jsx("div", { style: styles.slotRow, children: slots.map((selection, i) => (_jsx(MysterySlot, { zone: zone, sheetType: "Jokers", selection: selection ?? undefined, width: 48, onTap: () => handleSlotTap(i), onClear: selection ? () => handleSlotClear(i) : undefined }, i))) }), _jsx("div", { style: styles.scrollHint, children: "\u25C0 swipe \u25B6" }), activeSlot !== null && (_jsxs("div", { style: styles.overlay, children: [_jsx("div", { style: styles.overlayBackdrop, onClick: handleOverlayClose }), _jsx("div", { style: styles.pickerWrapper, children: pickerFlow === "category" ? (_jsx(CategoryMenu, { onSelect: handleCategorySelect, onCancel: handleOverlayClose })) : pickerFlow === "joker" ? (_jsx(JokerPicker, { onSelect: handleItemSelect, onCancel: handlePickerCancel })) : (_jsx(CategoryPicker, { config: CATEGORY_CONFIG_MAP[pickerFlow], onSelect: handleItemSelect, onCancel: handlePickerCancel })) })] })), filledCount > 0 && (_jsxs("div", { style: styles.jsonPreview, children: [_jsxs("div", { style: styles.jsonHeader, children: [_jsx("span", { children: "Filter Preview" }), _jsx("span", { style: { fontSize: 10, opacity: 0.6 }, children: "JSON" })] }), _jsx("div", { style: styles.jsonBody, children: _jsx(JsonTreeNode, { data: jsonTree, indent: 0 }) })] }))] }));
79
- }
80
- // ─── Category Selection Menu ─────────────────────────────────────────────────
81
- function CategoryMenu({ onSelect, onCancel, }) {
82
- return (_jsxs("div", { style: styles.catMenuContainer, children: [_jsxs("div", { style: styles.catMenuHeader, children: [_jsx("button", { onClick: onCancel, style: styles.backBtn, children: "\u2715" }), _jsx("span", { style: styles.catMenuTitle, children: "Select Category" }), _jsx("div", { style: { width: 44 } })] }), _jsx("div", { style: styles.catGrid, children: CATEGORIES.map((cat) => (_jsxs("button", { onClick: () => onSelect(cat.key), style: {
83
- ...styles.catBtn,
84
- borderColor: withAlpha(cat.color, 0.3),
85
- }, children: [_jsx("span", { style: styles.catIcon, children: cat.icon }), _jsxs("div", { style: styles.catText, children: [_jsx("span", { style: { ...styles.catLabel, color: cat.color }, children: cat.label }), _jsx("span", { style: styles.catHint, children: cat.hint })] })] }, cat.key))) })] }));
86
- }
87
- // ─── JSON tree renderer ──────────────────────────────────────────────────────
88
- function JsonTreeNode({ data, indent }) {
89
- if (data === null || data === undefined) {
90
- return _jsx("span", { style: { color: C.GREY }, children: "null" });
91
- }
92
- if (typeof data === "string") {
93
- return _jsxs("span", { style: { color: C.GREEN_TEXT }, children: ["\"", data, "\""] });
94
- }
95
- if (typeof data === "number" || typeof data === "boolean") {
96
- return _jsx("span", { style: { color: C.GOLD }, children: String(data) });
97
- }
98
- if (Array.isArray(data)) {
99
- if (data.length === 0)
100
- return _jsx("span", { style: { color: C.GREY }, children: "[]" });
101
- return (_jsxs("span", { children: [_jsx("span", { style: { color: C.GREY }, children: "[" }), data.map((item, i) => (_jsxs("div", { style: { paddingLeft: (indent + 1) * 14 }, children: [_jsx(JsonTreeNode, { data: item, indent: indent + 1 }), i < data.length - 1 && _jsx("span", { style: { color: C.GREY }, children: "," })] }, i))), _jsx("div", { style: { paddingLeft: indent * 14 }, children: _jsx("span", { style: { color: C.GREY }, children: "]" }) })] }));
102
- }
103
- if (typeof data === "object") {
104
- const entries = Object.entries(data);
105
- if (entries.length === 0)
106
- return _jsx("span", { style: { color: C.GREY }, children: "{}" });
107
- return (_jsxs("span", { children: [_jsx("span", { style: { color: C.GREY }, children: "{" }), entries.map(([key, val], i) => (_jsxs("div", { style: { paddingLeft: (indent + 1) * 14 }, children: [_jsx("span", { style: { color: C.BLUE }, children: key }), _jsx("span", { style: { color: C.GREY }, children: ": " }), _jsx(JsonTreeNode, { data: val, indent: indent + 1 }), i < entries.length - 1 && _jsx("span", { style: { color: C.GREY }, children: "," })] }, key))), _jsx("div", { style: { paddingLeft: indent * 14 }, children: _jsx("span", { style: { color: C.GREY }, children: "}" }) })] }));
108
- }
109
- return _jsx("span", { children: String(data) });
110
- }
111
- // ─── Build JSON tree from slots ──────────────────────────────────────────────
112
- function buildJsonTree(zone, slots) {
113
- const filled = slots.filter(Boolean);
114
- if (filled.length === 0)
115
- return {};
116
- const jamlZone = zone === "mustnot" ? "mustNot" : zone;
117
- // Group by clauseKey
118
- const groups = new Map();
119
- for (const s of filled) {
120
- const existing = groups.get(s.clauseKey) ?? [];
121
- existing.push(s.value);
122
- groups.set(s.clauseKey, existing);
123
- }
124
- const clauses = [];
125
- for (const [key, values] of groups) {
126
- if (values.length === 1) {
127
- clauses.push({ [key]: values[0] });
128
- }
129
- else {
130
- clauses.push({ [key]: values });
131
- }
132
- }
133
- return { [jamlZone]: clauses };
134
- }
135
- // ─── Category → picker config mapping ────────────────────────────────────────
136
- const CATEGORY_CONFIG_MAP = {
137
- joker: VOUCHER_PICKER_CONFIG, // Not used — routed to JokerPicker
138
- voucher: VOUCHER_PICKER_CONFIG,
139
- tag: TAG_PICKER_CONFIG,
140
- boss: BOSS_PICKER_CONFIG,
141
- tarot: TAROT_PICKER_CONFIG,
142
- planet: PLANET_PICKER_CONFIG,
143
- spectral: SPECTRAL_PICKER_CONFIG,
144
- pack: PACK_PICKER_CONFIG,
145
- };
146
- // ─── Zone colors ─────────────────────────────────────────────────────────────
147
- const ZONE_COLORS = {
148
- must: C.BLUE,
149
- should: C.RED,
150
- mustnot: C.ORANGE,
151
- };
152
- // ─── Styles ──────────────────────────────────────────────────────────────────
153
- const styles = {
154
- wrapper: {
155
- position: "relative",
156
- padding: 16,
157
- background: C.DARKEST,
158
- borderRadius: 8,
159
- border: `1px solid ${C.TEAL_GREY}`,
160
- fontFamily: "m6x11plus, ui-monospace, monospace",
161
- },
162
- zoneBar: {
163
- display: "flex",
164
- gap: 6,
165
- marginBottom: 12,
166
- },
167
- zoneBtn: {
168
- padding: "5px 12px",
169
- border: "2px solid",
170
- borderRadius: 4,
171
- background: "none",
172
- fontFamily: "m6x11plus, ui-monospace, monospace",
173
- fontSize: 12,
174
- fontWeight: "bold",
175
- cursor: "pointer",
176
- transition: "all 150ms",
177
- letterSpacing: 1,
178
- },
179
- sectionLabel: {
180
- display: "flex",
181
- justifyContent: "space-between",
182
- alignItems: "center",
183
- marginBottom: 8,
184
- fontSize: 14,
185
- fontWeight: "bold",
186
- },
187
- slotRow: {
188
- display: "flex",
189
- gap: 6,
190
- overflowX: "auto",
191
- paddingBottom: 8,
192
- WebkitOverflowScrolling: "touch",
193
- },
194
- scrollHint: {
195
- textAlign: "center",
196
- fontSize: 10,
197
- color: C.GREY,
198
- opacity: 0.5,
199
- marginTop: 2,
200
- marginBottom: 8,
201
- },
202
- overlay: {
203
- position: "fixed",
204
- inset: 0,
205
- zIndex: 9999,
206
- display: "flex",
207
- alignItems: "center",
208
- justifyContent: "center",
209
- },
210
- overlayBackdrop: {
211
- position: "absolute",
212
- inset: 0,
213
- background: withAlpha(C.BLACK, 0.6),
214
- backdropFilter: "blur(4px)",
215
- },
216
- pickerWrapper: {
217
- position: "relative",
218
- zIndex: 1,
219
- width: "90%",
220
- maxWidth: 420,
221
- },
222
- // Category menu
223
- catMenuContainer: {
224
- background: C.DARKEST,
225
- border: `2px solid ${C.TEAL_GREY}`,
226
- borderRadius: 8,
227
- overflow: "hidden",
228
- fontFamily: "m6x11plus, ui-monospace, monospace",
229
- boxShadow: `0 8px 32px ${withAlpha(C.BLACK, 0.6)}`,
230
- },
231
- catMenuHeader: {
232
- display: "flex",
233
- alignItems: "center",
234
- justifyContent: "space-between",
235
- padding: "10px 12px",
236
- borderBottom: `1px solid ${C.TEAL_GREY}`,
237
- background: withAlpha(C.DARK_GREY, 0.5),
238
- },
239
- catMenuTitle: {
240
- color: C.WHITE,
241
- fontSize: 16,
242
- fontWeight: "bold",
243
- letterSpacing: 0.5,
244
- },
245
- backBtn: {
246
- background: "none",
247
- border: "none",
248
- color: C.GREY,
249
- fontFamily: "m6x11plus, ui-monospace, monospace",
250
- fontSize: 14,
251
- cursor: "pointer",
252
- padding: "4px 8px",
253
- },
254
- catGrid: {
255
- display: "grid",
256
- gridTemplateColumns: "1fr 1fr",
257
- gap: 6,
258
- padding: 10,
259
- maxHeight: "70vh",
260
- overflowY: "auto",
261
- },
262
- catBtn: {
263
- display: "flex",
264
- alignItems: "center",
265
- gap: 8,
266
- padding: "10px 10px",
267
- border: "1px solid",
268
- borderRadius: 6,
269
- cursor: "pointer",
270
- background: withAlpha(C.DARK_GREY, 0.3),
271
- textAlign: "left",
272
- transition: "background 150ms, transform 100ms",
273
- fontFamily: "m6x11plus, ui-monospace, monospace",
274
- },
275
- catIcon: {
276
- fontSize: 20,
277
- flexShrink: 0,
278
- },
279
- catText: {
280
- display: "flex",
281
- flexDirection: "column",
282
- gap: 2,
283
- minWidth: 0,
284
- },
285
- catLabel: {
286
- fontSize: 13,
287
- fontWeight: "bold",
288
- fontFamily: "m6x11plus, ui-monospace, monospace",
289
- },
290
- catHint: {
291
- fontSize: 9,
292
- color: C.GREY,
293
- fontFamily: "m6x11plus, ui-monospace, monospace",
294
- lineHeight: "1.2",
295
- },
296
- // JSON preview
297
- jsonPreview: {
298
- marginTop: 12,
299
- borderRadius: 4,
300
- border: `1px solid ${C.TEAL_GREY}`,
301
- overflow: "hidden",
302
- },
303
- jsonHeader: {
304
- padding: "6px 10px",
305
- fontSize: 11,
306
- color: C.GREY,
307
- background: withAlpha(C.DARK_GREY, 0.5),
308
- borderBottom: `1px solid ${C.TEAL_GREY}`,
309
- letterSpacing: 1,
310
- textTransform: "uppercase",
311
- display: "flex",
312
- justifyContent: "space-between",
313
- alignItems: "center",
314
- },
315
- jsonBody: {
316
- padding: "8px 10px",
317
- fontSize: 12,
318
- background: withAlpha(C.DARKEST, 0.8),
319
- lineHeight: "1.6",
320
- fontFamily: "m6x11plus, ui-monospace, monospace",
321
- overflowX: "auto",
322
- },
323
- };
@@ -1,113 +0,0 @@
1
- "use client";
2
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
- import { useState, useCallback, useMemo } from "react";
4
- import { JimboSprite } from "../../ui/sprites.js";
5
- import { JimboColorOption } from "../../ui/tokens.js";
6
- import { JimboButton } from "../../ui/panel.js";
7
- import { JimboText } from "../../ui/jimboText.js";
8
- import { JOKERS } from "../../sprites/spriteData.js";
9
- const LEGENDARY_JOKERS = new Set([
10
- "Canio", "Triboulet", "Yorick", "Chicot", "Perkeo",
11
- ]);
12
- const RARE_JOKERS = new Set([
13
- "Blueprint", "Brainstorm", "Drivers License", "Burnt Joker",
14
- "Cartomancer", "Astronomer", "Satellite", "Shoot the Moon",
15
- "The Idol", "Seeing Double", "Matador", "Hit the Road",
16
- "The Duo", "The Trio", "The Family", "The Order", "The Tribe",
17
- "Stuntman", "Invisible Joker", "Showman", "Flower Pot",
18
- "Glass Joker", "Wee Joker", "Merry Andy", "Oops! All 6s",
19
- "Certificate", "Smeared Joker", "Throwback", "Hanging Chad",
20
- "Rough Gem", "Bloodstone", "Arrowhead", "Onyx Agate",
21
- ]);
22
- const UNCOMMON_JOKERS = new Set([
23
- "Greedy Joker", "Lusty Joker", "Wrathful Joker", "Gluttonous Joker",
24
- "Jolly Joker", "Zany Joker", "Mad Joker", "Crazy Joker", "Droll Joker",
25
- "Sly Joker", "Wily Joker", "Clever Joker", "Devious Joker", "Crafty Joker",
26
- "Joker Stencil", "Four Fingers", "Mime", "Credit Card",
27
- "Ceremonial Dagger", "Banner", "Mystic Summit", "Marble Joker",
28
- "Loyalty Card", "8 Ball", "Misprint", "Dusk", "Raised Fist",
29
- "Fibonacci", "Steel Joker", "Scary Face", "Abstract Joker",
30
- "Delayed Gratification", "Hack", "Pareidolia", "Gros Michel",
31
- "Even Steven", "Odd Todd", "Scholar", "Business Card", "Supernova",
32
- "Ride the Bus", "Space Joker", "Egg", "Burglar", "Blackboard",
33
- "Runner", "Ice Cream", "DNA", "Splash", "Blue Joker",
34
- "Sixth Sense", "Constellation", "Hiker", "Faceless Joker",
35
- "Green Joker", "Superposition", "To Do List", "Cavendish",
36
- "Card Sharp", "Red Card", "Madness", "Square Joker",
37
- "Seance", "Riff-raff", "Vampire", "Shortcut",
38
- "Hologram", "Vagabond", "Baron", "Cloud 9", "Rocket", "Obelisk",
39
- "Midas Mask", "Luchador", "Photograph", "Gift Card", "Turtle Bean",
40
- "Erosion", "Reserved Parking", "Mail In Rebate", "To the Moon", "Hallucination",
41
- "Fortune Teller", "Golden Joker", "Lucky Cat", "Baseball Card", "Bull",
42
- "Diet Cola", "Trading Card", "Flash Card", "Popcorn",
43
- "Spare Trousers", "Ancient Joker", "Ramen", "Walkie Talkie",
44
- "Seltzer", "Castle", "Smiley Face", "Campfire",
45
- "Golden Ticket", "Mr. Bones", "Acrobat", "Sock and Buskin",
46
- "Swashbuckler", "Troubadour", "Bootstraps",
47
- ]);
48
- function getJokerRarity(name) {
49
- if (LEGENDARY_JOKERS.has(name))
50
- return "legendary";
51
- if (RARE_JOKERS.has(name))
52
- return "rare";
53
- if (UNCOMMON_JOKERS.has(name))
54
- return "uncommon";
55
- return "common";
56
- }
57
- // ─── Rarity → JimboButton tones ──────────────────────────────────────────────
58
- const C = JimboColorOption;
59
- const RARITY_META = {
60
- common: { label: "Common", tone: "blue", hint: "Found in shops and Buffoon Packs" },
61
- uncommon: { label: "Uncommon", tone: "green", hint: "Found in shops and Buffoon Packs" },
62
- rare: { label: "Rare", tone: "red", hint: "Found in shops and Buffoon Packs" },
63
- legendary: { label: "Legendary", tone: "tarot", hint: "Spawns from The Soul only!" },
64
- };
65
- export function JokerPicker({ onSelect }) {
66
- const [step, setStep] = useState("rarity");
67
- const [selectedRarity, setSelectedRarity] = useState(null);
68
- const [search, setSearch] = useState("");
69
- const filteredJokers = useMemo(() => {
70
- if (!selectedRarity)
71
- return [];
72
- return JOKERS.filter((j) => {
73
- if (getJokerRarity(j.name) !== selectedRarity)
74
- return false;
75
- if (search && !j.name.toLowerCase().includes(search.toLowerCase()))
76
- return false;
77
- return true;
78
- });
79
- }, [selectedRarity, search]);
80
- const handleRaritySelect = useCallback((rarity) => {
81
- setSelectedRarity(rarity);
82
- setStep("specific");
83
- setSearch("");
84
- }, []);
85
- const handleJokerSelect = useCallback((joker) => {
86
- onSelect({
87
- category: "joker",
88
- value: joker.name,
89
- clauseKey: selectedRarity === "legendary" ? "legendaryJoker"
90
- : selectedRarity === "rare" ? "rareJoker"
91
- : selectedRarity === "uncommon" ? "uncommonJoker"
92
- : "commonJoker",
93
- rarity: selectedRarity ?? "common",
94
- });
95
- }, [onSelect, selectedRarity]);
96
- return (_jsxs("div", { style: { padding: 0, display: "flex", flexDirection: "column" }, children: [step === "rarity" && (_jsx("div", { className: "j-flex-col j-gap-sm", style: { padding: 10 }, children: ["common", "uncommon", "rare", "legendary"].map((rarity) => {
97
- const meta = RARITY_META[rarity];
98
- return (_jsx(JimboButton, { tone: meta.tone, size: "md", fullWidth: true, onClick: () => handleRaritySelect(rarity), children: _jsxs("span", { style: { display: "flex", flexDirection: "column", gap: 2, textAlign: "left", width: "100%" }, children: [_jsx("span", { children: meta.label }), _jsx("span", { style: { fontSize: 9, opacity: 0.7 }, children: meta.hint })] }) }, rarity));
99
- }) })), step === "specific" && selectedRarity && (_jsxs(_Fragment, { children: [_jsx("div", { className: "j-flex j-items-center j-justify-center", style: { padding: "8px 10px 4px" }, children: _jsxs(JimboText, { size: "md", children: [RARITY_META[selectedRarity].label, " Jokers"] }) }), _jsx("div", { className: "j-flex j-gap-sm", style: { padding: "4px 10px 4px" }, children: _jsx("input", { className: "j-seed-input__field", type: "text", placeholder: "Search jokers...", value: search, onChange: (e) => setSearch(e.target.value), style: { fontSize: 13, padding: "6px 10px", textTransform: "none", letterSpacing: "0.04em" } }) }), selectedRarity === "legendary" && (_jsx("div", { className: "j-inner-panel", style: { margin: "4px 10px 6px", padding: "6px 10px" }, children: _jsx(JimboText, { size: "xs", tone: "purple", children: "Legendary jokers spawn from The Soul. Find it in Arcana Pack, Spectral Pack, Charm Tag, or Ethereal Tag only!" }) })), _jsxs("div", { style: {
100
- display: "grid",
101
- gridTemplateColumns: "repeat(auto-fill, minmax(64px, 1fr))",
102
- gap: 6,
103
- padding: "8px 10px 10px"
104
- }, children: [filteredJokers.map((joker) => (_jsxs("div", { onClick: () => handleJokerSelect(joker), title: joker.name, style: {
105
- display: "flex",
106
- flexDirection: "column",
107
- alignItems: "center",
108
- gap: 3,
109
- padding: 4,
110
- borderRadius: 4,
111
- cursor: "pointer",
112
- }, children: [_jsx(JimboSprite, { name: joker.name, sheet: "Jokers", width: 48 }), _jsx(JimboText, { size: "micro", tone: "grey", style: { maxWidth: 60, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: joker.name })] }, joker.name))), filteredJokers.length === 0 && (_jsx("div", { style: { gridColumn: "1 / -1", padding: 20, textAlign: "center" }, children: _jsxs(JimboText, { size: "sm", tone: "grey", children: ["No jokers match \"", search, "\""] }) }))] }), _jsx("div", { style: { padding: "4px 10px 10px" }, children: _jsx(JimboButton, { tone: "orange", size: "md", fullWidth: true, onClick: () => setStep("rarity"), children: "Back" }) })] }))] }));
113
- }
@@ -1,128 +0,0 @@
1
- "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import React, { useState } from "react";
4
- import { JimboSprite } from "../../ui/sprites.js";
5
- import { JimboColorOption, withAlpha, JIMBO_ANIMATIONS } from "../../ui/tokens.js";
6
- // ─── Zone colors ─────────────────────────────────────────────────────────────
7
- const C = JimboColorOption;
8
- const ZONE_BORDER = {
9
- must: C.BLUE,
10
- should: C.RED,
11
- mustnot: C.ORANGE,
12
- };
13
- // ─── Sheet → "Any" wildcard mapping ─────────────────────────────────────────
14
- // ─── Component ───────────────────────────────────────────────────────────────
15
- export function MysterySlot({ zone, sheetType, selection, width = 56, onTap, onClear, style, }) {
16
- const [hover, setHover] = useState(false);
17
- const [pressed, setPressed] = useState(false);
18
- const [tilt, setTilt] = useState({ rx: 0, ry: 0, tx: 0, ty: 0 });
19
- const cardRef = React.useRef(null);
20
- const borderColor = ZONE_BORDER[zone];
21
- const isEmpty = !selection;
22
- const cardH = Math.round((width * 95) / 71);
23
- const spriteName = selection?.packName ?? selection?.value ?? "";
24
- const spriteSheet = selection?.packName
25
- ? "Boosters"
26
- : selection
27
- ? categoryToSheet(selection.category) ?? sheetType
28
- : sheetType;
29
- const scale = pressed
30
- ? 0.95
31
- : hover
32
- ? JIMBO_ANIMATIONS.JUICE_UP_SCALE
33
- : 1;
34
- const handleMouseMove = (e) => {
35
- if (!cardRef.current)
36
- return;
37
- const rect = cardRef.current.getBoundingClientRect();
38
- // Normalize coordinates: -1 to 1
39
- const nx = Math.max(-1, Math.min(1, ((e.clientX - rect.left) / rect.width - 0.5) * 2));
40
- const ny = Math.max(-1, Math.min(1, ((e.clientY - rect.top) / rect.height - 0.5) * 2));
41
- setTilt({
42
- rx: ny * -8, // subtle max 8deg tilt
43
- ry: nx * 8,
44
- tx: nx * -2, // subtle shift
45
- ty: ny * -2,
46
- });
47
- };
48
- const handleMouseLeave = () => {
49
- setHover(false);
50
- setPressed(false);
51
- setTilt({ rx: 0, ry: 0, tx: 0, ty: 0 });
52
- };
53
- return (_jsx("div", { ref: cardRef, onClick: onTap, onMouseEnter: () => setHover(true), onMouseLeave: handleMouseLeave, onMouseMove: handleMouseMove, onMouseDown: () => setPressed(true), onMouseUp: () => setPressed(false), style: {
54
- position: "relative",
55
- width: width + 8,
56
- height: cardH + 8,
57
- cursor: onTap ? "pointer" : "default",
58
- ...style,
59
- }, children: _jsxs("div", { style: {
60
- position: "absolute",
61
- inset: 0,
62
- display: "flex",
63
- alignItems: "center",
64
- justifyContent: "center",
65
- borderRadius: 6,
66
- border: isEmpty
67
- ? `2px dashed ${withAlpha(borderColor, 0.4)}`
68
- : `3px solid ${borderColor}`,
69
- background: isEmpty
70
- ? withAlpha(borderColor, 0.06)
71
- : withAlpha(C.DARKEST, 0.8),
72
- transform: `perspective(600px) scale(${scale}) rotateX(${tilt.rx}deg) rotateY(${tilt.ry}deg) translate(${tilt.tx}px, ${tilt.ty}px)`,
73
- transformStyle: "preserve-3d",
74
- transition: hover
75
- ? `border-color 200ms`
76
- : `transform 400ms ${JIMBO_ANIMATIONS.JUICE_EASING}, border-color 200ms`,
77
- boxShadow: hover ? `0 8px 16px ${withAlpha(C.BLACK, 0.4)}` : `0 2px 4px ${withAlpha(C.BLACK, 0.2)}`,
78
- zIndex: hover ? 10 : 1,
79
- pointerEvents: "none",
80
- }, children: [_jsx(JimboSprite, { name: spriteName, sheet: spriteSheet, width: width, style: {
81
- opacity: isEmpty ? 0.5 : 1,
82
- filter: isEmpty ? "saturate(0.3)" : "none",
83
- transition: "opacity 200ms, filter 200ms",
84
- } }), selection && onClear && (_jsx("div", { onClick: (e) => { e.stopPropagation(); onClear(); }, style: {
85
- position: "absolute",
86
- top: -6,
87
- right: -6,
88
- width: 18,
89
- height: 18,
90
- borderRadius: "50%",
91
- background: C.RED,
92
- color: C.WHITE,
93
- display: "flex",
94
- alignItems: "center",
95
- justifyContent: "center",
96
- fontSize: 11,
97
- fontFamily: "m6x11plus, ui-monospace, monospace",
98
- cursor: "pointer",
99
- lineHeight: 1,
100
- boxShadow: `0 1px 4px ${withAlpha(C.BLACK, 0.5)}`,
101
- transform: "translateZ(10px)", // Pop out in 3D
102
- }, children: "\u00D7" })), isEmpty && hover && (_jsx("div", { style: {
103
- position: "absolute",
104
- bottom: -16,
105
- left: "50%",
106
- transform: "translateX(-50%) translateZ(10px)",
107
- fontFamily: "m6x11plus, ui-monospace, monospace",
108
- fontSize: 10,
109
- color: borderColor,
110
- whiteSpace: "nowrap",
111
- textTransform: "uppercase",
112
- letterSpacing: 1,
113
- }, children: "+ tap" }))] }) }));
114
- }
115
- // ─── Helpers ─────────────────────────────────────────────────────────────────
116
- function categoryToSheet(cat) {
117
- switch (cat) {
118
- case "joker": return "Jokers";
119
- case "voucher": return "Vouchers";
120
- case "tag": return "tags";
121
- case "boss": return "BlindChips";
122
- case "tarot":
123
- case "spectral":
124
- case "planet": return "Tarots";
125
- case "pack": return "Boosters";
126
- default: return null;
127
- }
128
- }
@@ -1,7 +0,0 @@
1
- import type { StoryObj } from '@storybook/react';
2
- import { MysterySlot } from './MysterySlot';
3
- declare const meta: Meta<typeof MysterySlot>;
4
- export default meta;
5
- type Story = StoryObj<typeof meta>;
6
- export declare const Empty: Story;
7
- export declare const FilledJoker: Story;
@@ -1,31 +0,0 @@
1
- import { jsx as _jsx } from "react/jsx-runtime";
2
- import { MysterySlot } from './MysterySlot';
3
- const meta = {
4
- title: 'JAML/MysterySlot',
5
- component: MysterySlot,
6
- parameters: {
7
- layout: 'centered',
8
- },
9
- };
10
- export default meta;
11
- export const Empty = {
12
- args: {
13
- zone: 'must',
14
- width: 64,
15
- },
16
- render: (args) => (_jsx("div", { style: { background: '#1e2b2d', padding: 20 }, children: _jsx(MysterySlot, { ...args }) })),
17
- };
18
- export const FilledJoker = {
19
- args: {
20
- zone: 'must',
21
- width: 64,
22
- selection: {
23
- clauseKey: 'joker',
24
- value: 'Joker',
25
- displayLabel: 'Joker',
26
- spriteName: 'Joker',
27
- sheetType: 'Jokers',
28
- },
29
- },
30
- render: (args) => (_jsx("div", { style: { background: '#1e2b2d', padding: 20 }, children: _jsx(MysterySlot, { ...args }) })),
31
- };
@@ -1,4 +0,0 @@
1
- export { MysterySlot } from "./MysterySlot.js";
2
- export { JokerPicker } from "./JokerPicker.js";
3
- export { JamlMapEditor, CategoryMenu } from "./JamlMapEditor.js";
4
- export { CategoryPicker, VOUCHER_PICKER_CONFIG, TAG_PICKER_CONFIG, BOSS_PICKER_CONFIG, TAROT_PICKER_CONFIG, PLANET_PICKER_CONFIG, SPECTRAL_PICKER_CONFIG, PACK_PICKER_CONFIG, } from "./CategoryPicker.js";