@novely/core 0.7.1 → 0.8.1
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 +8 -3
- package/dist/index.global.js +70 -9
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +70 -9
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -45,7 +45,7 @@ type DeepPartial<T> = unknown extends T ? T : T extends object ? {
|
|
|
45
45
|
[P in keyof T]?: T[P] extends Array<infer U> ? Array<DeepPartial<U>> : T[P] extends ReadonlyArray<infer U> ? ReadonlyArray<DeepPartial<U>> : DeepPartial<T[P]>;
|
|
46
46
|
} : T;
|
|
47
47
|
|
|
48
|
-
type ValidAction = ['choice', [number]] | ['clear', [Set<keyof DefaultActionProxyProvider>?, Set<string>?]] | ['condition', [() => boolean, Record<string, ValidAction[]>]] | ['dialog', [string | undefined, Unwrappable, string | undefined]] | ['end', []] | ['showBackground', [string]] | ['playMusic', [string]] | ['stopMusic', [string]] | ['jump', [string]] | ['showCharacter', [string, keyof Character['emotions'], string?, string?]] | ['hideCharacter', [string, string?, string?, number?]] | ['animateCharacter', [string, number, ...string[]]] | ['wait', [FunctionableValue<number>]] | ['function', [() => Thenable<void>]] | ['input', [string, (meta: ActionInputOnInputMeta) => void, ActionInputSetup?]] | ['custom', [CustomHandler]] | ['vibrate', [...number[]]] | ['next', []] | ['text', [...string[]]] | ['exit'] | ValidAction[];
|
|
48
|
+
type ValidAction = ['choice', [number]] | ['clear', [Set<keyof DefaultActionProxyProvider>?, Set<string>?]] | ['condition', [() => boolean, Record<string, ValidAction[]>]] | ['dialog', [string | undefined, Unwrappable, string | undefined]] | ['end', []] | ['showBackground', [string]] | ['playMusic', [string]] | ['stopMusic', [string]] | ['jump', [string]] | ['showCharacter', [string, keyof Character['emotions'], string?, string?]] | ['hideCharacter', [string, string?, string?, number?]] | ['animateCharacter', [string, number, ...string[]]] | ['wait', [FunctionableValue<number>]] | ['function', [() => Thenable<void>]] | ['input', [string, (meta: ActionInputOnInputMeta) => void, ActionInputSetup?]] | ['custom', [CustomHandler]] | ['vibrate', [...number[]]] | ['next', []] | ['text', [...string[]]] | ['exit'] | ['preload', [string]] | ValidAction[];
|
|
49
49
|
type Story = Record<string, ValidAction[]>;
|
|
50
50
|
type Unwrappable = string | ((lang: string, obj: Record<string, unknown>) => string) | Record<string, string | (() => string)>;
|
|
51
51
|
type FunctionableValue<T> = T | (() => T);
|
|
@@ -134,6 +134,7 @@ type ActionProxyProvider<Characters extends Record<string, Character>> = {
|
|
|
134
134
|
vibrate: (...pattern: number[]) => ValidAction;
|
|
135
135
|
next: () => ValidAction;
|
|
136
136
|
text: (...text: Unwrappable[]) => ValidAction;
|
|
137
|
+
preload: (source: string) => ValidAction;
|
|
137
138
|
};
|
|
138
139
|
type DefaultActionProxyProvider = ActionProxyProvider<Record<string, Character>>;
|
|
139
140
|
type GetActionParameters<T extends Capitalize<keyof DefaultActionProxyProvider>> = Parameters<DefaultActionProxyProvider[Uncapitalize<T>]>;
|
|
@@ -289,12 +290,16 @@ interface NovelyInit<Languages extends string, Characters extends Record<string,
|
|
|
289
290
|
* @default true
|
|
290
291
|
*/
|
|
291
292
|
askBeforeExit?: boolean;
|
|
293
|
+
/**
|
|
294
|
+
* @default "lazy"
|
|
295
|
+
*/
|
|
296
|
+
preloadAssets?: "lazy" | "blocking";
|
|
292
297
|
}
|
|
293
|
-
declare const novely: <Languages extends string, Characters extends Record<string, Character<Languages>>, Inter extends _novely_t9n.T9N<Languages, string>, StateScheme extends State, DataScheme extends Data>({ characters, storage, storageDelay, renderer: createRenderer, initialScreen, t9n, languages, state: defaultState, data: defaultData, autosaves, migrations, throttleTimeout, getLanguage, overrideLanguage, askBeforeExit }: NovelyInit<Languages, Characters, Inter, StateScheme, DataScheme>) => {
|
|
298
|
+
declare const novely: <Languages extends string, Characters extends Record<string, Character<Languages>>, Inter extends _novely_t9n.T9N<Languages, string>, StateScheme extends State, DataScheme extends Data>({ characters, storage, storageDelay, renderer: createRenderer, initialScreen, t9n, languages, state: defaultState, data: defaultData, autosaves, migrations, throttleTimeout, getLanguage, overrideLanguage, askBeforeExit, preloadAssets }: NovelyInit<Languages, Characters, Inter, StateScheme, DataScheme>) => {
|
|
294
299
|
/**
|
|
295
300
|
* Function to set story
|
|
296
301
|
*/
|
|
297
|
-
withStory: (s: Story) => void
|
|
302
|
+
withStory: (s: Story) => Promise<void>;
|
|
298
303
|
/**
|
|
299
304
|
* Function to get actions
|
|
300
305
|
*/
|
package/dist/index.global.js
CHANGED
|
@@ -165,6 +165,10 @@ var Novely = (() => {
|
|
|
165
165
|
var isEmpty = (val) => {
|
|
166
166
|
return typeof val === "object" && !isNull(val) && Object.keys(val).length === 0;
|
|
167
167
|
};
|
|
168
|
+
var isCSSImage = (str2) => {
|
|
169
|
+
const startsWith = String.prototype.startsWith.bind(str2);
|
|
170
|
+
return startsWith("http") || startsWith("/") || startsWith(".") || startsWith("data");
|
|
171
|
+
};
|
|
168
172
|
var str = (value) => {
|
|
169
173
|
return String(value);
|
|
170
174
|
};
|
|
@@ -221,6 +225,31 @@ var Novely = (() => {
|
|
|
221
225
|
}
|
|
222
226
|
return -1;
|
|
223
227
|
};
|
|
228
|
+
var preloadImagesBlocking = (images) => {
|
|
229
|
+
return Promise.allSettled(Array.from(images).map((src) => {
|
|
230
|
+
const img = document.createElement("img");
|
|
231
|
+
img.src = src;
|
|
232
|
+
return new Promise((resolve, reject) => {
|
|
233
|
+
if (img.complete && img.naturalHeight !== 0) {
|
|
234
|
+
resolve(void 0);
|
|
235
|
+
}
|
|
236
|
+
img.addEventListener("load", resolve);
|
|
237
|
+
img.addEventListener("abort", reject);
|
|
238
|
+
img.addEventListener("error", reject);
|
|
239
|
+
});
|
|
240
|
+
}));
|
|
241
|
+
};
|
|
242
|
+
var createDeferredPromise = () => {
|
|
243
|
+
let resolve, reject;
|
|
244
|
+
const promise = new Promise((res, rej) => {
|
|
245
|
+
resolve = res;
|
|
246
|
+
reject = rej;
|
|
247
|
+
});
|
|
248
|
+
return { resolve, reject, promise };
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
// src/global.ts
|
|
252
|
+
var PRELOADED_ASSETS = /* @__PURE__ */ new Set();
|
|
224
253
|
|
|
225
254
|
// src/store.ts
|
|
226
255
|
var store = (current, subscribers = /* @__PURE__ */ new Set()) => {
|
|
@@ -316,16 +345,19 @@ var Novely = (() => {
|
|
|
316
345
|
throttleTimeout = 799,
|
|
317
346
|
getLanguage: getLanguage2 = getLanguage,
|
|
318
347
|
overrideLanguage = false,
|
|
319
|
-
askBeforeExit = true
|
|
348
|
+
askBeforeExit = true,
|
|
349
|
+
preloadAssets = "lazy"
|
|
320
350
|
}) => {
|
|
321
351
|
let story;
|
|
322
352
|
let times = /* @__PURE__ */ new Set();
|
|
353
|
+
const ASSETS_TO_PRELOAD = /* @__PURE__ */ new Set();
|
|
354
|
+
const assetsLoaded = createDeferredPromise();
|
|
323
355
|
defaultData ||= {};
|
|
324
356
|
defaultState ||= {};
|
|
325
357
|
const intime = (value) => {
|
|
326
358
|
return times.add(value), value;
|
|
327
359
|
};
|
|
328
|
-
const withStory = (s) => {
|
|
360
|
+
const withStory = async (s) => {
|
|
329
361
|
story = Object.fromEntries(
|
|
330
362
|
Object.entries(s).map(([name, items]) => {
|
|
331
363
|
const flat = (item) => {
|
|
@@ -339,12 +371,33 @@ var Novely = (() => {
|
|
|
339
371
|
return [name, flat(items)];
|
|
340
372
|
})
|
|
341
373
|
);
|
|
374
|
+
if (preloadAssets === "blocking" && ASSETS_TO_PRELOAD.size > 0) {
|
|
375
|
+
renderer.ui.showScreen("loading");
|
|
376
|
+
await preloadImagesBlocking(ASSETS_TO_PRELOAD);
|
|
377
|
+
}
|
|
378
|
+
ASSETS_TO_PRELOAD.clear();
|
|
379
|
+
assetsLoaded.resolve();
|
|
342
380
|
if (initialScreen !== "game")
|
|
343
381
|
renderer.ui.showScreen(initialScreen);
|
|
344
382
|
};
|
|
345
383
|
const action = new Proxy({}, {
|
|
346
384
|
get(_, prop) {
|
|
347
385
|
return (...props) => {
|
|
386
|
+
if (preloadAssets === "blocking") {
|
|
387
|
+
if (prop === "showBackground" && typeof props[0] === "string" && isCSSImage(props[0])) {
|
|
388
|
+
ASSETS_TO_PRELOAD.add(props[0]);
|
|
389
|
+
}
|
|
390
|
+
if (prop === "showCharacter" && typeof props[0] === "string" && typeof props[1] === "string") {
|
|
391
|
+
const images = characters[props[0]].emotions[props[1]];
|
|
392
|
+
if (typeof images === "string") {
|
|
393
|
+
ASSETS_TO_PRELOAD.add(images);
|
|
394
|
+
} else {
|
|
395
|
+
for (const asset of [images.head, images.body.left, images.body.right]) {
|
|
396
|
+
ASSETS_TO_PRELOAD.add(asset);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
348
401
|
return [prop, ...props];
|
|
349
402
|
};
|
|
350
403
|
}
|
|
@@ -419,7 +472,9 @@ var Novely = (() => {
|
|
|
419
472
|
initialDataLoaded = true;
|
|
420
473
|
$.update(() => stored);
|
|
421
474
|
if (initialScreen === "game")
|
|
422
|
-
|
|
475
|
+
assetsLoaded.promise.then(() => {
|
|
476
|
+
restore();
|
|
477
|
+
});
|
|
423
478
|
});
|
|
424
479
|
};
|
|
425
480
|
storageDelay.then(getStoredData);
|
|
@@ -465,7 +520,7 @@ var Novely = (() => {
|
|
|
465
520
|
};
|
|
466
521
|
let restoring = false;
|
|
467
522
|
let goingBack = false;
|
|
468
|
-
let interacted =
|
|
523
|
+
let interacted = 0;
|
|
469
524
|
const restore = async (save2) => {
|
|
470
525
|
if (!initialDataLoaded)
|
|
471
526
|
return;
|
|
@@ -581,16 +636,16 @@ var Novely = (() => {
|
|
|
581
636
|
return current;
|
|
582
637
|
};
|
|
583
638
|
const exit = (force = false) => {
|
|
584
|
-
if (interacted && !force && askBeforeExit) {
|
|
639
|
+
if (interacted > 1 && !force && askBeforeExit) {
|
|
585
640
|
renderer.ui.showExitPrompt();
|
|
586
641
|
return;
|
|
587
642
|
}
|
|
588
643
|
const current = stack.value;
|
|
589
644
|
stack.clear();
|
|
590
645
|
renderer.ui.showScreen("mainmenu");
|
|
591
|
-
const [
|
|
592
|
-
if (type === "auto"
|
|
593
|
-
if (
|
|
646
|
+
const [time, type] = current[2];
|
|
647
|
+
if (type === "auto") {
|
|
648
|
+
if (interacted <= 1 && times.has(time)) {
|
|
594
649
|
$.update((prev) => {
|
|
595
650
|
prev.saves = prev.saves.filter((save2) => save2 !== current);
|
|
596
651
|
return prev;
|
|
@@ -754,6 +809,12 @@ var Novely = (() => {
|
|
|
754
809
|
}
|
|
755
810
|
if (exited)
|
|
756
811
|
render();
|
|
812
|
+
},
|
|
813
|
+
preload([source]) {
|
|
814
|
+
if (!PRELOADED_ASSETS.has(source) && !goingBack && !restoring) {
|
|
815
|
+
PRELOADED_ASSETS.add(document.createElement("img").src = source);
|
|
816
|
+
}
|
|
817
|
+
push();
|
|
757
818
|
}
|
|
758
819
|
});
|
|
759
820
|
const enmemory = () => {
|
|
@@ -792,7 +853,7 @@ var Novely = (() => {
|
|
|
792
853
|
interactivity(true);
|
|
793
854
|
};
|
|
794
855
|
const interactivity = (value = false) => {
|
|
795
|
-
interacted = value;
|
|
856
|
+
interacted = value ? interacted + 1 : 0;
|
|
796
857
|
};
|
|
797
858
|
const unwrap = (content, global = false) => {
|
|
798
859
|
const {
|
package/dist/index.global.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../node_modules/.pnpm/deepmerge@4.3.1/node_modules/deepmerge/dist/cjs.js","../src/index.ts","../src/utils.ts","../src/store.ts","../src/novely.ts","../../../node_modules/.pnpm/klona@2.0.6/node_modules/klona/json/index.mjs","../src/constants.ts","../../t9n/src/lib.ts","../../t9n/src/translation.ts","../../t9n/src/translations.ts","../src/storage.ts"],"sourcesContent":["'use strict';\n\nvar isMergeableObject = function isMergeableObject(value) {\n\treturn isNonNullObject(value)\n\t\t&& !isSpecial(value)\n};\n\nfunction isNonNullObject(value) {\n\treturn !!value && typeof value === 'object'\n}\n\nfunction isSpecial(value) {\n\tvar stringValue = Object.prototype.toString.call(value);\n\n\treturn stringValue === '[object RegExp]'\n\t\t|| stringValue === '[object Date]'\n\t\t|| isReactElement(value)\n}\n\n// see https://github.com/facebook/react/blob/b5ac963fb791d1298e7f396236383bc955f916c1/src/isomorphic/classic/element/ReactElement.js#L21-L25\nvar canUseSymbol = typeof Symbol === 'function' && Symbol.for;\nvar REACT_ELEMENT_TYPE = canUseSymbol ? Symbol.for('react.element') : 0xeac7;\n\nfunction isReactElement(value) {\n\treturn value.$$typeof === REACT_ELEMENT_TYPE\n}\n\nfunction emptyTarget(val) {\n\treturn Array.isArray(val) ? [] : {}\n}\n\nfunction cloneUnlessOtherwiseSpecified(value, options) {\n\treturn (options.clone !== false && options.isMergeableObject(value))\n\t\t? deepmerge(emptyTarget(value), value, options)\n\t\t: value\n}\n\nfunction defaultArrayMerge(target, source, options) {\n\treturn target.concat(source).map(function(element) {\n\t\treturn cloneUnlessOtherwiseSpecified(element, options)\n\t})\n}\n\nfunction getMergeFunction(key, options) {\n\tif (!options.customMerge) {\n\t\treturn deepmerge\n\t}\n\tvar customMerge = options.customMerge(key);\n\treturn typeof customMerge === 'function' ? customMerge : deepmerge\n}\n\nfunction getEnumerableOwnPropertySymbols(target) {\n\treturn Object.getOwnPropertySymbols\n\t\t? Object.getOwnPropertySymbols(target).filter(function(symbol) {\n\t\t\treturn Object.propertyIsEnumerable.call(target, symbol)\n\t\t})\n\t\t: []\n}\n\nfunction getKeys(target) {\n\treturn Object.keys(target).concat(getEnumerableOwnPropertySymbols(target))\n}\n\nfunction propertyIsOnObject(object, property) {\n\ttry {\n\t\treturn property in object\n\t} catch(_) {\n\t\treturn false\n\t}\n}\n\n// Protects from prototype poisoning and unexpected merging up the prototype chain.\nfunction propertyIsUnsafe(target, key) {\n\treturn propertyIsOnObject(target, key) // Properties are safe to merge if they don't exist in the target yet,\n\t\t&& !(Object.hasOwnProperty.call(target, key) // unsafe if they exist up the prototype chain,\n\t\t\t&& Object.propertyIsEnumerable.call(target, key)) // and also unsafe if they're nonenumerable.\n}\n\nfunction mergeObject(target, source, options) {\n\tvar destination = {};\n\tif (options.isMergeableObject(target)) {\n\t\tgetKeys(target).forEach(function(key) {\n\t\t\tdestination[key] = cloneUnlessOtherwiseSpecified(target[key], options);\n\t\t});\n\t}\n\tgetKeys(source).forEach(function(key) {\n\t\tif (propertyIsUnsafe(target, key)) {\n\t\t\treturn\n\t\t}\n\n\t\tif (propertyIsOnObject(target, key) && options.isMergeableObject(source[key])) {\n\t\t\tdestination[key] = getMergeFunction(key, options)(target[key], source[key], options);\n\t\t} else {\n\t\t\tdestination[key] = cloneUnlessOtherwiseSpecified(source[key], options);\n\t\t}\n\t});\n\treturn destination\n}\n\nfunction deepmerge(target, source, options) {\n\toptions = options || {};\n\toptions.arrayMerge = options.arrayMerge || defaultArrayMerge;\n\toptions.isMergeableObject = options.isMergeableObject || isMergeableObject;\n\t// cloneUnlessOtherwiseSpecified is added to `options` so that custom arrayMerge()\n\t// implementations can use it. The caller may not replace it.\n\toptions.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified;\n\n\tvar sourceIsArray = Array.isArray(source);\n\tvar targetIsArray = Array.isArray(target);\n\tvar sourceAndTargetTypesMatch = sourceIsArray === targetIsArray;\n\n\tif (!sourceAndTargetTypesMatch) {\n\t\treturn cloneUnlessOtherwiseSpecified(source, options)\n\t} else if (sourceIsArray) {\n\t\treturn options.arrayMerge(target, source, options)\n\t} else {\n\t\treturn mergeObject(target, source, options)\n\t}\n}\n\ndeepmerge.all = function deepmergeAll(array, options) {\n\tif (!Array.isArray(array)) {\n\t\tthrow new Error('first argument should be an array')\n\t}\n\n\treturn array.reduce(function(prev, next) {\n\t\treturn deepmerge(prev, next, options)\n\t}, {})\n};\n\nvar deepmerge_1 = deepmerge;\n\nmodule.exports = deepmerge_1;\n","export type {\n\tValidAction,\n\tStory,\n\tActionProxyProvider,\n\tDefaultActionProxyProvider,\n\tGetActionParameters,\n\tUnwrappable,\n\tCustomHandler,\n\tCustomHandlerGetResult,\n\tCustomHandlerGetResultDataFunction,\n\tFunctionableValue,\n} from './action';\nexport type { Emotions, Character } from './character';\nexport type { CharacterHandle, AudioHandle, RendererStore, Renderer, RendererInit } from './renderer';\nexport type { Storage } from './storage';\nexport type { Thenable, Path, StorageData, StorageMeta, TypewriterSpeed, Lang, NovelyScreen } from './types';\nexport type { Stored } from './store';\nexport type { BaseTranslationStrings } from '@novely/t9n';\n\nexport { novely } from './novely';\nexport { localStorageStorage } from './storage';\n","import type { ActionProxyProvider, CustomHandler } from './action';\nimport type { Character } from './character';\nimport type { TypewriterSpeed, Thenable } from './types';\n\ntype MatchActionMap = {\n\t[Key in keyof ActionProxyProvider<Record<string, Character>>]: (\n\t\tdata: Parameters<ActionProxyProvider<Record<string, Character>>[Key]>,\n\t) => void;\n};\n\ntype MatchActionMapComplete = Omit<MatchActionMap, 'custom'> & {\n\tcustom: (value: [handler: CustomHandler]) => Thenable<void>;\n};\n\nconst matchAction = <M extends MatchActionMapComplete>(values: M) => {\n\treturn (action: keyof MatchActionMap, props: any) => {\n\t\treturn values[action](props);\n\t};\n};\n\nconst isNumber = (val: unknown): val is number => {\n\treturn typeof val === 'number';\n};\n\nconst isNull = (val: unknown): val is null => {\n\treturn val === null;\n};\n\nconst isString = (val: unknown): val is string => {\n\treturn typeof val === 'string';\n};\n\nconst isFunction = (val: unknown): val is (...parameters: any[]) => any => {\n\treturn typeof val === 'function';\n};\n\nconst isPromise = (val: unknown): val is Promise<any> => {\n\treturn Boolean(val) && (typeof val === 'object' || isFunction(val)) && isFunction((val as any).then);\n};\n\nconst isEmpty = (val: unknown): val is {} => {\n\treturn typeof val === 'object' && !isNull(val) && Object.keys(val).length === 0;\n};\n\nconst isCSSImage = (str: string) => {\n\tconst startsWith = String.prototype.startsWith.bind(str);\n\n\treturn startsWith('http') || startsWith('/') || startsWith('.') || startsWith('data');\n};\n\nconst str = (value: unknown) => {\n\treturn String(value);\n};\n\nconst isUserRequiredAction = (\n\taction: keyof MatchActionMapComplete,\n\tmeta: Parameters<MatchActionMapComplete[keyof MatchActionMapComplete]>,\n) => {\n\treturn action === 'custom' && meta[0] && (meta[0] as unknown as CustomHandler).requireUserAction;\n};\n\nconst getTypewriterSpeed = (): TypewriterSpeed => {\n\treturn 'Medium';\n};\n\nconst getLanguage = (languages: string[], _: any) => {\n\tlet { language } = navigator;\n\n\tif (languages.includes(language)) {\n\t\treturn language;\n\t} else if (languages.includes((language = language.substring(0, 2)))) {\n\t\treturn language;\n\t} else if ((language = languages.find((value) => navigator.languages.includes(value))!)) {\n\t\treturn language;\n\t}\n\n\t/**\n\t * We'v checked the `en-GB` format, `en` format, and maybe any second languages, but there were no matches\n\t */\n\treturn languages[0];\n};\n\n/**\n * @copyright Techlead LLC\n * @see https://learn.javascript.ru/task/throttle\n */\nconst throttle = <Fn extends (...args: any[]) => any>(fn: Fn, ms: number) => {\n\tlet throttled = false,\n\t\tsavedArgs: any,\n\t\tsavedThis: any;\n\n\tfunction wrapper(this: any) {\n\t\tif (throttled) {\n\t\t\tsavedArgs = arguments;\n\t\t\tsavedThis = this;\n\t\t\treturn;\n\t\t}\n\n\t\tfn.apply(this, arguments as unknown as any[]);\n\n\t\tthrottled = true;\n\n\t\tsetTimeout(function () {\n\t\t\tthrottled = false;\n\n\t\t\tif (savedArgs) {\n\t\t\t\twrapper.apply(savedThis, savedArgs);\n\t\t\t\tsavedArgs = savedThis = null;\n\t\t\t}\n\t\t}, ms);\n\t}\n\n\treturn wrapper as unknown as (...args: Parameters<Fn>) => void;\n};\n\nconst vibrate = (pattern: VibratePattern) => {\n\ttry {\n\t\tif ('vibrate' in navigator) {\n\t\t\tnavigator.vibrate(pattern);\n\t\t}\n\t} catch {}\n};\n\nconst findLastIndex = <T>(array: T[], fn: (item: T) => boolean) => {\n\tfor (let i = array.length - 1; i > 0; i--) {\n\t\tif (fn(array[i])) {\n\t\t\treturn i;\n\t\t}\n\t}\n\n\treturn -1;\n};\n\nexport {\n\tmatchAction,\n\tisNumber,\n\tisNull,\n\tisString,\n\tisPromise,\n\tisEmpty,\n\tisCSSImage,\n\tstr,\n\tisUserRequiredAction,\n\tgetTypewriterSpeed,\n\tgetLanguage,\n\tthrottle,\n\tisFunction,\n\tvibrate,\n\tfindLastIndex,\n};\n","type Stored<T> = {\n\tsubscribe: (cb: (value: T) => void) => () => void;\n\tupdate: (fn: (prev: T) => T) => void;\n\tget: () => T;\n};\n\nconst store = <T>(current: T, subscribers = new Set<(value: T) => void>()): Stored<T> => {\n\tconst subscribe = (cb: (value: T) => void) => {\n\t\tsubscribers.add(cb), cb(current);\n\n\t\treturn () => {\n\t\t\tsubscribers.delete(cb);\n\t\t};\n\t};\n\n\tconst push = (value: T) => {\n\t\tsubscribers.forEach((cb) => cb(value));\n\t};\n\n\tconst update = (fn: (prev: T) => T) => {\n\t\tpush((current = fn(current)));\n\t};\n\n\tconst get = () => {\n\t\treturn current;\n\t};\n\n\treturn { subscribe, update, get } as const;\n};\n\nexport { store };\nexport type { Stored };\n","import type { Character } from './character';\nimport type {\n\tActionProxyProvider,\n\tGetActionParameters,\n\tStory,\n\tValidAction,\n\tUnwrappable,\n\tCustomHandler,\n} from './action';\nimport type { Storage } from './storage';\nimport type { Save, State, Data, StorageData, DeepPartial, NovelyScreen, Migration } from './types';\nimport type { Renderer, RendererInit } from './renderer';\nimport type { SetupT9N } from '@novely/t9n';\nimport {\n\tmatchAction,\n\tisNumber,\n\tisNull,\n\tisString,\n\tisPromise,\n\tisEmpty,\n\tstr,\n\tisUserRequiredAction,\n\tgetTypewriterSpeed,\n\tgetLanguage as defaultGetLanguage,\n\tthrottle,\n\tisFunction,\n\tvibrate,\n\tfindLastIndex,\n} from './utils';\nimport { store } from './store';\nimport { all as deepmerge } from 'deepmerge';\nimport { klona } from 'klona/json';\nimport { SKIPPED_DURING_RESTORE, EMPTY_SET } from './constants';\nimport { replace as replaceT9N } from '@novely/t9n';\n\ninterface NovelyInit<\n\tLanguages extends string,\n\tCharacters extends Record<string, Character<Languages>>,\n\tInter extends ReturnType<SetupT9N<Languages>>,\n\tStateScheme extends State,\n\tDataScheme extends Data,\n> {\n\t/**\n\t * An array of languages supported by the game.\n\t */\n\tlanguages: Languages[];\n\t/**\n\t * An object containing the characters in the game.\n\t */\n\tcharacters: Characters;\n\t/**\n\t * An object that provides access to the game's storage system.\n\t */\n\tstorage: Storage;\n\t/**\n\t * Delay loading data until Promise is resolved\n\t */\n\tstorageDelay?: Promise<void>;\n\t/**\n\t * A function that returns a Renderer object used to display the game's content\n\t */\n\trenderer: (characters: RendererInit) => Renderer;\n\t/**\n\t * An optional property that specifies the initial screen to display when the game starts\n\t */\n\tinitialScreen?: NovelyScreen;\n\t/**\n\t * An object containing the translation functions used in the game\n\t */\n\tt9n: Inter;\n\t/**\n\t * Initial state value\n\t */\n\tstate?: StateScheme;\n\t/**\n\t * Initial data value\n\t */\n\tdata?: DataScheme;\n\t/**\n\t * Enable autosaves or disable\n\t * @default true\n\t */\n\tautosaves?: boolean;\n\t/**\n\t * Migration from old saves to newer\n\t */\n\tmigrations?: Migration[];\n\t/**\n\t * For saves Novely uses `throttle` function. This might be needed if you want to control frequency of saves to the storage\n\t * @default 799\n\t */\n\tthrottleTimeout?: number;\n\t/**\n\t * Custom language detector\n\t * @param languages Supported languages aka `languages: []` in the config\n\t * @example ```ts\n\t * novely({\n\t * \t\tgetLanguage(languages, original) {\n\t * \t\t\t\tif (!sdk) return original(languages);\n\t * \t\t\t\treturn sdk.environment.i18n.lang // i.e. custom language from some sdk\n\t * \t\t}\n\t * })\n\t * ```\n\t */\n\tgetLanguage?: (languages: string[], original: typeof defaultGetLanguage) => string;\n\t/**\n\t * Ignores saved language, and uses `getLanguage` to get it on every engine start\n\t * @default false\n\t */\n\toverrideLanguage?: boolean;\n\t/**\n\t * Show a prompt before exiting a game\n\t * @default true\n\t */\n\taskBeforeExit?: boolean;\n}\n\nconst novely = <\n\tLanguages extends string,\n\tCharacters extends Record<string, Character<Languages>>,\n\tInter extends ReturnType<SetupT9N<Languages>>,\n\tStateScheme extends State,\n\tDataScheme extends Data,\n>({\n\tcharacters,\n\tstorage,\n\tstorageDelay = Promise.resolve(),\n\trenderer: createRenderer,\n\tinitialScreen = 'mainmenu',\n\tt9n,\n\tlanguages,\n\tstate: defaultState,\n\tdata: defaultData,\n\tautosaves = true,\n\tmigrations = [],\n\tthrottleTimeout = 799,\n\tgetLanguage = defaultGetLanguage,\n\toverrideLanguage = false,\n\taskBeforeExit = true\n}: NovelyInit<Languages, Characters, Inter, StateScheme, DataScheme>) => {\n\tlet story: Story;\n\tlet times = new Set<number>();\n\n\t/**\n\t * Prevent `undefined`\n\t */\n\tdefaultData ||= {} as DataScheme;\n\tdefaultState ||= {} as StateScheme;\n\n\t/**\n\t * Saves timestamps created in this session\n\t */\n\tconst intime = (value: number) => {\n\t\treturn times.add(value), value;\n\t};\n\n\tconst withStory = (s: Story) => {\n\t\t/**\n\t\t * Transforms `(ValidAction | ValidAction[])[]` to `ValidAction[]`\n\t\t */\n\t\tstory = Object.fromEntries(\n\t\t\tObject.entries(s).map(([name, items]) => {\n\t\t\t\tconst flat = (item: (ValidAction | ValidAction[])[]): ValidAction[] => {\n\t\t\t\t\treturn item.flatMap((data) => {\n\t\t\t\t\t\tconst type = data[0];\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * This is not just an action like `['name', ...arguments]`, but an array of actions\n\t\t\t\t\t\t */\n\t\t\t\t\t\tif (Array.isArray(type)) return flat(data as ValidAction[]);\n\n\t\t\t\t\t\treturn [data as ValidAction];\n\t\t\t\t\t});\n\t\t\t\t};\n\n\t\t\t\treturn [name, flat(items)];\n\t\t\t}),\n\t\t);\n\n\t\t/**\n\t\t * When `initialScreen` is not a game, we can safely show it\n\t\t */\n\t\tif (initialScreen !== 'game') renderer.ui.showScreen(initialScreen);\n\t};\n\n\tconst action = new Proxy({} as ActionProxyProvider<Characters>, {\n\t\tget(_, prop) {\n\t\t\treturn (\n\t\t\t\t...props: Parameters<\n\t\t\t\t\tActionProxyProvider<Record<string, Character>>[keyof ActionProxyProvider<Record<string, Character>>]\n\t\t\t\t>\n\t\t\t) => {\n\t\t\t\treturn [prop, ...props];\n\t\t\t};\n\t\t},\n\t});\n\n\tfunction state(value: DeepPartial<StateScheme> | ((prev: StateScheme) => StateScheme)): void;\n\tfunction state(): StateScheme;\n\tfunction state(value?: DeepPartial<StateScheme> | ((prev: StateScheme) => StateScheme)): StateScheme | void {\n\t\tif (!value) return stack.value[1] as StateScheme | void;\n\n\t\tconst prev = stack.value[1];\n\t\tconst val = isFunction(value) ? value(prev as StateScheme) : deepmerge([prev, value]);\n\n\t\tstack.value[1] = val as StateScheme;\n\t}\n\n\tconst getDefaultSave = (state = {}) => {\n\t\treturn [\n\t\t\t[\n\t\t\t\t[null, 'start'],\n\t\t\t\t[null, 0],\n\t\t\t],\n\t\t\tstate,\n\t\t\t[intime(Date.now()), 'auto'],\n\t\t] as Save;\n\t};\n\n\tconst createStack = (current: Save, stack = [current]) => {\n\t\treturn {\n\t\t\tget value() {\n\t\t\t\treturn stack.at(-1)!;\n\t\t\t},\n\t\t\tset value(value: Save) {\n\t\t\t\tstack[stack.length - 1] = value;\n\t\t\t},\n\t\t\tback() {\n\t\t\t\tif (stack.length > 1) stack.pop(), (goingBack = true);\n\t\t\t},\n\t\t\tpush(value: Save) {\n\t\t\t\tstack.push(value);\n\t\t\t},\n\t\t\tclear() {\n\t\t\t\tstack = [getDefaultSave(klona(defaultState))];\n\t\t\t},\n\t\t};\n\t};\n\n\tconst getLanguageWithoutParameters = () => {\n\t\treturn getLanguage(languages, defaultGetLanguage);\n\t}\n\n\t/**\n\t * 1) Novely rendered using the `initialData`, but you can't start new game or `load` an empty one - this is scary, imagine losing your progress\n\t * 2) Actual stored data is loaded, language and etc is changed\n\t */\n\tconst initialData: StorageData = {\n\t\tsaves: [],\n\t\tdata: klona(defaultData) as Data,\n\t\tmeta: [getLanguageWithoutParameters(), getTypewriterSpeed()],\n\t};\n\n\tconst $ = store(initialData);\n\n\tlet initialDataLoaded = false;\n\n\tconst onStorageDataChange = (value: StorageData) => {\n\t\tif (initialDataLoaded) storage.set(value);\n\t};\n\n\tconst throttledOnStorageDataChange = throttle(onStorageDataChange, throttleTimeout);\n\n\t$.subscribe(throttledOnStorageDataChange);\n\n\tconst getStoredData = () => {\n\t\tstorage.get().then((stored) => {\n\t\t\t/**\n\t\t\t * Migration is done only once (when game loads it's data), and then it saves the updated format\n\t\t\t */\n\t\t\tfor (const migration of migrations) {\n\t\t\t\t// @ts-expect-error Types does not match between versions\n\t\t\t\tstored = migration(stored);\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Default `localStorageStorage` returns empty array and engine set this up itself\n\t\t\t */\n\t\t\tstored.meta[1] ||= getTypewriterSpeed();\n\n\t\t\t/**\n\t\t\t * When we need to override it we do that, when not – only when language was not defined already\n\t\t\t */\n\t\t\tif (overrideLanguage) {\n\t\t\t\tstored.meta[0] = getLanguageWithoutParameters();\n\t\t\t} else {\n\t\t\t\tstored.meta[0] ||= getLanguageWithoutParameters();\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * When data is empty replace it with `defaultData`\n\t\t\t * It also might be empty (default to empty)\n\t\t\t */\n\t\t\tif (isEmpty(stored.data)) {\n\t\t\t\tstored.data = defaultData as Data;\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Now the next store updates will entail saving via storage.set\n\t\t\t */\n\t\t\tinitialDataLoaded = true;\n\n\t\t\t$.update(() => stored);\n\n\t\t\t/**\n\t\t\t * When initialScreen is game, then we will load it, but after the data is loaded\n\t\t\t */\n\t\t\tif (initialScreen === 'game') restore();\n\t\t});\n\t};\n\n\t/**\n\t * By default this is resolved immediately, but also can be delayed.\n\t * I.e. storage has not loaded yet\n\t */\n\tstorageDelay.then(getStoredData);\n\n\tconst initial = getDefaultSave(klona(defaultState));\n\tconst stack = createStack(initial);\n\n\tconst save = (override = false, type: Save[2][1] = override ? 'auto' : 'manual') => {\n\t\tif (!initialDataLoaded) return;\n\n\t\t/**\n\t\t * When autosaves diabled just return\n\t\t */\n\t\tif (!autosaves && type === 'auto') return;\n\n\t\tconst current = klona(stack.value);\n\n\t\t$.update((prev) => {\n\t\t\t/**\n\t\t\t * Find latest save that were created in current session, and check if it is latest in an array\n\t\t\t *\n\t\t\t * We check if save was created in current session and it is latest in array\n\t\t\t * When it is not then replacing it will break logical chain\n\t\t\t *\n\t\t\t * [auto save 1]\n\t\t\t * [manual save 1]\n\t\t\t * [auto save 2] <- should not replace first auto save\n\t\t\t */\n\t\t\tconst isLatest = findLastIndex(prev.saves, (value) => times.has(value[2][0])) === prev.saves.length - 1;\n\n\t\t\t/**\n\t\t\t * Update type and time information\n\t\t\t */\n\t\t\tcurrent[2][0] = intime(Date.now());\n\t\t\tcurrent[2][1] = type;\n\n\t\t\tif (!override || !isLatest) {\n\t\t\t\tprev.saves.push(current);\n\n\t\t\t\treturn prev;\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Get latest\n\t\t\t */\n\t\t\tconst latest = prev.saves.at(-1);\n\n\t\t\t/**\n\t\t\t * When that save is the same type, replace it\n\t\t\t */\n\t\t\tif (latest && latest[2][1] === type) {\n\t\t\t\tprev.saves[prev.saves.length - 1] = current;\n\t\t\t} else {\n\t\t\t\tprev.saves.push(current);\n\t\t\t}\n\n\t\t\treturn prev;\n\t\t});\n\t};\n\n\tconst newGame = () => {\n\t\tif (!initialDataLoaded) return;\n\n\t\tconst save = getDefaultSave(klona(defaultState));\n\n\t\t/**\n\t\t * Initial save is automatic, and should be ignored when autosaves is turned off\n\t\t */\n\t\tif (autosaves) {\n\t\t\t$.update((prev) => {\n\t\t\t\treturn prev.saves.push(save), prev;\n\t\t\t});\n\t\t}\n\n\t\trestore(save);\n\t};\n\n\t/**\n\t * Set's the save\n\t */\n\tconst set = (save: Save) => {\n\t\tstack.value = save;\n\n\t\treturn restore(save);\n\t};\n\n\tlet restoring = false;\n\tlet goingBack = false;\n\tlet interacted = false;\n\n\t/**\n\t * Restore\n\t */\n\tconst restore = async (save?: Save) => {\n\t\tif (!initialDataLoaded) return;\n\n\t\tlet latest = save ? save : $.get().saves.at(-1);\n\n\t\t/**\n\t\t * When there is no game, then make a new game\n\t\t */\n\t\tif (!latest) {\n\t\t\t$.update(() => ({\n\t\t\t\tsaves: [initial],\n\t\t\t\tdata: klona(defaultData) as Data,\n\t\t\t\tmeta: [getLanguageWithoutParameters(), getTypewriterSpeed()],\n\t\t\t}));\n\n\t\t\tlatest = klona(initial);\n\t\t}\n\n\t\t(restoring = true), (stack.value = latest);\n\n\t\t/**\n\t\t * Текущий элемент в истории\n\t\t */\n\t\tlet current: any = story;\n\t\t/**\n\t\t * Текущий элемент `[null, int]`\n\t\t */\n\t\tlet index = 0;\n\n\t\t/**\n\t\t * Число элементов `[null, int]`\n\t\t */\n\t\tconst max = stack.value[0].reduce((acc, [type, val]) => {\n\t\t\tif (isNull(type) && isNumber(val)) return acc + 1;\n\n\t\t\treturn acc;\n\t\t}, 0);\n\n\t\tconst queue = [] as [any, any][];\n\t\tconst keep = new Set();\n\t\tconst characters = new Set();\n\n\t\tfor (const [type, val] of stack.value[0]) {\n\t\t\tif (type === null) {\n\t\t\t\tif (isString(val)) {\n\t\t\t\t\tcurrent = current[val];\n\t\t\t\t} else if (isNumber(val)) {\n\t\t\t\t\tindex++;\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Запустим все экшены которые идут в `[null, int]` от `0` до `int`\n\t\t\t\t\t * Почему-то потребовалось изменить `<` на `<=`, чтобы последний action попадал сюда\n\t\t\t\t\t */\n\t\t\t\t\tfor (let i = 0; i <= val; i++) {\n\t\t\t\t\t\tconst [action, ...meta] = current[i];\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * Add item to queue and action to keep\n\t\t\t\t\t\t */\n\t\t\t\t\t\tconst push = () => {\n\t\t\t\t\t\t\tkeep.add(action);\n\t\t\t\t\t\t\tqueue.push([action, meta]);\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * Do not remove characters that will be here anyways\n\t\t\t\t\t\t */\n\t\t\t\t\t\tif (action === 'showCharacter') characters.add(meta[0]);\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * Экшены, для закрытия которых пользователь должен с ними взаимодействовать\n\t\t\t\t\t\t * Также в эту группу входят экшены, которые не должны быть вызваны при восстановлении\n\t\t\t\t\t\t */\n\t\t\t\t\t\tif (SKIPPED_DURING_RESTORE.has(action) || isUserRequiredAction(action, meta)) {\n\t\t\t\t\t\t\tif (index === max && i === val) {\n\t\t\t\t\t\t\t\tpush();\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tpush();\n\t\t\t\t\t}\n\n\t\t\t\t\tcurrent = current[val];\n\t\t\t\t}\n\t\t\t} else if (type === 'choice') {\n\t\t\t\tcurrent = current[(val as number) + 1][1];\n\t\t\t} else if (type === 'condition') {\n\t\t\t\tcurrent = current[2][val];\n\t\t\t}\n\t\t}\n\n\t\tqueue.forEach((value, index) => {\n\t\t\t/**\n\t\t\t * Mutate the queue item\n\t\t\t */\n\t\t\tvalue.push(index);\n\t\t});\n\n\t\t/**\n\t\t * This is basically made for TypeScript.\n\t\t */\n\t\tconst indexedQueue = queue as unknown as [Exclude<ValidAction[0], ValidAction>, ValidAction[1], number][];\n\n\t\t/**\n\t\t * Run these exactly before the main loop.\n\t\t */\n\t\trenderer.ui.showScreen('game');\n\t\t/**\n\t\t * Provide the `keep` in there\n\t\t */\n\t\tmatch('clear', [keep, characters]);\n\n\t\t/**\n\t\t * Get the next actions array.\n\t\t */\n\t\tconst next = (i: number) => indexedQueue.slice(i + 1);\n\n\t\tfor await (const [action, meta, i] of indexedQueue) {\n\t\t\tif (action === 'function' || action === 'custom') {\n\t\t\t\t/**\n\t\t\t\t * When `callOnlyLatest` is `true`\n\t\t\t\t */\n\t\t\t\tif (action === 'custom' && (meta as GetActionParameters<'Custom'>)[0].callOnlyLatest) {\n\t\t\t\t\t/**\n\t\t\t\t\t * We'll calculate it is `latest` or not\n\t\t\t\t\t */\n\t\t\t\t\tconst notLatest = next(i).some(([_action, _meta]) => {\n\t\t\t\t\t\tif (!_meta || !meta) return false;\n\n\t\t\t\t\t\tconst c0 = _meta[0] as unknown as GetActionParameters<'Custom'>[0];\n\t\t\t\t\t\tconst c1 = meta[0] as unknown as GetActionParameters<'Custom'>[0];\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * Also check for `undefined`\n\t\t\t\t\t\t */\n\t\t\t\t\t\tconst isIdenticalID = c0.id && c1.id && c0.id === c1.id;\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * Equal by id or equal by `toString()`\n\t\t\t\t\t\t */\n\t\t\t\t\t\treturn isIdenticalID || str(c0) === str(c1);\n\t\t\t\t\t});\n\n\t\t\t\t\tif (notLatest) continue;\n\t\t\t\t}\n\n\t\t\t\t/**\n\t\t\t\t * Action can return Promise.\n\t\t\t\t */\n\t\t\t\tconst result = match(action, meta);\n\n\t\t\t\t/**\n\t\t\t\t * Should wait until it resolved\n\t\t\t\t */\n\t\t\t\tif (isPromise(result)) {\n\t\t\t\t\t/**\n\t\t\t\t\t * Await it!\n\t\t\t\t\t */\n\t\t\t\t\tawait result;\n\t\t\t\t}\n\t\t\t} else if (action === 'showCharacter') {\n\t\t\t\tconst skip = next(i).some(([_action, _meta]) => {\n\t\t\t\t\t/**\n\t\t\t\t\t * Проверка на возможный `undefined`\n\t\t\t\t\t */\n\t\t\t\t\tif (!_meta || !meta) return false;\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Будет ли персонаж скрыт в будущем\n\t\t\t\t\t * Нет смысла при загрузке сохранения загружать и отрисовывать персонажа, который будет скрыт\n\t\t\t\t\t */\n\t\t\t\t\tconst hidden = _action === 'hideCharacter' && _meta[0] === meta[0];\n\t\t\t\t\t/**\n\t\t\t\t\t * Не нужно запускать рендер персонажа, если после этого будет ещё один рендер этого персонажа\n\t\t\t\t\t * Таким образом избегаем ситуации, когда при загрузке вследствие гонки при загрузки изображений отрисовывается не последняя эмоция\n\t\t\t\t\t */\n\t\t\t\t\tconst notLatest = _action === action && _meta[0] === meta[0];\n\n\t\t\t\t\treturn hidden || notLatest;\n\t\t\t\t});\n\n\t\t\t\tif (skip) continue;\n\n\t\t\t\tmatch(action, meta);\n\t\t\t} else if (action === 'showBackground' || action === 'animateCharacter') {\n\t\t\t\t/**\n\t\t\t\t * Такая же оптимизация применяется к фонам и анимированию персонажей.\n\t\t\t\t * Если фон изменится, то нет смысла устанавливать текущий\n\t\t\t\t */\n\t\t\t\tconst notLatest = next(i).some(([_action]) => action === _action);\n\n\t\t\t\tif (notLatest) continue;\n\n\t\t\t\tmatch(action, meta);\n\t\t\t} else {\n\t\t\t\tmatch(action, meta);\n\t\t\t}\n\t\t}\n\n\t\t(restoring = goingBack = false), render();\n\t};\n\n\tconst refer = () => {\n\t\tlet current: any = story;\n\n\t\tfor (const [type, val] of stack.value[0]) {\n\t\t\tif (type === null) {\n\t\t\t\tcurrent = current[val];\n\t\t\t} else if (type === 'choice') {\n\t\t\t\tcurrent = current[(val as number) + 1][1];\n\t\t\t} else if (type === 'condition') {\n\t\t\t\tcurrent = current[2][val];\n\t\t\t}\n\t\t}\n\n\t\treturn current;\n\t};\n\n\t/**\n\t *\n\t * @param force Force exit\n\t */\n\tconst exit = (force = false) => {\n\t\tif (interacted && !force && askBeforeExit) {\n\t\t\trenderer.ui.showExitPrompt();\n\t\t\treturn;\n\t\t}\n\n\t\tconst current = stack.value;\n\n\t\tstack.clear();\n\t\trenderer.ui.showScreen('mainmenu');\n\n\t\t/**\n\t\t * First two save elements and it's type\n\t\t */\n\t\tconst [[first, second], , [time, type]] = current;\n\n\t\tif (type === 'auto' && first && second) {\n\t\t\t/**\n\t\t\t * Player has not interacted with game and it belongs to the current session\n\t\t\t */\n\t\t\tif (!interacted && times.has(time)) {\n\t\t\t\t$.update((prev) => {\n\t\t\t\t\tprev.saves = prev.saves.filter((save) => save !== current);\n\n\t\t\t\t\treturn prev;\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Reset interactive value\n\t\t */\n\t\tinteractivity(false);\n\t\t/**\n\t\t * Reset session times\n\t\t */\n\t\ttimes.clear();\n\t};\n\n\tconst back = () => {\n\t\treturn stack.back(), restore(stack.value);\n\t};\n\n\tconst renderer = createRenderer({\n\t\tcharacters,\n\t\tset,\n\t\trestore,\n\t\tsave,\n\t\tnewGame,\n\t\texit,\n\t\tback,\n\t\tstack,\n\t\tlanguages,\n\t\tt: t9n.i,\n\t\t$,\n\t});\n\n\tconst match = matchAction({\n\t\twait([time]) {\n\t\t\tif (!restoring) setTimeout(push, isFunction(time) ? time() : time);\n\t\t},\n\t\tshowBackground([background]) {\n\t\t\trenderer.background(background);\n\t\t\tpush();\n\t\t},\n\t\tplayMusic([source]) {\n\t\t\trenderer.music(source, 'music').play();\n\t\t\tpush();\n\t\t},\n\t\tstopMusic([source]) {\n\t\t\trenderer.music(source, 'music').stop();\n\t\t\tpush();\n\t\t},\n\t\tshowCharacter([character, emotion, className, style]) {\n\t\t\tconst handle = renderer.character(character);\n\n\t\t\thandle.append(className, style, restoring);\n\t\t\thandle.withEmotion(emotion)();\n\n\t\t\tpush();\n\t\t},\n\t\thideCharacter([character, className, style, duration]) {\n\t\t\trenderer.character(character).remove(className, style, duration)(push, restoring);\n\t\t},\n\t\tdialog([character, content, emotion]) {\n\t\t\t/**\n\t\t\t * Person name\n\t\t\t */\n\t\t\tconst name = (() => {\n\t\t\t\tconst c = character,\n\t\t\t\t\tcs = characters;\n\t\t\t\tconst lang = $.get().meta[0];\n\n\t\t\t\treturn c\n\t\t\t\t\t? c in cs\n\t\t\t\t\t\t? typeof cs[c].name === 'string'\n\t\t\t\t\t\t\t? (cs[c].name as string)\n\t\t\t\t\t\t\t: (cs[c].name as Record<string, string>)[lang]\n\t\t\t\t\t\t: c\n\t\t\t\t\t: '';\n\t\t\t})();\n\n\t\t\trenderer.dialog(unwrap(content), unwrap(name), character, emotion)(forward);\n\t\t},\n\t\tfunction([fn]) {\n\t\t\tconst result = fn(restoring, goingBack);\n\n\t\t\tif (!restoring) result ? result.then(push) : push();\n\n\t\t\treturn result;\n\t\t},\n\t\tchoice([question, ...choices]) {\n\t\t\tconst isWithoutQuestion = Array.isArray(question);\n\n\t\t\tif (isWithoutQuestion) {\n\t\t\t\t/**\n\t\t\t\t * Первый элемент может быть как строкой, так и элементов выбора\n\t\t\t\t */\n\t\t\t\tchoices.unshift(question as unknown as [Unwrappable, ValidAction[], () => boolean]);\n\t\t\t\t/**\n\t\t\t\t * Значит, текст не требуется\n\t\t\t\t */\n\t\t\t\tquestion = '';\n\t\t\t}\n\n\t\t\tconst unwrapped = choices.map(([content, action, visible]) => {\n\t\t\t\treturn [unwrap(content), action, visible] as [string, ValidAction[], () => boolean];\n\t\t\t});\n\n\t\t\trenderer.choices(\n\t\t\t\tunwrap(question),\n\t\t\t\tunwrapped,\n\t\t\t)((selected) => {\n\t\t\t\tenmemory();\n\n\t\t\t\t/**\n\t\t\t\t * If there is a question, then `index` should be shifted by `1`\n\t\t\t\t */\n\t\t\t\tconst offset = isWithoutQuestion ? 0 : 1;\n\n\t\t\t\tstack.value[0].push(['choice', selected + offset], [null, 0]);\n\t\t\t\trender();\n\t\t\t\tinteractivity(true);\n\t\t\t});\n\t\t},\n\t\tjump([scene]) {\n\t\t\t/**\n\t\t\t * `-1` index is used here because `clear` will run `next` that will increase index to `0`\n\t\t\t */\n\t\t\tstack.value[0] = [\n\t\t\t\t[null, scene],\n\t\t\t\t[null, -1],\n\t\t\t];\n\n\t\t\tmatch('clear', []);\n\t\t},\n\t\tclear([keep, characters]) {\n\t\t\t/**\n\t\t\t * Remove vibration\n\t\t\t */\n\t\t\tvibrate(0);\n\t\t\t/**\n\t\t\t * Call the actual `clear`\n\t\t\t */\n\t\t\trenderer.clear(goingBack, keep || EMPTY_SET, characters || EMPTY_SET)(push);\n\t\t},\n\t\tcondition([condition]) {\n\t\t\tconst value = condition();\n\n\t\t\tif (!restoring) stack.value[0].push(['condition', String(value)], [null, 0]), render();\n\t\t},\n\t\tend() {\n\t\t\t/**\n\t\t\t * Clear the Scene\n\t\t\t */\n\t\t\tmatch('clear', []);\n\t\t\t/**\n\t\t\t * Go to the main menu\n\t\t\t */\n\t\t\trenderer.ui.showScreen('mainmenu');\n\t\t\t/**\n\t\t\t * Reset interactive value\n\t\t\t */\n\t\t\tinteractivity(false);\n\t\t\t/**\n\t\t\t * Reset session times\n\t\t\t */\n\t\t\ttimes.clear();\n\t\t},\n\t\tinput([question, onInput, setup]) {\n\t\t\trenderer.input(unwrap(question), onInput, setup)(forward);\n\t\t},\n\t\tcustom([handler]) {\n\t\t\tconst result = renderer.custom(handler, goingBack, () => {\n\t\t\t\tif (!restoring && handler.requireUserAction) enmemory(), interactivity(true);\n\t\t\t\tif (!restoring) push();\n\t\t\t});\n\n\t\t\treturn result;\n\t\t},\n\t\tvibrate(pattern) {\n\t\t\tvibrate(pattern);\n\t\t\tpush();\n\t\t},\n\t\tnext() {\n\t\t\tpush();\n\t\t},\n\t\tanimateCharacter([character, timeout, ...classes]) {\n\t\t\tconst handler: CustomHandler = (get) => {\n\t\t\t\tconst { clear } = get('@@internal-animate-character', false);\n\t\t\t\tconst char = renderer.store.characters[character];\n\n\t\t\t\t/**\n\t\t\t\t * Character is not defined, maybe, `animateCharacter` was called before `showCharacter`\n\t\t\t\t */\n\t\t\t\tif (!char) return;\n\n\t\t\t\tconst target = char.canvas;\n\n\t\t\t\t/**\n\t\t\t\t * Character is not found\n\t\t\t\t */\n\t\t\t\tif (!target) return;\n\n\t\t\t\tconst classNames = classes.filter((className) => !target.classList.contains(className));\n\n\t\t\t\ttarget.classList.add(...classNames);\n\n\t\t\t\tconst timeoutId = setTimeout(() => {\n\t\t\t\t\ttarget.classList.remove(...classNames);\n\t\t\t\t}, timeout);\n\n\t\t\t\tclear(() => {\n\t\t\t\t\ttarget.classList.remove(...classNames);\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Clear timeout, because when you will game re-runs some callback might remove classes from character\n\t\t\t\t\t */\n\t\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\t});\n\t\t\t};\n\n\t\t\t/**\n\t\t\t * `callOnlyLatest` property will not have any effect, because `custom` is called directly\n\t\t\t */\n\t\t\tmatch('custom', [handler]);\n\t\t},\n\t\ttext(text) {\n\t\t\trenderer.text(text.map((content) => unwrap(content)).join(' '), forward);\n\t\t},\n\t\texit() {\n\t\t\tconst path = stack.value[0];\n\n\t\t\tlet exited = false;\n\n\t\t\tfor (let i = path.length - 1; i > 0; i--) {\n\t\t\t\tif (path[i][0] !== 'choice' && path[i][0] !== 'condition') continue;\n\n\t\t\t\texited = true;\n\t\t\t\tstack.value[0] = path.slice(0, i);\n\t\t\t\tnext();\n\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Run render only when exit was performed. This prevents infinite loop of `render` -> `undefined` -> `exit` -> `render`.\n\t\t\t */\n\t\t\tif (exited) render();\n\t\t},\n\t});\n\n\tconst enmemory = () => {\n\t\tif (restoring) return;\n\n\t\tconst current = klona(stack.value);\n\n\t\tcurrent[2][1] = 'auto';\n\n\t\tstack.push(current);\n\n\t\tsave(true, 'auto');\n\t};\n\n\tconst next = () => {\n\t\tconst path = stack.value[0];\n\t\t/**\n\t\t * Последний элемент пути\n\t\t */\n\t\tconst last = path[path.length - 1]!;\n\n\t\t/**\n\t\t * Если он вида `[null, int]` - увеличивает `int`\n\t\t */\n\t\tif (isNull(last[0]) && isNumber(last[1])) {\n\t\t\tlast[1] = last[1] + 1;\n\t\t\treturn;\n\t\t}\n\n\t\t/**\n\t\t * Иначе добавляет новое `[null int]`\n\t\t */\n\t\tpath.push([null, 0]);\n\t};\n\n\tconst render = () => {\n\t\tconst referred = refer();\n\n\t\tif (Array.isArray(referred)) {\n\t\t\tconst [action, ...props] = referred;\n\n\t\t\tmatch(action, props);\n\t\t} else {\n\t\t\tmatch('exit', []);\n\t\t}\n\t};\n\n\tconst push = () => {\n\t\tif (!restoring) next(), render();\n\t};\n\n\tconst forward = () => {\n\t\tenmemory();\n\t\tpush();\n\t\tinteractivity(true);\n\t};\n\n\tconst interactivity = (value = false) => {\n\t\tinteracted = value;\n\t};\n\n\t/**\n\t * Unwraps translatable content to string\n\t *\n\t * @example ```\n\t * unwrap(t('Hello'));\n\t * unwrap({ en: 'Hello', ru: 'Привет' });\n\t * unwrap({ en: () => data().ad_viewed ? 'Diamond Hat' : 'Diamond Hat (Watch Adv)' })\n\t * unwrap('Hello, {{name}}');\n\t * ```\n\t */\n\tconst unwrap = (content: Unwrappable, global = false) => {\n\t\tconst {\n\t\t\tdata,\n\t\t\tmeta: [lang],\n\t\t} = $.get();\n\n\t\tconst obj = global ? data : state();\n\t\tconst cnt = isFunction(content) ? content(lang, obj) : typeof content === 'string' ? content : content[lang];\n\n\t\tconst str = isFunction(cnt) ? cnt() : cnt;\n\n\t\treturn replaceT9N(str, obj);\n\t};\n\n\tfunction data(value: DeepPartial<DataScheme> | ((prev: DataScheme) => DataScheme)): void;\n\tfunction data(): DataScheme;\n\tfunction data(value?: DeepPartial<DataScheme> | ((prev: DataScheme) => DataScheme)): DataScheme | void {\n\t\tif (!value) return $.get().data as DataScheme | void;\n\n\t\tconst prev = $.get().data;\n\t\tconst val = isFunction(value) ? value(prev as DataScheme) : deepmerge([prev, value]);\n\n\t\t$.update((prev) => {\n\t\t\tprev.data = val;\n\n\t\t\treturn prev;\n\t\t});\n\t}\n\n\treturn {\n\t\t/**\n\t\t * Function to set story\n\t\t */\n\t\twithStory,\n\t\t/**\n\t\t * Function to get actions\n\t\t */\n\t\taction,\n\t\t/**\n\t\t * State that belongs to games\n\t\t */\n\t\tstate,\n\t\t/**\n\t\t * Unlike `state`, stored at global scope instead and shared between games\n\t\t */\n\t\tdata,\n\t\t/**\n\t\t * Unwraps translatable content to a string value\n\t\t */\n\t\tunwrap(content: Exclude<Unwrappable, Record<string, string>> | Record<Languages, string>) {\n\t\t\treturn unwrap(content, true);\n\t\t},\n\t\t/**\n\t\t * Function that is used for translation\n\t\t */\n\t\tt: t9n.t as Inter['t'],\n\t};\n};\n\nexport { novely };\n","export function klona(val) {\n\tvar k, out, tmp;\n\n\tif (Array.isArray(val)) {\n\t\tout = Array(k=val.length);\n\t\twhile (k--) out[k] = (tmp=val[k]) && typeof tmp === 'object' ? klona(tmp) : tmp;\n\t\treturn out;\n\t}\n\n\tif (Object.prototype.toString.call(val) === '[object Object]') {\n\t\tout = {}; // null\n\t\tfor (k in val) {\n\t\t\tif (k === '__proto__') {\n\t\t\t\tObject.defineProperty(out, k, {\n\t\t\t\t\tvalue: klona(val[k]),\n\t\t\t\t\tconfigurable: true,\n\t\t\t\t\tenumerable: true,\n\t\t\t\t\twritable: true,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tout[k] = (tmp=val[k]) && typeof tmp === 'object' ? klona(tmp) : tmp;\n\t\t\t}\n\t\t}\n\t\treturn out;\n\t}\n\n\treturn val;\n}\n","const SKIPPED_DURING_RESTORE = new Set(['dialog', 'choice', 'input', 'vibrate', 'text'] as const);\n\nconst EMPTY_SET = new Set<any>();\n\nexport { SKIPPED_DURING_RESTORE, EMPTY_SET };\n","const split = (input: string, delimeters: string[]) => {\n\tconst output: (string | undefined)[] = [];\n\n\tfor (const delimeter of delimeters) {\n\t\tif (!input) break;\n\n\t\tconst [start, end] = input.split(delimeter, 2);\n\n\t\toutput.push(start);\n\t\tinput = end;\n\t}\n\n\toutput.push(input);\n\n\treturn output;\n};\n\nexport { split };\n","import type { BaseTranslationStrings } from './translations';\nimport { split } from './lib';\n\ntype PluralType = Intl.LDMLPluralRule;\ntype FunctionalSetupT9N = <\n\tLanguageKey extends string,\n\tPluralKey extends string,\n\tStringKey extends string,\n\tActions extends string,\n>(parameters: {\n\t[Lang in LanguageKey]: {\n\t\tpluralization: {\n\t\t\t[Plural in PluralKey]: Partial<Record<PluralType, string>>;\n\t\t};\n\t\tinternal: { [Key in BaseTranslationStrings]: string };\n\t\tstrings: { [Str in StringKey]: string };\n\t\tactions?: { [Action in Actions]?: (value: string) => string };\n\t};\n}) => T9N<LanguageKey, StringKey>;\ntype SetupT9N<LanguageKey extends string> = <\n\tPluralKey extends string,\n\tStringKey extends string,\n\tActions extends string,\n>(parameters: {\n\t[Lang in LanguageKey]: {\n\t\tpluralization: {\n\t\t\t[Plural in PluralKey]: Partial<Record<PluralType, string>>;\n\t\t};\n\t\tinternal: { [Key in BaseTranslationStrings]: string };\n\t\tstrings: { [Str in StringKey]: string };\n\t\tactions?: { [Action in Actions]?: (value: string) => string };\n\t};\n}) => T9N<LanguageKey, StringKey>;\n\ntype T9N<LanguageKey extends string, StringKey extends string> = {\n\tt(\n\t\tkey: StringKey | Record<LanguageKey, AllowedContent>,\n\t): (lang: LanguageKey | (string & {}), obj: Record<string, unknown>) => string;\n\ti(key: StringKey, lang: LanguageKey | (string & {})): string;\n};\n\nconst RGX = /{{(.*?)}}/g;\n\ntype AllowedContent = string | (() => string | string[]) | string[] | (string | (() => string | string[]))[];\n\n/**\n * Unwraps any allowed content into string\n * @param c Content\n */\nconst unwrap = (c: AllowedContent): string => {\n\tif (Array.isArray(c)) {\n\t\treturn c.map((item) => unwrap(item)).join('<br>');\n\t}\n\n\tif (typeof c === 'function') {\n\t\treturn unwrap(c());\n\t}\n\n\treturn c;\n};\n\nconst replace = (\n\tstr: AllowedContent,\n\tobj: Record<string, unknown>,\n\tpluralization?: Record<string, Record<string, PluralType>>,\n\tactions?: Partial<Record<string, (str: string) => string>>,\n\tpr?: Intl.PluralRules,\n) => {\n\treturn unwrap(str).replace(RGX, (x: any, key: string, y: any) => {\n\t\tx = 0;\n\t\ty = obj;\n\n\t\tconst [pathstr, plural, action] = split(key.trim(), ['@', '%']);\n\n\t\tlet path = pathstr!.split('.');\n\n\t\twhile (y && x < path.length) y = y[path[x++]];\n\n\t\tif (plural && pluralization && y && pr) {\n\t\t\ty = pluralization[plural][pr.select(y)];\n\t\t}\n\n\t\tconst actionHandler = actions && action && actions[action];\n\n\t\tif (actionHandler) y = actionHandler(y);\n\n\t\treturn y != null ? y : '';\n\t});\n};\n\nconst createT9N: FunctionalSetupT9N = (parameters) => {\n\tlet locale: string | undefined;\n\tlet pr: Intl.PluralRules | undefined;\n\n\treturn {\n\t\tt(key) {\n\t\t\treturn (lang, obj) => {\n\t\t\t\t/**\n\t\t\t\t * At first run `locale` and `pr` are not defined.\n\t\t\t\t * When `locale` changes, `pr` should be updated`\n\t\t\t\t */\n\t\t\t\tif (!locale || !pr || lang != locale) {\n\t\t\t\t\tpr = new Intl.PluralRules((locale = lang));\n\t\t\t\t}\n\n\t\t\t\t// @ts-ignore\n\t\t\t\tconst str: string | string[] = typeof key === 'object' ? key[lang] : parameters[lang]['strings'][key];\n\n\t\t\t\tif (!str) return '';\n\n\t\t\t\t// @ts-ignore `(string & {})` cannot be used to index type `LanguageKey`.\n\t\t\t\treturn replace(str, obj, parameters[lang]['pluralization'], parameters[lang]['actions'], pr);\n\t\t\t};\n\t\t},\n\t\ti(key, lang) {\n\t\t\t// @ts-ignore `(string & {})` cannot be used to index type `LanguageKey`.\n\t\t\treturn parameters[lang]['internal'][key] as string;\n\t\t},\n\t};\n};\n\nexport { createT9N, replace };\nexport type { SetupT9N, T9N, AllowedContent, FunctionalSetupT9N };\n","const RU = {\n\tNewGame: 'Новая игра',\n\tHomeScreen: 'Главный экран',\n\tToTheGame: 'К игре',\n\tLanguage: 'Язык',\n\tNoSaves: 'Сохранений нет',\n\tLoadSave: 'Загрузить',\n\tSaves: 'Сохранения',\n\tSettings: 'Настройки',\n\tSumbit: 'Подтвердить',\n\tGoBack: 'Назад',\n\tDoSave: 'Сохранение',\n\tAuto: 'Авто',\n\tStop: 'Стоп',\n\tExit: 'Выход',\n\tAutomatic: 'Автоматическое',\n\tManual: 'Ручное',\n\tRemove: 'Удалить',\n\tLoadASaveFrom: 'Загрузить сохранение от',\n\tDeleteASaveFrom: 'Удалить сохранение от',\n\tTextSpeed: 'Скорость Текста',\n\tTextSpeedSlow: 'Медленная',\n\tTextSpeedMedium: 'Средняя',\n\tTextSpeedFast: 'Быстрая',\n\tTextSpeedAuto: 'Автоматическая',\n\tCompleteText: 'Завершить текст',\n\tGoForward: 'Перейти вперёд',\n\tExitDialogWarning: 'Вы уверены, что хотите выйти? Прогресс будет сохранён.',\n\tExitDialogExit: 'Выйти',\n\tExitDialogBack: 'Вернуться в игру',\n};\n\ntype BaseTranslationStrings = keyof typeof RU;\n\nconst EN: Record<BaseTranslationStrings, string> = {\n\tNewGame: 'New Game',\n\tHomeScreen: 'Home Screen',\n\tToTheGame: 'To the Game',\n\tLanguage: 'Language',\n\tNoSaves: 'No saves',\n\tLoadSave: 'Load',\n\tSaves: 'Saves',\n\tSettings: 'Settings',\n\tSumbit: 'Submit',\n\tGoBack: 'Go back',\n\tDoSave: 'Save',\n\tAuto: 'Auto',\n\tStop: 'Stop',\n\tExit: 'Exit',\n\tAutomatic: 'Automatic',\n\tManual: 'Manual',\n\tRemove: 'Remove',\n\tLoadASaveFrom: 'Load a save from',\n\tDeleteASaveFrom: 'Delete a save from',\n\tTextSpeed: 'Text Speed',\n\tTextSpeedSlow: 'Slow',\n\tTextSpeedMedium: 'Medium',\n\tTextSpeedFast: 'Fast',\n\tTextSpeedAuto: 'Auto',\n\tCompleteText: 'Complete text',\n\tGoForward: 'Go forward',\n\tExitDialogWarning: 'Are you sure you want to exit? Progress will be saved.',\n\tExitDialogExit: 'Exit',\n\tExitDialogBack: 'Return to game',\n};\n\n/**\n * Translated automatically\n */\nconst KK: Record<BaseTranslationStrings, string> = {\n\tNewGame: 'Жаңа ойын',\n\tHomeScreen: 'Негізгі экран',\n\tToTheGame: 'Ойынға',\n\tLanguage: 'Тіл',\n\tNoSaves: 'Сақтау жоқ',\n\tLoadSave: 'Жүктеу',\n\tSaves: 'Сақтау',\n\tSettings: 'Параметрлер',\n\tSumbit: 'Растау',\n\tGoBack: 'Артқа',\n\tDoSave: 'Сақтау',\n\tAuto: 'Авто',\n\tStop: 'Тоқта',\n\tExit: 'Шығу',\n\tAutomatic: 'Автоматты',\n\tManual: 'Қолмен',\n\tRemove: 'Жою',\n\tLoadASaveFrom: 'Сақтауды жүктеу',\n\tDeleteASaveFrom: 'Сақтауды жою',\n\tTextSpeed: 'Мәтін Жылдамдығы',\n\tTextSpeedSlow: 'Баяу',\n\tTextSpeedMedium: 'Орташа',\n\tTextSpeedFast: 'Жылдам',\n\tTextSpeedAuto: 'Автоматты',\n\tCompleteText: 'Мәтінді аяқтау',\n\tGoForward: 'Алға жылжу',\n\tExitDialogWarning: 'Сіз шыққыңыз келетініне сенімдісіз бе? Прогресс сақталады',\n\tExitDialogExit: 'Шығу',\n\tExitDialogBack: 'Ойынға оралу'\n};\n\n/**\n * Translated automatically\n */\nconst JP: Record<BaseTranslationStrings, string> = {\n\tNewGame: '「新しいゲーム」',\n\tHomeScreen: 'ホーム画面',\n\tToTheGame: '「ゲームに戻る」',\n\tLanguage: '言語',\n\tNoSaves: 'ノーセーブ',\n\tLoadSave: 'ダウンロード',\n\tSaves: '保存',\n\tSettings: '設定',\n\tSumbit: '確認',\n\tGoBack: '「戻る」',\n\tDoSave: '保存',\n\tAuto: 'オート',\n\tStop: '止まれ',\n\tExit: '出口',\n\tAutomatic: '自動',\n\tManual: 'マニュアル',\n\tRemove: '削除',\n\tLoadASaveFrom: 'ロードセーブから',\n\tDeleteASaveFrom: 'から保存を削除',\n\tTextSpeed: 'テキストスピード',\n\tTextSpeedSlow: '「遅い」',\n\tTextSpeedMedium: 'ミディアム',\n\tTextSpeedFast: '「速い」',\n\tTextSpeedAuto: '自動',\n\tCompleteText: 'テキストを完成させる',\n\tGoForward: '先に行く',\n\tExitDialogWarning: '本当に終了しますか?進行状況は保存されます',\n\tExitDialogExit: '終了',\n\tExitDialogBack: 'ゲームに戻る',\n};\n\nexport { RU, EN, KK, JP };\nexport type { BaseTranslationStrings };\n","import type { StorageData } from './types';\n\ninterface LocalStorageStorageSettings {\n\tkey: string;\n}\n\ninterface Storage {\n\tget: () => Promise<StorageData>;\n\tset: (data: StorageData) => Promise<void>;\n}\n\nconst localStorageStorage = (options: LocalStorageStorageSettings): Storage => {\n\treturn {\n\t\tasync get() {\n\t\t\tconst value = localStorage.getItem(options.key);\n\n\t\t\treturn value ? JSON.parse(value) : { saves: [], data: {}, meta: [] };\n\t\t},\n\t\tasync set(data) {\n\t\t\tlocalStorage.setItem(options.key, JSON.stringify(data));\n\t\t},\n\t};\n};\n\nexport type { Storage };\nexport { localStorageStorage };\n"],"mappings":"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","names":["isMergeableObject","deepmerge","split","input","delimeters","output","delimeter","start","end","RGX","unwrap","c","item","replace","str","obj","pluralization","actions","pr","x","key","y","pathstr","plural","action","path","actionHandler","getLanguage","data","deepmerge","state","stack","save","characters","action","push","index","next","str","prev"]}
|
|
1
|
+
{"version":3,"sources":["../../../node_modules/.pnpm/deepmerge@4.3.1/node_modules/deepmerge/dist/cjs.js","../src/index.ts","../src/utils.ts","../src/global.ts","../src/store.ts","../src/novely.ts","../../../node_modules/.pnpm/klona@2.0.6/node_modules/klona/json/index.mjs","../src/constants.ts","../../t9n/src/lib.ts","../../t9n/src/translation.ts","../../t9n/src/translations.ts","../src/storage.ts"],"sourcesContent":["'use strict';\n\nvar isMergeableObject = function isMergeableObject(value) {\n\treturn isNonNullObject(value)\n\t\t&& !isSpecial(value)\n};\n\nfunction isNonNullObject(value) {\n\treturn !!value && typeof value === 'object'\n}\n\nfunction isSpecial(value) {\n\tvar stringValue = Object.prototype.toString.call(value);\n\n\treturn stringValue === '[object RegExp]'\n\t\t|| stringValue === '[object Date]'\n\t\t|| isReactElement(value)\n}\n\n// see https://github.com/facebook/react/blob/b5ac963fb791d1298e7f396236383bc955f916c1/src/isomorphic/classic/element/ReactElement.js#L21-L25\nvar canUseSymbol = typeof Symbol === 'function' && Symbol.for;\nvar REACT_ELEMENT_TYPE = canUseSymbol ? Symbol.for('react.element') : 0xeac7;\n\nfunction isReactElement(value) {\n\treturn value.$$typeof === REACT_ELEMENT_TYPE\n}\n\nfunction emptyTarget(val) {\n\treturn Array.isArray(val) ? [] : {}\n}\n\nfunction cloneUnlessOtherwiseSpecified(value, options) {\n\treturn (options.clone !== false && options.isMergeableObject(value))\n\t\t? deepmerge(emptyTarget(value), value, options)\n\t\t: value\n}\n\nfunction defaultArrayMerge(target, source, options) {\n\treturn target.concat(source).map(function(element) {\n\t\treturn cloneUnlessOtherwiseSpecified(element, options)\n\t})\n}\n\nfunction getMergeFunction(key, options) {\n\tif (!options.customMerge) {\n\t\treturn deepmerge\n\t}\n\tvar customMerge = options.customMerge(key);\n\treturn typeof customMerge === 'function' ? customMerge : deepmerge\n}\n\nfunction getEnumerableOwnPropertySymbols(target) {\n\treturn Object.getOwnPropertySymbols\n\t\t? Object.getOwnPropertySymbols(target).filter(function(symbol) {\n\t\t\treturn Object.propertyIsEnumerable.call(target, symbol)\n\t\t})\n\t\t: []\n}\n\nfunction getKeys(target) {\n\treturn Object.keys(target).concat(getEnumerableOwnPropertySymbols(target))\n}\n\nfunction propertyIsOnObject(object, property) {\n\ttry {\n\t\treturn property in object\n\t} catch(_) {\n\t\treturn false\n\t}\n}\n\n// Protects from prototype poisoning and unexpected merging up the prototype chain.\nfunction propertyIsUnsafe(target, key) {\n\treturn propertyIsOnObject(target, key) // Properties are safe to merge if they don't exist in the target yet,\n\t\t&& !(Object.hasOwnProperty.call(target, key) // unsafe if they exist up the prototype chain,\n\t\t\t&& Object.propertyIsEnumerable.call(target, key)) // and also unsafe if they're nonenumerable.\n}\n\nfunction mergeObject(target, source, options) {\n\tvar destination = {};\n\tif (options.isMergeableObject(target)) {\n\t\tgetKeys(target).forEach(function(key) {\n\t\t\tdestination[key] = cloneUnlessOtherwiseSpecified(target[key], options);\n\t\t});\n\t}\n\tgetKeys(source).forEach(function(key) {\n\t\tif (propertyIsUnsafe(target, key)) {\n\t\t\treturn\n\t\t}\n\n\t\tif (propertyIsOnObject(target, key) && options.isMergeableObject(source[key])) {\n\t\t\tdestination[key] = getMergeFunction(key, options)(target[key], source[key], options);\n\t\t} else {\n\t\t\tdestination[key] = cloneUnlessOtherwiseSpecified(source[key], options);\n\t\t}\n\t});\n\treturn destination\n}\n\nfunction deepmerge(target, source, options) {\n\toptions = options || {};\n\toptions.arrayMerge = options.arrayMerge || defaultArrayMerge;\n\toptions.isMergeableObject = options.isMergeableObject || isMergeableObject;\n\t// cloneUnlessOtherwiseSpecified is added to `options` so that custom arrayMerge()\n\t// implementations can use it. The caller may not replace it.\n\toptions.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified;\n\n\tvar sourceIsArray = Array.isArray(source);\n\tvar targetIsArray = Array.isArray(target);\n\tvar sourceAndTargetTypesMatch = sourceIsArray === targetIsArray;\n\n\tif (!sourceAndTargetTypesMatch) {\n\t\treturn cloneUnlessOtherwiseSpecified(source, options)\n\t} else if (sourceIsArray) {\n\t\treturn options.arrayMerge(target, source, options)\n\t} else {\n\t\treturn mergeObject(target, source, options)\n\t}\n}\n\ndeepmerge.all = function deepmergeAll(array, options) {\n\tif (!Array.isArray(array)) {\n\t\tthrow new Error('first argument should be an array')\n\t}\n\n\treturn array.reduce(function(prev, next) {\n\t\treturn deepmerge(prev, next, options)\n\t}, {})\n};\n\nvar deepmerge_1 = deepmerge;\n\nmodule.exports = deepmerge_1;\n","export type {\n\tValidAction,\n\tStory,\n\tActionProxyProvider,\n\tDefaultActionProxyProvider,\n\tGetActionParameters,\n\tUnwrappable,\n\tCustomHandler,\n\tCustomHandlerGetResult,\n\tCustomHandlerGetResultDataFunction,\n\tFunctionableValue,\n} from './action';\nexport type { Emotions, Character } from './character';\nexport type { CharacterHandle, AudioHandle, RendererStore, Renderer, RendererInit } from './renderer';\nexport type { Storage } from './storage';\nexport type { Thenable, Path, StorageData, StorageMeta, TypewriterSpeed, Lang, NovelyScreen } from './types';\nexport type { Stored } from './store';\nexport type { BaseTranslationStrings } from '@novely/t9n';\n\nexport { novely } from './novely';\nexport { localStorageStorage } from './storage';\n","import type { ActionProxyProvider, CustomHandler } from './action';\nimport type { Character } from './character';\nimport type { TypewriterSpeed, Thenable } from './types';\n\ntype MatchActionMap = {\n\t[Key in keyof ActionProxyProvider<Record<string, Character>>]: (\n\t\tdata: Parameters<ActionProxyProvider<Record<string, Character>>[Key]>,\n\t) => void;\n};\n\ntype MatchActionMapComplete = Omit<MatchActionMap, 'custom'> & {\n\tcustom: (value: [handler: CustomHandler]) => Thenable<void>;\n};\n\nconst matchAction = <M extends MatchActionMapComplete>(values: M) => {\n\treturn (action: keyof MatchActionMap, props: any) => {\n\t\treturn values[action](props);\n\t};\n};\n\nconst isNumber = (val: unknown): val is number => {\n\treturn typeof val === 'number';\n};\n\nconst isNull = (val: unknown): val is null => {\n\treturn val === null;\n};\n\nconst isString = (val: unknown): val is string => {\n\treturn typeof val === 'string';\n};\n\nconst isFunction = (val: unknown): val is (...parameters: any[]) => any => {\n\treturn typeof val === 'function';\n};\n\nconst isPromise = (val: unknown): val is Promise<any> => {\n\treturn Boolean(val) && (typeof val === 'object' || isFunction(val)) && isFunction((val as any).then);\n};\n\nconst isEmpty = (val: unknown): val is {} => {\n\treturn typeof val === 'object' && !isNull(val) && Object.keys(val).length === 0;\n};\n\nconst isCSSImage = (str: string) => {\n\tconst startsWith = String.prototype.startsWith.bind(str);\n\n\treturn startsWith('http') || startsWith('/') || startsWith('.') || startsWith('data');\n};\n\nconst str = (value: unknown) => {\n\treturn String(value);\n};\n\nconst isUserRequiredAction = (\n\taction: keyof MatchActionMapComplete,\n\tmeta: Parameters<MatchActionMapComplete[keyof MatchActionMapComplete]>,\n) => {\n\treturn action === 'custom' && meta[0] && (meta[0] as unknown as CustomHandler).requireUserAction;\n};\n\nconst getTypewriterSpeed = (): TypewriterSpeed => {\n\treturn 'Medium';\n};\n\nconst getLanguage = (languages: string[], _: any) => {\n\tlet { language } = navigator;\n\n\tif (languages.includes(language)) {\n\t\treturn language;\n\t} else if (languages.includes((language = language.substring(0, 2)))) {\n\t\treturn language;\n\t} else if ((language = languages.find((value) => navigator.languages.includes(value))!)) {\n\t\treturn language;\n\t}\n\n\t/**\n\t * We'v checked the `en-GB` format, `en` format, and maybe any second languages, but there were no matches\n\t */\n\treturn languages[0];\n};\n\n/**\n * @copyright Techlead LLC\n * @see https://learn.javascript.ru/task/throttle\n */\nconst throttle = <Fn extends (...args: any[]) => any>(fn: Fn, ms: number) => {\n\tlet throttled = false,\n\t\tsavedArgs: any,\n\t\tsavedThis: any;\n\n\tfunction wrapper(this: any) {\n\t\tif (throttled) {\n\t\t\tsavedArgs = arguments;\n\t\t\tsavedThis = this;\n\t\t\treturn;\n\t\t}\n\n\t\tfn.apply(this, arguments as unknown as any[]);\n\n\t\tthrottled = true;\n\n\t\tsetTimeout(function () {\n\t\t\tthrottled = false;\n\n\t\t\tif (savedArgs) {\n\t\t\t\twrapper.apply(savedThis, savedArgs);\n\t\t\t\tsavedArgs = savedThis = null;\n\t\t\t}\n\t\t}, ms);\n\t}\n\n\treturn wrapper as unknown as (...args: Parameters<Fn>) => void;\n};\n\nconst vibrate = (pattern: VibratePattern) => {\n\ttry {\n\t\tif ('vibrate' in navigator) {\n\t\t\tnavigator.vibrate(pattern);\n\t\t}\n\t} catch {}\n};\n\nconst findLastIndex = <T>(array: T[], fn: (item: T) => boolean) => {\n\tfor (let i = array.length - 1; i > 0; i--) {\n\t\tif (fn(array[i])) {\n\t\t\treturn i;\n\t\t}\n\t}\n\n\treturn -1;\n};\n\nconst preloadImagesBlocking = (images: Set<string>) => {\n\treturn Promise.allSettled(Array.from(images).map(src => {\n\t\tconst img = document.createElement('img');\n\n\t\timg.src = src;\n\n\t\treturn new Promise<unknown>((resolve, reject) => {\n\t\t\t/**\n\t\t\t * Image is already loaded\n\t\t\t */\n\t\t\tif (img.complete && img.naturalHeight !== 0) {\n\t\t\t\tresolve(void 0);\n\t\t\t}\n\n\t\t\timg.addEventListener('load', resolve);\n\t\t\timg.addEventListener('abort', reject);\n\t\t\timg.addEventListener('error', reject);\n\t\t});\n\t}));\n}\n\nconst createDeferredPromise = <T extends unknown = void>() => {\n\tlet resolve!: (value: T | PromiseLike<T>) => void, reject!: (reason?: any) => void;\n\n\tconst promise = new Promise<T>((res, rej) => {\n\t\tresolve = res; reject = rej;\n\t});\n\n\treturn { resolve, reject, promise }\n}\n\nexport {\n\tmatchAction,\n\tisNumber,\n\tisNull,\n\tisString,\n\tisPromise,\n\tisEmpty,\n\tisCSSImage,\n\tstr,\n\tisUserRequiredAction,\n\tgetTypewriterSpeed,\n\tgetLanguage,\n\tthrottle,\n\tisFunction,\n\tvibrate,\n\tfindLastIndex,\n\tpreloadImagesBlocking,\n\tcreateDeferredPromise\n};\n","const PRELOADED_ASSETS = new Set<string>();\n\nexport { PRELOADED_ASSETS }\n","type Stored<T> = {\n\tsubscribe: (cb: (value: T) => void) => () => void;\n\tupdate: (fn: (prev: T) => T) => void;\n\tget: () => T;\n};\n\nconst store = <T>(current: T, subscribers = new Set<(value: T) => void>()): Stored<T> => {\n\tconst subscribe = (cb: (value: T) => void) => {\n\t\tsubscribers.add(cb), cb(current);\n\n\t\treturn () => {\n\t\t\tsubscribers.delete(cb);\n\t\t};\n\t};\n\n\tconst push = (value: T) => {\n\t\tsubscribers.forEach((cb) => cb(value));\n\t};\n\n\tconst update = (fn: (prev: T) => T) => {\n\t\tpush((current = fn(current)));\n\t};\n\n\tconst get = () => {\n\t\treturn current;\n\t};\n\n\treturn { subscribe, update, get } as const;\n};\n\nexport { store };\nexport type { Stored };\n","import type { Character } from './character';\nimport type {\n\tActionProxyProvider,\n\tGetActionParameters,\n\tStory,\n\tValidAction,\n\tUnwrappable,\n\tCustomHandler,\n} from './action';\nimport type { Storage } from './storage';\nimport type { Save, State, Data, StorageData, DeepPartial, NovelyScreen, Migration, ActionFN } from './types';\nimport type { Renderer, RendererInit } from './renderer';\nimport type { SetupT9N } from '@novely/t9n';\nimport {\n\tmatchAction,\n\tisNumber,\n\tisNull,\n\tisString,\n\tisPromise,\n\tisEmpty,\n\tisCSSImage,\n\tstr,\n\tisUserRequiredAction,\n\tgetTypewriterSpeed,\n\tgetLanguage as defaultGetLanguage,\n\tthrottle,\n\tisFunction,\n\tvibrate,\n\tfindLastIndex,\n\tpreloadImagesBlocking,\n\tcreateDeferredPromise\n} from './utils';\nimport { PRELOADED_ASSETS } from './global';\nimport { store } from './store';\nimport { all as deepmerge } from 'deepmerge';\nimport { klona } from 'klona/json';\nimport { SKIPPED_DURING_RESTORE, EMPTY_SET } from './constants';\nimport { replace as replaceT9N } from '@novely/t9n';\n\ninterface NovelyInit<\n\tLanguages extends string,\n\tCharacters extends Record<string, Character<Languages>>,\n\tInter extends ReturnType<SetupT9N<Languages>>,\n\tStateScheme extends State,\n\tDataScheme extends Data,\n> {\n\t/**\n\t * An array of languages supported by the game.\n\t */\n\tlanguages: Languages[];\n\t/**\n\t * An object containing the characters in the game.\n\t */\n\tcharacters: Characters;\n\t/**\n\t * An object that provides access to the game's storage system.\n\t */\n\tstorage: Storage;\n\t/**\n\t * Delay loading data until Promise is resolved\n\t */\n\tstorageDelay?: Promise<void>;\n\t/**\n\t * A function that returns a Renderer object used to display the game's content\n\t */\n\trenderer: (characters: RendererInit) => Renderer;\n\t/**\n\t * An optional property that specifies the initial screen to display when the game starts\n\t */\n\tinitialScreen?: NovelyScreen;\n\t/**\n\t * An object containing the translation functions used in the game\n\t */\n\tt9n: Inter;\n\t/**\n\t * Initial state value\n\t */\n\tstate?: StateScheme;\n\t/**\n\t * Initial data value\n\t */\n\tdata?: DataScheme;\n\t/**\n\t * Enable autosaves or disable\n\t * @default true\n\t */\n\tautosaves?: boolean;\n\t/**\n\t * Migration from old saves to newer\n\t */\n\tmigrations?: Migration[];\n\t/**\n\t * For saves Novely uses `throttle` function. This might be needed if you want to control frequency of saves to the storage\n\t * @default 799\n\t */\n\tthrottleTimeout?: number;\n\t/**\n\t * Custom language detector\n\t * @param languages Supported languages aka `languages: []` in the config\n\t * @example ```ts\n\t * novely({\n\t * \t\tgetLanguage(languages, original) {\n\t * \t\t\t\tif (!sdk) return original(languages);\n\t * \t\t\t\treturn sdk.environment.i18n.lang // i.e. custom language from some sdk\n\t * \t\t}\n\t * })\n\t * ```\n\t */\n\tgetLanguage?: (languages: string[], original: typeof defaultGetLanguage) => string;\n\t/**\n\t * Ignores saved language, and uses `getLanguage` to get it on every engine start\n\t * @default false\n\t */\n\toverrideLanguage?: boolean;\n\t/**\n\t * Show a prompt before exiting a game\n\t * @default true\n\t */\n\taskBeforeExit?: boolean;\n\t/**\n\t * @default \"lazy\"\n\t */\n\tpreloadAssets?: \"lazy\" | \"blocking\"\n}\n\nconst novely = <\n\tLanguages extends string,\n\tCharacters extends Record<string, Character<Languages>>,\n\tInter extends ReturnType<SetupT9N<Languages>>,\n\tStateScheme extends State,\n\tDataScheme extends Data,\n>({\n\tcharacters,\n\tstorage,\n\tstorageDelay = Promise.resolve(),\n\trenderer: createRenderer,\n\tinitialScreen = 'mainmenu',\n\tt9n,\n\tlanguages,\n\tstate: defaultState,\n\tdata: defaultData,\n\tautosaves = true,\n\tmigrations = [],\n\tthrottleTimeout = 799,\n\tgetLanguage = defaultGetLanguage,\n\toverrideLanguage = false,\n\taskBeforeExit = true,\n\tpreloadAssets = \"lazy\"\n}: NovelyInit<Languages, Characters, Inter, StateScheme, DataScheme>) => {\n\tlet story: Story;\n\tlet times = new Set<number>();\n\n\tconst ASSETS_TO_PRELOAD = new Set<string>();\n\tconst assetsLoaded = createDeferredPromise();\n\n\t/**\n\t * Prevent `undefined`\n\t */\n\tdefaultData ||= {} as DataScheme;\n\tdefaultState ||= {} as StateScheme;\n\n\t/**\n\t * Saves timestamps created in this session\n\t */\n\tconst intime = (value: number) => {\n\t\treturn times.add(value), value;\n\t};\n\n\tconst withStory = async (s: Story) => {\n\t\t/**\n\t\t * Transforms `(ValidAction | ValidAction[])[]` to `ValidAction[]`\n\t\t */\n\t\tstory = Object.fromEntries(\n\t\t\tObject.entries(s).map(([name, items]) => {\n\t\t\t\tconst flat = (item: (ValidAction | ValidAction[])[]): ValidAction[] => {\n\t\t\t\t\treturn item.flatMap((data) => {\n\t\t\t\t\t\tconst type = data[0];\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * This is not just an action like `['name', ...arguments]`, but an array of actions\n\t\t\t\t\t\t */\n\t\t\t\t\t\tif (Array.isArray(type)) return flat(data as ValidAction[]);\n\n\t\t\t\t\t\treturn [data as ValidAction];\n\t\t\t\t\t});\n\t\t\t\t};\n\n\t\t\t\treturn [name, flat(items)];\n\t\t\t}),\n\t\t);\n\n\t\tif (preloadAssets === 'blocking' && ASSETS_TO_PRELOAD.size > 0) {\n\t\t\trenderer.ui.showScreen('loading');\n\n\t\t\tawait preloadImagesBlocking(ASSETS_TO_PRELOAD);\n\t\t}\n\n\t\tASSETS_TO_PRELOAD.clear();\n\t\tassetsLoaded.resolve();\n\n\t\t/**\n\t\t * When `initialScreen` is not a game, we can safely show it\n\t\t */\n\t\tif (initialScreen !== 'game') renderer.ui.showScreen(initialScreen);\n\t};\n\n\tconst action = new Proxy({} as ActionProxyProvider<Characters>, {\n\t\tget(_, prop) {\n\t\t\treturn (...props: Parameters<ActionFN>) => {\n\t\t\t\tif (preloadAssets === 'blocking') {\n\t\t\t\t\t/**\n\t\t\t\t\t * Load backgrounds\n\t\t\t\t\t */\n\t\t\t\t\tif (prop === 'showBackground' && typeof props[0] === 'string' && isCSSImage(props[0])) {\n\t\t\t\t\t\tASSETS_TO_PRELOAD.add(props[0]);\n\t\t\t\t\t}\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Load characters\n\t\t\t\t\t */\n\t\t\t\t\tif (prop === 'showCharacter' && typeof props[0] === 'string' && typeof props[1] === 'string') {\n\t\t\t\t\t\tconst images = characters[props[0]].emotions[props[1]];\n\n\t\t\t\t\t\tif (typeof images === 'string') {\n\t\t\t\t\t\t\tASSETS_TO_PRELOAD.add(images);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tfor (const asset of [images.head, images.body.left, images.body.right]) {\n\t\t\t\t\t\t\t\tASSETS_TO_PRELOAD.add(asset);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn [prop, ...props];\n\t\t\t};\n\t\t},\n\t});\n\n\tfunction state(value: DeepPartial<StateScheme> | ((prev: StateScheme) => StateScheme)): void;\n\tfunction state(): StateScheme;\n\tfunction state(value?: DeepPartial<StateScheme> | ((prev: StateScheme) => StateScheme)): StateScheme | void {\n\t\tif (!value) return stack.value[1] as StateScheme | void;\n\n\t\tconst prev = stack.value[1];\n\t\tconst val = isFunction(value) ? value(prev as StateScheme) : deepmerge([prev, value]);\n\n\t\tstack.value[1] = val as StateScheme;\n\t}\n\n\tconst getDefaultSave = (state = {}) => {\n\t\treturn [\n\t\t\t[\n\t\t\t\t[null, 'start'],\n\t\t\t\t[null, 0],\n\t\t\t],\n\t\t\tstate,\n\t\t\t[intime(Date.now()), 'auto'],\n\t\t] as Save;\n\t};\n\n\tconst createStack = (current: Save, stack = [current]) => {\n\t\treturn {\n\t\t\tget value() {\n\t\t\t\treturn stack.at(-1)!;\n\t\t\t},\n\t\t\tset value(value: Save) {\n\t\t\t\tstack[stack.length - 1] = value;\n\t\t\t},\n\t\t\tback() {\n\t\t\t\tif (stack.length > 1) stack.pop(), (goingBack = true);\n\t\t\t},\n\t\t\tpush(value: Save) {\n\t\t\t\tstack.push(value);\n\t\t\t},\n\t\t\tclear() {\n\t\t\t\tstack = [getDefaultSave(klona(defaultState))];\n\t\t\t},\n\t\t};\n\t};\n\n\tconst getLanguageWithoutParameters = () => {\n\t\treturn getLanguage(languages, defaultGetLanguage);\n\t}\n\n\t/**\n\t * 1) Novely rendered using the `initialData`, but you can't start new game or `load` an empty one - this is scary, imagine losing your progress\n\t * 2) Actual stored data is loaded, language and etc is changed\n\t */\n\tconst initialData: StorageData = {\n\t\tsaves: [],\n\t\tdata: klona(defaultData) as Data,\n\t\tmeta: [getLanguageWithoutParameters(), getTypewriterSpeed()],\n\t};\n\n\tconst $ = store(initialData);\n\n\tlet initialDataLoaded = false;\n\n\tconst onStorageDataChange = (value: StorageData) => {\n\t\tif (initialDataLoaded) storage.set(value);\n\t};\n\n\tconst throttledOnStorageDataChange = throttle(onStorageDataChange, throttleTimeout);\n\n\t$.subscribe(throttledOnStorageDataChange);\n\n\tconst getStoredData = () => {\n\t\tstorage.get().then((stored) => {\n\t\t\t/**\n\t\t\t * Migration is done only once (when game loads it's data), and then it saves the updated format\n\t\t\t */\n\t\t\tfor (const migration of migrations) {\n\t\t\t\t// @ts-expect-error Types does not match between versions\n\t\t\t\tstored = migration(stored);\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Default `localStorageStorage` returns empty array and engine set this up itself\n\t\t\t */\n\t\t\tstored.meta[1] ||= getTypewriterSpeed();\n\n\t\t\t/**\n\t\t\t * When we need to override it we do that, when not – only when language was not defined already\n\t\t\t */\n\t\t\tif (overrideLanguage) {\n\t\t\t\tstored.meta[0] = getLanguageWithoutParameters();\n\t\t\t} else {\n\t\t\t\tstored.meta[0] ||= getLanguageWithoutParameters();\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * When data is empty replace it with `defaultData`\n\t\t\t * It also might be empty (default to empty)\n\t\t\t */\n\t\t\tif (isEmpty(stored.data)) {\n\t\t\t\tstored.data = defaultData as Data;\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Now the next store updates will entail saving via storage.set\n\t\t\t */\n\t\t\tinitialDataLoaded = true;\n\n\t\t\t$.update(() => stored);\n\n\t\t\t/**\n\t\t\t * When initialScreen is game, then we will load it, but after the data is loaded and when assets are loaded if that is needed\n\t\t\t */\n\t\t\tif (initialScreen === 'game') assetsLoaded.promise.then(() => {\n\t\t\t\trestore();\n\t\t\t});\n\t\t});\n\t};\n\n\t/**\n\t * By default this is resolved immediately, but also can be delayed.\n\t * I.e. storage has not loaded yet\n\t */\n\tstorageDelay.then(getStoredData);\n\n\tconst initial = getDefaultSave(klona(defaultState));\n\tconst stack = createStack(initial);\n\n\tconst save = (override = false, type: Save[2][1] = override ? 'auto' : 'manual') => {\n\t\tif (!initialDataLoaded) return;\n\n\t\t/**\n\t\t * When autosaves diabled just return\n\t\t */\n\t\tif (!autosaves && type === 'auto') return;\n\n\t\tconst current = klona(stack.value);\n\n\t\t$.update((prev) => {\n\t\t\t/**\n\t\t\t * Find latest save that were created in current session, and check if it is latest in an array\n\t\t\t *\n\t\t\t * We check if save was created in current session and it is latest in array\n\t\t\t * When it is not then replacing it will break logical chain\n\t\t\t *\n\t\t\t * [auto save 1]\n\t\t\t * [manual save 1]\n\t\t\t * [auto save 2] <- should not replace first auto save\n\t\t\t */\n\t\t\tconst isLatest = findLastIndex(prev.saves, (value) => times.has(value[2][0])) === prev.saves.length - 1;\n\n\t\t\t/**\n\t\t\t * Update type and time information\n\t\t\t */\n\t\t\tcurrent[2][0] = intime(Date.now());\n\t\t\tcurrent[2][1] = type;\n\n\t\t\tif (!override || !isLatest) {\n\t\t\t\tprev.saves.push(current);\n\n\t\t\t\treturn prev;\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Get latest\n\t\t\t */\n\t\t\tconst latest = prev.saves.at(-1);\n\n\t\t\t/**\n\t\t\t * When that save is the same type, replace it\n\t\t\t */\n\t\t\tif (latest && latest[2][1] === type) {\n\t\t\t\tprev.saves[prev.saves.length - 1] = current;\n\t\t\t} else {\n\t\t\t\tprev.saves.push(current);\n\t\t\t}\n\n\t\t\treturn prev;\n\t\t});\n\t};\n\n\tconst newGame = () => {\n\t\tif (!initialDataLoaded) return;\n\n\t\tconst save = getDefaultSave(klona(defaultState));\n\n\t\t/**\n\t\t * Initial save is automatic, and should be ignored when autosaves is turned off\n\t\t */\n\t\tif (autosaves) {\n\t\t\t$.update((prev) => {\n\t\t\t\treturn prev.saves.push(save), prev;\n\t\t\t});\n\t\t}\n\n\t\trestore(save);\n\t};\n\n\t/**\n\t * Set's the save\n\t */\n\tconst set = (save: Save) => {\n\t\tstack.value = save;\n\n\t\treturn restore(save);\n\t};\n\n\tlet restoring = false;\n\tlet goingBack = false;\n\tlet interacted = 0;\n\n\t/**\n\t * Restore\n\t */\n\tconst restore = async (save?: Save) => {\n\t\tif (!initialDataLoaded) return;\n\n\t\tlet latest = save ? save : $.get().saves.at(-1);\n\n\t\t/**\n\t\t * When there is no game, then make a new game\n\t\t */\n\t\tif (!latest) {\n\t\t\t$.update(() => ({\n\t\t\t\tsaves: [initial],\n\t\t\t\tdata: klona(defaultData) as Data,\n\t\t\t\tmeta: [getLanguageWithoutParameters(), getTypewriterSpeed()],\n\t\t\t}));\n\n\t\t\tlatest = klona(initial);\n\t\t}\n\n\t\t(restoring = true), (stack.value = latest);\n\n\t\t/**\n\t\t * Текущий элемент в истории\n\t\t */\n\t\tlet current: any = story;\n\t\t/**\n\t\t * Текущий элемент `[null, int]`\n\t\t */\n\t\tlet index = 0;\n\n\t\t/**\n\t\t * Число элементов `[null, int]`\n\t\t */\n\t\tconst max = stack.value[0].reduce((acc, [type, val]) => {\n\t\t\tif (isNull(type) && isNumber(val)) return acc + 1;\n\n\t\t\treturn acc;\n\t\t}, 0);\n\n\t\tconst queue = [] as [any, any][];\n\t\tconst keep = new Set();\n\t\tconst characters = new Set();\n\n\t\tfor (const [type, val] of stack.value[0]) {\n\t\t\tif (type === null) {\n\t\t\t\tif (isString(val)) {\n\t\t\t\t\tcurrent = current[val];\n\t\t\t\t} else if (isNumber(val)) {\n\t\t\t\t\tindex++;\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Запустим все экшены которые идут в `[null, int]` от `0` до `int`\n\t\t\t\t\t * Почему-то потребовалось изменить `<` на `<=`, чтобы последний action попадал сюда\n\t\t\t\t\t */\n\t\t\t\t\tfor (let i = 0; i <= val; i++) {\n\t\t\t\t\t\tconst [action, ...meta] = current[i];\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * Add item to queue and action to keep\n\t\t\t\t\t\t */\n\t\t\t\t\t\tconst push = () => {\n\t\t\t\t\t\t\tkeep.add(action);\n\t\t\t\t\t\t\tqueue.push([action, meta]);\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * Do not remove characters that will be here anyways\n\t\t\t\t\t\t */\n\t\t\t\t\t\tif (action === 'showCharacter') characters.add(meta[0]);\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * Экшены, для закрытия которых пользователь должен с ними взаимодействовать\n\t\t\t\t\t\t * Также в эту группу входят экшены, которые не должны быть вызваны при восстановлении\n\t\t\t\t\t\t */\n\t\t\t\t\t\tif (SKIPPED_DURING_RESTORE.has(action) || isUserRequiredAction(action, meta)) {\n\t\t\t\t\t\t\tif (index === max && i === val) {\n\t\t\t\t\t\t\t\tpush();\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tpush();\n\t\t\t\t\t}\n\n\t\t\t\t\tcurrent = current[val];\n\t\t\t\t}\n\t\t\t} else if (type === 'choice') {\n\t\t\t\tcurrent = current[(val as number) + 1][1];\n\t\t\t} else if (type === 'condition') {\n\t\t\t\tcurrent = current[2][val];\n\t\t\t}\n\t\t}\n\n\t\tqueue.forEach((value, index) => {\n\t\t\t/**\n\t\t\t * Mutate the queue item\n\t\t\t */\n\t\t\tvalue.push(index);\n\t\t});\n\n\t\t/**\n\t\t * This is basically made for TypeScript.\n\t\t */\n\t\tconst indexedQueue = queue as unknown as [Exclude<ValidAction[0], ValidAction>, ValidAction[1], number][];\n\n\t\t/**\n\t\t * Run these exactly before the main loop.\n\t\t */\n\t\trenderer.ui.showScreen('game');\n\t\t/**\n\t\t * Provide the `keep` in there\n\t\t */\n\t\tmatch('clear', [keep, characters]);\n\n\t\t/**\n\t\t * Get the next actions array.\n\t\t */\n\t\tconst next = (i: number) => indexedQueue.slice(i + 1);\n\n\t\tfor await (const [action, meta, i] of indexedQueue) {\n\t\t\tif (action === 'function' || action === 'custom') {\n\t\t\t\t/**\n\t\t\t\t * When `callOnlyLatest` is `true`\n\t\t\t\t */\n\t\t\t\tif (action === 'custom' && (meta as GetActionParameters<'Custom'>)[0].callOnlyLatest) {\n\t\t\t\t\t/**\n\t\t\t\t\t * We'll calculate it is `latest` or not\n\t\t\t\t\t */\n\t\t\t\t\tconst notLatest = next(i).some(([_action, _meta]) => {\n\t\t\t\t\t\tif (!_meta || !meta) return false;\n\n\t\t\t\t\t\tconst c0 = _meta[0] as unknown as GetActionParameters<'Custom'>[0];\n\t\t\t\t\t\tconst c1 = meta[0] as unknown as GetActionParameters<'Custom'>[0];\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * Also check for `undefined`\n\t\t\t\t\t\t */\n\t\t\t\t\t\tconst isIdenticalID = c0.id && c1.id && c0.id === c1.id;\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * Equal by id or equal by `toString()`\n\t\t\t\t\t\t */\n\t\t\t\t\t\treturn isIdenticalID || str(c0) === str(c1);\n\t\t\t\t\t});\n\n\t\t\t\t\tif (notLatest) continue;\n\t\t\t\t}\n\n\t\t\t\t/**\n\t\t\t\t * Action can return Promise.\n\t\t\t\t */\n\t\t\t\tconst result = match(action, meta);\n\n\t\t\t\t/**\n\t\t\t\t * Should wait until it resolved\n\t\t\t\t */\n\t\t\t\tif (isPromise(result)) {\n\t\t\t\t\t/**\n\t\t\t\t\t * Await it!\n\t\t\t\t\t */\n\t\t\t\t\tawait result;\n\t\t\t\t}\n\t\t\t} else if (action === 'showCharacter') {\n\t\t\t\tconst skip = next(i).some(([_action, _meta]) => {\n\t\t\t\t\t/**\n\t\t\t\t\t * Проверка на возможный `undefined`\n\t\t\t\t\t */\n\t\t\t\t\tif (!_meta || !meta) return false;\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Будет ли персонаж скрыт в будущем\n\t\t\t\t\t * Нет смысла при загрузке сохранения загружать и отрисовывать персонажа, который будет скрыт\n\t\t\t\t\t */\n\t\t\t\t\tconst hidden = _action === 'hideCharacter' && _meta[0] === meta[0];\n\t\t\t\t\t/**\n\t\t\t\t\t * Не нужно запускать рендер персонажа, если после этого будет ещё один рендер этого персонажа\n\t\t\t\t\t * Таким образом избегаем ситуации, когда при загрузке вследствие гонки при загрузки изображений отрисовывается не последняя эмоция\n\t\t\t\t\t */\n\t\t\t\t\tconst notLatest = _action === action && _meta[0] === meta[0];\n\n\t\t\t\t\treturn hidden || notLatest;\n\t\t\t\t});\n\n\t\t\t\tif (skip) continue;\n\n\t\t\t\tmatch(action, meta);\n\t\t\t} else if (action === 'showBackground' || action === 'animateCharacter') {\n\t\t\t\t/**\n\t\t\t\t * Такая же оптимизация применяется к фонам и анимированию персонажей.\n\t\t\t\t * Если фон изменится, то нет смысла устанавливать текущий\n\t\t\t\t */\n\t\t\t\tconst notLatest = next(i).some(([_action]) => action === _action);\n\n\t\t\t\tif (notLatest) continue;\n\n\t\t\t\tmatch(action, meta);\n\t\t\t} else {\n\t\t\t\tmatch(action, meta);\n\t\t\t}\n\t\t}\n\n\t\t(restoring = goingBack = false), render();\n\t};\n\n\tconst refer = () => {\n\t\tlet current: any = story;\n\n\t\tfor (const [type, val] of stack.value[0]) {\n\t\t\tif (type === null) {\n\t\t\t\tcurrent = current[val];\n\t\t\t} else if (type === 'choice') {\n\t\t\t\tcurrent = current[(val as number) + 1][1];\n\t\t\t} else if (type === 'condition') {\n\t\t\t\tcurrent = current[2][val];\n\t\t\t}\n\t\t}\n\n\t\treturn current;\n\t};\n\n\t/**\n\t * @param force Force exit\n\t */\n\tconst exit = (force = false) => {\n\t\tif (interacted > 1 && !force && askBeforeExit) {\n\t\t\trenderer.ui.showExitPrompt();\n\t\t\treturn;\n\t\t}\n\n\t\tconst current = stack.value;\n\n\t\tstack.clear();\n\t\trenderer.ui.showScreen('mainmenu');\n\n\t\t/**\n\t\t * First two save elements and it's type\n\t\t */\n\t\tconst [time, type] = current[2];\n\n\t\tif (type === 'auto') {\n\t\t\t/**\n\t\t\t * Save belongs to the current session\n\t\t\t * And player did not interacted or did it once, so this is probably not-needed save\n\t\t\t */\n\t\t\tif (interacted <= 1 && times.has(time)) {\n\t\t\t\t$.update((prev) => {\n\t\t\t\t\tprev.saves = prev.saves.filter((save) => save !== current);\n\n\t\t\t\t\treturn prev;\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Reset interactive value\n\t\t */\n\t\tinteractivity(false);\n\t\t/**\n\t\t * Reset session times\n\t\t */\n\t\ttimes.clear();\n\t};\n\n\tconst back = () => {\n\t\treturn stack.back(), restore(stack.value);\n\t};\n\n\tconst renderer = createRenderer({\n\t\tcharacters,\n\t\tset,\n\t\trestore,\n\t\tsave,\n\t\tnewGame,\n\t\texit,\n\t\tback,\n\t\tstack,\n\t\tlanguages,\n\t\tt: t9n.i,\n\t\t$,\n\t});\n\n\tconst match = matchAction({\n\t\twait([time]) {\n\t\t\tif (!restoring) setTimeout(push, isFunction(time) ? time() : time);\n\t\t},\n\t\tshowBackground([background]) {\n\t\t\trenderer.background(background);\n\t\t\tpush();\n\t\t},\n\t\tplayMusic([source]) {\n\t\t\trenderer.music(source, 'music').play();\n\t\t\tpush();\n\t\t},\n\t\tstopMusic([source]) {\n\t\t\trenderer.music(source, 'music').stop();\n\t\t\tpush();\n\t\t},\n\t\tshowCharacter([character, emotion, className, style]) {\n\t\t\tconst handle = renderer.character(character);\n\n\t\t\thandle.append(className, style, restoring);\n\t\t\thandle.withEmotion(emotion)();\n\n\t\t\tpush();\n\t\t},\n\t\thideCharacter([character, className, style, duration]) {\n\t\t\trenderer.character(character).remove(className, style, duration)(push, restoring);\n\t\t},\n\t\tdialog([character, content, emotion]) {\n\t\t\t/**\n\t\t\t * Person name\n\t\t\t */\n\t\t\tconst name = (() => {\n\t\t\t\tconst c = character,\n\t\t\t\t\tcs = characters;\n\t\t\t\tconst lang = $.get().meta[0];\n\n\t\t\t\treturn c\n\t\t\t\t\t? c in cs\n\t\t\t\t\t\t? typeof cs[c].name === 'string'\n\t\t\t\t\t\t\t? (cs[c].name as string)\n\t\t\t\t\t\t\t: (cs[c].name as Record<string, string>)[lang]\n\t\t\t\t\t\t: c\n\t\t\t\t\t: '';\n\t\t\t})();\n\n\t\t\trenderer.dialog(unwrap(content), unwrap(name), character, emotion)(forward);\n\t\t},\n\t\tfunction([fn]) {\n\t\t\tconst result = fn(restoring, goingBack);\n\n\t\t\tif (!restoring) result ? result.then(push) : push();\n\n\t\t\treturn result;\n\t\t},\n\t\tchoice([question, ...choices]) {\n\t\t\tconst isWithoutQuestion = Array.isArray(question);\n\n\t\t\tif (isWithoutQuestion) {\n\t\t\t\t/**\n\t\t\t\t * Первый элемент может быть как строкой, так и элементов выбора\n\t\t\t\t */\n\t\t\t\tchoices.unshift(question as unknown as [Unwrappable, ValidAction[], () => boolean]);\n\t\t\t\t/**\n\t\t\t\t * Значит, текст не требуется\n\t\t\t\t */\n\t\t\t\tquestion = '';\n\t\t\t}\n\n\t\t\tconst unwrapped = choices.map(([content, action, visible]) => {\n\t\t\t\treturn [unwrap(content), action, visible] as [string, ValidAction[], () => boolean];\n\t\t\t});\n\n\t\t\trenderer.choices(\n\t\t\t\tunwrap(question),\n\t\t\t\tunwrapped,\n\t\t\t)((selected) => {\n\t\t\t\tenmemory();\n\n\t\t\t\t/**\n\t\t\t\t * If there is a question, then `index` should be shifted by `1`\n\t\t\t\t */\n\t\t\t\tconst offset = isWithoutQuestion ? 0 : 1;\n\n\t\t\t\tstack.value[0].push(['choice', selected + offset], [null, 0]);\n\t\t\t\trender();\n\t\t\t\tinteractivity(true);\n\t\t\t});\n\t\t},\n\t\tjump([scene]) {\n\t\t\t/**\n\t\t\t * `-1` index is used here because `clear` will run `next` that will increase index to `0`\n\t\t\t */\n\t\t\tstack.value[0] = [\n\t\t\t\t[null, scene],\n\t\t\t\t[null, -1],\n\t\t\t];\n\n\t\t\tmatch('clear', []);\n\t\t},\n\t\tclear([keep, characters]) {\n\t\t\t/**\n\t\t\t * Remove vibration\n\t\t\t */\n\t\t\tvibrate(0);\n\t\t\t/**\n\t\t\t * Call the actual `clear`\n\t\t\t */\n\t\t\trenderer.clear(goingBack, keep || EMPTY_SET, characters || EMPTY_SET)(push);\n\t\t},\n\t\tcondition([condition]) {\n\t\t\tconst value = condition();\n\n\t\t\tif (!restoring) stack.value[0].push(['condition', String(value)], [null, 0]), render();\n\t\t},\n\t\tend() {\n\t\t\t/**\n\t\t\t * Clear the Scene\n\t\t\t */\n\t\t\tmatch('clear', []);\n\t\t\t/**\n\t\t\t * Go to the main menu\n\t\t\t */\n\t\t\trenderer.ui.showScreen('mainmenu');\n\t\t\t/**\n\t\t\t * Reset interactive value\n\t\t\t */\n\t\t\tinteractivity(false);\n\t\t\t/**\n\t\t\t * Reset session times\n\t\t\t */\n\t\t\ttimes.clear();\n\t\t},\n\t\tinput([question, onInput, setup]) {\n\t\t\trenderer.input(unwrap(question), onInput, setup)(forward);\n\t\t},\n\t\tcustom([handler]) {\n\t\t\tconst result = renderer.custom(handler, goingBack, () => {\n\t\t\t\tif (!restoring && handler.requireUserAction) enmemory(), interactivity(true);\n\t\t\t\tif (!restoring) push();\n\t\t\t});\n\n\t\t\treturn result;\n\t\t},\n\t\tvibrate(pattern) {\n\t\t\tvibrate(pattern);\n\t\t\tpush();\n\t\t},\n\t\tnext() {\n\t\t\tpush();\n\t\t},\n\t\tanimateCharacter([character, timeout, ...classes]) {\n\t\t\tconst handler: CustomHandler = (get) => {\n\t\t\t\tconst { clear } = get('@@internal-animate-character', false);\n\t\t\t\tconst char = renderer.store.characters[character];\n\n\t\t\t\t/**\n\t\t\t\t * Character is not defined, maybe, `animateCharacter` was called before `showCharacter`\n\t\t\t\t */\n\t\t\t\tif (!char) return;\n\n\t\t\t\tconst target = char.canvas;\n\n\t\t\t\t/**\n\t\t\t\t * Character is not found\n\t\t\t\t */\n\t\t\t\tif (!target) return;\n\n\t\t\t\tconst classNames = classes.filter((className) => !target.classList.contains(className));\n\n\t\t\t\ttarget.classList.add(...classNames);\n\n\t\t\t\tconst timeoutId = setTimeout(() => {\n\t\t\t\t\ttarget.classList.remove(...classNames);\n\t\t\t\t}, timeout);\n\n\t\t\t\tclear(() => {\n\t\t\t\t\ttarget.classList.remove(...classNames);\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Clear timeout, because when you will game re-runs some callback might remove classes from character\n\t\t\t\t\t */\n\t\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\t});\n\t\t\t};\n\n\t\t\t/**\n\t\t\t * `callOnlyLatest` property will not have any effect, because `custom` is called directly\n\t\t\t */\n\t\t\tmatch('custom', [handler]);\n\t\t},\n\t\ttext(text) {\n\t\t\trenderer.text(text.map((content) => unwrap(content)).join(' '), forward);\n\t\t},\n\t\texit() {\n\t\t\tconst path = stack.value[0];\n\n\t\t\tlet exited = false;\n\n\t\t\tfor (let i = path.length - 1; i > 0; i--) {\n\t\t\t\tif (path[i][0] !== 'choice' && path[i][0] !== 'condition') continue;\n\n\t\t\t\texited = true;\n\t\t\t\tstack.value[0] = path.slice(0, i);\n\t\t\t\tnext();\n\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Run render only when exit was performed. This prevents infinite loop of `render` -> `undefined` -> `exit` -> `render`.\n\t\t\t */\n\t\t\tif (exited) render();\n\t\t},\n\t\tpreload([source]) {\n\t\t\tif (!PRELOADED_ASSETS.has(source) && !goingBack && !restoring) {\n\t\t\t\t/**\n\t\t\t\t * Make image load\n\t\t\t\t */\n\t\t\t\tPRELOADED_ASSETS.add(document.createElement('img').src = source);\n\t\t\t}\n\n\t\t\tpush();\n\t\t}\n\t});\n\n\tconst enmemory = () => {\n\t\tif (restoring) return;\n\n\t\tconst current = klona(stack.value);\n\n\t\tcurrent[2][1] = 'auto';\n\n\t\tstack.push(current);\n\n\t\tsave(true, 'auto');\n\t};\n\n\tconst next = () => {\n\t\tconst path = stack.value[0];\n\t\t/**\n\t\t * Последний элемент пути\n\t\t */\n\t\tconst last = path[path.length - 1]!;\n\n\t\t/**\n\t\t * Если он вида `[null, int]` - увеличивает `int`\n\t\t */\n\t\tif (isNull(last[0]) && isNumber(last[1])) {\n\t\t\tlast[1] = last[1] + 1;\n\t\t\treturn;\n\t\t}\n\n\t\t/**\n\t\t * Иначе добавляет новое `[null, int]`\n\t\t */\n\t\tpath.push([null, 0]);\n\t};\n\n\tconst render = () => {\n\t\tconst referred = refer();\n\n\t\tif (Array.isArray(referred)) {\n\t\t\tconst [action, ...props] = referred;\n\n\t\t\tmatch(action, props);\n\t\t} else {\n\t\t\tmatch('exit', []);\n\t\t}\n\t};\n\n\tconst push = () => {\n\t\tif (!restoring) next(), render();\n\t};\n\n\tconst forward = () => {\n\t\tenmemory();\n\t\tpush();\n\t\tinteractivity(true);\n\t};\n\n\tconst interactivity = (value = false) => {\n\t\tinteracted = value ? (interacted + 1) : 0;\n\t};\n\n\t/**\n\t * Unwraps translatable content to string\n\t *\n\t * @example ```\n\t * unwrap(t('Hello'));\n\t * unwrap({ en: 'Hello', ru: 'Привет' });\n\t * unwrap({ en: () => data().ad_viewed ? 'Diamond Hat' : 'Diamond Hat (Watch Adv)' })\n\t * unwrap('Hello, {{name}}');\n\t * ```\n\t */\n\tconst unwrap = (content: Unwrappable, global = false) => {\n\t\tconst {\n\t\t\tdata,\n\t\t\tmeta: [lang],\n\t\t} = $.get();\n\n\t\tconst obj = global ? data : state();\n\t\tconst cnt = isFunction(content) ? content(lang, obj) : typeof content === 'string' ? content : content[lang];\n\n\t\tconst str = isFunction(cnt) ? cnt() : cnt;\n\n\t\treturn replaceT9N(str, obj);\n\t};\n\n\tfunction data(value: DeepPartial<DataScheme> | ((prev: DataScheme) => DataScheme)): void;\n\tfunction data(): DataScheme;\n\tfunction data(value?: DeepPartial<DataScheme> | ((prev: DataScheme) => DataScheme)): DataScheme | void {\n\t\tif (!value) return $.get().data as DataScheme | void;\n\n\t\tconst prev = $.get().data;\n\t\tconst val = isFunction(value) ? value(prev as DataScheme) : deepmerge([prev, value]);\n\n\t\t$.update((prev) => {\n\t\t\tprev.data = val;\n\n\t\t\treturn prev;\n\t\t});\n\t}\n\n\treturn {\n\t\t/**\n\t\t * Function to set story\n\t\t */\n\t\twithStory,\n\t\t/**\n\t\t * Function to get actions\n\t\t */\n\t\taction,\n\t\t/**\n\t\t * State that belongs to games\n\t\t */\n\t\tstate,\n\t\t/**\n\t\t * Unlike `state`, stored at global scope instead and shared between games\n\t\t */\n\t\tdata,\n\t\t/**\n\t\t * Unwraps translatable content to a string value\n\t\t */\n\t\tunwrap(content: Exclude<Unwrappable, Record<string, string>> | Record<Languages, string>) {\n\t\t\treturn unwrap(content, true);\n\t\t},\n\t\t/**\n\t\t * Function that is used for translation\n\t\t */\n\t\tt: t9n.t as Inter['t'],\n\t};\n};\n\nexport { novely };\n","export function klona(val) {\n\tvar k, out, tmp;\n\n\tif (Array.isArray(val)) {\n\t\tout = Array(k=val.length);\n\t\twhile (k--) out[k] = (tmp=val[k]) && typeof tmp === 'object' ? klona(tmp) : tmp;\n\t\treturn out;\n\t}\n\n\tif (Object.prototype.toString.call(val) === '[object Object]') {\n\t\tout = {}; // null\n\t\tfor (k in val) {\n\t\t\tif (k === '__proto__') {\n\t\t\t\tObject.defineProperty(out, k, {\n\t\t\t\t\tvalue: klona(val[k]),\n\t\t\t\t\tconfigurable: true,\n\t\t\t\t\tenumerable: true,\n\t\t\t\t\twritable: true,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tout[k] = (tmp=val[k]) && typeof tmp === 'object' ? klona(tmp) : tmp;\n\t\t\t}\n\t\t}\n\t\treturn out;\n\t}\n\n\treturn val;\n}\n","const SKIPPED_DURING_RESTORE = new Set(['dialog', 'choice', 'input', 'vibrate', 'text'] as const);\n\nconst EMPTY_SET = new Set<any>();\n\nexport { SKIPPED_DURING_RESTORE, EMPTY_SET };\n","const split = (input: string, delimeters: string[]) => {\n\tconst output: (string | undefined)[] = [];\n\n\tfor (const delimeter of delimeters) {\n\t\tif (!input) break;\n\n\t\tconst [start, end] = input.split(delimeter, 2);\n\n\t\toutput.push(start);\n\t\tinput = end;\n\t}\n\n\toutput.push(input);\n\n\treturn output;\n};\n\nexport { split };\n","import type { BaseTranslationStrings } from './translations';\nimport { split } from './lib';\n\ntype PluralType = Intl.LDMLPluralRule;\ntype FunctionalSetupT9N = <\n\tLanguageKey extends string,\n\tPluralKey extends string,\n\tStringKey extends string,\n\tActions extends string,\n>(parameters: {\n\t[Lang in LanguageKey]: {\n\t\tpluralization: {\n\t\t\t[Plural in PluralKey]: Partial<Record<PluralType, string>>;\n\t\t};\n\t\tinternal: { [Key in BaseTranslationStrings]: string };\n\t\tstrings: { [Str in StringKey]: string };\n\t\tactions?: { [Action in Actions]?: (value: string) => string };\n\t};\n}) => T9N<LanguageKey, StringKey>;\ntype SetupT9N<LanguageKey extends string> = <\n\tPluralKey extends string,\n\tStringKey extends string,\n\tActions extends string,\n>(parameters: {\n\t[Lang in LanguageKey]: {\n\t\tpluralization: {\n\t\t\t[Plural in PluralKey]: Partial<Record<PluralType, string>>;\n\t\t};\n\t\tinternal: { [Key in BaseTranslationStrings]: string };\n\t\tstrings: { [Str in StringKey]: string };\n\t\tactions?: { [Action in Actions]?: (value: string) => string };\n\t};\n}) => T9N<LanguageKey, StringKey>;\n\ntype T9N<LanguageKey extends string, StringKey extends string> = {\n\tt(\n\t\tkey: StringKey | Record<LanguageKey, AllowedContent>,\n\t): (lang: LanguageKey | (string & {}), obj: Record<string, unknown>) => string;\n\ti(key: StringKey, lang: LanguageKey | (string & {})): string;\n};\n\nconst RGX = /{{(.*?)}}/g;\n\ntype AllowedContent = string | (() => string | string[]) | string[] | (string | (() => string | string[]))[];\n\n/**\n * Unwraps any allowed content into string\n * @param c Content\n */\nconst unwrap = (c: AllowedContent): string => {\n\tif (Array.isArray(c)) {\n\t\treturn c.map((item) => unwrap(item)).join('<br>');\n\t}\n\n\tif (typeof c === 'function') {\n\t\treturn unwrap(c());\n\t}\n\n\treturn c;\n};\n\nconst replace = (\n\tstr: AllowedContent,\n\tobj: Record<string, unknown>,\n\tpluralization?: Record<string, Record<string, PluralType>>,\n\tactions?: Partial<Record<string, (str: string) => string>>,\n\tpr?: Intl.PluralRules,\n) => {\n\treturn unwrap(str).replace(RGX, (x: any, key: string, y: any) => {\n\t\tx = 0;\n\t\ty = obj;\n\n\t\tconst [pathstr, plural, action] = split(key.trim(), ['@', '%']);\n\n\t\tlet path = pathstr!.split('.');\n\n\t\twhile (y && x < path.length) y = y[path[x++]];\n\n\t\tif (plural && pluralization && y && pr) {\n\t\t\ty = pluralization[plural][pr.select(y)];\n\t\t}\n\n\t\tconst actionHandler = actions && action && actions[action];\n\n\t\tif (actionHandler) y = actionHandler(y);\n\n\t\treturn y != null ? y : '';\n\t});\n};\n\nconst createT9N: FunctionalSetupT9N = (parameters) => {\n\tlet locale: string | undefined;\n\tlet pr: Intl.PluralRules | undefined;\n\n\treturn {\n\t\tt(key) {\n\t\t\treturn (lang, obj) => {\n\t\t\t\t/**\n\t\t\t\t * At first run `locale` and `pr` are not defined.\n\t\t\t\t * When `locale` changes, `pr` should be updated`\n\t\t\t\t */\n\t\t\t\tif (!locale || !pr || lang != locale) {\n\t\t\t\t\tpr = new Intl.PluralRules((locale = lang));\n\t\t\t\t}\n\n\t\t\t\t// @ts-ignore\n\t\t\t\tconst str: string | string[] = typeof key === 'object' ? key[lang] : parameters[lang]['strings'][key];\n\n\t\t\t\tif (!str) return '';\n\n\t\t\t\t// @ts-ignore `(string & {})` cannot be used to index type `LanguageKey`.\n\t\t\t\treturn replace(str, obj, parameters[lang]['pluralization'], parameters[lang]['actions'], pr);\n\t\t\t};\n\t\t},\n\t\ti(key, lang) {\n\t\t\t// @ts-ignore `(string & {})` cannot be used to index type `LanguageKey`.\n\t\t\treturn parameters[lang]['internal'][key] as string;\n\t\t},\n\t};\n};\n\nexport { createT9N, replace };\nexport type { SetupT9N, T9N, AllowedContent, FunctionalSetupT9N };\n","const RU = {\n\tNewGame: 'Новая игра',\n\tHomeScreen: 'Главный экран',\n\tToTheGame: 'К игре',\n\tLanguage: 'Язык',\n\tNoSaves: 'Сохранений нет',\n\tLoadSave: 'Загрузить',\n\tSaves: 'Сохранения',\n\tSettings: 'Настройки',\n\tSumbit: 'Подтвердить',\n\tGoBack: 'Назад',\n\tDoSave: 'Сохранение',\n\tAuto: 'Авто',\n\tStop: 'Стоп',\n\tExit: 'Выход',\n\tAutomatic: 'Автоматическое',\n\tManual: 'Ручное',\n\tRemove: 'Удалить',\n\tLoadASaveFrom: 'Загрузить сохранение от',\n\tDeleteASaveFrom: 'Удалить сохранение от',\n\tTextSpeed: 'Скорость Текста',\n\tTextSpeedSlow: 'Медленная',\n\tTextSpeedMedium: 'Средняя',\n\tTextSpeedFast: 'Быстрая',\n\tTextSpeedAuto: 'Автоматическая',\n\tCompleteText: 'Завершить текст',\n\tGoForward: 'Перейти вперёд',\n\tExitDialogWarning: 'Вы уверены, что хотите выйти? Прогресс будет сохранён.',\n\tExitDialogExit: 'Выйти',\n\tExitDialogBack: 'Вернуться в игру',\n};\n\ntype BaseTranslationStrings = keyof typeof RU;\n\nconst EN: Record<BaseTranslationStrings, string> = {\n\tNewGame: 'New Game',\n\tHomeScreen: 'Home Screen',\n\tToTheGame: 'To the Game',\n\tLanguage: 'Language',\n\tNoSaves: 'No saves',\n\tLoadSave: 'Load',\n\tSaves: 'Saves',\n\tSettings: 'Settings',\n\tSumbit: 'Submit',\n\tGoBack: 'Go back',\n\tDoSave: 'Save',\n\tAuto: 'Auto',\n\tStop: 'Stop',\n\tExit: 'Exit',\n\tAutomatic: 'Automatic',\n\tManual: 'Manual',\n\tRemove: 'Remove',\n\tLoadASaveFrom: 'Load a save from',\n\tDeleteASaveFrom: 'Delete a save from',\n\tTextSpeed: 'Text Speed',\n\tTextSpeedSlow: 'Slow',\n\tTextSpeedMedium: 'Medium',\n\tTextSpeedFast: 'Fast',\n\tTextSpeedAuto: 'Auto',\n\tCompleteText: 'Complete text',\n\tGoForward: 'Go forward',\n\tExitDialogWarning: 'Are you sure you want to exit? Progress will be saved.',\n\tExitDialogExit: 'Exit',\n\tExitDialogBack: 'Return to game',\n};\n\n/**\n * Translated automatically\n */\nconst KK: Record<BaseTranslationStrings, string> = {\n\tNewGame: 'Жаңа ойын',\n\tHomeScreen: 'Негізгі экран',\n\tToTheGame: 'Ойынға',\n\tLanguage: 'Тіл',\n\tNoSaves: 'Сақтау жоқ',\n\tLoadSave: 'Жүктеу',\n\tSaves: 'Сақтау',\n\tSettings: 'Параметрлер',\n\tSumbit: 'Растау',\n\tGoBack: 'Артқа',\n\tDoSave: 'Сақтау',\n\tAuto: 'Авто',\n\tStop: 'Тоқта',\n\tExit: 'Шығу',\n\tAutomatic: 'Автоматты',\n\tManual: 'Қолмен',\n\tRemove: 'Жою',\n\tLoadASaveFrom: 'Сақтауды жүктеу',\n\tDeleteASaveFrom: 'Сақтауды жою',\n\tTextSpeed: 'Мәтін Жылдамдығы',\n\tTextSpeedSlow: 'Баяу',\n\tTextSpeedMedium: 'Орташа',\n\tTextSpeedFast: 'Жылдам',\n\tTextSpeedAuto: 'Автоматты',\n\tCompleteText: 'Мәтінді аяқтау',\n\tGoForward: 'Алға жылжу',\n\tExitDialogWarning: 'Сіз шыққыңыз келетініне сенімдісіз бе? Прогресс сақталады',\n\tExitDialogExit: 'Шығу',\n\tExitDialogBack: 'Ойынға оралу'\n};\n\n/**\n * Translated automatically\n */\nconst JP: Record<BaseTranslationStrings, string> = {\n\tNewGame: '「新しいゲーム」',\n\tHomeScreen: 'ホーム画面',\n\tToTheGame: '「ゲームに戻る」',\n\tLanguage: '言語',\n\tNoSaves: 'ノーセーブ',\n\tLoadSave: 'ダウンロード',\n\tSaves: '保存',\n\tSettings: '設定',\n\tSumbit: '確認',\n\tGoBack: '「戻る」',\n\tDoSave: '保存',\n\tAuto: 'オート',\n\tStop: '止まれ',\n\tExit: '出口',\n\tAutomatic: '自動',\n\tManual: 'マニュアル',\n\tRemove: '削除',\n\tLoadASaveFrom: 'ロードセーブから',\n\tDeleteASaveFrom: 'から保存を削除',\n\tTextSpeed: 'テキストスピード',\n\tTextSpeedSlow: '「遅い」',\n\tTextSpeedMedium: 'ミディアム',\n\tTextSpeedFast: '「速い」',\n\tTextSpeedAuto: '自動',\n\tCompleteText: 'テキストを完成させる',\n\tGoForward: '先に行く',\n\tExitDialogWarning: '本当に終了しますか?進行状況は保存されます',\n\tExitDialogExit: '終了',\n\tExitDialogBack: 'ゲームに戻る',\n};\n\nexport { RU, EN, KK, JP };\nexport type { BaseTranslationStrings };\n","import type { StorageData } from './types';\n\ninterface LocalStorageStorageSettings {\n\tkey: string;\n}\n\ninterface Storage {\n\tget: () => Promise<StorageData>;\n\tset: (data: StorageData) => Promise<void>;\n}\n\nconst localStorageStorage = (options: LocalStorageStorageSettings): Storage => {\n\treturn {\n\t\tasync get() {\n\t\t\tconst value = localStorage.getItem(options.key);\n\n\t\t\treturn value ? JSON.parse(value) : { saves: [], data: {}, meta: [] };\n\t\t},\n\t\tasync set(data) {\n\t\t\tlocalStorage.setItem(options.key, JSON.stringify(data));\n\t\t},\n\t};\n};\n\nexport type { Storage };\nexport { localStorageStorage };\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAEA,UAAI,oBAAoB,SAASA,mBAAkB,OAAO;AACzD,eAAO,gBAAgB,KAAK,KACxB,CAAC,UAAU,KAAK;AAAA,MACrB;AAEA,eAAS,gBAAgB,OAAO;AAC/B,eAAO,CAAC,CAAC,SAAS,OAAO,UAAU;AAAA,MACpC;AAEA,eAAS,UAAU,OAAO;AACzB,YAAI,cAAc,OAAO,UAAU,SAAS,KAAK,KAAK;AAEtD,eAAO,gBAAgB,qBACnB,gBAAgB,mBAChB,eAAe,KAAK;AAAA,MACzB;AAGA,UAAI,eAAe,OAAO,WAAW,cAAc,OAAO;AAC1D,UAAI,qBAAqB,eAAe,OAAO,IAAI,eAAe,IAAI;AAEtE,eAAS,eAAe,OAAO;AAC9B,eAAO,MAAM,aAAa;AAAA,MAC3B;AAEA,eAAS,YAAY,KAAK;AACzB,eAAO,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC;AAAA,MACnC;AAEA,eAAS,8BAA8B,OAAO,SAAS;AACtD,eAAQ,QAAQ,UAAU,SAAS,QAAQ,kBAAkB,KAAK,IAC/DC,WAAU,YAAY,KAAK,GAAG,OAAO,OAAO,IAC5C;AAAA,MACJ;AAEA,eAAS,kBAAkB,QAAQ,QAAQ,SAAS;AACnD,eAAO,OAAO,OAAO,MAAM,EAAE,IAAI,SAAS,SAAS;AAClD,iBAAO,8BAA8B,SAAS,OAAO;AAAA,QACtD,CAAC;AAAA,MACF;AAEA,eAAS,iBAAiB,KAAK,SAAS;AACvC,YAAI,CAAC,QAAQ,aAAa;AACzB,iBAAOA;AAAA,QACR;AACA,YAAI,cAAc,QAAQ,YAAY,GAAG;AACzC,eAAO,OAAO,gBAAgB,aAAa,cAAcA;AAAA,MAC1D;AAEA,eAAS,gCAAgC,QAAQ;AAChD,eAAO,OAAO,wBACX,OAAO,sBAAsB,MAAM,EAAE,OAAO,SAAS,QAAQ;AAC9D,iBAAO,OAAO,qBAAqB,KAAK,QAAQ,MAAM;AAAA,QACvD,CAAC,IACC,CAAC;AAAA,MACL;AAEA,eAAS,QAAQ,QAAQ;AACxB,eAAO,OAAO,KAAK,MAAM,EAAE,OAAO,gCAAgC,MAAM,CAAC;AAAA,MAC1E;AAEA,eAAS,mBAAmB,QAAQ,UAAU;AAC7C,YAAI;AACH,iBAAO,YAAY;AAAA,QACpB,SAAQ,GAAN;AACD,iBAAO;AAAA,QACR;AAAA,MACD;AAGA,eAAS,iBAAiB,QAAQ,KAAK;AACtC,eAAO,mBAAmB,QAAQ,GAAG,KACjC,EAAE,OAAO,eAAe,KAAK,QAAQ,GAAG,KACvC,OAAO,qBAAqB,KAAK,QAAQ,GAAG;AAAA,MAClD;AAEA,eAAS,YAAY,QAAQ,QAAQ,SAAS;AAC7C,YAAI,cAAc,CAAC;AACnB,YAAI,QAAQ,kBAAkB,MAAM,GAAG;AACtC,kBAAQ,MAAM,EAAE,QAAQ,SAAS,KAAK;AACrC,wBAAY,GAAG,IAAI,8BAA8B,OAAO,GAAG,GAAG,OAAO;AAAA,UACtE,CAAC;AAAA,QACF;AACA,gBAAQ,MAAM,EAAE,QAAQ,SAAS,KAAK;AACrC,cAAI,iBAAiB,QAAQ,GAAG,GAAG;AAClC;AAAA,UACD;AAEA,cAAI,mBAAmB,QAAQ,GAAG,KAAK,QAAQ,kBAAkB,OAAO,GAAG,CAAC,GAAG;AAC9E,wBAAY,GAAG,IAAI,iBAAiB,KAAK,OAAO,EAAE,OAAO,GAAG,GAAG,OAAO,GAAG,GAAG,OAAO;AAAA,UACpF,OAAO;AACN,wBAAY,GAAG,IAAI,8BAA8B,OAAO,GAAG,GAAG,OAAO;AAAA,UACtE;AAAA,QACD,CAAC;AACD,eAAO;AAAA,MACR;AAEA,eAASA,WAAU,QAAQ,QAAQ,SAAS;AAC3C,kBAAU,WAAW,CAAC;AACtB,gBAAQ,aAAa,QAAQ,cAAc;AAC3C,gBAAQ,oBAAoB,QAAQ,qBAAqB;AAGzD,gBAAQ,gCAAgC;AAExC,YAAI,gBAAgB,MAAM,QAAQ,MAAM;AACxC,YAAI,gBAAgB,MAAM,QAAQ,MAAM;AACxC,YAAI,4BAA4B,kBAAkB;AAElD,YAAI,CAAC,2BAA2B;AAC/B,iBAAO,8BAA8B,QAAQ,OAAO;AAAA,QACrD,WAAW,eAAe;AACzB,iBAAO,QAAQ,WAAW,QAAQ,QAAQ,OAAO;AAAA,QAClD,OAAO;AACN,iBAAO,YAAY,QAAQ,QAAQ,OAAO;AAAA,QAC3C;AAAA,MACD;AAEA,MAAAA,WAAU,MAAM,SAAS,aAAa,OAAO,SAAS;AACrD,YAAI,CAAC,MAAM,QAAQ,KAAK,GAAG;AAC1B,gBAAM,IAAI,MAAM,mCAAmC;AAAA,QACpD;AAEA,eAAO,MAAM,OAAO,SAAS,MAAM,MAAM;AACxC,iBAAOA,WAAU,MAAM,MAAM,OAAO;AAAA,QACrC,GAAG,CAAC,CAAC;AAAA,MACN;AAEA,UAAI,cAAcA;AAElB,aAAO,UAAU;AAAA;AAAA;;;ACpIjB;AAAA;AAAA;AAAA;AAAA;;;ACcA,MAAM,cAAc,CAAmC,WAAc;AACpE,WAAO,CAAC,QAA8B,UAAe;AACpD,aAAO,OAAO,MAAM,EAAE,KAAK;AAAA,IAC5B;AAAA,EACD;AAEA,MAAM,WAAW,CAAC,QAAgC;AACjD,WAAO,OAAO,QAAQ;AAAA,EACvB;AAEA,MAAM,SAAS,CAAC,QAA8B;AAC7C,WAAO,QAAQ;AAAA,EAChB;AAEA,MAAM,WAAW,CAAC,QAAgC;AACjD,WAAO,OAAO,QAAQ;AAAA,EACvB;AAEA,MAAM,aAAa,CAAC,QAAuD;AAC1E,WAAO,OAAO,QAAQ;AAAA,EACvB;AAEA,MAAM,YAAY,CAAC,QAAsC;AACxD,WAAO,QAAQ,GAAG,MAAM,OAAO,QAAQ,YAAY,WAAW,GAAG,MAAM,WAAY,IAAY,IAAI;AAAA,EACpG;AAEA,MAAM,UAAU,CAAC,QAA4B;AAC5C,WAAO,OAAO,QAAQ,YAAY,CAAC,OAAO,GAAG,KAAK,OAAO,KAAK,GAAG,EAAE,WAAW;AAAA,EAC/E;AAEA,MAAM,aAAa,CAACC,SAAgB;AACnC,UAAM,aAAa,OAAO,UAAU,WAAW,KAAKA,IAAG;AAEvD,WAAO,WAAW,MAAM,KAAK,WAAW,GAAG,KAAK,WAAW,GAAG,KAAK,WAAW,MAAM;AAAA,EACrF;AAEA,MAAM,MAAM,CAAC,UAAmB;AAC/B,WAAO,OAAO,KAAK;AAAA,EACpB;AAEA,MAAM,uBAAuB,CAC5B,QACA,SACI;AACJ,WAAO,WAAW,YAAY,KAAK,CAAC,KAAM,KAAK,CAAC,EAA+B;AAAA,EAChF;AAEA,MAAM,qBAAqB,MAAuB;AACjD,WAAO;AAAA,EACR;AAEA,MAAM,cAAc,CAAC,WAAqB,MAAW;AACpD,QAAI,EAAE,SAAS,IAAI;AAEnB,QAAI,UAAU,SAAS,QAAQ,GAAG;AACjC,aAAO;AAAA,IACR,WAAW,UAAU,SAAU,WAAW,SAAS,UAAU,GAAG,CAAC,CAAE,GAAG;AACrE,aAAO;AAAA,IACR,WAAY,WAAW,UAAU,KAAK,CAAC,UAAU,UAAU,UAAU,SAAS,KAAK,CAAC,GAAK;AACxF,aAAO;AAAA,IACR;AAKA,WAAO,UAAU,CAAC;AAAA,EACnB;AAMA,MAAM,WAAW,CAAqC,IAAQ,OAAe;AAC5E,QAAI,YAAY,OACf,WACA;AAED,aAAS,UAAmB;AAC3B,UAAI,WAAW;AACd,oBAAY;AACZ,oBAAY;AACZ;AAAA,MACD;AAEA,SAAG,MAAM,MAAM,SAA6B;AAE5C,kBAAY;AAEZ,iBAAW,WAAY;AACtB,oBAAY;AAEZ,YAAI,WAAW;AACd,kBAAQ,MAAM,WAAW,SAAS;AAClC,sBAAY,YAAY;AAAA,QACzB;AAAA,MACD,GAAG,EAAE;AAAA,IACN;AAEA,WAAO;AAAA,EACR;AAEA,MAAM,UAAU,CAAC,YAA4B;AAC5C,QAAI;AACH,UAAI,aAAa,WAAW;AAC3B,kBAAU,QAAQ,OAAO;AAAA,MAC1B;AAAA,IACD,QAAE;AAAA,IAAO;AAAA,EACV;AAEA,MAAM,gBAAgB,CAAI,OAAY,OAA6B;AAClE,aAAS,IAAI,MAAM,SAAS,GAAG,IAAI,GAAG,KAAK;AAC1C,UAAI,GAAG,MAAM,CAAC,CAAC,GAAG;AACjB,eAAO;AAAA,MACR;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AAEA,MAAM,wBAAwB,CAAC,WAAwB;AACtD,WAAO,QAAQ,WAAW,MAAM,KAAK,MAAM,EAAE,IAAI,SAAO;AACvD,YAAM,MAAM,SAAS,cAAc,KAAK;AAExC,UAAI,MAAM;AAEV,aAAO,IAAI,QAAiB,CAAC,SAAS,WAAW;AAIhD,YAAI,IAAI,YAAY,IAAI,kBAAkB,GAAG;AAC5C,kBAAQ,MAAM;AAAA,QACf;AAEA,YAAI,iBAAiB,QAAQ,OAAO;AACpC,YAAI,iBAAiB,SAAS,MAAM;AACpC,YAAI,iBAAiB,SAAS,MAAM;AAAA,MACrC,CAAC;AAAA,IACF,CAAC,CAAC;AAAA,EACH;AAEA,MAAM,wBAAwB,MAAgC;AAC7D,QAAI,SAA+C;AAEnD,UAAM,UAAU,IAAI,QAAW,CAAC,KAAK,QAAQ;AAC5C,gBAAU;AAAK,eAAS;AAAA,IACzB,CAAC;AAED,WAAO,EAAE,SAAS,QAAQ,QAAQ;AAAA,EACnC;;;AClKA,MAAM,mBAAmB,oBAAI,IAAY;;;ACMzC,MAAM,QAAQ,CAAI,SAAY,cAAc,oBAAI,IAAwB,MAAiB;AACxF,UAAM,YAAY,CAAC,OAA2B;AAC7C,kBAAY,IAAI,EAAE,GAAG,GAAG,OAAO;AAE/B,aAAO,MAAM;AACZ,oBAAY,OAAO,EAAE;AAAA,MACtB;AAAA,IACD;AAEA,UAAM,OAAO,CAAC,UAAa;AAC1B,kBAAY,QAAQ,CAAC,OAAO,GAAG,KAAK,CAAC;AAAA,IACtC;AAEA,UAAM,SAAS,CAAC,OAAuB;AACtC,WAAM,UAAU,GAAG,OAAO,CAAE;AAAA,IAC7B;AAEA,UAAM,MAAM,MAAM;AACjB,aAAO;AAAA,IACR;AAEA,WAAO,EAAE,WAAW,QAAQ,IAAI;AAAA,EACjC;;;ACMA,yBAAiC;;;AClC1B,WAAS,MAAM,KAAK;AAC1B,QAAI,GAAG,KAAK;AAEZ,QAAI,MAAM,QAAQ,GAAG,GAAG;AACvB,YAAM,MAAM,IAAE,IAAI,MAAM;AACxB,aAAO;AAAK,YAAI,CAAC,KAAK,MAAI,IAAI,CAAC,MAAM,OAAO,QAAQ,WAAW,MAAM,GAAG,IAAI;AAC5E,aAAO;AAAA,IACR;AAEA,QAAI,OAAO,UAAU,SAAS,KAAK,GAAG,MAAM,mBAAmB;AAC9D,YAAM,CAAC;AACP,WAAK,KAAK,KAAK;AACd,YAAI,MAAM,aAAa;AACtB,iBAAO,eAAe,KAAK,GAAG;AAAA,YAC7B,OAAO,MAAM,IAAI,CAAC,CAAC;AAAA,YACnB,cAAc;AAAA,YACd,YAAY;AAAA,YACZ,UAAU;AAAA,UACX,CAAC;AAAA,QACF,OAAO;AACN,cAAI,CAAC,KAAK,MAAI,IAAI,CAAC,MAAM,OAAO,QAAQ,WAAW,MAAM,GAAG,IAAI;AAAA,QACjE;AAAA,MACD;AACA,aAAO;AAAA,IACR;AAEA,WAAO;AAAA,EACR;;;AC3BA,MAAM,yBAAyB,oBAAI,IAAI,CAAC,UAAU,UAAU,SAAS,WAAW,MAAM,CAAU;AAEhG,MAAM,YAAY,oBAAI,IAAS;;;ACF/B,MAAMC,IAAQ,CAACC,GAAeC,MAAyB;AACtD,QAAMC,IAAiC,CAAC;AAExC,aAAWC,KAAaF,GAAY;AACnC,UAAI,CAACD;AAAO;AAEZ,UAAM,CAACI,GAAOC,CAAG,IAAIL,EAAM,MAAMG,GAAW,CAAC;AAE7CD,QAAO,KAAKE,CAAK,GACjBJ,IAAQK;IACT;AAEA,WAAAH,EAAO,KAAKF,CAAK,GAEVE;EACR;AC0BA,MAAMI,IAAM;AAAZ,MAQMC,IAAUC,OACX,MAAM,QAAQA,CAAC,IACXA,EAAE,IAAKC,OAASF,EAAOE,CAAI,CAAC,EAAE,KAAK,MAAM,IAG7C,OAAOD,KAAM,aACTD,EAAOC,EAAE,CAAC,IAGXA;AAjBR,MAoBME,IAAU,CACfC,GACAC,GACAC,GACAC,GACAC,MAEOR,EAAOI,CAAG,EAAE,QAAQL,GAAK,CAACU,GAAQC,GAAaC,MAAW;AAChEF,QAAI,GACJE,IAAIN;AAEJ,QAAM,CAACO,GAASC,GAAQC,CAAM,IAAItB,EAAMkB,EAAI,KAAK,GAAG,CAAC,KAAK,GAAG,CAAC,GAE1DK,IAAOH,EAAS,MAAM,GAAG;AAE7B,WAAOD,KAAKF,IAAIM,EAAK;AAAQJ,UAAIA,EAAEI,EAAKN,GAAG,CAAC;AAExCI,SAAUP,KAAiBK,KAAKH,MACnCG,IAAIL,EAAcO,CAAM,EAAEL,EAAG,OAAOG,CAAC,CAAC;AAGvC,QAAMK,IAAgBT,KAAWO,KAAUP,EAAQO,CAAM;AAEzD,WAAIE,MAAeL,IAAIK,EAAcL,CAAC,IAE/BA,KAAgB;EACxB,CAAC;;;AJsCF,MAAM,SAAS,CAMb;AAAA,IACD;AAAA,IACA;AAAA,IACA,eAAe,QAAQ,QAAQ;AAAA,IAC/B,UAAU;AAAA,IACV,gBAAgB;AAAA,IAChB;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,aAAa,CAAC;AAAA,IACd,kBAAkB;AAAA,IAClB,aAAAM,eAAc;AAAA,IACd,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,EACjB,MAAyE;AACxE,QAAI;AACJ,QAAI,QAAQ,oBAAI,IAAY;AAE5B,UAAM,oBAAoB,oBAAI,IAAY;AAC1C,UAAM,eAAe,sBAAsB;AAK3C,oBAAgB,CAAC;AACjB,qBAAiB,CAAC;AAKlB,UAAM,SAAS,CAAC,UAAkB;AACjC,aAAO,MAAM,IAAI,KAAK,GAAG;AAAA,IAC1B;AAEA,UAAM,YAAY,OAAO,MAAa;AAIrC,cAAQ,OAAO;AAAA,QACd,OAAO,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM;AACxC,gBAAM,OAAO,CAAC,SAAyD;AACtE,mBAAO,KAAK,QAAQ,CAACC,UAAS;AAC7B,oBAAM,OAAOA,MAAK,CAAC;AAKnB,kBAAI,MAAM,QAAQ,IAAI;AAAG,uBAAO,KAAKA,KAAqB;AAE1D,qBAAO,CAACA,KAAmB;AAAA,YAC5B,CAAC;AAAA,UACF;AAEA,iBAAO,CAAC,MAAM,KAAK,KAAK,CAAC;AAAA,QAC1B,CAAC;AAAA,MACF;AAEA,UAAI,kBAAkB,cAAc,kBAAkB,OAAO,GAAG;AAC/D,iBAAS,GAAG,WAAW,SAAS;AAEhC,cAAM,sBAAsB,iBAAiB;AAAA,MAC9C;AAEA,wBAAkB,MAAM;AACxB,mBAAa,QAAQ;AAKrB,UAAI,kBAAkB;AAAQ,iBAAS,GAAG,WAAW,aAAa;AAAA,IACnE;AAEA,UAAM,SAAS,IAAI,MAAM,CAAC,GAAsC;AAAA,MAC/D,IAAI,GAAG,MAAM;AACZ,eAAO,IAAI,UAAgC;AAC1C,cAAI,kBAAkB,YAAY;AAIjC,gBAAI,SAAS,oBAAoB,OAAO,MAAM,CAAC,MAAM,YAAY,WAAW,MAAM,CAAC,CAAC,GAAG;AACtF,gCAAkB,IAAI,MAAM,CAAC,CAAC;AAAA,YAC/B;AAKA,gBAAI,SAAS,mBAAmB,OAAO,MAAM,CAAC,MAAM,YAAY,OAAO,MAAM,CAAC,MAAM,UAAU;AAC7F,oBAAM,SAAS,WAAW,MAAM,CAAC,CAAC,EAAE,SAAS,MAAM,CAAC,CAAC;AAErD,kBAAI,OAAO,WAAW,UAAU;AAC/B,kCAAkB,IAAI,MAAM;AAAA,cAC7B,OAAO;AACN,2BAAW,SAAS,CAAC,OAAO,MAAM,OAAO,KAAK,MAAM,OAAO,KAAK,KAAK,GAAG;AACvE,oCAAkB,IAAI,KAAK;AAAA,gBAC5B;AAAA,cACD;AAAA,YACD;AAAA,UACD;AAEA,iBAAO,CAAC,MAAM,GAAG,KAAK;AAAA,QACvB;AAAA,MACD;AAAA,IACD,CAAC;AAID,aAAS,MAAM,OAA6F;AAC3G,UAAI,CAAC;AAAO,eAAO,MAAM,MAAM,CAAC;AAEhC,YAAM,OAAO,MAAM,MAAM,CAAC;AAC1B,YAAM,MAAM,WAAW,KAAK,IAAI,MAAM,IAAmB,QAAI,iBAAAC,KAAU,CAAC,MAAM,KAAK,CAAC;AAEpF,YAAM,MAAM,CAAC,IAAI;AAAA,IAClB;AAEA,UAAM,iBAAiB,CAACC,SAAQ,CAAC,MAAM;AACtC,aAAO;AAAA,QACN;AAAA,UACC,CAAC,MAAM,OAAO;AAAA,UACd,CAAC,MAAM,CAAC;AAAA,QACT;AAAA,QACAA;AAAA,QACA,CAAC,OAAO,KAAK,IAAI,CAAC,GAAG,MAAM;AAAA,MAC5B;AAAA,IACD;AAEA,UAAM,cAAc,CAAC,SAAeC,SAAQ,CAAC,OAAO,MAAM;AACzD,aAAO;AAAA,QACN,IAAI,QAAQ;AACX,iBAAOA,OAAM,GAAG,EAAE;AAAA,QACnB;AAAA,QACA,IAAI,MAAM,OAAa;AACtB,UAAAA,OAAMA,OAAM,SAAS,CAAC,IAAI;AAAA,QAC3B;AAAA,QACA,OAAO;AACN,cAAIA,OAAM,SAAS;AAAG,YAAAA,OAAM,IAAI,GAAI,YAAY;AAAA,QACjD;AAAA,QACA,KAAK,OAAa;AACjB,UAAAA,OAAM,KAAK,KAAK;AAAA,QACjB;AAAA,QACA,QAAQ;AACP,UAAAA,SAAQ,CAAC,eAAe,MAAM,YAAY,CAAC,CAAC;AAAA,QAC7C;AAAA,MACD;AAAA,IACD;AAEA,UAAM,+BAA+B,MAAM;AAC1C,aAAOJ,aAAY,WAAW,WAAkB;AAAA,IACjD;AAMA,UAAM,cAA2B;AAAA,MAChC,OAAO,CAAC;AAAA,MACR,MAAM,MAAM,WAAW;AAAA,MACvB,MAAM,CAAC,6BAA6B,GAAG,mBAAmB,CAAC;AAAA,IAC5D;AAEA,UAAM,IAAI,MAAM,WAAW;AAE3B,QAAI,oBAAoB;AAExB,UAAM,sBAAsB,CAAC,UAAuB;AACnD,UAAI;AAAmB,gBAAQ,IAAI,KAAK;AAAA,IACzC;AAEA,UAAM,+BAA+B,SAAS,qBAAqB,eAAe;AAElF,MAAE,UAAU,4BAA4B;AAExC,UAAM,gBAAgB,MAAM;AAC3B,cAAQ,IAAI,EAAE,KAAK,CAAC,WAAW;AAI9B,mBAAW,aAAa,YAAY;AAEnC,mBAAS,UAAU,MAAM;AAAA,QAC1B;AAKA,eAAO,KAAK,CAAC,MAAM,mBAAmB;AAKtC,YAAI,kBAAkB;AACrB,iBAAO,KAAK,CAAC,IAAI,6BAA6B;AAAA,QAC/C,OAAO;AACN,iBAAO,KAAK,CAAC,MAAM,6BAA6B;AAAA,QACjD;AAMA,YAAI,QAAQ,OAAO,IAAI,GAAG;AACzB,iBAAO,OAAO;AAAA,QACf;AAKA,4BAAoB;AAEpB,UAAE,OAAO,MAAM,MAAM;AAKrB,YAAI,kBAAkB;AAAQ,uBAAa,QAAQ,KAAK,MAAM;AAC7D,oBAAQ;AAAA,UACT,CAAC;AAAA,MACF,CAAC;AAAA,IACF;AAMA,iBAAa,KAAK,aAAa;AAE/B,UAAM,UAAU,eAAe,MAAM,YAAY,CAAC;AAClD,UAAM,QAAQ,YAAY,OAAO;AAEjC,UAAM,OAAO,CAAC,WAAW,OAAO,OAAmB,WAAW,SAAS,aAAa;AACnF,UAAI,CAAC;AAAmB;AAKxB,UAAI,CAAC,aAAa,SAAS;AAAQ;AAEnC,YAAM,UAAU,MAAM,MAAM,KAAK;AAEjC,QAAE,OAAO,CAAC,SAAS;AAWlB,cAAM,WAAW,cAAc,KAAK,OAAO,CAAC,UAAU,MAAM,IAAI,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,SAAS;AAKtG,gBAAQ,CAAC,EAAE,CAAC,IAAI,OAAO,KAAK,IAAI,CAAC;AACjC,gBAAQ,CAAC,EAAE,CAAC,IAAI;AAEhB,YAAI,CAAC,YAAY,CAAC,UAAU;AAC3B,eAAK,MAAM,KAAK,OAAO;AAEvB,iBAAO;AAAA,QACR;AAKA,cAAM,SAAS,KAAK,MAAM,GAAG,EAAE;AAK/B,YAAI,UAAU,OAAO,CAAC,EAAE,CAAC,MAAM,MAAM;AACpC,eAAK,MAAM,KAAK,MAAM,SAAS,CAAC,IAAI;AAAA,QACrC,OAAO;AACN,eAAK,MAAM,KAAK,OAAO;AAAA,QACxB;AAEA,eAAO;AAAA,MACR,CAAC;AAAA,IACF;AAEA,UAAM,UAAU,MAAM;AACrB,UAAI,CAAC;AAAmB;AAExB,YAAMK,QAAO,eAAe,MAAM,YAAY,CAAC;AAK/C,UAAI,WAAW;AACd,UAAE,OAAO,CAAC,SAAS;AAClB,iBAAO,KAAK,MAAM,KAAKA,KAAI,GAAG;AAAA,QAC/B,CAAC;AAAA,MACF;AAEA,cAAQA,KAAI;AAAA,IACb;AAKA,UAAM,MAAM,CAACA,UAAe;AAC3B,YAAM,QAAQA;AAEd,aAAO,QAAQA,KAAI;AAAA,IACpB;AAEA,QAAI,YAAY;AAChB,QAAI,YAAY;AAChB,QAAI,aAAa;AAKjB,UAAM,UAAU,OAAOA,UAAgB;AACtC,UAAI,CAAC;AAAmB;AAExB,UAAI,SAASA,QAAOA,QAAO,EAAE,IAAI,EAAE,MAAM,GAAG,EAAE;AAK9C,UAAI,CAAC,QAAQ;AACZ,UAAE,OAAO,OAAO;AAAA,UACf,OAAO,CAAC,OAAO;AAAA,UACf,MAAM,MAAM,WAAW;AAAA,UACvB,MAAM,CAAC,6BAA6B,GAAG,mBAAmB,CAAC;AAAA,QAC5D,EAAE;AAEF,iBAAS,MAAM,OAAO;AAAA,MACvB;AAEA,MAAC,YAAY,MAAQ,MAAM,QAAQ;AAKnC,UAAI,UAAe;AAInB,UAAI,QAAQ;AAKZ,YAAM,MAAM,MAAM,MAAM,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM;AACvD,YAAI,OAAO,IAAI,KAAK,SAAS,GAAG;AAAG,iBAAO,MAAM;AAEhD,eAAO;AAAA,MACR,GAAG,CAAC;AAEJ,YAAM,QAAQ,CAAC;AACf,YAAM,OAAO,oBAAI,IAAI;AACrB,YAAMC,cAAa,oBAAI,IAAI;AAE3B,iBAAW,CAAC,MAAM,GAAG,KAAK,MAAM,MAAM,CAAC,GAAG;AACzC,YAAI,SAAS,MAAM;AAClB,cAAI,SAAS,GAAG,GAAG;AAClB,sBAAU,QAAQ,GAAG;AAAA,UACtB,WAAW,SAAS,GAAG,GAAG;AACzB;AAMA,qBAAS,IAAI,GAAG,KAAK,KAAK,KAAK;AAC9B,oBAAM,CAACC,SAAQ,GAAG,IAAI,IAAI,QAAQ,CAAC;AAKnC,oBAAMC,QAAO,MAAM;AAClB,qBAAK,IAAID,OAAM;AACf,sBAAM,KAAK,CAACA,SAAQ,IAAI,CAAC;AAAA,cAC1B;AAKA,kBAAIA,YAAW;AAAiB,gBAAAD,YAAW,IAAI,KAAK,CAAC,CAAC;AAMtD,kBAAI,uBAAuB,IAAIC,OAAM,KAAK,qBAAqBA,SAAQ,IAAI,GAAG;AAC7E,oBAAI,UAAU,OAAO,MAAM,KAAK;AAC/B,kBAAAC,MAAK;AAAA,gBACN,OAAO;AACN;AAAA,gBACD;AAAA,cACD;AAEA,cAAAA,MAAK;AAAA,YACN;AAEA,sBAAU,QAAQ,GAAG;AAAA,UACtB;AAAA,QACD,WAAW,SAAS,UAAU;AAC7B,oBAAU,QAAS,MAAiB,CAAC,EAAE,CAAC;AAAA,QACzC,WAAW,SAAS,aAAa;AAChC,oBAAU,QAAQ,CAAC,EAAE,GAAG;AAAA,QACzB;AAAA,MACD;AAEA,YAAM,QAAQ,CAAC,OAAOC,WAAU;AAI/B,cAAM,KAAKA,MAAK;AAAA,MACjB,CAAC;AAKD,YAAM,eAAe;AAKrB,eAAS,GAAG,WAAW,MAAM;AAI7B,YAAM,SAAS,CAAC,MAAMH,WAAU,CAAC;AAKjC,YAAMI,QAAO,CAAC,MAAc,aAAa,MAAM,IAAI,CAAC;AAEpD,uBAAiB,CAACH,SAAQ,MAAM,CAAC,KAAK,cAAc;AACnD,YAAIA,YAAW,cAAcA,YAAW,UAAU;AAIjD,cAAIA,YAAW,YAAa,KAAuC,CAAC,EAAE,gBAAgB;AAIrF,kBAAM,YAAYG,MAAK,CAAC,EAAE,KAAK,CAAC,CAAC,SAAS,KAAK,MAAM;AACpD,kBAAI,CAAC,SAAS,CAAC;AAAM,uBAAO;AAE5B,oBAAM,KAAK,MAAM,CAAC;AAClB,oBAAM,KAAK,KAAK,CAAC;AAKjB,oBAAM,gBAAgB,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG;AAKrD,qBAAO,iBAAiB,IAAI,EAAE,MAAM,IAAI,EAAE;AAAA,YAC3C,CAAC;AAED,gBAAI;AAAW;AAAA,UAChB;AAKA,gBAAM,SAAS,MAAMH,SAAQ,IAAI;AAKjC,cAAI,UAAU,MAAM,GAAG;AAItB,kBAAM;AAAA,UACP;AAAA,QACD,WAAWA,YAAW,iBAAiB;AACtC,gBAAM,OAAOG,MAAK,CAAC,EAAE,KAAK,CAAC,CAAC,SAAS,KAAK,MAAM;AAI/C,gBAAI,CAAC,SAAS,CAAC;AAAM,qBAAO;AAM5B,kBAAM,SAAS,YAAY,mBAAmB,MAAM,CAAC,MAAM,KAAK,CAAC;AAKjE,kBAAM,YAAY,YAAYH,WAAU,MAAM,CAAC,MAAM,KAAK,CAAC;AAE3D,mBAAO,UAAU;AAAA,UAClB,CAAC;AAED,cAAI;AAAM;AAEV,gBAAMA,SAAQ,IAAI;AAAA,QACnB,WAAWA,YAAW,oBAAoBA,YAAW,oBAAoB;AAKxE,gBAAM,YAAYG,MAAK,CAAC,EAAE,KAAK,CAAC,CAAC,OAAO,MAAMH,YAAW,OAAO;AAEhE,cAAI;AAAW;AAEf,gBAAMA,SAAQ,IAAI;AAAA,QACnB,OAAO;AACN,gBAAMA,SAAQ,IAAI;AAAA,QACnB;AAAA,MACD;AAEA,MAAC,YAAY,YAAY,OAAQ,OAAO;AAAA,IACzC;AAEA,UAAM,QAAQ,MAAM;AACnB,UAAI,UAAe;AAEnB,iBAAW,CAAC,MAAM,GAAG,KAAK,MAAM,MAAM,CAAC,GAAG;AACzC,YAAI,SAAS,MAAM;AAClB,oBAAU,QAAQ,GAAG;AAAA,QACtB,WAAW,SAAS,UAAU;AAC7B,oBAAU,QAAS,MAAiB,CAAC,EAAE,CAAC;AAAA,QACzC,WAAW,SAAS,aAAa;AAChC,oBAAU,QAAQ,CAAC,EAAE,GAAG;AAAA,QACzB;AAAA,MACD;AAEA,aAAO;AAAA,IACR;AAKA,UAAM,OAAO,CAAC,QAAQ,UAAU;AAC/B,UAAI,aAAa,KAAK,CAAC,SAAS,eAAe;AAC9C,iBAAS,GAAG,eAAe;AAC3B;AAAA,MACD;AAEA,YAAM,UAAU,MAAM;AAEtB,YAAM,MAAM;AACZ,eAAS,GAAG,WAAW,UAAU;AAKjC,YAAM,CAAC,MAAM,IAAI,IAAI,QAAQ,CAAC;AAE9B,UAAI,SAAS,QAAQ;AAKpB,YAAI,cAAc,KAAK,MAAM,IAAI,IAAI,GAAG;AACvC,YAAE,OAAO,CAAC,SAAS;AAClB,iBAAK,QAAQ,KAAK,MAAM,OAAO,CAACF,UAASA,UAAS,OAAO;AAEzD,mBAAO;AAAA,UACR,CAAC;AAAA,QACF;AAAA,MACD;AAKA,oBAAc,KAAK;AAInB,YAAM,MAAM;AAAA,IACb;AAEA,UAAM,OAAO,MAAM;AAClB,aAAO,MAAM,KAAK,GAAG,QAAQ,MAAM,KAAK;AAAA,IACzC;AAEA,UAAM,WAAW,eAAe;AAAA,MAC/B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAG,IAAI;AAAA,MACP;AAAA,IACD,CAAC;AAED,UAAM,QAAQ,YAAY;AAAA,MACzB,KAAK,CAAC,IAAI,GAAG;AACZ,YAAI,CAAC;AAAW,qBAAW,MAAM,WAAW,IAAI,IAAI,KAAK,IAAI,IAAI;AAAA,MAClE;AAAA,MACA,eAAe,CAAC,UAAU,GAAG;AAC5B,iBAAS,WAAW,UAAU;AAC9B,aAAK;AAAA,MACN;AAAA,MACA,UAAU,CAAC,MAAM,GAAG;AACnB,iBAAS,MAAM,QAAQ,OAAO,EAAE,KAAK;AACrC,aAAK;AAAA,MACN;AAAA,MACA,UAAU,CAAC,MAAM,GAAG;AACnB,iBAAS,MAAM,QAAQ,OAAO,EAAE,KAAK;AACrC,aAAK;AAAA,MACN;AAAA,MACA,cAAc,CAAC,WAAW,SAAS,WAAW,KAAK,GAAG;AACrD,cAAM,SAAS,SAAS,UAAU,SAAS;AAE3C,eAAO,OAAO,WAAW,OAAO,SAAS;AACzC,eAAO,YAAY,OAAO,EAAE;AAE5B,aAAK;AAAA,MACN;AAAA,MACA,cAAc,CAAC,WAAW,WAAW,OAAO,QAAQ,GAAG;AACtD,iBAAS,UAAU,SAAS,EAAE,OAAO,WAAW,OAAO,QAAQ,EAAE,MAAM,SAAS;AAAA,MACjF;AAAA,MACA,OAAO,CAAC,WAAW,SAAS,OAAO,GAAG;AAIrC,cAAM,QAAQ,MAAM;AACnB,gBAAM,IAAI,WACT,KAAK;AACN,gBAAM,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC;AAE3B,iBAAO,IACJ,KAAK,KACJ,OAAO,GAAG,CAAC,EAAE,SAAS,WACpB,GAAG,CAAC,EAAE,OACN,GAAG,CAAC,EAAE,KAAgC,IAAI,IAC5C,IACD;AAAA,QACJ,GAAG;AAEH,iBAAS,OAAO,OAAO,OAAO,GAAG,OAAO,IAAI,GAAG,WAAW,OAAO,EAAE,OAAO;AAAA,MAC3E;AAAA,MACA,SAAS,CAAC,EAAE,GAAG;AACd,cAAM,SAAS,GAAG,WAAW,SAAS;AAEtC,YAAI,CAAC;AAAW,mBAAS,OAAO,KAAK,IAAI,IAAI,KAAK;AAElD,eAAO;AAAA,MACR;AAAA,MACA,OAAO,CAAC,UAAU,GAAG,OAAO,GAAG;AAC9B,cAAM,oBAAoB,MAAM,QAAQ,QAAQ;AAEhD,YAAI,mBAAmB;AAItB,kBAAQ,QAAQ,QAAkE;AAIlF,qBAAW;AAAA,QACZ;AAEA,cAAM,YAAY,QAAQ,IAAI,CAAC,CAAC,SAASE,SAAQ,OAAO,MAAM;AAC7D,iBAAO,CAAC,OAAO,OAAO,GAAGA,SAAQ,OAAO;AAAA,QACzC,CAAC;AAED,iBAAS;AAAA,UACR,OAAO,QAAQ;AAAA,UACf;AAAA,QACD,EAAE,CAAC,aAAa;AACf,mBAAS;AAKT,gBAAM,SAAS,oBAAoB,IAAI;AAEvC,gBAAM,MAAM,CAAC,EAAE,KAAK,CAAC,UAAU,WAAW,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC;AAC5D,iBAAO;AACP,wBAAc,IAAI;AAAA,QACnB,CAAC;AAAA,MACF;AAAA,MACA,KAAK,CAAC,KAAK,GAAG;AAIb,cAAM,MAAM,CAAC,IAAI;AAAA,UAChB,CAAC,MAAM,KAAK;AAAA,UACZ,CAAC,MAAM,EAAE;AAAA,QACV;AAEA,cAAM,SAAS,CAAC,CAAC;AAAA,MAClB;AAAA,MACA,MAAM,CAAC,MAAMD,WAAU,GAAG;AAIzB,gBAAQ,CAAC;AAIT,iBAAS,MAAM,WAAW,QAAQ,WAAWA,eAAc,SAAS,EAAE,IAAI;AAAA,MAC3E;AAAA,MACA,UAAU,CAAC,SAAS,GAAG;AACtB,cAAM,QAAQ,UAAU;AAExB,YAAI,CAAC;AAAW,gBAAM,MAAM,CAAC,EAAE,KAAK,CAAC,aAAa,OAAO,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,OAAO;AAAA,MACtF;AAAA,MACA,MAAM;AAIL,cAAM,SAAS,CAAC,CAAC;AAIjB,iBAAS,GAAG,WAAW,UAAU;AAIjC,sBAAc,KAAK;AAInB,cAAM,MAAM;AAAA,MACb;AAAA,MACA,MAAM,CAAC,UAAU,SAAS,KAAK,GAAG;AACjC,iBAAS,MAAM,OAAO,QAAQ,GAAG,SAAS,KAAK,EAAE,OAAO;AAAA,MACzD;AAAA,MACA,OAAO,CAAC,OAAO,GAAG;AACjB,cAAM,SAAS,SAAS,OAAO,SAAS,WAAW,MAAM;AACxD,cAAI,CAAC,aAAa,QAAQ;AAAmB,qBAAS,GAAG,cAAc,IAAI;AAC3E,cAAI,CAAC;AAAW,iBAAK;AAAA,QACtB,CAAC;AAED,eAAO;AAAA,MACR;AAAA,MACA,QAAQ,SAAS;AAChB,gBAAQ,OAAO;AACf,aAAK;AAAA,MACN;AAAA,MACA,OAAO;AACN,aAAK;AAAA,MACN;AAAA,MACA,iBAAiB,CAAC,WAAW,SAAS,GAAG,OAAO,GAAG;AAClD,cAAM,UAAyB,CAAC,QAAQ;AACvC,gBAAM,EAAE,MAAM,IAAI,IAAI,gCAAgC,KAAK;AAC3D,gBAAM,OAAO,SAAS,MAAM,WAAW,SAAS;AAKhD,cAAI,CAAC;AAAM;AAEX,gBAAM,SAAS,KAAK;AAKpB,cAAI,CAAC;AAAQ;AAEb,gBAAM,aAAa,QAAQ,OAAO,CAAC,cAAc,CAAC,OAAO,UAAU,SAAS,SAAS,CAAC;AAEtF,iBAAO,UAAU,IAAI,GAAG,UAAU;AAElC,gBAAM,YAAY,WAAW,MAAM;AAClC,mBAAO,UAAU,OAAO,GAAG,UAAU;AAAA,UACtC,GAAG,OAAO;AAEV,gBAAM,MAAM;AACX,mBAAO,UAAU,OAAO,GAAG,UAAU;AAKrC,yBAAa,SAAS;AAAA,UACvB,CAAC;AAAA,QACF;AAKA,cAAM,UAAU,CAAC,OAAO,CAAC;AAAA,MAC1B;AAAA,MACA,KAAK,MAAM;AACV,iBAAS,KAAK,KAAK,IAAI,CAAC,YAAY,OAAO,OAAO,CAAC,EAAE,KAAK,GAAG,GAAG,OAAO;AAAA,MACxE;AAAA,MACA,OAAO;AACN,cAAM,OAAO,MAAM,MAAM,CAAC;AAE1B,YAAI,SAAS;AAEb,iBAAS,IAAI,KAAK,SAAS,GAAG,IAAI,GAAG,KAAK;AACzC,cAAI,KAAK,CAAC,EAAE,CAAC,MAAM,YAAY,KAAK,CAAC,EAAE,CAAC,MAAM;AAAa;AAE3D,mBAAS;AACT,gBAAM,MAAM,CAAC,IAAI,KAAK,MAAM,GAAG,CAAC;AAChC,eAAK;AAEL;AAAA,QACD;AAKA,YAAI;AAAQ,iBAAO;AAAA,MACpB;AAAA,MACA,QAAQ,CAAC,MAAM,GAAG;AACjB,YAAI,CAAC,iBAAiB,IAAI,MAAM,KAAK,CAAC,aAAa,CAAC,WAAW;AAI9D,2BAAiB,IAAI,SAAS,cAAc,KAAK,EAAE,MAAM,MAAM;AAAA,QAChE;AAEA,aAAK;AAAA,MACN;AAAA,IACD,CAAC;AAED,UAAM,WAAW,MAAM;AACtB,UAAI;AAAW;AAEf,YAAM,UAAU,MAAM,MAAM,KAAK;AAEjC,cAAQ,CAAC,EAAE,CAAC,IAAI;AAEhB,YAAM,KAAK,OAAO;AAElB,WAAK,MAAM,MAAM;AAAA,IAClB;AAEA,UAAM,OAAO,MAAM;AAClB,YAAM,OAAO,MAAM,MAAM,CAAC;AAI1B,YAAM,OAAO,KAAK,KAAK,SAAS,CAAC;AAKjC,UAAI,OAAO,KAAK,CAAC,CAAC,KAAK,SAAS,KAAK,CAAC,CAAC,GAAG;AACzC,aAAK,CAAC,IAAI,KAAK,CAAC,IAAI;AACpB;AAAA,MACD;AAKA,WAAK,KAAK,CAAC,MAAM,CAAC,CAAC;AAAA,IACpB;AAEA,UAAM,SAAS,MAAM;AACpB,YAAM,WAAW,MAAM;AAEvB,UAAI,MAAM,QAAQ,QAAQ,GAAG;AAC5B,cAAM,CAACC,SAAQ,GAAG,KAAK,IAAI;AAE3B,cAAMA,SAAQ,KAAK;AAAA,MACpB,OAAO;AACN,cAAM,QAAQ,CAAC,CAAC;AAAA,MACjB;AAAA,IACD;AAEA,UAAM,OAAO,MAAM;AAClB,UAAI,CAAC;AAAW,aAAK,GAAG,OAAO;AAAA,IAChC;AAEA,UAAM,UAAU,MAAM;AACrB,eAAS;AACT,WAAK;AACL,oBAAc,IAAI;AAAA,IACnB;AAEA,UAAM,gBAAgB,CAAC,QAAQ,UAAU;AACxC,mBAAa,QAAS,aAAa,IAAK;AAAA,IACzC;AAYA,UAAM,SAAS,CAAC,SAAsB,SAAS,UAAU;AACxD,YAAM;AAAA,QACL,MAAAN;AAAA,QACA,MAAM,CAAC,IAAI;AAAA,MACZ,IAAI,EAAE,IAAI;AAEV,YAAM,MAAM,SAASA,QAAO,MAAM;AAClC,YAAM,MAAM,WAAW,OAAO,IAAI,QAAQ,MAAM,GAAG,IAAI,OAAO,YAAY,WAAW,UAAU,QAAQ,IAAI;AAE3G,YAAMU,OAAM,WAAW,GAAG,IAAI,IAAI,IAAI;AAEtC,aAAO,EAAWA,MAAK,GAAG;AAAA,IAC3B;AAIA,aAAS,KAAK,OAAyF;AACtG,UAAI,CAAC;AAAO,eAAO,EAAE,IAAI,EAAE;AAE3B,YAAM,OAAO,EAAE,IAAI,EAAE;AACrB,YAAM,MAAM,WAAW,KAAK,IAAI,MAAM,IAAkB,QAAI,iBAAAT,KAAU,CAAC,MAAM,KAAK,CAAC;AAEnF,QAAE,OAAO,CAACU,UAAS;AAClB,QAAAA,MAAK,OAAO;AAEZ,eAAOA;AAAA,MACR,CAAC;AAAA,IACF;AAEA,WAAO;AAAA;AAAA;AAAA;AAAA,MAIN;AAAA;AAAA;AAAA;AAAA,MAIA;AAAA;AAAA;AAAA;AAAA,MAIA;AAAA;AAAA;AAAA;AAAA,MAIA;AAAA;AAAA;AAAA;AAAA,MAIA,OAAO,SAAmF;AACzF,eAAO,OAAO,SAAS,IAAI;AAAA,MAC5B;AAAA;AAAA;AAAA;AAAA,MAIA,GAAG,IAAI;AAAA,IACR;AAAA,EACD;;;AM9iCA,MAAM,sBAAsB,CAAC,YAAkD;AAC9E,WAAO;AAAA,MACN,MAAM,MAAM;AACX,cAAM,QAAQ,aAAa,QAAQ,QAAQ,GAAG;AAE9C,eAAO,QAAQ,KAAK,MAAM,KAAK,IAAI,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,GAAG,MAAM,CAAC,EAAE;AAAA,MACpE;AAAA,MACA,MAAM,IAAI,MAAM;AACf,qBAAa,QAAQ,QAAQ,KAAK,KAAK,UAAU,IAAI,CAAC;AAAA,MACvD;AAAA,IACD;AAAA,EACD;","names":["isMergeableObject","deepmerge","str","split","input","delimeters","output","delimeter","start","end","RGX","unwrap","c","item","replace","str","obj","pluralization","actions","pr","x","key","y","pathstr","plural","action","path","actionHandler","getLanguage","data","deepmerge","state","stack","save","characters","action","push","index","next","str","prev"]}
|
package/dist/index.js
CHANGED
|
@@ -22,6 +22,10 @@ var isPromise = (val) => {
|
|
|
22
22
|
var isEmpty = (val) => {
|
|
23
23
|
return typeof val === "object" && !isNull(val) && Object.keys(val).length === 0;
|
|
24
24
|
};
|
|
25
|
+
var isCSSImage = (str2) => {
|
|
26
|
+
const startsWith = String.prototype.startsWith.bind(str2);
|
|
27
|
+
return startsWith("http") || startsWith("/") || startsWith(".") || startsWith("data");
|
|
28
|
+
};
|
|
25
29
|
var str = (value) => {
|
|
26
30
|
return String(value);
|
|
27
31
|
};
|
|
@@ -78,6 +82,31 @@ var findLastIndex = (array, fn) => {
|
|
|
78
82
|
}
|
|
79
83
|
return -1;
|
|
80
84
|
};
|
|
85
|
+
var preloadImagesBlocking = (images) => {
|
|
86
|
+
return Promise.allSettled(Array.from(images).map((src) => {
|
|
87
|
+
const img = document.createElement("img");
|
|
88
|
+
img.src = src;
|
|
89
|
+
return new Promise((resolve, reject) => {
|
|
90
|
+
if (img.complete && img.naturalHeight !== 0) {
|
|
91
|
+
resolve(void 0);
|
|
92
|
+
}
|
|
93
|
+
img.addEventListener("load", resolve);
|
|
94
|
+
img.addEventListener("abort", reject);
|
|
95
|
+
img.addEventListener("error", reject);
|
|
96
|
+
});
|
|
97
|
+
}));
|
|
98
|
+
};
|
|
99
|
+
var createDeferredPromise = () => {
|
|
100
|
+
let resolve, reject;
|
|
101
|
+
const promise = new Promise((res, rej) => {
|
|
102
|
+
resolve = res;
|
|
103
|
+
reject = rej;
|
|
104
|
+
});
|
|
105
|
+
return { resolve, reject, promise };
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
// src/global.ts
|
|
109
|
+
var PRELOADED_ASSETS = /* @__PURE__ */ new Set();
|
|
81
110
|
|
|
82
111
|
// src/store.ts
|
|
83
112
|
var store = (current, subscribers = /* @__PURE__ */ new Set()) => {
|
|
@@ -124,16 +153,19 @@ var novely = ({
|
|
|
124
153
|
throttleTimeout = 799,
|
|
125
154
|
getLanguage: getLanguage2 = getLanguage,
|
|
126
155
|
overrideLanguage = false,
|
|
127
|
-
askBeforeExit = true
|
|
156
|
+
askBeforeExit = true,
|
|
157
|
+
preloadAssets = "lazy"
|
|
128
158
|
}) => {
|
|
129
159
|
let story;
|
|
130
160
|
let times = /* @__PURE__ */ new Set();
|
|
161
|
+
const ASSETS_TO_PRELOAD = /* @__PURE__ */ new Set();
|
|
162
|
+
const assetsLoaded = createDeferredPromise();
|
|
131
163
|
defaultData ||= {};
|
|
132
164
|
defaultState ||= {};
|
|
133
165
|
const intime = (value) => {
|
|
134
166
|
return times.add(value), value;
|
|
135
167
|
};
|
|
136
|
-
const withStory = (s) => {
|
|
168
|
+
const withStory = async (s) => {
|
|
137
169
|
story = Object.fromEntries(
|
|
138
170
|
Object.entries(s).map(([name, items]) => {
|
|
139
171
|
const flat = (item) => {
|
|
@@ -147,12 +179,33 @@ var novely = ({
|
|
|
147
179
|
return [name, flat(items)];
|
|
148
180
|
})
|
|
149
181
|
);
|
|
182
|
+
if (preloadAssets === "blocking" && ASSETS_TO_PRELOAD.size > 0) {
|
|
183
|
+
renderer.ui.showScreen("loading");
|
|
184
|
+
await preloadImagesBlocking(ASSETS_TO_PRELOAD);
|
|
185
|
+
}
|
|
186
|
+
ASSETS_TO_PRELOAD.clear();
|
|
187
|
+
assetsLoaded.resolve();
|
|
150
188
|
if (initialScreen !== "game")
|
|
151
189
|
renderer.ui.showScreen(initialScreen);
|
|
152
190
|
};
|
|
153
191
|
const action = new Proxy({}, {
|
|
154
192
|
get(_, prop) {
|
|
155
193
|
return (...props) => {
|
|
194
|
+
if (preloadAssets === "blocking") {
|
|
195
|
+
if (prop === "showBackground" && typeof props[0] === "string" && isCSSImage(props[0])) {
|
|
196
|
+
ASSETS_TO_PRELOAD.add(props[0]);
|
|
197
|
+
}
|
|
198
|
+
if (prop === "showCharacter" && typeof props[0] === "string" && typeof props[1] === "string") {
|
|
199
|
+
const images = characters[props[0]].emotions[props[1]];
|
|
200
|
+
if (typeof images === "string") {
|
|
201
|
+
ASSETS_TO_PRELOAD.add(images);
|
|
202
|
+
} else {
|
|
203
|
+
for (const asset of [images.head, images.body.left, images.body.right]) {
|
|
204
|
+
ASSETS_TO_PRELOAD.add(asset);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
156
209
|
return [prop, ...props];
|
|
157
210
|
};
|
|
158
211
|
}
|
|
@@ -227,7 +280,9 @@ var novely = ({
|
|
|
227
280
|
initialDataLoaded = true;
|
|
228
281
|
$.update(() => stored);
|
|
229
282
|
if (initialScreen === "game")
|
|
230
|
-
|
|
283
|
+
assetsLoaded.promise.then(() => {
|
|
284
|
+
restore();
|
|
285
|
+
});
|
|
231
286
|
});
|
|
232
287
|
};
|
|
233
288
|
storageDelay.then(getStoredData);
|
|
@@ -273,7 +328,7 @@ var novely = ({
|
|
|
273
328
|
};
|
|
274
329
|
let restoring = false;
|
|
275
330
|
let goingBack = false;
|
|
276
|
-
let interacted =
|
|
331
|
+
let interacted = 0;
|
|
277
332
|
const restore = async (save2) => {
|
|
278
333
|
if (!initialDataLoaded)
|
|
279
334
|
return;
|
|
@@ -389,16 +444,16 @@ var novely = ({
|
|
|
389
444
|
return current;
|
|
390
445
|
};
|
|
391
446
|
const exit = (force = false) => {
|
|
392
|
-
if (interacted && !force && askBeforeExit) {
|
|
447
|
+
if (interacted > 1 && !force && askBeforeExit) {
|
|
393
448
|
renderer.ui.showExitPrompt();
|
|
394
449
|
return;
|
|
395
450
|
}
|
|
396
451
|
const current = stack.value;
|
|
397
452
|
stack.clear();
|
|
398
453
|
renderer.ui.showScreen("mainmenu");
|
|
399
|
-
const [
|
|
400
|
-
if (type === "auto"
|
|
401
|
-
if (
|
|
454
|
+
const [time, type] = current[2];
|
|
455
|
+
if (type === "auto") {
|
|
456
|
+
if (interacted <= 1 && times.has(time)) {
|
|
402
457
|
$.update((prev) => {
|
|
403
458
|
prev.saves = prev.saves.filter((save2) => save2 !== current);
|
|
404
459
|
return prev;
|
|
@@ -562,6 +617,12 @@ var novely = ({
|
|
|
562
617
|
}
|
|
563
618
|
if (exited)
|
|
564
619
|
render();
|
|
620
|
+
},
|
|
621
|
+
preload([source]) {
|
|
622
|
+
if (!PRELOADED_ASSETS.has(source) && !goingBack && !restoring) {
|
|
623
|
+
PRELOADED_ASSETS.add(document.createElement("img").src = source);
|
|
624
|
+
}
|
|
625
|
+
push();
|
|
565
626
|
}
|
|
566
627
|
});
|
|
567
628
|
const enmemory = () => {
|
|
@@ -600,7 +661,7 @@ var novely = ({
|
|
|
600
661
|
interactivity(true);
|
|
601
662
|
};
|
|
602
663
|
const interactivity = (value = false) => {
|
|
603
|
-
interacted = value;
|
|
664
|
+
interacted = value ? interacted + 1 : 0;
|
|
604
665
|
};
|
|
605
666
|
const unwrap = (content, global = false) => {
|
|
606
667
|
const {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils.ts","../src/store.ts","../src/novely.ts","../src/constants.ts","../src/storage.ts"],"sourcesContent":["import type { ActionProxyProvider, CustomHandler } from './action';\nimport type { Character } from './character';\nimport type { TypewriterSpeed, Thenable } from './types';\n\ntype MatchActionMap = {\n\t[Key in keyof ActionProxyProvider<Record<string, Character>>]: (\n\t\tdata: Parameters<ActionProxyProvider<Record<string, Character>>[Key]>,\n\t) => void;\n};\n\ntype MatchActionMapComplete = Omit<MatchActionMap, 'custom'> & {\n\tcustom: (value: [handler: CustomHandler]) => Thenable<void>;\n};\n\nconst matchAction = <M extends MatchActionMapComplete>(values: M) => {\n\treturn (action: keyof MatchActionMap, props: any) => {\n\t\treturn values[action](props);\n\t};\n};\n\nconst isNumber = (val: unknown): val is number => {\n\treturn typeof val === 'number';\n};\n\nconst isNull = (val: unknown): val is null => {\n\treturn val === null;\n};\n\nconst isString = (val: unknown): val is string => {\n\treturn typeof val === 'string';\n};\n\nconst isFunction = (val: unknown): val is (...parameters: any[]) => any => {\n\treturn typeof val === 'function';\n};\n\nconst isPromise = (val: unknown): val is Promise<any> => {\n\treturn Boolean(val) && (typeof val === 'object' || isFunction(val)) && isFunction((val as any).then);\n};\n\nconst isEmpty = (val: unknown): val is {} => {\n\treturn typeof val === 'object' && !isNull(val) && Object.keys(val).length === 0;\n};\n\nconst isCSSImage = (str: string) => {\n\tconst startsWith = String.prototype.startsWith.bind(str);\n\n\treturn startsWith('http') || startsWith('/') || startsWith('.') || startsWith('data');\n};\n\nconst str = (value: unknown) => {\n\treturn String(value);\n};\n\nconst isUserRequiredAction = (\n\taction: keyof MatchActionMapComplete,\n\tmeta: Parameters<MatchActionMapComplete[keyof MatchActionMapComplete]>,\n) => {\n\treturn action === 'custom' && meta[0] && (meta[0] as unknown as CustomHandler).requireUserAction;\n};\n\nconst getTypewriterSpeed = (): TypewriterSpeed => {\n\treturn 'Medium';\n};\n\nconst getLanguage = (languages: string[], _: any) => {\n\tlet { language } = navigator;\n\n\tif (languages.includes(language)) {\n\t\treturn language;\n\t} else if (languages.includes((language = language.substring(0, 2)))) {\n\t\treturn language;\n\t} else if ((language = languages.find((value) => navigator.languages.includes(value))!)) {\n\t\treturn language;\n\t}\n\n\t/**\n\t * We'v checked the `en-GB` format, `en` format, and maybe any second languages, but there were no matches\n\t */\n\treturn languages[0];\n};\n\n/**\n * @copyright Techlead LLC\n * @see https://learn.javascript.ru/task/throttle\n */\nconst throttle = <Fn extends (...args: any[]) => any>(fn: Fn, ms: number) => {\n\tlet throttled = false,\n\t\tsavedArgs: any,\n\t\tsavedThis: any;\n\n\tfunction wrapper(this: any) {\n\t\tif (throttled) {\n\t\t\tsavedArgs = arguments;\n\t\t\tsavedThis = this;\n\t\t\treturn;\n\t\t}\n\n\t\tfn.apply(this, arguments as unknown as any[]);\n\n\t\tthrottled = true;\n\n\t\tsetTimeout(function () {\n\t\t\tthrottled = false;\n\n\t\t\tif (savedArgs) {\n\t\t\t\twrapper.apply(savedThis, savedArgs);\n\t\t\t\tsavedArgs = savedThis = null;\n\t\t\t}\n\t\t}, ms);\n\t}\n\n\treturn wrapper as unknown as (...args: Parameters<Fn>) => void;\n};\n\nconst vibrate = (pattern: VibratePattern) => {\n\ttry {\n\t\tif ('vibrate' in navigator) {\n\t\t\tnavigator.vibrate(pattern);\n\t\t}\n\t} catch {}\n};\n\nconst findLastIndex = <T>(array: T[], fn: (item: T) => boolean) => {\n\tfor (let i = array.length - 1; i > 0; i--) {\n\t\tif (fn(array[i])) {\n\t\t\treturn i;\n\t\t}\n\t}\n\n\treturn -1;\n};\n\nexport {\n\tmatchAction,\n\tisNumber,\n\tisNull,\n\tisString,\n\tisPromise,\n\tisEmpty,\n\tisCSSImage,\n\tstr,\n\tisUserRequiredAction,\n\tgetTypewriterSpeed,\n\tgetLanguage,\n\tthrottle,\n\tisFunction,\n\tvibrate,\n\tfindLastIndex,\n};\n","type Stored<T> = {\n\tsubscribe: (cb: (value: T) => void) => () => void;\n\tupdate: (fn: (prev: T) => T) => void;\n\tget: () => T;\n};\n\nconst store = <T>(current: T, subscribers = new Set<(value: T) => void>()): Stored<T> => {\n\tconst subscribe = (cb: (value: T) => void) => {\n\t\tsubscribers.add(cb), cb(current);\n\n\t\treturn () => {\n\t\t\tsubscribers.delete(cb);\n\t\t};\n\t};\n\n\tconst push = (value: T) => {\n\t\tsubscribers.forEach((cb) => cb(value));\n\t};\n\n\tconst update = (fn: (prev: T) => T) => {\n\t\tpush((current = fn(current)));\n\t};\n\n\tconst get = () => {\n\t\treturn current;\n\t};\n\n\treturn { subscribe, update, get } as const;\n};\n\nexport { store };\nexport type { Stored };\n","import type { Character } from './character';\nimport type {\n\tActionProxyProvider,\n\tGetActionParameters,\n\tStory,\n\tValidAction,\n\tUnwrappable,\n\tCustomHandler,\n} from './action';\nimport type { Storage } from './storage';\nimport type { Save, State, Data, StorageData, DeepPartial, NovelyScreen, Migration } from './types';\nimport type { Renderer, RendererInit } from './renderer';\nimport type { SetupT9N } from '@novely/t9n';\nimport {\n\tmatchAction,\n\tisNumber,\n\tisNull,\n\tisString,\n\tisPromise,\n\tisEmpty,\n\tstr,\n\tisUserRequiredAction,\n\tgetTypewriterSpeed,\n\tgetLanguage as defaultGetLanguage,\n\tthrottle,\n\tisFunction,\n\tvibrate,\n\tfindLastIndex,\n} from './utils';\nimport { store } from './store';\nimport { all as deepmerge } from 'deepmerge';\nimport { klona } from 'klona/json';\nimport { SKIPPED_DURING_RESTORE, EMPTY_SET } from './constants';\nimport { replace as replaceT9N } from '@novely/t9n';\n\ninterface NovelyInit<\n\tLanguages extends string,\n\tCharacters extends Record<string, Character<Languages>>,\n\tInter extends ReturnType<SetupT9N<Languages>>,\n\tStateScheme extends State,\n\tDataScheme extends Data,\n> {\n\t/**\n\t * An array of languages supported by the game.\n\t */\n\tlanguages: Languages[];\n\t/**\n\t * An object containing the characters in the game.\n\t */\n\tcharacters: Characters;\n\t/**\n\t * An object that provides access to the game's storage system.\n\t */\n\tstorage: Storage;\n\t/**\n\t * Delay loading data until Promise is resolved\n\t */\n\tstorageDelay?: Promise<void>;\n\t/**\n\t * A function that returns a Renderer object used to display the game's content\n\t */\n\trenderer: (characters: RendererInit) => Renderer;\n\t/**\n\t * An optional property that specifies the initial screen to display when the game starts\n\t */\n\tinitialScreen?: NovelyScreen;\n\t/**\n\t * An object containing the translation functions used in the game\n\t */\n\tt9n: Inter;\n\t/**\n\t * Initial state value\n\t */\n\tstate?: StateScheme;\n\t/**\n\t * Initial data value\n\t */\n\tdata?: DataScheme;\n\t/**\n\t * Enable autosaves or disable\n\t * @default true\n\t */\n\tautosaves?: boolean;\n\t/**\n\t * Migration from old saves to newer\n\t */\n\tmigrations?: Migration[];\n\t/**\n\t * For saves Novely uses `throttle` function. This might be needed if you want to control frequency of saves to the storage\n\t * @default 799\n\t */\n\tthrottleTimeout?: number;\n\t/**\n\t * Custom language detector\n\t * @param languages Supported languages aka `languages: []` in the config\n\t * @example ```ts\n\t * novely({\n\t * \t\tgetLanguage(languages, original) {\n\t * \t\t\t\tif (!sdk) return original(languages);\n\t * \t\t\t\treturn sdk.environment.i18n.lang // i.e. custom language from some sdk\n\t * \t\t}\n\t * })\n\t * ```\n\t */\n\tgetLanguage?: (languages: string[], original: typeof defaultGetLanguage) => string;\n\t/**\n\t * Ignores saved language, and uses `getLanguage` to get it on every engine start\n\t * @default false\n\t */\n\toverrideLanguage?: boolean;\n\t/**\n\t * Show a prompt before exiting a game\n\t * @default true\n\t */\n\taskBeforeExit?: boolean;\n}\n\nconst novely = <\n\tLanguages extends string,\n\tCharacters extends Record<string, Character<Languages>>,\n\tInter extends ReturnType<SetupT9N<Languages>>,\n\tStateScheme extends State,\n\tDataScheme extends Data,\n>({\n\tcharacters,\n\tstorage,\n\tstorageDelay = Promise.resolve(),\n\trenderer: createRenderer,\n\tinitialScreen = 'mainmenu',\n\tt9n,\n\tlanguages,\n\tstate: defaultState,\n\tdata: defaultData,\n\tautosaves = true,\n\tmigrations = [],\n\tthrottleTimeout = 799,\n\tgetLanguage = defaultGetLanguage,\n\toverrideLanguage = false,\n\taskBeforeExit = true\n}: NovelyInit<Languages, Characters, Inter, StateScheme, DataScheme>) => {\n\tlet story: Story;\n\tlet times = new Set<number>();\n\n\t/**\n\t * Prevent `undefined`\n\t */\n\tdefaultData ||= {} as DataScheme;\n\tdefaultState ||= {} as StateScheme;\n\n\t/**\n\t * Saves timestamps created in this session\n\t */\n\tconst intime = (value: number) => {\n\t\treturn times.add(value), value;\n\t};\n\n\tconst withStory = (s: Story) => {\n\t\t/**\n\t\t * Transforms `(ValidAction | ValidAction[])[]` to `ValidAction[]`\n\t\t */\n\t\tstory = Object.fromEntries(\n\t\t\tObject.entries(s).map(([name, items]) => {\n\t\t\t\tconst flat = (item: (ValidAction | ValidAction[])[]): ValidAction[] => {\n\t\t\t\t\treturn item.flatMap((data) => {\n\t\t\t\t\t\tconst type = data[0];\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * This is not just an action like `['name', ...arguments]`, but an array of actions\n\t\t\t\t\t\t */\n\t\t\t\t\t\tif (Array.isArray(type)) return flat(data as ValidAction[]);\n\n\t\t\t\t\t\treturn [data as ValidAction];\n\t\t\t\t\t});\n\t\t\t\t};\n\n\t\t\t\treturn [name, flat(items)];\n\t\t\t}),\n\t\t);\n\n\t\t/**\n\t\t * When `initialScreen` is not a game, we can safely show it\n\t\t */\n\t\tif (initialScreen !== 'game') renderer.ui.showScreen(initialScreen);\n\t};\n\n\tconst action = new Proxy({} as ActionProxyProvider<Characters>, {\n\t\tget(_, prop) {\n\t\t\treturn (\n\t\t\t\t...props: Parameters<\n\t\t\t\t\tActionProxyProvider<Record<string, Character>>[keyof ActionProxyProvider<Record<string, Character>>]\n\t\t\t\t>\n\t\t\t) => {\n\t\t\t\treturn [prop, ...props];\n\t\t\t};\n\t\t},\n\t});\n\n\tfunction state(value: DeepPartial<StateScheme> | ((prev: StateScheme) => StateScheme)): void;\n\tfunction state(): StateScheme;\n\tfunction state(value?: DeepPartial<StateScheme> | ((prev: StateScheme) => StateScheme)): StateScheme | void {\n\t\tif (!value) return stack.value[1] as StateScheme | void;\n\n\t\tconst prev = stack.value[1];\n\t\tconst val = isFunction(value) ? value(prev as StateScheme) : deepmerge([prev, value]);\n\n\t\tstack.value[1] = val as StateScheme;\n\t}\n\n\tconst getDefaultSave = (state = {}) => {\n\t\treturn [\n\t\t\t[\n\t\t\t\t[null, 'start'],\n\t\t\t\t[null, 0],\n\t\t\t],\n\t\t\tstate,\n\t\t\t[intime(Date.now()), 'auto'],\n\t\t] as Save;\n\t};\n\n\tconst createStack = (current: Save, stack = [current]) => {\n\t\treturn {\n\t\t\tget value() {\n\t\t\t\treturn stack.at(-1)!;\n\t\t\t},\n\t\t\tset value(value: Save) {\n\t\t\t\tstack[stack.length - 1] = value;\n\t\t\t},\n\t\t\tback() {\n\t\t\t\tif (stack.length > 1) stack.pop(), (goingBack = true);\n\t\t\t},\n\t\t\tpush(value: Save) {\n\t\t\t\tstack.push(value);\n\t\t\t},\n\t\t\tclear() {\n\t\t\t\tstack = [getDefaultSave(klona(defaultState))];\n\t\t\t},\n\t\t};\n\t};\n\n\tconst getLanguageWithoutParameters = () => {\n\t\treturn getLanguage(languages, defaultGetLanguage);\n\t}\n\n\t/**\n\t * 1) Novely rendered using the `initialData`, but you can't start new game or `load` an empty one - this is scary, imagine losing your progress\n\t * 2) Actual stored data is loaded, language and etc is changed\n\t */\n\tconst initialData: StorageData = {\n\t\tsaves: [],\n\t\tdata: klona(defaultData) as Data,\n\t\tmeta: [getLanguageWithoutParameters(), getTypewriterSpeed()],\n\t};\n\n\tconst $ = store(initialData);\n\n\tlet initialDataLoaded = false;\n\n\tconst onStorageDataChange = (value: StorageData) => {\n\t\tif (initialDataLoaded) storage.set(value);\n\t};\n\n\tconst throttledOnStorageDataChange = throttle(onStorageDataChange, throttleTimeout);\n\n\t$.subscribe(throttledOnStorageDataChange);\n\n\tconst getStoredData = () => {\n\t\tstorage.get().then((stored) => {\n\t\t\t/**\n\t\t\t * Migration is done only once (when game loads it's data), and then it saves the updated format\n\t\t\t */\n\t\t\tfor (const migration of migrations) {\n\t\t\t\t// @ts-expect-error Types does not match between versions\n\t\t\t\tstored = migration(stored);\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Default `localStorageStorage` returns empty array and engine set this up itself\n\t\t\t */\n\t\t\tstored.meta[1] ||= getTypewriterSpeed();\n\n\t\t\t/**\n\t\t\t * When we need to override it we do that, when not – only when language was not defined already\n\t\t\t */\n\t\t\tif (overrideLanguage) {\n\t\t\t\tstored.meta[0] = getLanguageWithoutParameters();\n\t\t\t} else {\n\t\t\t\tstored.meta[0] ||= getLanguageWithoutParameters();\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * When data is empty replace it with `defaultData`\n\t\t\t * It also might be empty (default to empty)\n\t\t\t */\n\t\t\tif (isEmpty(stored.data)) {\n\t\t\t\tstored.data = defaultData as Data;\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Now the next store updates will entail saving via storage.set\n\t\t\t */\n\t\t\tinitialDataLoaded = true;\n\n\t\t\t$.update(() => stored);\n\n\t\t\t/**\n\t\t\t * When initialScreen is game, then we will load it, but after the data is loaded\n\t\t\t */\n\t\t\tif (initialScreen === 'game') restore();\n\t\t});\n\t};\n\n\t/**\n\t * By default this is resolved immediately, but also can be delayed.\n\t * I.e. storage has not loaded yet\n\t */\n\tstorageDelay.then(getStoredData);\n\n\tconst initial = getDefaultSave(klona(defaultState));\n\tconst stack = createStack(initial);\n\n\tconst save = (override = false, type: Save[2][1] = override ? 'auto' : 'manual') => {\n\t\tif (!initialDataLoaded) return;\n\n\t\t/**\n\t\t * When autosaves diabled just return\n\t\t */\n\t\tif (!autosaves && type === 'auto') return;\n\n\t\tconst current = klona(stack.value);\n\n\t\t$.update((prev) => {\n\t\t\t/**\n\t\t\t * Find latest save that were created in current session, and check if it is latest in an array\n\t\t\t *\n\t\t\t * We check if save was created in current session and it is latest in array\n\t\t\t * When it is not then replacing it will break logical chain\n\t\t\t *\n\t\t\t * [auto save 1]\n\t\t\t * [manual save 1]\n\t\t\t * [auto save 2] <- should not replace first auto save\n\t\t\t */\n\t\t\tconst isLatest = findLastIndex(prev.saves, (value) => times.has(value[2][0])) === prev.saves.length - 1;\n\n\t\t\t/**\n\t\t\t * Update type and time information\n\t\t\t */\n\t\t\tcurrent[2][0] = intime(Date.now());\n\t\t\tcurrent[2][1] = type;\n\n\t\t\tif (!override || !isLatest) {\n\t\t\t\tprev.saves.push(current);\n\n\t\t\t\treturn prev;\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Get latest\n\t\t\t */\n\t\t\tconst latest = prev.saves.at(-1);\n\n\t\t\t/**\n\t\t\t * When that save is the same type, replace it\n\t\t\t */\n\t\t\tif (latest && latest[2][1] === type) {\n\t\t\t\tprev.saves[prev.saves.length - 1] = current;\n\t\t\t} else {\n\t\t\t\tprev.saves.push(current);\n\t\t\t}\n\n\t\t\treturn prev;\n\t\t});\n\t};\n\n\tconst newGame = () => {\n\t\tif (!initialDataLoaded) return;\n\n\t\tconst save = getDefaultSave(klona(defaultState));\n\n\t\t/**\n\t\t * Initial save is automatic, and should be ignored when autosaves is turned off\n\t\t */\n\t\tif (autosaves) {\n\t\t\t$.update((prev) => {\n\t\t\t\treturn prev.saves.push(save), prev;\n\t\t\t});\n\t\t}\n\n\t\trestore(save);\n\t};\n\n\t/**\n\t * Set's the save\n\t */\n\tconst set = (save: Save) => {\n\t\tstack.value = save;\n\n\t\treturn restore(save);\n\t};\n\n\tlet restoring = false;\n\tlet goingBack = false;\n\tlet interacted = false;\n\n\t/**\n\t * Restore\n\t */\n\tconst restore = async (save?: Save) => {\n\t\tif (!initialDataLoaded) return;\n\n\t\tlet latest = save ? save : $.get().saves.at(-1);\n\n\t\t/**\n\t\t * When there is no game, then make a new game\n\t\t */\n\t\tif (!latest) {\n\t\t\t$.update(() => ({\n\t\t\t\tsaves: [initial],\n\t\t\t\tdata: klona(defaultData) as Data,\n\t\t\t\tmeta: [getLanguageWithoutParameters(), getTypewriterSpeed()],\n\t\t\t}));\n\n\t\t\tlatest = klona(initial);\n\t\t}\n\n\t\t(restoring = true), (stack.value = latest);\n\n\t\t/**\n\t\t * Текущий элемент в истории\n\t\t */\n\t\tlet current: any = story;\n\t\t/**\n\t\t * Текущий элемент `[null, int]`\n\t\t */\n\t\tlet index = 0;\n\n\t\t/**\n\t\t * Число элементов `[null, int]`\n\t\t */\n\t\tconst max = stack.value[0].reduce((acc, [type, val]) => {\n\t\t\tif (isNull(type) && isNumber(val)) return acc + 1;\n\n\t\t\treturn acc;\n\t\t}, 0);\n\n\t\tconst queue = [] as [any, any][];\n\t\tconst keep = new Set();\n\t\tconst characters = new Set();\n\n\t\tfor (const [type, val] of stack.value[0]) {\n\t\t\tif (type === null) {\n\t\t\t\tif (isString(val)) {\n\t\t\t\t\tcurrent = current[val];\n\t\t\t\t} else if (isNumber(val)) {\n\t\t\t\t\tindex++;\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Запустим все экшены которые идут в `[null, int]` от `0` до `int`\n\t\t\t\t\t * Почему-то потребовалось изменить `<` на `<=`, чтобы последний action попадал сюда\n\t\t\t\t\t */\n\t\t\t\t\tfor (let i = 0; i <= val; i++) {\n\t\t\t\t\t\tconst [action, ...meta] = current[i];\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * Add item to queue and action to keep\n\t\t\t\t\t\t */\n\t\t\t\t\t\tconst push = () => {\n\t\t\t\t\t\t\tkeep.add(action);\n\t\t\t\t\t\t\tqueue.push([action, meta]);\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * Do not remove characters that will be here anyways\n\t\t\t\t\t\t */\n\t\t\t\t\t\tif (action === 'showCharacter') characters.add(meta[0]);\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * Экшены, для закрытия которых пользователь должен с ними взаимодействовать\n\t\t\t\t\t\t * Также в эту группу входят экшены, которые не должны быть вызваны при восстановлении\n\t\t\t\t\t\t */\n\t\t\t\t\t\tif (SKIPPED_DURING_RESTORE.has(action) || isUserRequiredAction(action, meta)) {\n\t\t\t\t\t\t\tif (index === max && i === val) {\n\t\t\t\t\t\t\t\tpush();\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tpush();\n\t\t\t\t\t}\n\n\t\t\t\t\tcurrent = current[val];\n\t\t\t\t}\n\t\t\t} else if (type === 'choice') {\n\t\t\t\tcurrent = current[(val as number) + 1][1];\n\t\t\t} else if (type === 'condition') {\n\t\t\t\tcurrent = current[2][val];\n\t\t\t}\n\t\t}\n\n\t\tqueue.forEach((value, index) => {\n\t\t\t/**\n\t\t\t * Mutate the queue item\n\t\t\t */\n\t\t\tvalue.push(index);\n\t\t});\n\n\t\t/**\n\t\t * This is basically made for TypeScript.\n\t\t */\n\t\tconst indexedQueue = queue as unknown as [Exclude<ValidAction[0], ValidAction>, ValidAction[1], number][];\n\n\t\t/**\n\t\t * Run these exactly before the main loop.\n\t\t */\n\t\trenderer.ui.showScreen('game');\n\t\t/**\n\t\t * Provide the `keep` in there\n\t\t */\n\t\tmatch('clear', [keep, characters]);\n\n\t\t/**\n\t\t * Get the next actions array.\n\t\t */\n\t\tconst next = (i: number) => indexedQueue.slice(i + 1);\n\n\t\tfor await (const [action, meta, i] of indexedQueue) {\n\t\t\tif (action === 'function' || action === 'custom') {\n\t\t\t\t/**\n\t\t\t\t * When `callOnlyLatest` is `true`\n\t\t\t\t */\n\t\t\t\tif (action === 'custom' && (meta as GetActionParameters<'Custom'>)[0].callOnlyLatest) {\n\t\t\t\t\t/**\n\t\t\t\t\t * We'll calculate it is `latest` or not\n\t\t\t\t\t */\n\t\t\t\t\tconst notLatest = next(i).some(([_action, _meta]) => {\n\t\t\t\t\t\tif (!_meta || !meta) return false;\n\n\t\t\t\t\t\tconst c0 = _meta[0] as unknown as GetActionParameters<'Custom'>[0];\n\t\t\t\t\t\tconst c1 = meta[0] as unknown as GetActionParameters<'Custom'>[0];\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * Also check for `undefined`\n\t\t\t\t\t\t */\n\t\t\t\t\t\tconst isIdenticalID = c0.id && c1.id && c0.id === c1.id;\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * Equal by id or equal by `toString()`\n\t\t\t\t\t\t */\n\t\t\t\t\t\treturn isIdenticalID || str(c0) === str(c1);\n\t\t\t\t\t});\n\n\t\t\t\t\tif (notLatest) continue;\n\t\t\t\t}\n\n\t\t\t\t/**\n\t\t\t\t * Action can return Promise.\n\t\t\t\t */\n\t\t\t\tconst result = match(action, meta);\n\n\t\t\t\t/**\n\t\t\t\t * Should wait until it resolved\n\t\t\t\t */\n\t\t\t\tif (isPromise(result)) {\n\t\t\t\t\t/**\n\t\t\t\t\t * Await it!\n\t\t\t\t\t */\n\t\t\t\t\tawait result;\n\t\t\t\t}\n\t\t\t} else if (action === 'showCharacter') {\n\t\t\t\tconst skip = next(i).some(([_action, _meta]) => {\n\t\t\t\t\t/**\n\t\t\t\t\t * Проверка на возможный `undefined`\n\t\t\t\t\t */\n\t\t\t\t\tif (!_meta || !meta) return false;\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Будет ли персонаж скрыт в будущем\n\t\t\t\t\t * Нет смысла при загрузке сохранения загружать и отрисовывать персонажа, который будет скрыт\n\t\t\t\t\t */\n\t\t\t\t\tconst hidden = _action === 'hideCharacter' && _meta[0] === meta[0];\n\t\t\t\t\t/**\n\t\t\t\t\t * Не нужно запускать рендер персонажа, если после этого будет ещё один рендер этого персонажа\n\t\t\t\t\t * Таким образом избегаем ситуации, когда при загрузке вследствие гонки при загрузки изображений отрисовывается не последняя эмоция\n\t\t\t\t\t */\n\t\t\t\t\tconst notLatest = _action === action && _meta[0] === meta[0];\n\n\t\t\t\t\treturn hidden || notLatest;\n\t\t\t\t});\n\n\t\t\t\tif (skip) continue;\n\n\t\t\t\tmatch(action, meta);\n\t\t\t} else if (action === 'showBackground' || action === 'animateCharacter') {\n\t\t\t\t/**\n\t\t\t\t * Такая же оптимизация применяется к фонам и анимированию персонажей.\n\t\t\t\t * Если фон изменится, то нет смысла устанавливать текущий\n\t\t\t\t */\n\t\t\t\tconst notLatest = next(i).some(([_action]) => action === _action);\n\n\t\t\t\tif (notLatest) continue;\n\n\t\t\t\tmatch(action, meta);\n\t\t\t} else {\n\t\t\t\tmatch(action, meta);\n\t\t\t}\n\t\t}\n\n\t\t(restoring = goingBack = false), render();\n\t};\n\n\tconst refer = () => {\n\t\tlet current: any = story;\n\n\t\tfor (const [type, val] of stack.value[0]) {\n\t\t\tif (type === null) {\n\t\t\t\tcurrent = current[val];\n\t\t\t} else if (type === 'choice') {\n\t\t\t\tcurrent = current[(val as number) + 1][1];\n\t\t\t} else if (type === 'condition') {\n\t\t\t\tcurrent = current[2][val];\n\t\t\t}\n\t\t}\n\n\t\treturn current;\n\t};\n\n\t/**\n\t *\n\t * @param force Force exit\n\t */\n\tconst exit = (force = false) => {\n\t\tif (interacted && !force && askBeforeExit) {\n\t\t\trenderer.ui.showExitPrompt();\n\t\t\treturn;\n\t\t}\n\n\t\tconst current = stack.value;\n\n\t\tstack.clear();\n\t\trenderer.ui.showScreen('mainmenu');\n\n\t\t/**\n\t\t * First two save elements and it's type\n\t\t */\n\t\tconst [[first, second], , [time, type]] = current;\n\n\t\tif (type === 'auto' && first && second) {\n\t\t\t/**\n\t\t\t * Player has not interacted with game and it belongs to the current session\n\t\t\t */\n\t\t\tif (!interacted && times.has(time)) {\n\t\t\t\t$.update((prev) => {\n\t\t\t\t\tprev.saves = prev.saves.filter((save) => save !== current);\n\n\t\t\t\t\treturn prev;\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Reset interactive value\n\t\t */\n\t\tinteractivity(false);\n\t\t/**\n\t\t * Reset session times\n\t\t */\n\t\ttimes.clear();\n\t};\n\n\tconst back = () => {\n\t\treturn stack.back(), restore(stack.value);\n\t};\n\n\tconst renderer = createRenderer({\n\t\tcharacters,\n\t\tset,\n\t\trestore,\n\t\tsave,\n\t\tnewGame,\n\t\texit,\n\t\tback,\n\t\tstack,\n\t\tlanguages,\n\t\tt: t9n.i,\n\t\t$,\n\t});\n\n\tconst match = matchAction({\n\t\twait([time]) {\n\t\t\tif (!restoring) setTimeout(push, isFunction(time) ? time() : time);\n\t\t},\n\t\tshowBackground([background]) {\n\t\t\trenderer.background(background);\n\t\t\tpush();\n\t\t},\n\t\tplayMusic([source]) {\n\t\t\trenderer.music(source, 'music').play();\n\t\t\tpush();\n\t\t},\n\t\tstopMusic([source]) {\n\t\t\trenderer.music(source, 'music').stop();\n\t\t\tpush();\n\t\t},\n\t\tshowCharacter([character, emotion, className, style]) {\n\t\t\tconst handle = renderer.character(character);\n\n\t\t\thandle.append(className, style, restoring);\n\t\t\thandle.withEmotion(emotion)();\n\n\t\t\tpush();\n\t\t},\n\t\thideCharacter([character, className, style, duration]) {\n\t\t\trenderer.character(character).remove(className, style, duration)(push, restoring);\n\t\t},\n\t\tdialog([character, content, emotion]) {\n\t\t\t/**\n\t\t\t * Person name\n\t\t\t */\n\t\t\tconst name = (() => {\n\t\t\t\tconst c = character,\n\t\t\t\t\tcs = characters;\n\t\t\t\tconst lang = $.get().meta[0];\n\n\t\t\t\treturn c\n\t\t\t\t\t? c in cs\n\t\t\t\t\t\t? typeof cs[c].name === 'string'\n\t\t\t\t\t\t\t? (cs[c].name as string)\n\t\t\t\t\t\t\t: (cs[c].name as Record<string, string>)[lang]\n\t\t\t\t\t\t: c\n\t\t\t\t\t: '';\n\t\t\t})();\n\n\t\t\trenderer.dialog(unwrap(content), unwrap(name), character, emotion)(forward);\n\t\t},\n\t\tfunction([fn]) {\n\t\t\tconst result = fn(restoring, goingBack);\n\n\t\t\tif (!restoring) result ? result.then(push) : push();\n\n\t\t\treturn result;\n\t\t},\n\t\tchoice([question, ...choices]) {\n\t\t\tconst isWithoutQuestion = Array.isArray(question);\n\n\t\t\tif (isWithoutQuestion) {\n\t\t\t\t/**\n\t\t\t\t * Первый элемент может быть как строкой, так и элементов выбора\n\t\t\t\t */\n\t\t\t\tchoices.unshift(question as unknown as [Unwrappable, ValidAction[], () => boolean]);\n\t\t\t\t/**\n\t\t\t\t * Значит, текст не требуется\n\t\t\t\t */\n\t\t\t\tquestion = '';\n\t\t\t}\n\n\t\t\tconst unwrapped = choices.map(([content, action, visible]) => {\n\t\t\t\treturn [unwrap(content), action, visible] as [string, ValidAction[], () => boolean];\n\t\t\t});\n\n\t\t\trenderer.choices(\n\t\t\t\tunwrap(question),\n\t\t\t\tunwrapped,\n\t\t\t)((selected) => {\n\t\t\t\tenmemory();\n\n\t\t\t\t/**\n\t\t\t\t * If there is a question, then `index` should be shifted by `1`\n\t\t\t\t */\n\t\t\t\tconst offset = isWithoutQuestion ? 0 : 1;\n\n\t\t\t\tstack.value[0].push(['choice', selected + offset], [null, 0]);\n\t\t\t\trender();\n\t\t\t\tinteractivity(true);\n\t\t\t});\n\t\t},\n\t\tjump([scene]) {\n\t\t\t/**\n\t\t\t * `-1` index is used here because `clear` will run `next` that will increase index to `0`\n\t\t\t */\n\t\t\tstack.value[0] = [\n\t\t\t\t[null, scene],\n\t\t\t\t[null, -1],\n\t\t\t];\n\n\t\t\tmatch('clear', []);\n\t\t},\n\t\tclear([keep, characters]) {\n\t\t\t/**\n\t\t\t * Remove vibration\n\t\t\t */\n\t\t\tvibrate(0);\n\t\t\t/**\n\t\t\t * Call the actual `clear`\n\t\t\t */\n\t\t\trenderer.clear(goingBack, keep || EMPTY_SET, characters || EMPTY_SET)(push);\n\t\t},\n\t\tcondition([condition]) {\n\t\t\tconst value = condition();\n\n\t\t\tif (!restoring) stack.value[0].push(['condition', String(value)], [null, 0]), render();\n\t\t},\n\t\tend() {\n\t\t\t/**\n\t\t\t * Clear the Scene\n\t\t\t */\n\t\t\tmatch('clear', []);\n\t\t\t/**\n\t\t\t * Go to the main menu\n\t\t\t */\n\t\t\trenderer.ui.showScreen('mainmenu');\n\t\t\t/**\n\t\t\t * Reset interactive value\n\t\t\t */\n\t\t\tinteractivity(false);\n\t\t\t/**\n\t\t\t * Reset session times\n\t\t\t */\n\t\t\ttimes.clear();\n\t\t},\n\t\tinput([question, onInput, setup]) {\n\t\t\trenderer.input(unwrap(question), onInput, setup)(forward);\n\t\t},\n\t\tcustom([handler]) {\n\t\t\tconst result = renderer.custom(handler, goingBack, () => {\n\t\t\t\tif (!restoring && handler.requireUserAction) enmemory(), interactivity(true);\n\t\t\t\tif (!restoring) push();\n\t\t\t});\n\n\t\t\treturn result;\n\t\t},\n\t\tvibrate(pattern) {\n\t\t\tvibrate(pattern);\n\t\t\tpush();\n\t\t},\n\t\tnext() {\n\t\t\tpush();\n\t\t},\n\t\tanimateCharacter([character, timeout, ...classes]) {\n\t\t\tconst handler: CustomHandler = (get) => {\n\t\t\t\tconst { clear } = get('@@internal-animate-character', false);\n\t\t\t\tconst char = renderer.store.characters[character];\n\n\t\t\t\t/**\n\t\t\t\t * Character is not defined, maybe, `animateCharacter` was called before `showCharacter`\n\t\t\t\t */\n\t\t\t\tif (!char) return;\n\n\t\t\t\tconst target = char.canvas;\n\n\t\t\t\t/**\n\t\t\t\t * Character is not found\n\t\t\t\t */\n\t\t\t\tif (!target) return;\n\n\t\t\t\tconst classNames = classes.filter((className) => !target.classList.contains(className));\n\n\t\t\t\ttarget.classList.add(...classNames);\n\n\t\t\t\tconst timeoutId = setTimeout(() => {\n\t\t\t\t\ttarget.classList.remove(...classNames);\n\t\t\t\t}, timeout);\n\n\t\t\t\tclear(() => {\n\t\t\t\t\ttarget.classList.remove(...classNames);\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Clear timeout, because when you will game re-runs some callback might remove classes from character\n\t\t\t\t\t */\n\t\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\t});\n\t\t\t};\n\n\t\t\t/**\n\t\t\t * `callOnlyLatest` property will not have any effect, because `custom` is called directly\n\t\t\t */\n\t\t\tmatch('custom', [handler]);\n\t\t},\n\t\ttext(text) {\n\t\t\trenderer.text(text.map((content) => unwrap(content)).join(' '), forward);\n\t\t},\n\t\texit() {\n\t\t\tconst path = stack.value[0];\n\n\t\t\tlet exited = false;\n\n\t\t\tfor (let i = path.length - 1; i > 0; i--) {\n\t\t\t\tif (path[i][0] !== 'choice' && path[i][0] !== 'condition') continue;\n\n\t\t\t\texited = true;\n\t\t\t\tstack.value[0] = path.slice(0, i);\n\t\t\t\tnext();\n\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Run render only when exit was performed. This prevents infinite loop of `render` -> `undefined` -> `exit` -> `render`.\n\t\t\t */\n\t\t\tif (exited) render();\n\t\t},\n\t});\n\n\tconst enmemory = () => {\n\t\tif (restoring) return;\n\n\t\tconst current = klona(stack.value);\n\n\t\tcurrent[2][1] = 'auto';\n\n\t\tstack.push(current);\n\n\t\tsave(true, 'auto');\n\t};\n\n\tconst next = () => {\n\t\tconst path = stack.value[0];\n\t\t/**\n\t\t * Последний элемент пути\n\t\t */\n\t\tconst last = path[path.length - 1]!;\n\n\t\t/**\n\t\t * Если он вида `[null, int]` - увеличивает `int`\n\t\t */\n\t\tif (isNull(last[0]) && isNumber(last[1])) {\n\t\t\tlast[1] = last[1] + 1;\n\t\t\treturn;\n\t\t}\n\n\t\t/**\n\t\t * Иначе добавляет новое `[null int]`\n\t\t */\n\t\tpath.push([null, 0]);\n\t};\n\n\tconst render = () => {\n\t\tconst referred = refer();\n\n\t\tif (Array.isArray(referred)) {\n\t\t\tconst [action, ...props] = referred;\n\n\t\t\tmatch(action, props);\n\t\t} else {\n\t\t\tmatch('exit', []);\n\t\t}\n\t};\n\n\tconst push = () => {\n\t\tif (!restoring) next(), render();\n\t};\n\n\tconst forward = () => {\n\t\tenmemory();\n\t\tpush();\n\t\tinteractivity(true);\n\t};\n\n\tconst interactivity = (value = false) => {\n\t\tinteracted = value;\n\t};\n\n\t/**\n\t * Unwraps translatable content to string\n\t *\n\t * @example ```\n\t * unwrap(t('Hello'));\n\t * unwrap({ en: 'Hello', ru: 'Привет' });\n\t * unwrap({ en: () => data().ad_viewed ? 'Diamond Hat' : 'Diamond Hat (Watch Adv)' })\n\t * unwrap('Hello, {{name}}');\n\t * ```\n\t */\n\tconst unwrap = (content: Unwrappable, global = false) => {\n\t\tconst {\n\t\t\tdata,\n\t\t\tmeta: [lang],\n\t\t} = $.get();\n\n\t\tconst obj = global ? data : state();\n\t\tconst cnt = isFunction(content) ? content(lang, obj) : typeof content === 'string' ? content : content[lang];\n\n\t\tconst str = isFunction(cnt) ? cnt() : cnt;\n\n\t\treturn replaceT9N(str, obj);\n\t};\n\n\tfunction data(value: DeepPartial<DataScheme> | ((prev: DataScheme) => DataScheme)): void;\n\tfunction data(): DataScheme;\n\tfunction data(value?: DeepPartial<DataScheme> | ((prev: DataScheme) => DataScheme)): DataScheme | void {\n\t\tif (!value) return $.get().data as DataScheme | void;\n\n\t\tconst prev = $.get().data;\n\t\tconst val = isFunction(value) ? value(prev as DataScheme) : deepmerge([prev, value]);\n\n\t\t$.update((prev) => {\n\t\t\tprev.data = val;\n\n\t\t\treturn prev;\n\t\t});\n\t}\n\n\treturn {\n\t\t/**\n\t\t * Function to set story\n\t\t */\n\t\twithStory,\n\t\t/**\n\t\t * Function to get actions\n\t\t */\n\t\taction,\n\t\t/**\n\t\t * State that belongs to games\n\t\t */\n\t\tstate,\n\t\t/**\n\t\t * Unlike `state`, stored at global scope instead and shared between games\n\t\t */\n\t\tdata,\n\t\t/**\n\t\t * Unwraps translatable content to a string value\n\t\t */\n\t\tunwrap(content: Exclude<Unwrappable, Record<string, string>> | Record<Languages, string>) {\n\t\t\treturn unwrap(content, true);\n\t\t},\n\t\t/**\n\t\t * Function that is used for translation\n\t\t */\n\t\tt: t9n.t as Inter['t'],\n\t};\n};\n\nexport { novely };\n","const SKIPPED_DURING_RESTORE = new Set(['dialog', 'choice', 'input', 'vibrate', 'text'] as const);\n\nconst EMPTY_SET = new Set<any>();\n\nexport { SKIPPED_DURING_RESTORE, EMPTY_SET };\n","import type { StorageData } from './types';\n\ninterface LocalStorageStorageSettings {\n\tkey: string;\n}\n\ninterface Storage {\n\tget: () => Promise<StorageData>;\n\tset: (data: StorageData) => Promise<void>;\n}\n\nconst localStorageStorage = (options: LocalStorageStorageSettings): Storage => {\n\treturn {\n\t\tasync get() {\n\t\t\tconst value = localStorage.getItem(options.key);\n\n\t\t\treturn value ? JSON.parse(value) : { saves: [], data: {}, meta: [] };\n\t\t},\n\t\tasync set(data) {\n\t\t\tlocalStorage.setItem(options.key, JSON.stringify(data));\n\t\t},\n\t};\n};\n\nexport type { Storage };\nexport { localStorageStorage };\n"],"mappings":";AAcA,IAAM,cAAc,CAAmC,WAAc;AACpE,SAAO,CAAC,QAA8B,UAAe;AACpD,WAAO,OAAO,MAAM,EAAE,KAAK;AAAA,EAC5B;AACD;AAEA,IAAM,WAAW,CAAC,QAAgC;AACjD,SAAO,OAAO,QAAQ;AACvB;AAEA,IAAM,SAAS,CAAC,QAA8B;AAC7C,SAAO,QAAQ;AAChB;AAEA,IAAM,WAAW,CAAC,QAAgC;AACjD,SAAO,OAAO,QAAQ;AACvB;AAEA,IAAM,aAAa,CAAC,QAAuD;AAC1E,SAAO,OAAO,QAAQ;AACvB;AAEA,IAAM,YAAY,CAAC,QAAsC;AACxD,SAAO,QAAQ,GAAG,MAAM,OAAO,QAAQ,YAAY,WAAW,GAAG,MAAM,WAAY,IAAY,IAAI;AACpG;AAEA,IAAM,UAAU,CAAC,QAA4B;AAC5C,SAAO,OAAO,QAAQ,YAAY,CAAC,OAAO,GAAG,KAAK,OAAO,KAAK,GAAG,EAAE,WAAW;AAC/E;AAQA,IAAM,MAAM,CAAC,UAAmB;AAC/B,SAAO,OAAO,KAAK;AACpB;AAEA,IAAM,uBAAuB,CAC5B,QACA,SACI;AACJ,SAAO,WAAW,YAAY,KAAK,CAAC,KAAM,KAAK,CAAC,EAA+B;AAChF;AAEA,IAAM,qBAAqB,MAAuB;AACjD,SAAO;AACR;AAEA,IAAM,cAAc,CAAC,WAAqB,MAAW;AACpD,MAAI,EAAE,SAAS,IAAI;AAEnB,MAAI,UAAU,SAAS,QAAQ,GAAG;AACjC,WAAO;AAAA,EACR,WAAW,UAAU,SAAU,WAAW,SAAS,UAAU,GAAG,CAAC,CAAE,GAAG;AACrE,WAAO;AAAA,EACR,WAAY,WAAW,UAAU,KAAK,CAAC,UAAU,UAAU,UAAU,SAAS,KAAK,CAAC,GAAK;AACxF,WAAO;AAAA,EACR;AAKA,SAAO,UAAU,CAAC;AACnB;AAMA,IAAM,WAAW,CAAqC,IAAQ,OAAe;AAC5E,MAAI,YAAY,OACf,WACA;AAED,WAAS,UAAmB;AAC3B,QAAI,WAAW;AACd,kBAAY;AACZ,kBAAY;AACZ;AAAA,IACD;AAEA,OAAG,MAAM,MAAM,SAA6B;AAE5C,gBAAY;AAEZ,eAAW,WAAY;AACtB,kBAAY;AAEZ,UAAI,WAAW;AACd,gBAAQ,MAAM,WAAW,SAAS;AAClC,oBAAY,YAAY;AAAA,MACzB;AAAA,IACD,GAAG,EAAE;AAAA,EACN;AAEA,SAAO;AACR;AAEA,IAAM,UAAU,CAAC,YAA4B;AAC5C,MAAI;AACH,QAAI,aAAa,WAAW;AAC3B,gBAAU,QAAQ,OAAO;AAAA,IAC1B;AAAA,EACD,QAAE;AAAA,EAAO;AACV;AAEA,IAAM,gBAAgB,CAAI,OAAY,OAA6B;AAClE,WAAS,IAAI,MAAM,SAAS,GAAG,IAAI,GAAG,KAAK;AAC1C,QAAI,GAAG,MAAM,CAAC,CAAC,GAAG;AACjB,aAAO;AAAA,IACR;AAAA,EACD;AAEA,SAAO;AACR;;;AC7HA,IAAM,QAAQ,CAAI,SAAY,cAAc,oBAAI,IAAwB,MAAiB;AACxF,QAAM,YAAY,CAAC,OAA2B;AAC7C,gBAAY,IAAI,EAAE,GAAG,GAAG,OAAO;AAE/B,WAAO,MAAM;AACZ,kBAAY,OAAO,EAAE;AAAA,IACtB;AAAA,EACD;AAEA,QAAM,OAAO,CAAC,UAAa;AAC1B,gBAAY,QAAQ,CAAC,OAAO,GAAG,KAAK,CAAC;AAAA,EACtC;AAEA,QAAM,SAAS,CAAC,OAAuB;AACtC,SAAM,UAAU,GAAG,OAAO,CAAE;AAAA,EAC7B;AAEA,QAAM,MAAM,MAAM;AACjB,WAAO;AAAA,EACR;AAEA,SAAO,EAAE,WAAW,QAAQ,IAAI;AACjC;;;ACEA,SAAS,OAAO,iBAAiB;AACjC,SAAS,aAAa;;;AC/BtB,IAAM,yBAAyB,oBAAI,IAAI,CAAC,UAAU,UAAU,SAAS,WAAW,MAAM,CAAU;AAEhG,IAAM,YAAY,oBAAI,IAAS;;;AD+B/B,SAAS,WAAW,kBAAkB;AAoFtC,IAAM,SAAS,CAMb;AAAA,EACD;AAAA,EACA;AAAA,EACA,eAAe,QAAQ,QAAQ;AAAA,EAC/B,UAAU;AAAA,EACV,gBAAgB;AAAA,EAChB;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,MAAM;AAAA,EACN,YAAY;AAAA,EACZ,aAAa,CAAC;AAAA,EACd,kBAAkB;AAAA,EAClB,aAAAA,eAAc;AAAA,EACd,mBAAmB;AAAA,EACnB,gBAAgB;AACjB,MAAyE;AACxE,MAAI;AACJ,MAAI,QAAQ,oBAAI,IAAY;AAK5B,kBAAgB,CAAC;AACjB,mBAAiB,CAAC;AAKlB,QAAM,SAAS,CAAC,UAAkB;AACjC,WAAO,MAAM,IAAI,KAAK,GAAG;AAAA,EAC1B;AAEA,QAAM,YAAY,CAAC,MAAa;AAI/B,YAAQ,OAAO;AAAA,MACd,OAAO,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM;AACxC,cAAM,OAAO,CAAC,SAAyD;AACtE,iBAAO,KAAK,QAAQ,CAACC,UAAS;AAC7B,kBAAM,OAAOA,MAAK,CAAC;AAKnB,gBAAI,MAAM,QAAQ,IAAI;AAAG,qBAAO,KAAKA,KAAqB;AAE1D,mBAAO,CAACA,KAAmB;AAAA,UAC5B,CAAC;AAAA,QACF;AAEA,eAAO,CAAC,MAAM,KAAK,KAAK,CAAC;AAAA,MAC1B,CAAC;AAAA,IACF;AAKA,QAAI,kBAAkB;AAAQ,eAAS,GAAG,WAAW,aAAa;AAAA,EACnE;AAEA,QAAM,SAAS,IAAI,MAAM,CAAC,GAAsC;AAAA,IAC/D,IAAI,GAAG,MAAM;AACZ,aAAO,IACH,UAGC;AACJ,eAAO,CAAC,MAAM,GAAG,KAAK;AAAA,MACvB;AAAA,IACD;AAAA,EACD,CAAC;AAID,WAAS,MAAM,OAA6F;AAC3G,QAAI,CAAC;AAAO,aAAO,MAAM,MAAM,CAAC;AAEhC,UAAM,OAAO,MAAM,MAAM,CAAC;AAC1B,UAAM,MAAM,WAAW,KAAK,IAAI,MAAM,IAAmB,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;AAEpF,UAAM,MAAM,CAAC,IAAI;AAAA,EAClB;AAEA,QAAM,iBAAiB,CAACC,SAAQ,CAAC,MAAM;AACtC,WAAO;AAAA,MACN;AAAA,QACC,CAAC,MAAM,OAAO;AAAA,QACd,CAAC,MAAM,CAAC;AAAA,MACT;AAAA,MACAA;AAAA,MACA,CAAC,OAAO,KAAK,IAAI,CAAC,GAAG,MAAM;AAAA,IAC5B;AAAA,EACD;AAEA,QAAM,cAAc,CAAC,SAAeC,SAAQ,CAAC,OAAO,MAAM;AACzD,WAAO;AAAA,MACN,IAAI,QAAQ;AACX,eAAOA,OAAM,GAAG,EAAE;AAAA,MACnB;AAAA,MACA,IAAI,MAAM,OAAa;AACtB,QAAAA,OAAMA,OAAM,SAAS,CAAC,IAAI;AAAA,MAC3B;AAAA,MACA,OAAO;AACN,YAAIA,OAAM,SAAS;AAAG,UAAAA,OAAM,IAAI,GAAI,YAAY;AAAA,MACjD;AAAA,MACA,KAAK,OAAa;AACjB,QAAAA,OAAM,KAAK,KAAK;AAAA,MACjB;AAAA,MACA,QAAQ;AACP,QAAAA,SAAQ,CAAC,eAAe,MAAM,YAAY,CAAC,CAAC;AAAA,MAC7C;AAAA,IACD;AAAA,EACD;AAEA,QAAM,+BAA+B,MAAM;AAC1C,WAAOH,aAAY,WAAW,WAAkB;AAAA,EACjD;AAMA,QAAM,cAA2B;AAAA,IAChC,OAAO,CAAC;AAAA,IACR,MAAM,MAAM,WAAW;AAAA,IACvB,MAAM,CAAC,6BAA6B,GAAG,mBAAmB,CAAC;AAAA,EAC5D;AAEA,QAAM,IAAI,MAAM,WAAW;AAE3B,MAAI,oBAAoB;AAExB,QAAM,sBAAsB,CAAC,UAAuB;AACnD,QAAI;AAAmB,cAAQ,IAAI,KAAK;AAAA,EACzC;AAEA,QAAM,+BAA+B,SAAS,qBAAqB,eAAe;AAElF,IAAE,UAAU,4BAA4B;AAExC,QAAM,gBAAgB,MAAM;AAC3B,YAAQ,IAAI,EAAE,KAAK,CAAC,WAAW;AAI9B,iBAAW,aAAa,YAAY;AAEnC,iBAAS,UAAU,MAAM;AAAA,MAC1B;AAKA,aAAO,KAAK,CAAC,MAAM,mBAAmB;AAKtC,UAAI,kBAAkB;AACrB,eAAO,KAAK,CAAC,IAAI,6BAA6B;AAAA,MAC/C,OAAO;AACN,eAAO,KAAK,CAAC,MAAM,6BAA6B;AAAA,MACjD;AAMA,UAAI,QAAQ,OAAO,IAAI,GAAG;AACzB,eAAO,OAAO;AAAA,MACf;AAKA,0BAAoB;AAEpB,QAAE,OAAO,MAAM,MAAM;AAKrB,UAAI,kBAAkB;AAAQ,gBAAQ;AAAA,IACvC,CAAC;AAAA,EACF;AAMA,eAAa,KAAK,aAAa;AAE/B,QAAM,UAAU,eAAe,MAAM,YAAY,CAAC;AAClD,QAAM,QAAQ,YAAY,OAAO;AAEjC,QAAM,OAAO,CAAC,WAAW,OAAO,OAAmB,WAAW,SAAS,aAAa;AACnF,QAAI,CAAC;AAAmB;AAKxB,QAAI,CAAC,aAAa,SAAS;AAAQ;AAEnC,UAAM,UAAU,MAAM,MAAM,KAAK;AAEjC,MAAE,OAAO,CAAC,SAAS;AAWlB,YAAM,WAAW,cAAc,KAAK,OAAO,CAAC,UAAU,MAAM,IAAI,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,SAAS;AAKtG,cAAQ,CAAC,EAAE,CAAC,IAAI,OAAO,KAAK,IAAI,CAAC;AACjC,cAAQ,CAAC,EAAE,CAAC,IAAI;AAEhB,UAAI,CAAC,YAAY,CAAC,UAAU;AAC3B,aAAK,MAAM,KAAK,OAAO;AAEvB,eAAO;AAAA,MACR;AAKA,YAAM,SAAS,KAAK,MAAM,GAAG,EAAE;AAK/B,UAAI,UAAU,OAAO,CAAC,EAAE,CAAC,MAAM,MAAM;AACpC,aAAK,MAAM,KAAK,MAAM,SAAS,CAAC,IAAI;AAAA,MACrC,OAAO;AACN,aAAK,MAAM,KAAK,OAAO;AAAA,MACxB;AAEA,aAAO;AAAA,IACR,CAAC;AAAA,EACF;AAEA,QAAM,UAAU,MAAM;AACrB,QAAI,CAAC;AAAmB;AAExB,UAAMI,QAAO,eAAe,MAAM,YAAY,CAAC;AAK/C,QAAI,WAAW;AACd,QAAE,OAAO,CAAC,SAAS;AAClB,eAAO,KAAK,MAAM,KAAKA,KAAI,GAAG;AAAA,MAC/B,CAAC;AAAA,IACF;AAEA,YAAQA,KAAI;AAAA,EACb;AAKA,QAAM,MAAM,CAACA,UAAe;AAC3B,UAAM,QAAQA;AAEd,WAAO,QAAQA,KAAI;AAAA,EACpB;AAEA,MAAI,YAAY;AAChB,MAAI,YAAY;AAChB,MAAI,aAAa;AAKjB,QAAM,UAAU,OAAOA,UAAgB;AACtC,QAAI,CAAC;AAAmB;AAExB,QAAI,SAASA,QAAOA,QAAO,EAAE,IAAI,EAAE,MAAM,GAAG,EAAE;AAK9C,QAAI,CAAC,QAAQ;AACZ,QAAE,OAAO,OAAO;AAAA,QACf,OAAO,CAAC,OAAO;AAAA,QACf,MAAM,MAAM,WAAW;AAAA,QACvB,MAAM,CAAC,6BAA6B,GAAG,mBAAmB,CAAC;AAAA,MAC5D,EAAE;AAEF,eAAS,MAAM,OAAO;AAAA,IACvB;AAEA,IAAC,YAAY,MAAQ,MAAM,QAAQ;AAKnC,QAAI,UAAe;AAInB,QAAI,QAAQ;AAKZ,UAAM,MAAM,MAAM,MAAM,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,GAAG,MAAM;AACvD,UAAI,OAAO,IAAI,KAAK,SAAS,GAAG;AAAG,eAAO,MAAM;AAEhD,aAAO;AAAA,IACR,GAAG,CAAC;AAEJ,UAAM,QAAQ,CAAC;AACf,UAAM,OAAO,oBAAI,IAAI;AACrB,UAAMC,cAAa,oBAAI,IAAI;AAE3B,eAAW,CAAC,MAAM,GAAG,KAAK,MAAM,MAAM,CAAC,GAAG;AACzC,UAAI,SAAS,MAAM;AAClB,YAAI,SAAS,GAAG,GAAG;AAClB,oBAAU,QAAQ,GAAG;AAAA,QACtB,WAAW,SAAS,GAAG,GAAG;AACzB;AAMA,mBAAS,IAAI,GAAG,KAAK,KAAK,KAAK;AAC9B,kBAAM,CAACC,SAAQ,GAAG,IAAI,IAAI,QAAQ,CAAC;AAKnC,kBAAMC,QAAO,MAAM;AAClB,mBAAK,IAAID,OAAM;AACf,oBAAM,KAAK,CAACA,SAAQ,IAAI,CAAC;AAAA,YAC1B;AAKA,gBAAIA,YAAW;AAAiB,cAAAD,YAAW,IAAI,KAAK,CAAC,CAAC;AAMtD,gBAAI,uBAAuB,IAAIC,OAAM,KAAK,qBAAqBA,SAAQ,IAAI,GAAG;AAC7E,kBAAI,UAAU,OAAO,MAAM,KAAK;AAC/B,gBAAAC,MAAK;AAAA,cACN,OAAO;AACN;AAAA,cACD;AAAA,YACD;AAEA,YAAAA,MAAK;AAAA,UACN;AAEA,oBAAU,QAAQ,GAAG;AAAA,QACtB;AAAA,MACD,WAAW,SAAS,UAAU;AAC7B,kBAAU,QAAS,MAAiB,CAAC,EAAE,CAAC;AAAA,MACzC,WAAW,SAAS,aAAa;AAChC,kBAAU,QAAQ,CAAC,EAAE,GAAG;AAAA,MACzB;AAAA,IACD;AAEA,UAAM,QAAQ,CAAC,OAAOC,WAAU;AAI/B,YAAM,KAAKA,MAAK;AAAA,IACjB,CAAC;AAKD,UAAM,eAAe;AAKrB,aAAS,GAAG,WAAW,MAAM;AAI7B,UAAM,SAAS,CAAC,MAAMH,WAAU,CAAC;AAKjC,UAAMI,QAAO,CAAC,MAAc,aAAa,MAAM,IAAI,CAAC;AAEpD,qBAAiB,CAACH,SAAQ,MAAM,CAAC,KAAK,cAAc;AACnD,UAAIA,YAAW,cAAcA,YAAW,UAAU;AAIjD,YAAIA,YAAW,YAAa,KAAuC,CAAC,EAAE,gBAAgB;AAIrF,gBAAM,YAAYG,MAAK,CAAC,EAAE,KAAK,CAAC,CAAC,SAAS,KAAK,MAAM;AACpD,gBAAI,CAAC,SAAS,CAAC;AAAM,qBAAO;AAE5B,kBAAM,KAAK,MAAM,CAAC;AAClB,kBAAM,KAAK,KAAK,CAAC;AAKjB,kBAAM,gBAAgB,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG;AAKrD,mBAAO,iBAAiB,IAAI,EAAE,MAAM,IAAI,EAAE;AAAA,UAC3C,CAAC;AAED,cAAI;AAAW;AAAA,QAChB;AAKA,cAAM,SAAS,MAAMH,SAAQ,IAAI;AAKjC,YAAI,UAAU,MAAM,GAAG;AAItB,gBAAM;AAAA,QACP;AAAA,MACD,WAAWA,YAAW,iBAAiB;AACtC,cAAM,OAAOG,MAAK,CAAC,EAAE,KAAK,CAAC,CAAC,SAAS,KAAK,MAAM;AAI/C,cAAI,CAAC,SAAS,CAAC;AAAM,mBAAO;AAM5B,gBAAM,SAAS,YAAY,mBAAmB,MAAM,CAAC,MAAM,KAAK,CAAC;AAKjE,gBAAM,YAAY,YAAYH,WAAU,MAAM,CAAC,MAAM,KAAK,CAAC;AAE3D,iBAAO,UAAU;AAAA,QAClB,CAAC;AAED,YAAI;AAAM;AAEV,cAAMA,SAAQ,IAAI;AAAA,MACnB,WAAWA,YAAW,oBAAoBA,YAAW,oBAAoB;AAKxE,cAAM,YAAYG,MAAK,CAAC,EAAE,KAAK,CAAC,CAAC,OAAO,MAAMH,YAAW,OAAO;AAEhE,YAAI;AAAW;AAEf,cAAMA,SAAQ,IAAI;AAAA,MACnB,OAAO;AACN,cAAMA,SAAQ,IAAI;AAAA,MACnB;AAAA,IACD;AAEA,IAAC,YAAY,YAAY,OAAQ,OAAO;AAAA,EACzC;AAEA,QAAM,QAAQ,MAAM;AACnB,QAAI,UAAe;AAEnB,eAAW,CAAC,MAAM,GAAG,KAAK,MAAM,MAAM,CAAC,GAAG;AACzC,UAAI,SAAS,MAAM;AAClB,kBAAU,QAAQ,GAAG;AAAA,MACtB,WAAW,SAAS,UAAU;AAC7B,kBAAU,QAAS,MAAiB,CAAC,EAAE,CAAC;AAAA,MACzC,WAAW,SAAS,aAAa;AAChC,kBAAU,QAAQ,CAAC,EAAE,GAAG;AAAA,MACzB;AAAA,IACD;AAEA,WAAO;AAAA,EACR;AAMA,QAAM,OAAO,CAAC,QAAQ,UAAU;AAC/B,QAAI,cAAc,CAAC,SAAS,eAAe;AAC1C,eAAS,GAAG,eAAe;AAC3B;AAAA,IACD;AAEA,UAAM,UAAU,MAAM;AAEtB,UAAM,MAAM;AACZ,aAAS,GAAG,WAAW,UAAU;AAKjC,UAAM,CAAC,CAAC,OAAO,MAAM,GAAG,EAAE,CAAC,MAAM,IAAI,CAAC,IAAI;AAE1C,QAAI,SAAS,UAAU,SAAS,QAAQ;AAIvC,UAAI,CAAC,cAAc,MAAM,IAAI,IAAI,GAAG;AACnC,UAAE,OAAO,CAAC,SAAS;AAClB,eAAK,QAAQ,KAAK,MAAM,OAAO,CAACF,UAASA,UAAS,OAAO;AAEzD,iBAAO;AAAA,QACR,CAAC;AAAA,MACF;AAAA,IACD;AAKA,kBAAc,KAAK;AAInB,UAAM,MAAM;AAAA,EACb;AAEA,QAAM,OAAO,MAAM;AAClB,WAAO,MAAM,KAAK,GAAG,QAAQ,MAAM,KAAK;AAAA,EACzC;AAEA,QAAM,WAAW,eAAe;AAAA,IAC/B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG,IAAI;AAAA,IACP;AAAA,EACD,CAAC;AAED,QAAM,QAAQ,YAAY;AAAA,IACzB,KAAK,CAAC,IAAI,GAAG;AACZ,UAAI,CAAC;AAAW,mBAAW,MAAM,WAAW,IAAI,IAAI,KAAK,IAAI,IAAI;AAAA,IAClE;AAAA,IACA,eAAe,CAAC,UAAU,GAAG;AAC5B,eAAS,WAAW,UAAU;AAC9B,WAAK;AAAA,IACN;AAAA,IACA,UAAU,CAAC,MAAM,GAAG;AACnB,eAAS,MAAM,QAAQ,OAAO,EAAE,KAAK;AACrC,WAAK;AAAA,IACN;AAAA,IACA,UAAU,CAAC,MAAM,GAAG;AACnB,eAAS,MAAM,QAAQ,OAAO,EAAE,KAAK;AACrC,WAAK;AAAA,IACN;AAAA,IACA,cAAc,CAAC,WAAW,SAAS,WAAW,KAAK,GAAG;AACrD,YAAM,SAAS,SAAS,UAAU,SAAS;AAE3C,aAAO,OAAO,WAAW,OAAO,SAAS;AACzC,aAAO,YAAY,OAAO,EAAE;AAE5B,WAAK;AAAA,IACN;AAAA,IACA,cAAc,CAAC,WAAW,WAAW,OAAO,QAAQ,GAAG;AACtD,eAAS,UAAU,SAAS,EAAE,OAAO,WAAW,OAAO,QAAQ,EAAE,MAAM,SAAS;AAAA,IACjF;AAAA,IACA,OAAO,CAAC,WAAW,SAAS,OAAO,GAAG;AAIrC,YAAM,QAAQ,MAAM;AACnB,cAAM,IAAI,WACT,KAAK;AACN,cAAM,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC;AAE3B,eAAO,IACJ,KAAK,KACJ,OAAO,GAAG,CAAC,EAAE,SAAS,WACpB,GAAG,CAAC,EAAE,OACN,GAAG,CAAC,EAAE,KAAgC,IAAI,IAC5C,IACD;AAAA,MACJ,GAAG;AAEH,eAAS,OAAO,OAAO,OAAO,GAAG,OAAO,IAAI,GAAG,WAAW,OAAO,EAAE,OAAO;AAAA,IAC3E;AAAA,IACA,SAAS,CAAC,EAAE,GAAG;AACd,YAAM,SAAS,GAAG,WAAW,SAAS;AAEtC,UAAI,CAAC;AAAW,iBAAS,OAAO,KAAK,IAAI,IAAI,KAAK;AAElD,aAAO;AAAA,IACR;AAAA,IACA,OAAO,CAAC,UAAU,GAAG,OAAO,GAAG;AAC9B,YAAM,oBAAoB,MAAM,QAAQ,QAAQ;AAEhD,UAAI,mBAAmB;AAItB,gBAAQ,QAAQ,QAAkE;AAIlF,mBAAW;AAAA,MACZ;AAEA,YAAM,YAAY,QAAQ,IAAI,CAAC,CAAC,SAASE,SAAQ,OAAO,MAAM;AAC7D,eAAO,CAAC,OAAO,OAAO,GAAGA,SAAQ,OAAO;AAAA,MACzC,CAAC;AAED,eAAS;AAAA,QACR,OAAO,QAAQ;AAAA,QACf;AAAA,MACD,EAAE,CAAC,aAAa;AACf,iBAAS;AAKT,cAAM,SAAS,oBAAoB,IAAI;AAEvC,cAAM,MAAM,CAAC,EAAE,KAAK,CAAC,UAAU,WAAW,MAAM,GAAG,CAAC,MAAM,CAAC,CAAC;AAC5D,eAAO;AACP,sBAAc,IAAI;AAAA,MACnB,CAAC;AAAA,IACF;AAAA,IACA,KAAK,CAAC,KAAK,GAAG;AAIb,YAAM,MAAM,CAAC,IAAI;AAAA,QAChB,CAAC,MAAM,KAAK;AAAA,QACZ,CAAC,MAAM,EAAE;AAAA,MACV;AAEA,YAAM,SAAS,CAAC,CAAC;AAAA,IAClB;AAAA,IACA,MAAM,CAAC,MAAMD,WAAU,GAAG;AAIzB,cAAQ,CAAC;AAIT,eAAS,MAAM,WAAW,QAAQ,WAAWA,eAAc,SAAS,EAAE,IAAI;AAAA,IAC3E;AAAA,IACA,UAAU,CAAC,SAAS,GAAG;AACtB,YAAM,QAAQ,UAAU;AAExB,UAAI,CAAC;AAAW,cAAM,MAAM,CAAC,EAAE,KAAK,CAAC,aAAa,OAAO,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,OAAO;AAAA,IACtF;AAAA,IACA,MAAM;AAIL,YAAM,SAAS,CAAC,CAAC;AAIjB,eAAS,GAAG,WAAW,UAAU;AAIjC,oBAAc,KAAK;AAInB,YAAM,MAAM;AAAA,IACb;AAAA,IACA,MAAM,CAAC,UAAU,SAAS,KAAK,GAAG;AACjC,eAAS,MAAM,OAAO,QAAQ,GAAG,SAAS,KAAK,EAAE,OAAO;AAAA,IACzD;AAAA,IACA,OAAO,CAAC,OAAO,GAAG;AACjB,YAAM,SAAS,SAAS,OAAO,SAAS,WAAW,MAAM;AACxD,YAAI,CAAC,aAAa,QAAQ;AAAmB,mBAAS,GAAG,cAAc,IAAI;AAC3E,YAAI,CAAC;AAAW,eAAK;AAAA,MACtB,CAAC;AAED,aAAO;AAAA,IACR;AAAA,IACA,QAAQ,SAAS;AAChB,cAAQ,OAAO;AACf,WAAK;AAAA,IACN;AAAA,IACA,OAAO;AACN,WAAK;AAAA,IACN;AAAA,IACA,iBAAiB,CAAC,WAAW,SAAS,GAAG,OAAO,GAAG;AAClD,YAAM,UAAyB,CAAC,QAAQ;AACvC,cAAM,EAAE,MAAM,IAAI,IAAI,gCAAgC,KAAK;AAC3D,cAAM,OAAO,SAAS,MAAM,WAAW,SAAS;AAKhD,YAAI,CAAC;AAAM;AAEX,cAAM,SAAS,KAAK;AAKpB,YAAI,CAAC;AAAQ;AAEb,cAAM,aAAa,QAAQ,OAAO,CAAC,cAAc,CAAC,OAAO,UAAU,SAAS,SAAS,CAAC;AAEtF,eAAO,UAAU,IAAI,GAAG,UAAU;AAElC,cAAM,YAAY,WAAW,MAAM;AAClC,iBAAO,UAAU,OAAO,GAAG,UAAU;AAAA,QACtC,GAAG,OAAO;AAEV,cAAM,MAAM;AACX,iBAAO,UAAU,OAAO,GAAG,UAAU;AAKrC,uBAAa,SAAS;AAAA,QACvB,CAAC;AAAA,MACF;AAKA,YAAM,UAAU,CAAC,OAAO,CAAC;AAAA,IAC1B;AAAA,IACA,KAAK,MAAM;AACV,eAAS,KAAK,KAAK,IAAI,CAAC,YAAY,OAAO,OAAO,CAAC,EAAE,KAAK,GAAG,GAAG,OAAO;AAAA,IACxE;AAAA,IACA,OAAO;AACN,YAAM,OAAO,MAAM,MAAM,CAAC;AAE1B,UAAI,SAAS;AAEb,eAAS,IAAI,KAAK,SAAS,GAAG,IAAI,GAAG,KAAK;AACzC,YAAI,KAAK,CAAC,EAAE,CAAC,MAAM,YAAY,KAAK,CAAC,EAAE,CAAC,MAAM;AAAa;AAE3D,iBAAS;AACT,cAAM,MAAM,CAAC,IAAI,KAAK,MAAM,GAAG,CAAC;AAChC,aAAK;AAEL;AAAA,MACD;AAKA,UAAI;AAAQ,eAAO;AAAA,IACpB;AAAA,EACD,CAAC;AAED,QAAM,WAAW,MAAM;AACtB,QAAI;AAAW;AAEf,UAAM,UAAU,MAAM,MAAM,KAAK;AAEjC,YAAQ,CAAC,EAAE,CAAC,IAAI;AAEhB,UAAM,KAAK,OAAO;AAElB,SAAK,MAAM,MAAM;AAAA,EAClB;AAEA,QAAM,OAAO,MAAM;AAClB,UAAM,OAAO,MAAM,MAAM,CAAC;AAI1B,UAAM,OAAO,KAAK,KAAK,SAAS,CAAC;AAKjC,QAAI,OAAO,KAAK,CAAC,CAAC,KAAK,SAAS,KAAK,CAAC,CAAC,GAAG;AACzC,WAAK,CAAC,IAAI,KAAK,CAAC,IAAI;AACpB;AAAA,IACD;AAKA,SAAK,KAAK,CAAC,MAAM,CAAC,CAAC;AAAA,EACpB;AAEA,QAAM,SAAS,MAAM;AACpB,UAAM,WAAW,MAAM;AAEvB,QAAI,MAAM,QAAQ,QAAQ,GAAG;AAC5B,YAAM,CAACC,SAAQ,GAAG,KAAK,IAAI;AAE3B,YAAMA,SAAQ,KAAK;AAAA,IACpB,OAAO;AACN,YAAM,QAAQ,CAAC,CAAC;AAAA,IACjB;AAAA,EACD;AAEA,QAAM,OAAO,MAAM;AAClB,QAAI,CAAC;AAAW,WAAK,GAAG,OAAO;AAAA,EAChC;AAEA,QAAM,UAAU,MAAM;AACrB,aAAS;AACT,SAAK;AACL,kBAAc,IAAI;AAAA,EACnB;AAEA,QAAM,gBAAgB,CAAC,QAAQ,UAAU;AACxC,iBAAa;AAAA,EACd;AAYA,QAAM,SAAS,CAAC,SAAsB,SAAS,UAAU;AACxD,UAAM;AAAA,MACL,MAAAL;AAAA,MACA,MAAM,CAAC,IAAI;AAAA,IACZ,IAAI,EAAE,IAAI;AAEV,UAAM,MAAM,SAASA,QAAO,MAAM;AAClC,UAAM,MAAM,WAAW,OAAO,IAAI,QAAQ,MAAM,GAAG,IAAI,OAAO,YAAY,WAAW,UAAU,QAAQ,IAAI;AAE3G,UAAMS,OAAM,WAAW,GAAG,IAAI,IAAI,IAAI;AAEtC,WAAO,WAAWA,MAAK,GAAG;AAAA,EAC3B;AAIA,WAAS,KAAK,OAAyF;AACtG,QAAI,CAAC;AAAO,aAAO,EAAE,IAAI,EAAE;AAE3B,UAAM,OAAO,EAAE,IAAI,EAAE;AACrB,UAAM,MAAM,WAAW,KAAK,IAAI,MAAM,IAAkB,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;AAEnF,MAAE,OAAO,CAACC,UAAS;AAClB,MAAAA,MAAK,OAAO;AAEZ,aAAOA;AAAA,IACR,CAAC;AAAA,EACF;AAEA,SAAO;AAAA;AAAA;AAAA;AAAA,IAIN;AAAA;AAAA;AAAA;AAAA,IAIA;AAAA;AAAA;AAAA;AAAA,IAIA;AAAA;AAAA;AAAA;AAAA,IAIA;AAAA;AAAA;AAAA;AAAA,IAIA,OAAO,SAAmF;AACzF,aAAO,OAAO,SAAS,IAAI;AAAA,IAC5B;AAAA;AAAA;AAAA;AAAA,IAIA,GAAG,IAAI;AAAA,EACR;AACD;;;AEz/BA,IAAM,sBAAsB,CAAC,YAAkD;AAC9E,SAAO;AAAA,IACN,MAAM,MAAM;AACX,YAAM,QAAQ,aAAa,QAAQ,QAAQ,GAAG;AAE9C,aAAO,QAAQ,KAAK,MAAM,KAAK,IAAI,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,GAAG,MAAM,CAAC,EAAE;AAAA,IACpE;AAAA,IACA,MAAM,IAAI,MAAM;AACf,mBAAa,QAAQ,QAAQ,KAAK,KAAK,UAAU,IAAI,CAAC;AAAA,IACvD;AAAA,EACD;AACD;","names":["getLanguage","data","state","stack","save","characters","action","push","index","next","str","prev"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils.ts","../src/global.ts","../src/store.ts","../src/novely.ts","../src/constants.ts","../src/storage.ts"],"sourcesContent":["import type { ActionProxyProvider, CustomHandler } from './action';\nimport type { Character } from './character';\nimport type { TypewriterSpeed, Thenable } from './types';\n\ntype MatchActionMap = {\n\t[Key in keyof ActionProxyProvider<Record<string, Character>>]: (\n\t\tdata: Parameters<ActionProxyProvider<Record<string, Character>>[Key]>,\n\t) => void;\n};\n\ntype MatchActionMapComplete = Omit<MatchActionMap, 'custom'> & {\n\tcustom: (value: [handler: CustomHandler]) => Thenable<void>;\n};\n\nconst matchAction = <M extends MatchActionMapComplete>(values: M) => {\n\treturn (action: keyof MatchActionMap, props: any) => {\n\t\treturn values[action](props);\n\t};\n};\n\nconst isNumber = (val: unknown): val is number => {\n\treturn typeof val === 'number';\n};\n\nconst isNull = (val: unknown): val is null => {\n\treturn val === null;\n};\n\nconst isString = (val: unknown): val is string => {\n\treturn typeof val === 'string';\n};\n\nconst isFunction = (val: unknown): val is (...parameters: any[]) => any => {\n\treturn typeof val === 'function';\n};\n\nconst isPromise = (val: unknown): val is Promise<any> => {\n\treturn Boolean(val) && (typeof val === 'object' || isFunction(val)) && isFunction((val as any).then);\n};\n\nconst isEmpty = (val: unknown): val is {} => {\n\treturn typeof val === 'object' && !isNull(val) && Object.keys(val).length === 0;\n};\n\nconst isCSSImage = (str: string) => {\n\tconst startsWith = String.prototype.startsWith.bind(str);\n\n\treturn startsWith('http') || startsWith('/') || startsWith('.') || startsWith('data');\n};\n\nconst str = (value: unknown) => {\n\treturn String(value);\n};\n\nconst isUserRequiredAction = (\n\taction: keyof MatchActionMapComplete,\n\tmeta: Parameters<MatchActionMapComplete[keyof MatchActionMapComplete]>,\n) => {\n\treturn action === 'custom' && meta[0] && (meta[0] as unknown as CustomHandler).requireUserAction;\n};\n\nconst getTypewriterSpeed = (): TypewriterSpeed => {\n\treturn 'Medium';\n};\n\nconst getLanguage = (languages: string[], _: any) => {\n\tlet { language } = navigator;\n\n\tif (languages.includes(language)) {\n\t\treturn language;\n\t} else if (languages.includes((language = language.substring(0, 2)))) {\n\t\treturn language;\n\t} else if ((language = languages.find((value) => navigator.languages.includes(value))!)) {\n\t\treturn language;\n\t}\n\n\t/**\n\t * We'v checked the `en-GB` format, `en` format, and maybe any second languages, but there were no matches\n\t */\n\treturn languages[0];\n};\n\n/**\n * @copyright Techlead LLC\n * @see https://learn.javascript.ru/task/throttle\n */\nconst throttle = <Fn extends (...args: any[]) => any>(fn: Fn, ms: number) => {\n\tlet throttled = false,\n\t\tsavedArgs: any,\n\t\tsavedThis: any;\n\n\tfunction wrapper(this: any) {\n\t\tif (throttled) {\n\t\t\tsavedArgs = arguments;\n\t\t\tsavedThis = this;\n\t\t\treturn;\n\t\t}\n\n\t\tfn.apply(this, arguments as unknown as any[]);\n\n\t\tthrottled = true;\n\n\t\tsetTimeout(function () {\n\t\t\tthrottled = false;\n\n\t\t\tif (savedArgs) {\n\t\t\t\twrapper.apply(savedThis, savedArgs);\n\t\t\t\tsavedArgs = savedThis = null;\n\t\t\t}\n\t\t}, ms);\n\t}\n\n\treturn wrapper as unknown as (...args: Parameters<Fn>) => void;\n};\n\nconst vibrate = (pattern: VibratePattern) => {\n\ttry {\n\t\tif ('vibrate' in navigator) {\n\t\t\tnavigator.vibrate(pattern);\n\t\t}\n\t} catch {}\n};\n\nconst findLastIndex = <T>(array: T[], fn: (item: T) => boolean) => {\n\tfor (let i = array.length - 1; i > 0; i--) {\n\t\tif (fn(array[i])) {\n\t\t\treturn i;\n\t\t}\n\t}\n\n\treturn -1;\n};\n\nconst preloadImagesBlocking = (images: Set<string>) => {\n\treturn Promise.allSettled(Array.from(images).map(src => {\n\t\tconst img = document.createElement('img');\n\n\t\timg.src = src;\n\n\t\treturn new Promise<unknown>((resolve, reject) => {\n\t\t\t/**\n\t\t\t * Image is already loaded\n\t\t\t */\n\t\t\tif (img.complete && img.naturalHeight !== 0) {\n\t\t\t\tresolve(void 0);\n\t\t\t}\n\n\t\t\timg.addEventListener('load', resolve);\n\t\t\timg.addEventListener('abort', reject);\n\t\t\timg.addEventListener('error', reject);\n\t\t});\n\t}));\n}\n\nconst createDeferredPromise = <T extends unknown = void>() => {\n\tlet resolve!: (value: T | PromiseLike<T>) => void, reject!: (reason?: any) => void;\n\n\tconst promise = new Promise<T>((res, rej) => {\n\t\tresolve = res; reject = rej;\n\t});\n\n\treturn { resolve, reject, promise }\n}\n\nexport {\n\tmatchAction,\n\tisNumber,\n\tisNull,\n\tisString,\n\tisPromise,\n\tisEmpty,\n\tisCSSImage,\n\tstr,\n\tisUserRequiredAction,\n\tgetTypewriterSpeed,\n\tgetLanguage,\n\tthrottle,\n\tisFunction,\n\tvibrate,\n\tfindLastIndex,\n\tpreloadImagesBlocking,\n\tcreateDeferredPromise\n};\n","const PRELOADED_ASSETS = new Set<string>();\n\nexport { PRELOADED_ASSETS }\n","type Stored<T> = {\n\tsubscribe: (cb: (value: T) => void) => () => void;\n\tupdate: (fn: (prev: T) => T) => void;\n\tget: () => T;\n};\n\nconst store = <T>(current: T, subscribers = new Set<(value: T) => void>()): Stored<T> => {\n\tconst subscribe = (cb: (value: T) => void) => {\n\t\tsubscribers.add(cb), cb(current);\n\n\t\treturn () => {\n\t\t\tsubscribers.delete(cb);\n\t\t};\n\t};\n\n\tconst push = (value: T) => {\n\t\tsubscribers.forEach((cb) => cb(value));\n\t};\n\n\tconst update = (fn: (prev: T) => T) => {\n\t\tpush((current = fn(current)));\n\t};\n\n\tconst get = () => {\n\t\treturn current;\n\t};\n\n\treturn { subscribe, update, get } as const;\n};\n\nexport { store };\nexport type { Stored };\n","import type { Character } from './character';\nimport type {\n\tActionProxyProvider,\n\tGetActionParameters,\n\tStory,\n\tValidAction,\n\tUnwrappable,\n\tCustomHandler,\n} from './action';\nimport type { Storage } from './storage';\nimport type { Save, State, Data, StorageData, DeepPartial, NovelyScreen, Migration, ActionFN } from './types';\nimport type { Renderer, RendererInit } from './renderer';\nimport type { SetupT9N } from '@novely/t9n';\nimport {\n\tmatchAction,\n\tisNumber,\n\tisNull,\n\tisString,\n\tisPromise,\n\tisEmpty,\n\tisCSSImage,\n\tstr,\n\tisUserRequiredAction,\n\tgetTypewriterSpeed,\n\tgetLanguage as defaultGetLanguage,\n\tthrottle,\n\tisFunction,\n\tvibrate,\n\tfindLastIndex,\n\tpreloadImagesBlocking,\n\tcreateDeferredPromise\n} from './utils';\nimport { PRELOADED_ASSETS } from './global';\nimport { store } from './store';\nimport { all as deepmerge } from 'deepmerge';\nimport { klona } from 'klona/json';\nimport { SKIPPED_DURING_RESTORE, EMPTY_SET } from './constants';\nimport { replace as replaceT9N } from '@novely/t9n';\n\ninterface NovelyInit<\n\tLanguages extends string,\n\tCharacters extends Record<string, Character<Languages>>,\n\tInter extends ReturnType<SetupT9N<Languages>>,\n\tStateScheme extends State,\n\tDataScheme extends Data,\n> {\n\t/**\n\t * An array of languages supported by the game.\n\t */\n\tlanguages: Languages[];\n\t/**\n\t * An object containing the characters in the game.\n\t */\n\tcharacters: Characters;\n\t/**\n\t * An object that provides access to the game's storage system.\n\t */\n\tstorage: Storage;\n\t/**\n\t * Delay loading data until Promise is resolved\n\t */\n\tstorageDelay?: Promise<void>;\n\t/**\n\t * A function that returns a Renderer object used to display the game's content\n\t */\n\trenderer: (characters: RendererInit) => Renderer;\n\t/**\n\t * An optional property that specifies the initial screen to display when the game starts\n\t */\n\tinitialScreen?: NovelyScreen;\n\t/**\n\t * An object containing the translation functions used in the game\n\t */\n\tt9n: Inter;\n\t/**\n\t * Initial state value\n\t */\n\tstate?: StateScheme;\n\t/**\n\t * Initial data value\n\t */\n\tdata?: DataScheme;\n\t/**\n\t * Enable autosaves or disable\n\t * @default true\n\t */\n\tautosaves?: boolean;\n\t/**\n\t * Migration from old saves to newer\n\t */\n\tmigrations?: Migration[];\n\t/**\n\t * For saves Novely uses `throttle` function. This might be needed if you want to control frequency of saves to the storage\n\t * @default 799\n\t */\n\tthrottleTimeout?: number;\n\t/**\n\t * Custom language detector\n\t * @param languages Supported languages aka `languages: []` in the config\n\t * @example ```ts\n\t * novely({\n\t * \t\tgetLanguage(languages, original) {\n\t * \t\t\t\tif (!sdk) return original(languages);\n\t * \t\t\t\treturn sdk.environment.i18n.lang // i.e. custom language from some sdk\n\t * \t\t}\n\t * })\n\t * ```\n\t */\n\tgetLanguage?: (languages: string[], original: typeof defaultGetLanguage) => string;\n\t/**\n\t * Ignores saved language, and uses `getLanguage` to get it on every engine start\n\t * @default false\n\t */\n\toverrideLanguage?: boolean;\n\t/**\n\t * Show a prompt before exiting a game\n\t * @default true\n\t */\n\taskBeforeExit?: boolean;\n\t/**\n\t * @default \"lazy\"\n\t */\n\tpreloadAssets?: \"lazy\" | \"blocking\"\n}\n\nconst novely = <\n\tLanguages extends string,\n\tCharacters extends Record<string, Character<Languages>>,\n\tInter extends ReturnType<SetupT9N<Languages>>,\n\tStateScheme extends State,\n\tDataScheme extends Data,\n>({\n\tcharacters,\n\tstorage,\n\tstorageDelay = Promise.resolve(),\n\trenderer: createRenderer,\n\tinitialScreen = 'mainmenu',\n\tt9n,\n\tlanguages,\n\tstate: defaultState,\n\tdata: defaultData,\n\tautosaves = true,\n\tmigrations = [],\n\tthrottleTimeout = 799,\n\tgetLanguage = defaultGetLanguage,\n\toverrideLanguage = false,\n\taskBeforeExit = true,\n\tpreloadAssets = \"lazy\"\n}: NovelyInit<Languages, Characters, Inter, StateScheme, DataScheme>) => {\n\tlet story: Story;\n\tlet times = new Set<number>();\n\n\tconst ASSETS_TO_PRELOAD = new Set<string>();\n\tconst assetsLoaded = createDeferredPromise();\n\n\t/**\n\t * Prevent `undefined`\n\t */\n\tdefaultData ||= {} as DataScheme;\n\tdefaultState ||= {} as StateScheme;\n\n\t/**\n\t * Saves timestamps created in this session\n\t */\n\tconst intime = (value: number) => {\n\t\treturn times.add(value), value;\n\t};\n\n\tconst withStory = async (s: Story) => {\n\t\t/**\n\t\t * Transforms `(ValidAction | ValidAction[])[]` to `ValidAction[]`\n\t\t */\n\t\tstory = Object.fromEntries(\n\t\t\tObject.entries(s).map(([name, items]) => {\n\t\t\t\tconst flat = (item: (ValidAction | ValidAction[])[]): ValidAction[] => {\n\t\t\t\t\treturn item.flatMap((data) => {\n\t\t\t\t\t\tconst type = data[0];\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * This is not just an action like `['name', ...arguments]`, but an array of actions\n\t\t\t\t\t\t */\n\t\t\t\t\t\tif (Array.isArray(type)) return flat(data as ValidAction[]);\n\n\t\t\t\t\t\treturn [data as ValidAction];\n\t\t\t\t\t});\n\t\t\t\t};\n\n\t\t\t\treturn [name, flat(items)];\n\t\t\t}),\n\t\t);\n\n\t\tif (preloadAssets === 'blocking' && ASSETS_TO_PRELOAD.size > 0) {\n\t\t\trenderer.ui.showScreen('loading');\n\n\t\t\tawait preloadImagesBlocking(ASSETS_TO_PRELOAD);\n\t\t}\n\n\t\tASSETS_TO_PRELOAD.clear();\n\t\tassetsLoaded.resolve();\n\n\t\t/**\n\t\t * When `initialScreen` is not a game, we can safely show it\n\t\t */\n\t\tif (initialScreen !== 'game') renderer.ui.showScreen(initialScreen);\n\t};\n\n\tconst action = new Proxy({} as ActionProxyProvider<Characters>, {\n\t\tget(_, prop) {\n\t\t\treturn (...props: Parameters<ActionFN>) => {\n\t\t\t\tif (preloadAssets === 'blocking') {\n\t\t\t\t\t/**\n\t\t\t\t\t * Load backgrounds\n\t\t\t\t\t */\n\t\t\t\t\tif (prop === 'showBackground' && typeof props[0] === 'string' && isCSSImage(props[0])) {\n\t\t\t\t\t\tASSETS_TO_PRELOAD.add(props[0]);\n\t\t\t\t\t}\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Load characters\n\t\t\t\t\t */\n\t\t\t\t\tif (prop === 'showCharacter' && typeof props[0] === 'string' && typeof props[1] === 'string') {\n\t\t\t\t\t\tconst images = characters[props[0]].emotions[props[1]];\n\n\t\t\t\t\t\tif (typeof images === 'string') {\n\t\t\t\t\t\t\tASSETS_TO_PRELOAD.add(images);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tfor (const asset of [images.head, images.body.left, images.body.right]) {\n\t\t\t\t\t\t\t\tASSETS_TO_PRELOAD.add(asset);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn [prop, ...props];\n\t\t\t};\n\t\t},\n\t});\n\n\tfunction state(value: DeepPartial<StateScheme> | ((prev: StateScheme) => StateScheme)): void;\n\tfunction state(): StateScheme;\n\tfunction state(value?: DeepPartial<StateScheme> | ((prev: StateScheme) => StateScheme)): StateScheme | void {\n\t\tif (!value) return stack.value[1] as StateScheme | void;\n\n\t\tconst prev = stack.value[1];\n\t\tconst val = isFunction(value) ? value(prev as StateScheme) : deepmerge([prev, value]);\n\n\t\tstack.value[1] = val as StateScheme;\n\t}\n\n\tconst getDefaultSave = (state = {}) => {\n\t\treturn [\n\t\t\t[\n\t\t\t\t[null, 'start'],\n\t\t\t\t[null, 0],\n\t\t\t],\n\t\t\tstate,\n\t\t\t[intime(Date.now()), 'auto'],\n\t\t] as Save;\n\t};\n\n\tconst createStack = (current: Save, stack = [current]) => {\n\t\treturn {\n\t\t\tget value() {\n\t\t\t\treturn stack.at(-1)!;\n\t\t\t},\n\t\t\tset value(value: Save) {\n\t\t\t\tstack[stack.length - 1] = value;\n\t\t\t},\n\t\t\tback() {\n\t\t\t\tif (stack.length > 1) stack.pop(), (goingBack = true);\n\t\t\t},\n\t\t\tpush(value: Save) {\n\t\t\t\tstack.push(value);\n\t\t\t},\n\t\t\tclear() {\n\t\t\t\tstack = [getDefaultSave(klona(defaultState))];\n\t\t\t},\n\t\t};\n\t};\n\n\tconst getLanguageWithoutParameters = () => {\n\t\treturn getLanguage(languages, defaultGetLanguage);\n\t}\n\n\t/**\n\t * 1) Novely rendered using the `initialData`, but you can't start new game or `load` an empty one - this is scary, imagine losing your progress\n\t * 2) Actual stored data is loaded, language and etc is changed\n\t */\n\tconst initialData: StorageData = {\n\t\tsaves: [],\n\t\tdata: klona(defaultData) as Data,\n\t\tmeta: [getLanguageWithoutParameters(), getTypewriterSpeed()],\n\t};\n\n\tconst $ = store(initialData);\n\n\tlet initialDataLoaded = false;\n\n\tconst onStorageDataChange = (value: StorageData) => {\n\t\tif (initialDataLoaded) storage.set(value);\n\t};\n\n\tconst throttledOnStorageDataChange = throttle(onStorageDataChange, throttleTimeout);\n\n\t$.subscribe(throttledOnStorageDataChange);\n\n\tconst getStoredData = () => {\n\t\tstorage.get().then((stored) => {\n\t\t\t/**\n\t\t\t * Migration is done only once (when game loads it's data), and then it saves the updated format\n\t\t\t */\n\t\t\tfor (const migration of migrations) {\n\t\t\t\t// @ts-expect-error Types does not match between versions\n\t\t\t\tstored = migration(stored);\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Default `localStorageStorage` returns empty array and engine set this up itself\n\t\t\t */\n\t\t\tstored.meta[1] ||= getTypewriterSpeed();\n\n\t\t\t/**\n\t\t\t * When we need to override it we do that, when not – only when language was not defined already\n\t\t\t */\n\t\t\tif (overrideLanguage) {\n\t\t\t\tstored.meta[0] = getLanguageWithoutParameters();\n\t\t\t} else {\n\t\t\t\tstored.meta[0] ||= getLanguageWithoutParameters();\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * When data is empty replace it with `defaultData`\n\t\t\t * It also might be empty (default to empty)\n\t\t\t */\n\t\t\tif (isEmpty(stored.data)) {\n\t\t\t\tstored.data = defaultData as Data;\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Now the next store updates will entail saving via storage.set\n\t\t\t */\n\t\t\tinitialDataLoaded = true;\n\n\t\t\t$.update(() => stored);\n\n\t\t\t/**\n\t\t\t * When initialScreen is game, then we will load it, but after the data is loaded and when assets are loaded if that is needed\n\t\t\t */\n\t\t\tif (initialScreen === 'game') assetsLoaded.promise.then(() => {\n\t\t\t\trestore();\n\t\t\t});\n\t\t});\n\t};\n\n\t/**\n\t * By default this is resolved immediately, but also can be delayed.\n\t * I.e. storage has not loaded yet\n\t */\n\tstorageDelay.then(getStoredData);\n\n\tconst initial = getDefaultSave(klona(defaultState));\n\tconst stack = createStack(initial);\n\n\tconst save = (override = false, type: Save[2][1] = override ? 'auto' : 'manual') => {\n\t\tif (!initialDataLoaded) return;\n\n\t\t/**\n\t\t * When autosaves diabled just return\n\t\t */\n\t\tif (!autosaves && type === 'auto') return;\n\n\t\tconst current = klona(stack.value);\n\n\t\t$.update((prev) => {\n\t\t\t/**\n\t\t\t * Find latest save that were created in current session, and check if it is latest in an array\n\t\t\t *\n\t\t\t * We check if save was created in current session and it is latest in array\n\t\t\t * When it is not then replacing it will break logical chain\n\t\t\t *\n\t\t\t * [auto save 1]\n\t\t\t * [manual save 1]\n\t\t\t * [auto save 2] <- should not replace first auto save\n\t\t\t */\n\t\t\tconst isLatest = findLastIndex(prev.saves, (value) => times.has(value[2][0])) === prev.saves.length - 1;\n\n\t\t\t/**\n\t\t\t * Update type and time information\n\t\t\t */\n\t\t\tcurrent[2][0] = intime(Date.now());\n\t\t\tcurrent[2][1] = type;\n\n\t\t\tif (!override || !isLatest) {\n\t\t\t\tprev.saves.push(current);\n\n\t\t\t\treturn prev;\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Get latest\n\t\t\t */\n\t\t\tconst latest = prev.saves.at(-1);\n\n\t\t\t/**\n\t\t\t * When that save is the same type, replace it\n\t\t\t */\n\t\t\tif (latest && latest[2][1] === type) {\n\t\t\t\tprev.saves[prev.saves.length - 1] = current;\n\t\t\t} else {\n\t\t\t\tprev.saves.push(current);\n\t\t\t}\n\n\t\t\treturn prev;\n\t\t});\n\t};\n\n\tconst newGame = () => {\n\t\tif (!initialDataLoaded) return;\n\n\t\tconst save = getDefaultSave(klona(defaultState));\n\n\t\t/**\n\t\t * Initial save is automatic, and should be ignored when autosaves is turned off\n\t\t */\n\t\tif (autosaves) {\n\t\t\t$.update((prev) => {\n\t\t\t\treturn prev.saves.push(save), prev;\n\t\t\t});\n\t\t}\n\n\t\trestore(save);\n\t};\n\n\t/**\n\t * Set's the save\n\t */\n\tconst set = (save: Save) => {\n\t\tstack.value = save;\n\n\t\treturn restore(save);\n\t};\n\n\tlet restoring = false;\n\tlet goingBack = false;\n\tlet interacted = 0;\n\n\t/**\n\t * Restore\n\t */\n\tconst restore = async (save?: Save) => {\n\t\tif (!initialDataLoaded) return;\n\n\t\tlet latest = save ? save : $.get().saves.at(-1);\n\n\t\t/**\n\t\t * When there is no game, then make a new game\n\t\t */\n\t\tif (!latest) {\n\t\t\t$.update(() => ({\n\t\t\t\tsaves: [initial],\n\t\t\t\tdata: klona(defaultData) as Data,\n\t\t\t\tmeta: [getLanguageWithoutParameters(), getTypewriterSpeed()],\n\t\t\t}));\n\n\t\t\tlatest = klona(initial);\n\t\t}\n\n\t\t(restoring = true), (stack.value = latest);\n\n\t\t/**\n\t\t * Текущий элемент в истории\n\t\t */\n\t\tlet current: any = story;\n\t\t/**\n\t\t * Текущий элемент `[null, int]`\n\t\t */\n\t\tlet index = 0;\n\n\t\t/**\n\t\t * Число элементов `[null, int]`\n\t\t */\n\t\tconst max = stack.value[0].reduce((acc, [type, val]) => {\n\t\t\tif (isNull(type) && isNumber(val)) return acc + 1;\n\n\t\t\treturn acc;\n\t\t}, 0);\n\n\t\tconst queue = [] as [any, any][];\n\t\tconst keep = new Set();\n\t\tconst characters = new Set();\n\n\t\tfor (const [type, val] of stack.value[0]) {\n\t\t\tif (type === null) {\n\t\t\t\tif (isString(val)) {\n\t\t\t\t\tcurrent = current[val];\n\t\t\t\t} else if (isNumber(val)) {\n\t\t\t\t\tindex++;\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Запустим все экшены которые идут в `[null, int]` от `0` до `int`\n\t\t\t\t\t * Почему-то потребовалось изменить `<` на `<=`, чтобы последний action попадал сюда\n\t\t\t\t\t */\n\t\t\t\t\tfor (let i = 0; i <= val; i++) {\n\t\t\t\t\t\tconst [action, ...meta] = current[i];\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * Add item to queue and action to keep\n\t\t\t\t\t\t */\n\t\t\t\t\t\tconst push = () => {\n\t\t\t\t\t\t\tkeep.add(action);\n\t\t\t\t\t\t\tqueue.push([action, meta]);\n\t\t\t\t\t\t};\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * Do not remove characters that will be here anyways\n\t\t\t\t\t\t */\n\t\t\t\t\t\tif (action === 'showCharacter') characters.add(meta[0]);\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * Экшены, для закрытия которых пользователь должен с ними взаимодействовать\n\t\t\t\t\t\t * Также в эту группу входят экшены, которые не должны быть вызваны при восстановлении\n\t\t\t\t\t\t */\n\t\t\t\t\t\tif (SKIPPED_DURING_RESTORE.has(action) || isUserRequiredAction(action, meta)) {\n\t\t\t\t\t\t\tif (index === max && i === val) {\n\t\t\t\t\t\t\t\tpush();\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tpush();\n\t\t\t\t\t}\n\n\t\t\t\t\tcurrent = current[val];\n\t\t\t\t}\n\t\t\t} else if (type === 'choice') {\n\t\t\t\tcurrent = current[(val as number) + 1][1];\n\t\t\t} else if (type === 'condition') {\n\t\t\t\tcurrent = current[2][val];\n\t\t\t}\n\t\t}\n\n\t\tqueue.forEach((value, index) => {\n\t\t\t/**\n\t\t\t * Mutate the queue item\n\t\t\t */\n\t\t\tvalue.push(index);\n\t\t});\n\n\t\t/**\n\t\t * This is basically made for TypeScript.\n\t\t */\n\t\tconst indexedQueue = queue as unknown as [Exclude<ValidAction[0], ValidAction>, ValidAction[1], number][];\n\n\t\t/**\n\t\t * Run these exactly before the main loop.\n\t\t */\n\t\trenderer.ui.showScreen('game');\n\t\t/**\n\t\t * Provide the `keep` in there\n\t\t */\n\t\tmatch('clear', [keep, characters]);\n\n\t\t/**\n\t\t * Get the next actions array.\n\t\t */\n\t\tconst next = (i: number) => indexedQueue.slice(i + 1);\n\n\t\tfor await (const [action, meta, i] of indexedQueue) {\n\t\t\tif (action === 'function' || action === 'custom') {\n\t\t\t\t/**\n\t\t\t\t * When `callOnlyLatest` is `true`\n\t\t\t\t */\n\t\t\t\tif (action === 'custom' && (meta as GetActionParameters<'Custom'>)[0].callOnlyLatest) {\n\t\t\t\t\t/**\n\t\t\t\t\t * We'll calculate it is `latest` or not\n\t\t\t\t\t */\n\t\t\t\t\tconst notLatest = next(i).some(([_action, _meta]) => {\n\t\t\t\t\t\tif (!_meta || !meta) return false;\n\n\t\t\t\t\t\tconst c0 = _meta[0] as unknown as GetActionParameters<'Custom'>[0];\n\t\t\t\t\t\tconst c1 = meta[0] as unknown as GetActionParameters<'Custom'>[0];\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * Also check for `undefined`\n\t\t\t\t\t\t */\n\t\t\t\t\t\tconst isIdenticalID = c0.id && c1.id && c0.id === c1.id;\n\n\t\t\t\t\t\t/**\n\t\t\t\t\t\t * Equal by id or equal by `toString()`\n\t\t\t\t\t\t */\n\t\t\t\t\t\treturn isIdenticalID || str(c0) === str(c1);\n\t\t\t\t\t});\n\n\t\t\t\t\tif (notLatest) continue;\n\t\t\t\t}\n\n\t\t\t\t/**\n\t\t\t\t * Action can return Promise.\n\t\t\t\t */\n\t\t\t\tconst result = match(action, meta);\n\n\t\t\t\t/**\n\t\t\t\t * Should wait until it resolved\n\t\t\t\t */\n\t\t\t\tif (isPromise(result)) {\n\t\t\t\t\t/**\n\t\t\t\t\t * Await it!\n\t\t\t\t\t */\n\t\t\t\t\tawait result;\n\t\t\t\t}\n\t\t\t} else if (action === 'showCharacter') {\n\t\t\t\tconst skip = next(i).some(([_action, _meta]) => {\n\t\t\t\t\t/**\n\t\t\t\t\t * Проверка на возможный `undefined`\n\t\t\t\t\t */\n\t\t\t\t\tif (!_meta || !meta) return false;\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Будет ли персонаж скрыт в будущем\n\t\t\t\t\t * Нет смысла при загрузке сохранения загружать и отрисовывать персонажа, который будет скрыт\n\t\t\t\t\t */\n\t\t\t\t\tconst hidden = _action === 'hideCharacter' && _meta[0] === meta[0];\n\t\t\t\t\t/**\n\t\t\t\t\t * Не нужно запускать рендер персонажа, если после этого будет ещё один рендер этого персонажа\n\t\t\t\t\t * Таким образом избегаем ситуации, когда при загрузке вследствие гонки при загрузки изображений отрисовывается не последняя эмоция\n\t\t\t\t\t */\n\t\t\t\t\tconst notLatest = _action === action && _meta[0] === meta[0];\n\n\t\t\t\t\treturn hidden || notLatest;\n\t\t\t\t});\n\n\t\t\t\tif (skip) continue;\n\n\t\t\t\tmatch(action, meta);\n\t\t\t} else if (action === 'showBackground' || action === 'animateCharacter') {\n\t\t\t\t/**\n\t\t\t\t * Такая же оптимизация применяется к фонам и анимированию персонажей.\n\t\t\t\t * Если фон изменится, то нет смысла устанавливать текущий\n\t\t\t\t */\n\t\t\t\tconst notLatest = next(i).some(([_action]) => action === _action);\n\n\t\t\t\tif (notLatest) continue;\n\n\t\t\t\tmatch(action, meta);\n\t\t\t} else {\n\t\t\t\tmatch(action, meta);\n\t\t\t}\n\t\t}\n\n\t\t(restoring = goingBack = false), render();\n\t};\n\n\tconst refer = () => {\n\t\tlet current: any = story;\n\n\t\tfor (const [type, val] of stack.value[0]) {\n\t\t\tif (type === null) {\n\t\t\t\tcurrent = current[val];\n\t\t\t} else if (type === 'choice') {\n\t\t\t\tcurrent = current[(val as number) + 1][1];\n\t\t\t} else if (type === 'condition') {\n\t\t\t\tcurrent = current[2][val];\n\t\t\t}\n\t\t}\n\n\t\treturn current;\n\t};\n\n\t/**\n\t * @param force Force exit\n\t */\n\tconst exit = (force = false) => {\n\t\tif (interacted > 1 && !force && askBeforeExit) {\n\t\t\trenderer.ui.showExitPrompt();\n\t\t\treturn;\n\t\t}\n\n\t\tconst current = stack.value;\n\n\t\tstack.clear();\n\t\trenderer.ui.showScreen('mainmenu');\n\n\t\t/**\n\t\t * First two save elements and it's type\n\t\t */\n\t\tconst [time, type] = current[2];\n\n\t\tif (type === 'auto') {\n\t\t\t/**\n\t\t\t * Save belongs to the current session\n\t\t\t * And player did not interacted or did it once, so this is probably not-needed save\n\t\t\t */\n\t\t\tif (interacted <= 1 && times.has(time)) {\n\t\t\t\t$.update((prev) => {\n\t\t\t\t\tprev.saves = prev.saves.filter((save) => save !== current);\n\n\t\t\t\t\treturn prev;\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * Reset interactive value\n\t\t */\n\t\tinteractivity(false);\n\t\t/**\n\t\t * Reset session times\n\t\t */\n\t\ttimes.clear();\n\t};\n\n\tconst back = () => {\n\t\treturn stack.back(), restore(stack.value);\n\t};\n\n\tconst renderer = createRenderer({\n\t\tcharacters,\n\t\tset,\n\t\trestore,\n\t\tsave,\n\t\tnewGame,\n\t\texit,\n\t\tback,\n\t\tstack,\n\t\tlanguages,\n\t\tt: t9n.i,\n\t\t$,\n\t});\n\n\tconst match = matchAction({\n\t\twait([time]) {\n\t\t\tif (!restoring) setTimeout(push, isFunction(time) ? time() : time);\n\t\t},\n\t\tshowBackground([background]) {\n\t\t\trenderer.background(background);\n\t\t\tpush();\n\t\t},\n\t\tplayMusic([source]) {\n\t\t\trenderer.music(source, 'music').play();\n\t\t\tpush();\n\t\t},\n\t\tstopMusic([source]) {\n\t\t\trenderer.music(source, 'music').stop();\n\t\t\tpush();\n\t\t},\n\t\tshowCharacter([character, emotion, className, style]) {\n\t\t\tconst handle = renderer.character(character);\n\n\t\t\thandle.append(className, style, restoring);\n\t\t\thandle.withEmotion(emotion)();\n\n\t\t\tpush();\n\t\t},\n\t\thideCharacter([character, className, style, duration]) {\n\t\t\trenderer.character(character).remove(className, style, duration)(push, restoring);\n\t\t},\n\t\tdialog([character, content, emotion]) {\n\t\t\t/**\n\t\t\t * Person name\n\t\t\t */\n\t\t\tconst name = (() => {\n\t\t\t\tconst c = character,\n\t\t\t\t\tcs = characters;\n\t\t\t\tconst lang = $.get().meta[0];\n\n\t\t\t\treturn c\n\t\t\t\t\t? c in cs\n\t\t\t\t\t\t? typeof cs[c].name === 'string'\n\t\t\t\t\t\t\t? (cs[c].name as string)\n\t\t\t\t\t\t\t: (cs[c].name as Record<string, string>)[lang]\n\t\t\t\t\t\t: c\n\t\t\t\t\t: '';\n\t\t\t})();\n\n\t\t\trenderer.dialog(unwrap(content), unwrap(name), character, emotion)(forward);\n\t\t},\n\t\tfunction([fn]) {\n\t\t\tconst result = fn(restoring, goingBack);\n\n\t\t\tif (!restoring) result ? result.then(push) : push();\n\n\t\t\treturn result;\n\t\t},\n\t\tchoice([question, ...choices]) {\n\t\t\tconst isWithoutQuestion = Array.isArray(question);\n\n\t\t\tif (isWithoutQuestion) {\n\t\t\t\t/**\n\t\t\t\t * Первый элемент может быть как строкой, так и элементов выбора\n\t\t\t\t */\n\t\t\t\tchoices.unshift(question as unknown as [Unwrappable, ValidAction[], () => boolean]);\n\t\t\t\t/**\n\t\t\t\t * Значит, текст не требуется\n\t\t\t\t */\n\t\t\t\tquestion = '';\n\t\t\t}\n\n\t\t\tconst unwrapped = choices.map(([content, action, visible]) => {\n\t\t\t\treturn [unwrap(content), action, visible] as [string, ValidAction[], () => boolean];\n\t\t\t});\n\n\t\t\trenderer.choices(\n\t\t\t\tunwrap(question),\n\t\t\t\tunwrapped,\n\t\t\t)((selected) => {\n\t\t\t\tenmemory();\n\n\t\t\t\t/**\n\t\t\t\t * If there is a question, then `index` should be shifted by `1`\n\t\t\t\t */\n\t\t\t\tconst offset = isWithoutQuestion ? 0 : 1;\n\n\t\t\t\tstack.value[0].push(['choice', selected + offset], [null, 0]);\n\t\t\t\trender();\n\t\t\t\tinteractivity(true);\n\t\t\t});\n\t\t},\n\t\tjump([scene]) {\n\t\t\t/**\n\t\t\t * `-1` index is used here because `clear` will run `next` that will increase index to `0`\n\t\t\t */\n\t\t\tstack.value[0] = [\n\t\t\t\t[null, scene],\n\t\t\t\t[null, -1],\n\t\t\t];\n\n\t\t\tmatch('clear', []);\n\t\t},\n\t\tclear([keep, characters]) {\n\t\t\t/**\n\t\t\t * Remove vibration\n\t\t\t */\n\t\t\tvibrate(0);\n\t\t\t/**\n\t\t\t * Call the actual `clear`\n\t\t\t */\n\t\t\trenderer.clear(goingBack, keep || EMPTY_SET, characters || EMPTY_SET)(push);\n\t\t},\n\t\tcondition([condition]) {\n\t\t\tconst value = condition();\n\n\t\t\tif (!restoring) stack.value[0].push(['condition', String(value)], [null, 0]), render();\n\t\t},\n\t\tend() {\n\t\t\t/**\n\t\t\t * Clear the Scene\n\t\t\t */\n\t\t\tmatch('clear', []);\n\t\t\t/**\n\t\t\t * Go to the main menu\n\t\t\t */\n\t\t\trenderer.ui.showScreen('mainmenu');\n\t\t\t/**\n\t\t\t * Reset interactive value\n\t\t\t */\n\t\t\tinteractivity(false);\n\t\t\t/**\n\t\t\t * Reset session times\n\t\t\t */\n\t\t\ttimes.clear();\n\t\t},\n\t\tinput([question, onInput, setup]) {\n\t\t\trenderer.input(unwrap(question), onInput, setup)(forward);\n\t\t},\n\t\tcustom([handler]) {\n\t\t\tconst result = renderer.custom(handler, goingBack, () => {\n\t\t\t\tif (!restoring && handler.requireUserAction) enmemory(), interactivity(true);\n\t\t\t\tif (!restoring) push();\n\t\t\t});\n\n\t\t\treturn result;\n\t\t},\n\t\tvibrate(pattern) {\n\t\t\tvibrate(pattern);\n\t\t\tpush();\n\t\t},\n\t\tnext() {\n\t\t\tpush();\n\t\t},\n\t\tanimateCharacter([character, timeout, ...classes]) {\n\t\t\tconst handler: CustomHandler = (get) => {\n\t\t\t\tconst { clear } = get('@@internal-animate-character', false);\n\t\t\t\tconst char = renderer.store.characters[character];\n\n\t\t\t\t/**\n\t\t\t\t * Character is not defined, maybe, `animateCharacter` was called before `showCharacter`\n\t\t\t\t */\n\t\t\t\tif (!char) return;\n\n\t\t\t\tconst target = char.canvas;\n\n\t\t\t\t/**\n\t\t\t\t * Character is not found\n\t\t\t\t */\n\t\t\t\tif (!target) return;\n\n\t\t\t\tconst classNames = classes.filter((className) => !target.classList.contains(className));\n\n\t\t\t\ttarget.classList.add(...classNames);\n\n\t\t\t\tconst timeoutId = setTimeout(() => {\n\t\t\t\t\ttarget.classList.remove(...classNames);\n\t\t\t\t}, timeout);\n\n\t\t\t\tclear(() => {\n\t\t\t\t\ttarget.classList.remove(...classNames);\n\n\t\t\t\t\t/**\n\t\t\t\t\t * Clear timeout, because when you will game re-runs some callback might remove classes from character\n\t\t\t\t\t */\n\t\t\t\t\tclearTimeout(timeoutId);\n\t\t\t\t});\n\t\t\t};\n\n\t\t\t/**\n\t\t\t * `callOnlyLatest` property will not have any effect, because `custom` is called directly\n\t\t\t */\n\t\t\tmatch('custom', [handler]);\n\t\t},\n\t\ttext(text) {\n\t\t\trenderer.text(text.map((content) => unwrap(content)).join(' '), forward);\n\t\t},\n\t\texit() {\n\t\t\tconst path = stack.value[0];\n\n\t\t\tlet exited = false;\n\n\t\t\tfor (let i = path.length - 1; i > 0; i--) {\n\t\t\t\tif (path[i][0] !== 'choice' && path[i][0] !== 'condition') continue;\n\n\t\t\t\texited = true;\n\t\t\t\tstack.value[0] = path.slice(0, i);\n\t\t\t\tnext();\n\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t/**\n\t\t\t * Run render only when exit was performed. This prevents infinite loop of `render` -> `undefined` -> `exit` -> `render`.\n\t\t\t */\n\t\t\tif (exited) render();\n\t\t},\n\t\tpreload([source]) {\n\t\t\tif (!PRELOADED_ASSETS.has(source) && !goingBack && !restoring) {\n\t\t\t\t/**\n\t\t\t\t * Make image load\n\t\t\t\t */\n\t\t\t\tPRELOADED_ASSETS.add(document.createElement('img').src = source);\n\t\t\t}\n\n\t\t\tpush();\n\t\t}\n\t});\n\n\tconst enmemory = () => {\n\t\tif (restoring) return;\n\n\t\tconst current = klona(stack.value);\n\n\t\tcurrent[2][1] = 'auto';\n\n\t\tstack.push(current);\n\n\t\tsave(true, 'auto');\n\t};\n\n\tconst next = () => {\n\t\tconst path = stack.value[0];\n\t\t/**\n\t\t * Последний элемент пути\n\t\t */\n\t\tconst last = path[path.length - 1]!;\n\n\t\t/**\n\t\t * Если он вида `[null, int]` - увеличивает `int`\n\t\t */\n\t\tif (isNull(last[0]) && isNumber(last[1])) {\n\t\t\tlast[1] = last[1] + 1;\n\t\t\treturn;\n\t\t}\n\n\t\t/**\n\t\t * Иначе добавляет новое `[null, int]`\n\t\t */\n\t\tpath.push([null, 0]);\n\t};\n\n\tconst render = () => {\n\t\tconst referred = refer();\n\n\t\tif (Array.isArray(referred)) {\n\t\t\tconst [action, ...props] = referred;\n\n\t\t\tmatch(action, props);\n\t\t} else {\n\t\t\tmatch('exit', []);\n\t\t}\n\t};\n\n\tconst push = () => {\n\t\tif (!restoring) next(), render();\n\t};\n\n\tconst forward = () => {\n\t\tenmemory();\n\t\tpush();\n\t\tinteractivity(true);\n\t};\n\n\tconst interactivity = (value = false) => {\n\t\tinteracted = value ? (interacted + 1) : 0;\n\t};\n\n\t/**\n\t * Unwraps translatable content to string\n\t *\n\t * @example ```\n\t * unwrap(t('Hello'));\n\t * unwrap({ en: 'Hello', ru: 'Привет' });\n\t * unwrap({ en: () => data().ad_viewed ? 'Diamond Hat' : 'Diamond Hat (Watch Adv)' })\n\t * unwrap('Hello, {{name}}');\n\t * ```\n\t */\n\tconst unwrap = (content: Unwrappable, global = false) => {\n\t\tconst {\n\t\t\tdata,\n\t\t\tmeta: [lang],\n\t\t} = $.get();\n\n\t\tconst obj = global ? data : state();\n\t\tconst cnt = isFunction(content) ? content(lang, obj) : typeof content === 'string' ? content : content[lang];\n\n\t\tconst str = isFunction(cnt) ? cnt() : cnt;\n\n\t\treturn replaceT9N(str, obj);\n\t};\n\n\tfunction data(value: DeepPartial<DataScheme> | ((prev: DataScheme) => DataScheme)): void;\n\tfunction data(): DataScheme;\n\tfunction data(value?: DeepPartial<DataScheme> | ((prev: DataScheme) => DataScheme)): DataScheme | void {\n\t\tif (!value) return $.get().data as DataScheme | void;\n\n\t\tconst prev = $.get().data;\n\t\tconst val = isFunction(value) ? value(prev as DataScheme) : deepmerge([prev, value]);\n\n\t\t$.update((prev) => {\n\t\t\tprev.data = val;\n\n\t\t\treturn prev;\n\t\t});\n\t}\n\n\treturn {\n\t\t/**\n\t\t * Function to set story\n\t\t */\n\t\twithStory,\n\t\t/**\n\t\t * Function to get actions\n\t\t */\n\t\taction,\n\t\t/**\n\t\t * State that belongs to games\n\t\t */\n\t\tstate,\n\t\t/**\n\t\t * Unlike `state`, stored at global scope instead and shared between games\n\t\t */\n\t\tdata,\n\t\t/**\n\t\t * Unwraps translatable content to a string value\n\t\t */\n\t\tunwrap(content: Exclude<Unwrappable, Record<string, string>> | Record<Languages, string>) {\n\t\t\treturn unwrap(content, true);\n\t\t},\n\t\t/**\n\t\t * Function that is used for translation\n\t\t */\n\t\tt: t9n.t as Inter['t'],\n\t};\n};\n\nexport { novely };\n","const SKIPPED_DURING_RESTORE = new Set(['dialog', 'choice', 'input', 'vibrate', 'text'] as const);\n\nconst EMPTY_SET = new Set<any>();\n\nexport { SKIPPED_DURING_RESTORE, EMPTY_SET };\n","import type { StorageData } from './types';\n\ninterface LocalStorageStorageSettings {\n\tkey: string;\n}\n\ninterface Storage {\n\tget: () => Promise<StorageData>;\n\tset: (data: StorageData) => Promise<void>;\n}\n\nconst localStorageStorage = (options: LocalStorageStorageSettings): Storage => {\n\treturn {\n\t\tasync get() {\n\t\t\tconst value = localStorage.getItem(options.key);\n\n\t\t\treturn value ? JSON.parse(value) : { saves: [], data: {}, meta: [] };\n\t\t},\n\t\tasync set(data) {\n\t\t\tlocalStorage.setItem(options.key, JSON.stringify(data));\n\t\t},\n\t};\n};\n\nexport type { Storage };\nexport { localStorageStorage };\n"],"mappings":"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","names":["str","getLanguage","data","state","stack","save","characters","action","push","index","next","str","prev"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@novely/core",
|
|
3
3
|
"description": "Novely - powerful visual novel engine for creating interactive stories and games with branching narratives and rich multimedia content.",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.8.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"publishConfig": {
|