1681-engine 0.5.9 → 0.6.0

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 (210) hide show
  1. package/CHANGELOG.md +92 -1
  2. package/README.md +15 -6
  3. package/dist/1681-engine.js +588 -465
  4. package/dist/ai/behaviorTree.js +198 -0
  5. package/dist/ai/buildTree.js +54 -0
  6. package/dist/ambient/life/Birds.js +73 -0
  7. package/dist/ambient/life/Butterflies.js +43 -0
  8. package/dist/ambient/life/ChimneySmoke.js +50 -0
  9. package/dist/ambient/life/Drift.js +75 -0
  10. package/dist/ambient/life/Fireflies.js +52 -0
  11. package/dist/ambient/life/lifeMotion.js +49 -0
  12. package/dist/assets/AssetLoader.js +115 -70
  13. package/dist/assets/Prepainter.js +61 -0
  14. package/dist/assets/workerPainter.js +39 -0
  15. package/dist/audio/spatial.js +118 -0
  16. package/dist/cjs/electron/electronLike.d.ts +55 -0
  17. package/dist/cjs/electron/electronLike.js +7 -0
  18. package/dist/cjs/electron/index.d.ts +14 -0
  19. package/dist/cjs/electron/index.js +20 -0
  20. package/dist/cjs/electron/lockdown.d.ts +33 -0
  21. package/dist/cjs/electron/lockdown.js +69 -0
  22. package/dist/cjs/electron/lockdownRules.d.ts +28 -0
  23. package/dist/cjs/electron/lockdownRules.js +61 -0
  24. package/dist/cjs/electron/sessionStore.d.ts +40 -0
  25. package/dist/cjs/electron/sessionStore.js +77 -0
  26. package/dist/cjs/electron/shellId.d.ts +22 -0
  27. package/dist/cjs/electron/shellId.js +31 -0
  28. package/dist/cjs/electron/webFiles.d.ts +13 -0
  29. package/dist/cjs/electron/webFiles.js +52 -0
  30. package/dist/cjs/electron/webPatcher.d.ts +83 -0
  31. package/dist/cjs/electron/webPatcher.js +223 -0
  32. package/dist/cjs/electron/webPointers.d.ts +19 -0
  33. package/dist/cjs/electron/webPointers.js +35 -0
  34. package/dist/cjs/package.json +1 -0
  35. package/dist/cjs/updates/index.d.ts +8 -0
  36. package/dist/cjs/updates/index.js +21 -0
  37. package/dist/cjs/updates/manifest.d.ts +73 -0
  38. package/dist/cjs/updates/manifest.js +67 -0
  39. package/dist/cjs/updates/pickUpdate.d.ts +42 -0
  40. package/dist/cjs/updates/pickUpdate.js +52 -0
  41. package/dist/cjs/updates/webPlan.d.ts +20 -0
  42. package/dist/cjs/updates/webPlan.js +34 -0
  43. package/dist/dialogue/DialogueRunner.js +173 -0
  44. package/dist/dialogue/expr.js +137 -0
  45. package/dist/dialogue/validateDialogue.js +52 -0
  46. package/dist/ecs/prefab.js +94 -0
  47. package/dist/electron/lockdown.js +31 -0
  48. package/dist/electron/lockdownRules.js +42 -0
  49. package/dist/electron/sessionStore.js +48 -0
  50. package/dist/electron/shellId.js +18 -0
  51. package/dist/electron/webFiles.js +36 -0
  52. package/dist/electron/webPatcher.js +153 -0
  53. package/dist/electron/webPointers.js +25 -0
  54. package/dist/electron.js +19 -0
  55. package/dist/input/Actions.js +58 -27
  56. package/dist/input/InputCapture.js +98 -0
  57. package/dist/input/Keymap.js +32 -26
  58. package/dist/input/haptics.js +50 -0
  59. package/dist/input/inputTape.js +68 -0
  60. package/dist/mobile/backButton.js +40 -0
  61. package/dist/mobile/capacitor.js +48 -0
  62. package/dist/mobile/screen.js +31 -0
  63. package/dist/mobile.js +12 -0
  64. package/dist/nav/flowField.js +58 -0
  65. package/dist/nav/steering.js +77 -0
  66. package/dist/net/ApiClient.js +96 -0
  67. package/dist/net/InterpolationBuffer.js +30 -23
  68. package/dist/net/LagCompensator.js +100 -0
  69. package/dist/net/Room.js +122 -43
  70. package/dist/net/RoomHost.js +13 -4
  71. package/dist/net/SpatialHash.js +66 -0
  72. package/dist/pixel/lifeArt.js +83 -0
  73. package/dist/pixel.js +63 -58
  74. package/dist/react/ConfirmButton.js +24 -0
  75. package/dist/react/baseCss.js +1 -0
  76. package/dist/react/labels.js +7 -6
  77. package/dist/react/useJsonSelector.js +13 -0
  78. package/dist/react.js +73 -68
  79. package/dist/tilemap/TilemapView.js +57 -32
  80. package/dist/tilemap/autotile.js +103 -0
  81. package/dist/tilemap/collision.js +29 -18
  82. package/dist/tilemap/ldtk.js +21 -0
  83. package/dist/tilemap/ldtkParse.js +191 -0
  84. package/dist/types/ai/behaviorTree.d.ts +133 -0
  85. package/dist/types/ai/behaviorTree.d.ts.map +1 -0
  86. package/dist/types/ai/buildTree.d.ts +55 -0
  87. package/dist/types/ai/buildTree.d.ts.map +1 -0
  88. package/dist/types/ambient/life/Birds.d.ts +50 -0
  89. package/dist/types/ambient/life/Birds.d.ts.map +1 -0
  90. package/dist/types/ambient/life/Butterflies.d.ts +32 -0
  91. package/dist/types/ambient/life/Butterflies.d.ts.map +1 -0
  92. package/dist/types/ambient/life/ChimneySmoke.d.ts +37 -0
  93. package/dist/types/ambient/life/ChimneySmoke.d.ts.map +1 -0
  94. package/dist/types/ambient/life/Drift.d.ts +58 -0
  95. package/dist/types/ambient/life/Drift.d.ts.map +1 -0
  96. package/dist/types/ambient/life/Fireflies.d.ts +43 -0
  97. package/dist/types/ambient/life/Fireflies.d.ts.map +1 -0
  98. package/dist/types/ambient/life/lifeMotion.d.ts +63 -0
  99. package/dist/types/ambient/life/lifeMotion.d.ts.map +1 -0
  100. package/dist/types/assets/AssetLoader.d.ts +20 -0
  101. package/dist/types/assets/AssetLoader.d.ts.map +1 -1
  102. package/dist/types/assets/Prepainter.d.ts +64 -0
  103. package/dist/types/assets/Prepainter.d.ts.map +1 -0
  104. package/dist/types/assets/workerPainter.d.ts +21 -0
  105. package/dist/types/assets/workerPainter.d.ts.map +1 -0
  106. package/dist/types/audio/spatial.d.ts +107 -0
  107. package/dist/types/audio/spatial.d.ts.map +1 -0
  108. package/dist/types/dialogue/DialogueRunner.d.ts +78 -0
  109. package/dist/types/dialogue/DialogueRunner.d.ts.map +1 -0
  110. package/dist/types/dialogue/expr.d.ts +12 -0
  111. package/dist/types/dialogue/expr.d.ts.map +1 -0
  112. package/dist/types/dialogue/script.d.ts +78 -0
  113. package/dist/types/dialogue/script.d.ts.map +1 -0
  114. package/dist/types/dialogue/validateDialogue.d.ts +21 -0
  115. package/dist/types/dialogue/validateDialogue.d.ts.map +1 -0
  116. package/dist/types/ecs/prefab.d.ts +84 -0
  117. package/dist/types/ecs/prefab.d.ts.map +1 -0
  118. package/dist/types/electron/electronLike.d.ts +56 -0
  119. package/dist/types/electron/electronLike.d.ts.map +1 -0
  120. package/dist/types/electron/index.d.ts +15 -0
  121. package/dist/types/electron/index.d.ts.map +1 -0
  122. package/dist/types/electron/lockdown.d.ts +34 -0
  123. package/dist/types/electron/lockdown.d.ts.map +1 -0
  124. package/dist/types/electron/lockdownRules.d.ts +29 -0
  125. package/dist/types/electron/lockdownRules.d.ts.map +1 -0
  126. package/dist/types/electron/sessionStore.d.ts +41 -0
  127. package/dist/types/electron/sessionStore.d.ts.map +1 -0
  128. package/dist/types/electron/shellId.d.ts +23 -0
  129. package/dist/types/electron/shellId.d.ts.map +1 -0
  130. package/dist/types/electron/webFiles.d.ts +14 -0
  131. package/dist/types/electron/webFiles.d.ts.map +1 -0
  132. package/dist/types/electron/webPatcher.d.ts +84 -0
  133. package/dist/types/electron/webPatcher.d.ts.map +1 -0
  134. package/dist/types/electron/webPointers.d.ts +20 -0
  135. package/dist/types/electron/webPointers.d.ts.map +1 -0
  136. package/dist/types/index.d.ts +30 -3
  137. package/dist/types/index.d.ts.map +1 -1
  138. package/dist/types/input/Actions.d.ts +14 -0
  139. package/dist/types/input/Actions.d.ts.map +1 -1
  140. package/dist/types/input/InputCapture.d.ts +53 -0
  141. package/dist/types/input/InputCapture.d.ts.map +1 -0
  142. package/dist/types/input/Keymap.d.ts +12 -6
  143. package/dist/types/input/Keymap.d.ts.map +1 -1
  144. package/dist/types/input/haptics.d.ts +42 -0
  145. package/dist/types/input/haptics.d.ts.map +1 -0
  146. package/dist/types/input/inputTape.d.ts +66 -0
  147. package/dist/types/input/inputTape.d.ts.map +1 -0
  148. package/dist/types/mobile/backButton.d.ts +30 -0
  149. package/dist/types/mobile/backButton.d.ts.map +1 -0
  150. package/dist/types/mobile/capacitor.d.ts +62 -0
  151. package/dist/types/mobile/capacitor.d.ts.map +1 -0
  152. package/dist/types/mobile/index.d.ts +4 -0
  153. package/dist/types/mobile/index.d.ts.map +1 -0
  154. package/dist/types/mobile/screen.d.ts +27 -0
  155. package/dist/types/mobile/screen.d.ts.map +1 -0
  156. package/dist/types/nav/flowField.d.ts +31 -0
  157. package/dist/types/nav/flowField.d.ts.map +1 -0
  158. package/dist/types/nav/steering.d.ts +47 -0
  159. package/dist/types/nav/steering.d.ts.map +1 -0
  160. package/dist/types/net/ApiClient.d.ts +74 -0
  161. package/dist/types/net/ApiClient.d.ts.map +1 -0
  162. package/dist/types/net/InterpolationBuffer.d.ts +5 -0
  163. package/dist/types/net/InterpolationBuffer.d.ts.map +1 -1
  164. package/dist/types/net/LagCompensator.d.ts +70 -0
  165. package/dist/types/net/LagCompensator.d.ts.map +1 -0
  166. package/dist/types/net/Room.d.ts +72 -3
  167. package/dist/types/net/Room.d.ts.map +1 -1
  168. package/dist/types/net/RoomHost.d.ts +8 -3
  169. package/dist/types/net/RoomHost.d.ts.map +1 -1
  170. package/dist/types/net/SpatialHash.d.ts +25 -0
  171. package/dist/types/net/SpatialHash.d.ts.map +1 -0
  172. package/dist/types/pixel/index.d.ts +1 -0
  173. package/dist/types/pixel/index.d.ts.map +1 -1
  174. package/dist/types/pixel/lifeArt.d.ts +63 -0
  175. package/dist/types/pixel/lifeArt.d.ts.map +1 -0
  176. package/dist/types/react/ConfirmButton.d.ts +26 -0
  177. package/dist/types/react/ConfirmButton.d.ts.map +1 -0
  178. package/dist/types/react/baseCss.d.ts +1 -1
  179. package/dist/types/react/baseCss.d.ts.map +1 -1
  180. package/dist/types/react/index.d.ts +2 -0
  181. package/dist/types/react/index.d.ts.map +1 -1
  182. package/dist/types/react/labels.d.ts +2 -0
  183. package/dist/types/react/labels.d.ts.map +1 -1
  184. package/dist/types/react/useJsonSelector.d.ts +13 -0
  185. package/dist/types/react/useJsonSelector.d.ts.map +1 -0
  186. package/dist/types/tilemap/TilemapView.d.ts +17 -0
  187. package/dist/types/tilemap/TilemapView.d.ts.map +1 -1
  188. package/dist/types/tilemap/autotile.d.ts +95 -0
  189. package/dist/types/tilemap/autotile.d.ts.map +1 -0
  190. package/dist/types/tilemap/collision.d.ts +8 -0
  191. package/dist/types/tilemap/collision.d.ts.map +1 -1
  192. package/dist/types/tilemap/ldtk.d.ts +97 -0
  193. package/dist/types/tilemap/ldtk.d.ts.map +1 -0
  194. package/dist/types/tilemap/ldtkParse.d.ts +26 -0
  195. package/dist/types/tilemap/ldtkParse.d.ts.map +1 -0
  196. package/dist/types/ui/ScrollView.d.ts.map +1 -1
  197. package/dist/types/updates/index.d.ts +9 -0
  198. package/dist/types/updates/index.d.ts.map +1 -0
  199. package/dist/types/updates/manifest.d.ts +74 -0
  200. package/dist/types/updates/manifest.d.ts.map +1 -0
  201. package/dist/types/updates/pickUpdate.d.ts +43 -0
  202. package/dist/types/updates/pickUpdate.d.ts.map +1 -0
  203. package/dist/types/updates/webPlan.d.ts +21 -0
  204. package/dist/types/updates/webPlan.d.ts.map +1 -0
  205. package/dist/ui/ScrollView.js +10 -8
  206. package/dist/updates/manifest.js +35 -0
  207. package/dist/updates/pickUpdate.js +27 -0
  208. package/dist/updates/webPlan.js +14 -0
  209. package/dist/updates.js +15 -0
  210. package/package.json +35 -3
@@ -0,0 +1,173 @@
1
+ import { expr as u } from "./expr.js";
2
+ const f = 1e3;
3
+ class d {
4
+ constructor(t, s = {}) {
5
+ this.script = t, this.options = s, this.vars = s.vars ?? {};
6
+ const i = s.functions ?? {};
7
+ this.scope = {
8
+ get: (e) => l(this.vars, e),
9
+ call: (e, n) => {
10
+ if (e === "visited") return this.visits.get(String(n[0])) ?? 0;
11
+ if (e === "chose") return this.chosen.has(`${n[0]}#${n[1]}`);
12
+ const o = i[e];
13
+ if (!o) throw new Error(`dialogue: no function '${e}'`);
14
+ return o(...n);
15
+ }
16
+ };
17
+ }
18
+ script;
19
+ options;
20
+ vars;
21
+ node = null;
22
+ line = 0;
23
+ step = { type: "end" };
24
+ visits = /* @__PURE__ */ new Map();
25
+ chosen = /* @__PURE__ */ new Set();
26
+ scope;
27
+ /** The step showing now. */
28
+ get current() {
29
+ return this.step;
30
+ }
31
+ /** The node the dialogue is in, or null once it has ended. */
32
+ get at() {
33
+ return this.node;
34
+ }
35
+ /** How many times a node was entered. */
36
+ visited(t) {
37
+ return this.visits.get(t) ?? 0;
38
+ }
39
+ /** Begins at `node` (default the script's `start`, else its first node). */
40
+ start(t = this.script.start ?? Object.keys(this.script.nodes)[0]) {
41
+ return t === void 0 ? this.finish() : this.go(t);
42
+ }
43
+ /** The line showing was read: on to the next line, the choices, or wherever the node leads. */
44
+ next() {
45
+ return this.step.type !== "line" ? this.step : (this.line++, this.show(0));
46
+ }
47
+ /** Picks a choice by its `index` (as shown). A locked or unknown index changes nothing. */
48
+ choose(t) {
49
+ if (this.step.type !== "choices" || this.node === null) return this.step;
50
+ if (!this.step.choices.find((n) => n.index === t)?.enabled) return this.step;
51
+ const i = this.node, e = this.nodeOf(i).choices[t];
52
+ return this.chosen.add(`${i}#${t}`), this.assign(e.set), this.run(e.do), e.goto === void 0 ? this.finish() : this.go(e.goto);
53
+ }
54
+ /** Jumps to a node from outside (the game's own event broke in). */
55
+ jump(t) {
56
+ return this.go(t);
57
+ }
58
+ /** Ends the dialogue now. */
59
+ stop() {
60
+ return this.finish();
61
+ }
62
+ /** The value of an expression over this dialogue's variables, for a game that shares the language. */
63
+ evaluate(t) {
64
+ return u(t)(this.scope);
65
+ }
66
+ save() {
67
+ return {
68
+ node: this.node,
69
+ line: this.line,
70
+ vars: structuredClone(this.vars),
71
+ visits: Object.fromEntries(this.visits),
72
+ chosen: [...this.chosen]
73
+ };
74
+ }
75
+ /** Puts a saved dialogue back where it was, without running the node's `set` and `do` again. */
76
+ restore(t) {
77
+ for (const s of Object.keys(this.vars)) delete this.vars[s];
78
+ Object.assign(this.vars, structuredClone(t.vars)), this.visits.clear();
79
+ for (const [s, i] of Object.entries(t.visits)) this.visits.set(s, i);
80
+ this.chosen.clear();
81
+ for (const s of t.chosen) this.chosen.add(s);
82
+ return t.node === null || !this.script.nodes[t.node] ? this.finish() : (this.node = t.node, this.line = t.line, this.show(0));
83
+ }
84
+ go(t) {
85
+ return this.enter(t, 0);
86
+ }
87
+ enter(t, s) {
88
+ if (s > f) throw new Error(`dialogue: '${t}' loops without showing anything`);
89
+ const i = this.nodeOf(t);
90
+ return this.node = t, this.line = 0, this.visits.set(t, (this.visits.get(t) ?? 0) + 1), this.assign(i.set), this.run(i.do), this.node !== t ? this.step : this.show(s);
91
+ }
92
+ /** The step from the current line on: the next line that holds, else the choices, else the way on. */
93
+ show(t) {
94
+ const s = this.node, i = this.nodeOf(s), e = i.lines ?? [];
95
+ for (; this.line < e.length; this.line++) {
96
+ const r = e[this.line], h = typeof r == "string" ? { text: r } : r;
97
+ if (!(h.if !== void 0 && !this.test(h.if)))
98
+ return this.step = { type: "line", node: s, speaker: h.speaker, text: this.text(h.text, h.key), tags: h.tags ?? [] };
99
+ }
100
+ const n = this.offered(s, i);
101
+ if (n.length > 0) return this.step = { type: "choices", node: s, choices: n };
102
+ const o = this.wayOn(i);
103
+ return o === null ? this.finish() : this.enter(o, t + 1);
104
+ }
105
+ offered(t, s) {
106
+ const i = [];
107
+ return (s.choices ?? []).forEach((e, n) => {
108
+ if (e.once && this.chosen.has(`${t}#${n}`)) return;
109
+ const o = e.if === void 0 || this.test(e.if);
110
+ !o && !e.showLocked || i.push({ index: n, text: this.text(e.text, e.key), enabled: o });
111
+ }), i.some((e) => e.enabled) ? i : [];
112
+ }
113
+ wayOn(t) {
114
+ if (t.next === void 0) return null;
115
+ if (typeof t.next == "string") return t.next;
116
+ for (const s of t.next) if (s.if === void 0 || this.test(s.if)) return s.goto;
117
+ return null;
118
+ }
119
+ finish() {
120
+ return this.node = null, this.step = { type: "end" };
121
+ }
122
+ nodeOf(t) {
123
+ const s = this.script.nodes[t];
124
+ if (!s) throw new Error(`dialogue: no node '${t}'`);
125
+ return s;
126
+ }
127
+ test(t) {
128
+ return !!u(t)(this.scope);
129
+ }
130
+ assign(t) {
131
+ if (!t) return;
132
+ const s = Object.entries(t).map(([i, e]) => [i, u(e)(this.scope)]);
133
+ for (const [i, e] of s) p(this.vars, i, e);
134
+ }
135
+ run(t) {
136
+ for (const s of t ?? []) {
137
+ const i = typeof s == "string" ? s : s.name;
138
+ this.options.onCommand?.(i, typeof s == "string" ? [] : s.args ?? [], this);
139
+ }
140
+ }
141
+ /** `text` translated, with each `{expression}` replaced by its value; `{{` and `}}` are braces. */
142
+ text(t, s) {
143
+ return (this.options.translate ? this.options.translate(t, s) : t).replace(/\{\{|\}\}|\{([^{}]+)\}/g, (e, n) => {
144
+ if (e === "{{") return "{";
145
+ if (e === "}}") return "}";
146
+ const o = u(n.trim())(this.scope);
147
+ return o == null ? "" : String(o);
148
+ });
149
+ }
150
+ }
151
+ function l(c, t) {
152
+ let s = c;
153
+ for (const i of t.split(".")) {
154
+ if (s === null || typeof s != "object" || !Object.prototype.hasOwnProperty.call(s, i)) return;
155
+ s = s[i];
156
+ }
157
+ return s;
158
+ }
159
+ function p(c, t, s) {
160
+ const i = t.split(".");
161
+ let e = c;
162
+ for (const o of i.slice(0, -1)) {
163
+ if (o === "__proto__" || o === "constructor" || o === "prototype") throw new Error(`dialogue: cannot set '${t}'`);
164
+ const r = e[o];
165
+ e = r !== null && typeof r == "object" ? r : e[o] = {};
166
+ }
167
+ const n = i[i.length - 1];
168
+ if (n === "__proto__" || n === "constructor" || n === "prototype") throw new Error(`dialogue: cannot set '${t}'`);
169
+ e[n] = s;
170
+ }
171
+ export {
172
+ d as DialogueRunner
173
+ };
@@ -0,0 +1,137 @@
1
+ const A = ["&&", "||", "==", "!=", "<=", ">=", "<", ">", "!", "+", "-", "*", "/", "%", "(", ")", ","];
2
+ function N(r) {
3
+ const i = [];
4
+ let o = 0;
5
+ for (; o < r.length; ) {
6
+ const l = r[o];
7
+ if (/\s/.test(l)) {
8
+ o++;
9
+ continue;
10
+ }
11
+ if (/[0-9.]/.test(l)) {
12
+ const c = /^(?:\d+\.?\d*|\.\d+)/.exec(r.slice(o));
13
+ if (!c) throw new Error(`bad number at ${o}`);
14
+ i.push({ k: "num", v: Number(c[0]) }), o += c[0].length;
15
+ continue;
16
+ }
17
+ if (l === '"' || l === "'") {
18
+ let c = o + 1, p = "";
19
+ for (; c < r.length && r[c] !== l; )
20
+ r[c] === "\\" && c + 1 < r.length && c++, p += r[c], c++;
21
+ if (c >= r.length) throw new Error(`unclosed string at ${o}`);
22
+ i.push({ k: "str", v: p }), o = c + 1;
23
+ continue;
24
+ }
25
+ if (/[A-Za-z_$]/.test(l)) {
26
+ const c = /^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*/.exec(r.slice(o));
27
+ i.push({ k: "id", v: c[0] }), o += c[0].length;
28
+ continue;
29
+ }
30
+ const f = A.find((c) => r.startsWith(c, o));
31
+ if (!f) throw new Error(`unexpected '${l}' at ${o}`);
32
+ i.push({ k: "op", v: f }), o += f.length;
33
+ }
34
+ return i;
35
+ }
36
+ const m = (r) => !!r, k = (r, i) => r === i || r == null && i == null, s = (r) => typeof r == "number" ? r : typeof r == "boolean" ? Number(r) : r == null ? 0 : Number(r);
37
+ function Z(r) {
38
+ let i;
39
+ try {
40
+ i = N(r);
41
+ } catch (n) {
42
+ throw new Error(`expression '${r}': ${n.message}`);
43
+ }
44
+ let o = 0;
45
+ const l = () => i[o], f = (n) => l()?.k === "op" && l().v === n, c = (n) => {
46
+ const e = l();
47
+ return e?.k === "op" && n.includes(e.v);
48
+ }, p = (n) => {
49
+ throw new Error(`expression '${r}': ${n}`);
50
+ }, y = (n) => f(n) ? o++ : p(`expected '${n}'`), h = (n, e, u) => () => {
51
+ let t = n();
52
+ for (; c(e); ) {
53
+ const a = i[o++].v;
54
+ t = u(a, t, n());
55
+ }
56
+ return t;
57
+ }, x = () => {
58
+ const n = i[o++];
59
+ if (!n) return p("ended early");
60
+ if (n.k === "num" || n.k === "str") {
61
+ const e = n.v;
62
+ return () => e;
63
+ }
64
+ if (n.k === "id") {
65
+ const e = n.v;
66
+ if (e === "true") return () => !0;
67
+ if (e === "false") return () => !1;
68
+ if (e === "null") return () => null;
69
+ if (f("(")) {
70
+ o++;
71
+ const u = [];
72
+ for (; !f(")") && (u.push($()), !!f(",")); )
73
+ o++;
74
+ return y(")"), (t) => t.call(e, u.map((a) => a(t)));
75
+ }
76
+ return (u) => {
77
+ const t = u.get(e);
78
+ return typeof t == "number" || typeof t == "string" || typeof t == "boolean" || t == null ? t : String(t);
79
+ };
80
+ }
81
+ if (n.v === "(") {
82
+ const e = $();
83
+ return y(")"), e;
84
+ }
85
+ return p(`unexpected '${n.v}'`);
86
+ }, w = () => {
87
+ if (f("!")) {
88
+ o++;
89
+ const n = w();
90
+ return (e) => !m(n(e));
91
+ }
92
+ if (f("-")) {
93
+ o++;
94
+ const n = w();
95
+ return (e) => -s(n(e));
96
+ }
97
+ return x();
98
+ }, v = h(
99
+ w,
100
+ ["*", "/", "%"],
101
+ (n, e, u) => n === "*" ? (t) => s(e(t)) * s(u(t)) : n === "/" ? (t) => s(e(t)) / s(u(t)) : (t) => s(e(t)) % s(u(t))
102
+ ), E = h(
103
+ v,
104
+ ["+", "-"],
105
+ (n, e, u) => n === "+" ? (t) => {
106
+ const a = e(t), d = u(t);
107
+ return typeof a == "string" || typeof d == "string" ? `${a ?? ""}${d ?? ""}` : s(a) + s(d);
108
+ } : (t) => s(e(t)) - s(u(t))
109
+ ), _ = h(E, ["<", ">", "<=", ">=", "==", "!="], (n, e, u) => {
110
+ switch (n) {
111
+ case "==":
112
+ return (t) => k(e(t), u(t));
113
+ case "!=":
114
+ return (t) => !k(e(t), u(t));
115
+ case "<":
116
+ return (t) => s(e(t)) < s(u(t));
117
+ case ">":
118
+ return (t) => s(e(t)) > s(u(t));
119
+ case "<=":
120
+ return (t) => s(e(t)) <= s(u(t));
121
+ default:
122
+ return (t) => s(e(t)) >= s(u(t));
123
+ }
124
+ }), z = h(_, ["&&"], (n, e, u) => (t) => m(e(t)) && m(u(t))), $ = h(z, ["||"], (n, e, u) => (t) => m(e(t)) || m(u(t)));
125
+ i.length === 0 && p("empty");
126
+ const b = $();
127
+ return o < i.length && p(`unexpected '${i[o].v}'`), b;
128
+ }
129
+ const g = /* @__PURE__ */ new Map();
130
+ function O(r) {
131
+ let i = g.get(r);
132
+ return i || (i = Z(r), g.size > 2e3 && g.clear(), g.set(r, i)), i;
133
+ }
134
+ export {
135
+ Z as compileExpr,
136
+ O as expr
137
+ };
@@ -0,0 +1,52 @@
1
+ import { compileExpr as A } from "./expr.js";
2
+ function S(r, d = {}) {
3
+ const $ = [], s = (e, n) => $.push({ path: e, message: n, level: "error" }), g = Object.keys(r.nodes ?? {});
4
+ if (g.length === 0)
5
+ return s("nodes", "the script has no nodes"), $;
6
+ const m = r.start ?? g[0];
7
+ r.nodes[m] || s("start", `no node '${m}'`);
8
+ const p = d.functions ? /* @__PURE__ */ new Set(["visited", "chose", ...d.functions]) : null, a = (e, n) => {
9
+ if (typeof n != "string") return s(e, "must be an expression in a string");
10
+ try {
11
+ A(n);
12
+ } catch (o) {
13
+ return s(e, o.message);
14
+ }
15
+ if (p)
16
+ for (const o of n.matchAll(/([A-Za-z_$][\w$]*)\s*\(/g)) p.has(o[1]) || s(e, `no function '${o[1]}'`);
17
+ }, h = (e, n) => {
18
+ if (typeof n != "string") return s(e, "must be text");
19
+ for (const o of n.replace(/\{\{|\}\}/g, "").matchAll(/\{([^{}]*)\}/g)) a(e, o[1].trim());
20
+ }, u = (e, n) => {
21
+ (typeof n != "string" || !r.nodes[n]) && s(e, `no node '${String(n)}'`);
22
+ }, y = (e, n) => {
23
+ for (const [o, i] of Object.entries(n ?? {})) a(`${e}.${o}`, i);
24
+ }, v = (e, n) => {
25
+ (n ?? []).forEach((o, i) => {
26
+ const t = typeof o == "string" ? o : o?.name;
27
+ typeof t != "string" ? s(`${e}[${i}]`, "a command needs a name") : d.commands && !d.commands.includes(t) && s(`${e}[${i}]`, `no command '${t}'`);
28
+ });
29
+ }, w = /* @__PURE__ */ new Map();
30
+ for (const e of g) {
31
+ const n = r.nodes[e], o = `nodes.${e}`, i = [];
32
+ y(`${o}.set`, n.set), v(`${o}.do`, n.do), (n.lines ?? []).forEach((t, f) => {
33
+ if (typeof t == "string") return h(`${o}.lines[${f}]`, t);
34
+ h(`${o}.lines[${f}].text`, t.text), t.if !== void 0 && a(`${o}.lines[${f}].if`, t.if);
35
+ }), (n.choices ?? []).forEach((t, f) => {
36
+ const c = `${o}.choices[${f}]`;
37
+ h(`${c}.text`, t.text), t.if !== void 0 && a(`${c}.if`, t.if), y(`${c}.set`, t.set), v(`${c}.do`, t.do), t.goto !== void 0 && (u(`${c}.goto`, t.goto), i.push(t.goto));
38
+ }), typeof n.next == "string" ? (u(`${o}.next`, n.next), i.push(n.next)) : Array.isArray(n.next) && n.next.forEach((t, f) => {
39
+ t.if !== void 0 && a(`${o}.next[${f}].if`, t.if), u(`${o}.next[${f}].goto`, t.goto), i.push(t.goto);
40
+ }), w.set(e, i);
41
+ }
42
+ const l = /* @__PURE__ */ new Set(), x = r.nodes[m] ? [m] : [];
43
+ for (; x.length; ) {
44
+ const e = x.pop();
45
+ l.has(e) || !r.nodes[e] || (l.add(e), x.push(...w.get(e) ?? []));
46
+ }
47
+ for (const e of g) l.has(e) || $.push({ path: `nodes.${e}`, message: "nothing leads here from the start", level: "warning" });
48
+ return $;
49
+ }
50
+ export {
51
+ S as validateDialogue
52
+ };
@@ -0,0 +1,94 @@
1
+ function P(r, t) {
2
+ return [r, t];
3
+ }
4
+ function y(r, t, e = {}) {
5
+ const o = e.extends ?? null, n = new Map(o?.parts ?? []);
6
+ for (const [s, i] of t)
7
+ i === null ? n.delete(s) : n.set(s, l(n.get(s), i));
8
+ return { name: r, parts: n, base: o };
9
+ }
10
+ function w(r, t, e = {}) {
11
+ const o = e.with?.length ? y(t.name, e.with, { extends: t }).parts : t.parts, n = r.create(), s = { entity: n, args: e.args };
12
+ for (const [i, f] of o)
13
+ e.without?.includes(i) || r.add(n, i, g(f, s));
14
+ return n;
15
+ }
16
+ function x(r, t) {
17
+ for (let e = r; e; e = e.base) if (e === t) return !0;
18
+ return !1;
19
+ }
20
+ function g(r, t) {
21
+ return typeof r == "function" ? r(t) : r !== null && typeof r == "object" ? structuredClone(r) : r;
22
+ }
23
+ const h = (r) => r !== null && typeof r == "object" && !Array.isArray(r) && Object.getPrototypeOf(r) === Object.prototype;
24
+ function l(r, t) {
25
+ if (!h(r) || !h(t)) return t;
26
+ const e = { ...r };
27
+ for (const [o, n] of Object.entries(t)) e[o] = l(r[o], n);
28
+ return e;
29
+ }
30
+ class O {
31
+ types = /* @__PURE__ */ new Map();
32
+ factories = /* @__PURE__ */ new Map();
33
+ prefabs = /* @__PURE__ */ new Map();
34
+ /** Lets data name a component type. */
35
+ component(t, e) {
36
+ return this.types.set(t, e), this;
37
+ }
38
+ /** A value made in code for a prefab loaded from data (and its variants): the data cannot hold a function. */
39
+ factory(t, e, o) {
40
+ let n = this.factories.get(t);
41
+ return n || this.factories.set(t, n = /* @__PURE__ */ new Map()), n.set(e, o), this;
42
+ }
43
+ /** Adds a prefab made in code. */
44
+ add(t) {
45
+ return this.prefabs.set(t.name, t), this;
46
+ }
47
+ /**
48
+ * Builds the prefabs of `data`, bases before their variants (in any order in the data), and adds them. Throws,
49
+ * naming the prefab, on an unknown component or base, or a prefab that extends itself.
50
+ */
51
+ load(t) {
52
+ const e = /* @__PURE__ */ new Map(), o = /* @__PURE__ */ new Set(), n = (s) => {
53
+ const i = e.get(s);
54
+ if (i) return i;
55
+ const f = t[s];
56
+ if (!f) return this.get(s);
57
+ if (o.has(s)) throw new Error(`PrefabLibrary: '${s}' extends itself`);
58
+ o.add(s);
59
+ const d = f.extends === void 0 ? void 0 : n(f.extends), u = Object.entries(f.components ?? {}).map(([c, a]) => {
60
+ const b = this.types.get(c);
61
+ if (!b) throw new Error(`PrefabLibrary: '${s}' names an unknown component '${c}'`);
62
+ return [b, a];
63
+ });
64
+ for (const [c, a] of this.factories.get(s) ?? []) u.push([c, a]);
65
+ const p = y(s, u, { extends: d });
66
+ return o.delete(s), e.set(s, p), p;
67
+ };
68
+ for (const s of Object.keys(t)) n(s);
69
+ for (const [s, i] of e) this.prefabs.set(s, i);
70
+ return this;
71
+ }
72
+ get(t) {
73
+ const e = this.prefabs.get(t);
74
+ if (!e) throw new Error(`PrefabLibrary: no prefab '${t}'`);
75
+ return e;
76
+ }
77
+ has(t) {
78
+ return this.prefabs.has(t);
79
+ }
80
+ names() {
81
+ return [...this.prefabs.keys()];
82
+ }
83
+ /** `spawnPrefab` by name. */
84
+ spawn(t, e, o = {}) {
85
+ return w(t, this.get(e), o);
86
+ }
87
+ }
88
+ export {
89
+ O as PrefabLibrary,
90
+ y as definePrefab,
91
+ x as isPrefabOf,
92
+ P as prefabPart,
93
+ w as spawnPrefab
94
+ };
@@ -0,0 +1,31 @@
1
+ import { isAllowedNavigation as a, isDevToolsKey as d, debuggerRequested as f, isAllowedExternal as u } from "./lockdownRules.js";
2
+ function g(r, n) {
3
+ const i = n.log ?? ((...e) => console.log(...e)), t = r.webContents, s = (e, o) => {
4
+ u(e, n.external) ? n.shell.openExternal(e).catch((c) => i("could not open", e, c)) : i(`refused ${o}:`, e);
5
+ };
6
+ t.setWindowOpenHandler(({ url: e }) => (s(e, "external link"), { action: "deny" })), t.on("will-navigate", (e, o) => {
7
+ a(o, n.devServerUrl) || (e.preventDefault(), s(o, "navigation"));
8
+ }), t.on("will-redirect", (e, o) => {
9
+ a(o, n.devServerUrl) || e.preventDefault();
10
+ });
11
+ const l = n.devToolsKey === void 0 ? "F12" : n.devToolsKey;
12
+ t.on("before-input-event", (e, o) => {
13
+ if (n.packaged) {
14
+ d(o) && e.preventDefault();
15
+ return;
16
+ }
17
+ l && o.type === "keyDown" && o.key === l && (t.toggleDevTools(), e.preventDefault());
18
+ });
19
+ }
20
+ function w(r, n = []) {
21
+ const i = new Set(n);
22
+ r.setPermissionRequestHandler((t, s, l) => l(i.has(s))), r.setPermissionCheckHandler((t, s) => i.has(s));
23
+ }
24
+ function p(r, n = process.argv, i = (t) => process.exit(t)) {
25
+ return !r.isPackaged || !f(n, (t) => r.commandLine.hasSwitch(t)) ? !1 : (console.error("[main] refusing to run with a debugger attached"), i(1), !0);
26
+ }
27
+ export {
28
+ w as denyPermissions,
29
+ g as lockDownWindow,
30
+ p as refuseDebugLaunch
31
+ };
@@ -0,0 +1,42 @@
1
+ function i(e) {
2
+ try {
3
+ return new URL(e);
4
+ } catch {
5
+ return null;
6
+ }
7
+ }
8
+ function g(e, r) {
9
+ const t = i(e);
10
+ if (!t || t.protocol !== "https:" || t.username || t.password) return !1;
11
+ const o = t.hostname.toLowerCase(), s = (r.paths ?? []).filter((n) => n.host.toLowerCase() === o);
12
+ return s.length ? s.some((n) => t.pathname.toLowerCase().startsWith(n.prefix.toLowerCase())) : r.hosts.some((n) => {
13
+ const a = n.toLowerCase();
14
+ return o === a || o.endsWith(`.${a}`);
15
+ });
16
+ }
17
+ function f(e, r) {
18
+ const t = i(e);
19
+ if (!t) return !1;
20
+ if (r) {
21
+ const o = i(r);
22
+ return !!o && t.origin === o.origin;
23
+ }
24
+ return t.protocol === "file:";
25
+ }
26
+ function l(e) {
27
+ if (e.type !== "keyDown") return !1;
28
+ if (e.key === "F12") return !0;
29
+ const r = e.key.toLowerCase();
30
+ return (e.control || e.meta) && (e.shift || e.alt) && (r === "i" || r === "j" || r === "c");
31
+ }
32
+ const c = ["--inspect", "--remote-debugging-port", "--remote-debugging-pipe", "--remote-debugging-address"], u = ["remote-debugging-port", "remote-debugging-pipe", "inspect", "inspect-brk"];
33
+ function d(e, r = () => !1) {
34
+ return e.some((o) => c.some((s) => o === s || o.startsWith(`${s}=`) || o.startsWith(`${s}-`))) || u.some((o) => r(o));
35
+ }
36
+ export {
37
+ c as DEBUG_SWITCHES,
38
+ d as debuggerRequested,
39
+ g as isAllowedExternal,
40
+ f as isAllowedNavigation,
41
+ l as isDevToolsKey
42
+ };
@@ -0,0 +1,48 @@
1
+ import { promises as r } from "node:fs";
2
+ import { join as n } from "node:path";
3
+ class l {
4
+ constructor(t) {
5
+ this.o = t, this.file = n(t.dir, t.fileName ?? "session.bin"), this.maxLength = t.maxLength ?? 4096, this.platform = t.platform ?? process.platform;
6
+ }
7
+ o;
8
+ file;
9
+ maxLength;
10
+ platform;
11
+ /** Whether the OS can encrypt for real here. */
12
+ canEncrypt() {
13
+ const t = this.o.safeStorage;
14
+ return t.isEncryptionAvailable() ? this.platform !== "linux" || t.getSelectedStorageBackend?.() !== "basic_text" : !1;
15
+ }
16
+ /** The saved value, or null when there is none, it cannot be decrypted (another OS user, a reinstall) or nothing may be. */
17
+ async get() {
18
+ if (!this.canEncrypt()) return null;
19
+ try {
20
+ return this.o.safeStorage.decryptString(await r.readFile(this.file));
21
+ } catch {
22
+ return null;
23
+ }
24
+ }
25
+ /** Saves `value`; false when it is not a string, too long, or the OS cannot encrypt it. */
26
+ async set(t) {
27
+ if (typeof t != "string" || t.length > this.maxLength || !this.canEncrypt()) return !1;
28
+ const e = `${this.file}.${process.pid}.${Date.now()}.tmp`;
29
+ try {
30
+ await r.mkdir(this.o.dir, { recursive: !0 }), await r.writeFile(e, this.o.safeStorage.encryptString(t)), await r.rename(e, this.file);
31
+ } catch (a) {
32
+ throw await r.rm(e, { force: !0 }), a;
33
+ }
34
+ return !0;
35
+ }
36
+ async clear() {
37
+ await r.rm(this.file, { force: !0 });
38
+ }
39
+ }
40
+ function h(s, t, e = "session") {
41
+ return s.handle(`${e}:get`, () => t.get()), s.handle(`${e}:set`, (a, i) => t.set(i)), s.handle(`${e}:clear`, () => t.clear()), () => {
42
+ for (const a of ["get", "set", "clear"]) s.removeHandler?.(`${e}:${a}`);
43
+ };
44
+ }
45
+ export {
46
+ l as SessionStore,
47
+ h as registerSessionStore
48
+ };
@@ -0,0 +1,18 @@
1
+ import { createHash as a } from "node:crypto";
2
+ import { readdirSync as f, readFileSync as d } from "node:fs";
3
+ import { join as i } from "node:path";
4
+ function p(n, r) {
5
+ const o = typeof r == "string" ? { dirs: [r] } : r, s = o.match ?? ((t) => t.endsWith(".cjs")), e = a("sha256");
6
+ e.update(`electron ${n}
7
+ `);
8
+ for (const t of o.dirs)
9
+ for (const c of f(t).filter(s).sort())
10
+ e.update(`${c}
11
+ `), e.update(d(i(t, c)));
12
+ for (const t of o.extra ?? []) e.update(`extra ${t}
13
+ `);
14
+ return e.digest("hex").slice(0, o.length ?? 16);
15
+ }
16
+ export {
17
+ p as shellId
18
+ };
@@ -0,0 +1,36 @@
1
+ import { createHash as s } from "node:crypto";
2
+ import { readFile as c, mkdir as l, writeFile as u, readdir as f } from "node:fs/promises";
3
+ import { join as r, dirname as h } from "node:path";
4
+ const m = (t) => s("sha256").update(t).digest("hex");
5
+ async function n(t, e = "") {
6
+ const i = [];
7
+ for (const a of await f(r(t, e), { withFileTypes: !0 })) {
8
+ const o = e ? `${e}/${a.name}` : a.name;
9
+ a.isDirectory() ? i.push(...await n(t, o)) : i.push(o);
10
+ }
11
+ return i;
12
+ }
13
+ async function d(t) {
14
+ const e = /* @__PURE__ */ new Map();
15
+ for (const i of await n(t)) e.set(i, m(await c(r(t, ...i.split("/")))));
16
+ return e;
17
+ }
18
+ async function F(t, e, i) {
19
+ const a = r(t, ...e.split("/"));
20
+ await l(h(a), { recursive: !0 }), await u(a, i);
21
+ }
22
+ async function T(t, e, i) {
23
+ const a = new AbortController(), o = setTimeout(() => a.abort(), i);
24
+ try {
25
+ return await t(e, { signal: a.signal, cache: "no-store" });
26
+ } finally {
27
+ clearTimeout(o);
28
+ }
29
+ }
30
+ export {
31
+ T as fetchWithTimeout,
32
+ d as hashWeb,
33
+ n as listFiles,
34
+ F as putFile,
35
+ m as sha256
36
+ };