@puzzmo/sdk 1.0.32 → 1.0.33
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.
- package/dist/{createSimulator-COj3lAeu.js → createSimulator-Bo6J_KC_.js} +419 -294
- package/dist/createSimulator-Bo6J_KC_.js.map +1 -0
- package/dist/{createSimulator-DIT36V1k.cjs → createSimulator-EBKHk3L6.cjs} +56 -35
- package/dist/createSimulator-EBKHk3L6.cjs.map +1 -0
- package/dist/fonts.cjs +1 -1
- package/dist/fonts.cjs.map +1 -1
- package/dist/fonts.d.ts +13 -13
- package/dist/fonts.js +1 -1
- package/dist/fonts.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/simulator/createSimulator.d.ts.map +1 -1
- package/dist/simulator/index.cjs +1 -1
- package/dist/simulator/index.d.ts +1 -1
- package/dist/simulator/index.d.ts.map +1 -1
- package/dist/simulator/index.js +1 -1
- package/dist/simulator/standalone.cjs +1 -1
- package/dist/simulator/standalone.js +1 -1
- package/dist/simulator/state.d.ts +3 -1
- package/dist/simulator/state.d.ts.map +1 -1
- package/dist/simulator/types.d.ts +22 -1
- package/dist/simulator/types.d.ts.map +1 -1
- package/dist/simulator/views/HostView.d.ts +9 -0
- package/dist/simulator/views/HostView.d.ts.map +1 -0
- package/dist/simulator/views/index.d.ts +1 -0
- package/dist/simulator/views/index.d.ts.map +1 -1
- package/dist/types.d.ts +31 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.d.ts +19 -0
- package/dist/vite.d.ts.map +1 -1
- package/dist/vite.js.map +1 -1
- package/package.json +1 -1
- package/dist/createSimulator-COj3lAeu.js.map +0 -1
- package/dist/createSimulator-DIT36V1k.cjs.map +0 -1
|
@@ -314,9 +314,26 @@ var r = {
|
|
|
314
314
|
fixturePuzzle: "simulator-fixture-puzzle",
|
|
315
315
|
renderHost: "simulator-render-host",
|
|
316
316
|
renderContext: "simulator-render-context",
|
|
317
|
-
gameSettings: "simulator-game-settings"
|
|
317
|
+
gameSettings: "simulator-game-settings",
|
|
318
|
+
hostContext: "simulator-host-context"
|
|
318
319
|
};
|
|
320
|
+
/** The Host tab's persisted `hostContext` override, or null when the tab hasn't set one. */
|
|
319
321
|
function i() {
|
|
322
|
+
let e = localStorage.getItem(r.hostContext);
|
|
323
|
+
if (!e) return null;
|
|
324
|
+
try {
|
|
325
|
+
let t = JSON.parse(e);
|
|
326
|
+
if (Array.isArray(t)) return t;
|
|
327
|
+
} catch (e) {}
|
|
328
|
+
return null;
|
|
329
|
+
}
|
|
330
|
+
function a(e) {
|
|
331
|
+
localStorage.setItem(r.hostContext, JSON.stringify(e));
|
|
332
|
+
}
|
|
333
|
+
function o() {
|
|
334
|
+
localStorage.removeItem(r.hostContext);
|
|
335
|
+
}
|
|
336
|
+
function s() {
|
|
320
337
|
let e = localStorage.getItem(r.gameSettings);
|
|
321
338
|
if (!e) return {};
|
|
322
339
|
try {
|
|
@@ -325,7 +342,7 @@ function i() {
|
|
|
325
342
|
} catch (e) {}
|
|
326
343
|
return {};
|
|
327
344
|
}
|
|
328
|
-
function
|
|
345
|
+
function c() {
|
|
329
346
|
let e = localStorage.getItem(r.theme);
|
|
330
347
|
if (e) {
|
|
331
348
|
let t = n.find((t) => t.name === e);
|
|
@@ -333,16 +350,16 @@ function a() {
|
|
|
333
350
|
}
|
|
334
351
|
return n[0];
|
|
335
352
|
}
|
|
336
|
-
function
|
|
353
|
+
function l(e) {
|
|
337
354
|
var t;
|
|
338
355
|
let n = localStorage.getItem(r.tab);
|
|
339
356
|
return n && e.includes(n) ? n : (t = e[0]) == null ? "ctrl" : t;
|
|
340
357
|
}
|
|
341
|
-
function
|
|
358
|
+
function u(e) {
|
|
342
359
|
let t = localStorage.getItem(r.collapsed);
|
|
343
360
|
return t === null ? e : t === "true";
|
|
344
361
|
}
|
|
345
|
-
function
|
|
362
|
+
function d() {
|
|
346
363
|
let e = localStorage.getItem(r.renderHost);
|
|
347
364
|
return e && [
|
|
348
365
|
"game",
|
|
@@ -350,7 +367,7 @@ function c() {
|
|
|
350
367
|
"opengraph"
|
|
351
368
|
].includes(e) ? e : "game";
|
|
352
369
|
}
|
|
353
|
-
function
|
|
370
|
+
function f() {
|
|
354
371
|
let e = localStorage.getItem(r.renderContext);
|
|
355
372
|
if (e && [
|
|
356
373
|
"preview",
|
|
@@ -359,49 +376,55 @@ function l() {
|
|
|
359
376
|
"timeline"
|
|
360
377
|
].includes(e)) return e;
|
|
361
378
|
}
|
|
362
|
-
function
|
|
363
|
-
var
|
|
364
|
-
let
|
|
379
|
+
function p(e, t, n) {
|
|
380
|
+
var a, o, p;
|
|
381
|
+
let m = localStorage.getItem(r.fixtureCategory), h = localStorage.getItem(r.fixturePuzzle), g = i();
|
|
365
382
|
return {
|
|
366
|
-
|
|
383
|
+
hostContext: (a = g == null ? e.hostContext : g) == null ? [{
|
|
384
|
+
type: "app",
|
|
385
|
+
layout: "desktop",
|
|
386
|
+
host: null
|
|
387
|
+
}] : a,
|
|
388
|
+
hostContextIsOverridden: g !== null,
|
|
389
|
+
isCollapsed: u((o = e.collapsed) == null ? !0 : o),
|
|
367
390
|
isPaused: !1,
|
|
368
391
|
hasStarted: !1,
|
|
369
|
-
activeTab:
|
|
392
|
+
activeTab: l(n),
|
|
370
393
|
puzzleData: null,
|
|
371
394
|
originalPuzzle: "",
|
|
372
395
|
currentInputStr: "",
|
|
373
396
|
completionData: null,
|
|
374
|
-
selectedTheme:
|
|
375
|
-
selectedCategory:
|
|
376
|
-
selectedPuzzle:
|
|
377
|
-
renderHost:
|
|
378
|
-
renderContext:
|
|
379
|
-
gameSettings:
|
|
397
|
+
selectedTheme: c(),
|
|
398
|
+
selectedCategory: m && t.includes(m) ? m : (p = t[0]) == null ? null : p,
|
|
399
|
+
selectedPuzzle: h == null ? null : h,
|
|
400
|
+
renderHost: d(),
|
|
401
|
+
renderContext: f(),
|
|
402
|
+
gameSettings: s(),
|
|
380
403
|
settingsComponents: null
|
|
381
404
|
};
|
|
382
405
|
}
|
|
383
|
-
function
|
|
406
|
+
function m(e) {
|
|
384
407
|
localStorage.setItem(r.gameSettings, JSON.stringify(e));
|
|
385
408
|
}
|
|
386
|
-
function
|
|
409
|
+
function h() {
|
|
387
410
|
localStorage.removeItem(r.gameSettings);
|
|
388
411
|
}
|
|
389
|
-
function
|
|
412
|
+
function g(e) {
|
|
390
413
|
localStorage.setItem(r.collapsed, String(e));
|
|
391
414
|
}
|
|
392
|
-
function
|
|
415
|
+
function ee(e) {
|
|
393
416
|
localStorage.setItem(r.tab, e);
|
|
394
417
|
}
|
|
395
|
-
function
|
|
418
|
+
function te(e) {
|
|
396
419
|
localStorage.setItem(r.theme, e);
|
|
397
420
|
}
|
|
398
|
-
function
|
|
421
|
+
function _(e) {
|
|
399
422
|
localStorage.setItem(r.fixtureCategory, e);
|
|
400
423
|
}
|
|
401
|
-
function
|
|
424
|
+
function v(e) {
|
|
402
425
|
localStorage.setItem(r.fixturePuzzle, e);
|
|
403
426
|
}
|
|
404
|
-
function
|
|
427
|
+
function ne() {
|
|
405
428
|
localStorage.removeItem(r.fixturePuzzle);
|
|
406
429
|
}
|
|
407
430
|
function y(e) {
|
|
@@ -410,7 +433,7 @@ function y(e) {
|
|
|
410
433
|
function b(e) {
|
|
411
434
|
e ? localStorage.setItem(r.renderContext, e) : localStorage.removeItem(r.renderContext);
|
|
412
435
|
}
|
|
413
|
-
function
|
|
436
|
+
function re(e) {
|
|
414
437
|
let t = [];
|
|
415
438
|
return {
|
|
416
439
|
log(n, r, i) {
|
|
@@ -435,13 +458,13 @@ function ee(e) {
|
|
|
435
458
|
}
|
|
436
459
|
};
|
|
437
460
|
}
|
|
438
|
-
function
|
|
461
|
+
function ie(e, t, n) {
|
|
439
462
|
console.log("Simulator sending:", e, t), n == null || n.log(e, t, "out"), window.postMessage({
|
|
440
463
|
type: e,
|
|
441
464
|
data: t
|
|
442
465
|
}, "*");
|
|
443
466
|
}
|
|
444
|
-
function
|
|
467
|
+
function ae(e, t) {
|
|
445
468
|
let n = (n) => {
|
|
446
469
|
var r, i, a;
|
|
447
470
|
if (!(!(n == null || (r = n.data) == null) && r.type)) return;
|
|
@@ -451,7 +474,7 @@ function ne(e, t) {
|
|
|
451
474
|
return window.addEventListener("message", n), () => window.removeEventListener("message", n);
|
|
452
475
|
}
|
|
453
476
|
/** Parse fixture imports into a structured format: { category: { filename: data } } */
|
|
454
|
-
function
|
|
477
|
+
function oe(e) {
|
|
455
478
|
let t = /* @__PURE__ */ new Map();
|
|
456
479
|
console.log("Simulator: Parsing fixtures", Object.keys(e));
|
|
457
480
|
for (let [o, s] of Object.entries(e)) {
|
|
@@ -470,7 +493,7 @@ function re(e) {
|
|
|
470
493
|
}), t;
|
|
471
494
|
}
|
|
472
495
|
/** Render fixture selector HTML */
|
|
473
|
-
function
|
|
496
|
+
function x(e, t) {
|
|
474
497
|
return e.length === 0 ? "" : `
|
|
475
498
|
<div class="simulator-fixtures">
|
|
476
499
|
<div class="simulator-field">
|
|
@@ -487,7 +510,7 @@ function ie(e, t) {
|
|
|
487
510
|
`;
|
|
488
511
|
}
|
|
489
512
|
/** Update puzzle select options based on selected category */
|
|
490
|
-
function
|
|
513
|
+
function S(e, t, n, r) {
|
|
491
514
|
let i = t.get(n);
|
|
492
515
|
if (!i) return null;
|
|
493
516
|
let a = Array.from(i.keys()), o = r;
|
|
@@ -498,11 +521,11 @@ function x(e, t, n, r) {
|
|
|
498
521
|
return e.innerHTML = a.map((e) => `<option value="${e}" ${e === o ? "selected" : ""}>${e}</option>`).join(""), o;
|
|
499
522
|
}
|
|
500
523
|
/** Get puzzle data from fixtures */
|
|
501
|
-
function
|
|
524
|
+
function C(e, t, n) {
|
|
502
525
|
var r, i;
|
|
503
526
|
return !t || !n || (r = (i = e.get(t)) == null ? void 0 : i.get(n)) == null ? null : r;
|
|
504
527
|
}
|
|
505
|
-
function
|
|
528
|
+
function se() {
|
|
506
529
|
return {
|
|
507
530
|
id: "ctrl",
|
|
508
531
|
label: "Ctrl",
|
|
@@ -517,19 +540,19 @@ function ae() {
|
|
|
517
540
|
selectedCategory: e.state.selectedCategory,
|
|
518
541
|
selectedPuzzle: e.state.selectedPuzzle
|
|
519
542
|
}), e.fixtures && e.fixtureCategories.length > 0 && i) {
|
|
520
|
-
i.innerHTML =
|
|
543
|
+
i.innerHTML = x(e.fixtureCategories, e.state.selectedCategory);
|
|
521
544
|
let t = e.getElement("#simulator-fixture-category"), n = e.getElement("#simulator-fixture-puzzle");
|
|
522
545
|
if (t && n && e.state.selectedCategory) {
|
|
523
|
-
e.state.selectedPuzzle =
|
|
524
|
-
let r =
|
|
546
|
+
e.state.selectedPuzzle = S(n, e.fixtures, e.state.selectedCategory, e.state.selectedPuzzle);
|
|
547
|
+
let r = C(e.fixtures, e.state.selectedCategory, e.state.selectedPuzzle);
|
|
525
548
|
console.log("Simulator: Loading fixture puzzle", {
|
|
526
549
|
category: e.state.selectedCategory,
|
|
527
550
|
puzzle: e.state.selectedPuzzle,
|
|
528
551
|
hasPuzzleData: !!r
|
|
529
|
-
}), r && (e.state.puzzleData = r, e.state.originalPuzzle = r, e.state.selectedCategory &&
|
|
530
|
-
console.log("Simulator: Category changed, reloading...", t.value),
|
|
552
|
+
}), r && (e.state.puzzleData = r, e.state.originalPuzzle = r, e.state.selectedCategory && _(e.state.selectedCategory), e.state.selectedPuzzle && v(e.state.selectedPuzzle)), t.addEventListener("change", () => {
|
|
553
|
+
console.log("Simulator: Category changed, reloading...", t.value), _(t.value), ne(), window.location.reload();
|
|
531
554
|
}), n.addEventListener("change", () => {
|
|
532
|
-
console.log("Simulator: Puzzle changed, reloading...", n.value),
|
|
555
|
+
console.log("Simulator: Puzzle changed, reloading...", n.value), v(n.value), window.location.reload();
|
|
533
556
|
});
|
|
534
557
|
}
|
|
535
558
|
}
|
|
@@ -547,9 +570,9 @@ function ae() {
|
|
|
547
570
|
}
|
|
548
571
|
};
|
|
549
572
|
}
|
|
550
|
-
var
|
|
573
|
+
var w = "simulator-saved-states";
|
|
551
574
|
/** Find thumbnail function on globalThis (looks for functions ending in "Thumbnail") */
|
|
552
|
-
function
|
|
575
|
+
function T() {
|
|
553
576
|
let e = globalThis;
|
|
554
577
|
for (let t of Object.keys(e)) if (t.endsWith("Thumbnail") && typeof e[t] == "function") return {
|
|
555
578
|
name: t,
|
|
@@ -558,8 +581,8 @@ function w() {
|
|
|
558
581
|
return null;
|
|
559
582
|
}
|
|
560
583
|
/** Generate a small thumbnail SVG for a given input string */
|
|
561
|
-
function
|
|
562
|
-
let n =
|
|
584
|
+
function E(e, t) {
|
|
585
|
+
let n = T();
|
|
563
586
|
if (!n) return "";
|
|
564
587
|
try {
|
|
565
588
|
var r;
|
|
@@ -574,14 +597,14 @@ function T(e, t) {
|
|
|
574
597
|
return "";
|
|
575
598
|
}
|
|
576
599
|
}
|
|
577
|
-
var
|
|
578
|
-
function
|
|
600
|
+
var D = [];
|
|
601
|
+
function O(e, t = 8) {
|
|
579
602
|
let n = 14 * t + 8 + 4;
|
|
580
603
|
e.style.height = "auto";
|
|
581
604
|
let r = Math.min(Math.max(e.scrollHeight, 40), n);
|
|
582
605
|
e.style.height = `${r}px`;
|
|
583
606
|
}
|
|
584
|
-
function
|
|
607
|
+
function ce() {
|
|
585
608
|
let e = "", t = "";
|
|
586
609
|
return {
|
|
587
610
|
id: "data",
|
|
@@ -599,102 +622,102 @@ function oe() {
|
|
|
599
622
|
let i = n.getElement(".data-view-container");
|
|
600
623
|
i == null || i.querySelectorAll(".data-subtab-content").forEach((e) => {
|
|
601
624
|
e.classList.toggle("active", e.id === `data-subtab-${t}`);
|
|
602
|
-
}), t === "edit" ?
|
|
625
|
+
}), t === "edit" ? N(n) : t === "history" ? A(n) : t === "saves" && j(n);
|
|
603
626
|
});
|
|
604
627
|
});
|
|
605
628
|
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");
|
|
606
629
|
setTimeout(() => {
|
|
607
|
-
i && n.state.originalPuzzle && (i.value = n.state.originalPuzzle, e = n.state.originalPuzzle,
|
|
630
|
+
i && n.state.originalPuzzle && (i.value = n.state.originalPuzzle, e = n.state.originalPuzzle, O(i)), a && n.state.currentInputStr && (a.value = n.state.currentInputStr, t = n.state.currentInputStr, O(a));
|
|
608
631
|
}, 0), i == null || i.addEventListener("input", () => {
|
|
609
|
-
|
|
632
|
+
O(i);
|
|
610
633
|
let t = i.value !== e;
|
|
611
634
|
s && (s.disabled = !t);
|
|
612
635
|
}), a == null || a.addEventListener("input", () => {
|
|
613
|
-
|
|
636
|
+
O(a);
|
|
614
637
|
let e = a.value !== t;
|
|
615
638
|
l && (l.disabled = !e);
|
|
616
639
|
}), o == null || o.addEventListener("click", () => {
|
|
617
|
-
i && (i.value = n.state.originalPuzzle, e = n.state.originalPuzzle,
|
|
640
|
+
i && (i.value = n.state.originalPuzzle, e = n.state.originalPuzzle, O(i), s && (s.disabled = !0));
|
|
618
641
|
}), s == null || s.addEventListener("click", () => {
|
|
619
642
|
i && (n.state.puzzleData = i.value, 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);
|
|
620
643
|
}), c == null || c.addEventListener("click", () => {
|
|
621
|
-
a && (a.value = t,
|
|
644
|
+
a && (a.value = t, O(a), l && (l.disabled = !0));
|
|
622
645
|
}), l == null || l.addEventListener("click", () => {
|
|
623
646
|
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);
|
|
624
647
|
});
|
|
625
648
|
let f = n.getElement("#simulator-history-clear");
|
|
626
649
|
f == null || f.addEventListener("click", () => {
|
|
627
|
-
|
|
650
|
+
D = [], A(n);
|
|
628
651
|
});
|
|
629
652
|
let p = n.getElement("#simulator-save-name"), m = n.getElement("#simulator-save-btn");
|
|
630
653
|
m == null || m.addEventListener("click", () => {
|
|
631
654
|
if (!p || !p.value.trim()) return;
|
|
632
|
-
let e =
|
|
655
|
+
let e = k(), t = {
|
|
633
656
|
name: p.value.trim(),
|
|
634
657
|
puzzleStr: n.state.originalPuzzle,
|
|
635
658
|
inputStr: n.state.currentInputStr,
|
|
636
659
|
timestamp: Date.now()
|
|
637
660
|
};
|
|
638
|
-
e.push(t), localStorage.setItem(
|
|
639
|
-
}),
|
|
661
|
+
e.push(t), localStorage.setItem(w, JSON.stringify(e)), p.value = "", j(n);
|
|
662
|
+
}), j(n);
|
|
640
663
|
},
|
|
641
664
|
onActivate(n) {
|
|
642
|
-
e = n.state.originalPuzzle, t = n.state.currentInputStr,
|
|
665
|
+
e = n.state.originalPuzzle, t = n.state.currentInputStr, N(n), A(n);
|
|
643
666
|
},
|
|
644
667
|
onMessage(e, n, r) {
|
|
645
668
|
var i, a;
|
|
646
669
|
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;
|
|
647
670
|
if (e === "UPLOAD_NEW_GAME_STATE" && c) {
|
|
648
|
-
if (r.state.currentInputStr = c,
|
|
649
|
-
|
|
671
|
+
if (r.state.currentInputStr = c, D.length === 0 || D[D.length - 1].value !== c) {
|
|
672
|
+
D.push({
|
|
650
673
|
value: c,
|
|
651
674
|
timestamp: Date.now()
|
|
652
|
-
}),
|
|
675
|
+
}), D.length > 100 && (D = D.slice(-100));
|
|
653
676
|
let e = r.getElement("#data-subtab-history");
|
|
654
|
-
e != null && e.classList.contains("active") &&
|
|
677
|
+
e != null && e.classList.contains("active") && A(r);
|
|
655
678
|
}
|
|
656
|
-
o && (o.value = r.state.currentInputStr, t = r.state.currentInputStr,
|
|
679
|
+
o && (o.value = r.state.currentInputStr, t = r.state.currentInputStr, O(o), s && (s.disabled = !0));
|
|
657
680
|
}
|
|
658
681
|
}
|
|
659
682
|
};
|
|
660
683
|
}
|
|
661
|
-
function
|
|
684
|
+
function k() {
|
|
662
685
|
try {
|
|
663
|
-
let e = localStorage.getItem(
|
|
686
|
+
let e = localStorage.getItem(w);
|
|
664
687
|
return e ? JSON.parse(e) : [];
|
|
665
688
|
} catch (e) {
|
|
666
689
|
return [];
|
|
667
690
|
}
|
|
668
691
|
}
|
|
669
|
-
function
|
|
692
|
+
function A(e) {
|
|
670
693
|
let t = e.getElement("#simulator-history-list");
|
|
671
694
|
if (t) {
|
|
672
|
-
if (t.style.setProperty("--history-thumb-bg", e.state.selectedTheme.a_bg),
|
|
695
|
+
if (t.style.setProperty("--history-thumb-bg", e.state.selectedTheme.a_bg), D.length === 0) {
|
|
673
696
|
t.innerHTML = "<div class=\"simulator-empty\">No history yet</div>";
|
|
674
697
|
return;
|
|
675
698
|
}
|
|
676
|
-
t.innerHTML = [...
|
|
677
|
-
let r =
|
|
699
|
+
t.innerHTML = [...D].reverse().map((t, n) => {
|
|
700
|
+
let r = D.length - 1 - n, i = new Date(t.timestamp).toLocaleTimeString(), a = t.value.length > 60 ? t.value.slice(0, 60) + "..." : t.value;
|
|
678
701
|
return `
|
|
679
702
|
<div class="history-item" data-history-idx="${r}">
|
|
680
|
-
<div class="history-item-thumb">${
|
|
703
|
+
<div class="history-item-thumb">${E(e, t.value)}</div>
|
|
681
704
|
<div class="history-item-content">
|
|
682
705
|
<div class="history-item-header">
|
|
683
706
|
<span class="history-item-num">#${r + 1}</span>
|
|
684
707
|
<span class="history-item-time">${i}</span>
|
|
685
708
|
<button class="simulator-btn tiny history-restore-btn" data-history-idx="${r}">Restore</button>
|
|
686
709
|
</div>
|
|
687
|
-
<div class="history-item-preview">${
|
|
710
|
+
<div class="history-item-preview">${M(a)}</div>
|
|
688
711
|
</div>
|
|
689
712
|
</div>
|
|
690
713
|
`;
|
|
691
714
|
}).join(""), t.querySelectorAll(".history-restore-btn").forEach((t) => {
|
|
692
715
|
t.addEventListener("click", (t) => {
|
|
693
|
-
let n = parseInt(t.target.getAttribute("data-history-idx") || "0"), r =
|
|
716
|
+
let n = parseInt(t.target.getAttribute("data-history-idx") || "0"), r = D[n];
|
|
694
717
|
if (r) {
|
|
695
718
|
e.state.currentInputStr = r.value;
|
|
696
719
|
let t = e.getElement("#simulator-input");
|
|
697
|
-
t && (t.value = r.value,
|
|
720
|
+
t && (t.value = r.value, O(t)), e.updateStatus("Input restored from history", "ready");
|
|
698
721
|
let n = e.getElement(".data-subtab[data-subtab=\"edit\"]");
|
|
699
722
|
n == null || n.click();
|
|
700
723
|
}
|
|
@@ -702,10 +725,10 @@ function k(e) {
|
|
|
702
725
|
});
|
|
703
726
|
}
|
|
704
727
|
}
|
|
705
|
-
function
|
|
728
|
+
function j(e) {
|
|
706
729
|
let t = e.getElement("#simulator-saves-list");
|
|
707
730
|
if (!t) return;
|
|
708
|
-
let n =
|
|
731
|
+
let n = k();
|
|
709
732
|
if (n.length === 0) {
|
|
710
733
|
t.innerHTML = "<div class=\"simulator-empty\">No saved states</div>";
|
|
711
734
|
return;
|
|
@@ -715,7 +738,7 @@ function A(e) {
|
|
|
715
738
|
return `
|
|
716
739
|
<div class="save-item">
|
|
717
740
|
<div class="save-item-header">
|
|
718
|
-
<span class="save-item-name">${
|
|
741
|
+
<span class="save-item-name">${M(e.name)}</span>
|
|
719
742
|
<span class="save-item-time">${i} ${a}</span>
|
|
720
743
|
</div>
|
|
721
744
|
<div class="save-item-actions">
|
|
@@ -730,7 +753,7 @@ function A(e) {
|
|
|
730
753
|
if (r) {
|
|
731
754
|
e.state.puzzleData = r.puzzleStr, e.state.originalPuzzle = r.puzzleStr, e.state.currentInputStr = r.inputStr;
|
|
732
755
|
let t = e.getElement("#simulator-puzzle"), n = e.getElement("#simulator-input");
|
|
733
|
-
t && (t.value = r.puzzleStr,
|
|
756
|
+
t && (t.value = r.puzzleStr, O(t)), n && (n.value = r.inputStr, O(n)), e.updateStatus(`Loaded: ${r.name}`, "ready");
|
|
734
757
|
let i = e.getElement(".data-subtab[data-subtab=\"edit\"]");
|
|
735
758
|
i == null || i.click();
|
|
736
759
|
}
|
|
@@ -738,21 +761,21 @@ function A(e) {
|
|
|
738
761
|
}), t.querySelectorAll(".save-delete-btn").forEach((t) => {
|
|
739
762
|
t.addEventListener("click", (t) => {
|
|
740
763
|
let r = parseInt(t.target.getAttribute("data-save-idx") || "0"), i = n.filter((e, t) => t !== r);
|
|
741
|
-
localStorage.setItem(
|
|
764
|
+
localStorage.setItem(w, JSON.stringify(i)), j(e);
|
|
742
765
|
});
|
|
743
766
|
});
|
|
744
767
|
}
|
|
745
|
-
function
|
|
768
|
+
function M(e) {
|
|
746
769
|
return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
747
770
|
}
|
|
748
|
-
function
|
|
771
|
+
function N(e) {
|
|
749
772
|
let t = e.getElement("#simulator-puzzle"), n = e.getElement("#simulator-input"), r = e.getElement("#simulator-puzzle-apply"), i = e.getElement("#simulator-input-apply");
|
|
750
|
-
t && e.state.originalPuzzle && (t.value = e.state.originalPuzzle,
|
|
773
|
+
t && e.state.originalPuzzle && (t.value = e.state.originalPuzzle, O(t), r && (r.disabled = !0)), n && (n.value = e.state.currentInputStr, O(n), i && (i.disabled = !0));
|
|
751
774
|
}
|
|
752
|
-
function
|
|
775
|
+
function P(e) {
|
|
753
776
|
return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """);
|
|
754
777
|
}
|
|
755
|
-
function
|
|
778
|
+
function le() {
|
|
756
779
|
let e = 0;
|
|
757
780
|
return {
|
|
758
781
|
id: "msgs",
|
|
@@ -779,7 +802,7 @@ function se() {
|
|
|
779
802
|
<span class="simulator-msg-type">${t.direction === "out" ? "→" : "←"} ${t.type}</span>
|
|
780
803
|
<span class="simulator-msg-time">${t.time}</span>
|
|
781
804
|
</div>
|
|
782
|
-
${a ? `<div class="simulator-msg-data">${
|
|
805
|
+
${a ? `<div class="simulator-msg-data">${P(a)}</div>` : ""}
|
|
783
806
|
`;
|
|
784
807
|
let o = i.querySelector(".simulator-msg-data");
|
|
785
808
|
for (o && o.addEventListener("click", () => {
|
|
@@ -790,7 +813,7 @@ function se() {
|
|
|
790
813
|
}
|
|
791
814
|
};
|
|
792
815
|
}
|
|
793
|
-
function
|
|
816
|
+
function ue() {
|
|
794
817
|
return {
|
|
795
818
|
id: "done",
|
|
796
819
|
label: "Done",
|
|
@@ -827,7 +850,7 @@ function ce() {
|
|
|
827
850
|
}
|
|
828
851
|
};
|
|
829
852
|
}
|
|
830
|
-
function
|
|
853
|
+
function de() {
|
|
831
854
|
let e = [], t = () => (/* @__PURE__ */ new Date()).toLocaleTimeString("en-US", { hour12: !1 }), n = (e) => {
|
|
832
855
|
let { checkpointName: t, augConfig: n, time: r } = e, i = n == null ? void 0 : n.deeds;
|
|
833
856
|
return `
|
|
@@ -878,7 +901,7 @@ function le() {
|
|
|
878
901
|
};
|
|
879
902
|
}
|
|
880
903
|
/** Find thumbnail function on globalThis (looks for functions ending in "Thumbnail") */
|
|
881
|
-
function
|
|
904
|
+
function F() {
|
|
882
905
|
let e = globalThis;
|
|
883
906
|
for (let t of Object.keys(e)) if (t.endsWith("Thumbnail") && typeof e[t] == "function") return {
|
|
884
907
|
name: t,
|
|
@@ -886,7 +909,7 @@ function P() {
|
|
|
886
909
|
};
|
|
887
910
|
return null;
|
|
888
911
|
}
|
|
889
|
-
function
|
|
912
|
+
function fe() {
|
|
890
913
|
return {
|
|
891
914
|
id: "thumb",
|
|
892
915
|
label: "Thumb",
|
|
@@ -911,7 +934,7 @@ function ue() {
|
|
|
911
934
|
updatePreview: (e) => {
|
|
912
935
|
let t = e.getElement("#simulator-thumb-preview"), n = e.getElement("#simulator-thumb-fn");
|
|
913
936
|
t == null || t.style.setProperty("--sim-thumb-bg", e.state.selectedTheme.g_bg);
|
|
914
|
-
let r =
|
|
937
|
+
let r = F();
|
|
915
938
|
if (!r) {
|
|
916
939
|
t && (t.innerHTML = "<span class=\"simulator-empty\">No thumbnail function found</span>"), n && (n.textContent = "");
|
|
917
940
|
return;
|
|
@@ -934,7 +957,7 @@ function ue() {
|
|
|
934
957
|
};
|
|
935
958
|
}
|
|
936
959
|
/** Generate theme preview HTML showing key colors */
|
|
937
|
-
function
|
|
960
|
+
function I(e) {
|
|
938
961
|
let t = [
|
|
939
962
|
e.key,
|
|
940
963
|
e.subBrand,
|
|
@@ -945,7 +968,7 @@ function F(e) {
|
|
|
945
968
|
].map((e) => `<div class="simulator-theme-preview-cell" style="background: ${e}"></div>`).join("");
|
|
946
969
|
return `<div class="simulator-theme-preview" style="background: ${e.g_bg}">${t}</div>`;
|
|
947
970
|
}
|
|
948
|
-
function
|
|
971
|
+
function pe() {
|
|
949
972
|
return {
|
|
950
973
|
id: "theme",
|
|
951
974
|
label: "Theme",
|
|
@@ -957,49 +980,154 @@ function de() {
|
|
|
957
980
|
t && n.forEach((n) => {
|
|
958
981
|
let r = document.createElement("div");
|
|
959
982
|
r.className = `simulator-theme-item${n.name === e.state.selectedTheme.name ? " selected" : ""}`, r.innerHTML = `
|
|
960
|
-
${
|
|
983
|
+
${I(n)}
|
|
961
984
|
<div class="simulator-theme-name">${n.name}</div>
|
|
962
985
|
<div class="simulator-theme-type">${n.type}</div>
|
|
963
986
|
`, r.addEventListener("click", () => {
|
|
964
|
-
console.log("Simulator: Theme changed, reloading...", n.name),
|
|
987
|
+
console.log("Simulator: Theme changed, reloading...", n.name), te(n.name), window.location.reload();
|
|
965
988
|
}), t.appendChild(r);
|
|
966
989
|
});
|
|
967
990
|
}
|
|
968
991
|
};
|
|
969
992
|
}
|
|
970
|
-
var
|
|
971
|
-
|
|
972
|
-
|
|
993
|
+
var L = [
|
|
994
|
+
{
|
|
995
|
+
name: "app (desktop)",
|
|
996
|
+
context: [{
|
|
997
|
+
type: "app",
|
|
998
|
+
layout: "desktop",
|
|
999
|
+
host: null
|
|
1000
|
+
}]
|
|
1001
|
+
},
|
|
1002
|
+
{
|
|
1003
|
+
name: "app (mobile)",
|
|
1004
|
+
context: [{
|
|
1005
|
+
type: "app",
|
|
1006
|
+
layout: "mobile",
|
|
1007
|
+
host: null
|
|
1008
|
+
}]
|
|
1009
|
+
},
|
|
1010
|
+
{
|
|
1011
|
+
name: "app (ios)",
|
|
1012
|
+
context: [{
|
|
1013
|
+
type: "app",
|
|
1014
|
+
layout: "mobile",
|
|
1015
|
+
host: "ios-app"
|
|
1016
|
+
}]
|
|
1017
|
+
},
|
|
1018
|
+
{
|
|
1019
|
+
name: "embed",
|
|
1020
|
+
context: [{ type: "embed" }]
|
|
1021
|
+
},
|
|
1022
|
+
{
|
|
1023
|
+
name: "embed (no UI)",
|
|
1024
|
+
context: [{
|
|
1025
|
+
type: "embed",
|
|
1026
|
+
noUI: !0
|
|
1027
|
+
}]
|
|
1028
|
+
},
|
|
1029
|
+
{
|
|
1030
|
+
name: "sandbox",
|
|
1031
|
+
context: [{ type: "sandbox" }]
|
|
1032
|
+
}
|
|
1033
|
+
];
|
|
1034
|
+
/**
|
|
1035
|
+
* Host tab — edit the `hostContext` array the simulator sends in READY_DATA, so host-context
|
|
1036
|
+
* dependent features (embed settings, sandbox mode, mobile layout, …) can be exercised locally.
|
|
1037
|
+
* The bootstrap is only read at game boot, so applying a change persists it to localStorage and
|
|
1038
|
+
* restarts (reloads) the page — the same flow as the Theme tab.
|
|
1039
|
+
*/
|
|
1040
|
+
function me(e = []) {
|
|
1041
|
+
let t = [...L, ...e];
|
|
1042
|
+
return {
|
|
1043
|
+
id: "host",
|
|
1044
|
+
label: "Host",
|
|
1045
|
+
render() {
|
|
1046
|
+
return `
|
|
1047
|
+
<style>
|
|
1048
|
+
#simulator-tab-host .host-note { opacity: 0.5; font-size: 10px; margin: 4px 0 8px; }
|
|
1049
|
+
#simulator-tab-host .host-error { color: #f66; font-size: 11px; margin-top: 6px; white-space: pre-wrap; }
|
|
1050
|
+
#simulator-tab-host .host-actions { display: flex; gap: 6px; margin-top: 8px; }
|
|
1051
|
+
#simulator-tab-host .simulator-textarea { min-height: 140px; font-family: monospace; }
|
|
1052
|
+
</style>
|
|
1053
|
+
<div class="simulator-section">
|
|
1054
|
+
<div class="simulator-section-title">Host Context</div>
|
|
1055
|
+
<div class="host-note" id="host-source"></div>
|
|
1056
|
+
<select class="simulator-select" id="host-presets">
|
|
1057
|
+
<option value="">Preset…</option>
|
|
1058
|
+
${t.map((e, t) => `<option value="${t}">${R(e.name)}</option>`).join("")}
|
|
1059
|
+
</select>
|
|
1060
|
+
<textarea class="simulator-textarea" id="host-json" spellcheck="false"></textarea>
|
|
1061
|
+
<div class="host-actions">
|
|
1062
|
+
<button class="simulator-btn primary" id="host-apply">Apply & Restart</button>
|
|
1063
|
+
<button class="simulator-btn subtle" id="host-reset">Reset</button>
|
|
1064
|
+
</div>
|
|
1065
|
+
<div class="host-error" id="host-error"></div>
|
|
1066
|
+
</div>
|
|
1067
|
+
`;
|
|
1068
|
+
},
|
|
1069
|
+
bind(e) {
|
|
1070
|
+
var n, r;
|
|
1071
|
+
let i = e.getElement("#host-json"), s = e.getElement("#host-presets"), c = e.getElement("#host-error"), l = e.getElement("#host-source");
|
|
1072
|
+
!i || !s || !c || !l || (i.value = JSON.stringify(e.state.hostContext, null, 2), l.textContent = e.state.hostContextIsOverridden ? "Using this tab's override. Changes apply on restart." : "Using the vite config / default context. Changes apply on restart.", s.addEventListener("change", () => {
|
|
1073
|
+
let e = t[Number(s.value)];
|
|
1074
|
+
e && (i.value = JSON.stringify(e.context, null, 2));
|
|
1075
|
+
}), (n = e.getElement("#host-apply")) == null || n.addEventListener("click", () => {
|
|
1076
|
+
let e;
|
|
1077
|
+
try {
|
|
1078
|
+
e = JSON.parse(i.value);
|
|
1079
|
+
} catch (e) {
|
|
1080
|
+
c.textContent = `Invalid JSON: ${e.message}`;
|
|
1081
|
+
return;
|
|
1082
|
+
}
|
|
1083
|
+
if (!Array.isArray(e) || !e.every((e) => e && typeof e == "object" && typeof e.type == "string")) {
|
|
1084
|
+
c.textContent = "hostContext must be an array of { type: string, ... } objects";
|
|
1085
|
+
return;
|
|
1086
|
+
}
|
|
1087
|
+
console.log("Simulator: hostContext changed, reloading...", e), a(e), window.location.reload();
|
|
1088
|
+
}), (r = e.getElement("#host-reset")) == null || r.addEventListener("click", () => {
|
|
1089
|
+
o(), window.location.reload();
|
|
1090
|
+
}));
|
|
1091
|
+
}
|
|
1092
|
+
};
|
|
1093
|
+
}
|
|
1094
|
+
/** Minimal HTML-escape so preset names can't break the simulator markup. */
|
|
1095
|
+
function R(e) {
|
|
1096
|
+
return e.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
1097
|
+
}
|
|
1098
|
+
var z = "puzzmo_sim_api_mode", B = "http://localhost:8911", V = "https://api.puzzmo.com", H = () => localStorage.getItem(z) === "dev" ? "dev" : "prod", he = (e) => {
|
|
1099
|
+
localStorage.setItem(z, e);
|
|
1100
|
+
}, U = null, ge = function() {
|
|
973
1101
|
var e = t(function* () {
|
|
974
|
-
if (
|
|
1102
|
+
if (U !== null) return U;
|
|
975
1103
|
try {
|
|
976
|
-
let e = new AbortController(), t = setTimeout(() => e.abort(), 1e3), n = yield fetch(`${
|
|
977
|
-
return clearTimeout(t),
|
|
1104
|
+
let e = new AbortController(), t = setTimeout(() => e.abort(), 1e3), n = yield fetch(`${B}/healthz`, { signal: e.signal });
|
|
1105
|
+
return clearTimeout(t), U = n.ok, U;
|
|
978
1106
|
} catch (e) {
|
|
979
|
-
return
|
|
1107
|
+
return U = !1, !1;
|
|
980
1108
|
}
|
|
981
1109
|
});
|
|
982
1110
|
return function() {
|
|
983
1111
|
return e.apply(this, arguments);
|
|
984
1112
|
};
|
|
985
|
-
}(),
|
|
986
|
-
apiURL:
|
|
1113
|
+
}(), W = () => ({
|
|
1114
|
+
apiURL: H() === "dev" ? B : V,
|
|
987
1115
|
clientID: "protosdk:oauthclient",
|
|
988
1116
|
redirectUri: `${window.location.origin}/oauth/callback`
|
|
989
|
-
}),
|
|
1117
|
+
}), _e = () => {
|
|
990
1118
|
let e = new Uint8Array(32);
|
|
991
1119
|
return crypto.getRandomValues(e), Array.from(e, (e) => e.toString(16).padStart(2, "0")).join("");
|
|
992
|
-
},
|
|
993
|
-
let e = localStorage.getItem(
|
|
1120
|
+
}, G = "puzzmo_sim_oauth_token", K = "puzzmo_sim_oauth_refresh_token", ve = (e) => localStorage.setItem(G, e), ye = (e) => localStorage.setItem(K, e), q = () => {
|
|
1121
|
+
let e = localStorage.getItem(G);
|
|
994
1122
|
return e && `${e.substring(0, 20)}`, e;
|
|
995
|
-
},
|
|
996
|
-
localStorage.removeItem(
|
|
997
|
-
},
|
|
998
|
-
let e =
|
|
1123
|
+
}, J = () => localStorage.getItem(K), Y = () => {
|
|
1124
|
+
localStorage.removeItem(G), localStorage.removeItem(K);
|
|
1125
|
+
}, be = () => {
|
|
1126
|
+
let e = W(), t = _e();
|
|
999
1127
|
sessionStorage.setItem("oauth_state", t), sessionStorage.setItem("oauth_return_url", window.location.href);
|
|
1000
1128
|
let n = new URL(`${e.apiURL}/oauth/auth`);
|
|
1001
1129
|
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();
|
|
1002
|
-
},
|
|
1130
|
+
}, xe = (e) => {
|
|
1003
1131
|
try {
|
|
1004
1132
|
let t = e.split(".");
|
|
1005
1133
|
if (t.length !== 3) return !0;
|
|
@@ -1008,11 +1136,11 @@ var I = "puzzmo_sim_api_mode", L = "http://localhost:8911", R = "https://api.puz
|
|
|
1008
1136
|
} catch (e) {
|
|
1009
1137
|
return !0;
|
|
1010
1138
|
}
|
|
1011
|
-
},
|
|
1139
|
+
}, Se = function() {
|
|
1012
1140
|
var e = t(function* () {
|
|
1013
|
-
let e =
|
|
1141
|
+
let e = J();
|
|
1014
1142
|
if (!e) return !1;
|
|
1015
|
-
let t =
|
|
1143
|
+
let t = W();
|
|
1016
1144
|
try {
|
|
1017
1145
|
let n = new URLSearchParams({
|
|
1018
1146
|
grant_type: "refresh_token",
|
|
@@ -1026,9 +1154,9 @@ var I = "puzzmo_sim_api_mode", L = "http://localhost:8911", R = "https://api.puz
|
|
|
1026
1154
|
if (!r.ok) return r.statusText, !1;
|
|
1027
1155
|
let i = yield r.json(), a = i.access_token || i.accessToken;
|
|
1028
1156
|
if (!a) return !1;
|
|
1029
|
-
|
|
1157
|
+
ve(a);
|
|
1030
1158
|
let o = i.refresh_token || i.refreshToken;
|
|
1031
|
-
return o &&
|
|
1159
|
+
return o && ye(o), !0;
|
|
1032
1160
|
} catch (e) {
|
|
1033
1161
|
return !1;
|
|
1034
1162
|
}
|
|
@@ -1036,9 +1164,9 @@ var I = "puzzmo_sim_api_mode", L = "http://localhost:8911", R = "https://api.puz
|
|
|
1036
1164
|
return function() {
|
|
1037
1165
|
return e.apply(this, arguments);
|
|
1038
1166
|
};
|
|
1039
|
-
}(),
|
|
1167
|
+
}(), Ce = function() {
|
|
1040
1168
|
var e = t(function* (e, t) {
|
|
1041
|
-
let n =
|
|
1169
|
+
let n = W(), r = sessionStorage.getItem("oauth_state");
|
|
1042
1170
|
if (!r || r !== t) return null;
|
|
1043
1171
|
sessionStorage.removeItem("oauth_state");
|
|
1044
1172
|
try {
|
|
@@ -1060,13 +1188,13 @@ var I = "puzzmo_sim_api_mode", L = "http://localhost:8911", R = "https://api.puz
|
|
|
1060
1188
|
return function(t, n) {
|
|
1061
1189
|
return e.apply(this, arguments);
|
|
1062
1190
|
};
|
|
1063
|
-
}(),
|
|
1191
|
+
}(), we = function() {
|
|
1064
1192
|
var e = t(function* (e, t = {}) {
|
|
1065
|
-
let n =
|
|
1193
|
+
let n = W(), r = q();
|
|
1066
1194
|
if (!r) throw Error("Not authenticated");
|
|
1067
|
-
if (
|
|
1068
|
-
if (r =
|
|
1069
|
-
} else throw
|
|
1195
|
+
if (xe(r)) if (yield Se()) {
|
|
1196
|
+
if (r = q(), !r) throw Error("Token refresh succeeded but no token available");
|
|
1197
|
+
} else throw Y(), Error("Session expired. Please log in again.");
|
|
1070
1198
|
let i = yield fetch(`${n.apiURL}/graphql`, {
|
|
1071
1199
|
method: "POST",
|
|
1072
1200
|
headers: {
|
|
@@ -1085,7 +1213,7 @@ var I = "puzzmo_sim_api_mode", L = "http://localhost:8911", R = "https://api.puz
|
|
|
1085
1213
|
return function(t) {
|
|
1086
1214
|
return e.apply(this, arguments);
|
|
1087
1215
|
};
|
|
1088
|
-
}(),
|
|
1216
|
+
}(), Te = (e) => {
|
|
1089
1217
|
try {
|
|
1090
1218
|
let t = e.split(".");
|
|
1091
1219
|
return t.length, t.length === 3 ? JSON.parse(atob(t[1])) : null;
|
|
@@ -1093,15 +1221,15 @@ var I = "puzzmo_sim_api_mode", L = "http://localhost:8911", R = "https://api.puz
|
|
|
1093
1221
|
return null;
|
|
1094
1222
|
}
|
|
1095
1223
|
};
|
|
1096
|
-
function
|
|
1224
|
+
function Ee() {
|
|
1097
1225
|
let e = !1;
|
|
1098
1226
|
return {
|
|
1099
1227
|
id: "auth",
|
|
1100
1228
|
label: "Auth",
|
|
1101
1229
|
render() {
|
|
1102
|
-
let e =
|
|
1230
|
+
let e = q(), t = !!e, n = H(), r = n === "dev" ? B : V, i = `<button class="simulator-btn tiny" id="auth-dev-toggle" style="display: none;">${n === "dev" ? "Using Dev" : "Dev"}</button>`;
|
|
1103
1231
|
if (t) {
|
|
1104
|
-
let t =
|
|
1232
|
+
let t = Te(e), n = t != null && t.exp ? (/* @__PURE__ */ new Date(t.exp * 1e3)).toLocaleString() : "Unknown", a = !!J(), o = a ? Te(J()) : null, s = o != null && o.exp ? (/* @__PURE__ */ new Date(o.exp * 1e3)).toLocaleString() : null;
|
|
1105
1233
|
return `
|
|
1106
1234
|
<div class="simulator-section">
|
|
1107
1235
|
<div class="simulator-section-title auth-title-row">
|
|
@@ -1142,7 +1270,7 @@ function Se() {
|
|
|
1142
1270
|
</div>
|
|
1143
1271
|
<p class="auth-description">
|
|
1144
1272
|
Login with your Puzzmo account to make authenticated API requests.
|
|
1145
|
-
${n === "dev" ? `<br><strong>Using local dev server:</strong> ${
|
|
1273
|
+
${n === "dev" ? `<br><strong>Using local dev server:</strong> ${B}` : ""}
|
|
1146
1274
|
</p>
|
|
1147
1275
|
<div class="simulator-row">
|
|
1148
1276
|
<button class="simulator-btn primary" id="auth-login">Login with Puzzmo</button>
|
|
@@ -1153,21 +1281,21 @@ function Se() {
|
|
|
1153
1281
|
},
|
|
1154
1282
|
bind(n) {
|
|
1155
1283
|
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");
|
|
1156
|
-
e ?
|
|
1157
|
-
e && c && (c.style.display = "",
|
|
1284
|
+
e ? U && c && (c.style.display = "", H() === "dev" && c.classList.add("active")) : (e = !0, ge().then((e) => {
|
|
1285
|
+
e && c && (c.style.display = "", H() === "dev" && c.classList.add("active"));
|
|
1158
1286
|
})), c == null || c.addEventListener("click", () => {
|
|
1159
|
-
|
|
1287
|
+
he(H() === "dev" ? "prod" : "dev"), Y(), window.location.reload();
|
|
1160
1288
|
}), r == null || r.addEventListener("click", () => {
|
|
1161
|
-
|
|
1289
|
+
be();
|
|
1162
1290
|
}), i == null || i.addEventListener("click", () => {
|
|
1163
|
-
|
|
1291
|
+
Y(), window.location.reload();
|
|
1164
1292
|
}), a == null || a.addEventListener("click", t(function* () {
|
|
1165
|
-
a.disabled = !0, a.textContent = "Refreshing...", (yield
|
|
1293
|
+
a.disabled = !0, a.textContent = "Refreshing...", (yield Se()) ? window.location.reload() : (a.textContent = "Refresh Failed", a.disabled = !1);
|
|
1166
1294
|
})), o == null || o.addEventListener("click", t(function* () {
|
|
1167
1295
|
if (s) {
|
|
1168
1296
|
s.innerHTML = "<div class=\"loading\">Loading...</div>";
|
|
1169
1297
|
try {
|
|
1170
|
-
let t = yield
|
|
1298
|
+
let t = yield we("\n query {\n currentUser {\n id\n username\n usernameID\n name\n }\n }\n ");
|
|
1171
1299
|
if (t.errors) {
|
|
1172
1300
|
var e;
|
|
1173
1301
|
s.innerHTML = `<div class="error">Error: ${((e = t.errors[0]) == null ? void 0 : e.message) || "Unknown error"}</div>`;
|
|
@@ -1189,13 +1317,13 @@ function Se() {
|
|
|
1189
1317
|
if (n && r) {
|
|
1190
1318
|
let t = e.getElement("#auth-status");
|
|
1191
1319
|
t && (t.innerHTML = "<span class=\"indicator waiting\"></span><span>Exchanging code...</span>");
|
|
1192
|
-
let i = yield
|
|
1320
|
+
let i = yield Ce(n, r);
|
|
1193
1321
|
if (window.history.replaceState({}, "", window.location.pathname), i) {
|
|
1194
1322
|
let e = i.access_token || i.accessToken;
|
|
1195
1323
|
if (e) {
|
|
1196
|
-
|
|
1324
|
+
ve(e);
|
|
1197
1325
|
let t = i.refresh_token || i.refreshToken;
|
|
1198
|
-
t &&
|
|
1326
|
+
t && ye(t);
|
|
1199
1327
|
}
|
|
1200
1328
|
window.location.reload();
|
|
1201
1329
|
} else {
|
|
@@ -1207,9 +1335,9 @@ function Se() {
|
|
|
1207
1335
|
}
|
|
1208
1336
|
};
|
|
1209
1337
|
}
|
|
1210
|
-
var
|
|
1211
|
-
localStorage.removeItem(
|
|
1212
|
-
},
|
|
1338
|
+
var De = "puzzmo_sim_api_mode", Oe = "http://localhost:8911", ke = "https://api.puzzmo.com", X = "puzzmo_sim_oauth_token", Ae = "puzzmo_sim_oauth_refresh_token", je = () => localStorage.getItem(De) === "dev" ? "dev" : "prod", Me = () => localStorage.getItem(X), Ne = () => localStorage.getItem(Ae), Pe = (e) => localStorage.setItem(X, e), Fe = (e) => localStorage.setItem(Ae, e), Ie = () => {
|
|
1339
|
+
localStorage.removeItem(X), localStorage.removeItem(Ae);
|
|
1340
|
+
}, Le = (e) => {
|
|
1213
1341
|
try {
|
|
1214
1342
|
let t = e.split(".");
|
|
1215
1343
|
if (t.length !== 3) return !0;
|
|
@@ -1218,11 +1346,11 @@ var Ce = "puzzmo_sim_api_mode", we = "http://localhost:8911", Te = "https://api.
|
|
|
1218
1346
|
} catch (e) {
|
|
1219
1347
|
return !0;
|
|
1220
1348
|
}
|
|
1221
|
-
},
|
|
1349
|
+
}, Re = function() {
|
|
1222
1350
|
var e = t(function* () {
|
|
1223
|
-
let e =
|
|
1351
|
+
let e = Ne();
|
|
1224
1352
|
if (!e) return !1;
|
|
1225
|
-
let t =
|
|
1353
|
+
let t = je() === "dev" ? Oe : ke;
|
|
1226
1354
|
try {
|
|
1227
1355
|
let n = new URLSearchParams({
|
|
1228
1356
|
grant_type: "refresh_token",
|
|
@@ -1236,9 +1364,9 @@ var Ce = "puzzmo_sim_api_mode", we = "http://localhost:8911", Te = "https://api.
|
|
|
1236
1364
|
if (!r.ok) return !1;
|
|
1237
1365
|
let i = yield r.json(), a = i.access_token || i.accessToken;
|
|
1238
1366
|
if (!a) return !1;
|
|
1239
|
-
|
|
1367
|
+
Pe(a);
|
|
1240
1368
|
let o = i.refresh_token || i.refreshToken;
|
|
1241
|
-
return o &&
|
|
1369
|
+
return o && Fe(o), !0;
|
|
1242
1370
|
} catch (e) {
|
|
1243
1371
|
return !1;
|
|
1244
1372
|
}
|
|
@@ -1246,13 +1374,13 @@ var Ce = "puzzmo_sim_api_mode", we = "http://localhost:8911", Te = "https://api.
|
|
|
1246
1374
|
return function() {
|
|
1247
1375
|
return e.apply(this, arguments);
|
|
1248
1376
|
};
|
|
1249
|
-
}(),
|
|
1377
|
+
}(), ze = function() {
|
|
1250
1378
|
var e = t(function* (e, t = {}) {
|
|
1251
|
-
let n =
|
|
1379
|
+
let n = je() === "dev" ? Oe : ke, r = Me();
|
|
1252
1380
|
if (!r) throw Error("Not authenticated");
|
|
1253
|
-
if (
|
|
1254
|
-
if (r =
|
|
1255
|
-
} else throw
|
|
1381
|
+
if (Le(r)) if (yield Re()) {
|
|
1382
|
+
if (r = Me(), !r) throw Error("Token refresh succeeded but no token available");
|
|
1383
|
+
} else throw Ie(), Error("Session expired. Please log in again.");
|
|
1256
1384
|
let i = yield fetch(`${n}/graphql`, {
|
|
1257
1385
|
method: "POST",
|
|
1258
1386
|
headers: {
|
|
@@ -1271,19 +1399,19 @@ var Ce = "puzzmo_sim_api_mode", we = "http://localhost:8911", Te = "https://api.
|
|
|
1271
1399
|
return function(t) {
|
|
1272
1400
|
return e.apply(this, arguments);
|
|
1273
1401
|
};
|
|
1274
|
-
}(),
|
|
1402
|
+
}(), Be = "\n query GameFeaturesQuery($slug: ID!) {\n game(id: $slug) {\n id\n slug\n displayName\n featuresArr\n gameFeatures {\n slug\n title\n features {\n featureID\n title\n isEnabled\n }\n }\n }\n }\n", Ve = "\n mutation ToggleFeatureMutation($gameSlug: ID!, $input: UpdateGameInput!) {\n updateGame(id: $gameSlug, input: $input) {\n id\n featuresArr\n gameFeatures {\n slug\n title\n features {\n featureID\n title\n isEnabled\n }\n }\n }\n }\n", He = (e, t) => {
|
|
1275
1403
|
let n = t - 1, r = Math.floor(n / 31), i = n % 31, a = [...e];
|
|
1276
1404
|
for (; a.length <= r;) a.push(0);
|
|
1277
1405
|
return a[r] = a[r] ^ 1 << i, a;
|
|
1278
1406
|
};
|
|
1279
|
-
const
|
|
1280
|
-
function
|
|
1407
|
+
const Ue = () => !!Me();
|
|
1408
|
+
function We() {
|
|
1281
1409
|
let n = null, r = !1, i = null, a = function() {
|
|
1282
1410
|
var e = t(function* (e) {
|
|
1283
1411
|
r = !0, i = null;
|
|
1284
1412
|
try {
|
|
1285
1413
|
var t;
|
|
1286
|
-
let r = yield
|
|
1414
|
+
let r = yield ze(Be, { slug: e });
|
|
1287
1415
|
if (r.errors) {
|
|
1288
1416
|
var a;
|
|
1289
1417
|
i = ((a = r.errors[0]) == null ? void 0 : a.message) || "Unknown error", n = null;
|
|
@@ -1300,10 +1428,10 @@ function Re() {
|
|
|
1300
1428
|
}(), o = function() {
|
|
1301
1429
|
var r = t(function* (t) {
|
|
1302
1430
|
if (!n) return;
|
|
1303
|
-
let r =
|
|
1431
|
+
let r = He(n.featuresArr, t);
|
|
1304
1432
|
try {
|
|
1305
1433
|
var i;
|
|
1306
|
-
let t = yield
|
|
1434
|
+
let t = yield ze(Ve, {
|
|
1307
1435
|
gameSlug: n.slug,
|
|
1308
1436
|
input: { featuresArr: r }
|
|
1309
1437
|
});
|
|
@@ -1351,7 +1479,7 @@ function Re() {
|
|
|
1351
1479
|
id: "features",
|
|
1352
1480
|
label: "Features",
|
|
1353
1481
|
render() {
|
|
1354
|
-
return
|
|
1482
|
+
return Ue() ? `
|
|
1355
1483
|
<div class="features-view-container">
|
|
1356
1484
|
<div class="simulator-section">
|
|
1357
1485
|
<div class="simulator-section-title">Game Features</div>
|
|
@@ -1392,7 +1520,7 @@ function Re() {
|
|
|
1392
1520
|
e && (yield d(e));
|
|
1393
1521
|
})), i == null || i.addEventListener("keypress", (e) => {
|
|
1394
1522
|
e.key === "Enter" && (r == null || r.click());
|
|
1395
|
-
}), console.log("[FeaturesView] bind called, ctx.gameSlug:", e.gameSlug, "slugInput:", i), e.gameSlug && i && (i.value = e.gameSlug,
|
|
1523
|
+
}), console.log("[FeaturesView] bind called, ctx.gameSlug:", e.gameSlug, "slugInput:", i), e.gameSlug && i && (i.value = e.gameSlug, Ue() && !n && d(e.gameSlug)), u();
|
|
1396
1524
|
},
|
|
1397
1525
|
onActivate(e) {
|
|
1398
1526
|
let t = e.getElement("#simulator-tab-features");
|
|
@@ -1401,7 +1529,7 @@ function Re() {
|
|
|
1401
1529
|
};
|
|
1402
1530
|
}
|
|
1403
1531
|
/** Renders a single keyboard key as an HTML button string */
|
|
1404
|
-
var
|
|
1532
|
+
var Ge = (e, t) => {
|
|
1405
1533
|
var n, r;
|
|
1406
1534
|
let i = (n = t.symbols[e]) == null ? e : n, a = t.disabled.includes(e), o = t.highlight.includes(e), s = t.xl.includes(e), c = t.l.includes(e), l = (r = t.flexGrowSymbols) == null ? void 0 : r.includes(e);
|
|
1407
1535
|
return `<button class="${[
|
|
@@ -1412,9 +1540,9 @@ var ze = (e, t) => {
|
|
|
1412
1540
|
c ? "l" : "",
|
|
1413
1541
|
l ? "grow" : ""
|
|
1414
1542
|
].filter(Boolean).join(" ")}" data-key="${e}" ${a ? "disabled" : ""}>${i}</button>`;
|
|
1415
|
-
},
|
|
1416
|
-
function
|
|
1417
|
-
let e = null, t = () => e ?
|
|
1543
|
+
}, Ke = (e) => `<div class="sim-kb">${e.layout.filter((e) => e != null).map((t) => `<div class="sim-kb-row">${[...t].map((t) => Ge(t, e)).join("")}</div>`).join("")}</div>`;
|
|
1544
|
+
function qe() {
|
|
1545
|
+
let e = null, t = () => e ? Ke(e) : "<div class=\"sim-kb-empty\">No keyboard config received from game yet.<br>The game calls <code>sdk.keyboard.show(config)</code> to display a keyboard.</div>";
|
|
1418
1546
|
return {
|
|
1419
1547
|
id: "kbd",
|
|
1420
1548
|
label: "Kbd",
|
|
@@ -1428,19 +1556,19 @@ function Ve() {
|
|
|
1428
1556
|
`;
|
|
1429
1557
|
},
|
|
1430
1558
|
bind(e) {
|
|
1431
|
-
|
|
1559
|
+
Je(e);
|
|
1432
1560
|
},
|
|
1433
1561
|
onMessage(n, r, i) {
|
|
1434
1562
|
var a;
|
|
1435
1563
|
if (n !== "KEYBOARD_UPDATE_CONFIG") return;
|
|
1436
1564
|
e = !(!(r == null || (a = r.layout) == null) && a.length) || r.layout.every((e) => !e) ? null : r;
|
|
1437
1565
|
let o = i.getElement("#sim-kb-content");
|
|
1438
|
-
o && (o.innerHTML = t(),
|
|
1566
|
+
o && (o.innerHTML = t(), Je(i)), i.updateBadge("kbd", void 0);
|
|
1439
1567
|
}
|
|
1440
1568
|
};
|
|
1441
1569
|
}
|
|
1442
1570
|
/** Attach click handlers to all rendered keys */
|
|
1443
|
-
function
|
|
1571
|
+
function Je(e) {
|
|
1444
1572
|
var t;
|
|
1445
1573
|
let n = (t = e.getElement("#sim-kb-content")) == null ? void 0 : t.querySelectorAll(".sim-kb-key");
|
|
1446
1574
|
n == null || n.forEach((t) => {
|
|
@@ -1455,15 +1583,15 @@ function He(e) {
|
|
|
1455
1583
|
* change values (persisted to localStorage and pushed to the game as SETTINGS_UPDATE, matching the
|
|
1456
1584
|
* production host) and reflects UPDATE_SETTINGS_FROM_EMBED writes coming from the game.
|
|
1457
1585
|
*/
|
|
1458
|
-
function
|
|
1586
|
+
function Ye() {
|
|
1459
1587
|
let t = (e) => {
|
|
1460
1588
|
let t = e.state.settingsComponents;
|
|
1461
|
-
return !t || t.length === 0 ? "<div class=\"sim-settings-empty\">No settings registered by the game yet.<br>The game calls <code>sdk.settings.initialize(components)</code> to describe its settings UI.</div>" : `<div class="sim-settings-form">${t.map((t) =>
|
|
1589
|
+
return !t || t.length === 0 ? "<div class=\"sim-settings-empty\">No settings registered by the game yet.<br>The game calls <code>sdk.settings.initialize(components)</code> to describe its settings UI.</div>" : `<div class="sim-settings-form">${t.map((t) => Xe(t, e.state.gameSettings)).join("")}</div><div class="sim-settings-actions"><button class="simulator-btn tiny" id="sim-settings-reset">Reset to defaults</button></div>`;
|
|
1462
1590
|
}, n = (e) => {
|
|
1463
1591
|
let n = e.getElement("#sim-settings-content");
|
|
1464
1592
|
n && (n.innerHTML = t(e), i(e));
|
|
1465
1593
|
}, r = (e) => {
|
|
1466
|
-
|
|
1594
|
+
m(e.state.gameSettings), e.sendToGame("SETTINGS_UPDATE", e.state.gameSettings);
|
|
1467
1595
|
}, i = (t) => {
|
|
1468
1596
|
var i;
|
|
1469
1597
|
let a = t.getElement("#sim-settings-content");
|
|
@@ -1479,7 +1607,7 @@ function Ue() {
|
|
|
1479
1607
|
});
|
|
1480
1608
|
}), (i = a.querySelector("#sim-settings-reset")) == null || i.addEventListener("click", () => {
|
|
1481
1609
|
var e;
|
|
1482
|
-
|
|
1610
|
+
h(), t.state.gameSettings = Ze((e = t.state.settingsComponents) == null ? [] : e), r(t), n(t);
|
|
1483
1611
|
}));
|
|
1484
1612
|
};
|
|
1485
1613
|
return {
|
|
@@ -1494,21 +1622,21 @@ function Ue() {
|
|
|
1494
1622
|
onMessage(t, r, i) {
|
|
1495
1623
|
if (t === "INITIALIZE_SETTINGS") {
|
|
1496
1624
|
var a;
|
|
1497
|
-
i.state.settingsComponents = (a = r == null ? void 0 : r.components) == null ? [] : a, i.state.gameSettings = e(e({}, r == null ? void 0 : r.settings), i.state.gameSettings),
|
|
1625
|
+
i.state.settingsComponents = (a = r == null ? void 0 : r.components) == null ? [] : a, i.state.gameSettings = e(e({}, r == null ? void 0 : r.settings), i.state.gameSettings), m(i.state.gameSettings), n(i);
|
|
1498
1626
|
return;
|
|
1499
1627
|
}
|
|
1500
|
-
t === "UPDATE_SETTINGS_FROM_EMBED" && (i.state.gameSettings = e(e({}, i.state.gameSettings), r == null ? void 0 : r.settings),
|
|
1628
|
+
t === "UPDATE_SETTINGS_FROM_EMBED" && (i.state.gameSettings = e(e({}, i.state.gameSettings), r == null ? void 0 : r.settings), m(i.state.gameSettings), n(i));
|
|
1501
1629
|
}
|
|
1502
1630
|
};
|
|
1503
1631
|
}
|
|
1504
1632
|
/** Renders a single settings UI component as HTML, reading its current value from `settings` */
|
|
1505
|
-
function
|
|
1633
|
+
function Xe(e, t) {
|
|
1506
1634
|
switch (e.type) {
|
|
1507
1635
|
case "title": return `<div class="sim-settings-heading">${Q(e.value)}</div>`;
|
|
1508
1636
|
case "subtitle": return `<div class="sim-settings-subheading">${Q(e.value)}</div>`;
|
|
1509
1637
|
case "paragraph": return `<p class="sim-settings-paragraph">${Q(e.value)}</p>`;
|
|
1510
1638
|
case "separator": return "<div class=\"simulator-divider\"></div>";
|
|
1511
|
-
case "split": return `<div class="sim-settings-split">${e.content.map((e) =>
|
|
1639
|
+
case "split": return `<div class="sim-settings-split">${e.content.map((e) => Xe(e, t)).join("")}</div>`;
|
|
1512
1640
|
case "boolean": {
|
|
1513
1641
|
var n;
|
|
1514
1642
|
let r = ((n = t[e.name]) == null ? e.defaultValue : n) ? "checked" : "", i = e.subtitle ? `<div class="sim-settings-subtitle">${Q(e.subtitle)}</div>` : "";
|
|
@@ -1576,9 +1704,9 @@ function Z(e) {
|
|
|
1576
1704
|
return `<span class="simulator-label">${Q(e.title)}</span>${t}`;
|
|
1577
1705
|
}
|
|
1578
1706
|
/** Collects name → defaultValue pairs from components, recursing into split groups */
|
|
1579
|
-
function
|
|
1707
|
+
function Ze(e) {
|
|
1580
1708
|
let t = {};
|
|
1581
|
-
for (let n of e) n.type === "split" ? Object.assign(t,
|
|
1709
|
+
for (let n of e) n.type === "split" ? Object.assign(t, Ze(n.content)) : "name" in n && (t[n.name] = n.defaultValue);
|
|
1582
1710
|
return t;
|
|
1583
1711
|
}
|
|
1584
1712
|
function Q(e) {
|
|
@@ -1622,34 +1750,35 @@ var $ = null;
|
|
|
1622
1750
|
* Fixtures are loaded as raw strings and passed to the game verbatim (any text format works; the game parses it).
|
|
1623
1751
|
* This will show dropdowns in the Ctrl tab to select category and puzzle.
|
|
1624
1752
|
*/
|
|
1625
|
-
function
|
|
1753
|
+
function Qe(e = {}) {
|
|
1626
1754
|
var n, r, i;
|
|
1627
1755
|
if (console.log("[Simulator] createSimulator called with config:", {
|
|
1628
1756
|
slug: e.slug,
|
|
1629
1757
|
hasFixtures: !!e.fixtures
|
|
1630
1758
|
}), $) return e.fixtures && (console.log("[Simulator] Instance already exists, updating fixtures"), $.updateFixtures(e.fixtures)), $;
|
|
1631
|
-
let a = (n = e.autoStart) == null ? !0 : n, o = e.fixtures ?
|
|
1632
|
-
|
|
1633
|
-
oe(),
|
|
1634
|
-
c,
|
|
1759
|
+
let a = (n = e.autoStart) == null ? !0 : n, o = e.fixtures ? oe(e.fixtures) : null, s = o ? Array.from(o.keys()).sort() : [], c = le(), l = fe(), u = [
|
|
1760
|
+
se(),
|
|
1635
1761
|
ce(),
|
|
1636
|
-
|
|
1637
|
-
|
|
1762
|
+
c,
|
|
1763
|
+
ue(),
|
|
1638
1764
|
de(),
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1765
|
+
l,
|
|
1766
|
+
pe(),
|
|
1767
|
+
me(e.hostContextPresets),
|
|
1768
|
+
Ee(),
|
|
1769
|
+
We(),
|
|
1770
|
+
qe(),
|
|
1771
|
+
Ye(),
|
|
1643
1772
|
...(r = e.views) == null ? [] : r
|
|
1644
|
-
],
|
|
1773
|
+
], d = u.map((e) => e.id), f = p(e, s, d), m = {
|
|
1645
1774
|
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>",
|
|
1646
1775
|
play: "<svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"currentColor\"><polygon points=\"2,1 9,5 2,9\"/></svg>",
|
|
1647
1776
|
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>",
|
|
1648
1777
|
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>",
|
|
1649
1778
|
minimize: "<svg width=\"10\" height=\"10\" viewBox=\"0 0 10 10\" fill=\"currentColor\"><rect x=\"1\" y=\"4\" width=\"8\" height=\"2\"/></svg>",
|
|
1650
1779
|
expand: "<svg width=\"8\" height=\"8\" viewBox=\"0 0 8 8\" fill=\"currentColor\"><polygon points=\"1,1 7,4 1,7\"/></svg>"
|
|
1651
|
-
},
|
|
1652
|
-
|
|
1780
|
+
}, h = document.createElement("div");
|
|
1781
|
+
h.id = "simulator", h.innerHTML = `
|
|
1653
1782
|
<style>
|
|
1654
1783
|
:root {
|
|
1655
1784
|
--sim-bg: #1a1a2e;
|
|
@@ -2886,15 +3015,15 @@ function Ke(e = {}) {
|
|
|
2886
3015
|
border-top: 2px solid var(--sim-border);
|
|
2887
3016
|
}
|
|
2888
3017
|
</style>
|
|
2889
|
-
<div id="simulator-panel" class="${
|
|
3018
|
+
<div id="simulator-panel" class="${f.isCollapsed ? "collapsed" : ""}">
|
|
2890
3019
|
<div id="simulator-header">
|
|
2891
3020
|
<span id="simulator-title">PUZZMO SIMULATOR</span>
|
|
2892
3021
|
<span class="header-sep">|</span>
|
|
2893
3022
|
<div id="simulator-timer">--:--</div>
|
|
2894
3023
|
<span class="header-sep">|</span>
|
|
2895
3024
|
<div id="simulator-header-controls">
|
|
2896
|
-
<button id="simulator-header-pause" class="header-icon-btn" title="Pause" disabled>${
|
|
2897
|
-
<button id="simulator-header-retry" class="header-icon-btn" title="Retry" disabled>${
|
|
3025
|
+
<button id="simulator-header-pause" class="header-icon-btn" title="Pause" disabled>${m.pause}</button>
|
|
3026
|
+
<button id="simulator-header-retry" class="header-icon-btn" title="Retry" disabled>${m.retry}</button>
|
|
2898
3027
|
</div>
|
|
2899
3028
|
<span class="header-sep">|</span>
|
|
2900
3029
|
<div id="simulator-header-status">
|
|
@@ -2902,106 +3031,106 @@ function Ke(e = {}) {
|
|
|
2902
3031
|
<span id="simulator-header-status-text">Waiting...</span>
|
|
2903
3032
|
</div>
|
|
2904
3033
|
<span class="header-spacer"></span>
|
|
2905
|
-
<button id="simulator-header-settings" class="header-icon-btn" title="Settings">${
|
|
2906
|
-
<button id="simulator-toggle" class="header-icon-btn" title="Minimize">${
|
|
3034
|
+
<button id="simulator-header-settings" class="header-icon-btn" title="Settings">${m.cog}</button>
|
|
3035
|
+
<button id="simulator-toggle" class="header-icon-btn" title="Minimize">${m.minimize}</button>
|
|
2907
3036
|
</div>
|
|
2908
3037
|
<div id="simulator-body">
|
|
2909
3038
|
<div id="simulator-tabs">
|
|
2910
|
-
${
|
|
3039
|
+
${u.filter((e) => e.id !== "auth").map((e) => `<button class="simulator-tab" data-tab="${e.id}">${e.label}<span class="simulator-tab-badge" data-badge="${e.id}"></span></button>`).join("")}
|
|
2911
3040
|
</div>
|
|
2912
3041
|
<div id="simulator-content" class="hidden">
|
|
2913
|
-
${
|
|
3042
|
+
${u.map((e) => `<div id="simulator-tab-${e.id}" class="simulator-tab-content">${e.render()}</div>`).join("")}
|
|
2914
3043
|
</div>
|
|
2915
3044
|
</div>
|
|
2916
3045
|
</div>
|
|
2917
|
-
`, document.body.appendChild(
|
|
2918
|
-
let
|
|
2919
|
-
|
|
2920
|
-
},
|
|
2921
|
-
let n =
|
|
2922
|
-
n && (n.textContent = e), r && (r.className = `indicator ${t}`, r.textContent = i),
|
|
2923
|
-
},
|
|
2924
|
-
t && t !== "0" ?
|
|
2925
|
-
},
|
|
3046
|
+
`, document.body.appendChild(h);
|
|
3047
|
+
let te = h.querySelector("#simulator-panel"), _ = h.querySelector("#simulator-header"), v = h.querySelector("#simulator-header-indicator"), ne = h.querySelector("#simulator-header-status-text"), y = h.querySelector("#simulator-header-pause"), b = h.querySelector("#simulator-header-retry"), x = h.querySelector("#simulator-header-settings"), S = h.querySelector("#simulator-toggle"), C = h.querySelector("#simulator-timer"), w = h.querySelector("#simulator-tabs"), T = h.querySelector("#simulator-content"), E = (e) => h.querySelector(e), D = (e) => {
|
|
3048
|
+
y.innerHTML = e ? m.play : m.pause, y.title = e ? "Resume" : "Pause";
|
|
3049
|
+
}, O = (e, t) => {
|
|
3050
|
+
let n = E("#simulator-status .text"), r = E("#simulator-status .indicator"), i = t === "complete" ? "✓" : "";
|
|
3051
|
+
n && (n.textContent = e), r && (r.className = `indicator ${t}`, r.textContent = i), v.className = t, v.textContent = i, ne.textContent = e;
|
|
3052
|
+
}, k = (e, t) => {
|
|
3053
|
+
t && t !== "0" ? C.innerHTML = `${e}<span class="penalty">+${t}</span>` : C.textContent = e;
|
|
3054
|
+
}, A = (e) => {
|
|
2926
3055
|
var t;
|
|
2927
|
-
|
|
3056
|
+
f.activeTab = e, T.classList.remove("hidden"), ee(e), w.querySelectorAll(".simulator-tab").forEach((t) => {
|
|
2928
3057
|
t.classList.toggle("active", t.getAttribute("data-tab") === e);
|
|
2929
|
-
}),
|
|
3058
|
+
}), h.querySelectorAll(".simulator-tab-content").forEach((t) => {
|
|
2930
3059
|
t.classList.toggle("active", t.id === `simulator-tab-${e}`);
|
|
2931
|
-
}),
|
|
2932
|
-
let n =
|
|
2933
|
-
n == null || (t = n.onActivate) == null || t.call(n,
|
|
2934
|
-
},
|
|
2935
|
-
|
|
2936
|
-
},
|
|
2937
|
-
l.updatePreview(
|
|
2938
|
-
},
|
|
3060
|
+
}), x.classList.toggle("active", e === "auth");
|
|
3061
|
+
let n = u.find((t) => t.id === e);
|
|
3062
|
+
n == null || (t = n.onActivate) == null || t.call(n, L);
|
|
3063
|
+
}, j = (e) => {
|
|
3064
|
+
f.isCollapsed = e, te.classList.toggle("collapsed", e), g(e), e ? (T.classList.add("hidden"), w.querySelectorAll(".simulator-tab").forEach((e) => e.classList.remove("active"))) : A(f.activeTab);
|
|
3065
|
+
}, M = () => {
|
|
3066
|
+
l.updatePreview(L);
|
|
3067
|
+
}, N = function() {
|
|
2939
3068
|
var e = t(function* () {
|
|
2940
3069
|
var e, t;
|
|
2941
|
-
if (
|
|
3070
|
+
if (f.puzzleData) return f.puzzleData;
|
|
2942
3071
|
if (!o || o.size === 0) throw Error("No fixtures configured. Add puzzle fixture files (.json or .toml) to a fixtures directory and pass fixturesGlob to the simulator.");
|
|
2943
|
-
let n = (e =
|
|
3072
|
+
let n = (e = f.selectedCategory) == null ? s[0] : e, r = n ? o.get(n) : void 0;
|
|
2944
3073
|
if (!r || r.size === 0) throw Error(`No puzzles found in fixture category "${n}"`);
|
|
2945
|
-
let i = (t =
|
|
3074
|
+
let i = (t = f.selectedPuzzle) == null ? r.keys().next().value : t, a = i ? r.get(i) : void 0;
|
|
2946
3075
|
if (!a) throw Error(`Puzzle "${i}" not found in category "${n}"`);
|
|
2947
|
-
|
|
3076
|
+
f.puzzleData = a, console.log("Simulator: Puzzle loaded from fixtures", {
|
|
2948
3077
|
category: n,
|
|
2949
3078
|
puzzle: i
|
|
2950
|
-
}),
|
|
2951
|
-
let c =
|
|
2952
|
-
return c && (c.value =
|
|
3079
|
+
}), f.originalPuzzle = a;
|
|
3080
|
+
let c = E("#simulator-puzzle");
|
|
3081
|
+
return c && (c.value = f.originalPuzzle), f.activeTab === "thumb" && M(), f.puzzleData;
|
|
2953
3082
|
});
|
|
2954
3083
|
return function() {
|
|
2955
3084
|
return e.apply(this, arguments);
|
|
2956
3085
|
};
|
|
2957
|
-
}(),
|
|
2958
|
-
c.addLogEntry(e,
|
|
2959
|
-
}),
|
|
2960
|
-
|
|
2961
|
-
},
|
|
2962
|
-
let n =
|
|
3086
|
+
}(), P = re((e) => {
|
|
3087
|
+
c.addLogEntry(e, L);
|
|
3088
|
+
}), F = (e, t) => {
|
|
3089
|
+
ie(e, t, P);
|
|
3090
|
+
}, I = (e, t) => {
|
|
3091
|
+
let n = h.querySelector(`[data-badge="${e}"]`);
|
|
2963
3092
|
n && (n.textContent = t && t > 0 ? String(t) : "");
|
|
2964
|
-
},
|
|
2965
|
-
state:
|
|
2966
|
-
getElement:
|
|
2967
|
-
sendToGame:
|
|
2968
|
-
logMessage:
|
|
2969
|
-
loadPuzzle:
|
|
2970
|
-
updateStatus:
|
|
2971
|
-
updateTimer:
|
|
2972
|
-
setCollapsed:
|
|
2973
|
-
switchTab:
|
|
2974
|
-
updateThumbnail:
|
|
2975
|
-
updateBadge:
|
|
3093
|
+
}, L = {
|
|
3094
|
+
state: f,
|
|
3095
|
+
getElement: E,
|
|
3096
|
+
sendToGame: F,
|
|
3097
|
+
logMessage: P.log,
|
|
3098
|
+
loadPuzzle: N,
|
|
3099
|
+
updateStatus: O,
|
|
3100
|
+
updateTimer: k,
|
|
3101
|
+
setCollapsed: j,
|
|
3102
|
+
switchTab: A,
|
|
3103
|
+
updateThumbnail: M,
|
|
3104
|
+
updateBadge: I,
|
|
2976
3105
|
fixtures: o,
|
|
2977
3106
|
fixtureCategories: s,
|
|
2978
3107
|
gameSlug: (i = e.slug) == null ? null : i
|
|
2979
3108
|
};
|
|
2980
|
-
console.log("[Simulator] Context created with gameSlug:",
|
|
3109
|
+
console.log("[Simulator] Context created with gameSlug:", L.gameSlug), u.forEach((e) => e.bind(L)), w.querySelectorAll(".simulator-tab").forEach((e) => {
|
|
2981
3110
|
e.addEventListener("click", () => {
|
|
2982
3111
|
let t = e.getAttribute("data-tab");
|
|
2983
|
-
|
|
3112
|
+
A(t), I(t, 0);
|
|
2984
3113
|
});
|
|
2985
|
-
}), w.addEventListener("click", (e) => {
|
|
2986
|
-
e.stopPropagation(), N(!0);
|
|
2987
|
-
}), x.addEventListener("click", (e) => {
|
|
2988
|
-
e.stopPropagation(), h.isPaused ? (L("RESUME_GAME", {}), h.isPaused = !1, k(!1), A("Running", "ready")) : (L("PAUSE_GAME", {}), h.isPaused = !0, k(!0), A("Paused", "paused"));
|
|
2989
|
-
let t = O("#simulator-pause");
|
|
2990
|
-
t && (t.textContent = h.isPaused ? "Resume" : "Pause");
|
|
2991
3114
|
}), S.addEventListener("click", (e) => {
|
|
2992
|
-
e.stopPropagation(),
|
|
2993
|
-
let t = O("#simulator-pause"), n = O("#simulator-start");
|
|
2994
|
-
t && (t.disabled = !0, t.textContent = "Pause"), n && (n.textContent = "Start");
|
|
2995
|
-
}), C.addEventListener("click", (e) => {
|
|
2996
|
-
e.stopPropagation(), h.isCollapsed && N(!1), M("auth");
|
|
3115
|
+
e.stopPropagation(), j(!0);
|
|
2997
3116
|
}), y.addEventListener("click", (e) => {
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3002
|
-
|
|
3117
|
+
e.stopPropagation(), f.isPaused ? (F("RESUME_GAME", {}), f.isPaused = !1, D(!1), O("Running", "ready")) : (F("PAUSE_GAME", {}), f.isPaused = !0, D(!0), O("Paused", "paused"));
|
|
3118
|
+
let t = E("#simulator-pause");
|
|
3119
|
+
t && (t.textContent = f.isPaused ? "Resume" : "Pause");
|
|
3120
|
+
}), b.addEventListener("click", (e) => {
|
|
3121
|
+
e.stopPropagation(), F("RETRY_PUZZLE", {}), f.hasStarted = !1, f.isPaused = !1, D(!1), y.disabled = !0, O("Ready to retry", "ready");
|
|
3122
|
+
let t = E("#simulator-pause"), n = E("#simulator-start");
|
|
3123
|
+
t && (t.disabled = !0, t.textContent = "Pause"), n && (n.textContent = "Start");
|
|
3124
|
+
}), x.addEventListener("click", (e) => {
|
|
3125
|
+
e.stopPropagation(), f.isCollapsed && j(!1), A("auth");
|
|
3126
|
+
}), _.addEventListener("click", (e) => {
|
|
3127
|
+
f.isCollapsed && e.target !== S && j(!1);
|
|
3128
|
+
}), f.isCollapsed || A(f.activeTab);
|
|
3129
|
+
let R = new URLSearchParams(window.location.search);
|
|
3130
|
+
(R.has("code") || R.has("error")) && (j(!1), A("auth"));
|
|
3131
|
+
let z = (e) => ({
|
|
3003
3132
|
userState: {
|
|
3004
|
-
gameSettings:
|
|
3133
|
+
gameSettings: f.gameSettings,
|
|
3005
3134
|
id: "simulator-user",
|
|
3006
3135
|
ownerID: "simulator-owner"
|
|
3007
3136
|
},
|
|
@@ -3016,7 +3145,7 @@ function Ke(e = {}) {
|
|
|
3016
3145
|
},
|
|
3017
3146
|
startOrFindGameplay: { gamePlayed: {
|
|
3018
3147
|
additionalTimeAddedSecs: 0,
|
|
3019
|
-
boardState:
|
|
3148
|
+
boardState: f.currentInputStr,
|
|
3020
3149
|
combinedTimeSecs: 0,
|
|
3021
3150
|
completed: !1,
|
|
3022
3151
|
createdAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
@@ -3038,49 +3167,45 @@ function Ke(e = {}) {
|
|
|
3038
3167
|
mostRecentDaily: null
|
|
3039
3168
|
}
|
|
3040
3169
|
} },
|
|
3041
|
-
theme:
|
|
3042
|
-
hostContext:
|
|
3043
|
-
type: "app",
|
|
3044
|
-
layout: "desktop",
|
|
3045
|
-
host: null
|
|
3046
|
-
}],
|
|
3170
|
+
theme: f.selectedTheme,
|
|
3171
|
+
hostContext: f.hostContext,
|
|
3047
3172
|
appRuntimeContract: "1.0"
|
|
3048
|
-
}),
|
|
3173
|
+
}), B = function() {
|
|
3049
3174
|
var e = t(function* () {
|
|
3050
|
-
|
|
3175
|
+
O("Loading puzzle...", "waiting");
|
|
3051
3176
|
try {
|
|
3052
|
-
let e =
|
|
3053
|
-
|
|
3177
|
+
let e = z(yield N());
|
|
3178
|
+
O("Sending READY_DATA...", "waiting"), F("READY_DATA", e), O("Waiting for game to load...", "waiting");
|
|
3054
3179
|
} catch (e) {
|
|
3055
|
-
|
|
3180
|
+
O(`Error: ${e}`, "paused");
|
|
3056
3181
|
}
|
|
3057
3182
|
});
|
|
3058
3183
|
return function() {
|
|
3059
3184
|
return e.apply(this, arguments);
|
|
3060
3185
|
};
|
|
3061
|
-
}(),
|
|
3062
|
-
console.log("Simulator: Game loaded, ready to start"),
|
|
3186
|
+
}(), V = () => {
|
|
3187
|
+
console.log("Simulator: Game loaded, ready to start"), b.disabled = !1, u.forEach((e) => {
|
|
3063
3188
|
var t;
|
|
3064
|
-
return (t = e.onMessage) == null ? void 0 : t.call(e, "READY_GAME_LOADED", void 0,
|
|
3065
|
-
}), a && !
|
|
3066
|
-
let e =
|
|
3067
|
-
e == null || e.click(),
|
|
3189
|
+
return (t = e.onMessage) == null ? void 0 : t.call(e, "READY_GAME_LOADED", void 0, L);
|
|
3190
|
+
}), a && !f.hasStarted && setTimeout(() => {
|
|
3191
|
+
let e = E("#simulator-start");
|
|
3192
|
+
e == null || e.click(), y.disabled = !1, f.hasStarted = !0, O("Running", "ready");
|
|
3068
3193
|
}, 100);
|
|
3069
3194
|
};
|
|
3070
|
-
return
|
|
3195
|
+
return ae((e, t) => {
|
|
3071
3196
|
var n, r;
|
|
3072
3197
|
if (e === "READY") {
|
|
3073
|
-
console.log("Simulator: Received READY from game"),
|
|
3198
|
+
console.log("Simulator: Received READY from game"), B();
|
|
3074
3199
|
return;
|
|
3075
3200
|
}
|
|
3076
3201
|
if (e === "READY_GAME_LOADED") {
|
|
3077
|
-
|
|
3202
|
+
V();
|
|
3078
3203
|
return;
|
|
3079
3204
|
}
|
|
3080
3205
|
if (e === "TIMER_TICK") {
|
|
3081
3206
|
if (t != null && t.display) {
|
|
3082
3207
|
let [e, n] = t.display;
|
|
3083
|
-
|
|
3208
|
+
k(e, n);
|
|
3084
3209
|
}
|
|
3085
3210
|
return;
|
|
3086
3211
|
}
|
|
@@ -3089,30 +3214,30 @@ function Ke(e = {}) {
|
|
|
3089
3214
|
console.log("Simulator: Sidebar update", t);
|
|
3090
3215
|
return;
|
|
3091
3216
|
}
|
|
3092
|
-
|
|
3217
|
+
u.forEach((n) => {
|
|
3093
3218
|
var r;
|
|
3094
|
-
return (r = n.onMessage) == null ? void 0 : r.call(n, e, t,
|
|
3219
|
+
return (r = n.onMessage) == null ? void 0 : r.call(n, e, t, L);
|
|
3095
3220
|
});
|
|
3096
3221
|
let i = (n = t == null || (r = t.input) == null ? void 0 : r.boardState) == null ? t == null ? void 0 : t.boardState : n;
|
|
3097
|
-
e === "UPLOAD_NEW_GAME_STATE" && i && (
|
|
3098
|
-
},
|
|
3222
|
+
e === "UPLOAD_NEW_GAME_STATE" && i && (f.currentInputStr = i, f.activeTab === "thumb" && M(), console.log("Simulator: Game state uploaded", t)), e === "GAME_COMPLETED" && (console.log("Simulator: Game completed!", t), y.disabled = !0, f.hasStarted = !1, O("Completed!", "complete"));
|
|
3223
|
+
}, P), console.log("Simulator initialized"), $ = {
|
|
3099
3224
|
updateFixtures: (e) => {
|
|
3100
|
-
o =
|
|
3225
|
+
o = oe(e), s = Array.from(o.keys()).sort(), L.fixtures = o, L.fixtureCategories = s;
|
|
3101
3226
|
let t = localStorage.getItem("simulator-fixture-category");
|
|
3102
|
-
if (!
|
|
3227
|
+
if (!f.selectedCategory || !s.includes(f.selectedCategory)) {
|
|
3103
3228
|
var n;
|
|
3104
|
-
|
|
3229
|
+
f.selectedCategory = t && s.includes(t) ? t : (n = s[0]) == null ? null : n;
|
|
3105
3230
|
}
|
|
3106
|
-
let r =
|
|
3107
|
-
r == null || r.bind(
|
|
3231
|
+
let r = u.find((e) => e.id === "ctrl");
|
|
3232
|
+
r == null || r.bind(L), console.log("Simulator: Fixtures updated", {
|
|
3108
3233
|
categories: s,
|
|
3109
|
-
selectedCategory:
|
|
3234
|
+
selectedCategory: f.selectedCategory
|
|
3110
3235
|
});
|
|
3111
3236
|
},
|
|
3112
|
-
sendToGame:
|
|
3113
|
-
loadPuzzle:
|
|
3237
|
+
sendToGame: F,
|
|
3238
|
+
loadPuzzle: N
|
|
3114
3239
|
}, $;
|
|
3115
3240
|
}
|
|
3116
|
-
export {
|
|
3241
|
+
export { Qe as t };
|
|
3117
3242
|
|
|
3118
|
-
//# sourceMappingURL=createSimulator-
|
|
3243
|
+
//# sourceMappingURL=createSimulator-Bo6J_KC_.js.map
|