@novely/core 0.45.1 → 0.46.0-next.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.
- package/dist/index.d.ts +53 -33
- package/dist/index.global.js +1115 -939
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +817 -733
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1,15 +1,64 @@
|
|
|
1
|
+
// src/novely.ts
|
|
2
|
+
import { dequal } from "dequal/lite";
|
|
3
|
+
import { throttle } from "es-toolkit/function";
|
|
4
|
+
import { merge as deepmerge } from "es-toolkit/object";
|
|
5
|
+
import { DEV as DEV3 } from "esm-env";
|
|
6
|
+
|
|
7
|
+
// ../../node_modules/.pnpm/klona@2.0.6/node_modules/klona/full/index.mjs
|
|
8
|
+
function set(obj, key, val) {
|
|
9
|
+
if (typeof val.value === "object") val.value = klona(val.value);
|
|
10
|
+
if (!val.enumerable || val.get || val.set || !val.configurable || !val.writable || key === "__proto__") {
|
|
11
|
+
Object.defineProperty(obj, key, val);
|
|
12
|
+
} else obj[key] = val.value;
|
|
13
|
+
}
|
|
14
|
+
function klona(x) {
|
|
15
|
+
if (typeof x !== "object") return x;
|
|
16
|
+
var i = 0, k, list, tmp, str = Object.prototype.toString.call(x);
|
|
17
|
+
if (str === "[object Object]") {
|
|
18
|
+
tmp = Object.create(x.__proto__ || null);
|
|
19
|
+
} else if (str === "[object Array]") {
|
|
20
|
+
tmp = Array(x.length);
|
|
21
|
+
} else if (str === "[object Set]") {
|
|
22
|
+
tmp = /* @__PURE__ */ new Set();
|
|
23
|
+
x.forEach(function(val) {
|
|
24
|
+
tmp.add(klona(val));
|
|
25
|
+
});
|
|
26
|
+
} else if (str === "[object Map]") {
|
|
27
|
+
tmp = /* @__PURE__ */ new Map();
|
|
28
|
+
x.forEach(function(val, key) {
|
|
29
|
+
tmp.set(klona(key), klona(val));
|
|
30
|
+
});
|
|
31
|
+
} else if (str === "[object Date]") {
|
|
32
|
+
tmp = /* @__PURE__ */ new Date(+x);
|
|
33
|
+
} else if (str === "[object RegExp]") {
|
|
34
|
+
tmp = new RegExp(x.source, x.flags);
|
|
35
|
+
} else if (str === "[object DataView]") {
|
|
36
|
+
tmp = new x.constructor(klona(x.buffer));
|
|
37
|
+
} else if (str === "[object ArrayBuffer]") {
|
|
38
|
+
tmp = x.slice(0);
|
|
39
|
+
} else if (str.slice(-6) === "Array]") {
|
|
40
|
+
tmp = new x.constructor(x);
|
|
41
|
+
}
|
|
42
|
+
if (tmp) {
|
|
43
|
+
for (list = Object.getOwnPropertySymbols(x); i < list.length; i++) {
|
|
44
|
+
set(tmp, list[i], Object.getOwnPropertyDescriptor(x, list[i]));
|
|
45
|
+
}
|
|
46
|
+
for (i = 0, list = Object.getOwnPropertyNames(x); i < list.length; i++) {
|
|
47
|
+
if (Object.hasOwnProperty.call(tmp, k = list[i]) && tmp[k] === x[k]) continue;
|
|
48
|
+
set(tmp, k, Object.getOwnPropertyDescriptor(x, k));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return tmp || x;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// src/novely.ts
|
|
55
|
+
import pLimit from "p-limit";
|
|
56
|
+
|
|
1
57
|
// src/constants.ts
|
|
2
58
|
var SKIPPED_DURING_RESTORE = /* @__PURE__ */ new Set(["dialog", "choice", "input", "vibrate", "text"]);
|
|
3
59
|
var BLOCK_EXIT_STATEMENTS = /* @__PURE__ */ new Set(["choice:exit", "condition:exit", "block:exit"]);
|
|
4
60
|
var BLOCK_STATEMENTS = /* @__PURE__ */ new Set(["choice", "condition", "block"]);
|
|
5
|
-
var AUDIO_ACTIONS = /* @__PURE__ */ new Set([
|
|
6
|
-
"playMusic",
|
|
7
|
-
"stopMusic",
|
|
8
|
-
"playSound",
|
|
9
|
-
"stopSound",
|
|
10
|
-
"voice",
|
|
11
|
-
"stopVoice"
|
|
12
|
-
]);
|
|
61
|
+
var AUDIO_ACTIONS = /* @__PURE__ */ new Set(["playMusic", "stopMusic", "playSound", "stopSound", "voice", "stopVoice"]);
|
|
13
62
|
var EMPTY_SET = /* @__PURE__ */ new Set();
|
|
14
63
|
var DEFAULT_TYPEWRITER_SPEED = "Medium";
|
|
15
64
|
var HOWLER_SUPPORTED_FILE_FORMATS = /* @__PURE__ */ new Set([
|
|
@@ -45,170 +94,7 @@ var SUPPORTED_IMAGE_FILE_FORMATS = /* @__PURE__ */ new Set([
|
|
|
45
94
|
]);
|
|
46
95
|
var MAIN_CONTEXT_KEY = "$MAIN";
|
|
47
96
|
|
|
48
|
-
// src/
|
|
49
|
-
var STACK_MAP = /* @__PURE__ */ new Map();
|
|
50
|
-
var CUSTOM_ACTION_MAP = /* @__PURE__ */ new Map();
|
|
51
|
-
var PRELOADED_ASSETS = /* @__PURE__ */ new Set();
|
|
52
|
-
var ASSETS_TO_PRELOAD = /* @__PURE__ */ new Set();
|
|
53
|
-
|
|
54
|
-
// src/utils.ts
|
|
55
|
-
import { DEV as DEV2 } from "esm-env";
|
|
56
|
-
import { memoize as memoize2 } from "es-toolkit/function";
|
|
57
|
-
|
|
58
|
-
// src/asset.ts
|
|
59
|
-
import { DEV } from "esm-env";
|
|
60
|
-
|
|
61
|
-
// src/audio-codecs.ts
|
|
62
|
-
var cut = (str2) => str2.replace(/^no$/, "");
|
|
63
|
-
var audio = new Audio();
|
|
64
|
-
var canPlay = (type) => !!cut(audio.canPlayType(type));
|
|
65
|
-
var canPlayMultiple = (...types) => types.some((type) => canPlay(type));
|
|
66
|
-
var supportsMap = {
|
|
67
|
-
mp3: canPlayMultiple("audio/mpeg;", "audio/mp3;"),
|
|
68
|
-
mpeg: canPlay("audio/mpeg;"),
|
|
69
|
-
opus: canPlay('audio/ogg; codecs="opus"'),
|
|
70
|
-
ogg: canPlay('audio/ogg; codecs="vorbis"'),
|
|
71
|
-
oga: canPlay('audio/ogg; codecs="vorbis"'),
|
|
72
|
-
wav: canPlayMultiple('audio/wav; codecs="1"', "audio/wav;"),
|
|
73
|
-
aac: canPlay("audio/aac;"),
|
|
74
|
-
caf: canPlay("audio/x-caf;"),
|
|
75
|
-
m4a: canPlayMultiple("audio/x-m4a;", "audio/m4a;", "audio/aac;"),
|
|
76
|
-
m4b: canPlayMultiple("audio/x-m4b;", "audio/m4b;", "audio/aac;"),
|
|
77
|
-
mp4: canPlayMultiple("audio/x-mp4;", "audio/mp4;", "audio/aac;"),
|
|
78
|
-
weba: canPlay('audio/webm; codecs="vorbis"'),
|
|
79
|
-
webm: canPlay('audio/webm; codecs="vorbis"'),
|
|
80
|
-
dolby: canPlay('audio/mp4; codecs="ec-3"'),
|
|
81
|
-
flac: canPlayMultiple("audio/x-flac;", "audio/flac;")
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
// src/image-formats.ts
|
|
85
|
-
var avif = "data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A=";
|
|
86
|
-
var jxl = "data:image/jxl;base64,/woIAAAMABKIAgC4AF3lEgAAFSqjjBu8nOv58kOHxbSN6wxttW1hSaLIODZJJ3BIEkkaoCUzGM6qJAE=";
|
|
87
|
-
var webp = "data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA";
|
|
88
|
-
var supportsFormat = (source) => {
|
|
89
|
-
const { promise, resolve } = Promise.withResolvers();
|
|
90
|
-
const img = Object.assign(document.createElement("img"), {
|
|
91
|
-
src: source
|
|
92
|
-
});
|
|
93
|
-
img.onload = img.onerror = () => {
|
|
94
|
-
resolve(img.height === 2);
|
|
95
|
-
};
|
|
96
|
-
return promise;
|
|
97
|
-
};
|
|
98
|
-
var supportsMap2 = {
|
|
99
|
-
avif: false,
|
|
100
|
-
jxl: false,
|
|
101
|
-
webp: false
|
|
102
|
-
};
|
|
103
|
-
var formatsMap = {
|
|
104
|
-
avif,
|
|
105
|
-
jxl,
|
|
106
|
-
webp
|
|
107
|
-
};
|
|
108
|
-
var loadImageFormatsSupport = async () => {
|
|
109
|
-
const promises = [];
|
|
110
|
-
for (const [format, source] of Object.entries(formatsMap)) {
|
|
111
|
-
const promise = supportsFormat(source).then((supported) => {
|
|
112
|
-
supportsMap2[format] = supported;
|
|
113
|
-
});
|
|
114
|
-
promises.push(promise);
|
|
115
|
-
}
|
|
116
|
-
await Promise.all(promises);
|
|
117
|
-
};
|
|
118
|
-
loadImageFormatsSupport();
|
|
119
|
-
|
|
120
|
-
// src/asset.ts
|
|
121
|
-
import { memoize, once } from "es-toolkit/function";
|
|
122
|
-
var getType = memoize(
|
|
123
|
-
(extensions) => {
|
|
124
|
-
if (extensions.every((extension) => HOWLER_SUPPORTED_FILE_FORMATS.has(extension))) {
|
|
125
|
-
return "audio";
|
|
126
|
-
}
|
|
127
|
-
if (extensions.every((extension) => SUPPORTED_IMAGE_FILE_FORMATS.has(extension))) {
|
|
128
|
-
return "image";
|
|
129
|
-
}
|
|
130
|
-
throw extensions;
|
|
131
|
-
},
|
|
132
|
-
{
|
|
133
|
-
getCacheKey: (extensions) => extensions.join("~")
|
|
134
|
-
}
|
|
135
|
-
);
|
|
136
|
-
var SUPPORT_MAPS = {
|
|
137
|
-
"image": supportsMap2,
|
|
138
|
-
"audio": supportsMap
|
|
139
|
-
};
|
|
140
|
-
var assetPrivate = memoize(
|
|
141
|
-
(variants) => {
|
|
142
|
-
if (DEV && variants.length === 0) {
|
|
143
|
-
throw new Error(`Attempt to use "asset" function without arguments`);
|
|
144
|
-
}
|
|
145
|
-
const map = {};
|
|
146
|
-
const extensions = [];
|
|
147
|
-
for (const v of variants) {
|
|
148
|
-
const e = getUrlFileExtension(v);
|
|
149
|
-
map[e] = v;
|
|
150
|
-
extensions.push(e);
|
|
151
|
-
}
|
|
152
|
-
const type = getType(extensions);
|
|
153
|
-
const getSource = once(() => {
|
|
154
|
-
const support = SUPPORT_MAPS[type];
|
|
155
|
-
for (const extension of extensions) {
|
|
156
|
-
if (extension in support) {
|
|
157
|
-
if (support[extension]) {
|
|
158
|
-
return map[extension];
|
|
159
|
-
}
|
|
160
|
-
} else {
|
|
161
|
-
return map[extension];
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
if (DEV) {
|
|
165
|
-
throw new Error(`No matching asset was found for ${variants.map((v) => `"${v}"`).join(", ")}`);
|
|
166
|
-
}
|
|
167
|
-
return "";
|
|
168
|
-
});
|
|
169
|
-
return {
|
|
170
|
-
get source() {
|
|
171
|
-
return getSource();
|
|
172
|
-
},
|
|
173
|
-
get type() {
|
|
174
|
-
return type;
|
|
175
|
-
}
|
|
176
|
-
};
|
|
177
|
-
},
|
|
178
|
-
{
|
|
179
|
-
getCacheKey: (variants) => variants.join("~")
|
|
180
|
-
}
|
|
181
|
-
);
|
|
182
|
-
var asset = (...variants) => {
|
|
183
|
-
return assetPrivate(variants);
|
|
184
|
-
};
|
|
185
|
-
var isAsset = (suspect) => {
|
|
186
|
-
return suspect !== null && typeof suspect === "object" && "source" in suspect && "type" in suspect;
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
// src/utils.ts
|
|
190
|
-
var matchAction = ({ getContext, onBeforeActionCall, push, forward }, values) => {
|
|
191
|
-
return (action, props, { ctx, data }) => {
|
|
192
|
-
const context = typeof ctx === "string" ? getContext(ctx) : ctx;
|
|
193
|
-
onBeforeActionCall({
|
|
194
|
-
action,
|
|
195
|
-
props,
|
|
196
|
-
ctx: context
|
|
197
|
-
});
|
|
198
|
-
return values[action]({
|
|
199
|
-
ctx: context,
|
|
200
|
-
data,
|
|
201
|
-
push() {
|
|
202
|
-
if (context.meta.preview) return;
|
|
203
|
-
push(context);
|
|
204
|
-
},
|
|
205
|
-
forward() {
|
|
206
|
-
if (context.meta.preview) return;
|
|
207
|
-
forward(context);
|
|
208
|
-
}
|
|
209
|
-
}, props);
|
|
210
|
-
};
|
|
211
|
-
};
|
|
97
|
+
// src/utilities/assertions.ts
|
|
212
98
|
var isNumber = (val) => {
|
|
213
99
|
return typeof val === "number";
|
|
214
100
|
};
|
|
@@ -227,54 +113,13 @@ var isPromise = (val) => {
|
|
|
227
113
|
var isEmpty = (val) => {
|
|
228
114
|
return typeof val === "object" && !isNull(val) && Object.keys(val).length === 0;
|
|
229
115
|
};
|
|
230
|
-
var
|
|
231
|
-
const startsWith = String.prototype.startsWith.bind(
|
|
116
|
+
var isCSSImageURL = (url) => {
|
|
117
|
+
const startsWith = String.prototype.startsWith.bind(url);
|
|
232
118
|
return startsWith("http") || startsWith("/") || startsWith(".") || startsWith("data");
|
|
233
119
|
};
|
|
234
|
-
var str = String;
|
|
235
120
|
var isUserRequiredAction = ([action, ...meta]) => {
|
|
236
121
|
return Boolean(action === "custom" && meta[0] && meta[0].requireUserAction);
|
|
237
122
|
};
|
|
238
|
-
var getLanguage = (languages) => {
|
|
239
|
-
let { language } = navigator;
|
|
240
|
-
if (languages.includes(language)) {
|
|
241
|
-
return language;
|
|
242
|
-
} else if (languages.includes(language = language.slice(0, 2))) {
|
|
243
|
-
return language;
|
|
244
|
-
} else if (language = languages.find((value) => navigator.languages.includes(value))) {
|
|
245
|
-
return language;
|
|
246
|
-
}
|
|
247
|
-
return languages[0];
|
|
248
|
-
};
|
|
249
|
-
var createControlledPromise = () => {
|
|
250
|
-
const object = {
|
|
251
|
-
resolve: null,
|
|
252
|
-
reject: null,
|
|
253
|
-
promise: null,
|
|
254
|
-
cancel: null
|
|
255
|
-
};
|
|
256
|
-
const init = () => {
|
|
257
|
-
const promise = new Promise((resolve, reject) => {
|
|
258
|
-
object.reject = reject;
|
|
259
|
-
object.resolve = (value) => {
|
|
260
|
-
resolve({ cancelled: false, value });
|
|
261
|
-
};
|
|
262
|
-
object.cancel = () => {
|
|
263
|
-
resolve({ cancelled: true, value: null });
|
|
264
|
-
init();
|
|
265
|
-
};
|
|
266
|
-
});
|
|
267
|
-
object.promise = promise;
|
|
268
|
-
};
|
|
269
|
-
return init(), object;
|
|
270
|
-
};
|
|
271
|
-
var findLastPathItemBeforeItemOfType = (path, name) => {
|
|
272
|
-
const item = path.findLast(([_name, _value], i, array) => {
|
|
273
|
-
const next = array[i + 1];
|
|
274
|
-
return isNull(_name) && isNumber(_value) && next != null && next[0] === name;
|
|
275
|
-
});
|
|
276
|
-
return item;
|
|
277
|
-
};
|
|
278
123
|
var isBlockStatement = (statement) => {
|
|
279
124
|
return BLOCK_STATEMENTS.has(statement);
|
|
280
125
|
};
|
|
@@ -287,41 +132,284 @@ var isSkippedDuringRestore = (item) => {
|
|
|
287
132
|
var isAudioAction = (action) => {
|
|
288
133
|
return AUDIO_ACTIONS.has(action);
|
|
289
134
|
};
|
|
290
|
-
var noop = () => {
|
|
291
|
-
};
|
|
292
135
|
var isAction = (element) => {
|
|
293
136
|
return Array.isArray(element) && isString(element[0]);
|
|
294
137
|
};
|
|
295
|
-
var
|
|
296
|
-
return
|
|
297
|
-
const type = data[0];
|
|
298
|
-
if (Array.isArray(type)) return flatActions(data);
|
|
299
|
-
return [data];
|
|
300
|
-
});
|
|
301
|
-
};
|
|
302
|
-
var flattenStory = (story) => {
|
|
303
|
-
const entries = Object.entries(story).map(([name, items]) => {
|
|
304
|
-
return [name, flatActions(items)];
|
|
305
|
-
});
|
|
306
|
-
return Object.fromEntries(entries);
|
|
138
|
+
var isImageAsset = (asset2) => {
|
|
139
|
+
return isString(asset2) && isCSSImageURL(asset2);
|
|
307
140
|
};
|
|
308
|
-
var
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
141
|
+
var isBlockingAction = (action) => {
|
|
142
|
+
return isUserRequiredAction(action) || isSkippedDuringRestore(action[0]) && action[0] !== "vibrate";
|
|
143
|
+
};
|
|
144
|
+
var isAsset = (suspect) => {
|
|
145
|
+
return suspect !== null && typeof suspect === "object" && "source" in suspect && "type" in suspect;
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
// src/utilities/match-action.ts
|
|
149
|
+
var matchAction = (callbacks, values) => {
|
|
150
|
+
const { getContext, onBeforeActionCall, push, forward } = callbacks;
|
|
151
|
+
return (action, props, { ctx, data }) => {
|
|
152
|
+
const context = typeof ctx === "string" ? getContext(ctx) : ctx;
|
|
153
|
+
onBeforeActionCall({
|
|
154
|
+
action,
|
|
155
|
+
props,
|
|
156
|
+
ctx: context
|
|
157
|
+
});
|
|
158
|
+
return values[action](
|
|
159
|
+
{
|
|
160
|
+
ctx: context,
|
|
161
|
+
data,
|
|
162
|
+
push() {
|
|
163
|
+
if (context.meta.preview) return;
|
|
164
|
+
push(context);
|
|
165
|
+
},
|
|
166
|
+
forward() {
|
|
167
|
+
if (context.meta.preview) return;
|
|
168
|
+
forward(context);
|
|
169
|
+
}
|
|
170
|
+
},
|
|
171
|
+
props
|
|
172
|
+
);
|
|
173
|
+
};
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
// src/utilities/ungrupped.ts
|
|
177
|
+
import { memoize } from "es-toolkit/function";
|
|
178
|
+
import { DEV } from "esm-env";
|
|
179
|
+
var getLanguage = (languages) => {
|
|
180
|
+
let { language } = navigator;
|
|
181
|
+
if (languages.includes(language)) {
|
|
182
|
+
return language;
|
|
183
|
+
} else if (languages.includes(language = language.slice(0, 2))) {
|
|
184
|
+
return language;
|
|
185
|
+
} else if (language = languages.find((value) => navigator.languages.includes(value))) {
|
|
186
|
+
return language;
|
|
187
|
+
}
|
|
188
|
+
return languages[0];
|
|
189
|
+
};
|
|
190
|
+
var noop = () => {
|
|
191
|
+
};
|
|
192
|
+
var mapSet = (set2, fn) => {
|
|
193
|
+
return [...set2].map(fn);
|
|
194
|
+
};
|
|
195
|
+
var capitalize = (str) => {
|
|
196
|
+
return str[0].toUpperCase() + str.slice(1);
|
|
197
|
+
};
|
|
198
|
+
var getIntlLanguageDisplayName = memoize((lang) => {
|
|
199
|
+
try {
|
|
200
|
+
const intl = new Intl.DisplayNames([lang], {
|
|
201
|
+
type: "language"
|
|
202
|
+
});
|
|
203
|
+
return intl.of(lang) || lang;
|
|
204
|
+
} catch {
|
|
205
|
+
return lang;
|
|
206
|
+
}
|
|
207
|
+
});
|
|
208
|
+
var unwrapAsset = (asset2) => {
|
|
209
|
+
return isAsset(asset2) ? asset2.source : asset2;
|
|
210
|
+
};
|
|
211
|
+
var handleAudioAsset = (asset2) => {
|
|
212
|
+
if (DEV && isAsset(asset2) && asset2.type !== "audio") {
|
|
213
|
+
throw new Error("Attempt to use non-audio asset in audio action", { cause: asset2 });
|
|
214
|
+
}
|
|
215
|
+
return unwrapAsset(asset2);
|
|
216
|
+
};
|
|
217
|
+
var handleImageAsset = (asset2) => {
|
|
218
|
+
if (DEV && isAsset(asset2) && asset2.type !== "image") {
|
|
219
|
+
throw new Error("Attempt to use non-image asset in action that requires image assets", { cause: asset2 });
|
|
220
|
+
}
|
|
221
|
+
return unwrapAsset(asset2);
|
|
222
|
+
};
|
|
223
|
+
var getCharactersData = (characters) => {
|
|
224
|
+
const entries = Object.entries(characters);
|
|
225
|
+
const mapped = entries.map(([key, value]) => [key, { name: value.name, emotions: Object.keys(value.emotions) }]);
|
|
226
|
+
return Object.fromEntries(mapped);
|
|
227
|
+
};
|
|
228
|
+
var toArray = (target) => {
|
|
229
|
+
return Array.isArray(target) ? target : [target];
|
|
230
|
+
};
|
|
231
|
+
var getLanguageFromStore = (store2) => {
|
|
232
|
+
return store2.get().meta[0];
|
|
233
|
+
};
|
|
234
|
+
var getVolumeFromStore = (store2) => {
|
|
235
|
+
const { meta } = store2.get();
|
|
236
|
+
return {
|
|
237
|
+
music: meta[2],
|
|
238
|
+
sound: meta[3],
|
|
239
|
+
voice: meta[4]
|
|
240
|
+
};
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
// src/utilities/actions-processing.ts
|
|
244
|
+
var isExitImpossible = (path) => {
|
|
245
|
+
const blockStatements = path.filter(([item]) => isBlockStatement(item));
|
|
246
|
+
const blockExitStatements = path.filter(([item]) => isBlockExitStatement(item));
|
|
247
|
+
if (blockStatements.length === 0 && blockExitStatements.length === 0) {
|
|
248
|
+
return true;
|
|
249
|
+
}
|
|
250
|
+
if (blockStatements.length > blockExitStatements.length) {
|
|
251
|
+
return false;
|
|
252
|
+
}
|
|
253
|
+
return !blockExitStatements.every(([name], i) => name && name.startsWith(blockStatements[i][0]));
|
|
254
|
+
};
|
|
255
|
+
var createReferFunction = (story) => {
|
|
256
|
+
const refer = (path) => {
|
|
257
|
+
let current = story;
|
|
258
|
+
let precurrent = story;
|
|
259
|
+
const blocks = [];
|
|
260
|
+
for (const [type, val] of path) {
|
|
261
|
+
if (type === "jump") {
|
|
262
|
+
precurrent = story;
|
|
263
|
+
current = current[val];
|
|
264
|
+
} else if (type === null) {
|
|
265
|
+
precurrent = current;
|
|
266
|
+
current = current[val];
|
|
267
|
+
} else if (type === "choice") {
|
|
268
|
+
blocks.push(precurrent);
|
|
269
|
+
current = current[val + 1][1];
|
|
270
|
+
} else if (type === "condition") {
|
|
271
|
+
blocks.push(precurrent);
|
|
272
|
+
current = current[2][val];
|
|
273
|
+
} else if (type === "block") {
|
|
274
|
+
blocks.push(precurrent);
|
|
275
|
+
current = story[val];
|
|
276
|
+
} else if (type === "block:exit" || type === "choice:exit" || type === "condition:exit") {
|
|
277
|
+
current = blocks.pop();
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return current;
|
|
281
|
+
};
|
|
282
|
+
return refer;
|
|
283
|
+
};
|
|
284
|
+
var exitPath = ({ path, refer, onExitImpossible }) => {
|
|
285
|
+
const last = path.at(-1);
|
|
286
|
+
const ignore = [];
|
|
287
|
+
let wasExitImpossible = false;
|
|
288
|
+
if (!isAction(refer(path))) {
|
|
289
|
+
if (last && isNull(last[0]) && isNumber(last[1])) {
|
|
290
|
+
last[1]--;
|
|
291
|
+
} else {
|
|
292
|
+
path.pop();
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
if (isExitImpossible(path)) {
|
|
296
|
+
const referred = refer(path);
|
|
297
|
+
if (isAction(referred) && isSkippedDuringRestore(referred[0])) {
|
|
298
|
+
onExitImpossible?.();
|
|
299
|
+
}
|
|
300
|
+
wasExitImpossible = true;
|
|
301
|
+
return {
|
|
302
|
+
exitImpossible: wasExitImpossible
|
|
303
|
+
};
|
|
304
|
+
}
|
|
305
|
+
for (let i = path.length - 1; i > 0; i--) {
|
|
306
|
+
const [name] = path[i];
|
|
307
|
+
if (isBlockExitStatement(name)) {
|
|
308
|
+
ignore.push(name);
|
|
309
|
+
}
|
|
310
|
+
if (!isBlockStatement(name)) continue;
|
|
311
|
+
if (ignore.at(-1)?.startsWith(name)) {
|
|
312
|
+
ignore.pop();
|
|
313
|
+
continue;
|
|
314
|
+
}
|
|
315
|
+
path.push([`${name}:exit`]);
|
|
316
|
+
const prev = findLastPathItemBeforeItemOfType(path.slice(0, i + 1), name);
|
|
317
|
+
if (prev) path.push([null, prev[1] + 1]);
|
|
318
|
+
if (!isAction(refer(path))) {
|
|
319
|
+
path.pop();
|
|
320
|
+
continue;
|
|
321
|
+
}
|
|
322
|
+
break;
|
|
323
|
+
}
|
|
324
|
+
return {
|
|
325
|
+
exitImpossible: wasExitImpossible
|
|
326
|
+
};
|
|
327
|
+
};
|
|
328
|
+
var nextPath = (path) => {
|
|
329
|
+
const last = path.at(-1);
|
|
330
|
+
if (last && (isNull(last[0]) || last[0] === "jump") && isNumber(last[1])) {
|
|
331
|
+
last[1]++;
|
|
332
|
+
} else {
|
|
333
|
+
path.push([null, 0]);
|
|
334
|
+
}
|
|
335
|
+
return path;
|
|
336
|
+
};
|
|
337
|
+
var collectActionsBeforeBlockingAction = ({ path, refer, clone }) => {
|
|
338
|
+
const collection = [];
|
|
339
|
+
let action = refer(path);
|
|
340
|
+
while (true) {
|
|
341
|
+
if (action == void 0) {
|
|
342
|
+
const { exitImpossible } = exitPath({
|
|
343
|
+
path,
|
|
344
|
+
refer
|
|
345
|
+
});
|
|
346
|
+
if (exitImpossible) {
|
|
347
|
+
break;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
if (!action) {
|
|
351
|
+
break;
|
|
352
|
+
}
|
|
353
|
+
if (isBlockingAction(action)) {
|
|
354
|
+
const [name, ...props] = action;
|
|
355
|
+
if (name === "choice") {
|
|
356
|
+
const choiceProps = props;
|
|
357
|
+
for (let i = 0; i < choiceProps.length; i++) {
|
|
358
|
+
const branchContent = choiceProps[i];
|
|
359
|
+
if (!Array.isArray(branchContent)) continue;
|
|
360
|
+
const virtualPath = clone(path);
|
|
361
|
+
virtualPath.push(["choice", i], [null, 0]);
|
|
362
|
+
const innerActions = collectActionsBeforeBlockingAction({
|
|
363
|
+
path: virtualPath,
|
|
364
|
+
refer,
|
|
365
|
+
clone
|
|
366
|
+
});
|
|
367
|
+
collection.push(...innerActions);
|
|
368
|
+
}
|
|
369
|
+
} else if (name === "condition") {
|
|
370
|
+
const conditionProps = props;
|
|
371
|
+
const conditions = Object.keys(conditionProps[1]);
|
|
372
|
+
for (const condition of conditions) {
|
|
373
|
+
const virtualPath = clone(path);
|
|
374
|
+
virtualPath.push(["condition", condition], [null, 0]);
|
|
375
|
+
const innerActions = collectActionsBeforeBlockingAction({
|
|
376
|
+
path: virtualPath,
|
|
377
|
+
refer,
|
|
378
|
+
clone
|
|
379
|
+
});
|
|
380
|
+
collection.push(...innerActions);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
break;
|
|
384
|
+
}
|
|
385
|
+
collection.push(action);
|
|
386
|
+
if (action[0] === "jump") {
|
|
387
|
+
path = [
|
|
388
|
+
["jump", action[1]],
|
|
389
|
+
[null, 0]
|
|
390
|
+
];
|
|
391
|
+
} else if (action[0] == "block") {
|
|
392
|
+
path.push(["block", action[1]], [null, 0]);
|
|
393
|
+
} else {
|
|
394
|
+
nextPath(path);
|
|
395
|
+
}
|
|
396
|
+
action = refer(path);
|
|
397
|
+
}
|
|
398
|
+
return collection;
|
|
399
|
+
};
|
|
400
|
+
var findLastPathItemBeforeItemOfType = (path, name) => {
|
|
401
|
+
const item = path.findLast(([_name, _value], i, array) => {
|
|
402
|
+
const next = array[i + 1];
|
|
403
|
+
return isNull(_name) && isNumber(_value) && next != null && next[0] === name;
|
|
404
|
+
});
|
|
405
|
+
return item;
|
|
318
406
|
};
|
|
319
407
|
var getOppositeAction = (action) => {
|
|
320
408
|
const MAP = {
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
409
|
+
showCharacter: "hideCharacter",
|
|
410
|
+
playSound: "stopSound",
|
|
411
|
+
playMusic: "stopMusic",
|
|
412
|
+
voice: "stopVoice"
|
|
325
413
|
};
|
|
326
414
|
return MAP[action];
|
|
327
415
|
};
|
|
@@ -421,7 +509,7 @@ var createQueueProcessor = (queue, options) => {
|
|
|
421
509
|
const c1 = fn;
|
|
422
510
|
const isIdenticalID = Boolean(c0.id && c1.id && c0.id === c1.id);
|
|
423
511
|
const isIdenticalByReference = c0 === c1;
|
|
424
|
-
return isIdenticalID || isIdenticalByReference ||
|
|
512
|
+
return isIdenticalID || isIdenticalByReference || String(c0) === String(c1);
|
|
425
513
|
});
|
|
426
514
|
if (notLatest) continue;
|
|
427
515
|
} else if ("skipOnRestore" in fn && fn.skipOnRestore) {
|
|
@@ -488,53 +576,34 @@ var createQueueProcessor = (queue, options) => {
|
|
|
488
576
|
}
|
|
489
577
|
};
|
|
490
578
|
};
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
);
|
|
500
|
-
var createUseStackFunction = (renderer) => {
|
|
501
|
-
const useStack = (context) => {
|
|
502
|
-
const ctx = typeof context === "string" ? renderer.getContext(context) : context;
|
|
503
|
-
const stack = getStack(ctx);
|
|
504
|
-
return {
|
|
505
|
-
get previous() {
|
|
506
|
-
return stack.previous;
|
|
507
|
-
},
|
|
508
|
-
get value() {
|
|
509
|
-
return stack.at(-1);
|
|
510
|
-
},
|
|
511
|
-
set value(value) {
|
|
512
|
-
stack[stack.length - 1] = value;
|
|
513
|
-
},
|
|
514
|
-
back() {
|
|
515
|
-
if (stack.length > 1) {
|
|
516
|
-
stack.previous = stack.pop();
|
|
517
|
-
ctx.meta.goingBack = true;
|
|
518
|
-
}
|
|
519
|
-
},
|
|
520
|
-
push(value) {
|
|
521
|
-
stack.push(value);
|
|
522
|
-
},
|
|
523
|
-
clear() {
|
|
524
|
-
stack.previous = void 0;
|
|
525
|
-
stack.length = 0;
|
|
526
|
-
stack.length = 1;
|
|
527
|
-
}
|
|
528
|
-
};
|
|
579
|
+
|
|
580
|
+
// src/utilities/controlled-promise.ts
|
|
581
|
+
var createControlledPromise = () => {
|
|
582
|
+
const object = {
|
|
583
|
+
resolve: null,
|
|
584
|
+
reject: null,
|
|
585
|
+
promise: null,
|
|
586
|
+
cancel: null
|
|
529
587
|
};
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
};
|
|
535
|
-
|
|
536
|
-
|
|
588
|
+
const init = () => {
|
|
589
|
+
const promise = new Promise((resolve, reject) => {
|
|
590
|
+
object.reject = reject;
|
|
591
|
+
object.resolve = (value) => {
|
|
592
|
+
resolve({ cancelled: false, value });
|
|
593
|
+
};
|
|
594
|
+
object.cancel = () => {
|
|
595
|
+
resolve({ cancelled: true, value: null });
|
|
596
|
+
init();
|
|
597
|
+
};
|
|
598
|
+
});
|
|
599
|
+
object.promise = promise;
|
|
600
|
+
};
|
|
601
|
+
return init(), object;
|
|
537
602
|
};
|
|
603
|
+
|
|
604
|
+
// src/utilities/resources.ts
|
|
605
|
+
import { memoize as memoize2 } from "es-toolkit/function";
|
|
606
|
+
import { DEV as DEV2 } from "esm-env";
|
|
538
607
|
var getUrlFileExtension = (address) => {
|
|
539
608
|
try {
|
|
540
609
|
const { pathname } = new URL(address, location.href);
|
|
@@ -561,7 +630,7 @@ var fetchContentType = async (url, request) => {
|
|
|
561
630
|
};
|
|
562
631
|
var getResourseType = memoize2(
|
|
563
632
|
async ({ url, request }) => {
|
|
564
|
-
if (!
|
|
633
|
+
if (!isCSSImageURL(url)) {
|
|
565
634
|
return "other";
|
|
566
635
|
}
|
|
567
636
|
const extension = getUrlFileExtension(url);
|
|
@@ -584,313 +653,88 @@ var getResourseType = memoize2(
|
|
|
584
653
|
getCacheKey: ({ url }) => url
|
|
585
654
|
}
|
|
586
655
|
);
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
};
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
for (const [type, val] of path) {
|
|
606
|
-
if (type === "jump") {
|
|
607
|
-
precurrent = story;
|
|
608
|
-
current = current[val];
|
|
609
|
-
} else if (type === null) {
|
|
610
|
-
precurrent = current;
|
|
611
|
-
current = current[val];
|
|
612
|
-
} else if (type === "choice") {
|
|
613
|
-
blocks.push(precurrent);
|
|
614
|
-
current = current[val + 1][1];
|
|
615
|
-
} else if (type === "condition") {
|
|
616
|
-
blocks.push(precurrent);
|
|
617
|
-
current = current[2][val];
|
|
618
|
-
} else if (type === "block") {
|
|
619
|
-
blocks.push(precurrent);
|
|
620
|
-
current = story[val];
|
|
621
|
-
} else if (type === "block:exit" || type === "choice:exit" || type === "condition:exit") {
|
|
622
|
-
current = blocks.pop();
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
return current;
|
|
626
|
-
};
|
|
627
|
-
return refer;
|
|
628
|
-
};
|
|
629
|
-
var exitPath = ({ path, refer, onExitImpossible }) => {
|
|
630
|
-
const last = path.at(-1);
|
|
631
|
-
const ignore = [];
|
|
632
|
-
let wasExitImpossible = false;
|
|
633
|
-
if (!isAction(refer(path))) {
|
|
634
|
-
if (last && isNull(last[0]) && isNumber(last[1])) {
|
|
635
|
-
last[1]--;
|
|
636
|
-
} else {
|
|
637
|
-
path.pop();
|
|
638
|
-
}
|
|
656
|
+
|
|
657
|
+
// src/utilities/stack.ts
|
|
658
|
+
import { memoize as memoize3 } from "es-toolkit/function";
|
|
659
|
+
|
|
660
|
+
// src/shared.ts
|
|
661
|
+
var STACK_MAP = /* @__PURE__ */ new Map();
|
|
662
|
+
var CUSTOM_ACTION_MAP = /* @__PURE__ */ new Map();
|
|
663
|
+
var PRELOADED_ASSETS = /* @__PURE__ */ new Set();
|
|
664
|
+
var ASSETS_TO_PRELOAD = /* @__PURE__ */ new Set();
|
|
665
|
+
|
|
666
|
+
// src/utilities/stack.ts
|
|
667
|
+
var getStack = memoize3(
|
|
668
|
+
(_) => {
|
|
669
|
+
return [];
|
|
670
|
+
},
|
|
671
|
+
{
|
|
672
|
+
cache: STACK_MAP,
|
|
673
|
+
getCacheKey: (ctx) => ctx.id
|
|
639
674
|
}
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
wasExitImpossible = true;
|
|
675
|
+
);
|
|
676
|
+
var createUseStackFunction = (renderer) => {
|
|
677
|
+
const useStack = (context) => {
|
|
678
|
+
const ctx = typeof context === "string" ? renderer.getContext(context) : context;
|
|
679
|
+
const stack = getStack(ctx);
|
|
646
680
|
return {
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
path.push([`${name}:exit`]);
|
|
661
|
-
const prev = findLastPathItemBeforeItemOfType(path.slice(0, i + 1), name);
|
|
662
|
-
if (prev) path.push([null, prev[1] + 1]);
|
|
663
|
-
if (!isAction(refer(path))) {
|
|
664
|
-
path.pop();
|
|
665
|
-
continue;
|
|
666
|
-
}
|
|
667
|
-
break;
|
|
668
|
-
}
|
|
669
|
-
return {
|
|
670
|
-
exitImpossible: wasExitImpossible
|
|
671
|
-
};
|
|
672
|
-
};
|
|
673
|
-
var nextPath = (path) => {
|
|
674
|
-
const last = path.at(-1);
|
|
675
|
-
if (last && (isNull(last[0]) || last[0] === "jump") && isNumber(last[1])) {
|
|
676
|
-
last[1]++;
|
|
677
|
-
} else {
|
|
678
|
-
path.push([null, 0]);
|
|
679
|
-
}
|
|
680
|
-
return path;
|
|
681
|
-
};
|
|
682
|
-
var isBlockingAction = (action) => {
|
|
683
|
-
return isUserRequiredAction(action) || isSkippedDuringRestore(action[0]) && action[0] !== "vibrate";
|
|
684
|
-
};
|
|
685
|
-
var collectActionsBeforeBlockingAction = ({ path, refer, clone }) => {
|
|
686
|
-
const collection = [];
|
|
687
|
-
let action = refer(path);
|
|
688
|
-
while (true) {
|
|
689
|
-
if (action == void 0) {
|
|
690
|
-
const { exitImpossible } = exitPath({
|
|
691
|
-
path,
|
|
692
|
-
refer
|
|
693
|
-
});
|
|
694
|
-
if (exitImpossible) {
|
|
695
|
-
break;
|
|
696
|
-
}
|
|
697
|
-
}
|
|
698
|
-
if (!action) {
|
|
699
|
-
break;
|
|
700
|
-
}
|
|
701
|
-
if (isBlockingAction(action)) {
|
|
702
|
-
const [name, ...props] = action;
|
|
703
|
-
if (name === "choice") {
|
|
704
|
-
const choiceProps = props;
|
|
705
|
-
for (let i = 0; i < choiceProps.length; i++) {
|
|
706
|
-
const branchContent = choiceProps[i];
|
|
707
|
-
if (!Array.isArray(branchContent)) continue;
|
|
708
|
-
const virtualPath = clone(path);
|
|
709
|
-
virtualPath.push(["choice", i], [null, 0]);
|
|
710
|
-
const innerActions = collectActionsBeforeBlockingAction({
|
|
711
|
-
path: virtualPath,
|
|
712
|
-
refer,
|
|
713
|
-
clone
|
|
714
|
-
});
|
|
715
|
-
collection.push(...innerActions);
|
|
716
|
-
}
|
|
717
|
-
} else if (name === "condition") {
|
|
718
|
-
const conditionProps = props;
|
|
719
|
-
const conditions = Object.keys(conditionProps[1]);
|
|
720
|
-
for (const condition of conditions) {
|
|
721
|
-
const virtualPath = clone(path);
|
|
722
|
-
virtualPath.push(["condition", condition], [null, 0]);
|
|
723
|
-
const innerActions = collectActionsBeforeBlockingAction({
|
|
724
|
-
path: virtualPath,
|
|
725
|
-
refer,
|
|
726
|
-
clone
|
|
727
|
-
});
|
|
728
|
-
collection.push(...innerActions);
|
|
681
|
+
get previous() {
|
|
682
|
+
return stack.previous;
|
|
683
|
+
},
|
|
684
|
+
get value() {
|
|
685
|
+
return stack.at(-1);
|
|
686
|
+
},
|
|
687
|
+
set value(value) {
|
|
688
|
+
stack[stack.length - 1] = value;
|
|
689
|
+
},
|
|
690
|
+
back() {
|
|
691
|
+
if (stack.length > 1) {
|
|
692
|
+
stack.previous = stack.pop();
|
|
693
|
+
ctx.meta.goingBack = true;
|
|
729
694
|
}
|
|
695
|
+
},
|
|
696
|
+
push(value) {
|
|
697
|
+
stack.push(value);
|
|
698
|
+
},
|
|
699
|
+
clear() {
|
|
700
|
+
stack.previous = void 0;
|
|
701
|
+
stack.length = 0;
|
|
702
|
+
stack.length = 1;
|
|
730
703
|
}
|
|
731
|
-
break;
|
|
732
|
-
}
|
|
733
|
-
collection.push(action);
|
|
734
|
-
if (action[0] === "jump") {
|
|
735
|
-
path = [["jump", action[1]], [null, 0]];
|
|
736
|
-
} else if (action[0] == "block") {
|
|
737
|
-
path.push(["block", action[1]], [null, 0]);
|
|
738
|
-
} else {
|
|
739
|
-
nextPath(path);
|
|
740
|
-
}
|
|
741
|
-
action = refer(path);
|
|
742
|
-
}
|
|
743
|
-
return collection;
|
|
744
|
-
};
|
|
745
|
-
var unwrapAsset = (asset2) => {
|
|
746
|
-
return isAsset(asset2) ? asset2.source : asset2;
|
|
747
|
-
};
|
|
748
|
-
var handleAudioAsset = (asset2) => {
|
|
749
|
-
if (DEV2 && isAsset(asset2) && asset2.type !== "audio") {
|
|
750
|
-
throw new Error("Attempt to use non-audio asset in audio action", { cause: asset2 });
|
|
751
|
-
}
|
|
752
|
-
return unwrapAsset(asset2);
|
|
753
|
-
};
|
|
754
|
-
var handleImageAsset = (asset2) => {
|
|
755
|
-
if (DEV2 && isAsset(asset2) && asset2.type !== "image") {
|
|
756
|
-
throw new Error("Attempt to use non-image asset in action that requires image assets", { cause: asset2 });
|
|
757
|
-
}
|
|
758
|
-
return unwrapAsset(asset2);
|
|
759
|
-
};
|
|
760
|
-
var getCharactersData = (characters) => {
|
|
761
|
-
const entries = Object.entries(characters);
|
|
762
|
-
const mapped = entries.map(([key, value]) => [key, { name: value.name, emotions: Object.keys(value.emotions) }]);
|
|
763
|
-
return Object.fromEntries(mapped);
|
|
764
|
-
};
|
|
765
|
-
var toArray = (target) => {
|
|
766
|
-
return Array.isArray(target) ? target : [target];
|
|
767
|
-
};
|
|
768
|
-
var getLanguageFromStore = (store2) => {
|
|
769
|
-
return store2.get().meta[0];
|
|
770
|
-
};
|
|
771
|
-
var getVolumeFromStore = (store2) => {
|
|
772
|
-
const { meta } = store2.get();
|
|
773
|
-
return {
|
|
774
|
-
music: meta[2],
|
|
775
|
-
sound: meta[3],
|
|
776
|
-
voice: meta[4]
|
|
777
|
-
};
|
|
778
|
-
};
|
|
779
|
-
|
|
780
|
-
// src/novely.ts
|
|
781
|
-
import { throttle } from "es-toolkit/function";
|
|
782
|
-
import { merge as deepmerge } from "es-toolkit/object";
|
|
783
|
-
import { dequal } from "dequal/lite";
|
|
784
|
-
|
|
785
|
-
// src/store.ts
|
|
786
|
-
var store = (current, subscribers = /* @__PURE__ */ new Set()) => {
|
|
787
|
-
const subscribe = (cb) => {
|
|
788
|
-
subscribers.add(cb), cb(current);
|
|
789
|
-
return () => {
|
|
790
|
-
subscribers.delete(cb);
|
|
791
704
|
};
|
|
792
705
|
};
|
|
793
|
-
|
|
794
|
-
for (const cb of subscribers) cb(value);
|
|
795
|
-
};
|
|
796
|
-
const update = (fn) => {
|
|
797
|
-
push(current = fn(current));
|
|
798
|
-
};
|
|
799
|
-
const set2 = (val) => {
|
|
800
|
-
update(() => val);
|
|
801
|
-
};
|
|
802
|
-
const get = () => {
|
|
803
|
-
return current;
|
|
804
|
-
};
|
|
805
|
-
return { subscribe, update, set: set2, get };
|
|
706
|
+
return useStack;
|
|
806
707
|
};
|
|
807
708
|
|
|
808
|
-
//
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
}
|
|
815
|
-
function klona(x) {
|
|
816
|
-
if (typeof x !== "object") return x;
|
|
817
|
-
var i = 0, k, list, tmp, str2 = Object.prototype.toString.call(x);
|
|
818
|
-
if (str2 === "[object Object]") {
|
|
819
|
-
tmp = Object.create(x.__proto__ || null);
|
|
820
|
-
} else if (str2 === "[object Array]") {
|
|
821
|
-
tmp = Array(x.length);
|
|
822
|
-
} else if (str2 === "[object Set]") {
|
|
823
|
-
tmp = /* @__PURE__ */ new Set();
|
|
824
|
-
x.forEach(function(val) {
|
|
825
|
-
tmp.add(klona(val));
|
|
826
|
-
});
|
|
827
|
-
} else if (str2 === "[object Map]") {
|
|
828
|
-
tmp = /* @__PURE__ */ new Map();
|
|
829
|
-
x.forEach(function(val, key) {
|
|
830
|
-
tmp.set(klona(key), klona(val));
|
|
831
|
-
});
|
|
832
|
-
} else if (str2 === "[object Date]") {
|
|
833
|
-
tmp = /* @__PURE__ */ new Date(+x);
|
|
834
|
-
} else if (str2 === "[object RegExp]") {
|
|
835
|
-
tmp = new RegExp(x.source, x.flags);
|
|
836
|
-
} else if (str2 === "[object DataView]") {
|
|
837
|
-
tmp = new x.constructor(klona(x.buffer));
|
|
838
|
-
} else if (str2 === "[object ArrayBuffer]") {
|
|
839
|
-
tmp = x.slice(0);
|
|
840
|
-
} else if (str2.slice(-6) === "Array]") {
|
|
841
|
-
tmp = new x.constructor(x);
|
|
842
|
-
}
|
|
843
|
-
if (tmp) {
|
|
844
|
-
for (list = Object.getOwnPropertySymbols(x); i < list.length; i++) {
|
|
845
|
-
set(tmp, list[i], Object.getOwnPropertyDescriptor(x, list[i]));
|
|
846
|
-
}
|
|
847
|
-
for (i = 0, list = Object.getOwnPropertyNames(x); i < list.length; i++) {
|
|
848
|
-
if (Object.hasOwnProperty.call(tmp, k = list[i]) && tmp[k] === x[k]) continue;
|
|
849
|
-
set(tmp, k, Object.getOwnPropertyDescriptor(x, k));
|
|
850
|
-
}
|
|
851
|
-
}
|
|
852
|
-
return tmp || x;
|
|
853
|
-
}
|
|
854
|
-
|
|
855
|
-
// src/translation.ts
|
|
856
|
-
var RGX = /{{(.*?)}}/g;
|
|
857
|
-
var split = (input, delimeters) => {
|
|
858
|
-
const output = [];
|
|
859
|
-
for (const delimeter of delimeters) {
|
|
860
|
-
if (!input) break;
|
|
861
|
-
const [start, end] = input.split(delimeter, 2);
|
|
862
|
-
output.push(start);
|
|
863
|
-
input = end;
|
|
864
|
-
}
|
|
865
|
-
output.push(input);
|
|
866
|
-
return output;
|
|
709
|
+
// src/utilities/story.ts
|
|
710
|
+
var flatActions = (item) => {
|
|
711
|
+
return item.flatMap((data) => {
|
|
712
|
+
const type = data[0];
|
|
713
|
+
if (Array.isArray(type)) return flatActions(data);
|
|
714
|
+
return [data];
|
|
715
|
+
});
|
|
867
716
|
};
|
|
868
|
-
var
|
|
869
|
-
|
|
870
|
-
return
|
|
871
|
-
}
|
|
872
|
-
|
|
873
|
-
return flattenAllowedContent(c(state), state);
|
|
874
|
-
}
|
|
875
|
-
return c;
|
|
717
|
+
var flatStory = (story) => {
|
|
718
|
+
const entries = Object.entries(story).map(([name, items]) => {
|
|
719
|
+
return [name, flatActions(items)];
|
|
720
|
+
});
|
|
721
|
+
return Object.fromEntries(entries);
|
|
876
722
|
};
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
if (
|
|
883
|
-
|
|
884
|
-
}
|
|
885
|
-
const path = pathstr.split(".");
|
|
886
|
-
while (y && x < path.length) y = y[path[x++]];
|
|
887
|
-
if (plural && pluralization && y && pr) {
|
|
888
|
-
y = pluralization[plural][pr.select(y)];
|
|
723
|
+
|
|
724
|
+
// src/browser.ts
|
|
725
|
+
var setupBrowserVisibilityChangeListeners = ({ onChange }) => {
|
|
726
|
+
if (typeof document === "undefined") return noop;
|
|
727
|
+
const onVisibilityChange = () => {
|
|
728
|
+
if (document.visibilityState === "hidden") {
|
|
729
|
+
onChange();
|
|
889
730
|
}
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
731
|
+
};
|
|
732
|
+
addEventListener("visibilitychange", onVisibilityChange);
|
|
733
|
+
addEventListener("beforeunload", onChange);
|
|
734
|
+
return () => {
|
|
735
|
+
removeEventListener("visibilitychange", onVisibilityChange);
|
|
736
|
+
removeEventListener("beforeunload", onChange);
|
|
737
|
+
};
|
|
894
738
|
};
|
|
895
739
|
|
|
896
740
|
// src/custom-action.ts
|
|
@@ -933,13 +777,15 @@ var handleCustomAction = (ctx, fn, { lang, state, setMountElement, setClear, rem
|
|
|
933
777
|
};
|
|
934
778
|
};
|
|
935
779
|
const clear = (func) => {
|
|
936
|
-
setClear(
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
780
|
+
setClear(
|
|
781
|
+
holder.cleanup = () => {
|
|
782
|
+
func();
|
|
783
|
+
holder.node = null;
|
|
784
|
+
holder.cleanup = noop;
|
|
785
|
+
setMountElement(null);
|
|
786
|
+
setClear(noop);
|
|
787
|
+
}
|
|
788
|
+
);
|
|
943
789
|
};
|
|
944
790
|
const data = (updatedData) => {
|
|
945
791
|
if (updatedData) {
|
|
@@ -952,76 +798,40 @@ var handleCustomAction = (ctx, fn, { lang, state, setMountElement, setClear, rem
|
|
|
952
798
|
renderersRemove();
|
|
953
799
|
};
|
|
954
800
|
const stack = getStack2(ctx);
|
|
955
|
-
const getPath = () => {
|
|
956
|
-
return stack.value[0];
|
|
957
|
-
};
|
|
958
|
-
return fn({
|
|
959
|
-
flags,
|
|
960
|
-
lang,
|
|
961
|
-
state,
|
|
962
|
-
data,
|
|
963
|
-
clear,
|
|
964
|
-
remove,
|
|
965
|
-
rendererContext: ctx,
|
|
966
|
-
getDomNodes,
|
|
967
|
-
getPath,
|
|
968
|
-
contextKey: ctx.id
|
|
969
|
-
});
|
|
970
|
-
};
|
|
971
|
-
|
|
972
|
-
// src/storage.ts
|
|
973
|
-
var localStorageStorage = (options) => {
|
|
974
|
-
return {
|
|
975
|
-
async get() {
|
|
976
|
-
const fallback = { saves: [], data: {}, meta: [] };
|
|
977
|
-
try {
|
|
978
|
-
const value = localStorage.getItem(options.key);
|
|
979
|
-
return value ? JSON.parse(value) : fallback;
|
|
980
|
-
} catch {
|
|
981
|
-
return fallback;
|
|
982
|
-
}
|
|
983
|
-
},
|
|
984
|
-
async set(data) {
|
|
985
|
-
try {
|
|
986
|
-
localStorage.setItem(options.key, JSON.stringify(data));
|
|
987
|
-
} catch {
|
|
988
|
-
}
|
|
989
|
-
}
|
|
990
|
-
};
|
|
991
|
-
};
|
|
992
|
-
|
|
993
|
-
// src/browser.ts
|
|
994
|
-
var setupBrowserVisibilityChangeListeners = ({ onChange }) => {
|
|
995
|
-
if (typeof document === "undefined") return noop;
|
|
996
|
-
const onVisibilityChange = () => {
|
|
997
|
-
if (document.visibilityState === "hidden") {
|
|
998
|
-
onChange();
|
|
999
|
-
}
|
|
1000
|
-
};
|
|
1001
|
-
addEventListener("visibilitychange", onVisibilityChange);
|
|
1002
|
-
addEventListener("beforeunload", onChange);
|
|
1003
|
-
return () => {
|
|
1004
|
-
removeEventListener("visibilitychange", onVisibilityChange);
|
|
1005
|
-
removeEventListener("beforeunload", onChange);
|
|
801
|
+
const getPath = () => {
|
|
802
|
+
return stack.value[0];
|
|
1006
803
|
};
|
|
804
|
+
return fn({
|
|
805
|
+
flags,
|
|
806
|
+
lang,
|
|
807
|
+
state,
|
|
808
|
+
data,
|
|
809
|
+
clear,
|
|
810
|
+
remove,
|
|
811
|
+
rendererContext: ctx,
|
|
812
|
+
getDomNodes,
|
|
813
|
+
getPath,
|
|
814
|
+
contextKey: ctx.id
|
|
815
|
+
});
|
|
1007
816
|
};
|
|
1008
817
|
|
|
1009
|
-
// src/novely.ts
|
|
1010
|
-
import pLimit from "p-limit";
|
|
1011
|
-
import { DEV as DEV3 } from "esm-env";
|
|
1012
|
-
|
|
1013
818
|
// src/preloading.ts
|
|
1014
819
|
var ACTION_NAME_TO_VOLUME_MAP = {
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
820
|
+
playMusic: "music",
|
|
821
|
+
playSound: "sound",
|
|
822
|
+
voice: "voice"
|
|
1018
823
|
};
|
|
1019
824
|
var enqueueAssetForPreloading = (asset2) => {
|
|
1020
825
|
if (!PRELOADED_ASSETS.has(asset2)) {
|
|
1021
826
|
ASSETS_TO_PRELOAD.add(asset2);
|
|
1022
827
|
}
|
|
1023
828
|
};
|
|
1024
|
-
var handleAssetsPreloading = async ({
|
|
829
|
+
var handleAssetsPreloading = async ({
|
|
830
|
+
request,
|
|
831
|
+
limiter,
|
|
832
|
+
preloadAudioBlocking,
|
|
833
|
+
preloadImageBlocking
|
|
834
|
+
}) => {
|
|
1025
835
|
const list = mapSet(ASSETS_TO_PRELOAD, (asset2) => {
|
|
1026
836
|
return limiter(async () => {
|
|
1027
837
|
const type = await getResourseType({
|
|
@@ -1096,9 +906,9 @@ var huntAssets = ({ volume, lang, mode, characters, action, props, handle }) =>
|
|
|
1096
906
|
}
|
|
1097
907
|
return;
|
|
1098
908
|
}
|
|
1099
|
-
if (action === "custom" && props[0].assets
|
|
909
|
+
if (action === "custom" && props[0].assets) {
|
|
1100
910
|
for (const asset2 of props[0].assets) {
|
|
1101
|
-
handle(asset2);
|
|
911
|
+
isAsset(asset2) ? handle(asset2.source) : handle(asset2);
|
|
1102
912
|
}
|
|
1103
913
|
return;
|
|
1104
914
|
}
|
|
@@ -1106,10 +916,95 @@ var huntAssets = ({ volume, lang, mode, characters, action, props, handle }) =>
|
|
|
1106
916
|
for (let i = 1; i < props.length; i++) {
|
|
1107
917
|
const data = props[i];
|
|
1108
918
|
if (Array.isArray(data)) {
|
|
1109
|
-
handle(handleImageAsset(data[
|
|
919
|
+
handle(handleImageAsset(data[5]));
|
|
920
|
+
}
|
|
921
|
+
}
|
|
922
|
+
}
|
|
923
|
+
};
|
|
924
|
+
|
|
925
|
+
// src/storage.ts
|
|
926
|
+
var localStorageStorage = (options) => {
|
|
927
|
+
return {
|
|
928
|
+
async get() {
|
|
929
|
+
const fallback = { saves: [], data: {}, meta: [] };
|
|
930
|
+
try {
|
|
931
|
+
const value = localStorage.getItem(options.key);
|
|
932
|
+
return value ? JSON.parse(value) : fallback;
|
|
933
|
+
} catch {
|
|
934
|
+
return fallback;
|
|
935
|
+
}
|
|
936
|
+
},
|
|
937
|
+
async set(data) {
|
|
938
|
+
try {
|
|
939
|
+
localStorage.setItem(options.key, JSON.stringify(data));
|
|
940
|
+
} catch {
|
|
1110
941
|
}
|
|
1111
942
|
}
|
|
943
|
+
};
|
|
944
|
+
};
|
|
945
|
+
|
|
946
|
+
// src/store.ts
|
|
947
|
+
var store = (current, subscribers = /* @__PURE__ */ new Set()) => {
|
|
948
|
+
const subscribe = (cb) => {
|
|
949
|
+
subscribers.add(cb), cb(current);
|
|
950
|
+
return () => {
|
|
951
|
+
subscribers.delete(cb);
|
|
952
|
+
};
|
|
953
|
+
};
|
|
954
|
+
const push = (value) => {
|
|
955
|
+
for (const cb of subscribers) cb(value);
|
|
956
|
+
};
|
|
957
|
+
const update = (fn) => {
|
|
958
|
+
push(current = fn(current));
|
|
959
|
+
};
|
|
960
|
+
const set2 = (val) => {
|
|
961
|
+
update(() => val);
|
|
962
|
+
};
|
|
963
|
+
const get = () => {
|
|
964
|
+
return current;
|
|
965
|
+
};
|
|
966
|
+
return { subscribe, update, set: set2, get };
|
|
967
|
+
};
|
|
968
|
+
|
|
969
|
+
// src/translation.ts
|
|
970
|
+
var RGX = /{{(.*?)}}/g;
|
|
971
|
+
var split = (input, delimeters) => {
|
|
972
|
+
const output = [];
|
|
973
|
+
for (const delimeter of delimeters) {
|
|
974
|
+
if (!input) break;
|
|
975
|
+
const [start, end] = input.split(delimeter, 2);
|
|
976
|
+
output.push(start);
|
|
977
|
+
input = end;
|
|
978
|
+
}
|
|
979
|
+
output.push(input);
|
|
980
|
+
return output;
|
|
981
|
+
};
|
|
982
|
+
var flattenAllowedContent = (c, state) => {
|
|
983
|
+
if (Array.isArray(c)) {
|
|
984
|
+
return c.map((item) => flattenAllowedContent(item, state)).join("<br>");
|
|
985
|
+
}
|
|
986
|
+
if (typeof c === "function") {
|
|
987
|
+
return flattenAllowedContent(c(state), state);
|
|
1112
988
|
}
|
|
989
|
+
return c;
|
|
990
|
+
};
|
|
991
|
+
var replace = (input, data, pluralization, actions, pr) => {
|
|
992
|
+
return input.replaceAll(RGX, (x, key, y) => {
|
|
993
|
+
x = 0;
|
|
994
|
+
y = data;
|
|
995
|
+
const [pathstr, plural, action] = split(key.trim(), ["@", "%"]);
|
|
996
|
+
if (!pathstr) {
|
|
997
|
+
return "";
|
|
998
|
+
}
|
|
999
|
+
const path = pathstr.split(".");
|
|
1000
|
+
while (y && x < path.length) y = y[path[x++]];
|
|
1001
|
+
if (plural && pluralization && y && pr) {
|
|
1002
|
+
y = pluralization[plural][pr.select(y)];
|
|
1003
|
+
}
|
|
1004
|
+
const actionHandler = actions && action ? actions[action] : void 0;
|
|
1005
|
+
if (actionHandler) y = actionHandler(y);
|
|
1006
|
+
return y == null ? "" : y;
|
|
1007
|
+
});
|
|
1113
1008
|
};
|
|
1114
1009
|
|
|
1115
1010
|
// src/novely.ts
|
|
@@ -1150,7 +1045,7 @@ var novely = ({
|
|
|
1150
1045
|
};
|
|
1151
1046
|
const scriptBase = async (part) => {
|
|
1152
1047
|
if (destroyed) return;
|
|
1153
|
-
Object.assign(story,
|
|
1048
|
+
Object.assign(story, flatStory(part));
|
|
1154
1049
|
let loadingIsShown = false;
|
|
1155
1050
|
if (!initialScreenWasShown) {
|
|
1156
1051
|
renderer.ui.showLoading();
|
|
@@ -1229,7 +1124,8 @@ var novely = ({
|
|
|
1229
1124
|
[null, 0]
|
|
1230
1125
|
],
|
|
1231
1126
|
state,
|
|
1232
|
-
[intime(Date.now()), "auto"]
|
|
1127
|
+
[intime(Date.now()), "auto"],
|
|
1128
|
+
[]
|
|
1233
1129
|
];
|
|
1234
1130
|
};
|
|
1235
1131
|
const getLanguageWithoutParameters = () => {
|
|
@@ -1238,7 +1134,9 @@ var novely = ({
|
|
|
1238
1134
|
return language;
|
|
1239
1135
|
}
|
|
1240
1136
|
if (DEV3) {
|
|
1241
|
-
throw new Error(
|
|
1137
|
+
throw new Error(
|
|
1138
|
+
`Attempt to use unsupported language "${language}". Supported languages: ${languages.join(", ")}.`
|
|
1139
|
+
);
|
|
1242
1140
|
}
|
|
1243
1141
|
throw 0;
|
|
1244
1142
|
};
|
|
@@ -1354,7 +1252,9 @@ var novely = ({
|
|
|
1354
1252
|
const restore = async (save2) => {
|
|
1355
1253
|
if (isEmpty(story)) {
|
|
1356
1254
|
if (DEV3) {
|
|
1357
|
-
throw new Error(
|
|
1255
|
+
throw new Error(
|
|
1256
|
+
"Story is empty. You should call an `enine.script` function [https://novely.pages.dev/guide/story.html]"
|
|
1257
|
+
);
|
|
1358
1258
|
}
|
|
1359
1259
|
return;
|
|
1360
1260
|
}
|
|
@@ -1374,7 +1274,10 @@ var novely = ({
|
|
|
1374
1274
|
const [path] = stack.value = latest;
|
|
1375
1275
|
renderer.ui.showScreen("game");
|
|
1376
1276
|
const { queue, skip, skipPreserve } = getActionsFromPath(story, path, false);
|
|
1377
|
-
const {
|
|
1277
|
+
const {
|
|
1278
|
+
run,
|
|
1279
|
+
keep: { keep, characters: characters2, audio: audio2 }
|
|
1280
|
+
} = createQueueProcessor(queue, {
|
|
1378
1281
|
skip,
|
|
1379
1282
|
skipPreserve
|
|
1380
1283
|
});
|
|
@@ -1424,7 +1327,9 @@ var novely = ({
|
|
|
1424
1327
|
const isSaved = () => {
|
|
1425
1328
|
const { saves } = storageData.get();
|
|
1426
1329
|
const [currentPath, currentData] = stack.value;
|
|
1427
|
-
return saves.some(
|
|
1330
|
+
return saves.some(
|
|
1331
|
+
([path, data2, [date, type2]]) => type2 === "manual" && times.has(date) && dequal(path, currentPath) && dequal(data2, currentData)
|
|
1332
|
+
);
|
|
1428
1333
|
};
|
|
1429
1334
|
if (interacted > 1 && !force && askBeforeExit && !isSaved()) {
|
|
1430
1335
|
renderer.ui.showExitPrompt();
|
|
@@ -1520,7 +1425,9 @@ var novely = ({
|
|
|
1520
1425
|
const getLanguageDisplayName = (lang) => {
|
|
1521
1426
|
const language = translation[lang];
|
|
1522
1427
|
if (DEV3 && !language) {
|
|
1523
|
-
throw new Error(
|
|
1428
|
+
throw new Error(
|
|
1429
|
+
`Attempt to use unsupported language "${language}". Supported languages: ${languages.join(", ")}.`
|
|
1430
|
+
);
|
|
1524
1431
|
}
|
|
1525
1432
|
return capitalize(language.nameOverride || getIntlLanguageDisplayName(lang));
|
|
1526
1433
|
};
|
|
@@ -1539,6 +1446,61 @@ var novely = ({
|
|
|
1539
1446
|
const getCharacterAssets = (character, emotion) => {
|
|
1540
1447
|
return toArray(characters[character].emotions[emotion]).map(handleImageAsset);
|
|
1541
1448
|
};
|
|
1449
|
+
const getCharacterName = (character) => {
|
|
1450
|
+
const c = character;
|
|
1451
|
+
const cs = characters;
|
|
1452
|
+
const [lang] = storageData.get().meta;
|
|
1453
|
+
if (c && c in cs) {
|
|
1454
|
+
const block = cs[c].name;
|
|
1455
|
+
if (typeof block === "string") {
|
|
1456
|
+
return block;
|
|
1457
|
+
}
|
|
1458
|
+
if (lang in block) {
|
|
1459
|
+
return block[lang];
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1462
|
+
return String(c) || "";
|
|
1463
|
+
};
|
|
1464
|
+
const getDialogOverview = () => {
|
|
1465
|
+
const { value: save2 } = useStack(MAIN_CONTEXT_KEY);
|
|
1466
|
+
const stateSnapshots = save2[3];
|
|
1467
|
+
const { queue } = getActionsFromPath(story, save2[0], false);
|
|
1468
|
+
const [lang] = storageData.get().meta;
|
|
1469
|
+
const dialogItem = [];
|
|
1470
|
+
for (let p = 0, i = 0; i < queue.length; i++) {
|
|
1471
|
+
const action2 = queue[i];
|
|
1472
|
+
if (action2[0] === "dialog") {
|
|
1473
|
+
const [_, name, text] = action2;
|
|
1474
|
+
let voice = void 0;
|
|
1475
|
+
for (let j = i - 1; j > p; j--) {
|
|
1476
|
+
const action3 = queue[j];
|
|
1477
|
+
if (isUserRequiredAction(action3) || isSkippedDuringRestore(action3[0])) break;
|
|
1478
|
+
if (action3[0] === "stopVoice") break;
|
|
1479
|
+
if (action3[0] === "voice") {
|
|
1480
|
+
voice = action3[1];
|
|
1481
|
+
break;
|
|
1482
|
+
}
|
|
1483
|
+
}
|
|
1484
|
+
dialogItem.push({
|
|
1485
|
+
name,
|
|
1486
|
+
text,
|
|
1487
|
+
voice
|
|
1488
|
+
});
|
|
1489
|
+
p = i;
|
|
1490
|
+
}
|
|
1491
|
+
}
|
|
1492
|
+
const entries = dialogItem.map(({ name, text, voice }, i) => {
|
|
1493
|
+
const state = stateSnapshots[i];
|
|
1494
|
+
const audioSource = isString(voice) ? voice : isAsset(voice) ? voice : voice == void 0 ? voice : voice[lang];
|
|
1495
|
+
name = name ? getCharacterName(name) : "";
|
|
1496
|
+
return {
|
|
1497
|
+
name: templateReplace(name, state),
|
|
1498
|
+
text: templateReplace(text, state),
|
|
1499
|
+
voice: audioSource ? handleAudioAsset(audioSource) : ""
|
|
1500
|
+
};
|
|
1501
|
+
});
|
|
1502
|
+
return entries;
|
|
1503
|
+
};
|
|
1542
1504
|
const renderer = createRenderer({
|
|
1543
1505
|
mainContextKey: MAIN_CONTEXT_KEY,
|
|
1544
1506
|
characters: getCharactersData(characters),
|
|
@@ -1560,6 +1522,7 @@ var novely = ({
|
|
|
1560
1522
|
getLanguageDisplayName,
|
|
1561
1523
|
getCharacterColor,
|
|
1562
1524
|
getCharacterAssets,
|
|
1525
|
+
getDialogOverview,
|
|
1563
1526
|
getResourseType: getResourseTypeForRenderer
|
|
1564
1527
|
});
|
|
1565
1528
|
const useStack = createUseStackFunction(renderer);
|
|
@@ -1622,17 +1585,19 @@ var novely = ({
|
|
|
1622
1585
|
}
|
|
1623
1586
|
};
|
|
1624
1587
|
const match = matchAction(matchActionOptions, {
|
|
1625
|
-
wait({ ctx, push }, [time]) {
|
|
1588
|
+
wait({ ctx, data: data2, push }, [time]) {
|
|
1626
1589
|
if (ctx.meta.restoring) return;
|
|
1627
|
-
setTimeout(push, isFunction(time) ? time(
|
|
1590
|
+
setTimeout(push, isFunction(time) ? time(data2) : time);
|
|
1628
1591
|
},
|
|
1629
1592
|
showBackground({ ctx, push }, [background]) {
|
|
1630
1593
|
if (isString(background) || isAsset(background)) {
|
|
1631
1594
|
ctx.background({
|
|
1632
|
-
|
|
1595
|
+
all: handleImageAsset(background)
|
|
1633
1596
|
});
|
|
1634
1597
|
} else {
|
|
1635
|
-
ctx.background(
|
|
1598
|
+
ctx.background(
|
|
1599
|
+
Object.fromEntries(Object.entries(background).map(([media, asset2]) => [media, handleImageAsset(asset2)]))
|
|
1600
|
+
);
|
|
1636
1601
|
}
|
|
1637
1602
|
push();
|
|
1638
1603
|
},
|
|
@@ -1692,29 +1657,13 @@ var novely = ({
|
|
|
1692
1657
|
ctx.character(character).remove(className, style, duration, ctx.meta.restoring).then(push);
|
|
1693
1658
|
},
|
|
1694
1659
|
dialog({ ctx, data: data2, forward }, [character, content, emotion]) {
|
|
1695
|
-
const name = (
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
const block = cs[c].name;
|
|
1701
|
-
if (typeof block === "string") {
|
|
1702
|
-
return block;
|
|
1703
|
-
}
|
|
1704
|
-
if (lang in block) {
|
|
1705
|
-
return block[lang];
|
|
1706
|
-
}
|
|
1707
|
-
}
|
|
1708
|
-
return c || "";
|
|
1709
|
-
})();
|
|
1660
|
+
const name = getCharacterName(character);
|
|
1661
|
+
const stack = useStack(ctx);
|
|
1662
|
+
if (!ctx.meta.restoring && !ctx.meta.goingBack) {
|
|
1663
|
+
stack.value[3].push(clone(data2));
|
|
1664
|
+
}
|
|
1710
1665
|
ctx.clearBlockingActions("dialog");
|
|
1711
|
-
ctx.dialog(
|
|
1712
|
-
templateReplace(content, data2),
|
|
1713
|
-
templateReplace(name, data2),
|
|
1714
|
-
character,
|
|
1715
|
-
emotion,
|
|
1716
|
-
forward
|
|
1717
|
-
);
|
|
1666
|
+
ctx.dialog(templateReplace(content, data2), templateReplace(name, data2), character, emotion, forward);
|
|
1718
1667
|
},
|
|
1719
1668
|
function({ ctx, push }, [fn]) {
|
|
1720
1669
|
const { restoring, goingBack, preview: preview2 } = ctx.meta;
|
|
@@ -1739,19 +1688,19 @@ var novely = ({
|
|
|
1739
1688
|
const transformedChoices = choices.map(([content, _children, active, visible, onSelect, image]) => {
|
|
1740
1689
|
const active$ = store(false);
|
|
1741
1690
|
const visible$ = store(false);
|
|
1742
|
-
const
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
});
|
|
1749
|
-
const visibleValue = !visible || visible({
|
|
1691
|
+
const lang = getLanguageFromStore(storageData);
|
|
1692
|
+
const getCheckValue = (fn) => {
|
|
1693
|
+
if (!fn) {
|
|
1694
|
+
return true;
|
|
1695
|
+
}
|
|
1696
|
+
return fn({
|
|
1750
1697
|
lang,
|
|
1751
|
-
state
|
|
1698
|
+
state: getStateAtCtx(ctx)
|
|
1752
1699
|
});
|
|
1753
|
-
|
|
1754
|
-
|
|
1700
|
+
};
|
|
1701
|
+
const update = () => {
|
|
1702
|
+
active$.set(getCheckValue(active));
|
|
1703
|
+
visible$.set(getCheckValue(visible));
|
|
1755
1704
|
};
|
|
1756
1705
|
update();
|
|
1757
1706
|
const onSelectGuarded = onSelect || noop;
|
|
@@ -1764,7 +1713,9 @@ var novely = ({
|
|
|
1764
1713
|
return [templateReplace(content, data2), active$, visible$, onSelectWrapped, imageValue];
|
|
1765
1714
|
});
|
|
1766
1715
|
if (DEV3 && transformedChoices.length === 0) {
|
|
1767
|
-
throw new Error(
|
|
1716
|
+
throw new Error(
|
|
1717
|
+
`Running choice without variants to choose from, look at how to use Choice action properly [https://novely.pages.dev/guide/actions/choice#usage]`
|
|
1718
|
+
);
|
|
1768
1719
|
}
|
|
1769
1720
|
ctx.clearBlockingActions("choice");
|
|
1770
1721
|
ctx.choices(templateReplace(question, data2), transformedChoices, (selected) => {
|
|
@@ -1793,6 +1744,7 @@ var novely = ({
|
|
|
1793
1744
|
["jump", scene],
|
|
1794
1745
|
[null, -1]
|
|
1795
1746
|
];
|
|
1747
|
+
stack.value[3] = [];
|
|
1796
1748
|
match("clear", [], {
|
|
1797
1749
|
ctx,
|
|
1798
1750
|
data: data2
|
|
@@ -1807,19 +1759,19 @@ var novely = ({
|
|
|
1807
1759
|
push
|
|
1808
1760
|
);
|
|
1809
1761
|
},
|
|
1810
|
-
condition({ ctx }, [condition, variants]) {
|
|
1762
|
+
condition({ ctx, data: data2 }, [condition, variants]) {
|
|
1811
1763
|
if (DEV3 && Object.values(variants).length === 0) {
|
|
1812
1764
|
throw new Error(`Attempt to use Condition action with empty variants object`);
|
|
1813
1765
|
}
|
|
1814
1766
|
if (!ctx.meta.restoring) {
|
|
1815
|
-
const val = String(condition(
|
|
1767
|
+
const val = String(condition(data2));
|
|
1816
1768
|
if (DEV3 && !variants[val]) {
|
|
1817
1769
|
throw new Error(`Attempt to go to unknown variant "${val}"`);
|
|
1818
1770
|
}
|
|
1819
1771
|
if (DEV3 && variants[val].length === 0) {
|
|
1820
1772
|
throw new Error(`Attempt to go to empty variant "${val}"`);
|
|
1821
1773
|
}
|
|
1822
|
-
const stack = useStack(
|
|
1774
|
+
const stack = useStack(ctx);
|
|
1823
1775
|
stack.value[0].push(["condition", val], [null, 0]);
|
|
1824
1776
|
render(ctx);
|
|
1825
1777
|
}
|
|
@@ -1830,12 +1782,7 @@ var novely = ({
|
|
|
1830
1782
|
},
|
|
1831
1783
|
input({ ctx, data: data2, forward }, [question, onInput, setup]) {
|
|
1832
1784
|
ctx.clearBlockingActions("input");
|
|
1833
|
-
ctx.input(
|
|
1834
|
-
templateReplace(question, data2),
|
|
1835
|
-
onInput,
|
|
1836
|
-
setup || noop,
|
|
1837
|
-
forward
|
|
1838
|
-
);
|
|
1785
|
+
ctx.input(templateReplace(question, data2), onInput, setup || noop, forward);
|
|
1839
1786
|
},
|
|
1840
1787
|
custom({ ctx, push }, [fn]) {
|
|
1841
1788
|
if (fn.requireUserAction) {
|
|
@@ -1875,7 +1822,9 @@ var novely = ({
|
|
|
1875
1822
|
animateCharacter({ ctx, push }, [character, className]) {
|
|
1876
1823
|
const classes = className.split(" ");
|
|
1877
1824
|
if (DEV3 && classes.length === 0) {
|
|
1878
|
-
throw new Error(
|
|
1825
|
+
throw new Error(
|
|
1826
|
+
"Attempt to use AnimateCharacter without classes. Classes should be provided [https://novely.pages.dev/guide/actions/animateCharacter.html]"
|
|
1827
|
+
);
|
|
1879
1828
|
}
|
|
1880
1829
|
if (ctx.meta.preview) return;
|
|
1881
1830
|
ctx.character(character).animate(classes);
|
|
@@ -1909,7 +1858,9 @@ var novely = ({
|
|
|
1909
1858
|
},
|
|
1910
1859
|
preload({ ctx, push }, [source]) {
|
|
1911
1860
|
if (DEV3 && preloadAssets !== "lazy") {
|
|
1912
|
-
console.error(
|
|
1861
|
+
console.error(
|
|
1862
|
+
`You do not need a preload action becase "preloadAssets" strategy was set to "${preloadAssets}"`
|
|
1863
|
+
);
|
|
1913
1864
|
}
|
|
1914
1865
|
if (!ctx.meta.goingBack && !ctx.meta.restoring && !PRELOADED_ASSETS.has(source)) {
|
|
1915
1866
|
PRELOADED_ASSETS.add(renderer.misc.preloadImage(source));
|
|
@@ -1932,22 +1883,23 @@ var novely = ({
|
|
|
1932
1883
|
});
|
|
1933
1884
|
const render = (ctx) => {
|
|
1934
1885
|
const stack = useStack(ctx);
|
|
1935
|
-
const
|
|
1886
|
+
const [path, state] = stack.value;
|
|
1887
|
+
const referred = refer(path);
|
|
1936
1888
|
if (isAction(referred)) {
|
|
1937
1889
|
const [action2, ...props] = referred;
|
|
1938
1890
|
match(action2, props, {
|
|
1939
1891
|
ctx,
|
|
1940
|
-
data:
|
|
1892
|
+
data: state
|
|
1941
1893
|
});
|
|
1942
1894
|
} else if (Object.values(story).some((branch) => branch === referred)) {
|
|
1943
1895
|
match("end", [], {
|
|
1944
1896
|
ctx,
|
|
1945
|
-
data:
|
|
1897
|
+
data: state
|
|
1946
1898
|
});
|
|
1947
1899
|
} else {
|
|
1948
1900
|
match("exit", [], {
|
|
1949
1901
|
ctx,
|
|
1950
|
-
data:
|
|
1902
|
+
data: state
|
|
1951
1903
|
});
|
|
1952
1904
|
}
|
|
1953
1905
|
};
|
|
@@ -1955,21 +1907,15 @@ var novely = ({
|
|
|
1955
1907
|
interacted = value ? interacted + 1 : 0;
|
|
1956
1908
|
};
|
|
1957
1909
|
const templateReplace = (content, values) => {
|
|
1958
|
-
const {
|
|
1910
|
+
const {
|
|
1911
|
+
data: data2,
|
|
1912
|
+
meta: [lang]
|
|
1913
|
+
} = storageData.get();
|
|
1959
1914
|
const obj = values || data2;
|
|
1960
|
-
const
|
|
1961
|
-
!isFunction(content) && !isString(content) ? content[lang] : content,
|
|
1962
|
-
obj
|
|
1963
|
-
);
|
|
1915
|
+
const str = flattenAllowedContent(!isFunction(content) && !isString(content) ? content[lang] : content, obj);
|
|
1964
1916
|
const t2 = translation[lang];
|
|
1965
1917
|
const pluralRules = (t2.plural || t2.actions) && new Intl.PluralRules(t2.tag || lang);
|
|
1966
|
-
return replace(
|
|
1967
|
-
str2,
|
|
1968
|
-
obj,
|
|
1969
|
-
t2.plural,
|
|
1970
|
-
t2.actions,
|
|
1971
|
-
pluralRules
|
|
1972
|
-
);
|
|
1918
|
+
return replace(str, obj, t2.plural, t2.actions, pluralRules);
|
|
1973
1919
|
};
|
|
1974
1920
|
const data = (value) => {
|
|
1975
1921
|
const _data = storageData.get().data;
|
|
@@ -1993,7 +1939,9 @@ var novely = ({
|
|
|
1993
1939
|
const setStorageData = (data2) => {
|
|
1994
1940
|
if (destroyed) {
|
|
1995
1941
|
if (DEV3) {
|
|
1996
|
-
throw new Error(
|
|
1942
|
+
throw new Error(
|
|
1943
|
+
`function \`setStorageData\` was called after novely instance was destroyed. Data is not updater nor synced after destroy.`
|
|
1944
|
+
);
|
|
1997
1945
|
}
|
|
1998
1946
|
return;
|
|
1999
1947
|
}
|
|
@@ -2053,7 +2001,7 @@ var novely = ({
|
|
|
2053
2001
|
* @example
|
|
2054
2002
|
* ```ts
|
|
2055
2003
|
* import type { ConditionParams, StateFunction } from '@novely/core';
|
|
2056
|
-
|
|
2004
|
+
*
|
|
2057
2005
|
* const conditionCheck = (state: StateFunction<ConditionParams<typeof engine.typeEssintials>>) => {
|
|
2058
2006
|
* return state.age >= 18;
|
|
2059
2007
|
* }
|
|
@@ -2164,7 +2112,9 @@ var RU = {
|
|
|
2164
2112
|
CloseMenu: "\u0417\u0430\u043A\u0440\u044B\u0442\u044C \u043C\u0435\u043D\u044E",
|
|
2165
2113
|
MusicVolume: "\u0413\u0440\u043E\u043C\u043A\u043E\u0441\u0442\u044C \u043C\u0443\u0437\u044B\u043A\u0438",
|
|
2166
2114
|
SoundVolume: "\u0413\u0440\u043E\u043C\u043A\u043E\u0441\u0442\u044C \u0437\u0432\u0443\u043A\u043E\u0432",
|
|
2167
|
-
VoiceVolume: "\u0413\u0440\u043E\u043C\u043A\u043E\u0441\u0442\u044C \u0440\u0435\u0447\u0438"
|
|
2115
|
+
VoiceVolume: "\u0413\u0440\u043E\u043C\u043A\u043E\u0441\u0442\u044C \u0440\u0435\u0447\u0438",
|
|
2116
|
+
Close: "\u0417\u0430\u043A\u0440\u044B\u0442\u044C",
|
|
2117
|
+
DialogOverview: "\u041E\u0431\u0437\u043E\u0440 \u0434\u0438\u0430\u043B\u043E\u0433\u0430"
|
|
2168
2118
|
};
|
|
2169
2119
|
var EN = {
|
|
2170
2120
|
NewGame: "New Game",
|
|
@@ -2200,7 +2150,9 @@ var EN = {
|
|
|
2200
2150
|
CloseMenu: "Close menu",
|
|
2201
2151
|
MusicVolume: "Music volume",
|
|
2202
2152
|
SoundVolume: "Sound volume",
|
|
2203
|
-
VoiceVolume: "Voice volume"
|
|
2153
|
+
VoiceVolume: "Voice volume",
|
|
2154
|
+
Close: "Close",
|
|
2155
|
+
DialogOverview: "Dialog Overview"
|
|
2204
2156
|
};
|
|
2205
2157
|
var KK = {
|
|
2206
2158
|
NewGame: "\u0416\u0430\u04A3\u0430 \u043E\u0439\u044B\u043D",
|
|
@@ -2236,7 +2188,9 @@ var KK = {
|
|
|
2236
2188
|
CloseMenu: "\u041C\u04D9\u0437\u0456\u0440\u0434\u0456 \u0436\u0430\u0431\u0443",
|
|
2237
2189
|
MusicVolume: "\u041C\u0443\u0437\u044B\u043A\u0430\u043D\u044B\u04A3 \u043A\u04E9\u043B\u0435\u043C\u0456",
|
|
2238
2190
|
SoundVolume: "\u0414\u044B\u0431\u044B\u0441\u0442\u0430\u0440\u0434\u044B\u04A3 \u043A\u04E9\u043B\u0435\u043C\u0456",
|
|
2239
|
-
VoiceVolume: "\u0421\u04E9\u0439\u043B\u0435\u0443 \u043A\u04E9\u043B\u0435\u043C\u0456"
|
|
2191
|
+
VoiceVolume: "\u0421\u04E9\u0439\u043B\u0435\u0443 \u043A\u04E9\u043B\u0435\u043C\u0456",
|
|
2192
|
+
Close: "\u0416\u0430\u0431\u0443",
|
|
2193
|
+
DialogOverview: "\u0414\u0438\u0430\u043B\u043E\u0433\u049B\u0430 \u0428\u043E\u043B\u0443"
|
|
2240
2194
|
};
|
|
2241
2195
|
var JP = {
|
|
2242
2196
|
NewGame: "\u300C\u65B0\u3057\u3044\u30B2\u30FC\u30E0\u300D",
|
|
@@ -2272,7 +2226,137 @@ var JP = {
|
|
|
2272
2226
|
CloseMenu: "\u30E1\u30CB\u30E5\u30FC\u3092\u9589\u3058\u308B",
|
|
2273
2227
|
MusicVolume: "\u97F3\u697D\u306E\u30DC\u30EA\u30E5\u30FC\u30E0",
|
|
2274
2228
|
SoundVolume: "\u97F3\u91CF",
|
|
2275
|
-
VoiceVolume: "\u30B9\u30D4\u30FC\u30C1\u306E\u91CF"
|
|
2229
|
+
VoiceVolume: "\u30B9\u30D4\u30FC\u30C1\u306E\u91CF",
|
|
2230
|
+
Close: "\u9589\u3058\u308B",
|
|
2231
|
+
DialogOverview: "\u30C0\u30A4\u30A2\u30ED\u30B0\u306E\u6982\u8981"
|
|
2232
|
+
};
|
|
2233
|
+
|
|
2234
|
+
// src/asset.ts
|
|
2235
|
+
import { memoize as memoize4, once } from "es-toolkit/function";
|
|
2236
|
+
import { DEV as DEV4 } from "esm-env";
|
|
2237
|
+
|
|
2238
|
+
// src/audio-codecs.ts
|
|
2239
|
+
var cut = (str) => str.replace(/^no$/, "");
|
|
2240
|
+
var audio = new Audio();
|
|
2241
|
+
var canPlay = (type) => !!cut(audio.canPlayType(type));
|
|
2242
|
+
var canPlayMultiple = (...types) => types.some((type) => canPlay(type));
|
|
2243
|
+
var supportsMap = {
|
|
2244
|
+
mp3: canPlayMultiple("audio/mpeg;", "audio/mp3;"),
|
|
2245
|
+
mpeg: canPlay("audio/mpeg;"),
|
|
2246
|
+
opus: canPlay('audio/ogg; codecs="opus"'),
|
|
2247
|
+
ogg: canPlay('audio/ogg; codecs="vorbis"'),
|
|
2248
|
+
oga: canPlay('audio/ogg; codecs="vorbis"'),
|
|
2249
|
+
wav: canPlayMultiple('audio/wav; codecs="1"', "audio/wav;"),
|
|
2250
|
+
aac: canPlay("audio/aac;"),
|
|
2251
|
+
caf: canPlay("audio/x-caf;"),
|
|
2252
|
+
m4a: canPlayMultiple("audio/x-m4a;", "audio/m4a;", "audio/aac;"),
|
|
2253
|
+
m4b: canPlayMultiple("audio/x-m4b;", "audio/m4b;", "audio/aac;"),
|
|
2254
|
+
mp4: canPlayMultiple("audio/x-mp4;", "audio/mp4;", "audio/aac;"),
|
|
2255
|
+
weba: canPlay('audio/webm; codecs="vorbis"'),
|
|
2256
|
+
webm: canPlay('audio/webm; codecs="vorbis"'),
|
|
2257
|
+
dolby: canPlay('audio/mp4; codecs="ec-3"'),
|
|
2258
|
+
flac: canPlayMultiple("audio/x-flac;", "audio/flac;")
|
|
2259
|
+
};
|
|
2260
|
+
|
|
2261
|
+
// src/image-formats.ts
|
|
2262
|
+
var avif = "data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A=";
|
|
2263
|
+
var jxl = "data:image/jxl;base64,/woIAAAMABKIAgC4AF3lEgAAFSqjjBu8nOv58kOHxbSN6wxttW1hSaLIODZJJ3BIEkkaoCUzGM6qJAE=";
|
|
2264
|
+
var webp = "data:image/webp;base64,UklGRjoAAABXRUJQVlA4IC4AAACyAgCdASoCAAIALmk0mk0iIiIiIgBoSygABc6WWgAA/veff/0PP8bA//LwYAAA";
|
|
2265
|
+
var supportsFormat = (source) => {
|
|
2266
|
+
const { promise, resolve } = Promise.withResolvers();
|
|
2267
|
+
const img = Object.assign(document.createElement("img"), {
|
|
2268
|
+
src: source
|
|
2269
|
+
});
|
|
2270
|
+
img.onload = img.onerror = () => {
|
|
2271
|
+
resolve(img.height === 2);
|
|
2272
|
+
};
|
|
2273
|
+
return promise;
|
|
2274
|
+
};
|
|
2275
|
+
var supportsMap2 = {
|
|
2276
|
+
avif: false,
|
|
2277
|
+
jxl: false,
|
|
2278
|
+
webp: false
|
|
2279
|
+
};
|
|
2280
|
+
var formatsMap = {
|
|
2281
|
+
avif,
|
|
2282
|
+
jxl,
|
|
2283
|
+
webp
|
|
2284
|
+
};
|
|
2285
|
+
var loadImageFormatsSupport = async () => {
|
|
2286
|
+
const promises = [];
|
|
2287
|
+
for (const [format, source] of Object.entries(formatsMap)) {
|
|
2288
|
+
const promise = supportsFormat(source).then((supported) => {
|
|
2289
|
+
supportsMap2[format] = supported;
|
|
2290
|
+
});
|
|
2291
|
+
promises.push(promise);
|
|
2292
|
+
}
|
|
2293
|
+
await Promise.all(promises);
|
|
2294
|
+
};
|
|
2295
|
+
loadImageFormatsSupport();
|
|
2296
|
+
|
|
2297
|
+
// src/asset.ts
|
|
2298
|
+
var getType = memoize4(
|
|
2299
|
+
(extensions) => {
|
|
2300
|
+
if (extensions.every((extension) => HOWLER_SUPPORTED_FILE_FORMATS.has(extension))) {
|
|
2301
|
+
return "audio";
|
|
2302
|
+
}
|
|
2303
|
+
if (extensions.every((extension) => SUPPORTED_IMAGE_FILE_FORMATS.has(extension))) {
|
|
2304
|
+
return "image";
|
|
2305
|
+
}
|
|
2306
|
+
throw extensions;
|
|
2307
|
+
},
|
|
2308
|
+
{
|
|
2309
|
+
getCacheKey: (extensions) => extensions.join("~")
|
|
2310
|
+
}
|
|
2311
|
+
);
|
|
2312
|
+
var SUPPORT_MAPS = {
|
|
2313
|
+
image: supportsMap2,
|
|
2314
|
+
audio: supportsMap
|
|
2315
|
+
};
|
|
2316
|
+
var assetPrivate = memoize4(
|
|
2317
|
+
(variants) => {
|
|
2318
|
+
if (DEV4 && variants.length === 0) {
|
|
2319
|
+
throw new Error(`Attempt to use "asset" function without arguments`);
|
|
2320
|
+
}
|
|
2321
|
+
const map = {};
|
|
2322
|
+
const extensions = [];
|
|
2323
|
+
for (const v of variants) {
|
|
2324
|
+
const e = getUrlFileExtension(v);
|
|
2325
|
+
map[e] = v;
|
|
2326
|
+
extensions.push(e);
|
|
2327
|
+
}
|
|
2328
|
+
const type = getType(extensions);
|
|
2329
|
+
const getSource = once(() => {
|
|
2330
|
+
const support = SUPPORT_MAPS[type];
|
|
2331
|
+
for (const extension of extensions) {
|
|
2332
|
+
if (extension in support) {
|
|
2333
|
+
if (support[extension]) {
|
|
2334
|
+
return map[extension];
|
|
2335
|
+
}
|
|
2336
|
+
} else {
|
|
2337
|
+
return map[extension];
|
|
2338
|
+
}
|
|
2339
|
+
}
|
|
2340
|
+
if (DEV4) {
|
|
2341
|
+
throw new Error(`No matching asset was found for ${variants.map((v) => `"${v}"`).join(", ")}`);
|
|
2342
|
+
}
|
|
2343
|
+
return "";
|
|
2344
|
+
});
|
|
2345
|
+
return {
|
|
2346
|
+
get source() {
|
|
2347
|
+
return getSource();
|
|
2348
|
+
},
|
|
2349
|
+
get type() {
|
|
2350
|
+
return type;
|
|
2351
|
+
}
|
|
2352
|
+
};
|
|
2353
|
+
},
|
|
2354
|
+
{
|
|
2355
|
+
getCacheKey: (variants) => variants.join("~")
|
|
2356
|
+
}
|
|
2357
|
+
);
|
|
2358
|
+
var asset = (...variants) => {
|
|
2359
|
+
return assetPrivate(variants);
|
|
2276
2360
|
};
|
|
2277
2361
|
export {
|
|
2278
2362
|
EN,
|