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,80 +0,0 @@
1
- 'use client';
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { resolveJamlAssetUrl } from '../assets.js';
4
- import { RANK_MAP, SUIT_MAP, ENHANCER_MAP, SEAL_MAP, EDITION_MAP } from '../sprites/spriteData.js';
5
- function cn(...classes) { return classes.filter(Boolean).join(" "); }
6
- const CARD_WIDTH = 71;
7
- const CARD_HEIGHT = 95;
8
- const RANK_ALIAS = { A: 'Ace', K: 'King', Q: 'Queen', J: 'Jack' };
9
- const pascal = (s) => s[0].toUpperCase() + s.slice(1).toLowerCase();
10
- export function RealStandardcard({ suit, rank, enhancement, seal, edition, className, size = 71, style }) {
11
- const rankKey = RANK_ALIAS[rank] ?? rank;
12
- const suitKey = pascal(suit);
13
- const col = RANK_MAP[rankKey];
14
- const row = SUIT_MAP[suitKey];
15
- if (col === undefined || row === undefined) {
16
- console.warn(`Invalid card: ${rank} of ${suit}`);
17
- return null;
18
- }
19
- const scale = size / CARD_WIDTH;
20
- const finalH = size * (CARD_HEIGHT / CARD_WIDTH);
21
- // Base card position
22
- const bgX = -col * CARD_WIDTH;
23
- const bgY = -row * CARD_HEIGHT;
24
- // Enhancement background (if any) — ENHANCER_MAP is PascalCase, prop is lowercase
25
- const enhPos = enhancement ? ENHANCER_MAP[pascal(enhancement)] ?? { x: 0, y: 0 } : { x: 0, y: 0 };
26
- const enhBgX = -enhPos.x * CARD_WIDTH;
27
- const enhBgY = -enhPos.y * CARD_HEIGHT;
28
- // Seal overlay — SEAL_MAP is keyed by "Gold"/"Red"/"Blue"/"Purple"
29
- const sealPos = seal ? SEAL_MAP[pascal(seal)] ?? null : null;
30
- const sealBgX = sealPos ? -sealPos.x * CARD_WIDTH : 0;
31
- const sealBgY = sealPos ? -sealPos.y * CARD_HEIGHT : 0;
32
- // Edition overlay — EDITION_MAP gives column index on 5-wide editions sheet
33
- const editionCol = edition ? EDITION_MAP[edition] : undefined;
34
- const editionBgX = editionCol !== undefined ? -editionCol * CARD_WIDTH : 0;
35
- const editionBgY = 0;
36
- const isNegative = edition === 'Negative';
37
- const baseFilter = isNegative ? 'invert(0.94)' : 'none';
38
- const enhancersUrl = resolveJamlAssetUrl('enhancers');
39
- const deckUrl = resolveJamlAssetUrl('deck');
40
- const editionsUrl = resolveJamlAssetUrl('editions');
41
- return (_jsxs("div", { className: cn('relative overflow-hidden inline-block select-none', className), style: {
42
- width: size,
43
- height: finalH,
44
- imageRendering: 'pixelated',
45
- ...style
46
- }, title: `${rank} of ${suit}${enhancement ? ` (${enhancement})` : ''}${seal ? ` [${seal} seal]` : ''}${edition ? ` {${edition}}` : ''}`, children: [_jsx("div", { className: "absolute inset-0", style: {
47
- backgroundImage: `url(${enhancersUrl})`,
48
- backgroundPosition: `${enhBgX}px ${enhBgY}px`,
49
- width: CARD_WIDTH,
50
- height: CARD_HEIGHT,
51
- transform: `scale(${scale})`,
52
- transformOrigin: 'top left',
53
- backgroundRepeat: 'no-repeat',
54
- } }), _jsx("div", { className: "absolute inset-0 z-[1]", style: {
55
- backgroundImage: `url(${deckUrl})`,
56
- backgroundPosition: `${bgX}px ${bgY}px`,
57
- width: CARD_WIDTH,
58
- height: CARD_HEIGHT,
59
- transform: `scale(${scale})`,
60
- transformOrigin: 'top left',
61
- backgroundRepeat: 'no-repeat',
62
- filter: baseFilter
63
- } }), edition && edition !== 'Negative' && (_jsx("div", { className: "absolute inset-0 z-[2] mix-blend-screen opacity-60", style: {
64
- backgroundImage: `url(${editionsUrl})`,
65
- backgroundPosition: `${editionBgX}px ${editionBgY}px`,
66
- width: CARD_WIDTH,
67
- height: CARD_HEIGHT,
68
- transform: `scale(${scale})`,
69
- transformOrigin: 'top left',
70
- backgroundRepeat: 'no-repeat',
71
- } })), seal && (_jsx("div", { className: "absolute inset-0 z-[3]", style: {
72
- backgroundImage: `url(${enhancersUrl})`,
73
- backgroundPosition: `${sealBgX}px ${sealBgY}px`,
74
- width: CARD_WIDTH,
75
- height: CARD_HEIGHT,
76
- transform: `scale(${scale})`,
77
- transformOrigin: 'top left',
78
- backgroundRepeat: 'no-repeat',
79
- } })), isNegative && (_jsx("div", { className: "absolute inset-0 z-[4] bg-red-500/10 pointer-events-none mix-blend-overlay" }))] }));
80
- }
@@ -1,135 +0,0 @@
1
- "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- /* eslint-disable react-refresh/only-export-components */
4
- import { useState, useCallback, useMemo } from "react";
5
- import { JimboSprite } from "../../ui/sprites.js";
6
- import { JimboColorOption } from "../../ui/tokens.js";
7
- import { JimboText } from "../../ui/jimboText.js";
8
- // ─── Component ───────────────────────────────────────────────────────────────
9
- const C = JimboColorOption;
10
- export function CategoryPicker({ config, onSelect }) {
11
- const [search, setSearch] = useState("");
12
- const filtered = useMemo(() => {
13
- if (!search)
14
- return config.items;
15
- const q = search.toLowerCase();
16
- return config.items.filter((item) => item.name.toLowerCase().includes(q));
17
- }, [config.items, search]);
18
- const pairedVouchers = useMemo(() => {
19
- if (config.category !== "voucher")
20
- return null;
21
- const bases = config.items.filter((item) => item.pos.y % 2 === 0);
22
- const pairs = bases.map((base) => {
23
- const upgrade = config.items.find((u) => u.pos.x === base.pos.x && u.pos.y === base.pos.y + 1);
24
- return { base, upgrade };
25
- });
26
- if (!search)
27
- return pairs;
28
- const q = search.toLowerCase();
29
- return pairs.filter(p => p.base.name.toLowerCase().includes(q) || p.upgrade?.name.toLowerCase().includes(q));
30
- }, [config.items, search, config.category]);
31
- const handleSelect = useCallback((item) => {
32
- onSelect({
33
- category: config.category,
34
- value: item.name,
35
- clauseKey: config.clauseKey,
36
- });
37
- }, [onSelect, config]);
38
- const renderItem = (item, isMuted = false) => (_jsxs("div", { className: "j-juice-hover", onClick: () => handleSelect(item), title: item.name, style: {
39
- display: "flex",
40
- flexDirection: "column",
41
- alignItems: "center",
42
- gap: 3,
43
- padding: 4,
44
- borderRadius: 4,
45
- cursor: "pointer",
46
- opacity: isMuted ? 0.3 : 1,
47
- }, children: [_jsx(JimboSprite, { name: item.name, sheet: config.sheet, width: 48 }), _jsx(JimboText, { size: "micro", tone: "white", style: { lineHeight: 1.1, whiteSpace: "normal", textAlign: "center" }, children: item.name })] }, item.name));
48
- return (_jsxs("div", { style: { padding: 0, maxWidth: 420, maxHeight: "80vh", display: "flex", flexDirection: "column" }, children: [_jsx("div", { className: "j-flex j-gap-sm", style: { padding: "8px 10px 4px" }, children: _jsx("input", { className: "j-seed-input__field", type: "text", placeholder: `Search ${config.title.toLowerCase()}...`, value: search, onChange: (e) => setSearch(e.target.value), style: { fontSize: 13, padding: "6px 10px", textTransform: "none", letterSpacing: "0.04em" } }) }), config.hint && (_jsx("div", { className: "j-inner-panel", style: { margin: "4px 10px 6px", padding: "6px 10px" }, children: _jsx(JimboText, { size: "xs", tone: "grey", children: config.hint }) })), _jsxs("div", { className: "hide-scrollbar", style: {
49
- display: "flex",
50
- flexWrap: "wrap",
51
- gap: 6,
52
- padding: "8px 10px 10px",
53
- overflowY: "auto",
54
- flex: 1,
55
- alignContent: "flex-start",
56
- }, children: [config.category === "voucher" && pairedVouchers ? (pairedVouchers.map((pair) => (_jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 4, width: 64 }, children: [renderItem(pair.base, search ? !pair.base.name.toLowerCase().includes(search.toLowerCase()) : false), pair.upgrade && renderItem(pair.upgrade, search ? !pair.upgrade.name.toLowerCase().includes(search.toLowerCase()) : false)] }, pair.base.name)))) : (filtered.map((item) => (_jsx("div", { style: { width: 64 }, children: renderItem(item) }, item.name)))), ((config.category === "voucher" && pairedVouchers?.length === 0) ||
57
- (config.category !== "voucher" && filtered.length === 0)) && (_jsx("div", { style: { width: "100%", padding: 20, textAlign: "center" }, children: _jsxs(JimboText, { size: "sm", tone: "grey", children: ["No matches for \"", search, "\""] }) }))] })] }));
58
- }
59
- // ─── Pre-built configs ───────────────────────────────────────────────────────
60
- import { VOUCHERS, TAGS, BOSSES, BOOSTER_PACKS, TAROTS_AND_PLANETS } from "../../sprites/spriteData.js";
61
- // Split consumables by type
62
- const TAROT_CARDS = TAROTS_AND_PLANETS.filter((c) => {
63
- const y = c.pos.y;
64
- return y <= 2 && c.name !== "The Soul" && c.name !== "Black Hole";
65
- }).filter((c) => {
66
- return c.pos.y <= 1 || (c.pos.y === 2 && c.pos.x <= 1);
67
- });
68
- const PLANET_CARDS = TAROTS_AND_PLANETS.filter((c) => {
69
- return c.pos.y === 3 ||
70
- c.name === "Planet X" || c.name === "Ceres" || c.name === "Eris" ||
71
- c.name === "Black Hole";
72
- });
73
- const SPECTRAL_CARDS = TAROTS_AND_PLANETS.filter((c) => {
74
- return c.pos.y >= 4 || c.name === "The Soul";
75
- });
76
- export const VOUCHER_PICKER_CONFIG = {
77
- title: "Vouchers",
78
- category: "voucher",
79
- clauseKey: "voucher",
80
- sheet: "Vouchers",
81
- items: VOUCHERS,
82
- accent: C.ORANGE,
83
- };
84
- export const TAG_PICKER_CONFIG = {
85
- title: "Tags",
86
- category: "tag",
87
- clauseKey: "tag",
88
- sheet: "tags",
89
- items: TAGS,
90
- accent: C.GREEN,
91
- };
92
- export const BOSS_PICKER_CONFIG = {
93
- title: "Boss Blinds",
94
- category: "boss",
95
- clauseKey: "boss",
96
- sheet: "BlindChips",
97
- items: BOSSES,
98
- accent: C.RED,
99
- hint: "Boss Blinds appear at the end of each Ante.",
100
- };
101
- export const TAROT_PICKER_CONFIG = {
102
- title: "Tarot Cards",
103
- category: "tarot",
104
- clauseKey: "tarotCard",
105
- sheet: "Tarots",
106
- items: TAROT_CARDS,
107
- accent: C.PURPLE,
108
- hint: "Found in Arcana Packs and shops.",
109
- };
110
- export const PLANET_PICKER_CONFIG = {
111
- title: "Planet Cards",
112
- category: "planet",
113
- clauseKey: "planetCard",
114
- sheet: "Tarots",
115
- items: PLANET_CARDS,
116
- accent: C.BLUE,
117
- hint: "Found in Celestial Packs and shops.",
118
- };
119
- export const SPECTRAL_PICKER_CONFIG = {
120
- title: "Spectral Cards",
121
- category: "spectral",
122
- clauseKey: "spectralCard",
123
- sheet: "Tarots",
124
- items: SPECTRAL_CARDS,
125
- accent: C.TEAL_GREY,
126
- hint: "Found in Spectral Packs. Ghost Deck only for shop spawns!",
127
- };
128
- export const PACK_PICKER_CONFIG = {
129
- title: "Booster Packs",
130
- category: "pack",
131
- clauseKey: "pack",
132
- sheet: "Boosters",
133
- items: BOOSTER_PACKS,
134
- accent: C.ORANGE,
135
- };
@@ -1,304 +0,0 @@
1
- "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useState, useCallback, useRef, useEffect } 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 { JimboButton, JimboModal } from "../../ui/panel.js";
8
- import { JimboText } from "../../ui/jimboText.js";
9
- import { JimboColorOption, withAlpha } from "../../ui/tokens.js";
10
- import { JimboSprite } from "../../ui/sprites.js";
11
- // ─── Category menu items ─────────────────────────────────────────────────────
12
- const C = JimboColorOption;
13
- const CATEGORIES = [
14
- { key: "joker", label: "Joker", sprite: "Joker", sheet: "Jokers", tone: "blue", hint: "Shop, Buffoon Pack" },
15
- { key: "voucher", label: "Voucher", sprite: "Blank", sheet: "Vouchers", tone: "orange", hint: "1 per Ante in shop" },
16
- { key: "tarot", label: "Tarot Card", sprite: "The Fool", sheet: "Tarots", tone: "tarot", hint: "Arcana Pack, shop" },
17
- { key: "planet", label: "Planet Card", sprite: "Mercury", sheet: "Tarots", tone: "planet", hint: "Celestial Pack, shop" },
18
- { key: "spectral", label: "Spectral Card", sprite: "Grim", sheet: "Tarots", tone: "spectral", hint: "Ghost Deck, Spectral Pack" },
19
- { key: "tag", label: "Tag", sprite: "Uncommon Tag", sheet: "tags", tone: "green", hint: "Skip blind reward" },
20
- { key: "boss", label: "Boss Blind", sprite: "The Hook", sheet: "BlindChips", tone: "red", hint: "End of each Ante" },
21
- { key: "pack", label: "Booster Pack", sprite: "Arcana Pack", sheet: "Boosters", tone: "orange", hint: "Arcana, Celestial, etc." },
22
- ];
23
- const ZONE_TONE = {
24
- must: "blue",
25
- should: "green",
26
- mustnot: "red",
27
- };
28
- const ZONE_LABEL = {
29
- must: "Required",
30
- should: "Bonus",
31
- mustnot: "Avoid",
32
- };
33
- const CATEGORY_CONFIG_MAP = {
34
- voucher: VOUCHER_PICKER_CONFIG,
35
- tag: TAG_PICKER_CONFIG,
36
- boss: BOSS_PICKER_CONFIG,
37
- tarot: TAROT_PICKER_CONFIG,
38
- planet: PLANET_PICKER_CONFIG,
39
- spectral: SPECTRAL_PICKER_CONFIG,
40
- pack: PACK_PICKER_CONFIG,
41
- };
42
- // ─── Component ───────────────────────────────────────────────────────────────
43
- export function JamlMapEditor({ zone: initialZone = "must", onChange, }) {
44
- const onChangeRef = useRef(onChange);
45
- useEffect(() => {
46
- onChangeRef.current = onChange;
47
- });
48
- const [currentZone, setCurrentZone] = useState(initialZone);
49
- const [antesState, setAntesState] = useState({});
50
- const [activeSlot, setActiveSlot] = useState(null);
51
- const [activePackDetail, setActivePackDetail] = useState(null);
52
- const [pickerFlow, setPickerFlow] = useState("category");
53
- const [activePackSelection, setActivePackSelection] = useState(null);
54
- const handleSlotTap = useCallback((anteIndex, id, forceCategory) => {
55
- const existing = (antesState[anteIndex] || {})[id];
56
- if (forceCategory === "pack" && existing?.packName) {
57
- setActivePackDetail({ ante: anteIndex, id });
58
- return;
59
- }
60
- setActiveSlot({ ante: anteIndex, id, forceCategory });
61
- setPickerFlow(forceCategory || "category");
62
- }, [antesState]);
63
- const handleSlotClear = useCallback((anteIndex, id) => {
64
- setAntesState((prev) => {
65
- const next = { ...prev };
66
- if (!next[anteIndex])
67
- return next;
68
- const nextAnte = { ...next[anteIndex] };
69
- delete nextAnte[id];
70
- next[anteIndex] = nextAnte;
71
- onChangeRef.current?.(buildJamlText(next));
72
- return next;
73
- });
74
- setActivePackDetail((prev) => prev && prev.ante === anteIndex && prev.id === id ? null : prev);
75
- }, []);
76
- const handlePackChange = useCallback(() => {
77
- if (!activePackDetail)
78
- return;
79
- setActivePackDetail(null);
80
- setActivePackSelection(null);
81
- setActiveSlot({ ante: activePackDetail.ante, id: activePackDetail.id, forceCategory: "pack" });
82
- setPickerFlow("pack");
83
- }, [activePackDetail]);
84
- const handleCategorySelect = useCallback((cat) => {
85
- setPickerFlow(cat);
86
- }, []);
87
- const handleItemSelect = useCallback((selection) => {
88
- if (!activeSlot)
89
- return;
90
- if (activeSlot.forceCategory === "pack" && selection.category === "pack") {
91
- const slotIndex = getPackSlotIndex(activeSlot.id);
92
- if (slotIndex === null)
93
- return;
94
- const nextFlow = getPackFollowupFlow(selection.value);
95
- setActivePackSelection({ packName: selection.value, slotIndex });
96
- setPickerFlow(nextFlow);
97
- return;
98
- }
99
- const finalSelection = activePackSelection
100
- ? { ...selection, packName: activePackSelection.packName, boosterPacks: [activePackSelection.slotIndex] }
101
- : selection;
102
- setAntesState((prev) => {
103
- const next = { ...prev };
104
- const nextAnte = { ...(next[activeSlot.ante] || {}) };
105
- nextAnte[activeSlot.id] = { ...finalSelection, zone: currentZone };
106
- next[activeSlot.ante] = nextAnte;
107
- onChangeRef.current?.(buildJamlText(next));
108
- return next;
109
- });
110
- setActivePackSelection(null);
111
- setActiveSlot(null);
112
- }, [activePackSelection, activeSlot, currentZone]);
113
- const handlePickerCancel = useCallback(() => {
114
- if (activeSlot?.forceCategory === "pack" && activePackSelection) {
115
- setActivePackSelection(null);
116
- setPickerFlow("pack");
117
- }
118
- else if (activeSlot?.forceCategory) {
119
- setActiveSlot(null);
120
- }
121
- else if (pickerFlow !== "category") {
122
- setPickerFlow("category");
123
- }
124
- else {
125
- setActiveSlot(null);
126
- }
127
- }, [activePackSelection, activeSlot, pickerFlow]);
128
- const handleOverlayClose = useCallback(() => {
129
- setActivePackSelection(null);
130
- setActiveSlot(null);
131
- setActivePackDetail(null);
132
- }, []);
133
- const activePackDetailSelection = activePackDetail
134
- ? (antesState[activePackDetail.ante] || {})[activePackDetail.id]
135
- : undefined;
136
- const handleScrollAttach = useCallback((node) => {
137
- if (!node)
138
- return;
139
- const firstChild = node.children[1];
140
- if (firstChild)
141
- node.scrollTop = firstChild.offsetTop;
142
- }, []);
143
- const renderSlot = (anteIndex, id, width, sheetType, forceCategory) => {
144
- const sel = (antesState[anteIndex] || {})[id];
145
- return (_jsx(MysterySlot, { zone: sel ? sel.zone : "must", sheetType: sheetType, selection: sel, width: width, onTap: () => handleSlotTap(anteIndex, id, forceCategory), onClear: sel ? () => handleSlotClear(anteIndex, id) : undefined, style: { flexShrink: 0 } }, id));
146
- };
147
- return (_jsxs("div", { style: { width: "100%", height: "100%", display: "flex", flexDirection: "column" }, children: [_jsx("div", { ref: handleScrollAttach, className: "hide-scrollbar", style: {
148
- flex: 1,
149
- overflowY: "scroll",
150
- overflowX: "hidden",
151
- scrollSnapType: "y mandatory",
152
- scrollBehavior: "smooth",
153
- WebkitOverflowScrolling: "touch",
154
- overscrollBehaviorY: "contain",
155
- }, children: Array.from({ length: 8 }, (_, i) => i + 1).map((a) => (_jsxs("div", { style: {
156
- scrollSnapAlign: "start",
157
- scrollSnapStop: "always",
158
- padding: "24px 8px 64px 8px",
159
- minHeight: "100%",
160
- boxSizing: "border-box",
161
- display: "flex",
162
- flexDirection: "column",
163
- gap: 24,
164
- borderBottom: `2px solid ${C.DARK_GREY}`
165
- }, children: [_jsxs(JimboText, { size: "md", tone: "white", style: { textAlign: "center", marginBottom: 8 }, children: ["Ante ", a] }), _jsxs("div", { className: "j-flex j-justify-between j-items-end", children: [_jsxs("div", { className: "j-flex-col j-items-center j-gap-xs", children: [_jsx(JimboText, { size: "micro", tone: "grey", children: "Voucher" }), renderSlot(a, `ante_${a}_voucher`, 42, "Vouchers", "voucher")] }), _jsxs("div", { className: "j-flex-col j-items-center j-gap-xs", children: [_jsx(JimboText, { size: "micro", tone: "grey", children: "Small" }), renderSlot(a, `ante_${a}_tag_small`, 42, "tags", "tag")] }), _jsxs("div", { className: "j-flex-col j-items-center j-gap-xs", children: [_jsx(JimboText, { size: "micro", tone: "grey", children: "Big" }), renderSlot(a, `ante_${a}_tag_big`, 42, "tags", "tag")] }), _jsxs("div", { className: "j-flex-col j-items-center j-gap-xs", children: [_jsx(JimboText, { size: "micro", tone: "grey", children: "Boss" }), renderSlot(a, `ante_${a}_boss`, 42, "BlindChips", "boss")] })] }), _jsxs("div", { className: "j-flex-col j-gap-xs", children: [_jsx(JimboText, { size: "xs", tone: "grey", style: { letterSpacing: 1 }, children: "Shop Items" }), _jsx("div", { className: "j-flex hide-scrollbar j-gap-sm", style: { overflowX: "auto", paddingBottom: 8 }, children: [1, 2, 3, 4, 5, 6, 7, 8].map(i => renderSlot(a, `ante_${a}_shop_${i}`, 52, "Jokers")) })] }), _jsxs("div", { className: "j-flex-col j-gap-xs", children: [_jsx(JimboText, { size: "xs", tone: "grey", style: { letterSpacing: 1 }, children: "Packs" }), _jsx("div", { className: "j-flex-col j-gap-sm", children: getPackRows(a).map((row, rowIndex) => (_jsx("div", { className: "j-flex j-gap-sm", style: { flexWrap: "nowrap" }, children: row.map(i => renderSlot(a, `ante_${a}_pack_${i}`, 64, "Boosters", "pack")) }, rowIndex))) })] })] }, a))) }), _jsx(JimboModal, { open: activeSlot !== null, onClose: handlePickerCancel, title: pickerFlow === "category" ? "Select Category" : undefined, className: "j-picker-modal", children: activeSlot !== null && (_jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 8 }, children: [_jsxs("div", { className: "j-inner-panel", style: { padding: "8px 10px", marginBottom: 2 }, children: [_jsx(JimboText, { size: "xs", tone: "grey", style: { display: "block", marginBottom: 6 }, children: "This pick will be added as" }), _jsx("div", { className: "j-flex j-gap-sm", style: { flexWrap: "wrap" }, children: ["must", "should", "mustnot"].map((z) => (_jsx(JimboButton, { tone: currentZone === z ? ZONE_TONE[z] : "grey", size: "xs", onClick: () => setCurrentZone(z), children: ZONE_LABEL[z] }, z))) })] }), pickerFlow === "category" ? (_jsx(CategoryMenu, { onSelect: handleCategorySelect })) : pickerFlow === "joker" ? (_jsx(JokerPicker, { onSelect: handleItemSelect })) : pickerFlow === "packUnsupported" ? (_jsxs("div", { className: "j-flex-col j-gap-sm", style: { padding: 10, maxWidth: 360 }, children: [_jsxs("div", { className: "j-inner-panel", style: { padding: "10px 12px" }, children: [_jsx(JimboText, { size: "sm", tone: "orange", children: "Standard Packs need a dedicated playing-card picker." }), _jsx(JimboText, { size: "xs", tone: "grey", style: { display: "block", marginTop: 6 }, children: "Arcana, Celestial, Spectral, and Buffoon pack flows are wired. Standard Pack support can come next without faking the JAML shape." })] }), _jsx(JimboButton, { tone: "orange", size: "sm", fullWidth: true, onClick: () => {
166
- setActivePackSelection(null);
167
- setPickerFlow("pack");
168
- }, children: "Back to Packs" })] })) : (_jsx(CategoryPicker, { config: CATEGORY_CONFIG_MAP[pickerFlow], onSelect: handleItemSelect }))] })) }), _jsx(JimboModal, { open: activePackDetail !== null && !!activePackDetailSelection?.packName, onClose: handleOverlayClose, title: activePackDetailSelection?.packName ?? "Pack", className: "j-picker-modal", children: activePackDetail !== null && activePackDetailSelection?.packName && (_jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 10, maxWidth: 360 }, children: [_jsx("div", { className: "j-inner-panel", style: { padding: "10px 12px", background: withAlpha(C.DARKEST, 0.84) }, children: _jsxs("div", { style: { display: "flex", alignItems: "center", gap: 10 }, children: [_jsx(JimboSprite, { name: activePackDetailSelection.packName, sheet: "Boosters", width: 56 }), _jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 4 }, children: [_jsxs(JimboText, { size: "sm", tone: "white", children: ["Ante ", activePackDetail.ante, " pack ", ((activePackDetailSelection.boosterPacks?.[0] ?? 0) + 1)] }), _jsx(JimboText, { size: "xs", tone: "grey", children: getPackHelperText(activePackDetailSelection.packName) })] })] }) }), _jsxs("div", { className: "j-inner-panel", style: { padding: "10px 12px" }, children: [_jsx(JimboText, { size: "xs", tone: "grey", style: { display: "block", marginBottom: 8 }, children: "Peek" }), _jsxs("div", { style: { display: "flex", alignItems: "center", gap: 10, marginBottom: 10 }, children: [_jsx(JimboSprite, { name: activePackDetailSelection.packName, sheet: "Boosters", width: 44 }), _jsx(JimboText, { size: "sm", tone: "grey", children: "\u2192" }), _jsx(JimboSprite, { name: activePackDetailSelection.value, sheet: categoryToPreviewSheet(activePackDetailSelection.category), width: 48 }), _jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 3 }, children: [_jsx(JimboText, { size: "sm", tone: "white", children: activePackDetailSelection.value }), _jsxs(JimboText, { size: "xs", tone: "grey", children: [getSelectionCategoryLabel(activePackDetailSelection.category), " from ", activePackDetailSelection.packName] })] })] }), _jsxs("div", { className: "j-flex j-gap-sm", style: { flexWrap: "wrap" }, children: [_jsxs("div", { className: "j-inner-panel", style: { padding: "6px 8px", minWidth: 96 }, children: [_jsx(JimboText, { size: "micro", tone: "grey", style: { display: "block", marginBottom: 2 }, children: "Zone" }), _jsx(JimboText, { size: "xs", tone: getZoneTextTone(activePackDetailSelection.zone), children: ZONE_LABEL[activePackDetailSelection.zone] })] }), _jsxs("div", { className: "j-inner-panel", style: { padding: "6px 8px", minWidth: 120 }, children: [_jsx(JimboText, { size: "micro", tone: "grey", style: { display: "block", marginBottom: 2 }, children: "Clause" }), _jsx(JimboText, { size: "xs", tone: "white", children: activePackDetailSelection.clauseKey })] }), _jsxs("div", { className: "j-inner-panel", style: { padding: "6px 8px", minWidth: 96 }, children: [_jsx(JimboText, { size: "micro", tone: "grey", style: { display: "block", marginBottom: 2 }, children: "Source" }), _jsxs(JimboText, { size: "xs", tone: "white", children: ["boosterPacks: [", activePackDetailSelection.boosterPacks?.join(", ") ?? "", "]"] })] })] })] }), _jsxs("div", { className: "j-flex j-gap-sm", style: { flexWrap: "wrap" }, children: [_jsx(JimboButton, { tone: "blue", size: "sm", fullWidth: true, onClick: handlePackChange, children: "Re-pick Contents" }), _jsx(JimboButton, { tone: "red", size: "sm", fullWidth: true, onClick: () => handleSlotClear(activePackDetail.ante, activePackDetail.id), children: "Clear This Pack" })] })] })) })] }));
169
- }
170
- // ─── Category Selection Menu ─────────────────────────────────────────────────
171
- export function CategoryMenu({ onSelect, }) {
172
- return (_jsx("div", { className: "hide-scrollbar", style: {
173
- display: "flex",
174
- flexDirection: "column",
175
- gap: 12,
176
- padding: "10px 4px",
177
- maxHeight: "70vh",
178
- overflowY: "auto",
179
- }, children: CATEGORIES.map((cat) => (_jsx(JimboButton, { tone: cat.tone, size: "sm", fullWidth: true, onClick: () => onSelect(cat.key), children: _jsxs("div", { style: { display: "flex", alignItems: "center", gap: 8, width: "100%", textAlign: "left" }, children: [_jsx(JimboSprite, { name: cat.sprite, sheet: cat.sheet, width: 24 }), _jsxs("div", { style: { display: "flex", flexDirection: "column", gap: 1 }, children: [_jsx("span", { style: { fontSize: 11 }, children: cat.label }), _jsx("span", { style: { fontSize: 8, opacity: 0.7, letterSpacing: "0.04em", lineHeight: 1, whiteSpace: "normal" }, children: cat.hint })] })] }) }, cat.key))) }));
180
- }
181
- // ─── Build JAML text from slots ──────────────────────────────────────────────
182
- function getPackSlotIndex(slotId) {
183
- const match = /_pack_(\d+)$/.exec(slotId);
184
- if (!match)
185
- return null;
186
- return Number(match[1]) - 1;
187
- }
188
- function getPackRows(ante) {
189
- const packCount = ante < 2 ? 4 : 6;
190
- const rows = [];
191
- for (let i = 1; i <= packCount; i += 2) {
192
- rows.push([i, i + 1].filter((slot) => slot <= packCount));
193
- }
194
- return rows;
195
- }
196
- function getPackFollowupFlow(packName) {
197
- if (packName.includes("Buffoon"))
198
- return "joker";
199
- if (packName.includes("Arcana"))
200
- return "tarot";
201
- if (packName.includes("Celestial"))
202
- return "planet";
203
- if (packName.includes("Spectral"))
204
- return "spectral";
205
- return "packUnsupported";
206
- }
207
- function categoryToPreviewSheet(category) {
208
- if (category === "joker")
209
- return "Jokers";
210
- if (category === "voucher")
211
- return "Vouchers";
212
- if (category === "tag")
213
- return "tags";
214
- if (category === "boss")
215
- return "BlindChips";
216
- if (category === "pack")
217
- return "Boosters";
218
- return "Tarots";
219
- }
220
- function getPackHelperText(packName) {
221
- if (packName.includes("Buffoon"))
222
- return "Peek the joker this pack is meant to carry.";
223
- if (packName.includes("Arcana"))
224
- return "Peek the tarot card currently attached to this pack.";
225
- if (packName.includes("Celestial"))
226
- return "Peek the planet card currently attached to this pack.";
227
- if (packName.includes("Spectral"))
228
- return "Peek the spectral card currently attached to this pack.";
229
- return "Peek the item currently attached to this pack.";
230
- }
231
- function getSelectionCategoryLabel(category) {
232
- if (category === "joker")
233
- return "Joker";
234
- if (category === "voucher")
235
- return "Voucher";
236
- if (category === "tag")
237
- return "Tag";
238
- if (category === "boss")
239
- return "Boss Blind";
240
- if (category === "tarot")
241
- return "Tarot Card";
242
- if (category === "planet")
243
- return "Planet Card";
244
- if (category === "spectral")
245
- return "Spectral Card";
246
- return "Pack";
247
- }
248
- function getZoneTextTone(zone) {
249
- if (zone === "must")
250
- return "blue";
251
- if (zone === "should")
252
- return "green";
253
- return "red";
254
- }
255
- function buildJamlText(antes) {
256
- const byZone = {
257
- must: {}, should: {}, mustnot: {}
258
- };
259
- for (const [anteStr, selections] of Object.entries(antes)) {
260
- const anteNum = parseInt(anteStr, 10);
261
- for (const sel of Object.values(selections)) {
262
- const zone = sel.zone;
263
- const key = sel.clauseKey;
264
- if (!byZone[zone][key]) {
265
- byZone[zone][key] = [];
266
- }
267
- const existing = byZone[zone][key].find(item => item.value === sel.value &&
268
- (item.boosterPacks ?? []).join(",") === (sel.boosterPacks ?? []).join(","));
269
- if (existing) {
270
- if (!existing.antes.includes(anteNum))
271
- existing.antes.push(anteNum);
272
- }
273
- else {
274
- byZone[zone][key].push({ value: sel.value, antes: [anteNum], boosterPacks: sel.boosterPacks });
275
- }
276
- }
277
- }
278
- const lines = [];
279
- lines.push("name: My Custom Seed Map");
280
- lines.push("author: JamlBuilder");
281
- lines.push("description: Auto-generated from the visual editor.");
282
- lines.push("deck: Red");
283
- lines.push("stake: White");
284
- for (const [zone, label] of [["must", "must"], ["should", "should"], ["mustnot", "mustNot"]]) {
285
- const clauses = byZone[zone];
286
- if (Object.keys(clauses).length === 0)
287
- continue;
288
- lines.push(`${label}:`);
289
- for (const [key, items] of Object.entries(clauses)) {
290
- for (const item of items) {
291
- lines.push(` - ${key}: ${item.value}`);
292
- // Only emit `antes:` if it's not all 8 antes (simplification, or just emit it)
293
- if (item.antes.length < 8) {
294
- lines.push(` antes: [${item.antes.sort((a, b) => a - b).join(", ")}]`);
295
- }
296
- if (item.boosterPacks && item.boosterPacks.length > 0) {
297
- lines.push(` sources:`);
298
- lines.push(` boosterPacks: [${item.boosterPacks.join(", ")}]`);
299
- }
300
- }
301
- }
302
- }
303
- return lines.join("\n") + "\n";
304
- }
@@ -1,7 +0,0 @@
1
- import type { StoryObj } from '@storybook/react';
2
- import { JamlMapEditor } from './JamlMapEditor';
3
- import "../../ui/jimbo.css";
4
- declare const meta: Meta<typeof JamlMapEditor>;
5
- export default meta;
6
- type Story = StoryObj<typeof meta>;
7
- export declare const Default: Story;
@@ -1,26 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { JamlMapEditor } from './JamlMapEditor';
3
- import { useState } from 'react';
4
- import { JimboModalRoot } from '../../ui/panel';
5
- import "../../ui/jimbo.css"; // Ensure global CSS is loaded
6
- const meta = {
7
- title: 'JamlMap/JamlMapEditor',
8
- component: JamlMapEditor,
9
- parameters: {
10
- layout: 'fullscreen',
11
- viewport: {
12
- defaultViewport: 'mobile1', // iPhone SE
13
- },
14
- },
15
- decorators: [
16
- (Story) => (_jsxs("div", { style: { width: "375px", height: "667px", margin: "0 auto", overflow: "hidden", border: "1px solid #333" }, children: [_jsx(Story, {}), _jsx(JimboModalRoot, {})] })),
17
- ],
18
- };
19
- export default meta;
20
- export const Default = {
21
- render: () => {
22
- // eslint-disable-next-line react-hooks/rules-of-hooks
23
- const [clauses, setClauses] = useState([]);
24
- return (_jsx(JamlMapEditor, { clauses: clauses, onChange: setClauses }));
25
- },
26
- };
@@ -1,8 +0,0 @@
1
- import { type SlotSelection, type JamlZone } from "./MysterySlot.js";
2
- export interface JamlMapEditorDemoProps {
3
- /** Initial zone for the demo. */
4
- zone?: JamlZone;
5
- /** Callback when selections change. */
6
- onChange?: (slots: (SlotSelection | null)[]) => void;
7
- }
8
- export declare function JamlMapEditorDemo({ zone: initialZone, onChange, }: JamlMapEditorDemoProps): import("react/jsx-runtime").JSX.Element;