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,355 +0,0 @@
1
- "use client";
2
- import { jsx as _jsx } from "react/jsx-runtime";
3
- import { Layer } from "../render/Layer.js";
4
- import { JamlCardRenderer } from "../render/CanvasRenderer.js";
5
- import { JOKERS, JOKER_FACES, TAROTS_AND_PLANETS, CONSUMABLE_FACES, TAGS, VOUCHERS, BOSSES, EDITION_MAP, SPRITE_SHEETS, STICKER_MAP, RANK_MAP, SUIT_MAP, ENHANCER_MAP, SEAL_MAP, } from "../sprites/spriteData.js";
6
- function normalizeCardRank(raw) {
7
- const value = raw.trim().toUpperCase();
8
- if (value === "A" || value === "ACE")
9
- return "Ace";
10
- if (value === "K" || value === "KING")
11
- return "King";
12
- if (value === "Q" || value === "QUEEN")
13
- return "Queen";
14
- if (value === "J" || value === "JACK")
15
- return "Jack";
16
- return raw.trim();
17
- }
18
- function normalizeCardSuit(raw) {
19
- const value = raw.trim().toLowerCase();
20
- if (value === "heart" || value === "hearts")
21
- return "Hearts";
22
- if (value === "club" || value === "clubs")
23
- return "Clubs";
24
- if (value === "diamond" || value === "diamonds")
25
- return "Diamonds";
26
- if (value === "spade" || value === "spades")
27
- return "Spades";
28
- return raw.trim();
29
- }
30
- function parseStandardcardName(name) {
31
- const trimmed = name.trim();
32
- const ofMatch = /^(A|K|Q|J|10|[2-9]|Ace|King|Queen|Jack)\s+of\s+(Hearts|Clubs|Diamonds|Spades)$/i.exec(trimmed);
33
- if (ofMatch) {
34
- return {
35
- rank: normalizeCardRank(ofMatch[1]),
36
- suit: normalizeCardSuit(ofMatch[2]),
37
- };
38
- }
39
- const shortMatch = /^(A|K|Q|J|10|[2-9])\s*([HCDS])$/i.exec(trimmed);
40
- if (shortMatch) {
41
- const suitMap = {
42
- H: "Hearts",
43
- C: "Clubs",
44
- D: "Diamonds",
45
- S: "Spades",
46
- };
47
- return {
48
- rank: normalizeCardRank(shortMatch[1]),
49
- suit: suitMap[shortMatch[2].toUpperCase()],
50
- };
51
- }
52
- return null;
53
- }
54
- const MODIFIER_PREFIXES = [
55
- "Eternal",
56
- "Perishable",
57
- "Rental",
58
- "Foil",
59
- "Holographic",
60
- "Polychrome",
61
- "Negative",
62
- "Bonus",
63
- "Mult",
64
- "Wild",
65
- "Glass",
66
- "Steel",
67
- "Stone",
68
- "Gold",
69
- "Lucky",
70
- "Gold Seal",
71
- "Red Seal",
72
- "Blue Seal",
73
- "Purple Seal",
74
- ];
75
- function stripModifiers(name) {
76
- let remaining = name;
77
- let edition;
78
- let isEternal = false;
79
- let isPerishable = false;
80
- let isRental = false;
81
- let changed = true;
82
- while (changed) {
83
- changed = false;
84
- for (const prefix of MODIFIER_PREFIXES) {
85
- if (remaining.startsWith(prefix + " ")) {
86
- const stripped = remaining.slice(prefix.length + 1);
87
- if (prefix === "Foil" || prefix === "Holographic" || prefix === "Polychrome" || prefix === "Negative") {
88
- edition = prefix;
89
- }
90
- else if (prefix === "Eternal") {
91
- isEternal = true;
92
- }
93
- else if (prefix === "Perishable") {
94
- isPerishable = true;
95
- }
96
- else if (prefix === "Rental") {
97
- isRental = true;
98
- }
99
- remaining = stripped;
100
- changed = true;
101
- break;
102
- }
103
- }
104
- }
105
- return { baseName: remaining, edition, isEternal, isPerishable, isRental };
106
- }
107
- function resolvePackedAnalyzerItem(item, scale) {
108
- if (typeof item.value !== "number" || !Number.isFinite(item.value)) {
109
- return null;
110
- }
111
- const displayName = String(item.name || "").trim();
112
- const { baseName, edition, isEternal, isPerishable, isRental } = stripModifiers(displayName);
113
- // Use motely-wasm enum to determine category — no hand-rolled bitmasks
114
- const itemType = item.value & 0xffff;
115
- const catNibble = (itemType >> 12) & 0xf;
116
- if (catNibble === 5 /* Joker */) {
117
- const jokerName = JOKERS.some((joker) => joker.name === baseName) ? baseName : displayName;
118
- if (JOKERS.some((joker) => joker.name === jokerName)) {
119
- return { kind: "joker", type: "joker", card: { name: jokerName, edition, isEternal, isPerishable, isRental, scale } };
120
- }
121
- }
122
- if (catNibble === 3 /* Tarot */ ||
123
- catNibble === 4 /* Planet */ ||
124
- catNibble === 2 /* Spectral */) {
125
- const consumableName = TAROTS_AND_PLANETS.some((consumable) => consumable.name === baseName) ? baseName : displayName;
126
- if (TAROTS_AND_PLANETS.some((consumable) => consumable.name === consumableName)) {
127
- return { kind: "consumable", type: "consumable", card: { name: consumableName, edition, scale } };
128
- }
129
- }
130
- if (baseName !== displayName) {
131
- if (JOKERS.some((joker) => joker.name === baseName)) {
132
- return { kind: "joker", type: "joker", card: { name: baseName, edition, isEternal, isPerishable, isRental, scale } };
133
- }
134
- if (TAROTS_AND_PLANETS.some((consumable) => consumable.name === baseName)) {
135
- return { kind: "consumable", type: "consumable", card: { name: baseName, edition, scale } };
136
- }
137
- if (VOUCHERS.some((voucher) => voucher.name === baseName)) {
138
- return { kind: "voucher", voucherName: baseName };
139
- }
140
- }
141
- const standardcard = parseStandardcardName(displayName) ?? parseStandardcardName(baseName);
142
- if (standardcard) {
143
- return {
144
- kind: "playing",
145
- type: "playing",
146
- card: {
147
- name: displayName,
148
- rank: standardcard.rank,
149
- suit: standardcard.suit,
150
- scale,
151
- },
152
- };
153
- }
154
- return { kind: "unknown", label: displayName };
155
- }
156
- // eslint-disable-next-line react-refresh/only-export-components
157
- export function resolveAnalyzerShopItem(item, scale = 1) {
158
- const displayName = String(item.name || "").trim();
159
- if (!displayName) {
160
- return { kind: "unknown", label: String(item.id || "").trim() || "Unknown Item" };
161
- }
162
- const packedResolved = resolvePackedAnalyzerItem(item, scale);
163
- if (packedResolved && packedResolved.kind !== "unknown") {
164
- return packedResolved;
165
- }
166
- if (VOUCHERS.some((voucher) => voucher.name === displayName)) {
167
- return { kind: "voucher", voucherName: displayName };
168
- }
169
- if (JOKERS.some((joker) => joker.name === displayName)) {
170
- return { kind: "joker", type: "joker", card: { name: displayName, scale } };
171
- }
172
- if (TAROTS_AND_PLANETS.some((consumable) => consumable.name === displayName)) {
173
- return { kind: "consumable", type: "consumable", card: { name: displayName, scale } };
174
- }
175
- const { baseName, edition, isEternal, isPerishable, isRental } = stripModifiers(displayName);
176
- if (baseName !== displayName) {
177
- if (JOKERS.some((joker) => joker.name === baseName)) {
178
- return { kind: "joker", type: "joker", card: { name: baseName, edition, isEternal, isPerishable, isRental, scale } };
179
- }
180
- if (TAROTS_AND_PLANETS.some((consumable) => consumable.name === baseName)) {
181
- return { kind: "consumable", type: "consumable", card: { name: baseName, edition, scale } };
182
- }
183
- if (VOUCHERS.some((voucher) => voucher.name === baseName)) {
184
- return { kind: "voucher", voucherName: baseName };
185
- }
186
- }
187
- const standardcard = parseStandardcardName(displayName) ?? parseStandardcardName(baseName);
188
- if (standardcard) {
189
- return {
190
- kind: "playing",
191
- type: "playing",
192
- card: {
193
- name: displayName,
194
- rank: standardcard.rank,
195
- suit: standardcard.suit,
196
- scale,
197
- },
198
- };
199
- }
200
- return packedResolved ?? { kind: "unknown", label: displayName };
201
- }
202
- export function JamlGameCard({ card, type, className = "", hoverTilt = false }) {
203
- const { name, edition, isEternal, isPerishable, isRental, rank, suit, enhancements, seal, scale = 1 } = card;
204
- const layers = [];
205
- if (type === "joker") {
206
- const jokerData = JOKERS.find((j) => j.name === name);
207
- if (jokerData)
208
- layers.push(new Layer({ ...jokerData, source: SPRITE_SHEETS.jokers.src, order: 0, columns: SPRITE_SHEETS.jokers.columns, rows: SPRITE_SHEETS.jokers.rows }));
209
- const face = JOKER_FACES.find((j) => j.name === name);
210
- if (face)
211
- layers.push(new Layer({ ...face, source: SPRITE_SHEETS.jokers.src, order: 1, columns: SPRITE_SHEETS.jokers.columns, rows: SPRITE_SHEETS.jokers.rows }));
212
- }
213
- else if (type === "consumable") {
214
- const consumable = TAROTS_AND_PLANETS.find((t) => t.name === name);
215
- if (consumable)
216
- layers.push(new Layer({ ...consumable, order: 0, source: SPRITE_SHEETS.tarots.src, rows: SPRITE_SHEETS.tarots.rows, columns: SPRITE_SHEETS.tarots.columns }));
217
- const face = CONSUMABLE_FACES.find((t) => t.name === name);
218
- if (face)
219
- layers.push(new Layer({
220
- ...face,
221
- order: 1,
222
- source: SPRITE_SHEETS.enhancers.src,
223
- rows: SPRITE_SHEETS.enhancers.rows,
224
- columns: SPRITE_SHEETS.enhancers.columns,
225
- animated: face.animated,
226
- }));
227
- }
228
- else if (rank && suit) {
229
- const enhancerPos = (enhancements ?? [])
230
- .map((m) => ENHANCER_MAP[m])
231
- .find((pos) => Boolean(pos)) ?? { x: 1, y: 0 };
232
- layers.push(new Layer({
233
- pos: enhancerPos,
234
- name: "background",
235
- order: 0,
236
- source: SPRITE_SHEETS.enhancers.src,
237
- rows: SPRITE_SHEETS.enhancers.rows,
238
- columns: SPRITE_SHEETS.enhancers.columns,
239
- }));
240
- layers.push(new Layer({
241
- pos: { x: RANK_MAP[rank] ?? 0, y: SUIT_MAP[suit] ?? 0 },
242
- name,
243
- order: 1,
244
- source: SPRITE_SHEETS.deck.src,
245
- rows: SPRITE_SHEETS.deck.rows,
246
- columns: SPRITE_SHEETS.deck.columns,
247
- }));
248
- }
249
- if (edition) {
250
- const index = EDITION_MAP[edition];
251
- if (index !== undefined) {
252
- layers.push(new Layer({
253
- pos: { x: index, y: 0 },
254
- name: edition,
255
- order: 2,
256
- source: SPRITE_SHEETS.editions.src,
257
- rows: SPRITE_SHEETS.editions.rows,
258
- columns: SPRITE_SHEETS.editions.columns,
259
- }));
260
- }
261
- }
262
- if (isEternal) {
263
- layers.push(new Layer({
264
- pos: STICKER_MAP["Eternal"],
265
- name: "Eternal",
266
- order: 3,
267
- source: SPRITE_SHEETS.stickers.src,
268
- rows: SPRITE_SHEETS.stickers.rows,
269
- columns: SPRITE_SHEETS.stickers.columns,
270
- }));
271
- }
272
- if (isPerishable) {
273
- layers.push(new Layer({
274
- pos: STICKER_MAP["Perishable"],
275
- name: "Perishable",
276
- order: 4,
277
- source: SPRITE_SHEETS.stickers.src,
278
- rows: SPRITE_SHEETS.stickers.rows,
279
- columns: SPRITE_SHEETS.stickers.columns,
280
- }));
281
- }
282
- if (isRental) {
283
- layers.push(new Layer({
284
- pos: STICKER_MAP["Rental"],
285
- name: "Rental",
286
- order: 5,
287
- source: SPRITE_SHEETS.stickers.src,
288
- rows: SPRITE_SHEETS.stickers.rows,
289
- columns: SPRITE_SHEETS.stickers.columns,
290
- }));
291
- }
292
- if (seal) {
293
- const sealPos = SEAL_MAP[seal];
294
- if (sealPos) {
295
- layers.push(new Layer({
296
- pos: sealPos,
297
- name: seal,
298
- order: 6,
299
- source: SPRITE_SHEETS.enhancers.src,
300
- rows: SPRITE_SHEETS.enhancers.rows,
301
- columns: SPRITE_SHEETS.enhancers.columns,
302
- }));
303
- }
304
- }
305
- const wrapperStyle = { width: `${71 * scale}px` };
306
- return (_jsx("div", { style: wrapperStyle, className: className, children: _jsx(JamlCardRenderer, { invert: edition === "Negative", layers: layers, hoverTilt: hoverTilt }) }));
307
- }
308
- export function JamlVoucher({ voucherName, scale = 1, className = "", hoverTilt = false }) {
309
- const voucherData = VOUCHERS.find((v) => v.name === voucherName);
310
- if (!voucherData)
311
- return null;
312
- const layers = [
313
- new Layer({
314
- ...voucherData,
315
- order: 0,
316
- source: SPRITE_SHEETS.vouchers.src,
317
- rows: SPRITE_SHEETS.vouchers.rows,
318
- columns: SPRITE_SHEETS.vouchers.columns,
319
- }),
320
- ];
321
- const wrapperStyle = { width: `${71 * scale}px` };
322
- return (_jsx("div", { style: wrapperStyle, className: className, children: _jsx(JamlCardRenderer, { layers: layers, hoverTilt: hoverTilt }) }));
323
- }
324
- export function JamlTag({ tagName, scale = 1, className = "", hoverTilt = false }) {
325
- const tagData = TAGS.find((t) => t.name === tagName);
326
- if (!tagData)
327
- return null;
328
- const layers = [
329
- new Layer({
330
- ...tagData,
331
- order: 0,
332
- source: SPRITE_SHEETS.tags.src,
333
- rows: SPRITE_SHEETS.tags.rows,
334
- columns: SPRITE_SHEETS.tags.columns,
335
- }),
336
- ];
337
- const wrapperStyle = { width: `${71 * scale}px` };
338
- return (_jsx("div", { style: wrapperStyle, className: className, children: _jsx(JamlCardRenderer, { layers: layers, hoverTilt: hoverTilt }) }));
339
- }
340
- export function JamlBoss({ bossName, scale = 1, className = "", hoverTilt = false }) {
341
- const bossData = BOSSES.find((b) => b.name === bossName);
342
- if (!bossData)
343
- return null;
344
- const layers = [
345
- new Layer({
346
- ...bossData,
347
- order: 0,
348
- source: SPRITE_SHEETS.blinds.src,
349
- rows: SPRITE_SHEETS.blinds.rows,
350
- columns: SPRITE_SHEETS.blinds.columns,
351
- }),
352
- ];
353
- const wrapperStyle = { width: `${71 * scale}px` };
354
- return (_jsx("div", { style: wrapperStyle, className: className, children: _jsx(JamlCardRenderer, { layers: layers, hoverTilt: hoverTilt }) }));
355
- }
@@ -1,22 +0,0 @@
1
- "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { JimboText } from "../ui/jimboText.js";
4
- import { JimboButton } from "../ui/panel.js";
5
- const AESTHETICS = [
6
- { id: "Palindrome", value: 0, label: "Palindrome", desc: "Seeds that read the same forwards and backwards" },
7
- { id: "Psychosis", value: 1, label: "Psychosis", desc: "Unsettling or eerie seed patterns" },
8
- { id: "Gross", value: 2, label: "Gross", desc: "Seeds with crude or disgusting words" },
9
- { id: "Nsfw", value: 3, label: "NSFW", desc: "Seeds with adult content" },
10
- { id: "Funny", value: 4, label: "Funny", desc: "Seeds that spell funny words" },
11
- { id: "Balatro", value: 5, label: "Balatro", desc: "Seeds referencing the game itself" },
12
- ];
13
- /**
14
- * Pill-toggle selector for seed aesthetic filters.
15
- * All styling via jimbo.css `.j-aesthetic-selector` / `.j-aesthetic-pill` — zero inline styles.
16
- */
17
- export function JamlAestheticSelector({ value, onChange, className, style }) {
18
- return (_jsxs("div", { className: `j-aesthetic-selector ${className ?? ""}`, style: style, children: [_jsx(JimboText, { size: "xs", tone: "grey", children: "Seed Aesthetics" }), _jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: 6, marginTop: 4 }, children: AESTHETICS.map((a) => {
19
- const isActive = value === a.id;
20
- return (_jsx(JimboButton, { tone: isActive ? "red" : "grey", size: "sm", onClick: () => onChange(isActive ? null : a.id, a.value), children: a.label }, a.id));
21
- }) })] }));
22
- }
@@ -1,263 +0,0 @@
1
- "use client";
2
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { useCallback, useMemo, useRef } from "react";
4
- import { JamlBoss, JamlGameCard, JamlTag, JamlVoucher, resolveAnalyzerShopItem } from "./GameCard.js";
5
- import { useMotelyStream } from "../hooks/useShopStream.js";
6
- import { useInfiniteScroll } from "../hooks/useIntersectionObserver.js";
7
- import { useAnteTracker } from "../ui/hooks.js";
8
- import { JimboText } from "../ui/jimboText.js";
9
- import { ANALYZER_STREAM_META, DEFAULT_ENABLED_STREAMS, buildStreamHandle, } from "../hooks/analyzerStreamRegistry.js";
10
- import { JimboColorOption, withAlpha } from "../ui/tokens.js";
11
- const C = JimboColorOption;
12
- const TONE_COLORS = {
13
- gold: C.GOLD_TEXT,
14
- purple: C.TAROT_BUTTON,
15
- blue: C.PLANET_BUTTON,
16
- spectral: C.SPECTRAL_BUTTON,
17
- default: C.GOLD_TEXT,
18
- };
19
- import { JamlMapPreview } from "./JamlMapPreview.js";
20
- export function JamlAnalyzerFullscreen({ antes, live, jaml, tallyColumns, tallyLabels, enabledStreams, chunkSize = 12, className = "", topPage, }) {
21
- const effectiveEnabled = enabledStreams ?? DEFAULT_ENABLED_STREAMS;
22
- const { currentAnte, scrollRef, scrollToAnte, registerAnteRef } = useAnteTracker(antes);
23
- return (_jsxs("div", { className: className, style: styles.root, children: [_jsxs("div", { ref: scrollRef, style: styles.scroller, children: [topPage ? topPage : jaml && (_jsxs("section", { style: { ...styles.section, scrollSnapAlign: "start", justifyContent: 'center' }, children: [_jsxs("div", { style: { marginBottom: 20 }, children: [_jsx("div", { style: styles.anteLabel, children: "JAML" }), _jsx("div", { style: styles.anteNumber, children: "MAP" })] }), _jsx(JamlMapPreview, { jaml: jaml, tallyColumns: tallyColumns, tallyLabels: tallyLabels }), _jsx("div", { style: { marginTop: 24, textAlign: 'center', opacity: 0.6 }, children: _jsx(JimboText, { size: "xs", tone: "grey", children: "Scroll down to explore seed details" }) })] })), antes.map((ante) => (_jsx(AnteSection, { ante: ante, live: live, enabledStreams: effectiveEnabled, chunkSize: chunkSize, registerRef: (el) => registerAnteRef(ante.ante, el) }, ante.ante)))] }), _jsx(SideRail, { antes: antes.map((a) => a.ante), currentAnte: currentAnte, onJump: scrollToAnte })] }));
24
- }
25
- function AnteSection({ ante, live, enabledStreams, chunkSize, registerRef }) {
26
- return (_jsxs("section", { ref: registerRef, "data-ante": ante.ante, style: styles.section, children: [_jsxs("header", { style: styles.header, children: [_jsxs("div", { children: [_jsx("div", { style: styles.anteLabel, children: "Ante" }), _jsx("div", { style: styles.anteNumber, children: ante.ante })] }), ante.voucher && (_jsxs("div", { style: styles.voucherBlock, children: [_jsx(JamlVoucher, { voucherName: ante.voucher, scale: 0.85 }), _jsx("div", { style: styles.voucherCaption, children: ante.voucher })] }))] }), _jsxs("div", { style: styles.blindRow, children: [_jsx(BlindCell, { label: "Small", tag: ante.smallBlindTag }), _jsx(BlindCell, { label: "Big", tag: ante.bigBlindTag }), ante.boss && (_jsxs("div", { style: styles.bossCell, children: [_jsx("div", { style: styles.cellLabel, children: "Boss" }), _jsx(JamlBoss, { bossName: ante.boss, scale: 0.7 }), _jsx("div", { style: styles.cellCaption, children: ante.boss })] }))] }), ante.packs && ante.packs.length > 0 && (_jsxs("div", { style: styles.streamLane, children: [_jsx("div", { style: styles.streamLabel, children: "Packs" }), _jsx("div", { style: styles.packRow, children: ante.packs.map((pack, i) => (_jsx("div", { style: styles.packPill, children: pack }, `${ante.ante}-pack-${i}`))) })] })), enabledStreams.map((key) => {
27
- const isShop = key === "shop";
28
- const initialItems = isShop
29
- ? (ante.shop ?? []).map((item) => ({
30
- id: item.id,
31
- name: item.name,
32
- value: item.value,
33
- }))
34
- : [];
35
- return (_jsx(StreamLane, { ante: ante.ante, streamKey: key, live: live, chunkSize: chunkSize, initialItems: initialItems }, `${ante.ante}-${key}`));
36
- })] }));
37
- }
38
- function StreamLane({ ante, streamKey, live, chunkSize, initialItems }) {
39
- const meta = ANALYZER_STREAM_META[streamKey];
40
- const handle = useMemo(() => (live ? buildStreamHandle(live, ante, streamKey) : null), [live, ante, streamKey]);
41
- const stream = useMotelyStream(handle?.initStream ?? null, handle?.nextItem ?? null, [ante, streamKey, live?.seed, live?.deck, live?.stake], initialItems);
42
- const desired = live?.desiredNames ?? new Set();
43
- const toneColor = TONE_COLORS[meta.tone] ?? TONE_COLORS.default;
44
- return (_jsxs("div", { style: styles.streamLane, children: [_jsxs("div", { style: { ...styles.streamLabel, color: toneColor }, children: [meta.label, stream.items.length > 0 ? ` · ${stream.items.length}` : ""] }), _jsx(ShopRow, { items: stream.items, desired: desired, loadingMore: stream.loadingMore, ready: stream.ready, onPullMore: () => stream.pullMore(chunkSize) }), stream.error && _jsxs("div", { style: styles.errorLine, children: ["stream error: ", stream.error] })] }));
45
- }
46
- function BlindCell({ label, tag }) {
47
- if (!tag)
48
- return null;
49
- return (_jsxs("div", { style: styles.blindCell, children: [_jsx("div", { style: styles.cellLabel, children: label }), _jsx(JamlTag, { tagName: tag, scale: 0.7 }), _jsx("div", { style: styles.cellCaption, children: tag })] }));
50
- }
51
- function ShopRow({ items, desired, loadingMore, ready, onPullMore }) {
52
- const lastTriggerRef = useRef(0);
53
- const throttlePull = useCallback(() => {
54
- const now = Date.now();
55
- if (now - lastTriggerRef.current < 200)
56
- return;
57
- lastTriggerRef.current = now;
58
- onPullMore();
59
- }, [onPullMore]);
60
- const sentinelRef = useInfiniteScroll(throttlePull, {
61
- threshold: 0.1,
62
- rootMargin: "0px 200px 0px 0px",
63
- }, ready && !loadingMore);
64
- return (_jsxs("div", { style: styles.shopRow, children: [items.map((item) => (_jsx(ShopItem, { item: item, desired: desired.has(item.name.toLowerCase()) }, item.id))), _jsx("div", { ref: sentinelRef, style: styles.sentinel, children: loadingMore ? "…" : "" })] }));
65
- }
66
- function ShopItem({ item, desired }) {
67
- const resolved = resolveAnalyzerShopItem({ id: item.id, name: item.name, value: item.value });
68
- const wrapperStyle = {
69
- flexShrink: 0,
70
- position: "relative",
71
- filter: desired ? `drop-shadow(0 0 6px ${C.GOLD})` : undefined,
72
- };
73
- const labelStyle = {
74
- fontSize: 10,
75
- color: desired ? C.GOLD : C.GREY,
76
- textAlign: "center",
77
- marginTop: 2,
78
- maxWidth: 80,
79
- overflow: "hidden",
80
- textOverflow: "ellipsis",
81
- whiteSpace: "nowrap",
82
- };
83
- return (_jsxs("div", { style: wrapperStyle, children: [resolved.kind === "joker" || resolved.kind === "consumable" || resolved.kind === "playing" ? (_jsx(JamlGameCard, { card: resolved.card, type: resolved.type })) : resolved.kind === "voucher" ? (_jsx(JamlVoucher, { voucherName: resolved.voucherName, scale: 0.7 })) : (_jsx("div", { style: styles.unknownTile, children: ("label" in resolved ? resolved.label : item.name) || "?" })), _jsx("div", { style: labelStyle, children: item.name })] }));
84
- }
85
- function SideRail({ antes, currentAnte, onJump }) {
86
- return (_jsx("div", { style: styles.sideRail, children: antes.map((ante) => {
87
- const active = ante === currentAnte;
88
- return (_jsx("button", { type: "button", onClick: () => onJump(ante), "aria-label": `Jump to ante ${ante}`, style: {
89
- ...styles.sideRailDot,
90
- background: active ? C.GOLD : withAlpha(C.WHITE, 0.25),
91
- transform: active ? "scale(1.4)" : "scale(1)",
92
- boxShadow: active ? `0 0 8px ${C.GOLD}` : "none",
93
- } }, ante));
94
- }) }));
95
- }
96
- const styles = {
97
- root: {
98
- position: "relative",
99
- width: "100%",
100
- height: "100svh",
101
- background: C.DARKEST,
102
- color: C.WHITE,
103
- fontFamily: "var(--font-sans, m6x11plus), monospace",
104
- overflow: "hidden",
105
- },
106
- scroller: {
107
- width: "100%",
108
- height: "100%",
109
- overflowY: "scroll",
110
- scrollSnapType: "y mandatory",
111
- scrollBehavior: "smooth",
112
- WebkitOverflowScrolling: "touch",
113
- },
114
- section: {
115
- width: "100%",
116
- minHeight: "100svh",
117
- scrollSnapAlign: "start",
118
- padding: "20px 16px 28px",
119
- display: "flex",
120
- flexDirection: "column",
121
- gap: 12,
122
- boxSizing: "border-box",
123
- borderBottom: `1px solid ${withAlpha(C.WHITE, 0.05)}`,
124
- },
125
- header: {
126
- display: "flex",
127
- justifyContent: "space-between",
128
- alignItems: "flex-start",
129
- gap: 12,
130
- },
131
- anteLabel: {
132
- fontSize: 12,
133
- color: C.GREY,
134
- letterSpacing: "0.16em",
135
- },
136
- anteNumber: {
137
- fontSize: 72,
138
- color: C.GOLD,
139
- lineHeight: 0.9,
140
- textShadow: `3px 3px 0 ${C.BLACK}`,
141
- },
142
- voucherBlock: {
143
- display: "flex",
144
- flexDirection: "column",
145
- alignItems: "center",
146
- gap: 4,
147
- },
148
- voucherCaption: {
149
- fontSize: 10,
150
- color: C.PURPLE,
151
- letterSpacing: "0.1em",
152
- },
153
- blindRow: {
154
- display: "flex",
155
- gap: 16,
156
- flexWrap: "wrap",
157
- },
158
- blindCell: {
159
- display: "flex",
160
- flexDirection: "column",
161
- alignItems: "center",
162
- gap: 4,
163
- },
164
- bossCell: {
165
- display: "flex",
166
- flexDirection: "column",
167
- alignItems: "center",
168
- gap: 4,
169
- },
170
- cellLabel: {
171
- fontSize: 10,
172
- color: C.GREY,
173
- letterSpacing: "0.12em",
174
- },
175
- cellCaption: {
176
- fontSize: 10,
177
- color: C.WHITE,
178
- maxWidth: 90,
179
- textAlign: "center",
180
- overflow: "hidden",
181
- textOverflow: "ellipsis",
182
- whiteSpace: "nowrap",
183
- },
184
- streamLane: {
185
- display: "flex",
186
- flexDirection: "column",
187
- gap: 6,
188
- minHeight: 0,
189
- },
190
- streamLabel: {
191
- fontSize: 11,
192
- color: C.GOLD_TEXT,
193
- letterSpacing: "0.16em",
194
- },
195
- shopRow: {
196
- display: "flex",
197
- gap: 10,
198
- overflowX: "auto",
199
- overflowY: "hidden",
200
- paddingBottom: 6,
201
- scrollbarWidth: "thin",
202
- },
203
- packRow: {
204
- display: "flex",
205
- flexWrap: "wrap",
206
- gap: 6,
207
- },
208
- packPill: {
209
- padding: "4px 10px",
210
- background: withAlpha(C.PANEL_EDGE, 0.9),
211
- border: `1px solid ${C.INNER_BORDER}`,
212
- borderRadius: 4,
213
- fontSize: 11,
214
- color: C.WHITE,
215
- },
216
- sentinel: {
217
- flexShrink: 0,
218
- width: 28,
219
- display: "flex",
220
- alignItems: "center",
221
- justifyContent: "center",
222
- color: C.GREY,
223
- fontSize: 14,
224
- },
225
- unknownTile: {
226
- width: 71,
227
- height: 95,
228
- border: `1px dashed ${C.GREY}`,
229
- borderRadius: 4,
230
- display: "flex",
231
- alignItems: "center",
232
- justifyContent: "center",
233
- fontSize: 9,
234
- color: C.GREY,
235
- padding: 4,
236
- textAlign: "center",
237
- },
238
- errorLine: {
239
- fontSize: 10,
240
- color: C.RED,
241
- },
242
- sideRail: {
243
- position: "absolute",
244
- top: "50%",
245
- right: 6,
246
- transform: "translateY(-50%)",
247
- display: "flex",
248
- flexDirection: "column",
249
- gap: 8,
250
- zIndex: 5,
251
- pointerEvents: "auto",
252
- },
253
- sideRailDot: {
254
- width: 8,
255
- height: 8,
256
- borderRadius: "50%",
257
- border: "none",
258
- cursor: "pointer",
259
- padding: 0,
260
- transition: "transform 0.15s ease, background 0.15s ease, box-shadow 0.15s ease",
261
- },
262
- };
263
- export { ANALYZER_STREAM_META } from "../hooks/analyzerStreamRegistry.js";