@puzzmo/sdk 1.0.8 → 1.0.9

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 (38) hide show
  1. package/README.md +72 -34
  2. package/dist/{createSimulator-_TBV3Yo7.cjs → createSimulator-BmeD2jIP.cjs} +28 -28
  3. package/dist/createSimulator-BmeD2jIP.cjs.map +1 -0
  4. package/dist/{createSimulator-D4oY1VzY.js → createSimulator-D-ln1AMv.js} +2 -8
  5. package/dist/createSimulator-D-ln1AMv.js.map +1 -0
  6. package/dist/{workshop.d.ts → editor.d.ts} +16 -3
  7. package/dist/editor.d.ts.map +1 -0
  8. package/dist/index.cjs +1 -1
  9. package/dist/index.cjs.map +1 -1
  10. package/dist/index.d.ts +3 -2
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +3 -11
  13. package/dist/index.js.map +1 -1
  14. package/dist/objectSpread2-C4RR_HMd.cjs +1 -0
  15. package/dist/objectSpread2-CJo2CZQ6.js +76 -0
  16. package/dist/sdk.d.ts.map +1 -1
  17. package/dist/simulator/createSimulator.d.ts +3 -0
  18. package/dist/simulator/createSimulator.d.ts.map +1 -1
  19. package/dist/simulator/index.cjs +1 -1
  20. package/dist/simulator/index.js +1 -1
  21. package/dist/simulator/standalone.cjs +1 -1
  22. package/dist/simulator/standalone.js +1 -1
  23. package/dist/types.d.ts +49 -29
  24. package/dist/types.d.ts.map +1 -1
  25. package/dist/vite.cjs +3 -3
  26. package/dist/vite.cjs.map +1 -1
  27. package/dist/vite.d.ts +18 -0
  28. package/dist/vite.d.ts.map +1 -1
  29. package/dist/vite.js +79 -23
  30. package/dist/vite.js.map +1 -1
  31. package/package.json +1 -1
  32. package/dist/asyncToGenerator-BlxRHn40.cjs +0 -1
  33. package/dist/asyncToGenerator-CPSNHDFw.js +0 -25
  34. package/dist/createSimulator-D4oY1VzY.js.map +0 -1
  35. package/dist/createSimulator-_TBV3Yo7.cjs.map +0 -1
  36. package/dist/objectSpread2-B6tAAMuy.cjs +0 -1
  37. package/dist/objectSpread2-vLYiAtaU.js +0 -52
  38. package/dist/workshop.d.ts.map +0 -1
package/README.md CHANGED
@@ -1,11 +1,30 @@
1
- # @puzzmo/sdk
1
+ # Puzzmo Game Infra
2
2
 
3
- SDK for building games on the Puzzmo platform. Handles communication between your game and the Puzzmo host (puzzmo.com, embeds, native apps).
3
+ Over the years we have a pretty refined route for making web games: prototype in HTML with no concern for code quality, share with people you like, then migrate it to a "real" codebase.
4
+
5
+ LLMs have changed this, and we're finding that the 'prototype in HTML' phase is getting close enough to production quality that it does not always warrant a a multi-month conversion to React/TypeScript/Redux to ensure the codebase can live forever.
6
+
7
+ So, after shipping two full games with this pipeline, we've knocked enough kinks out that it's ready for a more public space.
8
+
9
+ So, how do you make a game? Well first, you need a game - we can't help there! However, once you do, then you can start migrating it to run on Puzzmo by: `yarn create puzzmo game`.
10
+
11
+ ## @puzzmo/sdk
12
+
13
+ This repo is the SDK for building games on the Puzzmo platform. Handles communication between your game and Puzzmo.
14
+
15
+ There are a few parts here!
16
+
17
+ 1. The SDK, e.g. the runtime API for launching a game, completing it and other essentials
18
+ 2. The simulator, which provides the same message sending infrastructure Puzzmo.com will send to your game
19
+ 3. App integration information, e.g. how to make custom thumbnails for your puzzles (and more)
20
+ 4. Vite plugins which can help you get up and running faster
4
21
 
5
22
  ## Install
6
23
 
7
24
  ```bash
8
25
  npm install @puzzmo/sdk
26
+
27
+ yarn add @puzzmo/sdk
9
28
  ```
10
29
 
11
30
  ## Quick Start
@@ -43,33 +62,33 @@ Creates an SDK instance. Options:
43
62
 
44
63
  ### Lifecycle
45
64
 
46
- | Method | Description |
47
- | -------------------------- | -------------------------------------------------------------------------- |
48
- | `sdk.gameReady()` | Async. Signals readiness, returns puzzle data and theme. |
49
- | `sdk.gameLoaded(state?)` | Signals game UI is ready. Host will send `start`. |
50
- | `sdk.on(event, handler)` | Listen for events: `start`, `pause`, `resume`, `retry`, `settingsUpdate`. |
51
- | `sdk.off(event, handler)` | Remove an event listener. |
65
+ | Method | Description |
66
+ | ------------------------- | ------------------------------------------------------------------------- |
67
+ | `sdk.gameReady()` | Async. Signals readiness, returns puzzle data and theme. |
68
+ | `sdk.gameLoaded(state?)` | Signals game UI is ready. Host will send `start`. |
69
+ | `sdk.on(event, handler)` | Listen for events: `start`, `pause`, `resume`, `retry`, `settingsUpdate`. |
70
+ | `sdk.off(event, handler)` | Remove an event listener. |
52
71
 
53
72
  ### Game State
54
73
 
55
- | Method | Description |
56
- | ----------------------------------------------------------- | ---------------------------------------------------------- |
57
- | `sdk.updateGameState(stateString, play?)` | Save current game state for persistence. |
58
- | `sdk.gameCompleted(play, config?)` | Signal game completion with metrics and deeds. |
59
- | `sdk.showCompletionScreen(results, gameplay, showRetry?)` | Show the Puzzmo completion UI. |
60
- | `sdk.hitCheckpoint(name, config, augConfig?)` | Signal a gameplay milestone (for ads, leaderboards). |
74
+ | Method | Description |
75
+ | --------------------------------------------------------- | ---------------------------------------------------- |
76
+ | `sdk.updateGameState(stateString, play?)` | Save current game state for persistence. |
77
+ | `sdk.gameCompleted(play, config?)` | Signal game completion with metrics and deeds. |
78
+ | `sdk.showCompletionScreen(results, gameplay, showRetry?)` | Show the Puzzmo completion UI. |
79
+ | `sdk.hitCheckpoint(name, config, augConfig?)` | Signal a gameplay milestone (for ads, leaderboards). |
61
80
 
62
81
  ### Timer
63
82
 
64
83
  The SDK manages a timer automatically (starts on `start`, pauses on `pause`, resets on `retry`).
65
84
 
66
85
  ```ts
67
- sdk.timer.timeMs() // Elapsed time in ms
68
- sdk.timer.timeSecs() // Elapsed time in seconds
69
- sdk.timer.display() // ["1:23", "0:05"] (elapsed, penalty)
70
- sdk.timer.addPenalty(5000) // Add 5s penalty
71
- sdk.timer.isPaused() // Check if paused
72
- sdk.timer.isRunning() // Check if running
86
+ sdk.timer.timeMs() // Elapsed time in ms
87
+ sdk.timer.timeSecs() // Elapsed time in seconds
88
+ sdk.timer.display() // ["1:23", "0:05"] (elapsed, penalty)
89
+ sdk.timer.addPenalty(5000) // Add 5s penalty
90
+ sdk.timer.isPaused() // Check if paused
91
+ sdk.timer.isRunning() // Check if running
73
92
  ```
74
93
 
75
94
  ## Theme
@@ -80,14 +99,14 @@ The `theme` object from `gameReady()` contains color tokens for the current Puzz
80
99
  const { theme } = await sdk.gameReady()
81
100
 
82
101
  // Key colors
83
- theme.g_bg // Game background
84
- theme.fg // Foreground text
85
- theme.key // Primary accent
86
- theme.player // Player color (blue)
87
- theme.alt1 // Accent green
88
- theme.alt2 // Accent yellow
89
- theme.alt3 // Accent purple
90
- theme.type // "light" or "dark"
102
+ theme.g_bg // Game background
103
+ theme.fg // Foreground text
104
+ theme.key // Primary accent
105
+ theme.player // Player color (blue)
106
+ theme.alt1 // Accent green
107
+ theme.alt2 // Accent yellow
108
+ theme.alt3 // Accent purple
109
+ theme.type // "light" or "dark"
91
110
  ```
92
111
 
93
112
  See the `Theme` type export for the full list of tokens.
@@ -101,23 +120,42 @@ sdk.gameCompleted(metrics, {
101
120
  deeds: [
102
121
  { id: "moves", value: 42 },
103
122
  { id: "accuracy", value: 95 },
104
- { id: "streak", value: 8 },
123
+ { id: "hit-streak", value: 8 },
105
124
  ],
106
125
  })
107
126
  ```
108
127
 
109
128
  The SDK automatically adds `points` and `time` deeds.
110
129
 
111
- ## Workshop Types
130
+ ## App Integration
131
+
132
+ For games to show a dynamic thumbnail, you will need an App Bundle
133
+
134
+ ```ts
135
+ import type { EditorBundle, ValidationReport } from "@puzzmo/sdk"
136
+ import { puzzleToSVG } from "./src/puzzleToSVG"
137
+
138
+ export const AppBundle = {
139
+ renderThumbnail(puzzleString, boardState, config) {
140
+ return puzzleToSVG(puzzleString, boardState, config)
141
+ },
142
+ } satisfies EditorBundle
143
+ ```
144
+
145
+ This and the editor bundle are separate JavaScript files from your main game.
146
+
147
+ There are Vite plugins to make this easy, but otherwise, they should be files in your upload named `app-bundle.js` and `editor-bundle.js` with ESM exports which match the shapes of the TypeScript types.
148
+
149
+ ## Editor Integration
112
150
 
113
- For games that support puzzle editing in Puzzmo Workshop:
151
+ For games that support puzzle editing in Puzzmo Workshop, you will need an Editor Bundle:
114
152
 
115
153
  ```ts
116
- import type { WorkshopBundle, ValidationReport } from "@puzzmo/sdk"
154
+ import type { EditorBundle, ValidationReport } from "@puzzmo/sdk"
117
155
 
118
156
  export const validator = {
119
- validate(data: string): ValidationReport {
157
+ validate(data) {
120
158
  return { success: true, issues: [] }
121
159
  },
122
- }
160
+ } satisfies EditorBundle
123
161
  ```
@@ -1,4 +1,4 @@
1
- const e=require(`./asyncToGenerator-BlxRHn40.cjs`),t=require(`./objectSpread2-B6tAAMuy.cjs`),n=[{name:`Puzzmo (light)`,type:`light`,key:`#FFAAAC`,keyFG:`#000000`,keyStrong:`#F7868B`,keyLight:`#FFD2D3`,g_key:`#FFAAAC`,subBrand:`#FFC000`,subBrandFG:`#000000`,player:`#5DBAFC`,playerFG:`#000000`,playerLight:`#9EDDFF`,alt1:`#98B389`,alt2:`#FAC16C`,alt3:`#D298FF`,fg:`#000000`,error:`#FF3C3C`,alwaysDark:`#1B1D29`,alwaysLight:`#FFFFFF`,g_bg:`#FFFFFF`,g_bgAlt:`#EBEBEB`,g_bgDark:`#D6D6D6`,g_textDark:`#1B1B28`,g_textLight:`#FFFFFF`,g_blank:`#000000`,g_unsolved:`#C2C2C2`,g_outline:`#1B1D29`,a_bg:`#F2F2F2`,a_bgAlt:`#ECECEC`,a_puzmo:`#FFC000`,a_headerText:`#000000`,a_table:`#F9F9F9`,a_tableAlt:`#F6F4F4`,a_inlineTag:`#D9D9D9`,a_anchor:`#1F97EE`,a_infoBG:`#FFFFFF`},{name:`Puzzmo (dark)`,type:`dark`,key:`#FFAAAC`,keyFG:`#000000`,keyStrong:`#F7868B`,keyLight:`#FFD2D3`,g_key:`#FFAAAC`,player:`#5DBAFC`,playerFG:`#000000`,playerLight:`#9EDDFF`,subBrand:`#FFC000`,subBrandFG:`#000000`,alt1:`#98B389`,alt2:`#FAC16C`,alt3:`#D298FF`,error:`#FF3C3C`,fg:`#ECECEC`,alwaysDark:`#1B1D29`,alwaysLight:`#FFFFFF`,g_bg:`#374351`,g_bgAlt:`#333D49`,g_bgDark:`#2C2F33`,g_textDark:`#F2F2F2`,g_textLight:`#20180E`,g_blank:`#000000`,g_unsolved:`#747474`,g_outline:`#646464`,a_bg:`#141620`,a_bgAlt:`#202433`,a_puzmo:`#FFC000`,a_headerText:`#A1BAD4`,a_table:`#303246`,a_tableAlt:`#393b52`,a_inlineTag:`#ECECEC`,a_anchor:`#1F97EE`,a_infoBG:`#282C3A`},{name:`Foshay`,type:`light`,key:`#98B389`,keyFG:`#313540`,keyStrong:`#87BD69`,keyLight:`#809B77`,g_key:`#98B389`,player:`#3EC0E5`,subBrand:`#FFC000`,subBrandFG:`#000000`,playerFG:`#292B35`,playerLight:`#A8B5D6`,alt1:`#D87DA4`,alt2:`#E3A54F`,alt3:`#D298FF`,error:`#FF3C3C`,fg:`#292B35`,alwaysDark:`#292B35`,alwaysLight:`#D1DBF2`,g_bg:`#949EBA`,g_bgAlt:`#8891AB`,g_bgDark:`#7B839B`,g_textDark:`#292B35`,g_textLight:`#FFFFFF`,g_blank:`#292B35`,g_unsolved:`#B6B7BA`,g_outline:`#676F83`,a_bg:`#828CA3`,a_bgAlt:`#7F889F`,a_puzmo:`#FFC000`,a_headerText:`#292B35`,a_table:`#7A8399`,a_tableAlt:`#767E94`,a_inlineTag:`#ECECEC`,a_anchor:`#56C9E9`,a_infoBG:`#767F95`},{name:`Bright white`,type:`light`,key:`#67ced2`,keyFG:`#000000`,keyStrong:`#26a0a5`,keyLight:`#ade6e9`,g_key:`#67ced2`,subBrand:`#FFC000`,subBrandFG:`#000000`,player:`#5DBAFC`,playerFG:`#000000`,playerLight:`#9EDDFF`,alt1:`#d26767`,alt2:`#fac16c`,alt3:`#7580bd`,fg:`#000000`,error:`#FF3C3C`,alwaysDark:`#111111`,alwaysLight:`#FFFFFF`,g_bg:`#f6f6f6`,g_bgAlt:`#F4F4F4`,g_bgDark:`#D6D6D6`,g_textDark:`#1B1B28`,g_textLight:`#FFFFFF`,g_blank:`#000000`,g_unsolved:`#C2C2C2`,g_outline:`#1B1D29`,a_bg:`#FFFFFF`,a_bgAlt:`#f8fbfc`,a_puzmo:`#FFC000`,a_headerText:`#000000`,a_table:`#EDEDED`,a_tableAlt:`#DBDBDB`,a_inlineTag:`#D9D9D9`,a_anchor:`#1F97EE`,a_infoBG:`#f6f6f6`},{name:`Submersible`,type:`dark`,key:`#CD6DC6`,keyFG:`#031698`,keyStrong:`#FF7ABC`,keyLight:`#B467CB`,g_key:`#CD6DC6`,subBrand:`#FFC000`,subBrandFG:`#000000`,player:`#4AB1D1`,playerFG:`#071D47`,playerLight:`#3C99D7`,alt1:`#8BA964`,alt2:`#C69A58`,alt3:`#7644B5`,fg:`#FFEBFF`,error:`#FF3C3C`,alwaysDark:`#031698`,alwaysLight:`#FFEBFF`,g_bg:`#043BED`,g_bgAlt:`#0A31CC`,g_bgDark:`#0E2DA8`,g_textDark:`#031698`,g_textLight:`#FFEBFF`,g_blank:`#031698`,g_unsolved:`#3662F1`,g_outline:`#031698`,a_bg:`#043BED`,a_bgAlt:`#0A31CC`,a_puzmo:`#FFC000`,a_headerText:`#FFEBFF`,a_table:`#043BED`,a_tableAlt:`#0A31CC`,a_inlineTag:`#FF7ABC`,a_anchor:`#FF7ABC`,a_infoBG:`#0A31CC`},{name:`Hot Dog (beta)`,type:`light`,key:`#FFFF00`,keyFG:`#000000`,keyStrong:`#FFE600`,keyLight:`#FFEC44`,g_key:`#FFFF00`,subBrand:`#FFC000`,subBrandFG:`#000000`,player:`#FF7A00`,playerFG:`#000000`,playerLight:`#FFA450`,alt1:`#3ABC5E`,alt2:`#5C3ABC`,alt3:`#BC3AAF`,fg:`#000000`,error:`#FF3C3C`,alwaysDark:`#1B1D29`,alwaysLight:`#FFFFFF`,g_bg:`#EBFF00`,g_bgAlt:`#EBEBEB`,g_bgDark:`#D6D6D6`,g_textDark:`#1B1B28`,g_textLight:`#FFFFFF`,g_blank:`#000000`,g_unsolved:`#C2C2C2`,g_outline:`#1B1D29`,a_bg:`#FF0000`,a_bgAlt:`#E50000`,a_puzmo:`#FFC000`,a_headerText:`#FFFFFF`,a_table:`#E50000`,a_tableAlt:`#FF2525`,a_inlineTag:`#000000`,a_anchor:`#000000`,a_infoBG:`#C6C6C6`},{name:`Outlook Hayesy (beta)`,type:`light`,key:`#DAB98C`,keyFG:`#000000`,keyStrong:`#B99368`,keyLight:`#DAB98C`,subBrand:`#FFC000`,subBrandFG:`#000000`,g_key:`#DAB98C`,player:`#5DBAFC`,playerFG:`#000000`,playerLight:`#9EDDFF`,alt1:`#5EC386`,alt2:`#5E93C3`,alt3:`#C35E5E`,fg:`#000000`,error:`#FF3C3C`,alwaysDark:`#5E390F`,alwaysLight:`#FFF3E4`,g_bg:`#FFFFFF`,g_bgAlt:`#EBEBEB`,g_bgDark:`#D6D6D6`,g_textDark:`#1B1B28`,g_textLight:`#FFFFFF`,g_blank:`#000000`,g_unsolved:`#C2C2C2`,g_outline:`#1B1D29`,a_bg:`#FEF5E8`,a_bgAlt:`#ffffff`,a_puzmo:`#FAC7CE`,a_headerText:`#000000`,a_table:`#FAE8D3`,a_tableAlt:`#EED7BC`,a_inlineTag:`#D9D9D9`,a_anchor:`#B99368`,a_infoBG:`#FFFFFF`},{name:`Console (beta)`,type:`dark`,key:`#957df9`,keyFG:`#000000`,keyStrong:`#590FF5`,keyLight:`#590FF5`,subBrand:`#FFC000`,subBrandFG:`#000000`,g_key:`#FFFF00`,player:`#ffffff`,playerFG:`#000000`,playerLight:`#9EDDFF`,alt1:`#590ff5`,alt2:`#00e200`,alt3:`#ff8a02`,fg:`#00e200`,error:`#FF3C3C`,alwaysDark:`#1B1D29`,alwaysLight:`#00e200`,g_bg:`#101428`,g_bgAlt:`#101428`,g_bgDark:`#00e200`,g_textDark:`#00e200`,g_textLight:`#590ff5`,g_blank:`#00e200`,g_unsolved:`#0000ff`,g_outline:`#00e200`,a_bg:`#000000`,a_bgAlt:`#112211`,a_puzmo:`#ffffff`,a_headerText:`#00e200`,a_table:`#000000`,a_tableAlt:`#002200`,a_inlineTag:`#D9D9D9`,a_anchor:`#957df9`,a_infoBG:`#001900`}];var r={collapsed:`simulator-collapsed`,tab:`simulator-tab`,theme:`simulator-theme`,fixtureCategory:`simulator-fixture-category`,fixturePuzzle:`simulator-fixture-puzzle`,renderHost:`simulator-render-host`,renderContext:`simulator-render-context`};function i(){let e=localStorage.getItem(r.theme);if(e){let t=n.find(t=>t.name===e);if(t)return t}return n[0]}function a(e){var t;let n=localStorage.getItem(r.tab);return n&&e.includes(n)?n:(t=e[0])==null?`ctrl`:t}function o(e){let t=localStorage.getItem(r.collapsed);return t===null?e:t===`true`}function s(){let e=localStorage.getItem(r.renderHost);return e&&[`game`,`app`,`opengraph`].includes(e)?e:`game`}function c(){let e=localStorage.getItem(r.renderContext);if(e&&[`preview`,`share`,`completed`,`timeline`].includes(e))return e}function l(e,t,n){var l,u;let d=localStorage.getItem(r.fixtureCategory),f=localStorage.getItem(r.fixturePuzzle);return{isCollapsed:o((l=e.collapsed)==null?!0:l),isPaused:!1,hasStarted:!1,activeTab:a(n),puzzleData:null,originalPuzzle:``,currentInputStr:``,completionData:null,selectedTheme:i(),selectedCategory:d&&t.includes(d)?d:(u=t[0])==null?null:u,selectedPuzzle:f==null?null:f,renderHost:s(),renderContext:c()}}function u(e){localStorage.setItem(r.collapsed,String(e))}function d(e){localStorage.setItem(r.tab,e)}function f(e){localStorage.setItem(r.theme,e)}function p(e){localStorage.setItem(r.fixtureCategory,e)}function m(e){localStorage.setItem(r.fixturePuzzle,e)}function h(){localStorage.removeItem(r.fixturePuzzle)}function g(e){e?localStorage.setItem(r.renderHost,e):localStorage.removeItem(r.renderHost)}function _(e){e?localStorage.setItem(r.renderContext,e):localStorage.removeItem(r.renderContext)}function ee(e){let t=[];return{log(n,r,i){let a={type:n,data:r,time:new Date().toLocaleTimeString(`en-US`,{hour12:!1,hour:`2-digit`,minute:`2-digit`,second:`2-digit`}),direction:i};t.push(a),t.length>100&&t.shift(),e==null||e(a)},clear(){t.length=0},getLog(){return t}}}function te(e,t,n){console.log(`Simulator sending:`,e,t),n==null||n.log(e,t,`out`),window.postMessage({type:e,data:t},`*`)}function ne(e,t){let n=n=>{var r,i,a;if(!(!(n==null||(r=n.data)==null)&&r.type))return;let o=n.data.type,s=(i=(a=n.data.data)==null?n.data.json:a)==null?{}:i;[`TIMER_TICK`,`TIMER_SYNC`].includes(o)||t==null||t.log(o,s,`in`),e(o,s)};return window.addEventListener(`message`,n),()=>window.removeEventListener(`message`,n)}function v(e){let t=new Map;console.log(`Simulator: Parsing fixtures`,Object.keys(e));for(let[o,s]of Object.entries(e)){var n,r,i,a;let e=o.split(`/`),c=(n=(r=e.pop())==null?void 0:r.replace(`.json`,``))==null?``:n,l=(i=e.pop())==null?`default`:i;t.has(l)||t.set(l,new Map);let u=(a=s.default)==null?s:a;t.get(l).set(c,u)}return t.forEach((e,n)=>{let r=new Map(Array.from(e.entries()).sort((e,t)=>{var n,r,i,a;return parseInt((n=(r=e[0].match(/\d+/))==null?void 0:r[0])==null?`0`:n)-parseInt((i=(a=t[0].match(/\d+/))==null?void 0:a[0])==null?`0`:i)}));t.set(n,r)}),t}function y(e,t){return e.length===0?``:`
1
+ const e=require(`./objectSpread2-C4RR_HMd.cjs`),t=[{name:`Puzzmo (light)`,type:`light`,key:`#FFAAAC`,keyFG:`#000000`,keyStrong:`#F7868B`,keyLight:`#FFD2D3`,g_key:`#FFAAAC`,subBrand:`#FFC000`,subBrandFG:`#000000`,player:`#5DBAFC`,playerFG:`#000000`,playerLight:`#9EDDFF`,alt1:`#98B389`,alt2:`#FAC16C`,alt3:`#D298FF`,fg:`#000000`,error:`#FF3C3C`,alwaysDark:`#1B1D29`,alwaysLight:`#FFFFFF`,g_bg:`#FFFFFF`,g_bgAlt:`#EBEBEB`,g_bgDark:`#D6D6D6`,g_textDark:`#1B1B28`,g_textLight:`#FFFFFF`,g_blank:`#000000`,g_unsolved:`#C2C2C2`,g_outline:`#1B1D29`,a_bg:`#F2F2F2`,a_bgAlt:`#ECECEC`,a_puzmo:`#FFC000`,a_headerText:`#000000`,a_table:`#F9F9F9`,a_tableAlt:`#F6F4F4`,a_inlineTag:`#D9D9D9`,a_anchor:`#1F97EE`,a_infoBG:`#FFFFFF`},{name:`Puzzmo (dark)`,type:`dark`,key:`#FFAAAC`,keyFG:`#000000`,keyStrong:`#F7868B`,keyLight:`#FFD2D3`,g_key:`#FFAAAC`,player:`#5DBAFC`,playerFG:`#000000`,playerLight:`#9EDDFF`,subBrand:`#FFC000`,subBrandFG:`#000000`,alt1:`#98B389`,alt2:`#FAC16C`,alt3:`#D298FF`,error:`#FF3C3C`,fg:`#ECECEC`,alwaysDark:`#1B1D29`,alwaysLight:`#FFFFFF`,g_bg:`#374351`,g_bgAlt:`#333D49`,g_bgDark:`#2C2F33`,g_textDark:`#F2F2F2`,g_textLight:`#20180E`,g_blank:`#000000`,g_unsolved:`#747474`,g_outline:`#646464`,a_bg:`#141620`,a_bgAlt:`#202433`,a_puzmo:`#FFC000`,a_headerText:`#A1BAD4`,a_table:`#303246`,a_tableAlt:`#393b52`,a_inlineTag:`#ECECEC`,a_anchor:`#1F97EE`,a_infoBG:`#282C3A`},{name:`Foshay`,type:`light`,key:`#98B389`,keyFG:`#313540`,keyStrong:`#87BD69`,keyLight:`#809B77`,g_key:`#98B389`,player:`#3EC0E5`,subBrand:`#FFC000`,subBrandFG:`#000000`,playerFG:`#292B35`,playerLight:`#A8B5D6`,alt1:`#D87DA4`,alt2:`#E3A54F`,alt3:`#D298FF`,error:`#FF3C3C`,fg:`#292B35`,alwaysDark:`#292B35`,alwaysLight:`#D1DBF2`,g_bg:`#949EBA`,g_bgAlt:`#8891AB`,g_bgDark:`#7B839B`,g_textDark:`#292B35`,g_textLight:`#FFFFFF`,g_blank:`#292B35`,g_unsolved:`#B6B7BA`,g_outline:`#676F83`,a_bg:`#828CA3`,a_bgAlt:`#7F889F`,a_puzmo:`#FFC000`,a_headerText:`#292B35`,a_table:`#7A8399`,a_tableAlt:`#767E94`,a_inlineTag:`#ECECEC`,a_anchor:`#56C9E9`,a_infoBG:`#767F95`},{name:`Bright white`,type:`light`,key:`#67ced2`,keyFG:`#000000`,keyStrong:`#26a0a5`,keyLight:`#ade6e9`,g_key:`#67ced2`,subBrand:`#FFC000`,subBrandFG:`#000000`,player:`#5DBAFC`,playerFG:`#000000`,playerLight:`#9EDDFF`,alt1:`#d26767`,alt2:`#fac16c`,alt3:`#7580bd`,fg:`#000000`,error:`#FF3C3C`,alwaysDark:`#111111`,alwaysLight:`#FFFFFF`,g_bg:`#f6f6f6`,g_bgAlt:`#F4F4F4`,g_bgDark:`#D6D6D6`,g_textDark:`#1B1B28`,g_textLight:`#FFFFFF`,g_blank:`#000000`,g_unsolved:`#C2C2C2`,g_outline:`#1B1D29`,a_bg:`#FFFFFF`,a_bgAlt:`#f8fbfc`,a_puzmo:`#FFC000`,a_headerText:`#000000`,a_table:`#EDEDED`,a_tableAlt:`#DBDBDB`,a_inlineTag:`#D9D9D9`,a_anchor:`#1F97EE`,a_infoBG:`#f6f6f6`},{name:`Submersible`,type:`dark`,key:`#CD6DC6`,keyFG:`#031698`,keyStrong:`#FF7ABC`,keyLight:`#B467CB`,g_key:`#CD6DC6`,subBrand:`#FFC000`,subBrandFG:`#000000`,player:`#4AB1D1`,playerFG:`#071D47`,playerLight:`#3C99D7`,alt1:`#8BA964`,alt2:`#C69A58`,alt3:`#7644B5`,fg:`#FFEBFF`,error:`#FF3C3C`,alwaysDark:`#031698`,alwaysLight:`#FFEBFF`,g_bg:`#043BED`,g_bgAlt:`#0A31CC`,g_bgDark:`#0E2DA8`,g_textDark:`#031698`,g_textLight:`#FFEBFF`,g_blank:`#031698`,g_unsolved:`#3662F1`,g_outline:`#031698`,a_bg:`#043BED`,a_bgAlt:`#0A31CC`,a_puzmo:`#FFC000`,a_headerText:`#FFEBFF`,a_table:`#043BED`,a_tableAlt:`#0A31CC`,a_inlineTag:`#FF7ABC`,a_anchor:`#FF7ABC`,a_infoBG:`#0A31CC`},{name:`Hot Dog (beta)`,type:`light`,key:`#FFFF00`,keyFG:`#000000`,keyStrong:`#FFE600`,keyLight:`#FFEC44`,g_key:`#FFFF00`,subBrand:`#FFC000`,subBrandFG:`#000000`,player:`#FF7A00`,playerFG:`#000000`,playerLight:`#FFA450`,alt1:`#3ABC5E`,alt2:`#5C3ABC`,alt3:`#BC3AAF`,fg:`#000000`,error:`#FF3C3C`,alwaysDark:`#1B1D29`,alwaysLight:`#FFFFFF`,g_bg:`#EBFF00`,g_bgAlt:`#EBEBEB`,g_bgDark:`#D6D6D6`,g_textDark:`#1B1B28`,g_textLight:`#FFFFFF`,g_blank:`#000000`,g_unsolved:`#C2C2C2`,g_outline:`#1B1D29`,a_bg:`#FF0000`,a_bgAlt:`#E50000`,a_puzmo:`#FFC000`,a_headerText:`#FFFFFF`,a_table:`#E50000`,a_tableAlt:`#FF2525`,a_inlineTag:`#000000`,a_anchor:`#000000`,a_infoBG:`#C6C6C6`},{name:`Outlook Hayesy (beta)`,type:`light`,key:`#DAB98C`,keyFG:`#000000`,keyStrong:`#B99368`,keyLight:`#DAB98C`,subBrand:`#FFC000`,subBrandFG:`#000000`,g_key:`#DAB98C`,player:`#5DBAFC`,playerFG:`#000000`,playerLight:`#9EDDFF`,alt1:`#5EC386`,alt2:`#5E93C3`,alt3:`#C35E5E`,fg:`#000000`,error:`#FF3C3C`,alwaysDark:`#5E390F`,alwaysLight:`#FFF3E4`,g_bg:`#FFFFFF`,g_bgAlt:`#EBEBEB`,g_bgDark:`#D6D6D6`,g_textDark:`#1B1B28`,g_textLight:`#FFFFFF`,g_blank:`#000000`,g_unsolved:`#C2C2C2`,g_outline:`#1B1D29`,a_bg:`#FEF5E8`,a_bgAlt:`#ffffff`,a_puzmo:`#FAC7CE`,a_headerText:`#000000`,a_table:`#FAE8D3`,a_tableAlt:`#EED7BC`,a_inlineTag:`#D9D9D9`,a_anchor:`#B99368`,a_infoBG:`#FFFFFF`},{name:`Console (beta)`,type:`dark`,key:`#957df9`,keyFG:`#000000`,keyStrong:`#590FF5`,keyLight:`#590FF5`,subBrand:`#FFC000`,subBrandFG:`#000000`,g_key:`#FFFF00`,player:`#ffffff`,playerFG:`#000000`,playerLight:`#9EDDFF`,alt1:`#590ff5`,alt2:`#00e200`,alt3:`#ff8a02`,fg:`#00e200`,error:`#FF3C3C`,alwaysDark:`#1B1D29`,alwaysLight:`#00e200`,g_bg:`#101428`,g_bgAlt:`#101428`,g_bgDark:`#00e200`,g_textDark:`#00e200`,g_textLight:`#590ff5`,g_blank:`#00e200`,g_unsolved:`#0000ff`,g_outline:`#00e200`,a_bg:`#000000`,a_bgAlt:`#112211`,a_puzmo:`#ffffff`,a_headerText:`#00e200`,a_table:`#000000`,a_tableAlt:`#002200`,a_inlineTag:`#D9D9D9`,a_anchor:`#957df9`,a_infoBG:`#001900`}];var n={collapsed:`simulator-collapsed`,tab:`simulator-tab`,theme:`simulator-theme`,fixtureCategory:`simulator-fixture-category`,fixturePuzzle:`simulator-fixture-puzzle`,renderHost:`simulator-render-host`,renderContext:`simulator-render-context`};function r(){let e=localStorage.getItem(n.theme);if(e){let n=t.find(t=>t.name===e);if(n)return n}return t[0]}function i(e){var t;let r=localStorage.getItem(n.tab);return r&&e.includes(r)?r:(t=e[0])==null?`ctrl`:t}function a(e){let t=localStorage.getItem(n.collapsed);return t===null?e:t===`true`}function o(){let e=localStorage.getItem(n.renderHost);return e&&[`game`,`app`,`opengraph`].includes(e)?e:`game`}function s(){let e=localStorage.getItem(n.renderContext);if(e&&[`preview`,`share`,`completed`,`timeline`].includes(e))return e}function c(e,t,c){var l,u;let d=localStorage.getItem(n.fixtureCategory),f=localStorage.getItem(n.fixturePuzzle);return{isCollapsed:a((l=e.collapsed)==null?!0:l),isPaused:!1,hasStarted:!1,activeTab:i(c),puzzleData:null,originalPuzzle:``,currentInputStr:``,completionData:null,selectedTheme:r(),selectedCategory:d&&t.includes(d)?d:(u=t[0])==null?null:u,selectedPuzzle:f==null?null:f,renderHost:o(),renderContext:s()}}function l(e){localStorage.setItem(n.collapsed,String(e))}function u(e){localStorage.setItem(n.tab,e)}function d(e){localStorage.setItem(n.theme,e)}function f(e){localStorage.setItem(n.fixtureCategory,e)}function p(e){localStorage.setItem(n.fixturePuzzle,e)}function m(){localStorage.removeItem(n.fixturePuzzle)}function h(e){e?localStorage.setItem(n.renderHost,e):localStorage.removeItem(n.renderHost)}function g(e){e?localStorage.setItem(n.renderContext,e):localStorage.removeItem(n.renderContext)}function ee(e){let t=[];return{log(n,r,i){let a={type:n,data:r,time:new Date().toLocaleTimeString(`en-US`,{hour12:!1,hour:`2-digit`,minute:`2-digit`,second:`2-digit`}),direction:i};t.push(a),t.length>100&&t.shift(),e==null||e(a)},clear(){t.length=0},getLog(){return t}}}function te(e,t,n){console.log(`Simulator sending:`,e,t),n==null||n.log(e,t,`out`),window.postMessage({type:e,data:t},`*`)}function ne(e,t){let n=n=>{var r,i,a;if(!(!(n==null||(r=n.data)==null)&&r.type))return;let o=n.data.type,s=(i=(a=n.data.data)==null?n.data.json:a)==null?{}:i;[`TIMER_TICK`,`TIMER_SYNC`].includes(o)||t==null||t.log(o,s,`in`),e(o,s)};return window.addEventListener(`message`,n),()=>window.removeEventListener(`message`,n)}function _(e){let t=new Map;console.log(`Simulator: Parsing fixtures`,Object.keys(e));for(let[o,s]of Object.entries(e)){var n,r,i,a;let e=o.split(`/`),c=(n=(r=e.pop())==null?void 0:r.replace(`.json`,``))==null?``:n,l=(i=e.pop())==null?`default`:i;t.has(l)||t.set(l,new Map);let u=(a=s.default)==null?s:a;t.get(l).set(c,u)}return t.forEach((e,n)=>{let r=new Map(Array.from(e.entries()).sort((e,t)=>{var n,r,i,a;return parseInt((n=(r=e[0].match(/\d+/))==null?void 0:r[0])==null?`0`:n)-parseInt((i=(a=t[0].match(/\d+/))==null?void 0:a[0])==null?`0`:i)}));t.set(n,r)}),t}function v(e,t){return e.length===0?``:`
2
2
  <div class="simulator-fixtures">
3
3
  <div class="simulator-field">
4
4
  <label class="simulator-label">Category</label>
@@ -11,7 +11,7 @@ const e=require(`./asyncToGenerator-BlxRHn40.cjs`),t=require(`./objectSpread2-B6
11
11
  <select class="simulator-select" id="simulator-fixture-puzzle"></select>
12
12
  </div>
13
13
  </div>
14
- `}function b(e,t,n,r){let i=t.get(n);if(!i)return null;let a=Array.from(i.keys()),o=r;if(!r||!i.has(r)){var s;o=(s=a[0])==null?null:s}return e.innerHTML=a.map(e=>`<option value="${e}" ${e===o?`selected`:``}>${e}</option>`).join(``),o}function x(e,t,n){var r,i;return!t||!n||(r=(i=e.get(t))==null?void 0:i.get(n))==null?null:r}function re(){return{id:`ctrl`,label:`Ctrl`,render(){return`
14
+ `}function y(e,t,n,r){let i=t.get(n);if(!i)return null;let a=Array.from(i.keys()),o=r;if(!r||!i.has(r)){var s;o=(s=a[0])==null?null:s}return e.innerHTML=a.map(e=>`<option value="${e}" ${e===o?`selected`:``}>${e}</option>`).join(``),o}function b(e,t,n){var r,i;return!t||!n||(r=(i=e.get(t))==null?void 0:i.get(n))==null?null:r}function re(){return{id:`ctrl`,label:`Ctrl`,render(){return`
15
15
  <div id="simulator-fixtures-container"></div>
16
16
  <div id="simulator-status">
17
17
  <span class="indicator waiting"></span>
@@ -24,7 +24,7 @@ const e=require(`./asyncToGenerator-BlxRHn40.cjs`),t=require(`./objectSpread2-B6
24
24
  <div class="simulator-row">
25
25
  <button class="simulator-btn danger" id="simulator-retry" disabled>Retry</button>
26
26
  </div>
27
- `},bind(e){let t=e.getElement(`#simulator-start`),n=e.getElement(`#simulator-pause`),r=e.getElement(`#simulator-retry`),i=e.getElement(`#simulator-fixtures-container`);if(console.log(`Simulator: CtrlView.bind called`,{hasFixtures:!!e.fixtures,categories:e.fixtureCategories,selectedCategory:e.state.selectedCategory,selectedPuzzle:e.state.selectedPuzzle}),e.fixtures&&e.fixtureCategories.length>0&&i){i.innerHTML=y(e.fixtureCategories,e.state.selectedCategory);let t=e.getElement(`#simulator-fixture-category`),n=e.getElement(`#simulator-fixture-puzzle`);if(t&&n&&e.state.selectedCategory){e.state.selectedPuzzle=b(n,e.fixtures,e.state.selectedCategory,e.state.selectedPuzzle);let r=x(e.fixtures,e.state.selectedCategory,e.state.selectedPuzzle);console.log(`Simulator: Loading fixture puzzle`,{category:e.state.selectedCategory,puzzle:e.state.selectedPuzzle,hasPuzzleData:!!r}),r&&(e.state.puzzleData=r,e.state.originalPuzzle=JSON.stringify(r,null,2),e.state.selectedCategory&&p(e.state.selectedCategory),e.state.selectedPuzzle&&m(e.state.selectedPuzzle)),t.addEventListener(`change`,()=>{console.log(`Simulator: Category changed, reloading...`,t.value),p(t.value),h(),window.location.reload()}),n.addEventListener(`change`,()=>{console.log(`Simulator: Puzzle changed, reloading...`,n.value),m(n.value),window.location.reload()})}}t==null||t.addEventListener(`click`,()=>{e.state.isPaused?(e.sendToGame(`RESUME_GAME`,{}),e.state.isPaused=!1,n&&(n.textContent=`Pause`),e.updateStatus(`Running`,`ready`)):(e.sendToGame(`START_GAME`,void 0),e.state.hasStarted=!0,n&&(n.disabled=!1),t&&(t.textContent=`Resume`),e.updateStatus(`Running`,`ready`))}),n==null||n.addEventListener(`click`,()=>{e.state.isPaused?(e.sendToGame(`RESUME_GAME`,{}),e.state.isPaused=!1,n.textContent=`Pause`,e.updateStatus(`Running`,`ready`)):(e.sendToGame(`PAUSE_GAME`,{}),e.state.isPaused=!0,n.textContent=`Resume`,e.updateStatus(`Paused`,`paused`))}),r==null||r.addEventListener(`click`,()=>{e.sendToGame(`RETRY_PUZZLE`,{}),e.state.hasStarted=!1,e.state.isPaused=!1,n&&(n.disabled=!0,n.textContent=`Pause`),t&&(t.textContent=`Start`),e.updateStatus(`Ready to retry`,`ready`)})},onMessage(e,t,n){let r=n.getElement(`#simulator-start`),i=n.getElement(`#simulator-pause`),a=n.getElement(`#simulator-retry`);e===`READY_GAME_LOADED`&&(r&&(r.disabled=!1),a&&(a.disabled=!1),n.updateStatus(`Ready`,`ready`)),e===`GAME_COMPLETED`&&(n.state.hasStarted=!1,i&&(i.disabled=!0),r&&(r.disabled=!0),n.updateStatus(`Completed!`,`ready`))}}}var S=`simulator-saved-states`;function C(){let e=globalThis;for(let t of Object.keys(e))if(t.endsWith(`Thumbnail`)&&typeof e[t]==`function`)return{name:t,fn:e[t]};return null}function w(e,t){let n=C();if(!n)return``;try{let r=e.state.puzzleData?JSON.stringify(e.state.puzzleData):``,i={viewerIsOwner:!0,theme:e.state.selectedTheme,strict:!0,renderHost:`game`};return n.fn(r,t,i)}catch(e){return``}}var T=[];function E(e,t=8){let n=14*t+8+4;e.style.height=`auto`;let r=Math.min(Math.max(e.scrollHeight,40),n);e.style.height=`${r}px`}function ie(){let e=``,t=``;return{id:`data`,label:`Data`,render(){return`
27
+ `},bind(e){let t=e.getElement(`#simulator-start`),n=e.getElement(`#simulator-pause`),r=e.getElement(`#simulator-retry`),i=e.getElement(`#simulator-fixtures-container`);if(console.log(`Simulator: CtrlView.bind called`,{hasFixtures:!!e.fixtures,categories:e.fixtureCategories,selectedCategory:e.state.selectedCategory,selectedPuzzle:e.state.selectedPuzzle}),e.fixtures&&e.fixtureCategories.length>0&&i){i.innerHTML=v(e.fixtureCategories,e.state.selectedCategory);let t=e.getElement(`#simulator-fixture-category`),n=e.getElement(`#simulator-fixture-puzzle`);if(t&&n&&e.state.selectedCategory){e.state.selectedPuzzle=y(n,e.fixtures,e.state.selectedCategory,e.state.selectedPuzzle);let r=b(e.fixtures,e.state.selectedCategory,e.state.selectedPuzzle);console.log(`Simulator: Loading fixture puzzle`,{category:e.state.selectedCategory,puzzle:e.state.selectedPuzzle,hasPuzzleData:!!r}),r&&(e.state.puzzleData=r,e.state.originalPuzzle=JSON.stringify(r,null,2),e.state.selectedCategory&&f(e.state.selectedCategory),e.state.selectedPuzzle&&p(e.state.selectedPuzzle)),t.addEventListener(`change`,()=>{console.log(`Simulator: Category changed, reloading...`,t.value),f(t.value),m(),window.location.reload()}),n.addEventListener(`change`,()=>{console.log(`Simulator: Puzzle changed, reloading...`,n.value),p(n.value),window.location.reload()})}}t==null||t.addEventListener(`click`,()=>{e.state.isPaused?(e.sendToGame(`RESUME_GAME`,{}),e.state.isPaused=!1,n&&(n.textContent=`Pause`),e.updateStatus(`Running`,`ready`)):(e.sendToGame(`START_GAME`,void 0),e.state.hasStarted=!0,n&&(n.disabled=!1),t&&(t.textContent=`Resume`),e.updateStatus(`Running`,`ready`))}),n==null||n.addEventListener(`click`,()=>{e.state.isPaused?(e.sendToGame(`RESUME_GAME`,{}),e.state.isPaused=!1,n.textContent=`Pause`,e.updateStatus(`Running`,`ready`)):(e.sendToGame(`PAUSE_GAME`,{}),e.state.isPaused=!0,n.textContent=`Resume`,e.updateStatus(`Paused`,`paused`))}),r==null||r.addEventListener(`click`,()=>{e.sendToGame(`RETRY_PUZZLE`,{}),e.state.hasStarted=!1,e.state.isPaused=!1,n&&(n.disabled=!0,n.textContent=`Pause`),t&&(t.textContent=`Start`),e.updateStatus(`Ready to retry`,`ready`)})},onMessage(e,t,n){let r=n.getElement(`#simulator-start`),i=n.getElement(`#simulator-pause`),a=n.getElement(`#simulator-retry`);e===`READY_GAME_LOADED`&&(r&&(r.disabled=!1),a&&(a.disabled=!1),n.updateStatus(`Ready`,`ready`)),e===`GAME_COMPLETED`&&(n.state.hasStarted=!1,i&&(i.disabled=!0),r&&(r.disabled=!0),n.updateStatus(`Completed!`,`ready`))}}}var x=`simulator-saved-states`;function S(){let e=globalThis;for(let t of Object.keys(e))if(t.endsWith(`Thumbnail`)&&typeof e[t]==`function`)return{name:t,fn:e[t]};return null}function C(e,t){let n=S();if(!n)return``;try{let r=e.state.puzzleData?JSON.stringify(e.state.puzzleData):``,i={viewerIsOwner:!0,theme:e.state.selectedTheme,strict:!0,renderHost:`game`};return n.fn(r,t,i)}catch(e){return``}}var w=[];function T(e,t=8){let n=14*t+8+4;e.style.height=`auto`;let r=Math.min(Math.max(e.scrollHeight,40),n);e.style.height=`${r}px`}function ie(){let e=``,t=``;return{id:`data`,label:`Data`,render(){return`
28
28
  <div class="data-view-container">
29
29
  <div class="data-subtabs">
30
30
  <button class="data-subtab active" data-subtab="edit">Edit</button>
@@ -73,22 +73,22 @@ const e=require(`./asyncToGenerator-BlxRHn40.cjs`),t=require(`./objectSpread2-B6
73
73
  </div>
74
74
  </div>
75
75
  </div>
76
- `},bind(n){let r=n.getElement(`.data-subtabs`);r==null||r.querySelectorAll(`.data-subtab`).forEach(e=>{e.addEventListener(`click`,()=>{let t=e.getAttribute(`data-subtab`);if(!t)return;r.querySelectorAll(`.data-subtab`).forEach(e=>e.classList.remove(`active`)),e.classList.add(`active`);let i=n.getElement(`.data-view-container`);i==null||i.querySelectorAll(`.data-subtab-content`).forEach(e=>{e.classList.toggle(`active`,e.id===`data-subtab-${t}`)}),t===`edit`?j(n):t===`history`?O(n):t===`saves`&&k(n)})});let i=n.getElement(`#simulator-puzzle`),a=n.getElement(`#simulator-input`),o=n.getElement(`#simulator-puzzle-reset`),s=n.getElement(`#simulator-puzzle-apply`),c=n.getElement(`#simulator-input-reset`),l=n.getElement(`#simulator-input-apply`),u=n.getElement(`#simulator-start`),d=n.getElement(`#simulator-pause`);setTimeout(()=>{i&&n.state.originalPuzzle&&(i.value=n.state.originalPuzzle,e=n.state.originalPuzzle,E(i)),a&&n.state.currentInputStr&&(a.value=n.state.currentInputStr,t=n.state.currentInputStr,E(a))},0),i==null||i.addEventListener(`input`,()=>{E(i);let t=i.value!==e;s&&(s.disabled=!t)}),a==null||a.addEventListener(`input`,()=>{E(a);let e=a.value!==t;l&&(l.disabled=!e)}),o==null||o.addEventListener(`click`,()=>{i&&(i.value=n.state.originalPuzzle,e=n.state.originalPuzzle,E(i),s&&(s.disabled=!0))}),s==null||s.addEventListener(`click`,()=>{if(i)try{let t=JSON.parse(i.value);n.state.puzzleData=t,n.state.originalPuzzle=i.value,e=i.value,n.sendToGame(`RETRY_PUZZLE`,{}),n.state.hasStarted=!1,n.state.isPaused=!1,d&&(d.disabled=!0,d.textContent=`Pause`),u&&(u.textContent=`Start`),n.updateStatus(`Puzzle updated`,`ready`),s.disabled=!0}catch(e){console.error(`Simulator: Invalid puzzle JSON`,e),n.updateStatus(`Invalid JSON`,`paused`)}}),c==null||c.addEventListener(`click`,()=>{a&&(a.value=t,E(a),l&&(l.disabled=!0))}),l==null||l.addEventListener(`click`,()=>{a&&(n.state.currentInputStr=a.value,t=a.value,console.log(`Simulator: Input string updated (game restart required to apply)`),n.updateStatus(`Input stored`,`ready`),l.disabled=!0)});let f=n.getElement(`#simulator-history-clear`);f==null||f.addEventListener(`click`,()=>{T=[],O(n)});let p=n.getElement(`#simulator-save-name`),m=n.getElement(`#simulator-save-btn`);m==null||m.addEventListener(`click`,()=>{if(!p||!p.value.trim())return;let e=D(),t={name:p.value.trim(),puzzleStr:n.state.originalPuzzle,inputStr:n.state.currentInputStr,timestamp:Date.now()};e.push(t),localStorage.setItem(S,JSON.stringify(e)),p.value=``,k(n)}),k(n)},onActivate(n){e=n.state.originalPuzzle,t=n.state.currentInputStr,j(n),O(n)},onMessage(e,n,r){var i,a;let o=r.getElement(`#simulator-input`),s=r.getElement(`#simulator-input-apply`),c=(i=n==null||(a=n.input)==null?void 0:a.boardState)==null?n==null?void 0:n.boardState:i;if(e===`UPLOAD_NEW_GAME_STATE`&&c){if(r.state.currentInputStr=c,T.length===0||T[T.length-1].value!==c){T.push({value:c,timestamp:Date.now()}),T.length>100&&(T=T.slice(-100));let e=r.getElement(`#data-subtab-history`);e!=null&&e.classList.contains(`active`)&&O(r)}o&&(o.value=r.state.currentInputStr,t=r.state.currentInputStr,E(o),s&&(s.disabled=!0))}}}}function D(){try{let e=localStorage.getItem(S);return e?JSON.parse(e):[]}catch(e){return[]}}function O(e){let t=e.getElement(`#simulator-history-list`);if(t){if(t.style.setProperty(`--history-thumb-bg`,e.state.selectedTheme.a_bg),T.length===0){t.innerHTML=`<div class="simulator-empty">No history yet</div>`;return}t.innerHTML=[...T].reverse().map((t,n)=>{let r=T.length-1-n,i=new Date(t.timestamp).toLocaleTimeString(),a=t.value.length>60?t.value.slice(0,60)+`...`:t.value;return`
76
+ `},bind(n){let r=n.getElement(`.data-subtabs`);r==null||r.querySelectorAll(`.data-subtab`).forEach(e=>{e.addEventListener(`click`,()=>{let t=e.getAttribute(`data-subtab`);if(!t)return;r.querySelectorAll(`.data-subtab`).forEach(e=>e.classList.remove(`active`)),e.classList.add(`active`);let i=n.getElement(`.data-view-container`);i==null||i.querySelectorAll(`.data-subtab-content`).forEach(e=>{e.classList.toggle(`active`,e.id===`data-subtab-${t}`)}),t===`edit`?A(n):t===`history`?D(n):t===`saves`&&O(n)})});let i=n.getElement(`#simulator-puzzle`),a=n.getElement(`#simulator-input`),o=n.getElement(`#simulator-puzzle-reset`),s=n.getElement(`#simulator-puzzle-apply`),c=n.getElement(`#simulator-input-reset`),l=n.getElement(`#simulator-input-apply`),u=n.getElement(`#simulator-start`),d=n.getElement(`#simulator-pause`);setTimeout(()=>{i&&n.state.originalPuzzle&&(i.value=n.state.originalPuzzle,e=n.state.originalPuzzle,T(i)),a&&n.state.currentInputStr&&(a.value=n.state.currentInputStr,t=n.state.currentInputStr,T(a))},0),i==null||i.addEventListener(`input`,()=>{T(i);let t=i.value!==e;s&&(s.disabled=!t)}),a==null||a.addEventListener(`input`,()=>{T(a);let e=a.value!==t;l&&(l.disabled=!e)}),o==null||o.addEventListener(`click`,()=>{i&&(i.value=n.state.originalPuzzle,e=n.state.originalPuzzle,T(i),s&&(s.disabled=!0))}),s==null||s.addEventListener(`click`,()=>{if(i)try{let t=JSON.parse(i.value);n.state.puzzleData=t,n.state.originalPuzzle=i.value,e=i.value,n.sendToGame(`RETRY_PUZZLE`,{}),n.state.hasStarted=!1,n.state.isPaused=!1,d&&(d.disabled=!0,d.textContent=`Pause`),u&&(u.textContent=`Start`),n.updateStatus(`Puzzle updated`,`ready`),s.disabled=!0}catch(e){console.error(`Simulator: Invalid puzzle JSON`,e),n.updateStatus(`Invalid JSON`,`paused`)}}),c==null||c.addEventListener(`click`,()=>{a&&(a.value=t,T(a),l&&(l.disabled=!0))}),l==null||l.addEventListener(`click`,()=>{a&&(n.state.currentInputStr=a.value,t=a.value,console.log(`Simulator: Input string updated (game restart required to apply)`),n.updateStatus(`Input stored`,`ready`),l.disabled=!0)});let f=n.getElement(`#simulator-history-clear`);f==null||f.addEventListener(`click`,()=>{w=[],D(n)});let p=n.getElement(`#simulator-save-name`),m=n.getElement(`#simulator-save-btn`);m==null||m.addEventListener(`click`,()=>{if(!p||!p.value.trim())return;let e=E(),t={name:p.value.trim(),puzzleStr:n.state.originalPuzzle,inputStr:n.state.currentInputStr,timestamp:Date.now()};e.push(t),localStorage.setItem(x,JSON.stringify(e)),p.value=``,O(n)}),O(n)},onActivate(n){e=n.state.originalPuzzle,t=n.state.currentInputStr,A(n),D(n)},onMessage(e,n,r){var i,a;let o=r.getElement(`#simulator-input`),s=r.getElement(`#simulator-input-apply`),c=(i=n==null||(a=n.input)==null?void 0:a.boardState)==null?n==null?void 0:n.boardState:i;if(e===`UPLOAD_NEW_GAME_STATE`&&c){if(r.state.currentInputStr=c,w.length===0||w[w.length-1].value!==c){w.push({value:c,timestamp:Date.now()}),w.length>100&&(w=w.slice(-100));let e=r.getElement(`#data-subtab-history`);e!=null&&e.classList.contains(`active`)&&D(r)}o&&(o.value=r.state.currentInputStr,t=r.state.currentInputStr,T(o),s&&(s.disabled=!0))}}}}function E(){try{let e=localStorage.getItem(x);return e?JSON.parse(e):[]}catch(e){return[]}}function D(e){let t=e.getElement(`#simulator-history-list`);if(t){if(t.style.setProperty(`--history-thumb-bg`,e.state.selectedTheme.a_bg),w.length===0){t.innerHTML=`<div class="simulator-empty">No history yet</div>`;return}t.innerHTML=[...w].reverse().map((t,n)=>{let r=w.length-1-n,i=new Date(t.timestamp).toLocaleTimeString(),a=t.value.length>60?t.value.slice(0,60)+`...`:t.value;return`
77
77
  <div class="history-item" data-history-idx="${r}">
78
- <div class="history-item-thumb">${w(e,t.value)}</div>
78
+ <div class="history-item-thumb">${C(e,t.value)}</div>
79
79
  <div class="history-item-content">
80
80
  <div class="history-item-header">
81
81
  <span class="history-item-num">#${r+1}</span>
82
82
  <span class="history-item-time">${i}</span>
83
83
  <button class="simulator-btn tiny history-restore-btn" data-history-idx="${r}">Restore</button>
84
84
  </div>
85
- <div class="history-item-preview">${A(a)}</div>
85
+ <div class="history-item-preview">${k(a)}</div>
86
86
  </div>
87
87
  </div>
88
- `}).join(``),t.querySelectorAll(`.history-restore-btn`).forEach(t=>{t.addEventListener(`click`,t=>{let n=parseInt(t.target.getAttribute(`data-history-idx`)||`0`),r=T[n];if(r){e.state.currentInputStr=r.value;let t=e.getElement(`#simulator-input`);t&&(t.value=r.value,E(t)),e.updateStatus(`Input restored from history`,`ready`);let n=e.getElement(`.data-subtab[data-subtab="edit"]`);n==null||n.click()}})})}}function k(e){let t=e.getElement(`#simulator-saves-list`);if(!t)return;let n=D();if(n.length===0){t.innerHTML=`<div class="simulator-empty">No saved states</div>`;return}t.innerHTML=[...n].reverse().map((e,t)=>{let r=n.length-1-t,i=new Date(e.timestamp).toLocaleDateString(),a=new Date(e.timestamp).toLocaleTimeString();return`
88
+ `}).join(``),t.querySelectorAll(`.history-restore-btn`).forEach(t=>{t.addEventListener(`click`,t=>{let n=parseInt(t.target.getAttribute(`data-history-idx`)||`0`),r=w[n];if(r){e.state.currentInputStr=r.value;let t=e.getElement(`#simulator-input`);t&&(t.value=r.value,T(t)),e.updateStatus(`Input restored from history`,`ready`);let n=e.getElement(`.data-subtab[data-subtab="edit"]`);n==null||n.click()}})})}}function O(e){let t=e.getElement(`#simulator-saves-list`);if(!t)return;let n=E();if(n.length===0){t.innerHTML=`<div class="simulator-empty">No saved states</div>`;return}t.innerHTML=[...n].reverse().map((e,t)=>{let r=n.length-1-t,i=new Date(e.timestamp).toLocaleDateString(),a=new Date(e.timestamp).toLocaleTimeString();return`
89
89
  <div class="save-item">
90
90
  <div class="save-item-header">
91
- <span class="save-item-name">${A(e.name)}</span>
91
+ <span class="save-item-name">${k(e.name)}</span>
92
92
  <span class="save-item-time">${i} ${a}</span>
93
93
  </div>
94
94
  <div class="save-item-actions">
@@ -96,7 +96,7 @@ const e=require(`./asyncToGenerator-BlxRHn40.cjs`),t=require(`./objectSpread2-B6
96
96
  <button class="simulator-btn tiny danger save-delete-btn" data-save-idx="${r}">Delete</button>
97
97
  </div>
98
98
  </div>
99
- `}).join(``),t.querySelectorAll(`.save-load-btn`).forEach(t=>{t.addEventListener(`click`,t=>{let r=n[parseInt(t.target.getAttribute(`data-save-idx`)||`0`)];if(r){try{e.state.puzzleData=JSON.parse(r.puzzleStr),e.state.originalPuzzle=r.puzzleStr}catch(t){e.state.originalPuzzle=r.puzzleStr}e.state.currentInputStr=r.inputStr;let t=e.getElement(`#simulator-puzzle`),n=e.getElement(`#simulator-input`);t&&(t.value=r.puzzleStr,E(t)),n&&(n.value=r.inputStr,E(n)),e.updateStatus(`Loaded: ${r.name}`,`ready`);let i=e.getElement(`.data-subtab[data-subtab="edit"]`);i==null||i.click()}})}),t.querySelectorAll(`.save-delete-btn`).forEach(t=>{t.addEventListener(`click`,t=>{let r=parseInt(t.target.getAttribute(`data-save-idx`)||`0`),i=n.filter((e,t)=>t!==r);localStorage.setItem(S,JSON.stringify(i)),k(e)})})}function A(e){return e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`)}function j(e){let t=e.getElement(`#simulator-puzzle`),n=e.getElement(`#simulator-input`),r=e.getElement(`#simulator-puzzle-apply`),i=e.getElement(`#simulator-input-apply`);t&&e.state.originalPuzzle&&(t.value=e.state.originalPuzzle,E(t),r&&(r.disabled=!0)),n&&(n.value=e.state.currentInputStr,E(n),i&&(i.disabled=!0))}function M(e){return e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`)}function ae(){let e=0;return{id:`msgs`,label:`Msgs`,render(){return`
99
+ `}).join(``),t.querySelectorAll(`.save-load-btn`).forEach(t=>{t.addEventListener(`click`,t=>{let r=n[parseInt(t.target.getAttribute(`data-save-idx`)||`0`)];if(r){try{e.state.puzzleData=JSON.parse(r.puzzleStr),e.state.originalPuzzle=r.puzzleStr}catch(t){e.state.originalPuzzle=r.puzzleStr}e.state.currentInputStr=r.inputStr;let t=e.getElement(`#simulator-puzzle`),n=e.getElement(`#simulator-input`);t&&(t.value=r.puzzleStr,T(t)),n&&(n.value=r.inputStr,T(n)),e.updateStatus(`Loaded: ${r.name}`,`ready`);let i=e.getElement(`.data-subtab[data-subtab="edit"]`);i==null||i.click()}})}),t.querySelectorAll(`.save-delete-btn`).forEach(t=>{t.addEventListener(`click`,t=>{let r=parseInt(t.target.getAttribute(`data-save-idx`)||`0`),i=n.filter((e,t)=>t!==r);localStorage.setItem(x,JSON.stringify(i)),O(e)})})}function k(e){return e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`)}function A(e){let t=e.getElement(`#simulator-puzzle`),n=e.getElement(`#simulator-input`),r=e.getElement(`#simulator-puzzle-apply`),i=e.getElement(`#simulator-input-apply`);t&&e.state.originalPuzzle&&(t.value=e.state.originalPuzzle,T(t),r&&(r.disabled=!0)),n&&(n.value=e.state.currentInputStr,T(n),i&&(i.disabled=!0))}function j(e){return e.replace(/&/g,`&amp;`).replace(/</g,`&lt;`).replace(/>/g,`&gt;`).replace(/"/g,`&quot;`)}function ae(){let e=0;return{id:`msgs`,label:`Msgs`,render(){return`
100
100
  <div class="msgs-view-container">
101
101
  <div class="msgs-header">
102
102
  <span class="simulator-label">Message Log</span>
@@ -109,7 +109,7 @@ const e=require(`./asyncToGenerator-BlxRHn40.cjs`),t=require(`./objectSpread2-B6
109
109
  <span class="simulator-msg-type">${t.direction===`out`?`→`:`←`} ${t.type}</span>
110
110
  <span class="simulator-msg-time">${t.time}</span>
111
111
  </div>
112
- ${a?`<div class="simulator-msg-data">${M(a)}</div>`:``}
112
+ ${a?`<div class="simulator-msg-data">${j(a)}</div>`:``}
113
113
  `;let o=i.querySelector(`.simulator-msg-data`);for(o&&o.addEventListener(`click`,()=>{r.querySelectorAll(`.simulator-msg.expanded`).forEach(e=>{e!==i&&e.classList.remove(`expanded`)}),i.classList.toggle(`expanded`)}),r.insertBefore(i,r.firstChild);r.children.length>50;)r.removeChild(r.lastChild)}}}function oe(){return{id:`done`,label:`Done`,render(){return`
114
114
  <div id="simulator-done-empty" class="simulator-empty">Game not completed yet</div>
115
115
  <div id="simulator-done-content" style="display:none;">
@@ -156,7 +156,7 @@ const e=require(`./asyncToGenerator-BlxRHn40.cjs`),t=require(`./objectSpread2-B6
156
156
  ${r()}
157
157
  </div>
158
158
  </div>
159
- `},bind(t){let n=t.getElement(`#simulator-checkpoints-clear`),i=t.getElement(`#simulator-checkpoints-list`);n==null||n.addEventListener(`click`,()=>{e=[],i&&(i.innerHTML=r()),t.updateBadge(`checkpoints`,0)})},onMessage(n,i,a){if(n!==`HIT_CHECKPOINT`)return;let o={checkpointName:i.checkpointName,augConfig:i.augConfig,time:t()};e.push(o),a.updateBadge(`checkpoints`,e.length);let s=a.getElement(`#simulator-checkpoints-list`);s&&(s.innerHTML=r(),s.scrollTop=s.scrollHeight)}}}function N(){let e=globalThis;for(let t of Object.keys(e))if(t.endsWith(`Thumbnail`)&&typeof e[t]==`function`)return{name:t,fn:e[t]};return null}function ce(){return{id:`thumb`,label:`Thumb`,render(){return`
159
+ `},bind(t){let n=t.getElement(`#simulator-checkpoints-clear`),i=t.getElement(`#simulator-checkpoints-list`);n==null||n.addEventListener(`click`,()=>{e=[],i&&(i.innerHTML=r()),t.updateBadge(`checkpoints`,0)})},onMessage(n,i,a){if(n!==`HIT_CHECKPOINT`)return;let o={checkpointName:i.checkpointName,augConfig:i.augConfig,time:t()};e.push(o),a.updateBadge(`checkpoints`,e.length);let s=a.getElement(`#simulator-checkpoints-list`);s&&(s.innerHTML=r(),s.scrollTop=s.scrollHeight)}}}function M(){let e=globalThis;for(let t of Object.keys(e))if(t.endsWith(`Thumbnail`)&&typeof e[t]==`function`)return{name:t,fn:e[t]};return null}function ce(){return{id:`thumb`,label:`Thumb`,render(){return`
160
160
  <div class="thumb-view-container">
161
161
  <div class="thumb-header">
162
162
  <span class="simulator-label">Thumbnail Preview</span>
@@ -185,18 +185,18 @@ const e=require(`./asyncToGenerator-BlxRHn40.cjs`),t=require(`./objectSpread2-B6
185
185
  </select>
186
186
  </div>
187
187
  </div>
188
- `},bind(e){let t=e.getElement(`#simulator-thumb-refresh`);t==null||t.addEventListener(`click`,()=>e.updateThumbnail());let n=e.getElement(`#simulator-render-host-select`),r=e.getElement(`#simulator-render-context-select`),i=e.getElement(`#simulator-render-context-field`),a=()=>{i&&(i.style.display=e.state.renderHost===`opengraph`?`block`:`none`)};n&&(e.state.renderHost||(e.state.renderHost=`game`,g(e.state.renderHost)),n.value=e.state.renderHost||`game`,n.addEventListener(`change`,()=>{e.state.renderHost=n.value,g(e.state.renderHost),a(),e.updateThumbnail()})),r&&(e.state.renderContext||(e.state.renderContext=`preview`,_(e.state.renderContext)),r.value=e.state.renderContext||`preview`,r.addEventListener(`change`,()=>{e.state.renderContext=r.value,_(e.state.renderContext),e.updateThumbnail()})),a()},onActivate(e){setTimeout(()=>e.updateThumbnail(),0)},updatePreview:e=>{let t=e.getElement(`#simulator-thumb-preview`),n=e.getElement(`#simulator-thumb-fn`);t==null||t.style.setProperty(`--sim-thumb-bg`,e.state.selectedTheme.g_bg);let r=N();if(!r){t&&(t.innerHTML=`<span class="simulator-empty">No thumbnail function found</span>`),n&&(n.textContent=``);return}n&&(n.textContent=`Using: ${r.name}()`);try{let n=e.state.puzzleData?JSON.stringify(e.state.puzzleData):``,i={viewerIsOwner:!0,theme:e.state.selectedTheme,strict:!0,renderHost:e.state.renderHost,renderContext:e.state.renderContext},a=r.fn(n,e.state.currentInputStr,i);t&&(t.innerHTML=a)}catch(e){console.error(`Simulator: Thumbnail error`,e),t&&(t.innerHTML=`<span class="simulator-empty">Error: ${e}</span>`)}}}}function P(e){let t=[e.key,e.subBrand,e.player,e.alt1,e.alt2,e.alt3].map(e=>`<div class="simulator-theme-preview-cell" style="background: ${e}"></div>`).join(``);return`<div class="simulator-theme-preview" style="background: ${e.g_bg}">${t}</div>`}function le(){return{id:`theme`,label:`Theme`,render(){return`
188
+ `},bind(e){let t=e.getElement(`#simulator-thumb-refresh`);t==null||t.addEventListener(`click`,()=>e.updateThumbnail());let n=e.getElement(`#simulator-render-host-select`),r=e.getElement(`#simulator-render-context-select`),i=e.getElement(`#simulator-render-context-field`),a=()=>{i&&(i.style.display=e.state.renderHost===`opengraph`?`block`:`none`)};n&&(e.state.renderHost||(e.state.renderHost=`game`,h(e.state.renderHost)),n.value=e.state.renderHost||`game`,n.addEventListener(`change`,()=>{e.state.renderHost=n.value,h(e.state.renderHost),a(),e.updateThumbnail()})),r&&(e.state.renderContext||(e.state.renderContext=`preview`,g(e.state.renderContext)),r.value=e.state.renderContext||`preview`,r.addEventListener(`change`,()=>{e.state.renderContext=r.value,g(e.state.renderContext),e.updateThumbnail()})),a()},onActivate(e){setTimeout(()=>e.updateThumbnail(),0)},updatePreview:e=>{let t=e.getElement(`#simulator-thumb-preview`),n=e.getElement(`#simulator-thumb-fn`);t==null||t.style.setProperty(`--sim-thumb-bg`,e.state.selectedTheme.g_bg);let r=M();if(!r){t&&(t.innerHTML=`<span class="simulator-empty">No thumbnail function found</span>`),n&&(n.textContent=``);return}n&&(n.textContent=`Using: ${r.name}()`);try{let n=e.state.puzzleData?JSON.stringify(e.state.puzzleData):``,i={viewerIsOwner:!0,theme:e.state.selectedTheme,strict:!0,renderHost:e.state.renderHost,renderContext:e.state.renderContext},a=r.fn(n,e.state.currentInputStr,i);t&&(t.innerHTML=a)}catch(e){console.error(`Simulator: Thumbnail error`,e),t&&(t.innerHTML=`<span class="simulator-empty">Error: ${e}</span>`)}}}}function N(e){let t=[e.key,e.subBrand,e.player,e.alt1,e.alt2,e.alt3].map(e=>`<div class="simulator-theme-preview-cell" style="background: ${e}"></div>`).join(``);return`<div class="simulator-theme-preview" style="background: ${e.g_bg}">${t}</div>`}function le(){return{id:`theme`,label:`Theme`,render(){return`
189
189
  <div class="theme-view-container">
190
190
  <div class="theme-header">
191
191
  <span class="simulator-label">Select Theme</span>
192
192
  </div>
193
193
  <div id="simulator-themes" class="simulator-themes"></div>
194
194
  </div>
195
- `},bind(e){let t=e.getElement(`#simulator-themes`);t&&n.forEach(n=>{let r=document.createElement(`div`);r.className=`simulator-theme-item${n.name===e.state.selectedTheme.name?` selected`:``}`,r.innerHTML=`
196
- ${P(n)}
197
- <div class="simulator-theme-name">${n.name}</div>
198
- <div class="simulator-theme-type">${n.type}</div>
199
- `,r.addEventListener(`click`,()=>{console.log(`Simulator: Theme changed, reloading...`,n.name),f(n.name),window.location.reload()}),t.appendChild(r)})}}}var F=`puzzmo_sim_api_mode`,I=`http://localhost:8911`,L=`https://api.puzzmo.com`,R=()=>localStorage.getItem(F)===`dev`?`dev`:`prod`,z=e=>{localStorage.setItem(F,e)},B=null,V=function(){var t=e.t(function*(){if(B!==null)return B;try{let e=new AbortController,t=setTimeout(()=>e.abort(),1e3),n=yield fetch(`${I}/healthz`,{signal:e.signal});return clearTimeout(t),B=n.ok,B}catch(e){return B=!1,!1}});return function(){return t.apply(this,arguments)}}(),H=()=>({apiURL:R()===`dev`?I:L,clientID:`protosdk:oauthclient`,redirectUri:`${window.location.origin}/oauth/callback`}),U=()=>{let e=new Uint8Array(32);return crypto.getRandomValues(e),Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``)},W=`puzzmo_sim_oauth_token`,G=`puzzmo_sim_oauth_refresh_token`,K=e=>localStorage.setItem(W,e),ue=e=>localStorage.setItem(G,e),q=()=>{let e=localStorage.getItem(W);return console.log(`[AuthView] getAccessToken:`,{TOKEN_KEY:W,token:e?`${e.substring(0,20)}...`:null}),e},J=()=>localStorage.getItem(G),Y=()=>{localStorage.removeItem(W),localStorage.removeItem(G)},de=()=>{let e=H(),t=U();sessionStorage.setItem(`oauth_state`,t),sessionStorage.setItem(`oauth_return_url`,window.location.href);let n=new URL(`${e.apiURL}/oauth/auth`);n.searchParams.set(`client_id`,e.clientID),n.searchParams.set(`response_type`,`code`),n.searchParams.set(`redirect_uri`,e.redirectUri),n.searchParams.set(`state`,t),window.location.href=n.toString()},fe=e=>{try{let t=e.split(`.`);if(t.length!==3)return!0;let n=JSON.parse(atob(t[1])).exp;return n?Date.now()>=n*1e3-300*1e3:!0}catch(e){return!0}},pe=function(){var t=e.t(function*(){let e=J();if(!e)return console.log(`[AuthView] No refresh token available`),!1;let t=H();try{let n=new URLSearchParams({grant_type:`refresh_token`,refresh_token:e,client_id:t.clientID}),r=yield fetch(`${t.apiURL}/oauth/token`,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`},body:n.toString()});if(!r.ok)return console.error(`[AuthView] Failed to refresh token:`,r.statusText),!1;let i=yield r.json(),a=i.access_token||i.accessToken;if(!a)return console.error(`[AuthView] No access token in refresh response`),!1;K(a);let o=i.refresh_token||i.refreshToken;return o&&ue(o),console.log(`[AuthView] Successfully refreshed access token`),!0}catch(e){return console.error(`[AuthView] Error refreshing token:`,e),!1}});return function(){return t.apply(this,arguments)}}(),me=function(){var t=e.t(function*(e,t){let n=H(),r=sessionStorage.getItem(`oauth_state`);if(!r||r!==t)return console.error(`OAuth state mismatch - possible CSRF attack`),null;sessionStorage.removeItem(`oauth_state`);try{let t=new URLSearchParams({grant_type:`authorization_code`,code:e,client_id:n.clientID,redirect_uri:n.redirectUri}),r=yield fetch(`${n.apiURL}/oauth/token`,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`},body:t.toString()});return r.ok?yield r.json():(console.error(`Failed to exchange code for token:`,r.statusText),null)}catch(e){return console.error(`Error exchanging code for token:`,e),null}});return function(e,n){return t.apply(this,arguments)}}(),he=function(){var t=e.t(function*(e,t={}){let n=H(),r=q();if(!r)throw Error(`Not authenticated`);if(fe(r))if(console.log(`[AuthView] Access token expired, attempting refresh...`),yield pe()){if(r=q(),!r)throw Error(`Token refresh succeeded but no token available`)}else throw Y(),Error(`Session expired. Please log in again.`);let i=yield fetch(`${n.apiURL}/graphql`,{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${r}`,"auth-provider":`custom`},body:JSON.stringify({query:e,variables:t})});if(!i.ok)throw Error(`API request failed: ${i.statusText}`);return i.json()});return function(e){return t.apply(this,arguments)}}(),ge=e=>{try{console.log(`[AuthView] decodeJWT input:`,e);let t=e.split(`.`);if(console.log(`[AuthView] JWT parts:`,t.length),t.length!==3)return null;let n=JSON.parse(atob(t[1]));return console.log(`[AuthView] JWT payload:`,n),n}catch(e){return console.error(`[AuthView] decodeJWT error:`,e),null}};function _e(){let t=!1;return{id:`auth`,label:`Auth`,render(){let e=q(),t=!!e,n=R(),r=n===`dev`?I:L,i=`<button class="simulator-btn tiny" id="auth-dev-toggle" style="display: none;">${n===`dev`?`Using Dev`:`Dev`}</button>`;if(t){let t=ge(e),n=t!=null&&t.exp?new Date(t.exp*1e3).toLocaleString():`Unknown`,a=!!J(),o=a?ge(J()):null,s=o!=null&&o.exp?new Date(o.exp*1e3).toLocaleString():null;return console.log({decoded:t}),`
195
+ `},bind(e){let n=e.getElement(`#simulator-themes`);n&&t.forEach(t=>{let r=document.createElement(`div`);r.className=`simulator-theme-item${t.name===e.state.selectedTheme.name?` selected`:``}`,r.innerHTML=`
196
+ ${N(t)}
197
+ <div class="simulator-theme-name">${t.name}</div>
198
+ <div class="simulator-theme-type">${t.type}</div>
199
+ `,r.addEventListener(`click`,()=>{console.log(`Simulator: Theme changed, reloading...`,t.name),d(t.name),window.location.reload()}),n.appendChild(r)})}}}var P=`puzzmo_sim_api_mode`,F=`http://localhost:8911`,I=`https://api.puzzmo.com`,L=()=>localStorage.getItem(P)===`dev`?`dev`:`prod`,R=e=>{localStorage.setItem(P,e)},z=null,B=function(){var t=e.n(function*(){if(z!==null)return z;try{let e=new AbortController,t=setTimeout(()=>e.abort(),1e3),n=yield fetch(`${F}/healthz`,{signal:e.signal});return clearTimeout(t),z=n.ok,z}catch(e){return z=!1,!1}});return function(){return t.apply(this,arguments)}}(),V=()=>({apiURL:L()===`dev`?F:I,clientID:`protosdk:oauthclient`,redirectUri:`${window.location.origin}/oauth/callback`}),H=()=>{let e=new Uint8Array(32);return crypto.getRandomValues(e),Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``)},U=`puzzmo_sim_oauth_token`,W=`puzzmo_sim_oauth_refresh_token`,G=e=>localStorage.setItem(U,e),K=e=>localStorage.setItem(W,e),q=()=>{let e=localStorage.getItem(U);return console.log(`[AuthView] getAccessToken:`,{TOKEN_KEY:U,token:e?`${e.substring(0,20)}...`:null}),e},J=()=>localStorage.getItem(W),Y=()=>{localStorage.removeItem(U),localStorage.removeItem(W)},ue=()=>{let e=V(),t=H();sessionStorage.setItem(`oauth_state`,t),sessionStorage.setItem(`oauth_return_url`,window.location.href);let n=new URL(`${e.apiURL}/oauth/auth`);n.searchParams.set(`client_id`,e.clientID),n.searchParams.set(`response_type`,`code`),n.searchParams.set(`redirect_uri`,e.redirectUri),n.searchParams.set(`state`,t),window.location.href=n.toString()},de=e=>{try{let t=e.split(`.`);if(t.length!==3)return!0;let n=JSON.parse(atob(t[1])).exp;return n?Date.now()>=n*1e3-300*1e3:!0}catch(e){return!0}},fe=function(){var t=e.n(function*(){let e=J();if(!e)return console.log(`[AuthView] No refresh token available`),!1;let t=V();try{let n=new URLSearchParams({grant_type:`refresh_token`,refresh_token:e,client_id:t.clientID}),r=yield fetch(`${t.apiURL}/oauth/token`,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`},body:n.toString()});if(!r.ok)return console.error(`[AuthView] Failed to refresh token:`,r.statusText),!1;let i=yield r.json(),a=i.access_token||i.accessToken;if(!a)return console.error(`[AuthView] No access token in refresh response`),!1;G(a);let o=i.refresh_token||i.refreshToken;return o&&K(o),console.log(`[AuthView] Successfully refreshed access token`),!0}catch(e){return console.error(`[AuthView] Error refreshing token:`,e),!1}});return function(){return t.apply(this,arguments)}}(),pe=function(){var t=e.n(function*(e,t){let n=V(),r=sessionStorage.getItem(`oauth_state`);if(!r||r!==t)return console.error(`OAuth state mismatch - possible CSRF attack`),null;sessionStorage.removeItem(`oauth_state`);try{let t=new URLSearchParams({grant_type:`authorization_code`,code:e,client_id:n.clientID,redirect_uri:n.redirectUri}),r=yield fetch(`${n.apiURL}/oauth/token`,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`},body:t.toString()});return r.ok?yield r.json():(console.error(`Failed to exchange code for token:`,r.statusText),null)}catch(e){return console.error(`Error exchanging code for token:`,e),null}});return function(e,n){return t.apply(this,arguments)}}(),me=function(){var t=e.n(function*(e,t={}){let n=V(),r=q();if(!r)throw Error(`Not authenticated`);if(de(r))if(console.log(`[AuthView] Access token expired, attempting refresh...`),yield fe()){if(r=q(),!r)throw Error(`Token refresh succeeded but no token available`)}else throw Y(),Error(`Session expired. Please log in again.`);let i=yield fetch(`${n.apiURL}/graphql`,{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${r}`,"auth-provider":`custom`},body:JSON.stringify({query:e,variables:t})});if(!i.ok)throw Error(`API request failed: ${i.statusText}`);return i.json()});return function(e){return t.apply(this,arguments)}}(),he=e=>{try{console.log(`[AuthView] decodeJWT input:`,e);let t=e.split(`.`);if(console.log(`[AuthView] JWT parts:`,t.length),t.length!==3)return null;let n=JSON.parse(atob(t[1]));return console.log(`[AuthView] JWT payload:`,n),n}catch(e){return console.error(`[AuthView] decodeJWT error:`,e),null}};function ge(){let t=!1;return{id:`auth`,label:`Auth`,render(){let e=q(),t=!!e,n=L(),r=n===`dev`?F:I,i=`<button class="simulator-btn tiny" id="auth-dev-toggle" style="display: none;">${n===`dev`?`Using Dev`:`Dev`}</button>`;if(t){let t=he(e),n=t!=null&&t.exp?new Date(t.exp*1e3).toLocaleString():`Unknown`,a=!!J(),o=a?he(J()):null,s=o!=null&&o.exp?new Date(o.exp*1e3).toLocaleString():null;return console.log({decoded:t}),`
200
200
  <div class="simulator-section">
201
201
  <div class="simulator-section-title auth-title-row">
202
202
  <span>Puzzmo Authentication</span>
@@ -234,14 +234,14 @@ const e=require(`./asyncToGenerator-BlxRHn40.cjs`),t=require(`./objectSpread2-B6
234
234
  </div>
235
235
  <p class="auth-description">
236
236
  Login with your Puzzmo account to make authenticated API requests.
237
- ${n===`dev`?`<br><strong>Using local dev server:</strong> ${I}`:``}
237
+ ${n===`dev`?`<br><strong>Using local dev server:</strong> ${F}`:``}
238
238
  </p>
239
239
  <div class="simulator-row">
240
240
  <button class="simulator-btn primary" id="auth-login">Login with Puzzmo</button>
241
241
  </div>
242
242
  <div id="auth-error" class="auth-error"></div>
243
243
  </div>
244
- `},bind(n){let r=n.getElement(`#auth-login`),i=n.getElement(`#auth-logout`),a=n.getElement(`#auth-refresh`),o=n.getElement(`#auth-test-api`),s=n.getElement(`#auth-api-result`),c=n.getElement(`#auth-dev-toggle`);t?B&&c&&(c.style.display=``,R()===`dev`&&c.classList.add(`active`)):(t=!0,V().then(e=>{e&&c&&(c.style.display=``,R()===`dev`&&c.classList.add(`active`))})),c==null||c.addEventListener(`click`,()=>{z(R()===`dev`?`prod`:`dev`),Y(),window.location.reload()}),r==null||r.addEventListener(`click`,()=>{de()}),i==null||i.addEventListener(`click`,()=>{Y(),window.location.reload()}),a==null||a.addEventListener(`click`,e.t(function*(){a.disabled=!0,a.textContent=`Refreshing...`,(yield pe())?window.location.reload():(a.textContent=`Refresh Failed`,a.disabled=!1)})),o==null||o.addEventListener(`click`,e.t(function*(){if(s){s.innerHTML=`<div class="loading">Loading...</div>`;try{let t=yield he(`
244
+ `},bind(n){let r=n.getElement(`#auth-login`),i=n.getElement(`#auth-logout`),a=n.getElement(`#auth-refresh`),o=n.getElement(`#auth-test-api`),s=n.getElement(`#auth-api-result`),c=n.getElement(`#auth-dev-toggle`);t?z&&c&&(c.style.display=``,L()===`dev`&&c.classList.add(`active`)):(t=!0,B().then(e=>{e&&c&&(c.style.display=``,L()===`dev`&&c.classList.add(`active`))})),c==null||c.addEventListener(`click`,()=>{R(L()===`dev`?`prod`:`dev`),Y(),window.location.reload()}),r==null||r.addEventListener(`click`,()=>{ue()}),i==null||i.addEventListener(`click`,()=>{Y(),window.location.reload()}),a==null||a.addEventListener(`click`,e.n(function*(){a.disabled=!0,a.textContent=`Refreshing...`,(yield fe())?window.location.reload():(a.textContent=`Refresh Failed`,a.disabled=!1)})),o==null||o.addEventListener(`click`,e.n(function*(){if(s){s.innerHTML=`<div class="loading">Loading...</div>`;try{let t=yield me(`
245
245
  query {
246
246
  currentUser {
247
247
  id
@@ -250,7 +250,7 @@ const e=require(`./asyncToGenerator-BlxRHn40.cjs`),t=require(`./objectSpread2-B6
250
250
  name
251
251
  }
252
252
  }
253
- `);if(t.errors){var e;s.innerHTML=`<div class="error">Error: ${((e=t.errors[0])==null?void 0:e.message)||`Unknown error`}</div>`}else s.innerHTML=`<pre>${JSON.stringify(t.data,null,2)}</pre>`}catch(e){s.innerHTML=`<div class="error">Error: ${e instanceof Error?e.message:`Unknown error`}</div>`}}}))},onActivate(t){return e.t(function*(){let e=new URLSearchParams(window.location.search),n=e.get(`code`),r=e.get(`state`),i=e.get(`error`);if(i){let e=t.getElement(`#auth-error`);e&&(e.innerHTML=`<div class="error">OAuth error: ${i}</div>`),window.history.replaceState({},``,window.location.pathname);return}if(n&&r){let e=t.getElement(`#auth-status`);e&&(e.innerHTML=`<span class="indicator waiting"></span><span>Exchanging code...</span>`);let i=yield me(n,r);if(window.history.replaceState({},``,window.location.pathname),i){let e=i.access_token||i.accessToken;if(e){K(e);let t=i.refresh_token||i.refreshToken;t&&ue(t)}window.location.reload()}else{let e=t.getElement(`#auth-error`);e&&(e.innerHTML=`<div class="error">Failed to exchange code for token</div>`)}}})()}}}var ve=`puzzmo_sim_api_mode`,ye=`http://localhost:8911`,be=`https://api.puzzmo.com`,X=`puzzmo_sim_oauth_token`,Z=`puzzmo_sim_oauth_refresh_token`,xe=()=>localStorage.getItem(ve)===`dev`?`dev`:`prod`,Q=()=>localStorage.getItem(X),Se=()=>localStorage.getItem(Z),Ce=e=>localStorage.setItem(X,e),we=e=>localStorage.setItem(Z,e),Te=()=>{localStorage.removeItem(X),localStorage.removeItem(Z)},Ee=e=>{try{let t=e.split(`.`);if(t.length!==3)return!0;let n=JSON.parse(atob(t[1])).exp;return n?Date.now()>=n*1e3-300*1e3:!0}catch(e){return!0}},De=function(){var t=e.t(function*(){let e=Se();if(!e)return!1;let t=xe()===`dev`?ye:be;try{let n=new URLSearchParams({grant_type:`refresh_token`,refresh_token:e,client_id:`protosdk:oauthclient`}),r=yield fetch(`${t}/oauth/token`,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`},body:n.toString()});if(!r.ok)return!1;let i=yield r.json(),a=i.access_token||i.accessToken;if(!a)return!1;Ce(a);let o=i.refresh_token||i.refreshToken;return o&&we(o),!0}catch(e){return!1}});return function(){return t.apply(this,arguments)}}(),Oe=function(){var t=e.t(function*(e,t={}){let n=xe()===`dev`?ye:be,r=Q();if(!r)throw Error(`Not authenticated`);if(Ee(r))if(yield De()){if(r=Q(),!r)throw Error(`Token refresh succeeded but no token available`)}else throw Te(),Error(`Session expired. Please log in again.`);let i=yield fetch(`${n}/graphql`,{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${r}`,"auth-provider":`custom`},body:JSON.stringify({query:e,variables:t})});if(!i.ok)throw Error(`API request failed: ${i.statusText}`);return i.json()});return function(e){return t.apply(this,arguments)}}(),ke=`
253
+ `);if(t.errors){var e;s.innerHTML=`<div class="error">Error: ${((e=t.errors[0])==null?void 0:e.message)||`Unknown error`}</div>`}else s.innerHTML=`<pre>${JSON.stringify(t.data,null,2)}</pre>`}catch(e){s.innerHTML=`<div class="error">Error: ${e instanceof Error?e.message:`Unknown error`}</div>`}}}))},onActivate(t){return e.n(function*(){let e=new URLSearchParams(window.location.search),n=e.get(`code`),r=e.get(`state`),i=e.get(`error`);if(i){let e=t.getElement(`#auth-error`);e&&(e.innerHTML=`<div class="error">OAuth error: ${i}</div>`),window.history.replaceState({},``,window.location.pathname);return}if(n&&r){let e=t.getElement(`#auth-status`);e&&(e.innerHTML=`<span class="indicator waiting"></span><span>Exchanging code...</span>`);let i=yield pe(n,r);if(window.history.replaceState({},``,window.location.pathname),i){let e=i.access_token||i.accessToken;if(e){G(e);let t=i.refresh_token||i.refreshToken;t&&K(t)}window.location.reload()}else{let e=t.getElement(`#auth-error`);e&&(e.innerHTML=`<div class="error">Failed to exchange code for token</div>`)}}})()}}}var _e=`puzzmo_sim_api_mode`,ve=`http://localhost:8911`,ye=`https://api.puzzmo.com`,X=`puzzmo_sim_oauth_token`,Z=`puzzmo_sim_oauth_refresh_token`,be=()=>localStorage.getItem(_e)===`dev`?`dev`:`prod`,Q=()=>localStorage.getItem(X),xe=()=>localStorage.getItem(Z),Se=e=>localStorage.setItem(X,e),Ce=e=>localStorage.setItem(Z,e),we=()=>{localStorage.removeItem(X),localStorage.removeItem(Z)},Te=e=>{try{let t=e.split(`.`);if(t.length!==3)return!0;let n=JSON.parse(atob(t[1])).exp;return n?Date.now()>=n*1e3-300*1e3:!0}catch(e){return!0}},Ee=function(){var t=e.n(function*(){let e=xe();if(!e)return!1;let t=be()===`dev`?ve:ye;try{let n=new URLSearchParams({grant_type:`refresh_token`,refresh_token:e,client_id:`protosdk:oauthclient`}),r=yield fetch(`${t}/oauth/token`,{method:`POST`,headers:{"Content-Type":`application/x-www-form-urlencoded`},body:n.toString()});if(!r.ok)return!1;let i=yield r.json(),a=i.access_token||i.accessToken;if(!a)return!1;Se(a);let o=i.refresh_token||i.refreshToken;return o&&Ce(o),!0}catch(e){return!1}});return function(){return t.apply(this,arguments)}}(),De=function(){var t=e.n(function*(e,t={}){let n=be()===`dev`?ve:ye,r=Q();if(!r)throw Error(`Not authenticated`);if(Te(r))if(yield Ee()){if(r=Q(),!r)throw Error(`Token refresh succeeded but no token available`)}else throw we(),Error(`Session expired. Please log in again.`);let i=yield fetch(`${n}/graphql`,{method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${r}`,"auth-provider":`custom`},body:JSON.stringify({query:e,variables:t})});if(!i.ok)throw Error(`API request failed: ${i.statusText}`);return i.json()});return function(e){return t.apply(this,arguments)}}(),Oe=`
254
254
  query GameFeaturesQuery($slug: ID!) {
255
255
  game(id: $slug) {
256
256
  id
@@ -268,7 +268,7 @@ const e=require(`./asyncToGenerator-BlxRHn40.cjs`),t=require(`./objectSpread2-B6
268
268
  }
269
269
  }
270
270
  }
271
- `,Ae=`
271
+ `,ke=`
272
272
  mutation ToggleFeatureMutation($gameSlug: ID!, $input: UpdateGameInput!) {
273
273
  updateGame(id: $gameSlug, input: $input) {
274
274
  id
@@ -284,7 +284,7 @@ const e=require(`./asyncToGenerator-BlxRHn40.cjs`),t=require(`./objectSpread2-B6
284
284
  }
285
285
  }
286
286
  }
287
- `,je=(e,t)=>{let n=t-1,r=Math.floor(n/31),i=n%31,a=[...e];for(;a.length<=r;)a.push(0);return a[r]=a[r]^1<<i,a};const Me=()=>!!Q();function Ne(){let n=null,r=!1,i=null,a=function(){var t=e.t(function*(e){r=!0,i=null;try{var t;let r=yield Oe(ke,{slug:e});if(r.errors){var a;i=((a=r.errors[0])==null?void 0:a.message)||`Unknown error`,n=null}else (t=r.data)!=null&&t.game?n=r.data.game:(i=`Game not found`,n=null)}catch(e){i=e instanceof Error?e.message:`Unknown error`,n=null}finally{r=!1}});return function(e){return t.apply(this,arguments)}}(),o=function(){var r=e.t(function*(e){if(!n)return;let r=je(n.featuresArr,e);try{var i;let e=yield Oe(Ae,{gameSlug:n.slug,input:{featuresArr:r}});if(e.errors){var a;console.error(`Failed to toggle feature:`,(a=e.errors[0])==null?void 0:a.message)}else (i=e.data)!=null&&i.updateGame&&(n=t.t(t.t({},n),{},{featuresArr:e.data.updateGame.featuresArr,gameFeatures:e.data.updateGame.gameFeatures}))}catch(e){console.error(`Failed to toggle feature:`,e)}});return function(e){return r.apply(this,arguments)}}(),s=()=>{if(r)return`<div class="features-loading">Loading features...</div>`;if(i)return`<div class="features-error">${i}</div>`;if(!n)return`<div class="features-empty">Enter your game slug above to load features</div>`;let e=n.gameFeatures.map(e=>{let t=e.features.map(e=>{let t=e.isEnabled?`enabled`:`disabled`,n=e.isEnabled?`✓`:`✗`;return`
287
+ `,Ae=(e,t)=>{let n=t-1,r=Math.floor(n/31),i=n%31,a=[...e];for(;a.length<=r;)a.push(0);return a[r]=a[r]^1<<i,a};const je=()=>!!Q();function Me(){let t=null,n=!1,r=null,i=function(){var i=e.n(function*(e){n=!0,r=null;try{var i;let n=yield De(Oe,{slug:e});if(n.errors){var a;r=((a=n.errors[0])==null?void 0:a.message)||`Unknown error`,t=null}else (i=n.data)!=null&&i.game?t=n.data.game:(r=`Game not found`,t=null)}catch(e){r=e instanceof Error?e.message:`Unknown error`,t=null}finally{n=!1}});return function(e){return i.apply(this,arguments)}}(),a=function(){var n=e.n(function*(n){if(!t)return;let r=Ae(t.featuresArr,n);try{var i;let n=yield De(ke,{gameSlug:t.slug,input:{featuresArr:r}});if(n.errors){var a;console.error(`Failed to toggle feature:`,(a=n.errors[0])==null?void 0:a.message)}else (i=n.data)!=null&&i.updateGame&&(t=e.t(e.t({},t),{},{featuresArr:n.data.updateGame.featuresArr,gameFeatures:n.data.updateGame.gameFeatures}))}catch(e){console.error(`Failed to toggle feature:`,e)}});return function(e){return n.apply(this,arguments)}}(),o=()=>{if(n)return`<div class="features-loading">Loading features...</div>`;if(r)return`<div class="features-error">${r}</div>`;if(!t)return`<div class="features-empty">Enter your game slug above to load features</div>`;let e=t.gameFeatures.map(e=>{let t=e.features.map(e=>{let t=e.isEnabled?`enabled`:`disabled`,n=e.isEnabled?`✓`:`✗`;return`
288
288
  <div class="feature-item ${t}" data-feature-id="${e.featureID}">
289
289
  <span class="feature-status">${n}</span>
290
290
  <span class="feature-title">${e.title}</span>
@@ -295,9 +295,9 @@ const e=require(`./asyncToGenerator-BlxRHn40.cjs`),t=require(`./objectSpread2-B6
295
295
  <div class="feature-group-items">${t}</div>
296
296
  </div>
297
297
  `}).join(``);return`
298
- <div class="features-game-name">${n.displayName}</div>
298
+ <div class="features-game-name">${t.displayName}</div>
299
299
  ${e}
300
- `};return{id:`features`,label:`Features`,render(){return Me()?`
300
+ `};return{id:`features`,label:`Features`,render(){return je()?`
301
301
  <div class="features-view-container">
302
302
  <div class="simulator-section">
303
303
  <div class="simulator-section-title">Game Features</div>
@@ -308,7 +308,7 @@ const e=require(`./asyncToGenerator-BlxRHn40.cjs`),t=require(`./objectSpread2-B6
308
308
  </div>
309
309
  <div class="simulator-divider"></div>
310
310
  <div id="features-content" class="features-content">
311
- ${s()}
311
+ ${o()}
312
312
  </div>
313
313
  </div>
314
314
  `:`
@@ -321,7 +321,7 @@ const e=require(`./asyncToGenerator-BlxRHn40.cjs`),t=require(`./objectSpread2-B6
321
321
  </div>
322
322
  </div>
323
323
  </div>
324
- `},bind(t){let r=t.getElement(`#features-load-btn`),i=t.getElement(`#features-game-slug`),c=t.getElement(`#features-content`),l=()=>{c&&(c.innerHTML=s(),u())},u=()=>{var n;let r=(n=t.getElement(`#features-content`))==null?void 0:n.querySelectorAll(`.feature-item`);r==null||r.forEach(t=>{t.addEventListener(`click`,e.t(function*(){let e=parseInt(t.getAttribute(`data-feature-id`)||`0`);e>0&&(t.classList.add(`updating`),yield o(e),l())}))})},d=function(){var t=e.t(function*(e){e&&(r&&(r.disabled=!0,r.textContent=`Loading...`),yield a(e),l(),r&&(r.disabled=!1,r.textContent=`Load`))});return function(e){return t.apply(this,arguments)}}();r==null||r.addEventListener(`click`,e.t(function*(){let e=i==null?void 0:i.value.trim();e&&(yield d(e))})),i==null||i.addEventListener(`keypress`,e=>{e.key===`Enter`&&(r==null||r.click())}),console.log(`[FeaturesView] bind called, ctx.gameSlug:`,t.gameSlug,`slugInput:`,i),t.gameSlug&&i&&(i.value=t.gameSlug,Me()&&!n&&d(t.gameSlug)),u()},onActivate(e){let t=e.getElement(`#simulator-tab-features`);t&&(t.innerHTML=this.render(),this.bind(e))}}}var $=null;function Pe(t={}){var n,r;if(console.log(`[Simulator] createSimulator called with config:`,{slug:t.slug,hasFixtures:!!t.fixtures}),$)return t.fixtures&&(console.log(`[Simulator] Instance already exists, updating fixtures`),$.updateFixtures(t.fixtures)),$;let i=(n=t.autoStart)==null?!0:n,a=t.fixtures?v(t.fixtures):null,o=a?Array.from(a.keys()).sort():[],s=ae(),c=ce(),f=[re(),ie(),s,oe(),se(),c,le(),_e(),Ne()],p=f.map(e=>e.id),m=l(t,o,p),h={pause:`<svg width="10" height="10" viewBox="0 0 10 10" fill="currentColor"><rect x="1" y="1" width="3" height="8"/><rect x="6" y="1" width="3" height="8"/></svg>`,play:`<svg width="10" height="10" viewBox="0 0 10 10" fill="currentColor"><polygon points="2,1 9,5 2,9"/></svg>`,retry:`<svg width="10" height="10" viewBox="0 0 10 10" fill="currentColor"><path d="M5 1C2.8 1 1 2.8 1 5s1.8 4 4 4c1.8 0 3.3-1.2 3.8-2.8H7.5c-.4.9-1.3 1.5-2.5 1.5-1.5 0-2.7-1.2-2.7-2.7S3.5 2.3 5 2.3c.7 0 1.4.3 1.9.8L5.5 4.5H9V1L7.6 2.4C6.9 1.5 5.9 1 5 1z"/></svg>`,cog:`<svg width="10" height="10" viewBox="0 0 10 10" fill="currentColor"><path d="M9.5 5.8l-.8-.5c0-.2.1-.5.1-.8s0-.5-.1-.8l.8-.5c.1-.1.2-.2.1-.4l-.8-1.4c-.1-.1-.2-.2-.4-.1l-1 .3c-.3-.3-.7-.5-1.1-.6L6.1.2C6.1.1 6 0 5.8 0H4.2c-.2 0-.3.1-.3.2l-.2 1c-.4.1-.7.3-1.1.6l-1-.3c-.2 0-.3 0-.4.1l-.8 1.4c-.1.2 0 .3.1.4l.8.5c0 .2-.1.5-.1.8s0 .5.1.8l-.8.5c-.1.1-.2.2-.1.4l.8 1.4c.1.1.2.2.4.1l1-.3c.3.3.7.5 1.1.6l.2 1c0 .1.1.2.3.2h1.6c.2 0 .3-.1.3-.2l.2-1c.4-.1.7-.3 1.1-.6l1 .3c.2 0 .3 0 .4-.1l.8-1.4c.1-.2 0-.3-.1-.4zM5 6.5c-.8 0-1.5-.7-1.5-1.5S4.2 3.5 5 3.5 6.5 4.2 6.5 5 5.8 6.5 5 6.5z"/></svg>`,minimize:`<svg width="10" height="10" viewBox="0 0 10 10" fill="currentColor"><rect x="1" y="4" width="8" height="2"/></svg>`,expand:`<svg width="8" height="8" viewBox="0 0 8 8" fill="currentColor"><polygon points="1,1 7,4 1,7"/></svg>`},g=document.createElement(`div`);g.id=`simulator`,g.innerHTML=`
324
+ `},bind(n){let r=n.getElement(`#features-load-btn`),s=n.getElement(`#features-game-slug`),c=n.getElement(`#features-content`),l=()=>{c&&(c.innerHTML=o(),u())},u=()=>{var t;let r=(t=n.getElement(`#features-content`))==null?void 0:t.querySelectorAll(`.feature-item`);r==null||r.forEach(t=>{t.addEventListener(`click`,e.n(function*(){let e=parseInt(t.getAttribute(`data-feature-id`)||`0`);e>0&&(t.classList.add(`updating`),yield a(e),l())}))})},d=function(){var t=e.n(function*(e){e&&(r&&(r.disabled=!0,r.textContent=`Loading...`),yield i(e),l(),r&&(r.disabled=!1,r.textContent=`Load`))});return function(e){return t.apply(this,arguments)}}();r==null||r.addEventListener(`click`,e.n(function*(){let e=s==null?void 0:s.value.trim();e&&(yield d(e))})),s==null||s.addEventListener(`keypress`,e=>{e.key===`Enter`&&(r==null||r.click())}),console.log(`[FeaturesView] bind called, ctx.gameSlug:`,n.gameSlug,`slugInput:`,s),n.gameSlug&&s&&(s.value=n.gameSlug,je()&&!t&&d(n.gameSlug)),u()},onActivate(e){let t=e.getElement(`#simulator-tab-features`);t&&(t.innerHTML=this.render(),this.bind(e))}}}var $=null;function Ne(t={}){var n,r;if(console.log(`[Simulator] createSimulator called with config:`,{slug:t.slug,hasFixtures:!!t.fixtures}),$)return t.fixtures&&(console.log(`[Simulator] Instance already exists, updating fixtures`),$.updateFixtures(t.fixtures)),$;let i=(n=t.autoStart)==null?!0:n,a=t.fixtures?_(t.fixtures):null,o=a?Array.from(a.keys()).sort():[],s=ae(),d=ce(),f=[re(),ie(),s,oe(),se(),d,le(),ge(),Me()],p=f.map(e=>e.id),m=c(t,o,p),h={pause:`<svg width="10" height="10" viewBox="0 0 10 10" fill="currentColor"><rect x="1" y="1" width="3" height="8"/><rect x="6" y="1" width="3" height="8"/></svg>`,play:`<svg width="10" height="10" viewBox="0 0 10 10" fill="currentColor"><polygon points="2,1 9,5 2,9"/></svg>`,retry:`<svg width="10" height="10" viewBox="0 0 10 10" fill="currentColor"><path d="M5 1C2.8 1 1 2.8 1 5s1.8 4 4 4c1.8 0 3.3-1.2 3.8-2.8H7.5c-.4.9-1.3 1.5-2.5 1.5-1.5 0-2.7-1.2-2.7-2.7S3.5 2.3 5 2.3c.7 0 1.4.3 1.9.8L5.5 4.5H9V1L7.6 2.4C6.9 1.5 5.9 1 5 1z"/></svg>`,cog:`<svg width="10" height="10" viewBox="0 0 10 10" fill="currentColor"><path d="M9.5 5.8l-.8-.5c0-.2.1-.5.1-.8s0-.5-.1-.8l.8-.5c.1-.1.2-.2.1-.4l-.8-1.4c-.1-.1-.2-.2-.4-.1l-1 .3c-.3-.3-.7-.5-1.1-.6L6.1.2C6.1.1 6 0 5.8 0H4.2c-.2 0-.3.1-.3.2l-.2 1c-.4.1-.7.3-1.1.6l-1-.3c-.2 0-.3 0-.4.1l-.8 1.4c-.1.2 0 .3.1.4l.8.5c0 .2-.1.5-.1.8s0 .5.1.8l-.8.5c-.1.1-.2.2-.1.4l.8 1.4c.1.1.2.2.4.1l1-.3c.3.3.7.5 1.1.6l.2 1c0 .1.1.2.3.2h1.6c.2 0 .3-.1.3-.2l.2-1c.4-.1.7-.3 1.1-.6l1 .3c.2 0 .3 0 .4-.1l.8-1.4c.1-.2 0-.3-.1-.4zM5 6.5c-.8 0-1.5-.7-1.5-1.5S4.2 3.5 5 3.5 6.5 4.2 6.5 5 5.8 6.5 5 6.5z"/></svg>`,minimize:`<svg width="10" height="10" viewBox="0 0 10 10" fill="currentColor"><rect x="1" y="4" width="8" height="2"/></svg>`,expand:`<svg width="8" height="8" viewBox="0 0 8 8" fill="currentColor"><polygon points="1,1 7,4 1,7"/></svg>`},g=document.createElement(`div`);g.id=`simulator`,g.innerHTML=`
325
325
  <style>
326
326
  :root {
327
327
  --sim-bg: #1a1a2e;
@@ -1424,5 +1424,5 @@ const e=require(`./asyncToGenerator-BlxRHn40.cjs`),t=require(`./objectSpread2-B6
1424
1424
  </div>
1425
1425
  </div>
1426
1426
  </div>
1427
- `,document.body.appendChild(g);let _=g.querySelector(`#simulator-panel`),y=g.querySelector(`#simulator-header`),b=g.querySelector(`#simulator-header-indicator`),x=g.querySelector(`#simulator-header-status-text`),S=g.querySelector(`#simulator-header-pause`),C=g.querySelector(`#simulator-header-retry`),w=g.querySelector(`#simulator-header-settings`),T=g.querySelector(`#simulator-toggle`),E=g.querySelector(`#simulator-timer`),D=g.querySelector(`#simulator-tabs`),O=g.querySelector(`#simulator-content`),k=e=>g.querySelector(e),A=e=>{S.innerHTML=e?h.play:h.pause,S.title=e?`Resume`:`Pause`},j=(e,t)=>{let n=k(`#simulator-status .text`),r=k(`#simulator-status .indicator`);n&&(n.textContent=e),r&&(r.className=`indicator ${t}`),b.className=t,x.textContent=e},M=(e,t)=>{t&&t!==`0`?E.innerHTML=`${e}<span class="penalty">+${t}</span>`:E.textContent=e},N=e=>{var t;m.activeTab=e,O.classList.remove(`hidden`),d(e),D.querySelectorAll(`.simulator-tab`).forEach(t=>{t.classList.toggle(`active`,t.getAttribute(`data-tab`)===e)}),g.querySelectorAll(`.simulator-tab-content`).forEach(t=>{t.classList.toggle(`active`,t.id===`simulator-tab-${e}`)}),w.classList.toggle(`active`,e===`auth`);let n=f.find(t=>t.id===e);n==null||(t=n.onActivate)==null||t.call(n,B)},P=e=>{m.isCollapsed=e,_.classList.toggle(`collapsed`,e),u(e),e?(O.classList.add(`hidden`),D.querySelectorAll(`.simulator-tab`).forEach(e=>e.classList.remove(`active`))):N(m.activeTab)},F=()=>{c.updatePreview(B)},I=function(){var t=e.t(function*(){var e,t;if(m.puzzleData)return m.puzzleData;if(!a||a.size===0)throw Error(`No fixtures configured. Add puzzle JSON files to a fixtures directory and pass fixturesGlob to the simulator.`);let n=(e=m.selectedCategory)==null?o[0]:e,r=n?a.get(n):void 0;if(!r||r.size===0)throw Error(`No puzzles found in fixture category "${n}"`);let i=(t=m.selectedPuzzle)==null?r.keys().next().value:t,s=i?r.get(i):void 0;if(!s)throw Error(`Puzzle "${i}" not found in category "${n}"`);m.puzzleData=s,console.log(`Simulator: Puzzle loaded from fixtures`,{category:n,puzzle:i}),m.originalPuzzle=JSON.stringify(m.puzzleData,null,2);let c=k(`#simulator-puzzle`);return c&&(c.value=m.originalPuzzle),m.activeTab===`thumb`&&F(),m.puzzleData});return function(){return t.apply(this,arguments)}}(),L=ee(e=>{s.addLogEntry(e,B)}),R=(e,t)=>{te(e,t,L)},z=(e,t)=>{let n=g.querySelector(`[data-badge="${e}"]`);n&&(n.textContent=t&&t>0?String(t):``)},B={state:m,getElement:k,sendToGame:R,logMessage:L.log,loadPuzzle:I,updateStatus:j,updateTimer:M,setCollapsed:P,switchTab:N,updateThumbnail:F,updateBadge:z,fixtures:a,fixtureCategories:o,gameSlug:(r=t.slug)==null?null:r};console.log(`[Simulator] Context created with gameSlug:`,B.gameSlug),f.forEach(e=>e.bind(B)),D.querySelectorAll(`.simulator-tab`).forEach(e=>{e.addEventListener(`click`,()=>{let t=e.getAttribute(`data-tab`);N(t),z(t,0)})}),T.addEventListener(`click`,e=>{e.stopPropagation(),P(!0)}),S.addEventListener(`click`,e=>{e.stopPropagation(),m.isPaused?(R(`RESUME_GAME`,{}),m.isPaused=!1,A(!1),j(`Running`,`ready`)):(R(`PAUSE_GAME`,{}),m.isPaused=!0,A(!0),j(`Paused`,`paused`));let t=k(`#simulator-pause`);t&&(t.textContent=m.isPaused?`Resume`:`Pause`)}),C.addEventListener(`click`,e=>{e.stopPropagation(),R(`RETRY_PUZZLE`,{}),m.hasStarted=!1,m.isPaused=!1,A(!1),S.disabled=!0,j(`Ready to retry`,`ready`);let t=k(`#simulator-pause`),n=k(`#simulator-start`);t&&(t.disabled=!0,t.textContent=`Pause`),n&&(n.textContent=`Start`)}),w.addEventListener(`click`,e=>{e.stopPropagation(),m.isCollapsed&&P(!1),N(`auth`)}),y.addEventListener(`click`,e=>{m.isCollapsed&&e.target!==T&&P(!1)}),m.isCollapsed||N(m.activeTab);let V=new URLSearchParams(window.location.search);(V.has(`code`)||V.has(`error`))&&(P(!1),N(`auth`));let H=e=>({userState:{gameSettings:{},id:`simulator-user`,nakamaLogin:`simulator`,ownerID:`simulator-owner`},currentUser:null,startOrFindGameplay:{gamePlayed:{additionalTimeAddedSecs:0,boardState:m.currentInputStr,cheatsUsed:0,combinedTimeSecs:0,completed:!1,createdAt:new Date().toISOString(),elapsedTimeSecs:0,hintsUsed:0,id:`simulator-gameplay-${Date.now()}`,metric1:0,metric2:0,metric3:0,metric4:0,metricStrings:[],ownerID:`simulator-owner`,pointsAwarded:0,resetsUsed:0,slug:`simulator-game`,viewerOwnsPuzzle:!0,puzzle:{id:`simulator-puzzle`,name:`Proto Jig Puzzle`,puzzle:JSON.stringify(e),seriesNumber:1,game:{assetsPath:`./assets/`,assetsSha:``,displayName:`Proto Game`,exposedGlobalFunction:`startGame`,jsPath:``,slug:`proto-game`}}}},theme:m.selectedTheme,hostFlags:[],hostContext:[],appRuntimeContract:`1.0`}),U=function(){var t=e.t(function*(){j(`Loading puzzle...`,`waiting`);try{let e=H(yield I());j(`Sending READY_DATA...`,`waiting`),R(`READY_DATA`,e),j(`Waiting for game to load...`,`waiting`)}catch(e){j(`Error: ${e}`,`paused`)}});return function(){return t.apply(this,arguments)}}(),W=()=>{console.log(`Simulator: Game loaded, ready to start`),C.disabled=!1,f.forEach(e=>{var t;return(t=e.onMessage)==null?void 0:t.call(e,`READY_GAME_LOADED`,void 0,B)}),i&&!m.hasStarted&&setTimeout(()=>{let e=k(`#simulator-start`);e==null||e.click(),S.disabled=!1,m.hasStarted=!0,j(`Running`,`ready`)},100)};return ne((e,t)=>{var n,r;if(e===`READY`){console.log(`Simulator: Received READY from game`),U();return}if(e===`INITIALIZE_SETTINGS`){console.log(`Simulator: Game initialized settings`,t);return}if(e===`READY_GAME_LOADED`){W();return}if(e===`TIMER_TICK`){if(t!=null&&t.display){let[e,n]=t.display;M(e,n)}return}if(e===`TIMER_SYNC`)return;if(e===`SHOW_GAME_COMPLETE_SCREEN`){console.log(`Simulator: Show completion screen`,t);return}if(e===`SIDEBAR_UPDATE`){console.log(`Simulator: Sidebar update`,t);return}f.forEach(n=>{var r;return(r=n.onMessage)==null?void 0:r.call(n,e,t,B)});let i=(n=t==null||(r=t.input)==null?void 0:r.boardState)==null?t==null?void 0:t.boardState:n;e===`UPLOAD_NEW_GAME_STATE`&&i&&(m.currentInputStr=i,m.activeTab===`thumb`&&F(),console.log(`Simulator: Game state uploaded`,t)),e===`GAME_COMPLETED`&&(console.log(`Simulator: Game completed!`,t),S.disabled=!0,m.hasStarted=!1,j(`Completed!`,`ready`))},L),console.log(`Simulator initialized`),$={updateFixtures:e=>{a=v(e),o=Array.from(a.keys()).sort(),B.fixtures=a,B.fixtureCategories=o;let t=localStorage.getItem(`simulator-fixture-category`);if(!m.selectedCategory||!o.includes(m.selectedCategory)){var n;m.selectedCategory=t&&o.includes(t)?t:(n=o[0])==null?null:n}let r=f.find(e=>e.id===`ctrl`);r==null||r.bind(B),console.log(`Simulator: Fixtures updated`,{categories:o,selectedCategory:m.selectedCategory})},sendToGame:R,loadPuzzle:I},$}Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return Pe}});
1428
- //# sourceMappingURL=createSimulator-_TBV3Yo7.cjs.map
1427
+ `,document.body.appendChild(g);let v=g.querySelector(`#simulator-panel`),y=g.querySelector(`#simulator-header`),b=g.querySelector(`#simulator-header-indicator`),x=g.querySelector(`#simulator-header-status-text`),S=g.querySelector(`#simulator-header-pause`),C=g.querySelector(`#simulator-header-retry`),w=g.querySelector(`#simulator-header-settings`),T=g.querySelector(`#simulator-toggle`),E=g.querySelector(`#simulator-timer`),D=g.querySelector(`#simulator-tabs`),O=g.querySelector(`#simulator-content`),k=e=>g.querySelector(e),A=e=>{S.innerHTML=e?h.play:h.pause,S.title=e?`Resume`:`Pause`},j=(e,t)=>{let n=k(`#simulator-status .text`),r=k(`#simulator-status .indicator`);n&&(n.textContent=e),r&&(r.className=`indicator ${t}`),b.className=t,x.textContent=e},M=(e,t)=>{t&&t!==`0`?E.innerHTML=`${e}<span class="penalty">+${t}</span>`:E.textContent=e},N=e=>{var t;m.activeTab=e,O.classList.remove(`hidden`),u(e),D.querySelectorAll(`.simulator-tab`).forEach(t=>{t.classList.toggle(`active`,t.getAttribute(`data-tab`)===e)}),g.querySelectorAll(`.simulator-tab-content`).forEach(t=>{t.classList.toggle(`active`,t.id===`simulator-tab-${e}`)}),w.classList.toggle(`active`,e===`auth`);let n=f.find(t=>t.id===e);n==null||(t=n.onActivate)==null||t.call(n,B)},P=e=>{m.isCollapsed=e,v.classList.toggle(`collapsed`,e),l(e),e?(O.classList.add(`hidden`),D.querySelectorAll(`.simulator-tab`).forEach(e=>e.classList.remove(`active`))):N(m.activeTab)},F=()=>{d.updatePreview(B)},I=function(){var t=e.n(function*(){var e,t;if(m.puzzleData)return m.puzzleData;if(!a||a.size===0)throw Error(`No fixtures configured. Add puzzle JSON files to a fixtures directory and pass fixturesGlob to the simulator.`);let n=(e=m.selectedCategory)==null?o[0]:e,r=n?a.get(n):void 0;if(!r||r.size===0)throw Error(`No puzzles found in fixture category "${n}"`);let i=(t=m.selectedPuzzle)==null?r.keys().next().value:t,s=i?r.get(i):void 0;if(!s)throw Error(`Puzzle "${i}" not found in category "${n}"`);m.puzzleData=s,console.log(`Simulator: Puzzle loaded from fixtures`,{category:n,puzzle:i}),m.originalPuzzle=JSON.stringify(m.puzzleData,null,2);let c=k(`#simulator-puzzle`);return c&&(c.value=m.originalPuzzle),m.activeTab===`thumb`&&F(),m.puzzleData});return function(){return t.apply(this,arguments)}}(),L=ee(e=>{s.addLogEntry(e,B)}),R=(e,t)=>{te(e,t,L)},z=(e,t)=>{let n=g.querySelector(`[data-badge="${e}"]`);n&&(n.textContent=t&&t>0?String(t):``)},B={state:m,getElement:k,sendToGame:R,logMessage:L.log,loadPuzzle:I,updateStatus:j,updateTimer:M,setCollapsed:P,switchTab:N,updateThumbnail:F,updateBadge:z,fixtures:a,fixtureCategories:o,gameSlug:(r=t.slug)==null?null:r};console.log(`[Simulator] Context created with gameSlug:`,B.gameSlug),f.forEach(e=>e.bind(B)),D.querySelectorAll(`.simulator-tab`).forEach(e=>{e.addEventListener(`click`,()=>{let t=e.getAttribute(`data-tab`);N(t),z(t,0)})}),T.addEventListener(`click`,e=>{e.stopPropagation(),P(!0)}),S.addEventListener(`click`,e=>{e.stopPropagation(),m.isPaused?(R(`RESUME_GAME`,{}),m.isPaused=!1,A(!1),j(`Running`,`ready`)):(R(`PAUSE_GAME`,{}),m.isPaused=!0,A(!0),j(`Paused`,`paused`));let t=k(`#simulator-pause`);t&&(t.textContent=m.isPaused?`Resume`:`Pause`)}),C.addEventListener(`click`,e=>{e.stopPropagation(),R(`RETRY_PUZZLE`,{}),m.hasStarted=!1,m.isPaused=!1,A(!1),S.disabled=!0,j(`Ready to retry`,`ready`);let t=k(`#simulator-pause`),n=k(`#simulator-start`);t&&(t.disabled=!0,t.textContent=`Pause`),n&&(n.textContent=`Start`)}),w.addEventListener(`click`,e=>{e.stopPropagation(),m.isCollapsed&&P(!1),N(`auth`)}),y.addEventListener(`click`,e=>{m.isCollapsed&&e.target!==T&&P(!1)}),m.isCollapsed||N(m.activeTab);let V=new URLSearchParams(window.location.search);(V.has(`code`)||V.has(`error`))&&(P(!1),N(`auth`));let H=e=>({userState:{gameSettings:{},id:`simulator-user`,nakamaLogin:`simulator`,ownerID:`simulator-owner`},currentUser:null,startOrFindGameplay:{gamePlayed:{additionalTimeAddedSecs:0,boardState:m.currentInputStr,cheatsUsed:0,combinedTimeSecs:0,completed:!1,createdAt:new Date().toISOString(),elapsedTimeSecs:0,hintsUsed:0,id:`simulator-gameplay-${Date.now()}`,ownerID:`simulator-owner`,pointsAwarded:0,resetsUsed:0,slug:`simulator-game`,viewerOwnsPuzzle:!0,puzzle:{id:`simulator-puzzle`,name:`Proto Jig Puzzle`,puzzle:JSON.stringify(e),seriesNumber:1,game:{assetsPath:`./assets/`,assetsSha:``,displayName:`Proto Game`,exposedGlobalFunction:`startGame`,jsPath:``,slug:`proto-game`}}}},theme:m.selectedTheme,hostFlags:[],hostContext:[],appRuntimeContract:`1.0`}),U=function(){var t=e.n(function*(){j(`Loading puzzle...`,`waiting`);try{let e=H(yield I());j(`Sending READY_DATA...`,`waiting`),R(`READY_DATA`,e),j(`Waiting for game to load...`,`waiting`)}catch(e){j(`Error: ${e}`,`paused`)}});return function(){return t.apply(this,arguments)}}(),W=()=>{console.log(`Simulator: Game loaded, ready to start`),C.disabled=!1,f.forEach(e=>{var t;return(t=e.onMessage)==null?void 0:t.call(e,`READY_GAME_LOADED`,void 0,B)}),i&&!m.hasStarted&&setTimeout(()=>{let e=k(`#simulator-start`);e==null||e.click(),S.disabled=!1,m.hasStarted=!0,j(`Running`,`ready`)},100)};return ne((e,t)=>{var n,r;if(e===`READY`){console.log(`Simulator: Received READY from game`),U();return}if(e===`INITIALIZE_SETTINGS`){console.log(`Simulator: Game initialized settings`,t);return}if(e===`READY_GAME_LOADED`){W();return}if(e===`TIMER_TICK`){if(t!=null&&t.display){let[e,n]=t.display;M(e,n)}return}if(e===`TIMER_SYNC`)return;if(e===`SHOW_GAME_COMPLETE_SCREEN`){console.log(`Simulator: Show completion screen`,t);return}if(e===`SIDEBAR_UPDATE`){console.log(`Simulator: Sidebar update`,t);return}f.forEach(n=>{var r;return(r=n.onMessage)==null?void 0:r.call(n,e,t,B)});let i=(n=t==null||(r=t.input)==null?void 0:r.boardState)==null?t==null?void 0:t.boardState:n;e===`UPLOAD_NEW_GAME_STATE`&&i&&(m.currentInputStr=i,m.activeTab===`thumb`&&F(),console.log(`Simulator: Game state uploaded`,t)),e===`GAME_COMPLETED`&&(console.log(`Simulator: Game completed!`,t),S.disabled=!0,m.hasStarted=!1,j(`Completed!`,`ready`))},L),console.log(`Simulator initialized`),$={updateFixtures:e=>{a=_(e),o=Array.from(a.keys()).sort(),B.fixtures=a,B.fixtureCategories=o;let t=localStorage.getItem(`simulator-fixture-category`);if(!m.selectedCategory||!o.includes(m.selectedCategory)){var n;m.selectedCategory=t&&o.includes(t)?t:(n=o[0])==null?null:n}let r=f.find(e=>e.id===`ctrl`);r==null||r.bind(B),console.log(`Simulator: Fixtures updated`,{categories:o,selectedCategory:m.selectedCategory})},sendToGame:R,loadPuzzle:I},$}Object.defineProperty(exports,`t`,{enumerable:!0,get:function(){return Ne}});
1428
+ //# sourceMappingURL=createSimulator-BmeD2jIP.cjs.map