risupack 0.1.4 → 0.2.2

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/README.md CHANGED
@@ -1,63 +1,97 @@
1
1
  # risupack
2
2
 
3
- A CLI and TypeScript library for building and unpacking RisuAI CharX and RisuM artifacts.
3
+ A command-line tool and TypeScript library for building RisuAI CharX modules, unpacking CharX and RisuM files, bundling Lua, and inspecting RisuSave databases.
4
+
5
+ ## Requirements
6
+
7
+ - Node.js 20 or later
4
8
 
5
9
  ## Installation
6
10
 
11
+ Install risupack in the project that contains the module sources.
12
+
7
13
  ```sh
8
14
  npm install --save-dev risupack
9
15
  ```
10
16
 
11
- ## Commands
17
+ Run the local installation with `npx risupack`.
18
+
19
+ ## New modules
20
+
21
+ A module without character prompts needs only a manifest.
22
+
23
+ ```text
24
+ sample-module/
25
+ └── charx.json
26
+ ```
27
+
28
+ ```json
29
+ {
30
+ "description": "Sample module",
31
+ "name": "Sample Module",
32
+ "namespace": "sample-module",
33
+ "version": "1.0.0"
34
+ }
35
+ ```
36
+
37
+ Build the CharX from the manifest.
12
38
 
13
39
  ```sh
14
- risupack build-charx <manifest.json> [output.charx]
15
- risupack bundle-lua <entry.lua> <output.lua>
16
- risupack inspect-risusave <database.bin> [namespace-or-name]
17
- risupack unpack-charx <input.charx> [output-directory]
18
- risupack unpack-risum <input.risum> [output-directory]
40
+ npx risupack build-charx sample-module/charx.json
19
41
  ```
20
42
 
21
- Set `SOURCE_DATE_EPOCH` when reproducible CharX output is required.
43
+ Without `output`, the command writes `../dist/<name>.charx` relative to the manifest directory.
44
+
45
+ Add lorebooks, regexes, triggers, CSS, toggles, assets, or character prompts only when the module needs them. Reference each source from `charx.json`.
46
+
47
+ ## Existing modules
48
+
49
+ Unpack an existing CharX into editable sources.
22
50
 
23
51
  ```sh
24
- SOURCE_DATE_EPOCH=1700000000 risupack build-charx module/charx.json
52
+ npx risupack unpack-charx character.charx character
25
53
  ```
26
54
 
27
- ## CharX output
55
+ Both unpack commands require an absent or empty output directory. When the output argument is omitted, each command uses the input filename without its extension.
28
56
 
29
- The builder creates a ZIP archive containing the RisuAI card, encoded module, assets, and CharX metadata.
57
+ Edit the generated sources and rebuild from the generated manifest.
30
58
 
31
- ```text
32
- module.charx
33
- ├── card.json
34
- ├── module.risum
35
- ├── assets/
36
- └── x_meta/
59
+ ```sh
60
+ npx risupack build-charx character/charx.json
61
+ ```
62
+
63
+ Use `unpack-risum` for a standalone RisuM file.
64
+
65
+ ```sh
66
+ npx risupack unpack-risum module.risum module
37
67
  ```
38
68
 
39
- ## Module layout
69
+ The generated `charx.json` can be passed to `build-charx` to package the recovered module as a CharX.
40
70
 
41
- The builder does not require a particular source directory layout. The `unpack-charx` and `unpack-risum` commands materialize recovered sources with the following layout when the corresponding source types exist.
71
+ ## Source layout
72
+
73
+ All manifest paths, including `output` and `bundleOutput`, are relative to `charx.json`. A generated source directory can contain the following files when the module uses the corresponding features.
42
74
 
43
75
  ```text
44
- <output>/
76
+ <module>/
77
+ ├── alternate_greetings/
45
78
  ├── assets/
46
79
  ├── lorebooks/
47
80
  ├── regex/
48
- ├── styles/
49
81
  ├── triggers/
82
+ ├── card.json
50
83
  ├── charx.json
84
+ ├── description.md
85
+ ├── first_mes.md
86
+ ├── style.html
51
87
  └── toggles.txt
52
88
  ```
53
89
 
54
- Input manifests may use other layouts. Update every affected path in `charx.json` after moving a source file.
90
+ The builder accepts other layouts. Update the paths in `charx.json` after moving a source file.
55
91
 
56
- ## Manifest paths
92
+ ## Manifest
57
93
 
58
- Resolve paths inside `charx.json` from the directory containing `charx.json`. This rule applies to `CSS`, `assets`, `icon`, `lorebook`, `output`, `regex`, `toggles`, trigger `lua`, and trigger `bundleOutput`.
59
-
60
- Use the following manifest structure.
94
+ `name` is the only field enforced as required. Set a stable `namespace` for module identity and lookup.
61
95
 
62
96
  ```json
63
97
  {
@@ -68,120 +102,158 @@ Use the following manifest structure.
68
102
  "name": "background"
69
103
  }
70
104
  ],
71
- "card": "card.json",
105
+ "creator": "Creator",
72
106
  "description": "Module description",
107
+ "folders": ["Internal"],
73
108
  "hideIcon": false,
74
109
  "icon": "assets/icon.png",
110
+ "license": "AGPL-3.0-only",
75
111
  "lorebook": [
76
112
  {
77
113
  "alwaysActive": false,
78
- "comment": "sample",
114
+ "comment": "Sample",
79
115
  "file": "lorebooks/sample.md",
80
- "folder": "Sample",
116
+ "folder": "Internal",
81
117
  "insertOrder": 100,
82
- "key": "",
118
+ "key": "sample",
83
119
  "mode": "normal",
84
120
  "secondaryKey": "",
85
121
  "selective": false,
86
122
  "useRegex": false
87
123
  }
88
124
  ],
89
- "lowLevelAccess": true,
125
+ "lowLevelAccess": false,
90
126
  "name": "Sample Module",
91
- "namespace": "sample",
127
+ "namespace": "sample-module",
128
+ "output": "../dist/sample-module.charx",
92
129
  "regex": ["regex/display.md"],
130
+ "tags": ["utility"],
93
131
  "toggles": "toggles.txt",
94
132
  "triggers": [
95
133
  {
96
134
  "bundle": true,
97
- "lowLevelAccess": true,
98
- "lua": "triggers/main.lua"
135
+ "comment": "Start",
136
+ "lowLevelAccess": false,
137
+ "lua": "triggers/main.lua",
138
+ "type": "start"
99
139
  }
100
140
  ],
101
141
  "version": "1.0.0"
102
142
  }
103
143
  ```
104
144
 
105
- ## Manifest fields
106
-
107
- - `name`: Required non-empty module name.
108
- - `namespace`: RisuAI module namespace.
109
- - `version`: Packaged module version.
110
- - `description`: Packaged module description.
111
- - `creator`: Package creator name.
112
- - `license`: Package license identifier or text.
113
- - `tags`: Array of package tags. Defaults to an empty array.
114
- - `output`: Output path used when the CLI output argument is omitted. Defaults to `../dist/<sanitized-name>.charx` relative to the manifest directory.
115
- - `card`: Source character card whose character fields are preserved. Module-managed metadata, lorebooks, assets, CSS, and toggles are rebuilt from the manifest.
116
- - `CSS`: Custom CSS source.
117
- - `toggles`: Module toggle source.
118
- - `icon`: Main module icon path. The builder supplies an empty default icon when omitted.
119
- - `hideIcon`: Hides the module icon in chat when `true`. Defaults to `false`.
120
- - `lowLevelAccess`: Enables module-level low-level access when `true`. Defaults to `false`.
121
- - `folders`: Lorebook folder names to create even when no lorebook entry references them.
122
- - `assets`: Additional packaged assets.
123
- - `lorebook`: Lorebook entries.
124
- - `regex`: Regex entries in execution order.
125
- - `triggers`: Lua trigger entries.
126
-
127
- ## Source values
128
-
129
- `CSS`, `toggles`, and lorebook sources accept a path string, a file object, or inline content.
145
+ - `CSS`: CSS or HTML source inserted into the RisuAI background HTML field
146
+ - `assets`: Additional files packaged as RisuAI assets
147
+ - `card`: Optional character card sources
148
+ - `creator`: Creator name
149
+ - `description`: Package description stored as creator notes
150
+ - `folders`: Lorebook folders to create even when no entry references them
151
+ - `hideIcon`: Whether RisuAI hides the module icon in chat, defaulting to `false`
152
+ - `icon`: Main module icon; omission creates a transparent placeholder icon
153
+ - `license`: Package license identifier or text
154
+ - `lorebook`: Lorebook entries
155
+ - `lowLevelAccess`: Module-level low-level access, defaulting to `false`
156
+ - `name`: Required non-empty module name
157
+ - `namespace`: Module namespace
158
+ - `output`: Default CharX output path
159
+ - `regex`: Regex entries in execution order
160
+ - `tags`: Package tags, defaulting to an empty array
161
+ - `toggles`: Module toggle source
162
+ - `triggers`: Trigger entries
163
+ - `version`: Package version
164
+
165
+ ## Text sources
166
+
167
+ CSS, toggles, lorebook contents, and external character text fields accept a path string or an object containing `file` or `content`.
130
168
 
131
169
  ```json
132
170
  {
133
- "CSS": "styles/main.html",
134
- "toggles": { "file": "toggles.txt" },
171
+ "CSS": "style.html",
135
172
  "lorebook": [
136
173
  {
137
- "comment": "inline",
174
+ "comment": "Inline",
138
175
  "content": "Inline lorebook content"
139
176
  }
140
- ]
177
+ ],
178
+ "toggles": {
179
+ "file": "toggles.txt"
180
+ }
141
181
  }
142
182
  ```
143
183
 
144
- When a source object contains both `content` and `file`, `content` takes precedence. A bundled Lua lorebook requires `file`.
184
+ `content` takes precedence when an object contains both `content` and `file`. Bundled Lua lorebooks require `file`.
145
185
 
146
- ## Lorebook entries
186
+ ## Character sources
147
187
 
148
- - `file`: Lorebook source path. Required unless `content` is provided.
149
- - `content`: Inline lorebook source.
150
- - `comment`: Lorebook name. Defaults to the source file basename.
151
- - `alwaysActive`: Enables constant activation. Defaults to `false`.
152
- - `activationPercent`: RisuAI activation percentage.
153
- - `folder`: Display folder name. The builder creates referenced folders automatically.
154
- - `insertOrder`: Lorebook insertion order. Defaults to `100`.
155
- - `key`: Comma-separated primary activation keys. Defaults to an empty string.
156
- - `secondaryKey`: Comma-separated secondary activation keys. Defaults to an empty string.
157
- - `selective`: Enables secondary-key matching. Defaults to `false`.
158
- - `mode`: RisuAI lorebook mode. Defaults to `normal`.
159
- - `useRegex`: Treats activation keys as regular expressions when `true`. Defaults to `false`.
160
- - `extentions`: RisuAI-specific lorebook extension values. Use this exact spelling.
161
- - `bundle`: Bundles the Lua source and its `require()` dependencies when `true`. Defaults to `false`.
162
- - `bundleOutput`: Optional path for retaining the bundled Lua artifact.
188
+ Omit `card` when the module has no character-specific prompts or settings.
163
189
 
164
- ## Lua triggers
190
+ Use a card source object to keep the character description and greetings in separate Markdown files.
191
+
192
+ ```json
193
+ {
194
+ "card": {
195
+ "alternate_greetings": ["alternate_greetings/1.md", "alternate_greetings/2.md"],
196
+ "description": "description.md",
197
+ "file": "card.json",
198
+ "first_mes": "first_mes.md"
199
+ }
200
+ }
201
+ ```
202
+
203
+ - `alternate_greetings`: Alternate greeting sources in display order
204
+ - `description`: Character description source
205
+ - `file`: Optional JSON source for other character card fields
206
+ - `first_mes`: First message source
165
207
 
166
- Define Lua triggers with `lua`. Do not specify `effect`, `conditions`, or `type` for Lua triggers.
208
+ When `file` is omitted, the builder starts from an empty character card. A referenced `card.json` may contain `{}` when all required character content is stored in the external text files. Put other Character Card fields under `data`.
167
209
 
168
- - `lua`: Unbundled Lua entry file. Required.
169
- - `bundle`: Bundles the entry file and its `require()` dependencies. Defaults to `true`.
170
- - `bundleOutput`: Optional path for retaining the bundled Lua artifact.
171
- - `comment`: Trigger name. Defaults to an empty string.
172
- - `lowLevelAccess`: Enables low-level access for the trigger.
210
+ The unpack commands create character sources only when the packaged card contains character-specific values.
173
211
 
174
- Omit `bundleOutput` for normal CharX builds. The builder uses a temporary output and removes it after packaging. Set `bundleOutput` only when a standalone bundled Lua artifact is required.
212
+ ## Lorebooks
213
+
214
+ Each lorebook entry accepts the following fields.
215
+
216
+ - `activationPercent`: RisuAI activation percentage
217
+ - `alwaysActive`: Constant activation, defaulting to `false`
218
+ - `bookVersion`: Lorebook format version, defaulting to `2`
219
+ - `bundle`: Whether to bundle a Lua source and its `require()` dependencies, defaulting to `false`
220
+ - `bundleOutput`: Optional path that retains the bundled Lua output
221
+ - `comment`: Lorebook name, defaulting to the source filename
222
+ - `content`: Inline lorebook content
223
+ - `extentions`: RisuAI-specific lorebook extension values; retain this spelling
224
+ - `file`: Lorebook source path, required unless `content` is present
225
+ - `folder`: RisuAI lorebook folder name
226
+ - `insertOrder`: Insertion order, defaulting to `100`
227
+ - `key`: Comma-separated primary activation keys, defaulting to an empty string
228
+ - `mode`: RisuAI lorebook mode, defaulting to `normal`
229
+ - `secondaryKey`: Comma-separated secondary activation keys, defaulting to an empty string
230
+ - `selective`: Secondary-key matching, defaulting to `false`
231
+ - `useRegex`: Regular expression matching for activation keys, defaulting to `false`
232
+
233
+ Set `bundle` to `true` when the packaged lorebook must contain bundled Lua instead of the Lua entry source.
234
+
235
+ ```json
236
+ {
237
+ "lorebook": [
238
+ {
239
+ "alwaysActive": false,
240
+ "bundle": true,
241
+ "comment": "Renderer",
242
+ "file": "lorebooks/renderer.lua",
243
+ "insertOrder": 200
244
+ }
245
+ ]
246
+ }
247
+ ```
175
248
 
176
- Keep modules loaded through Lua `require()` beside the trigger entry point or at paths resolvable by the Lua bundler.
249
+ Omit `bundleOutput` during normal builds. The builder removes its temporary bundle after packaging.
177
250
 
178
- ## Regex entries
251
+ ## Regexes
179
252
 
180
- Store one regex entry in each Markdown file. Put RisuAI regex metadata in frontmatter and the pattern pair in the body.
253
+ Store one file-based regex entry in each Markdown file.
181
254
 
182
255
  ```md
183
256
  ---
184
- ableFlag: true
185
257
  comment: Display
186
258
  flag: gs
187
259
  type: editdisplay
@@ -193,19 +265,18 @@ OUT:
193
265
  replacement
194
266
  ```
195
267
 
196
- Use the frontmatter keys `ableFlag`, `comment`, `flag`, and `type`. Omit `flag` when the regex requires no flags. Leave the body after `OUT:` empty when the replacement is empty.
268
+ The frontmatter accepts `comment`, `flag`, and `type`. The generated RisuAI `ableFlag` value is `true` when `flag` is present and `false` when `flag` is absent. Leave the content after `OUT:` empty for an empty replacement.
197
269
 
198
- List regex file paths in execution order in the manifest `regex` array.
199
-
200
- Regex entries accept a file path, a file object, or an inline object.
270
+ Manifest entries accept a path, an object containing `file`, or inline regex data.
201
271
 
202
272
  ```json
203
273
  {
204
274
  "regex": [
205
275
  "regex/display.md",
206
- { "file": "regex/request.md" },
207
276
  {
208
- "ableFlag": true,
277
+ "file": "regex/request.md"
278
+ },
279
+ {
209
280
  "comment": "Inline",
210
281
  "flag": "gs",
211
282
  "in": "input pattern",
@@ -216,28 +287,127 @@ Regex entries accept a file path, a file object, or an inline object.
216
287
  }
217
288
  ```
218
289
 
219
- Inline regex entries require string values for both `in` and `out`. `ableFlag` defaults to `true`, `comment` defaults to an empty string, and `type` defaults to `editdisplay`.
290
+ Inline entries require string values for `in` and `out`. The presence of `flag` also controls `ableFlag` for inline entries. `comment` defaults to an empty string, and `type` defaults to `editdisplay`.
220
291
 
221
- ## Lorebooks
292
+ ## Lua triggers
293
+
294
+ Set `lua` to an unbundled Lua entry file.
295
+
296
+ ```json
297
+ {
298
+ "triggers": [
299
+ {
300
+ "bundle": true,
301
+ "comment": "Start",
302
+ "conditions": [],
303
+ "lowLevelAccess": false,
304
+ "lua": "triggers/main.lua",
305
+ "type": "start"
306
+ }
307
+ ]
308
+ }
309
+ ```
310
+
311
+ - `bundle`: Whether to bundle `require()` dependencies, defaulting to `true`
312
+ - `bundleOutput`: Optional path that retains the bundled Lua output
313
+ - `comment`: Trigger name, defaulting to an empty string
314
+ - `conditions`: RisuAI trigger conditions, defaulting to an empty array
315
+ - `lowLevelAccess`: Trigger-level low-level access
316
+ - `lua`: Lua entry file
317
+ - `type`: RisuAI trigger type, defaulting to `start`
318
+
319
+ The bundler resolves `require("lib.example")` as `lib/example.lua` relative to the Lua entry file's directory. Omit `bundleOutput` during normal builds to use a temporary bundle.
320
+
321
+ A trigger without `lua` must provide a RisuAI `effect` array directly. This form preserves triggers that cannot be represented as one Lua effect.
322
+
323
+ ## CSS and toggles
324
+
325
+ risupack copies CSS and toggle sources into the package without changing their contents.
326
+
327
+ Wrap custom styles in a `<style>` element.
222
328
 
223
- Include Markdown prompts in the manifest `lorebook` array.
329
+ ```html
330
+ <style>
331
+ .sample-panel {
332
+ color: white;
333
+ }
334
+ </style>
335
+ ```
336
+
337
+ Write one toggle definition per line.
224
338
 
225
- Set `comment` to the exact lorebook name consumed by the module. Use `folder` to group entries in RisuAI.
339
+ ```text
340
+ enabled=Enable feature
341
+ theme=Theme=select=Light,Dark
342
+ label=Label=text
343
+ ```
226
344
 
227
- Set lorebook `bundle` to `true` when RisuAI must receive bundled Lua as lorebook instead of the source file. Set lorebook `file` to the unbundled Lua entry point. Omit `bundleOutput` to remove the temporary bundle after packaging.
345
+ Checkbox values omit the type. Select values use `select` followed by comma-separated options. Text values use `text`.
228
346
 
229
347
  ## Assets
230
348
 
231
- List additional packaged files in the manifest `assets` array.
349
+ List additional packaged files in `assets`.
232
350
 
233
- - `file`: Asset source path. Required.
234
- - `name`: RisuAI asset lookup name. Defaults to the source filename without its extension.
235
- - `extension`: Packaged extension without a leading dot. Defaults to the source file extension and accepts lowercase letters and digits.
351
+ - `extension`: Packaged extension without a leading dot; defaults to the lowercase source extension and accepts ASCII letters and digits
352
+ - `file`: Required asset source path
353
+ - `name`: RisuAI asset name, defaulting to the source filename without its extension
236
354
 
237
- Archive entry names replace unsupported characters and add numeric suffixes to resolve collisions.
355
+ The builder sanitizes unsupported archive filename characters and adds numeric suffixes for collisions.
356
+
357
+ ## Reproducible builds
358
+
359
+ Set `SOURCE_DATE_EPOCH` to a Unix timestamp to fix timestamps in the generated card and ZIP entries.
360
+
361
+ ```sh
362
+ SOURCE_DATE_EPOCH=1700000000 npx risupack build-charx module/charx.json
363
+ ```
364
+
365
+ Identical inputs and a fixed source date produce byte-identical CharX files.
366
+
367
+ ## CharX contents
368
+
369
+ A built CharX contains the generated card, encoded module, assets, and asset metadata.
370
+
371
+ ```text
372
+ module.charx
373
+ ├── assets/
374
+ ├── x_meta/
375
+ ├── card.json
376
+ └── module.risum
377
+ ```
378
+
379
+ The archive always contains `card.json`, `module.risum`, and a main icon. The source manifest does not require a `card` or `icon` field.
380
+
381
+ ## Utility commands
382
+
383
+ Bundle a standalone Lua entry file.
384
+
385
+ ```sh
386
+ npx risupack bundle-lua triggers/main.lua dist/main.lua
387
+ ```
388
+
389
+ The command writes one Lua file containing resolved `require()` dependencies and the entry code.
390
+
391
+ Inspect the module records stored in a RisuSave database.
392
+
393
+ ```sh
394
+ npx risupack inspect-risusave database.bin
395
+ npx risupack inspect-risusave database.bin module-namespace
396
+ ```
397
+
398
+ The optional query matches a module namespace, name, or ID. The command writes the matching records as JSON to standard output.
238
399
 
239
400
  ## Programmatic API
240
401
 
402
+ Import commands from the package root.
403
+
404
+ ```ts
405
+ import { buildCharX, unpackCharX } from "risupack";
406
+
407
+ buildCharX("module/charx.json", "dist/module.charx");
408
+ unpackCharX("dist/module.charx", "module-unpacked");
409
+ ```
410
+
241
411
  The package exports `buildCharX()`, `bundleLua()`, `createExpandedModuleSources()`, `decodeModule()`, `parseModuleBlock()`, `parseZIP()`, `unpackCharX()`, and `unpackRisuM()`.
242
412
 
243
413
  ## License
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { a as unpackCharX, c as bundleLua, o as parseModuleBlock, s as buildCharX, t as unpackRisuM } from "./unpack-risum-CyOf_v7e.js";
2
+ import { a as unpackCharX, c as bundleLua, o as parseModuleBlock, s as buildCharX, t as unpackRisuM } from "./unpack-risum-tckgp4pg.js";
3
3
  import { readFileSync } from "node:fs";
4
4
  import { join, parse } from "node:path";
5
5
  //#region src/cli.ts
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- import { a as unpackCharX, c as bundleLua, i as parseZIP, n as createExpandedModuleSources, o as parseModuleBlock, r as decodeModule, s as buildCharX, t as unpackRisuM } from "./unpack-risum-CyOf_v7e.js";
1
+ import { a as unpackCharX, c as bundleLua, i as parseZIP, n as createExpandedModuleSources, o as parseModuleBlock, r as decodeModule, s as buildCharX, t as unpackRisuM } from "./unpack-risum-tckgp4pg.js";
2
2
  export { buildCharX, bundleLua, createExpandedModuleSources, decodeModule, parseModuleBlock, parseZIP, unpackCharX, unpackRisuM };
@@ -159,6 +159,20 @@ function readSource(manifestDirectory, source, label) {
159
159
  assert$2(typeof source.file === "string", `${label}.file must be a string`);
160
160
  return fs.readFileSync(path.resolve(manifestDirectory, source.file), "utf8");
161
161
  }
162
+ function readCard(manifest, manifestDirectory) {
163
+ if (!manifest.card) return;
164
+ if (typeof manifest.card === "string") return JSON.parse(readSource(manifestDirectory, manifest.card, "card"));
165
+ const card = "content" in manifest.card || "file" in manifest.card ? JSON.parse(readSource(manifestDirectory, manifest.card, "card")) : {};
166
+ const data = card.data ?? {};
167
+ if (manifest.card.alternate_greetings !== void 0) {
168
+ assert$2(Array.isArray(manifest.card.alternate_greetings), "card.alternate_greetings must be an array");
169
+ data.alternate_greetings = manifest.card.alternate_greetings.map((source, index) => readSource(manifestDirectory, source, `card.alternate_greetings[${index}]`));
170
+ }
171
+ if (manifest.card.description !== void 0) data.description = readSource(manifestDirectory, manifest.card.description, "card.description");
172
+ if (manifest.card.first_mes !== void 0) data.first_mes = readSource(manifestDirectory, manifest.card.first_mes, "card.first_mes");
173
+ card.data = data;
174
+ return card;
175
+ }
162
176
  function sanitizeArchiveName(name) {
163
177
  return Array.from(name, (character) => character.charCodeAt(0) < 32 ? "_" : character).join("").replace(/[<>:"/\\|?*]/g, "_").trim().slice(0, 100) || "asset";
164
178
  }
@@ -205,7 +219,7 @@ function parseRegexDocument(content, fileName) {
205
219
  const { body, metadata } = parseFrontmatter(content, fileName);
206
220
  const parsed = parseRegexBody(body, fileName);
207
221
  return {
208
- ableFlag: metadata.ableFlag ?? true,
222
+ ableFlag: metadata.flag !== void 0,
209
223
  comment: metadata.comment ?? "",
210
224
  flag: metadata.flag,
211
225
  in: parsed.in,
@@ -223,7 +237,7 @@ function buildRegexScripts(manifestDirectory, regexGroups = []) {
223
237
  if (group.in !== void 0 || group.out !== void 0) {
224
238
  assert$2(typeof group.in === "string" && typeof group.out === "string", "Inline regex entries require in and out");
225
239
  scripts.push({
226
- ableFlag: group.ableFlag ?? true,
240
+ ableFlag: group.flag !== void 0,
227
241
  comment: group.comment ?? "",
228
242
  flag: group.flag,
229
243
  in: group.in,
@@ -564,7 +578,7 @@ function buildCharX(manifestPath, outputArgument) {
564
578
  const regex = buildRegexScripts(manifestDirectory, manifest.regex);
565
579
  const trigger = buildTriggers(manifest, manifestDirectory);
566
580
  const { cardAssets, files: assetFiles } = createAssetFiles(manifest, manifestDirectory);
567
- const card = createCard(manifest, lorebook, cardAssets, manifest.card ? JSON.parse(readSource(manifestDirectory, manifest.card, "card")) : void 0);
581
+ const card = createCard(manifest, lorebook, cardAssets, readCard(manifest, manifestDirectory));
568
582
  const module = {
569
583
  description: `Module for ${manifest.name}`,
570
584
  id: createUUID(`${manifest.namespace ?? manifest.name}:module`),
@@ -710,11 +724,96 @@ function takeSourcePath(directory, label, extension, takenPaths) {
710
724
  return candidate;
711
725
  }
712
726
  function createRegexDocument(regex) {
713
- const frontmatter = [`ableFlag: ${regex.ableFlag ?? true}`, `comment: ${regex.comment ?? ""}`];
727
+ const frontmatter = [`comment: ${regex.comment ?? ""}`];
714
728
  if (regex.flag !== void 0) frontmatter.push(`flag: ${regex.flag}`);
715
729
  frontmatter.push(`type: ${regex.type ?? "editdisplay"}`);
716
730
  return `---\n${frontmatter.join("\n")}\n---\n\nIN:\n${regex.in ?? ""}\nOUT:\n${regex.out ?? ""}\n`;
717
731
  }
732
+ function createCardSources(card, files) {
733
+ const sourceCard = JSON.parse(JSON.stringify(card));
734
+ const data = sourceCard.data ?? {};
735
+ const risuai = data.extensions?.risuai;
736
+ const alternateGreetings = data.alternate_greetings ?? [];
737
+ assert$1(Array.isArray(alternateGreetings), "card.data.alternate_greetings must be an array");
738
+ for (let index = 0; index < alternateGreetings.length; index += 1) {
739
+ const greeting = alternateGreetings[index];
740
+ assert$1(typeof greeting === "string", `card.data.alternate_greetings[${index}] must be a string`);
741
+ }
742
+ const description = data.description ?? "";
743
+ const firstMessage = data.first_mes ?? "";
744
+ assert$1(typeof description === "string", "card.data.description must be a string");
745
+ assert$1(typeof firstMessage === "string", "card.data.first_mes must be a string");
746
+ delete data.alternate_greetings;
747
+ delete data.assets;
748
+ delete data.character_book;
749
+ delete data.character_version;
750
+ delete data.creator;
751
+ delete data.creator_notes;
752
+ delete data.description;
753
+ delete data.first_mes;
754
+ delete data.modification_date;
755
+ delete data.name;
756
+ delete data.tags;
757
+ if (risuai) {
758
+ delete risuai.backgroundHTML;
759
+ delete risuai.hideChatIcon;
760
+ delete risuai.license;
761
+ delete risuai.lowLevelAccess;
762
+ delete risuai.moduleNamespace;
763
+ delete risuai.toggles;
764
+ for (const [key, value] of Object.entries({
765
+ additionalText: "",
766
+ bias: [],
767
+ defaultVariables: "",
768
+ inlayViewScreen: false,
769
+ largePortrait: false,
770
+ lorePlus: false,
771
+ prebuiltAssetCommand: "",
772
+ prebuiltAssetExclude: [],
773
+ prebuiltAssetStyle: "",
774
+ sdData: [],
775
+ utilityBot: false,
776
+ viewScreen: "none",
777
+ virtualscript: "",
778
+ vits: {}
779
+ })) if (JSON.stringify(sortKeysDeep(risuai[key])) === JSON.stringify(sortKeysDeep(value))) delete risuai[key];
780
+ if (Object.keys(risuai).length === 0) delete data.extensions.risuai;
781
+ }
782
+ if (data.extensions) {
783
+ delete data.extensions.moduleNoneImage;
784
+ if (Object.keys(data.extensions).length === 0) delete data.extensions;
785
+ }
786
+ for (const [key, value] of Object.entries({
787
+ creation_date: 0,
788
+ group_only_greetings: [],
789
+ mes_example: "",
790
+ nickname: "",
791
+ personality: "",
792
+ post_history_instructions: "",
793
+ scenario: "",
794
+ source: [],
795
+ system_prompt: ""
796
+ })) if (JSON.stringify(sortKeysDeep(data[key])) === JSON.stringify(sortKeysDeep(value))) delete data[key];
797
+ if (Object.keys(data).length === 0) delete sourceCard.data;
798
+ else sourceCard.data = data;
799
+ if (sourceCard.spec === "chara_card_v3") delete sourceCard.spec;
800
+ if (sourceCard.spec_version === "3.0") delete sourceCard.spec_version;
801
+ if (!(alternateGreetings.length > 0 || description !== "" || firstMessage !== "" || Object.keys(sourceCard).length > 0)) return;
802
+ const alternateGreetingFiles = alternateGreetings.map((greeting, index) => {
803
+ const file = `alternate_greetings/${index + 1}.md`;
804
+ files.set(file, Buffer.from(greeting, "utf8"));
805
+ return file;
806
+ });
807
+ files.set("description.md", Buffer.from(description, "utf8"));
808
+ files.set("first_mes.md", Buffer.from(firstMessage, "utf8"));
809
+ files.set("card.json", Buffer.from(`${JSON.stringify(sortKeysDeep(sourceCard), null, 2)}\n`, "utf8"));
810
+ return {
811
+ alternate_greetings: alternateGreetingFiles,
812
+ description: "description.md",
813
+ file: "card.json",
814
+ first_mes: "first_mes.md"
815
+ };
816
+ }
718
817
  function createExpandedModuleSources(card, decodedModule) {
719
818
  const moduleData = decodedModule.module;
720
819
  const files = /* @__PURE__ */ new Map();
@@ -774,7 +873,7 @@ function createExpandedModuleSources(card, decodedModule) {
774
873
  }
775
874
  const risuai = card.data?.extensions?.risuai ?? {};
776
875
  const manifest = {
777
- card: "card.json",
876
+ card: createCardSources(card, files),
778
877
  creator: card.data?.creator,
779
878
  description: card.data?.creator_notes ?? moduleData.description ?? "",
780
879
  folders,
@@ -912,11 +1011,11 @@ function unpackCharX(inputPath, outputPath) {
912
1011
  decodedModule = decodeModule(moduleEntry.data, map);
913
1012
  }
914
1013
  const expandedSources = decodedModule ? createExpandedModuleSources(card, decodedModule) : /* @__PURE__ */ new Map();
915
- for (const name of expandedSources.keys()) assert$1(!extracted.has(name), `Generated module source conflicts with an archive entry: ${name}`);
1014
+ for (const name of expandedSources.keys()) assert$1(name === "card.json" || !extracted.has(name), `Generated module source conflicts with an archive entry: ${name}`);
916
1015
  assertEmptyOutputDirectory$1(resolvedOutputPath);
917
1016
  fs.mkdirSync(resolvedOutputPath, { recursive: true });
918
1017
  for (const [name, entry] of extracted) {
919
- if (name === "module.risum") continue;
1018
+ if (name === "module.risum" || decodedModule && name === "card.json" || expandedSources.has(name)) continue;
920
1019
  const destination = path.join(resolvedOutputPath, ...name.split("/"));
921
1020
  if (entry.directory) {
922
1021
  fs.mkdirSync(destination, { recursive: true });
@@ -1055,4 +1154,4 @@ function unpackRisuM(inputPath, outputPath) {
1055
1154
  //#endregion
1056
1155
  export { unpackCharX as a, bundleLua as c, parseZIP as i, createExpandedModuleSources as n, parseModuleBlock as o, decodeModule as r, buildCharX as s, unpackRisuM as t };
1057
1156
 
1058
- //# sourceMappingURL=unpack-risum-CyOf_v7e.js.map
1157
+ //# sourceMappingURL=unpack-risum-tckgp4pg.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unpack-risum-tckgp4pg.js","names":[],"sources":["../src/bundle.ts","../src/build-charx.ts","../src/inspect-risusave.ts","../src/unpack-charx.ts","../src/unpack-risum.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\n\nconst REQUIRE_PATTERN = /require\\s*\\(?[\"']([^\"']+)[\"']\\)?/g;\n\ninterface BundleState {\n entryPath: string;\n hoistedComments: string[];\n includedModules: Set<string>;\n preloads: string[];\n totalInputBytes: number;\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes === 0) {\n return \"0 B\";\n }\n\n const base = 1024;\n const sizes = [\"B\", \"KB\", \"MB\"];\n const index = Math.floor(Math.log(bytes) / Math.log(base));\n return `${Number.parseFloat((bytes / Math.pow(base, index)).toFixed(2))} ${sizes[index]}`;\n}\n\nfunction resolveModulePath(moduleName: string): string {\n return `${moduleName.replace(/\\./g, \"/\")}.lua`;\n}\n\nfunction minifyLua(content: string, hoistedComments: string[]): string {\n const tokenPattern =\n /(--\\[(=*)\\[[\\s\\S]*?\\]\\2\\])|(--.*)|(\\[(=*)\\[[\\s\\S]*?\\]\\5\\])|(\"([^\"\\\\]|\\\\.)*\")|('([^'\\\\]|\\\\.)*')/g;\n\n return content\n .replace(\n tokenPattern,\n (match: string, longComment?: string, _equals?: string, shortComment?: string) => {\n if (!longComment && !shortComment) {\n return match;\n }\n if (shortComment?.startsWith(\"--!\") || (longComment && /^--\\[(=*)\\[!/.test(match))) {\n hoistedComments.push(match);\n }\n return \" \";\n },\n )\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line.length > 0)\n .join(\"\\n\");\n}\n\nfunction processModule(moduleName: string, state: BundleState): void {\n if (state.includedModules.has(moduleName)) {\n return;\n }\n\n const rootDirectory = path.dirname(path.resolve(state.entryPath));\n const modulePath = path.join(rootDirectory, resolveModulePath(moduleName));\n if (!fs.existsSync(modulePath)) {\n console.warn(`Warning: Module '${moduleName}' not found`);\n return;\n }\n\n const rawContent = fs.readFileSync(modulePath, \"utf8\");\n state.includedModules.add(moduleName);\n state.totalInputBytes += fs.statSync(modulePath).size;\n\n for (const match of rawContent.matchAll(new RegExp(REQUIRE_PATTERN.source, \"g\"))) {\n const dependency = match[1];\n if (dependency) {\n processModule(dependency, state);\n }\n }\n\n const minifiedContent = minifyLua(rawContent, state.hoistedComments);\n state.preloads.push(`package.preload[\"${moduleName}\"]=function(...)${minifiedContent} end`);\n}\n\nfunction bundleLua(entryPath: string, outputArgument: string): string {\n const resolvedEntryPath = path.resolve(entryPath);\n if (!fs.existsSync(resolvedEntryPath)) {\n throw new Error(`Entry file not found: ${entryPath}`);\n }\n\n let outputPath = path.resolve(outputArgument);\n if (fs.existsSync(outputPath) && fs.statSync(outputPath).isDirectory()) {\n outputPath = path.join(outputPath, path.basename(resolvedEntryPath));\n }\n if (path.extname(outputPath) !== \".lua\") {\n outputPath += \".lua\";\n }\n\n const state: BundleState = {\n entryPath: resolvedEntryPath,\n hoistedComments: [],\n includedModules: new Set(),\n preloads: [],\n totalInputBytes: fs.statSync(resolvedEntryPath).size,\n };\n const mainContent = fs.readFileSync(resolvedEntryPath, \"utf8\");\n\n for (const match of mainContent.matchAll(new RegExp(REQUIRE_PATTERN.source, \"g\"))) {\n const moduleName = match[1];\n if (moduleName) {\n processModule(moduleName, state);\n }\n }\n\n const mainMinified = minifyLua(mainContent, state.hoistedComments);\n const hoisted = state.hoistedComments.length > 0 ? `${state.hoistedComments.join(\"\\n\")}\\n` : \"\";\n const output = `${hoisted}${state.preloads.join(\"\\n\")}\\n${mainMinified}`;\n\n fs.mkdirSync(path.dirname(outputPath), { recursive: true });\n fs.writeFileSync(outputPath, output, \"utf8\");\n\n const outputBytes = fs.statSync(outputPath).size;\n const reduction = ((state.totalInputBytes - outputBytes) / state.totalInputBytes) * 100;\n console.log(\n `Bundled ${path.relative(process.cwd(), resolvedEntryPath)} to ${path.relative(process.cwd(), outputPath)}`,\n );\n console.log(\n `${state.includedModules.size} modules, ${formatBytes(state.totalInputBytes)} to ${formatBytes(outputBytes)}, ${reduction.toFixed(2)}% reduction`,\n );\n return outputPath;\n}\n\nexport { bundleLua };\n","import crypto from \"node:crypto\";\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport zlib from \"node:zlib\";\n\nimport { bundleLua } from \"./bundle.js\";\n\nconst DEFAULT_ICON = Buffer.from(\n \"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M/wHwAEAQH/69v17QAAAABJRU5ErkJggg==\",\n \"base64\",\n);\nconst RPACK_MAP_PATH = path.join(\n path.dirname(fileURLToPath(import.meta.url)),\n \"..\",\n \"vendor\",\n \"rpack\",\n \"rpack_map.bin\",\n);\n\nconst CRC32_TABLE = (() => {\n const table = new Uint32Array(256);\n for (let index = 0; index < table.length; index += 1) {\n let value = index;\n for (let bit = 0; bit < 8; bit += 1) {\n if ((value & 1) !== 0) {\n value = 0xedb88320 ^ (value >>> 1);\n } else {\n value >>>= 1;\n }\n }\n table[index] = value >>> 0;\n }\n return table;\n})();\n\nfunction assert(condition: unknown, message: string): asserts condition {\n if (!condition) {\n throw new Error(message);\n }\n}\n\nfunction calculateCRC32(data) {\n let value = 0xffffffff;\n for (const byte of data) {\n value = CRC32_TABLE[(value ^ byte) & 0xff] ^ (value >>> 8);\n }\n return (value ^ 0xffffffff) >>> 0;\n}\n\nfunction createUUID(seed) {\n const bytes = crypto.createHash(\"sha256\").update(seed).digest().subarray(0, 16);\n bytes[6] = (bytes[6] & 0x0f) | 0x50;\n bytes[8] = (bytes[8] & 0x3f) | 0x80;\n const hex = bytes.toString(\"hex\");\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n}\n\nfunction detectImageType(data) {\n if (data.subarray(0, 8).equals(Buffer.from(\"89504e470d0a1a0a\", \"hex\"))) {\n return \"PNG\";\n }\n if (data.subarray(0, 3).equals(Buffer.from(\"ffd8ff\", \"hex\"))) {\n return \"JPEG\";\n }\n if (\n data.subarray(0, 6).toString(\"ascii\") === \"GIF87a\" ||\n data.subarray(0, 6).toString(\"ascii\") === \"GIF89a\"\n ) {\n return \"GIF\";\n }\n if (\n data.subarray(0, 4).toString(\"ascii\") === \"RIFF\" &&\n data.subarray(8, 12).toString(\"ascii\") === \"WEBP\"\n ) {\n return \"WEBP\";\n }\n return \"Unknown\";\n}\n\nfunction getAssetCategory(extension) {\n const audio = new Set([\"flac\", \"mp3\", \"ogg\", \"wav\"]);\n const code = new Set([\"js\", \"lua\", \"ts\"]);\n const fonts = new Set([\"otf\", \"ttf\", \"woff\", \"woff2\"]);\n const images = new Set([\"avif\", \"gif\", \"jpeg\", \"jpg\", \"png\", \"webp\"]);\n const models = new Set([\"mmd\", \"obj\"]);\n const video = new Set([\"avi\", \"mkv\", \"mov\", \"mp4\", \"webm\"]);\n\n if (audio.has(extension)) {\n return \"audio\";\n }\n if (code.has(extension)) {\n return \"code\";\n }\n if (fonts.has(extension)) {\n return \"fonts\";\n }\n if (images.has(extension)) {\n return \"image\";\n }\n if (models.has(extension)) {\n return \"model\";\n }\n if (extension === \"onnx\" || extension === \"safetensors\" || extension === \"cpkt\") {\n return \"ai\";\n }\n if (video.has(extension)) {\n return \"video\";\n }\n return \"other\";\n}\n\nfunction readSource(manifestDirectory, source, label) {\n if (typeof source === \"string\") {\n return fs.readFileSync(path.resolve(manifestDirectory, source), \"utf8\");\n }\n assert(source && typeof source === \"object\", `${label} must be a file path or source object`);\n if (typeof source.content === \"string\") {\n return source.content;\n }\n assert(typeof source.file === \"string\", `${label}.file must be a string`);\n return fs.readFileSync(path.resolve(manifestDirectory, source.file), \"utf8\");\n}\n\nfunction readCard(manifest, manifestDirectory) {\n if (!manifest.card) {\n return undefined;\n }\n\n if (typeof manifest.card === \"string\") {\n return JSON.parse(readSource(manifestDirectory, manifest.card, \"card\"));\n }\n\n const baseSourcePresent = \"content\" in manifest.card || \"file\" in manifest.card;\n const card = baseSourcePresent\n ? JSON.parse(readSource(manifestDirectory, manifest.card, \"card\"))\n : {};\n const data = card.data ?? {};\n if (manifest.card.alternate_greetings !== undefined) {\n assert(\n Array.isArray(manifest.card.alternate_greetings),\n \"card.alternate_greetings must be an array\",\n );\n data.alternate_greetings = manifest.card.alternate_greetings.map((source, index) =>\n readSource(manifestDirectory, source, `card.alternate_greetings[${index}]`),\n );\n }\n if (manifest.card.description !== undefined) {\n data.description = readSource(manifestDirectory, manifest.card.description, \"card.description\");\n }\n if (manifest.card.first_mes !== undefined) {\n data.first_mes = readSource(manifestDirectory, manifest.card.first_mes, \"card.first_mes\");\n }\n card.data = data;\n return card;\n}\n\nfunction sanitizeArchiveName(name: string): string {\n const sanitized = Array.from(name, (character) =>\n character.charCodeAt(0) < 32 ? \"_\" : character,\n )\n .join(\"\")\n .replace(/[<>:\"/\\\\|?*]/g, \"_\")\n .trim();\n return sanitized.slice(0, 100) || \"asset\";\n}\n\nfunction sortKeysDeep(value) {\n if (Array.isArray(value)) {\n return value.map(sortKeysDeep);\n }\n if (value && typeof value === \"object\" && !Buffer.isBuffer(value)) {\n const sorted = {};\n for (const key of Object.keys(value).sort()) {\n if (value[key] !== undefined) {\n sorted[key] = sortKeysDeep(value[key]);\n }\n }\n return sorted;\n }\n return value;\n}\n\nfunction parseFrontmatter(content, fileName) {\n const normalized = content.replace(/\\r\\n/g, \"\\n\");\n assert(normalized.startsWith(\"---\\n\"), `Missing frontmatter in ${fileName}`);\n const end = normalized.indexOf(\"\\n---\\n\", 4);\n assert(end !== -1, `Unclosed frontmatter in ${fileName}`);\n const metadata: Record<string, string | boolean> = {};\n for (const line of normalized.slice(4, end).split(\"\\n\")) {\n if (line.trim() === \"\") {\n continue;\n }\n const separator = line.indexOf(\":\");\n assert(separator !== -1, `Invalid frontmatter line in ${fileName}: ${line}`);\n const key = line.slice(0, separator).trim();\n const rawValue = line.slice(separator + 1).trim();\n assert(key !== \"\", `Empty frontmatter key in ${fileName}`);\n if (rawValue === \"true\") {\n metadata[key] = true;\n } else if (rawValue === \"false\") {\n metadata[key] = false;\n } else {\n metadata[key] = rawValue;\n }\n }\n return {\n body: normalized.slice(end + 5),\n metadata,\n };\n}\n\nfunction parseRegexBody(content, fileName) {\n const normalized = content.replace(/^\\n+/, \"\").replace(/\\n$/, \"\");\n const match = normalized.match(/^IN:\\s*\\n([\\s\\S]*?)\\nOUT:\\s*(?:\\n([\\s\\S]*))?$/);\n assert(match, `Invalid regex body in ${fileName}`);\n return {\n in: match[1],\n out: match[2] ?? \"\",\n };\n}\n\nfunction parseRegexDocument(content, fileName) {\n const { body, metadata } = parseFrontmatter(content, fileName);\n const parsed = parseRegexBody(body, fileName);\n return {\n ableFlag: metadata.flag !== undefined,\n comment: metadata.comment ?? \"\",\n flag: metadata.flag,\n in: parsed.in,\n out: parsed.out,\n type: metadata.type ?? \"editdisplay\",\n };\n}\n\nfunction buildRegexScripts(manifestDirectory, regexGroups: any[] = []) {\n const scripts: any[] = [];\n for (const group of regexGroups) {\n if (typeof group === \"string\") {\n scripts.push(\n parseRegexDocument(readSource(manifestDirectory, group, `regex ${group}`), group),\n );\n continue;\n }\n if (group.in !== undefined || group.out !== undefined) {\n assert(\n typeof group.in === \"string\" && typeof group.out === \"string\",\n \"Inline regex entries require in and out\",\n );\n scripts.push({\n ableFlag: group.flag !== undefined,\n comment: group.comment ?? \"\",\n flag: group.flag,\n in: group.in,\n out: group.out,\n type: group.type ?? \"editdisplay\",\n });\n continue;\n }\n\n assert(\n typeof group.file === \"string\",\n \"Regex entries require a file path, or inline in and out fields\",\n );\n scripts.push(\n parseRegexDocument(\n readSource(manifestDirectory, group.file, `regex ${group.file}`),\n group.file,\n ),\n );\n }\n return scripts;\n}\n\nfunction buildLorebook(manifest, manifestDirectory) {\n const folderKeys = new Map<string, string>();\n const folderNames = new Set<string>(manifest.folders ?? []);\n for (const entry of manifest.lorebook ?? []) {\n if (entry.folder) {\n folderNames.add(entry.folder);\n }\n }\n for (const name of folderNames) {\n folderKeys.set(\n name,\n `\\uf000folder:${createUUID(`${manifest.namespace ?? manifest.name}:folder:${name}`)}`,\n );\n }\n\n const temporaryDirectory = fs.mkdtempSync(path.join(os.tmpdir(), \"risums-charx-lorebook-\"));\n try {\n const lorebook = (manifest.lorebook ?? []).map((entry, index) => {\n let content;\n if (entry.bundle) {\n assert(\n typeof entry.file === \"string\",\n `Bundled lorebook ${entry.comment ?? index + 1} requires a file`,\n );\n const entryPath = path.resolve(manifestDirectory, entry.file);\n const outputPath = entry.bundleOutput\n ? path.resolve(manifestDirectory, entry.bundleOutput)\n : path.join(temporaryDirectory, `lorebook-${index}.lua`);\n content = readBundledLua(entryPath, outputPath);\n } else {\n content = readSource(\n manifestDirectory,\n entry,\n `lorebook ${entry.comment ?? entry.file ?? \"\"}`,\n );\n }\n return {\n activationPercent: entry.activationPercent,\n alwaysActive: entry.alwaysActive ?? false,\n bookVersion: entry.bookVersion ?? 2,\n comment: entry.comment ?? path.basename(entry.file ?? \"Lorebook\"),\n content,\n extentions: entry.extentions,\n folder: entry.folder ? folderKeys.get(entry.folder) : undefined,\n insertorder: entry.insertOrder ?? 100,\n key: entry.key ?? \"\",\n mode: entry.mode ?? \"normal\",\n secondkey: entry.secondaryKey ?? \"\",\n selective: entry.selective ?? false,\n useRegex: entry.useRegex ?? false,\n };\n });\n\n for (const name of folderNames) {\n lorebook.push({\n alwaysActive: false,\n bookVersion: 2,\n comment: name,\n content: \"\",\n insertorder: 100,\n key: folderKeys.get(name),\n mode: \"folder\",\n secondkey: \"\",\n selective: false,\n useRegex: false,\n });\n }\n return lorebook;\n } finally {\n fs.rmSync(temporaryDirectory, { force: true, recursive: true });\n }\n}\n\nfunction readBundledLua(entryPath: string, outputPath: string): string {\n bundleLua(entryPath, outputPath);\n return fs.readFileSync(outputPath, \"utf8\");\n}\n\nfunction buildTriggers(manifest, manifestDirectory) {\n const temporaryDirectory = fs.mkdtempSync(path.join(os.tmpdir(), \"risums-charx-\"));\n try {\n return (manifest.triggers ?? []).map((trigger, index) => {\n let effect = trigger.effect;\n if (trigger.lua) {\n const entryPath = path.resolve(manifestDirectory, trigger.lua);\n let code;\n if (trigger.bundle ?? true) {\n const outputPath = trigger.bundleOutput\n ? path.resolve(manifestDirectory, trigger.bundleOutput)\n : path.join(temporaryDirectory, `trigger-${index}.lua`);\n code = readBundledLua(entryPath, outputPath);\n } else {\n code = fs.readFileSync(entryPath, \"utf8\");\n }\n effect = [{ code, type: \"triggerlua\" }];\n }\n assert(Array.isArray(effect), `Trigger ${index + 1} requires lua or effect`);\n return {\n comment: trigger.comment ?? \"\",\n conditions: trigger.conditions ?? [],\n effect,\n lowLevelAccess: trigger.lowLevelAccess,\n type: trigger.type ?? \"start\",\n };\n });\n } finally {\n fs.rmSync(temporaryDirectory, { force: true, recursive: true });\n }\n}\n\nfunction createRisuM(module, encodeMap) {\n const payload = Buffer.from(\n JSON.stringify(sortKeysDeep({ module, type: \"risuModule\" }), null, 2),\n \"utf8\",\n );\n const encoded = Buffer.allocUnsafe(payload.length);\n for (let index = 0; index < payload.length; index += 1) {\n encoded[index] = encodeMap[payload[index]];\n }\n const header = Buffer.alloc(6);\n header.writeUInt8(111, 0);\n header.writeUInt8(0, 1);\n header.writeUInt32LE(encoded.length, 2);\n return Buffer.concat([header, encoded, Buffer.from([0])]);\n}\n\nfunction createAssetFiles(manifest, manifestDirectory) {\n const cardAssets: any[] = [];\n const files: Array<{ data: Buffer; name: string }> = [];\n const takenNames = new Set<string>();\n\n function addAsset({ data, extension, name, type }) {\n const category = getAssetCategory(extension);\n const baseDirectory = `assets/${type === \"icon\" ? \"icon\" : \"other\"}/${category}`;\n const baseName = sanitizeArchiveName(name);\n let archiveName = baseName;\n let suffix = 0;\n while (takenNames.has(archiveName)) {\n suffix += 1;\n archiveName = `${baseName}_${suffix}`;\n }\n const archivePath = `${baseDirectory}/${archiveName}.${extension}`;\n takenNames.add(archiveName);\n cardAssets.push({\n ext: extension,\n name,\n type,\n uri: `embeded://${archivePath}`,\n });\n files.push({ data, name: archivePath });\n files.push({\n data: Buffer.from(JSON.stringify({ type: detectImageType(data) }, null, 2)),\n name: `x_meta/${archiveName}.json`,\n });\n }\n\n if (manifest.icon) {\n const iconPath = path.resolve(manifestDirectory, manifest.icon);\n const extension = path.extname(iconPath).slice(1).toLowerCase() || \"png\";\n addAsset({ data: fs.readFileSync(iconPath), extension, name: \"main\", type: \"icon\" });\n } else {\n addAsset({ data: DEFAULT_ICON, extension: \"png\", name: \"main\", type: \"icon\" });\n }\n\n for (const asset of manifest.assets ?? []) {\n assert(typeof asset.file === \"string\", \"Asset file must be a string\");\n const assetPath = path.resolve(manifestDirectory, asset.file);\n const extension = (asset.extension ?? path.extname(assetPath).slice(1)).toLowerCase();\n assert(extension !== \"\", `Cannot determine extension for ${asset.file}`);\n assert(/^[a-z0-9]+$/.test(extension), `Invalid extension for ${asset.file}: ${extension}`);\n addAsset({\n data: fs.readFileSync(assetPath),\n extension,\n name: asset.name ?? path.basename(assetPath, path.extname(assetPath)),\n type: \"x-risu-asset\",\n });\n }\n return { cardAssets, files };\n}\n\nfunction createCard(manifest, lorebook, cardAssets, sourceCard?: Record<string, any>) {\n const sourceData = sourceCard?.data ?? {};\n const sourceExtensions = sourceData.extensions ?? {};\n const sourceRisuAI = sourceExtensions.risuai ?? {};\n const entries = lorebook.map((entry) => ({\n case_sensitive: entry.extentions?.risu_case_sensitive ?? false,\n comment: entry.comment,\n constant: entry.alwaysActive,\n content: entry.content,\n enabled: true,\n extensions: {\n ...entry.extentions,\n risu_activationPercent: entry.activationPercent,\n risu_loreCache: entry.loreCache,\n },\n folder: entry.folder,\n insertion_order: entry.insertorder,\n keys: entry.key.split(\",\").map((key) => key.trim()),\n mode: entry.mode,\n name: entry.comment,\n secondary_keys: entry.selective\n ? entry.secondkey.split(\",\").map((key) => key.trim())\n : undefined,\n selective: entry.selective,\n use_regex: entry.useRegex,\n }));\n return {\n ...sourceCard,\n data: {\n ...sourceData,\n alternate_greetings: sourceData.alternate_greetings ?? [],\n assets: cardAssets,\n character_book: {\n entries,\n extensions: { risu_fullWordMatching: false },\n },\n character_version: manifest.version ?? sourceData.character_version ?? \"\",\n creation_date: sourceData.creation_date ?? 0,\n creator: manifest.creator ?? sourceData.creator ?? \"\",\n creator_notes: manifest.description ?? sourceData.creator_notes ?? \"\",\n description: sourceData.description ?? \"\",\n extensions: {\n ...sourceExtensions,\n moduleNoneImage: manifest.icon ? undefined : true,\n risuai: {\n ...sourceRisuAI,\n additionalText: sourceRisuAI.additionalText ?? \"\",\n backgroundHTML: manifest.CSS\n ? readSource(path.dirname(manifest.__path), manifest.CSS, \"CSS\")\n : \"\",\n bias: sourceRisuAI.bias ?? [],\n defaultVariables: sourceRisuAI.defaultVariables ?? \"\",\n hideChatIcon: manifest.hideIcon ?? false,\n inlayViewScreen: sourceRisuAI.inlayViewScreen ?? false,\n largePortrait: sourceRisuAI.largePortrait ?? false,\n license: manifest.license ?? \"\",\n lorePlus: sourceRisuAI.lorePlus ?? false,\n lowLevelAccess: manifest.lowLevelAccess ?? false,\n moduleNamespace: manifest.namespace,\n newGenData: sourceRisuAI.newGenData,\n prebuiltAssetCommand: sourceRisuAI.prebuiltAssetCommand ?? \"\",\n prebuiltAssetExclude: sourceRisuAI.prebuiltAssetExclude ?? [],\n prebuiltAssetStyle: sourceRisuAI.prebuiltAssetStyle ?? \"\",\n sdData: sourceRisuAI.sdData ?? [],\n toggles: manifest.toggles\n ? readSource(path.dirname(manifest.__path), manifest.toggles, \"toggles\")\n : \"\",\n utilityBot: sourceRisuAI.utilityBot ?? false,\n viewScreen: \"none\",\n virtualscript: sourceRisuAI.virtualscript ?? \"\",\n vits: sourceRisuAI.vits ?? {},\n },\n },\n first_mes: sourceData.first_mes ?? \"\",\n group_only_greetings: sourceData.group_only_greetings ?? [],\n mes_example: sourceData.mes_example ?? \"\",\n modification_date: process.env.SOURCE_DATE_EPOCH\n ? Number(process.env.SOURCE_DATE_EPOCH)\n : Math.floor(Date.now() / 1000),\n name: manifest.name,\n nickname: sourceData.nickname ?? \"\",\n personality: sourceData.personality ?? \"\",\n post_history_instructions: sourceData.post_history_instructions ?? \"\",\n scenario: sourceData.scenario ?? \"\",\n source: sourceData.source ?? [],\n system_prompt: sourceData.system_prompt ?? \"\",\n tags: manifest.tags ?? sourceData.tags ?? [],\n },\n spec: sourceCard?.spec ?? \"chara_card_v3\",\n spec_version: sourceCard?.spec_version ?? \"3.0\",\n };\n}\n\nfunction getDOSDateTime(date) {\n const year = Math.max(1980, date.getUTCFullYear());\n return {\n date: ((year - 1980) << 9) | ((date.getUTCMonth() + 1) << 5) | date.getUTCDate(),\n time:\n (date.getUTCHours() << 11) |\n (date.getUTCMinutes() << 5) |\n Math.floor(date.getUTCSeconds() / 2),\n };\n}\n\nfunction createZIP(files, timestamp) {\n assert(files.length <= 0xffff, \"ZIP contains too many files\");\n const centralRecords: Buffer[] = [];\n const localRecords: Buffer[] = [];\n let offset = 0;\n const { date, time } = getDOSDateTime(timestamp);\n\n for (const file of files) {\n const data = Buffer.from(file.data);\n const compressed = zlib.deflateRawSync(data, { level: 6 });\n const fileName = Buffer.from(file.name.replace(/\\\\/g, \"/\"), \"utf8\");\n const CRC32 = calculateCRC32(data);\n assert(\n data.length <= 0xffffffff && compressed.length <= 0xffffffff,\n `${file.name} exceeds ZIP32 limits`,\n );\n\n const localHeader = Buffer.alloc(30);\n localHeader.writeUInt32LE(0x04034b50, 0);\n localHeader.writeUInt16LE(20, 4);\n localHeader.writeUInt16LE(0x0800, 6);\n localHeader.writeUInt16LE(8, 8);\n localHeader.writeUInt16LE(time, 10);\n localHeader.writeUInt16LE(date, 12);\n localHeader.writeUInt32LE(CRC32, 14);\n localHeader.writeUInt32LE(compressed.length, 18);\n localHeader.writeUInt32LE(data.length, 22);\n localHeader.writeUInt16LE(fileName.length, 26);\n localHeader.writeUInt16LE(0, 28);\n localRecords.push(localHeader, fileName, compressed);\n\n const centralHeader = Buffer.alloc(46);\n centralHeader.writeUInt32LE(0x02014b50, 0);\n centralHeader.writeUInt16LE(20, 4);\n centralHeader.writeUInt16LE(20, 6);\n centralHeader.writeUInt16LE(0x0800, 8);\n centralHeader.writeUInt16LE(8, 10);\n centralHeader.writeUInt16LE(time, 12);\n centralHeader.writeUInt16LE(date, 14);\n centralHeader.writeUInt32LE(CRC32, 16);\n centralHeader.writeUInt32LE(compressed.length, 20);\n centralHeader.writeUInt32LE(data.length, 24);\n centralHeader.writeUInt16LE(fileName.length, 28);\n centralHeader.writeUInt16LE(0, 30);\n centralHeader.writeUInt16LE(0, 32);\n centralHeader.writeUInt16LE(0, 34);\n centralHeader.writeUInt16LE(0, 36);\n centralHeader.writeUInt32LE(0, 38);\n centralHeader.writeUInt32LE(offset, 42);\n centralRecords.push(centralHeader, fileName);\n offset += localHeader.length + fileName.length + compressed.length;\n }\n\n const centralDirectory = Buffer.concat(centralRecords);\n const end = Buffer.alloc(22);\n end.writeUInt32LE(0x06054b50, 0);\n end.writeUInt16LE(0, 4);\n end.writeUInt16LE(0, 6);\n end.writeUInt16LE(files.length, 8);\n end.writeUInt16LE(files.length, 10);\n end.writeUInt32LE(centralDirectory.length, 12);\n end.writeUInt32LE(offset, 16);\n end.writeUInt16LE(0, 20);\n return Buffer.concat([...localRecords, centralDirectory, end]);\n}\n\nfunction buildCharX(manifestPath: string, outputArgument?: string): string {\n const resolvedManifestPath = path.resolve(manifestPath);\n const manifestDirectory = path.dirname(resolvedManifestPath);\n const manifest = JSON.parse(fs.readFileSync(resolvedManifestPath, \"utf8\"));\n manifest.__path = resolvedManifestPath;\n assert(typeof manifest.name === \"string\" && manifest.name !== \"\", \"Manifest name is required\");\n\n const lorebook = buildLorebook(manifest, manifestDirectory);\n const regex = buildRegexScripts(manifestDirectory, manifest.regex);\n const trigger = buildTriggers(manifest, manifestDirectory);\n const { cardAssets, files: assetFiles } = createAssetFiles(manifest, manifestDirectory);\n const sourceCard = readCard(manifest, manifestDirectory);\n const card = createCard(manifest, lorebook, cardAssets, sourceCard);\n const module = {\n description: `Module for ${manifest.name}`,\n id: createUUID(`${manifest.namespace ?? manifest.name}:module`),\n lorebook,\n name: `${manifest.name} Module`,\n regex,\n trigger,\n };\n\n const map = fs.readFileSync(RPACK_MAP_PATH);\n assert(map.length >= 256, `Invalid RPack map: ${RPACK_MAP_PATH}`);\n const files = [\n ...assetFiles,\n { data: Buffer.from(JSON.stringify(sortKeysDeep(card), null, 2)), name: \"card.json\" },\n { data: createRisuM(sortKeysDeep(module), map.subarray(0, 256)), name: \"module.risum\" },\n ].sort((left, right) => left.name.localeCompare(right.name));\n\n const outputPath = outputArgument\n ? path.resolve(outputArgument)\n : path.resolve(\n manifestDirectory,\n manifest.output ?? `../dist/${sanitizeArchiveName(manifest.name)}.charx`,\n );\n fs.mkdirSync(path.dirname(outputPath), { recursive: true });\n const timestamp = process.env.SOURCE_DATE_EPOCH\n ? new Date(Number(process.env.SOURCE_DATE_EPOCH) * 1000)\n : new Date();\n fs.writeFileSync(outputPath, createZIP(files, timestamp));\n console.log(`Built ${path.relative(process.cwd(), outputPath)} (${files.length} files)`);\n return outputPath;\n}\n\nexport { buildCharX };\n","import zlib from \"node:zlib\";\n\nconst MAGIC = Buffer.from(\"RISUSAVE\\0\");\nconst MODULE_BLOCK_TYPE = 5;\n\ninterface ModuleRecord {\n id?: unknown;\n name?: unknown;\n namespace?: unknown;\n [key: string]: unknown;\n}\n\nfunction parseModuleBlock(database: Buffer): ModuleRecord[] {\n if (!database.subarray(0, MAGIC.length).equals(MAGIC)) {\n throw new Error(\"Invalid RISUSAVE header\");\n }\n\n let offset = MAGIC.length;\n while (offset < database.length) {\n if (offset + 3 > database.length) {\n throw new Error(`Truncated block header at byte ${offset}`);\n }\n const type = database[offset];\n const compressed = database[offset + 1] === 1;\n const nameLength = database[offset + 2];\n offset += 3;\n\n if (offset + nameLength + 4 > database.length) {\n throw new Error(`Truncated block name at byte ${offset}`);\n }\n const name = database.subarray(offset, offset + nameLength).toString(\"utf8\");\n offset += nameLength;\n const contentLength = database.readUInt32LE(offset);\n offset += 4;\n\n if (offset + contentLength > database.length) {\n throw new Error(`Truncated ${name} block at byte ${offset}`);\n }\n let content = database.subarray(offset, offset + contentLength);\n offset += contentLength;\n\n if (type !== MODULE_BLOCK_TYPE) {\n continue;\n }\n if (compressed) {\n content = zlib.gunzipSync(content);\n }\n return JSON.parse(content.toString(\"utf8\")) as ModuleRecord[];\n }\n throw new Error(\"RISUSAVE module block not found\");\n}\n\nexport { parseModuleBlock };\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport zlib from \"node:zlib\";\n\nconst RPACK_MAP_PATH = path.join(\n path.dirname(fileURLToPath(import.meta.url)),\n \"..\",\n \"vendor\",\n \"rpack\",\n \"rpack_map.bin\",\n);\n\nconst CRC32_TABLE = (() => {\n const table = new Uint32Array(256);\n for (let index = 0; index < table.length; index += 1) {\n let value = index;\n for (let bit = 0; bit < 8; bit += 1) {\n if ((value & 1) !== 0) {\n value = 0xedb88320 ^ (value >>> 1);\n } else {\n value >>>= 1;\n }\n }\n table[index] = value >>> 0;\n }\n return table;\n})();\n\nfunction assert(condition: unknown, message: string): asserts condition {\n if (!condition) {\n throw new Error(message);\n }\n}\n\nfunction calculateCRC32(data) {\n let value = 0xffffffff;\n for (const byte of data) {\n value = CRC32_TABLE[(value ^ byte) & 0xff] ^ (value >>> 8);\n }\n return (value ^ 0xffffffff) >>> 0;\n}\n\nfunction decodeModule(data: Buffer, map: Buffer): Record<string, any> {\n assert(data.length >= 7, \"module.risum is truncated\");\n assert(data.readUInt8(0) === 111, \"Invalid module.risum magic number\");\n assert(data.readUInt8(1) === 0, `Unsupported module.risum version: ${data.readUInt8(1)}`);\n\n const encodedLength = data.readUInt32LE(2);\n assert(encodedLength <= data.length - 6, \"module.risum payload is truncated\");\n assert(map.length >= 256, `Invalid RPack map: ${RPACK_MAP_PATH}`);\n\n let decodeMap;\n if (map.length >= 512) {\n decodeMap = map.subarray(256, 512);\n } else {\n decodeMap = Buffer.alloc(256);\n const seen = new Set();\n for (let index = 0; index < 256; index += 1) {\n const encoded = map[index];\n assert(!seen.has(encoded), \"RPack encode map is not a permutation\");\n seen.add(encoded);\n decodeMap[encoded] = index;\n }\n }\n\n const encoded = data.subarray(6, 6 + encodedLength);\n const decoded = Buffer.allocUnsafe(encoded.length);\n for (let index = 0; index < encoded.length; index += 1) {\n decoded[index] = decodeMap[encoded[index]];\n }\n\n const parsed = JSON.parse(decoded.toString(\"utf8\"));\n assert(\n parsed && parsed.type === \"risuModule\" && parsed.module,\n \"module.risum does not contain a Risu module\",\n );\n return parsed;\n}\n\nfunction findEndOfCentralDirectory(archive) {\n const minimumOffset = Math.max(0, archive.length - 0xffff - 22);\n for (let offset = archive.length - 22; offset >= minimumOffset; offset -= 1) {\n if (archive.readUInt32LE(offset) === 0x06054b50) {\n const commentLength = archive.readUInt16LE(offset + 20);\n if (offset + 22 + commentLength === archive.length) {\n return offset;\n }\n }\n }\n throw new Error(\"ZIP end record not found\");\n}\n\nfunction normalizeEntryName(name) {\n assert(name !== \"\", \"ZIP entry has an empty name\");\n assert(!name.includes(\"\\0\"), `ZIP entry contains a null byte: ${JSON.stringify(name)}`);\n\n const normalized = name.replace(/\\\\/g, \"/\");\n assert(!normalized.startsWith(\"/\"), `ZIP entry uses an absolute path: ${name}`);\n assert(!/^[a-zA-Z]:/.test(normalized), `ZIP entry uses an absolute path: ${name}`);\n\n const parts = normalized.split(\"/\");\n assert(!parts.includes(\"..\"), `ZIP entry escapes the output directory: ${name}`);\n return parts.filter((part) => part !== \"\" && part !== \".\").join(\"/\");\n}\n\nfunction sanitizeSourceName(name: string, fallback: string): string {\n const sanitized = Array.from(name, (character) =>\n character.charCodeAt(0) < 32 ? \"_\" : character,\n )\n .join(\"\")\n .replace(/[<>:\"/\\\\|?*]/g, \"_\")\n .replace(/[. ]+$/g, \"\")\n .trim();\n return sanitized || fallback;\n}\n\nfunction sortKeysDeep(value) {\n if (Array.isArray(value)) {\n return value.map(sortKeysDeep);\n }\n if (value && typeof value === \"object\" && !Buffer.isBuffer(value)) {\n const sorted = {};\n for (const key of Object.keys(value).sort()) {\n if (value[key] !== undefined) {\n sorted[key] = sortKeysDeep(value[key]);\n }\n }\n return sorted;\n }\n return value;\n}\n\nfunction takeSourcePath(directory, label, extension, takenPaths) {\n const baseName = sanitizeSourceName(label, \"untitled\");\n const suffix = baseName.toLowerCase().endsWith(extension) ? \"\" : extension;\n let candidate = `${directory}/${baseName}${suffix}`;\n let collision = 1;\n while (takenPaths.has(candidate)) {\n collision += 1;\n candidate = `${directory}/${baseName}_${collision}${suffix}`;\n }\n takenPaths.add(candidate);\n return candidate;\n}\n\nfunction createRegexDocument(regex) {\n const frontmatter = [`comment: ${regex.comment ?? \"\"}`];\n if (regex.flag !== undefined) {\n frontmatter.push(`flag: ${regex.flag}`);\n }\n frontmatter.push(`type: ${regex.type ?? \"editdisplay\"}`);\n return `---\\n${frontmatter.join(\"\\n\")}\\n---\\n\\nIN:\\n${regex.in ?? \"\"}\\nOUT:\\n${regex.out ?? \"\"}\\n`;\n}\n\nfunction createCardSources(card, files) {\n const sourceCard = JSON.parse(JSON.stringify(card));\n const data = sourceCard.data ?? {};\n const risuai = data.extensions?.risuai;\n\n const alternateGreetings = data.alternate_greetings ?? [];\n assert(Array.isArray(alternateGreetings), \"card.data.alternate_greetings must be an array\");\n for (let index = 0; index < alternateGreetings.length; index += 1) {\n const greeting = alternateGreetings[index];\n assert(\n typeof greeting === \"string\",\n `card.data.alternate_greetings[${index}] must be a string`,\n );\n }\n\n const description = data.description ?? \"\";\n const firstMessage = data.first_mes ?? \"\";\n assert(typeof description === \"string\", \"card.data.description must be a string\");\n assert(typeof firstMessage === \"string\", \"card.data.first_mes must be a string\");\n\n delete data.alternate_greetings;\n delete data.assets;\n delete data.character_book;\n delete data.character_version;\n delete data.creator;\n delete data.creator_notes;\n delete data.description;\n delete data.first_mes;\n delete data.modification_date;\n delete data.name;\n delete data.tags;\n\n if (risuai) {\n delete risuai.backgroundHTML;\n delete risuai.hideChatIcon;\n delete risuai.license;\n delete risuai.lowLevelAccess;\n delete risuai.moduleNamespace;\n delete risuai.toggles;\n const defaults = {\n additionalText: \"\",\n bias: [],\n defaultVariables: \"\",\n inlayViewScreen: false,\n largePortrait: false,\n lorePlus: false,\n prebuiltAssetCommand: \"\",\n prebuiltAssetExclude: [],\n prebuiltAssetStyle: \"\",\n sdData: [],\n utilityBot: false,\n viewScreen: \"none\",\n virtualscript: \"\",\n vits: {},\n };\n for (const [key, value] of Object.entries(defaults)) {\n if (JSON.stringify(sortKeysDeep(risuai[key])) === JSON.stringify(sortKeysDeep(value))) {\n delete risuai[key];\n }\n }\n if (Object.keys(risuai).length === 0) {\n delete data.extensions.risuai;\n }\n }\n if (data.extensions) {\n delete data.extensions.moduleNoneImage;\n if (Object.keys(data.extensions).length === 0) {\n delete data.extensions;\n }\n }\n\n const dataDefaults = {\n creation_date: 0,\n group_only_greetings: [],\n mes_example: \"\",\n nickname: \"\",\n personality: \"\",\n post_history_instructions: \"\",\n scenario: \"\",\n source: [],\n system_prompt: \"\",\n };\n for (const [key, value] of Object.entries(dataDefaults)) {\n if (JSON.stringify(sortKeysDeep(data[key])) === JSON.stringify(sortKeysDeep(value))) {\n delete data[key];\n }\n }\n\n if (Object.keys(data).length === 0) {\n delete sourceCard.data;\n } else {\n sourceCard.data = data;\n }\n if (sourceCard.spec === \"chara_card_v3\") {\n delete sourceCard.spec;\n }\n if (sourceCard.spec_version === \"3.0\") {\n delete sourceCard.spec_version;\n }\n\n const cardRequired =\n alternateGreetings.length > 0 ||\n description !== \"\" ||\n firstMessage !== \"\" ||\n Object.keys(sourceCard).length > 0;\n if (!cardRequired) {\n return undefined;\n }\n\n const alternateGreetingFiles = alternateGreetings.map((greeting, index) => {\n const file = `alternate_greetings/${index + 1}.md`;\n files.set(file, Buffer.from(greeting, \"utf8\"));\n return file;\n });\n files.set(\"description.md\", Buffer.from(description, \"utf8\"));\n files.set(\"first_mes.md\", Buffer.from(firstMessage, \"utf8\"));\n files.set(\n \"card.json\",\n Buffer.from(`${JSON.stringify(sortKeysDeep(sourceCard), null, 2)}\\n`, \"utf8\"),\n );\n return {\n alternate_greetings: alternateGreetingFiles,\n description: \"description.md\",\n file: \"card.json\",\n first_mes: \"first_mes.md\",\n };\n}\n\nfunction createExpandedModuleSources(\n card: Record<string, any>,\n decodedModule: Record<string, any>,\n): Map<string, Buffer> {\n const moduleData = decodedModule.module;\n const files = new Map<string, Buffer>();\n const folderNames = new Map<any, any>();\n const folders: any[] = [];\n const takenPaths = new Set<string>();\n\n for (const entry of moduleData.lorebook ?? []) {\n if (entry.mode !== \"folder\") {\n continue;\n }\n folderNames.set(entry.key, entry.comment);\n folders.push(entry.comment);\n }\n\n const lorebook: any[] = [];\n for (const entry of moduleData.lorebook ?? []) {\n if (entry.mode === \"folder\") {\n continue;\n }\n const file = takeSourcePath(\"lorebooks\", entry.comment, \".md\", takenPaths);\n files.set(file, Buffer.from(entry.content ?? \"\", \"utf8\"));\n lorebook.push({\n activationPercent: entry.activationPercent,\n alwaysActive: entry.alwaysActive ?? false,\n bookVersion: entry.bookVersion ?? 2,\n comment: entry.comment ?? \"\",\n extentions: entry.extentions,\n file,\n folder: folderNames.get(entry.folder),\n insertOrder: entry.insertorder ?? 100,\n key: entry.key ?? \"\",\n mode: entry.mode ?? \"normal\",\n secondaryKey: entry.secondkey ?? \"\",\n selective: entry.selective ?? false,\n useRegex: entry.useRegex ?? false,\n });\n }\n\n const regex: string[] = [];\n for (const entry of moduleData.regex ?? []) {\n const file = takeSourcePath(\"regex\", entry.comment, \".md\", takenPaths);\n files.set(file, Buffer.from(createRegexDocument(entry), \"utf8\"));\n regex.push(file);\n }\n\n const triggers: any[] = [];\n for (let index = 0; index < (moduleData.trigger ?? []).length; index += 1) {\n const trigger = moduleData.trigger[index];\n const luaEffect =\n trigger.effect?.length === 1 && trigger.effect[0].type === \"triggerlua\"\n ? trigger.effect[0]\n : undefined;\n if (!luaEffect || typeof luaEffect.code !== \"string\") {\n triggers.push(trigger);\n continue;\n }\n\n const label = trigger.comment || `trigger-${index + 1}`;\n const luaPath = takeSourcePath(\"triggers\", label, \".lua\", takenPaths);\n files.set(luaPath, Buffer.from(luaEffect.code, \"utf8\"));\n triggers.push({\n bundle: false,\n comment: trigger.comment ?? \"\",\n conditions: trigger.conditions ?? [],\n lowLevelAccess: trigger.lowLevelAccess,\n lua: luaPath,\n type: trigger.type ?? \"start\",\n });\n }\n\n const risuai = card.data?.extensions?.risuai ?? {};\n const manifest: Record<string, any> = {\n card: createCardSources(card, files),\n creator: card.data?.creator,\n description: card.data?.creator_notes ?? moduleData.description ?? \"\",\n folders,\n hideIcon: risuai.hideChatIcon ?? moduleData.hideIcon ?? false,\n lorebook,\n lowLevelAccess: risuai.lowLevelAccess ?? moduleData.lowLevelAccess ?? false,\n name: card.data?.name ?? moduleData.name,\n namespace: risuai.moduleNamespace ?? moduleData.namespace,\n regex,\n tags: card.data?.tags,\n triggers,\n version: card.data?.character_version ?? \"\",\n };\n\n const CSS = risuai.backgroundHTML ?? moduleData.backgroundEmbedding;\n if (CSS) {\n manifest.CSS = \"style.html\";\n files.set(\"style.html\", Buffer.from(CSS, \"utf8\"));\n }\n const toggles = risuai.toggles ?? moduleData.customModuleToggle;\n if (toggles) {\n manifest.toggles = \"toggles.txt\";\n files.set(\"toggles.txt\", Buffer.from(toggles, \"utf8\"));\n }\n\n const mainIcon = card.data?.assets?.find(\n (asset) => asset.type === \"icon\" && asset.name === \"main\",\n );\n if (mainIcon?.uri?.startsWith(\"embeded://\")) {\n manifest.icon = mainIcon.uri.slice(\"embeded://\".length);\n }\n\n const assets: any[] = [];\n for (const asset of card.data?.assets ?? []) {\n if (asset === mainIcon || !asset.uri?.startsWith(\"embeded://\")) {\n continue;\n }\n assets.push({\n extension: asset.ext,\n file: asset.uri.slice(\"embeded://\".length),\n name: asset.name,\n });\n }\n if (assets.length > 0) {\n manifest.assets = assets;\n }\n\n files.set(\n \"charx.json\",\n Buffer.from(`${JSON.stringify(sortKeysDeep(manifest), null, 2)}\\n`, \"utf8\"),\n );\n return files;\n}\n\nfunction parseZIP(archive: Buffer) {\n const endOffset = findEndOfCentralDirectory(archive);\n const diskNumber = archive.readUInt16LE(endOffset + 4);\n const centralDisk = archive.readUInt16LE(endOffset + 6);\n const diskEntries = archive.readUInt16LE(endOffset + 8);\n const totalEntries = archive.readUInt16LE(endOffset + 10);\n const centralSize = archive.readUInt32LE(endOffset + 12);\n const centralOffset = archive.readUInt32LE(endOffset + 16);\n\n assert(diskNumber === 0 && centralDisk === 0, \"Multi-disk ZIP archives are not supported\");\n assert(diskEntries === totalEntries, \"Inconsistent ZIP entry count\");\n assert(\n totalEntries !== 0xffff && centralSize !== 0xffffffff && centralOffset !== 0xffffffff,\n \"ZIP64 is not supported\",\n );\n\n const zipOffset = endOffset - centralSize - centralOffset;\n assert(zipOffset >= 0, \"Invalid ZIP central directory offset\");\n\n const entries: any[] = [];\n const names = new Set();\n let offset = zipOffset + centralOffset;\n for (let index = 0; index < totalEntries; index += 1) {\n assert(offset + 46 <= archive.length, \"ZIP central directory is truncated\");\n assert(\n archive.readUInt32LE(offset) === 0x02014b50,\n `Invalid ZIP central record at byte ${offset}`,\n );\n\n const flags = archive.readUInt16LE(offset + 8);\n const method = archive.readUInt16LE(offset + 10);\n const expectedCRC32 = archive.readUInt32LE(offset + 16);\n const compressedSize = archive.readUInt32LE(offset + 20);\n const uncompressedSize = archive.readUInt32LE(offset + 24);\n const nameLength = archive.readUInt16LE(offset + 28);\n const extraLength = archive.readUInt16LE(offset + 30);\n const commentLength = archive.readUInt16LE(offset + 32);\n const diskStart = archive.readUInt16LE(offset + 34);\n const localOffset = archive.readUInt32LE(offset + 42);\n const recordLength = 46 + nameLength + extraLength + commentLength;\n\n assert(offset + recordLength <= archive.length, \"ZIP central record is truncated\");\n assert((flags & 1) === 0, \"Encrypted ZIP entries are not supported\");\n assert(method === 0 || method === 8, `Unsupported ZIP compression method: ${method}`);\n assert(diskStart === 0, \"Multi-disk ZIP entries are not supported\");\n assert(\n compressedSize !== 0xffffffff &&\n uncompressedSize !== 0xffffffff &&\n localOffset !== 0xffffffff,\n \"ZIP64 entries are not supported\",\n );\n\n const rawName = archive.subarray(offset + 46, offset + 46 + nameLength);\n const decodedName = rawName.toString(\"utf8\");\n const directory = decodedName.endsWith(\"/\") || decodedName.endsWith(\"\\\\\");\n const name = normalizeEntryName(decodedName);\n assert(name !== \"\", \"ZIP entry resolves to an empty path\");\n assert(!names.has(name), `Duplicate ZIP entry: ${name}`);\n names.add(name);\n\n entries.push({\n compressedSize,\n directory,\n expectedCRC32,\n localOffset: zipOffset + localOffset,\n method,\n name,\n uncompressedSize,\n });\n offset += recordLength;\n }\n\n assert(offset === endOffset, \"ZIP central directory size does not match its records\");\n return entries;\n}\n\nfunction readEntry(archive, entry) {\n const offset = entry.localOffset;\n assert(offset + 30 <= archive.length, `ZIP local record is truncated: ${entry.name}`);\n assert(archive.readUInt32LE(offset) === 0x04034b50, `Invalid ZIP local record: ${entry.name}`);\n\n const nameLength = archive.readUInt16LE(offset + 26);\n const extraLength = archive.readUInt16LE(offset + 28);\n const dataOffset = offset + 30 + nameLength + extraLength;\n const dataEnd = dataOffset + entry.compressedSize;\n assert(dataEnd <= archive.length, `ZIP entry data is truncated: ${entry.name}`);\n\n const compressed = archive.subarray(dataOffset, dataEnd);\n const data = entry.method === 0 ? Buffer.from(compressed) : zlib.inflateRawSync(compressed);\n assert(data.length === entry.uncompressedSize, `ZIP entry size mismatch: ${entry.name}`);\n assert(\n calculateCRC32(data) === entry.expectedCRC32,\n `ZIP entry checksum mismatch: ${entry.name}`,\n );\n assert(!entry.directory || data.length === 0, `ZIP directory entry contains data: ${entry.name}`);\n return data;\n}\n\nfunction assertEmptyOutputDirectory(outputDirectory) {\n if (!fs.existsSync(outputDirectory)) {\n return;\n }\n assert(\n fs.statSync(outputDirectory).isDirectory(),\n `Output path is not a directory: ${outputDirectory}`,\n );\n assert(\n fs.readdirSync(outputDirectory).length === 0,\n `Output directory is not empty: ${outputDirectory}`,\n );\n}\n\nfunction unpackCharX(inputPath: string, outputPath: string): string {\n const resolvedInputPath = path.resolve(inputPath);\n const resolvedOutputPath = path.resolve(outputPath);\n const archive = fs.readFileSync(resolvedInputPath);\n const entries = parseZIP(archive);\n const extracted = new Map<string, { data: Buffer; directory: boolean }>();\n\n for (const entry of entries) {\n extracted.set(entry.name, {\n data: readEntry(archive, entry),\n directory: entry.directory,\n });\n }\n\n const cardEntry = extracted.get(\"card.json\");\n assert(cardEntry, \"CharX archive does not contain card.json\");\n assert(!cardEntry.directory, \"card.json is a directory\");\n const card = JSON.parse(cardEntry.data.toString(\"utf8\"));\n\n let decodedModule;\n if (extracted.has(\"module.risum\")) {\n const moduleEntry = extracted.get(\"module.risum\");\n assert(moduleEntry, \"CharX archive does not contain module.risum\");\n assert(!moduleEntry.directory, \"module.risum is a directory\");\n const map = fs.readFileSync(RPACK_MAP_PATH);\n decodedModule = decodeModule(moduleEntry.data, map);\n }\n\n const expandedSources = decodedModule\n ? createExpandedModuleSources(card, decodedModule)\n : new Map();\n for (const name of expandedSources.keys()) {\n assert(\n name === \"card.json\" || !extracted.has(name),\n `Generated module source conflicts with an archive entry: ${name}`,\n );\n }\n\n assertEmptyOutputDirectory(resolvedOutputPath);\n fs.mkdirSync(resolvedOutputPath, { recursive: true });\n\n for (const [name, entry] of extracted) {\n if (\n name === \"module.risum\" ||\n (decodedModule && name === \"card.json\") ||\n expandedSources.has(name)\n ) {\n continue;\n }\n const destination = path.join(resolvedOutputPath, ...name.split(\"/\"));\n if (entry.directory) {\n fs.mkdirSync(destination, { recursive: true });\n continue;\n }\n fs.mkdirSync(path.dirname(destination), { recursive: true });\n fs.writeFileSync(destination, entry.data);\n }\n\n for (const [name, data] of expandedSources) {\n const destination = path.join(resolvedOutputPath, ...name.split(\"/\"));\n fs.mkdirSync(path.dirname(destination), { recursive: true });\n fs.writeFileSync(destination, data);\n }\n\n const relativeOutput = path.relative(process.cwd(), resolvedOutputPath) || \".\";\n console.log(\n `Unpacked ${entries.length - (decodedModule ? 1 : 0)} archive files to ${relativeOutput}`,\n );\n return resolvedOutputPath;\n}\n\nexport { createExpandedModuleSources, decodeModule, parseZIP, unpackCharX };\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport { createExpandedModuleSources } from \"./unpack-charx.js\";\n\nconst RPACK_MAP_PATH = path.join(\n path.dirname(fileURLToPath(import.meta.url)),\n \"..\",\n \"vendor\",\n \"rpack\",\n \"rpack_map.bin\",\n);\n\nfunction assert(condition: unknown, message: string): asserts condition {\n if (!condition) {\n throw new Error(message);\n }\n}\n\nfunction assertEmptyOutputDirectory(outputDirectory) {\n if (!fs.existsSync(outputDirectory)) {\n return;\n }\n assert(\n fs.statSync(outputDirectory).isDirectory(),\n `Output path is not a directory: ${outputDirectory}`,\n );\n assert(\n fs.readdirSync(outputDirectory).length === 0,\n `Output directory is not empty: ${outputDirectory}`,\n );\n}\n\nfunction decodeRPack(data, decodeMap) {\n for (let index = 0; index < data.length; index += 1) {\n data[index] = decodeMap[data[index]];\n }\n return data;\n}\n\nfunction readExactly(fileDescriptor, length, position, label) {\n const data = Buffer.allocUnsafe(length);\n let read = 0;\n while (read < length) {\n const count = fs.readSync(fileDescriptor, data, read, length - read, position + read);\n assert(count > 0, `${label} is truncated at byte ${position + read}`);\n read += count;\n }\n return data;\n}\n\nfunction sanitizeAssetName(name: string, fallback: string): string {\n const sanitized = Array.from(name, (character) =>\n character.charCodeAt(0) < 32 ? \"_\" : character,\n )\n .join(\"\")\n .replace(/[<>:\"/\\\\|?*]/g, \"_\")\n .replace(/[. ]+$/g, \"\")\n .trim();\n return sanitized.slice(0, 180) || fallback;\n}\n\nfunction detectAssetExtension(data, fallback) {\n if (data.subarray(0, 8).equals(Buffer.from(\"89504e470d0a1a0a\", \"hex\"))) {\n return \"png\";\n }\n if (data.subarray(0, 3).equals(Buffer.from(\"ffd8ff\", \"hex\"))) {\n return \"jpg\";\n }\n if (\n data.subarray(0, 6).toString(\"ascii\") === \"GIF87a\" ||\n data.subarray(0, 6).toString(\"ascii\") === \"GIF89a\"\n ) {\n return \"gif\";\n }\n if (\n data.subarray(0, 4).toString(\"ascii\") === \"RIFF\" &&\n data.subarray(8, 12).toString(\"ascii\") === \"WEBP\"\n ) {\n return \"webp\";\n }\n if (data.subarray(4, 12).toString(\"ascii\").includes(\"ftypavif\")) {\n return \"avif\";\n }\n return /^[a-z0-9]+$/i.test(fallback ?? \"\") ? fallback.toLowerCase() : \"bin\";\n}\n\nfunction takeAssetPath(asset, data, index, takenPaths) {\n const extension = detectAssetExtension(data, asset[2]);\n const baseName = sanitizeAssetName(asset[0] ?? \"\", `asset_${index + 1}`);\n let candidate = `assets/${baseName}.${extension}`;\n let collision = 1;\n while (takenPaths.has(candidate)) {\n collision += 1;\n candidate = `assets/${baseName}_${collision}.${extension}`;\n }\n takenPaths.add(candidate);\n return candidate;\n}\n\nfunction writeSources(outputDirectory, decodedModule, assetSources) {\n const card = {\n data: {\n name: decodedModule.module.name,\n },\n };\n const sources = createExpandedModuleSources(card, decodedModule);\n const manifestSource = sources.get(\"charx.json\");\n assert(manifestSource, \"Expanded module sources do not contain charx.json\");\n const manifest = JSON.parse(manifestSource.toString(\"utf8\"));\n manifest.assets = assetSources;\n sources.set(\"charx.json\", Buffer.from(`${JSON.stringify(manifest, null, 2)}\\n`, \"utf8\"));\n\n for (const [name, data] of sources) {\n const destination = path.join(outputDirectory, ...name.split(\"/\"));\n fs.mkdirSync(path.dirname(destination), { recursive: true });\n fs.writeFileSync(destination, data);\n }\n}\n\nfunction unpackRisuM(inputPath: string, outputPath: string): string {\n const resolvedInputPath = path.resolve(inputPath);\n const resolvedOutputPath = path.resolve(outputPath);\n assertEmptyOutputDirectory(resolvedOutputPath);\n\n const map = fs.readFileSync(RPACK_MAP_PATH);\n assert(map.length >= 512, `Invalid RPack map: ${RPACK_MAP_PATH}`);\n const decodeMap = map.subarray(256, 512);\n const fileDescriptor = fs.openSync(resolvedInputPath, \"r\");\n\n try {\n const fileSize = fs.fstatSync(fileDescriptor).size;\n const header = readExactly(fileDescriptor, 6, 0, \"RISUM header\");\n assert(header.readUInt8(0) === 111, \"Invalid RISUM magic number\");\n assert(header.readUInt8(1) === 0, `Unsupported RISUM version: ${header.readUInt8(1)}`);\n\n const payloadLength = header.readUInt32LE(2);\n const payload = readExactly(fileDescriptor, payloadLength, 6, \"RISUM module payload\");\n const decodedModule = JSON.parse(decodeRPack(payload, decodeMap).toString(\"utf8\"));\n assert(\n decodedModule?.type === \"risuModule\" && decodedModule.module,\n \"RISUM does not contain a Risu module\",\n );\n\n const assetMetadata = decodedModule.module.assets ?? [];\n const assetSources: any[] = [];\n const takenPaths = new Set<string>();\n let assetIndex = 0;\n let position = 6 + payloadLength;\n\n fs.mkdirSync(path.join(resolvedOutputPath, \"assets\"), { recursive: true });\n while (position < fileSize) {\n const marker = readExactly(fileDescriptor, 1, position, \"RISUM asset marker\").readUInt8(0);\n position += 1;\n if (marker === 0) {\n break;\n }\n assert(marker === 1, `Invalid RISUM asset marker at byte ${position - 1}: ${marker}`);\n assert(\n assetIndex < assetMetadata.length,\n \"RISUM contains more asset blocks than asset metadata entries\",\n );\n\n const lengthData = readExactly(fileDescriptor, 4, position, \"RISUM asset length\");\n const assetLength = lengthData.readUInt32LE(0);\n position += 4;\n const encodedAsset = readExactly(\n fileDescriptor,\n assetLength,\n position,\n `RISUM asset ${assetIndex + 1}`,\n );\n position += assetLength;\n\n const metadata = assetMetadata[assetIndex];\n assert(metadata, `RISUM asset ${assetIndex + 1} has no metadata`);\n const decodedAsset = decodeRPack(encodedAsset, decodeMap);\n const sourcePath = takeAssetPath(metadata, decodedAsset, assetIndex, takenPaths);\n const destination = path.join(resolvedOutputPath, ...sourcePath.split(\"/\"));\n fs.writeFileSync(destination, decodedAsset);\n assetSources.push({\n extension: path.extname(sourcePath).slice(1),\n file: sourcePath,\n name: metadata[0],\n });\n assetIndex += 1;\n\n if (assetIndex % 500 === 0) {\n console.log(`Extracted ${assetIndex} / ${assetMetadata.length} assets`);\n }\n }\n\n assert(\n assetIndex === assetMetadata.length,\n `RISUM contains ${assetIndex} asset blocks but declares ${assetMetadata.length}`,\n );\n assert(\n position === fileSize,\n `RISUM contains ${fileSize - position} trailing bytes after the end marker`,\n );\n writeSources(resolvedOutputPath, decodedModule, assetSources);\n\n const relativeOutput = path.relative(process.cwd(), resolvedOutputPath) || \".\";\n console.log(`Unpacked ${assetIndex} assets and module sources to ${relativeOutput}`);\n return resolvedOutputPath;\n } finally {\n fs.closeSync(fileDescriptor);\n }\n}\n\nexport { unpackRisuM };\n"],"mappings":";;;;;;;AAGA,IAAM,kBAAkB;AAUxB,SAAS,YAAY,OAAuB;CAC1C,IAAI,UAAU,GACZ,OAAO;CAGT,MAAM,OAAO;CACb,MAAM,QAAQ;EAAC;EAAK;EAAM;CAAI;CAC9B,MAAM,QAAQ,KAAK,MAAM,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI,CAAC;CACzD,OAAO,GAAG,OAAO,YAAY,QAAQ,KAAK,IAAI,MAAM,KAAK,EAAA,CAAG,QAAQ,CAAC,CAAC,EAAE,GAAG,MAAM;AACnF;AAEA,SAAS,kBAAkB,YAA4B;CACrD,OAAO,GAAG,WAAW,QAAQ,OAAO,GAAG,EAAE;AAC3C;AAEA,SAAS,UAAU,SAAiB,iBAAmC;CAIrE,OAAO,QACJ,QACC,oGACC,OAAe,aAAsB,SAAkB,iBAA0B;EAChF,IAAI,CAAC,eAAe,CAAC,cACnB,OAAO;EAET,IAAI,cAAc,WAAW,KAAK,KAAM,eAAe,eAAe,KAAK,KAAK,GAC9E,gBAAgB,KAAK,KAAK;EAE5B,OAAO;CACT,CACF,CAAC,CACA,MAAM,IAAI,CAAC,CACX,KAAK,SAAS,KAAK,KAAK,CAAC,CAAC,CAC1B,QAAQ,SAAS,KAAK,SAAS,CAAC,CAAC,CACjC,KAAK,IAAI;AACd;AAEA,SAAS,cAAc,YAAoB,OAA0B;CACnE,IAAI,MAAM,gBAAgB,IAAI,UAAU,GACtC;CAGF,MAAM,gBAAgB,KAAK,QAAQ,KAAK,QAAQ,MAAM,SAAS,CAAC;CAChE,MAAM,aAAa,KAAK,KAAK,eAAe,kBAAkB,UAAU,CAAC;CACzE,IAAI,CAAC,GAAG,WAAW,UAAU,GAAG;EAC9B,QAAQ,KAAK,oBAAoB,WAAW,YAAY;EACxD;CACF;CAEA,MAAM,aAAa,GAAG,aAAa,YAAY,MAAM;CACrD,MAAM,gBAAgB,IAAI,UAAU;CACpC,MAAM,mBAAmB,GAAG,SAAS,UAAU,CAAC,CAAC;CAEjD,KAAK,MAAM,SAAS,WAAW,SAAS,IAAI,OAAO,gBAAgB,QAAQ,GAAG,CAAC,GAAG;EAChF,MAAM,aAAa,MAAM;EACzB,IAAI,YACF,cAAc,YAAY,KAAK;CAEnC;CAEA,MAAM,kBAAkB,UAAU,YAAY,MAAM,eAAe;CACnE,MAAM,SAAS,KAAK,oBAAoB,WAAW,kBAAkB,gBAAgB,KAAK;AAC5F;AAEA,SAAS,UAAU,WAAmB,gBAAgC;CACpE,MAAM,oBAAoB,KAAK,QAAQ,SAAS;CAChD,IAAI,CAAC,GAAG,WAAW,iBAAiB,GAClC,MAAM,IAAI,MAAM,yBAAyB,WAAW;CAGtD,IAAI,aAAa,KAAK,QAAQ,cAAc;CAC5C,IAAI,GAAG,WAAW,UAAU,KAAK,GAAG,SAAS,UAAU,CAAC,CAAC,YAAY,GACnE,aAAa,KAAK,KAAK,YAAY,KAAK,SAAS,iBAAiB,CAAC;CAErE,IAAI,KAAK,QAAQ,UAAU,MAAM,QAC/B,cAAc;CAGhB,MAAM,QAAqB;EACzB,WAAW;EACX,iBAAiB,CAAC;EAClB,iCAAiB,IAAI,IAAI;EACzB,UAAU,CAAC;EACX,iBAAiB,GAAG,SAAS,iBAAiB,CAAC,CAAC;CAClD;CACA,MAAM,cAAc,GAAG,aAAa,mBAAmB,MAAM;CAE7D,KAAK,MAAM,SAAS,YAAY,SAAS,IAAI,OAAO,gBAAgB,QAAQ,GAAG,CAAC,GAAG;EACjF,MAAM,aAAa,MAAM;EACzB,IAAI,YACF,cAAc,YAAY,KAAK;CAEnC;CAEA,MAAM,eAAe,UAAU,aAAa,MAAM,eAAe;CAEjE,MAAM,SAAS,GADC,MAAM,gBAAgB,SAAS,IAAI,GAAG,MAAM,gBAAgB,KAAK,IAAI,EAAE,MAAM,KACjE,MAAM,SAAS,KAAK,IAAI,EAAE,IAAI;CAE1D,GAAG,UAAU,KAAK,QAAQ,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;CAC1D,GAAG,cAAc,YAAY,QAAQ,MAAM;CAE3C,MAAM,cAAc,GAAG,SAAS,UAAU,CAAC,CAAC;CAC5C,MAAM,aAAc,MAAM,kBAAkB,eAAe,MAAM,kBAAmB;CACpF,QAAQ,IACN,WAAW,KAAK,SAAS,QAAQ,IAAI,GAAG,iBAAiB,EAAE,MAAM,KAAK,SAAS,QAAQ,IAAI,GAAG,UAAU,GAC1G;CACA,QAAQ,IACN,GAAG,MAAM,gBAAgB,KAAK,YAAY,YAAY,MAAM,eAAe,EAAE,MAAM,YAAY,WAAW,EAAE,IAAI,UAAU,QAAQ,CAAC,EAAE,YACvI;CACA,OAAO;AACT;;;ACnHA,IAAM,eAAe,OAAO,KAC1B,oGACA,QACF;AACA,IAAM,mBAAiB,KAAK,KAC1B,KAAK,QAAQ,cAAc,YAAY,GAAG,CAAC,GAC3C,MACA,UACA,SACA,eACF;AAEA,IAAM,uBAAqB;CACzB,MAAM,wBAAQ,IAAI,YAAY,GAAG;CACjC,KAAK,IAAI,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS,GAAG;EACpD,IAAI,QAAQ;EACZ,KAAK,IAAI,MAAM,GAAG,MAAM,GAAG,OAAO,GAChC,KAAK,QAAQ,OAAO,GAClB,QAAQ,aAAc,UAAU;OAEhC,WAAW;EAGf,MAAM,SAAS,UAAU;CAC3B;CACA,OAAO;AACT,EAAA,CAAG;AAEH,SAAS,SAAO,WAAoB,SAAoC;CACtE,IAAI,CAAC,WACH,MAAM,IAAI,MAAM,OAAO;AAE3B;AAEA,SAAS,iBAAe,MAAM;CAC5B,IAAI,QAAQ;CACZ,KAAK,MAAM,QAAQ,MACjB,QAAQ,eAAa,QAAQ,QAAQ,OAAS,UAAU;CAE1D,QAAQ,QAAQ,gBAAgB;AAClC;AAEA,SAAS,WAAW,MAAM;CACxB,MAAM,QAAQ,OAAO,WAAW,QAAQ,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,GAAG,EAAE;CAC9E,MAAM,KAAM,MAAM,KAAK,KAAQ;CAC/B,MAAM,KAAM,MAAM,KAAK,KAAQ;CAC/B,MAAM,MAAM,MAAM,SAAS,KAAK;CAChC,OAAO,GAAG,IAAI,MAAM,GAAG,CAAC,EAAE,GAAG,IAAI,MAAM,GAAG,EAAE,EAAE,GAAG,IAAI,MAAM,IAAI,EAAE,EAAE,GAAG,IAAI,MAAM,IAAI,EAAE,EAAE,GAAG,IAAI,MAAM,EAAE;AACzG;AAEA,SAAS,gBAAgB,MAAM;CAC7B,IAAI,KAAK,SAAS,GAAG,CAAC,CAAC,CAAC,OAAO,OAAO,KAAK,oBAAoB,KAAK,CAAC,GACnE,OAAO;CAET,IAAI,KAAK,SAAS,GAAG,CAAC,CAAC,CAAC,OAAO,OAAO,KAAK,UAAU,KAAK,CAAC,GACzD,OAAO;CAET,IACE,KAAK,SAAS,GAAG,CAAC,CAAC,CAAC,SAAS,OAAO,MAAM,YAC1C,KAAK,SAAS,GAAG,CAAC,CAAC,CAAC,SAAS,OAAO,MAAM,UAE1C,OAAO;CAET,IACE,KAAK,SAAS,GAAG,CAAC,CAAC,CAAC,SAAS,OAAO,MAAM,UAC1C,KAAK,SAAS,GAAG,EAAE,CAAC,CAAC,SAAS,OAAO,MAAM,QAE3C,OAAO;CAET,OAAO;AACT;AAEA,SAAS,iBAAiB,WAAW;CACnC,MAAM,wBAAQ,IAAI,IAAI;EAAC;EAAQ;EAAO;EAAO;CAAK,CAAC;CACnD,MAAM,uBAAO,IAAI,IAAI;EAAC;EAAM;EAAO;CAAI,CAAC;CACxC,MAAM,wBAAQ,IAAI,IAAI;EAAC;EAAO;EAAO;EAAQ;CAAO,CAAC;CACrD,MAAM,yBAAS,IAAI,IAAI;EAAC;EAAQ;EAAO;EAAQ;EAAO;EAAO;CAAM,CAAC;CACpE,MAAM,yBAAS,IAAI,IAAI,CAAC,OAAO,KAAK,CAAC;CACrC,MAAM,wBAAQ,IAAI,IAAI;EAAC;EAAO;EAAO;EAAO;EAAO;CAAM,CAAC;CAE1D,IAAI,MAAM,IAAI,SAAS,GACrB,OAAO;CAET,IAAI,KAAK,IAAI,SAAS,GACpB,OAAO;CAET,IAAI,MAAM,IAAI,SAAS,GACrB,OAAO;CAET,IAAI,OAAO,IAAI,SAAS,GACtB,OAAO;CAET,IAAI,OAAO,IAAI,SAAS,GACtB,OAAO;CAET,IAAI,cAAc,UAAU,cAAc,iBAAiB,cAAc,QACvE,OAAO;CAET,IAAI,MAAM,IAAI,SAAS,GACrB,OAAO;CAET,OAAO;AACT;AAEA,SAAS,WAAW,mBAAmB,QAAQ,OAAO;CACpD,IAAI,OAAO,WAAW,UACpB,OAAO,GAAG,aAAa,KAAK,QAAQ,mBAAmB,MAAM,GAAG,MAAM;CAExE,SAAO,UAAU,OAAO,WAAW,UAAU,GAAG,MAAM,sCAAsC;CAC5F,IAAI,OAAO,OAAO,YAAY,UAC5B,OAAO,OAAO;CAEhB,SAAO,OAAO,OAAO,SAAS,UAAU,GAAG,MAAM,uBAAuB;CACxE,OAAO,GAAG,aAAa,KAAK,QAAQ,mBAAmB,OAAO,IAAI,GAAG,MAAM;AAC7E;AAEA,SAAS,SAAS,UAAU,mBAAmB;CAC7C,IAAI,CAAC,SAAS,MACZ;CAGF,IAAI,OAAO,SAAS,SAAS,UAC3B,OAAO,KAAK,MAAM,WAAW,mBAAmB,SAAS,MAAM,MAAM,CAAC;CAIxE,MAAM,OADoB,aAAa,SAAS,QAAQ,UAAU,SAAS,OAEvE,KAAK,MAAM,WAAW,mBAAmB,SAAS,MAAM,MAAM,CAAC,IAC/D,CAAC;CACL,MAAM,OAAO,KAAK,QAAQ,CAAC;CAC3B,IAAI,SAAS,KAAK,wBAAwB,KAAA,GAAW;EACnD,SACE,MAAM,QAAQ,SAAS,KAAK,mBAAmB,GAC/C,2CACF;EACA,KAAK,sBAAsB,SAAS,KAAK,oBAAoB,KAAK,QAAQ,UACxE,WAAW,mBAAmB,QAAQ,4BAA4B,MAAM,EAAE,CAC5E;CACF;CACA,IAAI,SAAS,KAAK,gBAAgB,KAAA,GAChC,KAAK,cAAc,WAAW,mBAAmB,SAAS,KAAK,aAAa,kBAAkB;CAEhG,IAAI,SAAS,KAAK,cAAc,KAAA,GAC9B,KAAK,YAAY,WAAW,mBAAmB,SAAS,KAAK,WAAW,gBAAgB;CAE1F,KAAK,OAAO;CACZ,OAAO;AACT;AAEA,SAAS,oBAAoB,MAAsB;CAOjD,OANkB,MAAM,KAAK,OAAO,cAClC,UAAU,WAAW,CAAC,IAAI,KAAK,MAAM,SACvC,CAAC,CACE,KAAK,EAAE,CAAC,CACR,QAAQ,iBAAiB,GAAG,CAAC,CAC7B,KACI,CAAA,CAAU,MAAM,GAAG,GAAG,KAAK;AACpC;AAEA,SAAS,eAAa,OAAO;CAC3B,IAAI,MAAM,QAAQ,KAAK,GACrB,OAAO,MAAM,IAAI,cAAY;CAE/B,IAAI,SAAS,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,GAAG;EACjE,MAAM,SAAS,CAAC;EAChB,KAAK,MAAM,OAAO,OAAO,KAAK,KAAK,CAAC,CAAC,KAAK,GACxC,IAAI,MAAM,SAAS,KAAA,GACjB,OAAO,OAAO,eAAa,MAAM,IAAI;EAGzC,OAAO;CACT;CACA,OAAO;AACT;AAEA,SAAS,iBAAiB,SAAS,UAAU;CAC3C,MAAM,aAAa,QAAQ,QAAQ,SAAS,IAAI;CAChD,SAAO,WAAW,WAAW,OAAO,GAAG,0BAA0B,UAAU;CAC3E,MAAM,MAAM,WAAW,QAAQ,WAAW,CAAC;CAC3C,SAAO,QAAQ,IAAI,2BAA2B,UAAU;CACxD,MAAM,WAA6C,CAAC;CACpD,KAAK,MAAM,QAAQ,WAAW,MAAM,GAAG,GAAG,CAAC,CAAC,MAAM,IAAI,GAAG;EACvD,IAAI,KAAK,KAAK,MAAM,IAClB;EAEF,MAAM,YAAY,KAAK,QAAQ,GAAG;EAClC,SAAO,cAAc,IAAI,+BAA+B,SAAS,IAAI,MAAM;EAC3E,MAAM,MAAM,KAAK,MAAM,GAAG,SAAS,CAAC,CAAC,KAAK;EAC1C,MAAM,WAAW,KAAK,MAAM,YAAY,CAAC,CAAC,CAAC,KAAK;EAChD,SAAO,QAAQ,IAAI,4BAA4B,UAAU;EACzD,IAAI,aAAa,QACf,SAAS,OAAO;OACX,IAAI,aAAa,SACtB,SAAS,OAAO;OAEhB,SAAS,OAAO;CAEpB;CACA,OAAO;EACL,MAAM,WAAW,MAAM,MAAM,CAAC;EAC9B;CACF;AACF;AAEA,SAAS,eAAe,SAAS,UAAU;CAEzC,MAAM,QADa,QAAQ,QAAQ,QAAQ,EAAE,CAAC,CAAC,QAAQ,OAAO,EAChD,CAAA,CAAW,MAAM,+CAA+C;CAC9E,SAAO,OAAO,yBAAyB,UAAU;CACjD,OAAO;EACL,IAAI,MAAM;EACV,KAAK,MAAM,MAAM;CACnB;AACF;AAEA,SAAS,mBAAmB,SAAS,UAAU;CAC7C,MAAM,EAAE,MAAM,aAAa,iBAAiB,SAAS,QAAQ;CAC7D,MAAM,SAAS,eAAe,MAAM,QAAQ;CAC5C,OAAO;EACL,UAAU,SAAS,SAAS,KAAA;EAC5B,SAAS,SAAS,WAAW;EAC7B,MAAM,SAAS;EACf,IAAI,OAAO;EACX,KAAK,OAAO;EACZ,MAAM,SAAS,QAAQ;CACzB;AACF;AAEA,SAAS,kBAAkB,mBAAmB,cAAqB,CAAC,GAAG;CACrE,MAAM,UAAiB,CAAC;CACxB,KAAK,MAAM,SAAS,aAAa;EAC/B,IAAI,OAAO,UAAU,UAAU;GAC7B,QAAQ,KACN,mBAAmB,WAAW,mBAAmB,OAAO,SAAS,OAAO,GAAG,KAAK,CAClF;GACA;EACF;EACA,IAAI,MAAM,OAAO,KAAA,KAAa,MAAM,QAAQ,KAAA,GAAW;GACrD,SACE,OAAO,MAAM,OAAO,YAAY,OAAO,MAAM,QAAQ,UACrD,yCACF;GACA,QAAQ,KAAK;IACX,UAAU,MAAM,SAAS,KAAA;IACzB,SAAS,MAAM,WAAW;IAC1B,MAAM,MAAM;IACZ,IAAI,MAAM;IACV,KAAK,MAAM;IACX,MAAM,MAAM,QAAQ;GACtB,CAAC;GACD;EACF;EAEA,SACE,OAAO,MAAM,SAAS,UACtB,gEACF;EACA,QAAQ,KACN,mBACE,WAAW,mBAAmB,MAAM,MAAM,SAAS,MAAM,MAAM,GAC/D,MAAM,IACR,CACF;CACF;CACA,OAAO;AACT;AAEA,SAAS,cAAc,UAAU,mBAAmB;CAClD,MAAM,6BAAa,IAAI,IAAoB;CAC3C,MAAM,cAAc,IAAI,IAAY,SAAS,WAAW,CAAC,CAAC;CAC1D,KAAK,MAAM,SAAS,SAAS,YAAY,CAAC,GACxC,IAAI,MAAM,QACR,YAAY,IAAI,MAAM,MAAM;CAGhC,KAAK,MAAM,QAAQ,aACjB,WAAW,IACT,MACA,gBAAgB,WAAW,GAAG,SAAS,aAAa,SAAS,KAAK,UAAU,MAAM,GACpF;CAGF,MAAM,qBAAqB,GAAG,YAAY,KAAK,KAAK,GAAG,OAAO,GAAG,wBAAwB,CAAC;CAC1F,IAAI;EACF,MAAM,YAAY,SAAS,YAAY,CAAC,EAAA,CAAG,KAAK,OAAO,UAAU;GAC/D,IAAI;GACJ,IAAI,MAAM,QAAQ;IAChB,SACE,OAAO,MAAM,SAAS,UACtB,oBAAoB,MAAM,WAAW,QAAQ,EAAE,iBACjD;IAKA,UAAU,eAJQ,KAAK,QAAQ,mBAAmB,MAAM,IAI/B,GAHN,MAAM,eACrB,KAAK,QAAQ,mBAAmB,MAAM,YAAY,IAClD,KAAK,KAAK,oBAAoB,YAAY,MAAM,KAAK,CACX;GAChD,OACE,UAAU,WACR,mBACA,OACA,YAAY,MAAM,WAAW,MAAM,QAAQ,IAC7C;GAEF,OAAO;IACL,mBAAmB,MAAM;IACzB,cAAc,MAAM,gBAAgB;IACpC,aAAa,MAAM,eAAe;IAClC,SAAS,MAAM,WAAW,KAAK,SAAS,MAAM,QAAQ,UAAU;IAChE;IACA,YAAY,MAAM;IAClB,QAAQ,MAAM,SAAS,WAAW,IAAI,MAAM,MAAM,IAAI,KAAA;IACtD,aAAa,MAAM,eAAe;IAClC,KAAK,MAAM,OAAO;IAClB,MAAM,MAAM,QAAQ;IACpB,WAAW,MAAM,gBAAgB;IACjC,WAAW,MAAM,aAAa;IAC9B,UAAU,MAAM,YAAY;GAC9B;EACF,CAAC;EAED,KAAK,MAAM,QAAQ,aACjB,SAAS,KAAK;GACZ,cAAc;GACd,aAAa;GACb,SAAS;GACT,SAAS;GACT,aAAa;GACb,KAAK,WAAW,IAAI,IAAI;GACxB,MAAM;GACN,WAAW;GACX,WAAW;GACX,UAAU;EACZ,CAAC;EAEH,OAAO;CACT,UAAU;EACR,GAAG,OAAO,oBAAoB;GAAE,OAAO;GAAM,WAAW;EAAK,CAAC;CAChE;AACF;AAEA,SAAS,eAAe,WAAmB,YAA4B;CACrE,UAAU,WAAW,UAAU;CAC/B,OAAO,GAAG,aAAa,YAAY,MAAM;AAC3C;AAEA,SAAS,cAAc,UAAU,mBAAmB;CAClD,MAAM,qBAAqB,GAAG,YAAY,KAAK,KAAK,GAAG,OAAO,GAAG,eAAe,CAAC;CACjF,IAAI;EACF,QAAQ,SAAS,YAAY,CAAC,EAAA,CAAG,KAAK,SAAS,UAAU;GACvD,IAAI,SAAS,QAAQ;GACrB,IAAI,QAAQ,KAAK;IACf,MAAM,YAAY,KAAK,QAAQ,mBAAmB,QAAQ,GAAG;IAC7D,IAAI;IACJ,IAAI,QAAQ,UAAU,MAIpB,OAAO,eAAe,WAHH,QAAQ,eACvB,KAAK,QAAQ,mBAAmB,QAAQ,YAAY,IACpD,KAAK,KAAK,oBAAoB,WAAW,MAAM,KAAK,CACb;SAE3C,OAAO,GAAG,aAAa,WAAW,MAAM;IAE1C,SAAS,CAAC;KAAE;KAAM,MAAM;IAAa,CAAC;GACxC;GACA,SAAO,MAAM,QAAQ,MAAM,GAAG,WAAW,QAAQ,EAAE,wBAAwB;GAC3E,OAAO;IACL,SAAS,QAAQ,WAAW;IAC5B,YAAY,QAAQ,cAAc,CAAC;IACnC;IACA,gBAAgB,QAAQ;IACxB,MAAM,QAAQ,QAAQ;GACxB;EACF,CAAC;CACH,UAAU;EACR,GAAG,OAAO,oBAAoB;GAAE,OAAO;GAAM,WAAW;EAAK,CAAC;CAChE;AACF;AAEA,SAAS,YAAY,QAAQ,WAAW;CACtC,MAAM,UAAU,OAAO,KACrB,KAAK,UAAU,eAAa;EAAE;EAAQ,MAAM;CAAa,CAAC,GAAG,MAAM,CAAC,GACpE,MACF;CACA,MAAM,UAAU,OAAO,YAAY,QAAQ,MAAM;CACjD,KAAK,IAAI,QAAQ,GAAG,QAAQ,QAAQ,QAAQ,SAAS,GACnD,QAAQ,SAAS,UAAU,QAAQ;CAErC,MAAM,SAAS,OAAO,MAAM,CAAC;CAC7B,OAAO,WAAW,KAAK,CAAC;CACxB,OAAO,WAAW,GAAG,CAAC;CACtB,OAAO,cAAc,QAAQ,QAAQ,CAAC;CACtC,OAAO,OAAO,OAAO;EAAC;EAAQ;EAAS,OAAO,KAAK,CAAC,CAAC,CAAC;CAAC,CAAC;AAC1D;AAEA,SAAS,iBAAiB,UAAU,mBAAmB;CACrD,MAAM,aAAoB,CAAC;CAC3B,MAAM,QAA+C,CAAC;CACtD,MAAM,6BAAa,IAAI,IAAY;CAEnC,SAAS,SAAS,EAAE,MAAM,WAAW,MAAM,QAAQ;EACjD,MAAM,WAAW,iBAAiB,SAAS;EAC3C,MAAM,gBAAgB,UAAU,SAAS,SAAS,SAAS,QAAQ,GAAG;EACtE,MAAM,WAAW,oBAAoB,IAAI;EACzC,IAAI,cAAc;EAClB,IAAI,SAAS;EACb,OAAO,WAAW,IAAI,WAAW,GAAG;GAClC,UAAU;GACV,cAAc,GAAG,SAAS,GAAG;EAC/B;EACA,MAAM,cAAc,GAAG,cAAc,GAAG,YAAY,GAAG;EACvD,WAAW,IAAI,WAAW;EAC1B,WAAW,KAAK;GACd,KAAK;GACL;GACA;GACA,KAAK,aAAa;EACpB,CAAC;EACD,MAAM,KAAK;GAAE;GAAM,MAAM;EAAY,CAAC;EACtC,MAAM,KAAK;GACT,MAAM,OAAO,KAAK,KAAK,UAAU,EAAE,MAAM,gBAAgB,IAAI,EAAE,GAAG,MAAM,CAAC,CAAC;GAC1E,MAAM,UAAU,YAAY;EAC9B,CAAC;CACH;CAEA,IAAI,SAAS,MAAM;EACjB,MAAM,WAAW,KAAK,QAAQ,mBAAmB,SAAS,IAAI;EAC9D,MAAM,YAAY,KAAK,QAAQ,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,YAAY,KAAK;EACnE,SAAS;GAAE,MAAM,GAAG,aAAa,QAAQ;GAAG;GAAW,MAAM;GAAQ,MAAM;EAAO,CAAC;CACrF,OACE,SAAS;EAAE,MAAM;EAAc,WAAW;EAAO,MAAM;EAAQ,MAAM;CAAO,CAAC;CAG/E,KAAK,MAAM,SAAS,SAAS,UAAU,CAAC,GAAG;EACzC,SAAO,OAAO,MAAM,SAAS,UAAU,6BAA6B;EACpE,MAAM,YAAY,KAAK,QAAQ,mBAAmB,MAAM,IAAI;EAC5D,MAAM,aAAa,MAAM,aAAa,KAAK,QAAQ,SAAS,CAAC,CAAC,MAAM,CAAC,EAAA,CAAG,YAAY;EACpF,SAAO,cAAc,IAAI,kCAAkC,MAAM,MAAM;EACvE,SAAO,cAAc,KAAK,SAAS,GAAG,yBAAyB,MAAM,KAAK,IAAI,WAAW;EACzF,SAAS;GACP,MAAM,GAAG,aAAa,SAAS;GAC/B;GACA,MAAM,MAAM,QAAQ,KAAK,SAAS,WAAW,KAAK,QAAQ,SAAS,CAAC;GACpE,MAAM;EACR,CAAC;CACH;CACA,OAAO;EAAE;EAAY;CAAM;AAC7B;AAEA,SAAS,WAAW,UAAU,UAAU,YAAY,YAAkC;CACpF,MAAM,aAAa,YAAY,QAAQ,CAAC;CACxC,MAAM,mBAAmB,WAAW,cAAc,CAAC;CACnD,MAAM,eAAe,iBAAiB,UAAU,CAAC;CACjD,MAAM,UAAU,SAAS,KAAK,WAAW;EACvC,gBAAgB,MAAM,YAAY,uBAAuB;EACzD,SAAS,MAAM;EACf,UAAU,MAAM;EAChB,SAAS,MAAM;EACf,SAAS;EACT,YAAY;GACV,GAAG,MAAM;GACT,wBAAwB,MAAM;GAC9B,gBAAgB,MAAM;EACxB;EACA,QAAQ,MAAM;EACd,iBAAiB,MAAM;EACvB,MAAM,MAAM,IAAI,MAAM,GAAG,CAAC,CAAC,KAAK,QAAQ,IAAI,KAAK,CAAC;EAClD,MAAM,MAAM;EACZ,MAAM,MAAM;EACZ,gBAAgB,MAAM,YAClB,MAAM,UAAU,MAAM,GAAG,CAAC,CAAC,KAAK,QAAQ,IAAI,KAAK,CAAC,IAClD,KAAA;EACJ,WAAW,MAAM;EACjB,WAAW,MAAM;CACnB,EAAE;CACF,OAAO;EACL,GAAG;EACH,MAAM;GACJ,GAAG;GACH,qBAAqB,WAAW,uBAAuB,CAAC;GACxD,QAAQ;GACR,gBAAgB;IACd;IACA,YAAY,EAAE,uBAAuB,MAAM;GAC7C;GACA,mBAAmB,SAAS,WAAW,WAAW,qBAAqB;GACvE,eAAe,WAAW,iBAAiB;GAC3C,SAAS,SAAS,WAAW,WAAW,WAAW;GACnD,eAAe,SAAS,eAAe,WAAW,iBAAiB;GACnE,aAAa,WAAW,eAAe;GACvC,YAAY;IACV,GAAG;IACH,iBAAiB,SAAS,OAAO,KAAA,IAAY;IAC7C,QAAQ;KACN,GAAG;KACH,gBAAgB,aAAa,kBAAkB;KAC/C,gBAAgB,SAAS,MACrB,WAAW,KAAK,QAAQ,SAAS,MAAM,GAAG,SAAS,KAAK,KAAK,IAC7D;KACJ,MAAM,aAAa,QAAQ,CAAC;KAC5B,kBAAkB,aAAa,oBAAoB;KACnD,cAAc,SAAS,YAAY;KACnC,iBAAiB,aAAa,mBAAmB;KACjD,eAAe,aAAa,iBAAiB;KAC7C,SAAS,SAAS,WAAW;KAC7B,UAAU,aAAa,YAAY;KACnC,gBAAgB,SAAS,kBAAkB;KAC3C,iBAAiB,SAAS;KAC1B,YAAY,aAAa;KACzB,sBAAsB,aAAa,wBAAwB;KAC3D,sBAAsB,aAAa,wBAAwB,CAAC;KAC5D,oBAAoB,aAAa,sBAAsB;KACvD,QAAQ,aAAa,UAAU,CAAC;KAChC,SAAS,SAAS,UACd,WAAW,KAAK,QAAQ,SAAS,MAAM,GAAG,SAAS,SAAS,SAAS,IACrE;KACJ,YAAY,aAAa,cAAc;KACvC,YAAY;KACZ,eAAe,aAAa,iBAAiB;KAC7C,MAAM,aAAa,QAAQ,CAAC;IAC9B;GACF;GACA,WAAW,WAAW,aAAa;GACnC,sBAAsB,WAAW,wBAAwB,CAAC;GAC1D,aAAa,WAAW,eAAe;GACvC,mBAAmB,QAAQ,IAAI,oBAC3B,OAAO,QAAQ,IAAI,iBAAiB,IACpC,KAAK,MAAM,KAAK,IAAI,IAAI,GAAI;GAChC,MAAM,SAAS;GACf,UAAU,WAAW,YAAY;GACjC,aAAa,WAAW,eAAe;GACvC,2BAA2B,WAAW,6BAA6B;GACnE,UAAU,WAAW,YAAY;GACjC,QAAQ,WAAW,UAAU,CAAC;GAC9B,eAAe,WAAW,iBAAiB;GAC3C,MAAM,SAAS,QAAQ,WAAW,QAAQ,CAAC;EAC7C;EACA,MAAM,YAAY,QAAQ;EAC1B,cAAc,YAAY,gBAAgB;CAC5C;AACF;AAEA,SAAS,eAAe,MAAM;CAE5B,OAAO;EACL,MAFW,KAAK,IAAI,MAAM,KAAK,eAAe,CAEtC,IAAO,QAAS,IAAO,KAAK,YAAY,IAAI,KAAM,IAAK,KAAK,WAAW;EAC/E,MACG,KAAK,YAAY,KAAK,KACtB,KAAK,cAAc,KAAK,IACzB,KAAK,MAAM,KAAK,cAAc,IAAI,CAAC;CACvC;AACF;AAEA,SAAS,UAAU,OAAO,WAAW;CACnC,SAAO,MAAM,UAAU,OAAQ,6BAA6B;CAC5D,MAAM,iBAA2B,CAAC;CAClC,MAAM,eAAyB,CAAC;CAChC,IAAI,SAAS;CACb,MAAM,EAAE,MAAM,SAAS,eAAe,SAAS;CAE/C,KAAK,MAAM,QAAQ,OAAO;EACxB,MAAM,OAAO,OAAO,KAAK,KAAK,IAAI;EAClC,MAAM,aAAa,KAAK,eAAe,MAAM,EAAE,OAAO,EAAE,CAAC;EACzD,MAAM,WAAW,OAAO,KAAK,KAAK,KAAK,QAAQ,OAAO,GAAG,GAAG,MAAM;EAClE,MAAM,QAAQ,iBAAe,IAAI;EACjC,SACE,KAAK,UAAU,cAAc,WAAW,UAAU,YAClD,GAAG,KAAK,KAAK,sBACf;EAEA,MAAM,cAAc,OAAO,MAAM,EAAE;EACnC,YAAY,cAAc,UAAY,CAAC;EACvC,YAAY,cAAc,IAAI,CAAC;EAC/B,YAAY,cAAc,MAAQ,CAAC;EACnC,YAAY,cAAc,GAAG,CAAC;EAC9B,YAAY,cAAc,MAAM,EAAE;EAClC,YAAY,cAAc,MAAM,EAAE;EAClC,YAAY,cAAc,OAAO,EAAE;EACnC,YAAY,cAAc,WAAW,QAAQ,EAAE;EAC/C,YAAY,cAAc,KAAK,QAAQ,EAAE;EACzC,YAAY,cAAc,SAAS,QAAQ,EAAE;EAC7C,YAAY,cAAc,GAAG,EAAE;EAC/B,aAAa,KAAK,aAAa,UAAU,UAAU;EAEnD,MAAM,gBAAgB,OAAO,MAAM,EAAE;EACrC,cAAc,cAAc,UAAY,CAAC;EACzC,cAAc,cAAc,IAAI,CAAC;EACjC,cAAc,cAAc,IAAI,CAAC;EACjC,cAAc,cAAc,MAAQ,CAAC;EACrC,cAAc,cAAc,GAAG,EAAE;EACjC,cAAc,cAAc,MAAM,EAAE;EACpC,cAAc,cAAc,MAAM,EAAE;EACpC,cAAc,cAAc,OAAO,EAAE;EACrC,cAAc,cAAc,WAAW,QAAQ,EAAE;EACjD,cAAc,cAAc,KAAK,QAAQ,EAAE;EAC3C,cAAc,cAAc,SAAS,QAAQ,EAAE;EAC/C,cAAc,cAAc,GAAG,EAAE;EACjC,cAAc,cAAc,GAAG,EAAE;EACjC,cAAc,cAAc,GAAG,EAAE;EACjC,cAAc,cAAc,GAAG,EAAE;EACjC,cAAc,cAAc,GAAG,EAAE;EACjC,cAAc,cAAc,QAAQ,EAAE;EACtC,eAAe,KAAK,eAAe,QAAQ;EAC3C,UAAU,YAAY,SAAS,SAAS,SAAS,WAAW;CAC9D;CAEA,MAAM,mBAAmB,OAAO,OAAO,cAAc;CACrD,MAAM,MAAM,OAAO,MAAM,EAAE;CAC3B,IAAI,cAAc,WAAY,CAAC;CAC/B,IAAI,cAAc,GAAG,CAAC;CACtB,IAAI,cAAc,GAAG,CAAC;CACtB,IAAI,cAAc,MAAM,QAAQ,CAAC;CACjC,IAAI,cAAc,MAAM,QAAQ,EAAE;CAClC,IAAI,cAAc,iBAAiB,QAAQ,EAAE;CAC7C,IAAI,cAAc,QAAQ,EAAE;CAC5B,IAAI,cAAc,GAAG,EAAE;CACvB,OAAO,OAAO,OAAO;EAAC,GAAG;EAAc;EAAkB;CAAG,CAAC;AAC/D;AAEA,SAAS,WAAW,cAAsB,gBAAiC;CACzE,MAAM,uBAAuB,KAAK,QAAQ,YAAY;CACtD,MAAM,oBAAoB,KAAK,QAAQ,oBAAoB;CAC3D,MAAM,WAAW,KAAK,MAAM,GAAG,aAAa,sBAAsB,MAAM,CAAC;CACzE,SAAS,SAAS;CAClB,SAAO,OAAO,SAAS,SAAS,YAAY,SAAS,SAAS,IAAI,2BAA2B;CAE7F,MAAM,WAAW,cAAc,UAAU,iBAAiB;CAC1D,MAAM,QAAQ,kBAAkB,mBAAmB,SAAS,KAAK;CACjE,MAAM,UAAU,cAAc,UAAU,iBAAiB;CACzD,MAAM,EAAE,YAAY,OAAO,eAAe,iBAAiB,UAAU,iBAAiB;CAEtF,MAAM,OAAO,WAAW,UAAU,UAAU,YADzB,SAAS,UAAU,iBACkB,CAAU;CAClE,MAAM,SAAS;EACb,aAAa,cAAc,SAAS;EACpC,IAAI,WAAW,GAAG,SAAS,aAAa,SAAS,KAAK,QAAQ;EAC9D;EACA,MAAM,GAAG,SAAS,KAAK;EACvB;EACA;CACF;CAEA,MAAM,MAAM,GAAG,aAAa,gBAAc;CAC1C,SAAO,IAAI,UAAU,KAAK,sBAAsB,kBAAgB;CAChE,MAAM,QAAQ;EACZ,GAAG;EACH;GAAE,MAAM,OAAO,KAAK,KAAK,UAAU,eAAa,IAAI,GAAG,MAAM,CAAC,CAAC;GAAG,MAAM;EAAY;EACpF;GAAE,MAAM,YAAY,eAAa,MAAM,GAAG,IAAI,SAAS,GAAG,GAAG,CAAC;GAAG,MAAM;EAAe;CACxF,CAAC,CAAC,MAAM,MAAM,UAAU,KAAK,KAAK,cAAc,MAAM,IAAI,CAAC;CAE3D,MAAM,aAAa,iBACf,KAAK,QAAQ,cAAc,IAC3B,KAAK,QACH,mBACA,SAAS,UAAU,WAAW,oBAAoB,SAAS,IAAI,EAAE,OACnE;CACJ,GAAG,UAAU,KAAK,QAAQ,UAAU,GAAG,EAAE,WAAW,KAAK,CAAC;CAC1D,MAAM,YAAY,QAAQ,IAAI,oCAC1B,IAAI,KAAK,OAAO,QAAQ,IAAI,iBAAiB,IAAI,GAAI,oBACrD,IAAI,KAAK;CACb,GAAG,cAAc,YAAY,UAAU,OAAO,SAAS,CAAC;CACxD,QAAQ,IAAI,SAAS,KAAK,SAAS,QAAQ,IAAI,GAAG,UAAU,EAAE,IAAI,MAAM,OAAO,QAAQ;CACvF,OAAO;AACT;;;AC1pBA,IAAM,QAAQ,OAAO,KAAK,YAAY;AACtC,IAAM,oBAAoB;AAS1B,SAAS,iBAAiB,UAAkC;CAC1D,IAAI,CAAC,SAAS,SAAS,GAAG,MAAM,MAAM,CAAC,CAAC,OAAO,KAAK,GAClD,MAAM,IAAI,MAAM,yBAAyB;CAG3C,IAAI,SAAS,MAAM;CACnB,OAAO,SAAS,SAAS,QAAQ;EAC/B,IAAI,SAAS,IAAI,SAAS,QACxB,MAAM,IAAI,MAAM,kCAAkC,QAAQ;EAE5D,MAAM,OAAO,SAAS;EACtB,MAAM,aAAa,SAAS,SAAS,OAAO;EAC5C,MAAM,aAAa,SAAS,SAAS;EACrC,UAAU;EAEV,IAAI,SAAS,aAAa,IAAI,SAAS,QACrC,MAAM,IAAI,MAAM,gCAAgC,QAAQ;EAE1D,MAAM,OAAO,SAAS,SAAS,QAAQ,SAAS,UAAU,CAAC,CAAC,SAAS,MAAM;EAC3E,UAAU;EACV,MAAM,gBAAgB,SAAS,aAAa,MAAM;EAClD,UAAU;EAEV,IAAI,SAAS,gBAAgB,SAAS,QACpC,MAAM,IAAI,MAAM,aAAa,KAAK,iBAAiB,QAAQ;EAE7D,IAAI,UAAU,SAAS,SAAS,QAAQ,SAAS,aAAa;EAC9D,UAAU;EAEV,IAAI,SAAS,mBACX;EAEF,IAAI,YACF,UAAU,KAAK,WAAW,OAAO;EAEnC,OAAO,KAAK,MAAM,QAAQ,SAAS,MAAM,CAAC;CAC5C;CACA,MAAM,IAAI,MAAM,iCAAiC;AACnD;;;AC7CA,IAAM,mBAAiB,KAAK,KAC1B,KAAK,QAAQ,cAAc,YAAY,GAAG,CAAC,GAC3C,MACA,UACA,SACA,eACF;AAEA,IAAM,qBAAqB;CACzB,MAAM,wBAAQ,IAAI,YAAY,GAAG;CACjC,KAAK,IAAI,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS,GAAG;EACpD,IAAI,QAAQ;EACZ,KAAK,IAAI,MAAM,GAAG,MAAM,GAAG,OAAO,GAChC,KAAK,QAAQ,OAAO,GAClB,QAAQ,aAAc,UAAU;OAEhC,WAAW;EAGf,MAAM,SAAS,UAAU;CAC3B;CACA,OAAO;AACT,EAAA,CAAG;AAEH,SAAS,SAAO,WAAoB,SAAoC;CACtE,IAAI,CAAC,WACH,MAAM,IAAI,MAAM,OAAO;AAE3B;AAEA,SAAS,eAAe,MAAM;CAC5B,IAAI,QAAQ;CACZ,KAAK,MAAM,QAAQ,MACjB,QAAQ,aAAa,QAAQ,QAAQ,OAAS,UAAU;CAE1D,QAAQ,QAAQ,gBAAgB;AAClC;AAEA,SAAS,aAAa,MAAc,KAAkC;CACpE,SAAO,KAAK,UAAU,GAAG,2BAA2B;CACpD,SAAO,KAAK,UAAU,CAAC,MAAM,KAAK,mCAAmC;CACrE,SAAO,KAAK,UAAU,CAAC,MAAM,GAAG,qCAAqC,KAAK,UAAU,CAAC,GAAG;CAExF,MAAM,gBAAgB,KAAK,aAAa,CAAC;CACzC,SAAO,iBAAiB,KAAK,SAAS,GAAG,mCAAmC;CAC5E,SAAO,IAAI,UAAU,KAAK,sBAAsB,kBAAgB;CAEhE,IAAI;CACJ,IAAI,IAAI,UAAU,KAChB,YAAY,IAAI,SAAS,KAAK,GAAG;MAC5B;EACL,YAAY,OAAO,MAAM,GAAG;EAC5B,MAAM,uBAAO,IAAI,IAAI;EACrB,KAAK,IAAI,QAAQ,GAAG,QAAQ,KAAK,SAAS,GAAG;GAC3C,MAAM,UAAU,IAAI;GACpB,SAAO,CAAC,KAAK,IAAI,OAAO,GAAG,uCAAuC;GAClE,KAAK,IAAI,OAAO;GAChB,UAAU,WAAW;EACvB;CACF;CAEA,MAAM,UAAU,KAAK,SAAS,GAAG,IAAI,aAAa;CAClD,MAAM,UAAU,OAAO,YAAY,QAAQ,MAAM;CACjD,KAAK,IAAI,QAAQ,GAAG,QAAQ,QAAQ,QAAQ,SAAS,GACnD,QAAQ,SAAS,UAAU,QAAQ;CAGrC,MAAM,SAAS,KAAK,MAAM,QAAQ,SAAS,MAAM,CAAC;CAClD,SACE,UAAU,OAAO,SAAS,gBAAgB,OAAO,QACjD,6CACF;CACA,OAAO;AACT;AAEA,SAAS,0BAA0B,SAAS;CAC1C,MAAM,gBAAgB,KAAK,IAAI,GAAG,QAAQ,SAAS,QAAS,EAAE;CAC9D,KAAK,IAAI,SAAS,QAAQ,SAAS,IAAI,UAAU,eAAe,UAAU,GACxE,IAAI,QAAQ,aAAa,MAAM,MAAM,WAAY;EAC/C,MAAM,gBAAgB,QAAQ,aAAa,SAAS,EAAE;EACtD,IAAI,SAAS,KAAK,kBAAkB,QAAQ,QAC1C,OAAO;CAEX;CAEF,MAAM,IAAI,MAAM,0BAA0B;AAC5C;AAEA,SAAS,mBAAmB,MAAM;CAChC,SAAO,SAAS,IAAI,6BAA6B;CACjD,SAAO,CAAC,KAAK,SAAS,IAAI,GAAG,mCAAmC,KAAK,UAAU,IAAI,GAAG;CAEtF,MAAM,aAAa,KAAK,QAAQ,OAAO,GAAG;CAC1C,SAAO,CAAC,WAAW,WAAW,GAAG,GAAG,oCAAoC,MAAM;CAC9E,SAAO,CAAC,aAAa,KAAK,UAAU,GAAG,oCAAoC,MAAM;CAEjF,MAAM,QAAQ,WAAW,MAAM,GAAG;CAClC,SAAO,CAAC,MAAM,SAAS,IAAI,GAAG,2CAA2C,MAAM;CAC/E,OAAO,MAAM,QAAQ,SAAS,SAAS,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,GAAG;AACrE;AAEA,SAAS,mBAAmB,MAAc,UAA0B;CAQlE,OAPkB,MAAM,KAAK,OAAO,cAClC,UAAU,WAAW,CAAC,IAAI,KAAK,MAAM,SACvC,CAAC,CACE,KAAK,EAAE,CAAC,CACR,QAAQ,iBAAiB,GAAG,CAAC,CAC7B,QAAQ,WAAW,EAAE,CAAC,CACtB,KACI,KAAa;AACtB;AAEA,SAAS,aAAa,OAAO;CAC3B,IAAI,MAAM,QAAQ,KAAK,GACrB,OAAO,MAAM,IAAI,YAAY;CAE/B,IAAI,SAAS,OAAO,UAAU,YAAY,CAAC,OAAO,SAAS,KAAK,GAAG;EACjE,MAAM,SAAS,CAAC;EAChB,KAAK,MAAM,OAAO,OAAO,KAAK,KAAK,CAAC,CAAC,KAAK,GACxC,IAAI,MAAM,SAAS,KAAA,GACjB,OAAO,OAAO,aAAa,MAAM,IAAI;EAGzC,OAAO;CACT;CACA,OAAO;AACT;AAEA,SAAS,eAAe,WAAW,OAAO,WAAW,YAAY;CAC/D,MAAM,WAAW,mBAAmB,OAAO,UAAU;CACrD,MAAM,SAAS,SAAS,YAAY,CAAC,CAAC,SAAS,SAAS,IAAI,KAAK;CACjE,IAAI,YAAY,GAAG,UAAU,GAAG,WAAW;CAC3C,IAAI,YAAY;CAChB,OAAO,WAAW,IAAI,SAAS,GAAG;EAChC,aAAa;EACb,YAAY,GAAG,UAAU,GAAG,SAAS,GAAG,YAAY;CACtD;CACA,WAAW,IAAI,SAAS;CACxB,OAAO;AACT;AAEA,SAAS,oBAAoB,OAAO;CAClC,MAAM,cAAc,CAAC,YAAY,MAAM,WAAW,IAAI;CACtD,IAAI,MAAM,SAAS,KAAA,GACjB,YAAY,KAAK,SAAS,MAAM,MAAM;CAExC,YAAY,KAAK,SAAS,MAAM,QAAQ,eAAe;CACvD,OAAO,QAAQ,YAAY,KAAK,IAAI,EAAE,gBAAgB,MAAM,MAAM,GAAG,UAAU,MAAM,OAAO,GAAG;AACjG;AAEA,SAAS,kBAAkB,MAAM,OAAO;CACtC,MAAM,aAAa,KAAK,MAAM,KAAK,UAAU,IAAI,CAAC;CAClD,MAAM,OAAO,WAAW,QAAQ,CAAC;CACjC,MAAM,SAAS,KAAK,YAAY;CAEhC,MAAM,qBAAqB,KAAK,uBAAuB,CAAC;CACxD,SAAO,MAAM,QAAQ,kBAAkB,GAAG,gDAAgD;CAC1F,KAAK,IAAI,QAAQ,GAAG,QAAQ,mBAAmB,QAAQ,SAAS,GAAG;EACjE,MAAM,WAAW,mBAAmB;EACpC,SACE,OAAO,aAAa,UACpB,iCAAiC,MAAM,mBACzC;CACF;CAEA,MAAM,cAAc,KAAK,eAAe;CACxC,MAAM,eAAe,KAAK,aAAa;CACvC,SAAO,OAAO,gBAAgB,UAAU,wCAAwC;CAChF,SAAO,OAAO,iBAAiB,UAAU,sCAAsC;CAE/E,OAAO,KAAK;CACZ,OAAO,KAAK;CACZ,OAAO,KAAK;CACZ,OAAO,KAAK;CACZ,OAAO,KAAK;CACZ,OAAO,KAAK;CACZ,OAAO,KAAK;CACZ,OAAO,KAAK;CACZ,OAAO,KAAK;CACZ,OAAO,KAAK;CACZ,OAAO,KAAK;CAEZ,IAAI,QAAQ;EACV,OAAO,OAAO;EACd,OAAO,OAAO;EACd,OAAO,OAAO;EACd,OAAO,OAAO;EACd,OAAO,OAAO;EACd,OAAO,OAAO;EAiBd,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ;GAfxC,gBAAgB;GAChB,MAAM,CAAC;GACP,kBAAkB;GAClB,iBAAiB;GACjB,eAAe;GACf,UAAU;GACV,sBAAsB;GACtB,sBAAsB,CAAC;GACvB,oBAAoB;GACpB,QAAQ,CAAC;GACT,YAAY;GACZ,YAAY;GACZ,eAAe;GACf,MAAM,CAAC;EAEiC,CAAQ,GAChD,IAAI,KAAK,UAAU,aAAa,OAAO,IAAI,CAAC,MAAM,KAAK,UAAU,aAAa,KAAK,CAAC,GAClF,OAAO,OAAO;EAGlB,IAAI,OAAO,KAAK,MAAM,CAAC,CAAC,WAAW,GACjC,OAAO,KAAK,WAAW;CAE3B;CACA,IAAI,KAAK,YAAY;EACnB,OAAO,KAAK,WAAW;EACvB,IAAI,OAAO,KAAK,KAAK,UAAU,CAAC,CAAC,WAAW,GAC1C,OAAO,KAAK;CAEhB;CAaA,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ;EAVxC,eAAe;EACf,sBAAsB,CAAC;EACvB,aAAa;EACb,UAAU;EACV,aAAa;EACb,2BAA2B;EAC3B,UAAU;EACV,QAAQ,CAAC;EACT,eAAe;CAEyB,CAAY,GACpD,IAAI,KAAK,UAAU,aAAa,KAAK,IAAI,CAAC,MAAM,KAAK,UAAU,aAAa,KAAK,CAAC,GAChF,OAAO,KAAK;CAIhB,IAAI,OAAO,KAAK,IAAI,CAAC,CAAC,WAAW,GAC/B,OAAO,WAAW;MAElB,WAAW,OAAO;CAEpB,IAAI,WAAW,SAAS,iBACtB,OAAO,WAAW;CAEpB,IAAI,WAAW,iBAAiB,OAC9B,OAAO,WAAW;CAQpB,IAAI,EAJF,mBAAmB,SAAS,KAC5B,gBAAgB,MAChB,iBAAiB,MACjB,OAAO,KAAK,UAAU,CAAC,CAAC,SAAS,IAEjC;CAGF,MAAM,yBAAyB,mBAAmB,KAAK,UAAU,UAAU;EACzE,MAAM,OAAO,uBAAuB,QAAQ,EAAE;EAC9C,MAAM,IAAI,MAAM,OAAO,KAAK,UAAU,MAAM,CAAC;EAC7C,OAAO;CACT,CAAC;CACD,MAAM,IAAI,kBAAkB,OAAO,KAAK,aAAa,MAAM,CAAC;CAC5D,MAAM,IAAI,gBAAgB,OAAO,KAAK,cAAc,MAAM,CAAC;CAC3D,MAAM,IACJ,aACA,OAAO,KAAK,GAAG,KAAK,UAAU,aAAa,UAAU,GAAG,MAAM,CAAC,EAAE,KAAK,MAAM,CAC9E;CACA,OAAO;EACL,qBAAqB;EACrB,aAAa;EACb,MAAM;EACN,WAAW;CACb;AACF;AAEA,SAAS,4BACP,MACA,eACqB;CACrB,MAAM,aAAa,cAAc;CACjC,MAAM,wBAAQ,IAAI,IAAoB;CACtC,MAAM,8BAAc,IAAI,IAAc;CACtC,MAAM,UAAiB,CAAC;CACxB,MAAM,6BAAa,IAAI,IAAY;CAEnC,KAAK,MAAM,SAAS,WAAW,YAAY,CAAC,GAAG;EAC7C,IAAI,MAAM,SAAS,UACjB;EAEF,YAAY,IAAI,MAAM,KAAK,MAAM,OAAO;EACxC,QAAQ,KAAK,MAAM,OAAO;CAC5B;CAEA,MAAM,WAAkB,CAAC;CACzB,KAAK,MAAM,SAAS,WAAW,YAAY,CAAC,GAAG;EAC7C,IAAI,MAAM,SAAS,UACjB;EAEF,MAAM,OAAO,eAAe,aAAa,MAAM,SAAS,OAAO,UAAU;EACzE,MAAM,IAAI,MAAM,OAAO,KAAK,MAAM,WAAW,IAAI,MAAM,CAAC;EACxD,SAAS,KAAK;GACZ,mBAAmB,MAAM;GACzB,cAAc,MAAM,gBAAgB;GACpC,aAAa,MAAM,eAAe;GAClC,SAAS,MAAM,WAAW;GAC1B,YAAY,MAAM;GAClB;GACA,QAAQ,YAAY,IAAI,MAAM,MAAM;GACpC,aAAa,MAAM,eAAe;GAClC,KAAK,MAAM,OAAO;GAClB,MAAM,MAAM,QAAQ;GACpB,cAAc,MAAM,aAAa;GACjC,WAAW,MAAM,aAAa;GAC9B,UAAU,MAAM,YAAY;EAC9B,CAAC;CACH;CAEA,MAAM,QAAkB,CAAC;CACzB,KAAK,MAAM,SAAS,WAAW,SAAS,CAAC,GAAG;EAC1C,MAAM,OAAO,eAAe,SAAS,MAAM,SAAS,OAAO,UAAU;EACrE,MAAM,IAAI,MAAM,OAAO,KAAK,oBAAoB,KAAK,GAAG,MAAM,CAAC;EAC/D,MAAM,KAAK,IAAI;CACjB;CAEA,MAAM,WAAkB,CAAC;CACzB,KAAK,IAAI,QAAQ,GAAG,SAAS,WAAW,WAAW,CAAC,EAAA,CAAG,QAAQ,SAAS,GAAG;EACzE,MAAM,UAAU,WAAW,QAAQ;EACnC,MAAM,YACJ,QAAQ,QAAQ,WAAW,KAAK,QAAQ,OAAO,EAAE,CAAC,SAAS,eACvD,QAAQ,OAAO,KACf,KAAA;EACN,IAAI,CAAC,aAAa,OAAO,UAAU,SAAS,UAAU;GACpD,SAAS,KAAK,OAAO;GACrB;EACF;EAGA,MAAM,UAAU,eAAe,YADjB,QAAQ,WAAW,WAAW,QAAQ,KACF,QAAQ,UAAU;EACpE,MAAM,IAAI,SAAS,OAAO,KAAK,UAAU,MAAM,MAAM,CAAC;EACtD,SAAS,KAAK;GACZ,QAAQ;GACR,SAAS,QAAQ,WAAW;GAC5B,YAAY,QAAQ,cAAc,CAAC;GACnC,gBAAgB,QAAQ;GACxB,KAAK;GACL,MAAM,QAAQ,QAAQ;EACxB,CAAC;CACH;CAEA,MAAM,SAAS,KAAK,MAAM,YAAY,UAAU,CAAC;CACjD,MAAM,WAAgC;EACpC,MAAM,kBAAkB,MAAM,KAAK;EACnC,SAAS,KAAK,MAAM;EACpB,aAAa,KAAK,MAAM,iBAAiB,WAAW,eAAe;EACnE;EACA,UAAU,OAAO,gBAAgB,WAAW,YAAY;EACxD;EACA,gBAAgB,OAAO,kBAAkB,WAAW,kBAAkB;EACtE,MAAM,KAAK,MAAM,QAAQ,WAAW;EACpC,WAAW,OAAO,mBAAmB,WAAW;EAChD;EACA,MAAM,KAAK,MAAM;EACjB;EACA,SAAS,KAAK,MAAM,qBAAqB;CAC3C;CAEA,MAAM,MAAM,OAAO,kBAAkB,WAAW;CAChD,IAAI,KAAK;EACP,SAAS,MAAM;EACf,MAAM,IAAI,cAAc,OAAO,KAAK,KAAK,MAAM,CAAC;CAClD;CACA,MAAM,UAAU,OAAO,WAAW,WAAW;CAC7C,IAAI,SAAS;EACX,SAAS,UAAU;EACnB,MAAM,IAAI,eAAe,OAAO,KAAK,SAAS,MAAM,CAAC;CACvD;CAEA,MAAM,WAAW,KAAK,MAAM,QAAQ,MACjC,UAAU,MAAM,SAAS,UAAU,MAAM,SAAS,MACrD;CACA,IAAI,UAAU,KAAK,WAAW,YAAY,GACxC,SAAS,OAAO,SAAS,IAAI,MAAM,EAAmB;CAGxD,MAAM,SAAgB,CAAC;CACvB,KAAK,MAAM,SAAS,KAAK,MAAM,UAAU,CAAC,GAAG;EAC3C,IAAI,UAAU,YAAY,CAAC,MAAM,KAAK,WAAW,YAAY,GAC3D;EAEF,OAAO,KAAK;GACV,WAAW,MAAM;GACjB,MAAM,MAAM,IAAI,MAAM,EAAmB;GACzC,MAAM,MAAM;EACd,CAAC;CACH;CACA,IAAI,OAAO,SAAS,GAClB,SAAS,SAAS;CAGpB,MAAM,IACJ,cACA,OAAO,KAAK,GAAG,KAAK,UAAU,aAAa,QAAQ,GAAG,MAAM,CAAC,EAAE,KAAK,MAAM,CAC5E;CACA,OAAO;AACT;AAEA,SAAS,SAAS,SAAiB;CACjC,MAAM,YAAY,0BAA0B,OAAO;CACnD,MAAM,aAAa,QAAQ,aAAa,YAAY,CAAC;CACrD,MAAM,cAAc,QAAQ,aAAa,YAAY,CAAC;CACtD,MAAM,cAAc,QAAQ,aAAa,YAAY,CAAC;CACtD,MAAM,eAAe,QAAQ,aAAa,YAAY,EAAE;CACxD,MAAM,cAAc,QAAQ,aAAa,YAAY,EAAE;CACvD,MAAM,gBAAgB,QAAQ,aAAa,YAAY,EAAE;CAEzD,SAAO,eAAe,KAAK,gBAAgB,GAAG,2CAA2C;CACzF,SAAO,gBAAgB,cAAc,8BAA8B;CACnE,SACE,iBAAiB,SAAU,gBAAgB,cAAc,kBAAkB,YAC3E,wBACF;CAEA,MAAM,YAAY,YAAY,cAAc;CAC5C,SAAO,aAAa,GAAG,sCAAsC;CAE7D,MAAM,UAAiB,CAAC;CACxB,MAAM,wBAAQ,IAAI,IAAI;CACtB,IAAI,SAAS,YAAY;CACzB,KAAK,IAAI,QAAQ,GAAG,QAAQ,cAAc,SAAS,GAAG;EACpD,SAAO,SAAS,MAAM,QAAQ,QAAQ,oCAAoC;EAC1E,SACE,QAAQ,aAAa,MAAM,MAAM,UACjC,sCAAsC,QACxC;EAEA,MAAM,QAAQ,QAAQ,aAAa,SAAS,CAAC;EAC7C,MAAM,SAAS,QAAQ,aAAa,SAAS,EAAE;EAC/C,MAAM,gBAAgB,QAAQ,aAAa,SAAS,EAAE;EACtD,MAAM,iBAAiB,QAAQ,aAAa,SAAS,EAAE;EACvD,MAAM,mBAAmB,QAAQ,aAAa,SAAS,EAAE;EACzD,MAAM,aAAa,QAAQ,aAAa,SAAS,EAAE;EACnD,MAAM,cAAc,QAAQ,aAAa,SAAS,EAAE;EACpD,MAAM,gBAAgB,QAAQ,aAAa,SAAS,EAAE;EACtD,MAAM,YAAY,QAAQ,aAAa,SAAS,EAAE;EAClD,MAAM,cAAc,QAAQ,aAAa,SAAS,EAAE;EACpD,MAAM,eAAe,KAAK,aAAa,cAAc;EAErD,SAAO,SAAS,gBAAgB,QAAQ,QAAQ,iCAAiC;EACjF,UAAQ,QAAQ,OAAO,GAAG,yCAAyC;EACnE,SAAO,WAAW,KAAK,WAAW,GAAG,uCAAuC,QAAQ;EACpF,SAAO,cAAc,GAAG,0CAA0C;EAClE,SACE,mBAAmB,cACjB,qBAAqB,cACrB,gBAAgB,YAClB,iCACF;EAGA,MAAM,cADU,QAAQ,SAAS,SAAS,IAAI,SAAS,KAAK,UACxC,CAAA,CAAQ,SAAS,MAAM;EAC3C,MAAM,YAAY,YAAY,SAAS,GAAG,KAAK,YAAY,SAAS,IAAI;EACxE,MAAM,OAAO,mBAAmB,WAAW;EAC3C,SAAO,SAAS,IAAI,qCAAqC;EACzD,SAAO,CAAC,MAAM,IAAI,IAAI,GAAG,wBAAwB,MAAM;EACvD,MAAM,IAAI,IAAI;EAEd,QAAQ,KAAK;GACX;GACA;GACA;GACA,aAAa,YAAY;GACzB;GACA;GACA;EACF,CAAC;EACD,UAAU;CACZ;CAEA,SAAO,WAAW,WAAW,uDAAuD;CACpF,OAAO;AACT;AAEA,SAAS,UAAU,SAAS,OAAO;CACjC,MAAM,SAAS,MAAM;CACrB,SAAO,SAAS,MAAM,QAAQ,QAAQ,kCAAkC,MAAM,MAAM;CACpF,SAAO,QAAQ,aAAa,MAAM,MAAM,UAAY,6BAA6B,MAAM,MAAM;CAE7F,MAAM,aAAa,QAAQ,aAAa,SAAS,EAAE;CACnD,MAAM,cAAc,QAAQ,aAAa,SAAS,EAAE;CACpD,MAAM,aAAa,SAAS,KAAK,aAAa;CAC9C,MAAM,UAAU,aAAa,MAAM;CACnC,SAAO,WAAW,QAAQ,QAAQ,gCAAgC,MAAM,MAAM;CAE9E,MAAM,aAAa,QAAQ,SAAS,YAAY,OAAO;CACvD,MAAM,OAAO,MAAM,WAAW,IAAI,OAAO,KAAK,UAAU,IAAI,KAAK,eAAe,UAAU;CAC1F,SAAO,KAAK,WAAW,MAAM,kBAAkB,4BAA4B,MAAM,MAAM;CACvF,SACE,eAAe,IAAI,MAAM,MAAM,eAC/B,gCAAgC,MAAM,MACxC;CACA,SAAO,CAAC,MAAM,aAAa,KAAK,WAAW,GAAG,sCAAsC,MAAM,MAAM;CAChG,OAAO;AACT;AAEA,SAAS,6BAA2B,iBAAiB;CACnD,IAAI,CAAC,GAAG,WAAW,eAAe,GAChC;CAEF,SACE,GAAG,SAAS,eAAe,CAAC,CAAC,YAAY,GACzC,mCAAmC,iBACrC;CACA,SACE,GAAG,YAAY,eAAe,CAAC,CAAC,WAAW,GAC3C,kCAAkC,iBACpC;AACF;AAEA,SAAS,YAAY,WAAmB,YAA4B;CAClE,MAAM,oBAAoB,KAAK,QAAQ,SAAS;CAChD,MAAM,qBAAqB,KAAK,QAAQ,UAAU;CAClD,MAAM,UAAU,GAAG,aAAa,iBAAiB;CACjD,MAAM,UAAU,SAAS,OAAO;CAChC,MAAM,4BAAY,IAAI,IAAkD;CAExE,KAAK,MAAM,SAAS,SAClB,UAAU,IAAI,MAAM,MAAM;EACxB,MAAM,UAAU,SAAS,KAAK;EAC9B,WAAW,MAAM;CACnB,CAAC;CAGH,MAAM,YAAY,UAAU,IAAI,WAAW;CAC3C,SAAO,WAAW,0CAA0C;CAC5D,SAAO,CAAC,UAAU,WAAW,0BAA0B;CACvD,MAAM,OAAO,KAAK,MAAM,UAAU,KAAK,SAAS,MAAM,CAAC;CAEvD,IAAI;CACJ,IAAI,UAAU,IAAI,cAAc,GAAG;EACjC,MAAM,cAAc,UAAU,IAAI,cAAc;EAChD,SAAO,aAAa,6CAA6C;EACjE,SAAO,CAAC,YAAY,WAAW,6BAA6B;EAC5D,MAAM,MAAM,GAAG,aAAa,gBAAc;EAC1C,gBAAgB,aAAa,YAAY,MAAM,GAAG;CACpD;CAEA,MAAM,kBAAkB,gBACpB,4BAA4B,MAAM,aAAa,oBAC/C,IAAI,IAAI;CACZ,KAAK,MAAM,QAAQ,gBAAgB,KAAK,GACtC,SACE,SAAS,eAAe,CAAC,UAAU,IAAI,IAAI,GAC3C,4DAA4D,MAC9D;CAGF,6BAA2B,kBAAkB;CAC7C,GAAG,UAAU,oBAAoB,EAAE,WAAW,KAAK,CAAC;CAEpD,KAAK,MAAM,CAAC,MAAM,UAAU,WAAW;EACrC,IACE,SAAS,kBACR,iBAAiB,SAAS,eAC3B,gBAAgB,IAAI,IAAI,GAExB;EAEF,MAAM,cAAc,KAAK,KAAK,oBAAoB,GAAG,KAAK,MAAM,GAAG,CAAC;EACpE,IAAI,MAAM,WAAW;GACnB,GAAG,UAAU,aAAa,EAAE,WAAW,KAAK,CAAC;GAC7C;EACF;EACA,GAAG,UAAU,KAAK,QAAQ,WAAW,GAAG,EAAE,WAAW,KAAK,CAAC;EAC3D,GAAG,cAAc,aAAa,MAAM,IAAI;CAC1C;CAEA,KAAK,MAAM,CAAC,MAAM,SAAS,iBAAiB;EAC1C,MAAM,cAAc,KAAK,KAAK,oBAAoB,GAAG,KAAK,MAAM,GAAG,CAAC;EACpE,GAAG,UAAU,KAAK,QAAQ,WAAW,GAAG,EAAE,WAAW,KAAK,CAAC;EAC3D,GAAG,cAAc,aAAa,IAAI;CACpC;CAEA,MAAM,iBAAiB,KAAK,SAAS,QAAQ,IAAI,GAAG,kBAAkB,KAAK;CAC3E,QAAQ,IACN,YAAY,QAAQ,UAAU,gBAAgB,IAAI,GAAG,oBAAoB,gBAC3E;CACA,OAAO;AACT;;;AC7kBA,IAAM,iBAAiB,KAAK,KAC1B,KAAK,QAAQ,cAAc,YAAY,GAAG,CAAC,GAC3C,MACA,UACA,SACA,eACF;AAEA,SAAS,OAAO,WAAoB,SAAoC;CACtE,IAAI,CAAC,WACH,MAAM,IAAI,MAAM,OAAO;AAE3B;AAEA,SAAS,2BAA2B,iBAAiB;CACnD,IAAI,CAAC,GAAG,WAAW,eAAe,GAChC;CAEF,OACE,GAAG,SAAS,eAAe,CAAC,CAAC,YAAY,GACzC,mCAAmC,iBACrC;CACA,OACE,GAAG,YAAY,eAAe,CAAC,CAAC,WAAW,GAC3C,kCAAkC,iBACpC;AACF;AAEA,SAAS,YAAY,MAAM,WAAW;CACpC,KAAK,IAAI,QAAQ,GAAG,QAAQ,KAAK,QAAQ,SAAS,GAChD,KAAK,SAAS,UAAU,KAAK;CAE/B,OAAO;AACT;AAEA,SAAS,YAAY,gBAAgB,QAAQ,UAAU,OAAO;CAC5D,MAAM,OAAO,OAAO,YAAY,MAAM;CACtC,IAAI,OAAO;CACX,OAAO,OAAO,QAAQ;EACpB,MAAM,QAAQ,GAAG,SAAS,gBAAgB,MAAM,MAAM,SAAS,MAAM,WAAW,IAAI;EACpF,OAAO,QAAQ,GAAG,GAAG,MAAM,wBAAwB,WAAW,MAAM;EACpE,QAAQ;CACV;CACA,OAAO;AACT;AAEA,SAAS,kBAAkB,MAAc,UAA0B;CAQjE,OAPkB,MAAM,KAAK,OAAO,cAClC,UAAU,WAAW,CAAC,IAAI,KAAK,MAAM,SACvC,CAAC,CACE,KAAK,EAAE,CAAC,CACR,QAAQ,iBAAiB,GAAG,CAAC,CAC7B,QAAQ,WAAW,EAAE,CAAC,CACtB,KACI,CAAA,CAAU,MAAM,GAAG,GAAG,KAAK;AACpC;AAEA,SAAS,qBAAqB,MAAM,UAAU;CAC5C,IAAI,KAAK,SAAS,GAAG,CAAC,CAAC,CAAC,OAAO,OAAO,KAAK,oBAAoB,KAAK,CAAC,GACnE,OAAO;CAET,IAAI,KAAK,SAAS,GAAG,CAAC,CAAC,CAAC,OAAO,OAAO,KAAK,UAAU,KAAK,CAAC,GACzD,OAAO;CAET,IACE,KAAK,SAAS,GAAG,CAAC,CAAC,CAAC,SAAS,OAAO,MAAM,YAC1C,KAAK,SAAS,GAAG,CAAC,CAAC,CAAC,SAAS,OAAO,MAAM,UAE1C,OAAO;CAET,IACE,KAAK,SAAS,GAAG,CAAC,CAAC,CAAC,SAAS,OAAO,MAAM,UAC1C,KAAK,SAAS,GAAG,EAAE,CAAC,CAAC,SAAS,OAAO,MAAM,QAE3C,OAAO;CAET,IAAI,KAAK,SAAS,GAAG,EAAE,CAAC,CAAC,SAAS,OAAO,CAAC,CAAC,SAAS,UAAU,GAC5D,OAAO;CAET,OAAO,eAAe,KAAK,YAAY,EAAE,IAAI,SAAS,YAAY,IAAI;AACxE;AAEA,SAAS,cAAc,OAAO,MAAM,OAAO,YAAY;CACrD,MAAM,YAAY,qBAAqB,MAAM,MAAM,EAAE;CACrD,MAAM,WAAW,kBAAkB,MAAM,MAAM,IAAI,SAAS,QAAQ,GAAG;CACvE,IAAI,YAAY,UAAU,SAAS,GAAG;CACtC,IAAI,YAAY;CAChB,OAAO,WAAW,IAAI,SAAS,GAAG;EAChC,aAAa;EACb,YAAY,UAAU,SAAS,GAAG,UAAU,GAAG;CACjD;CACA,WAAW,IAAI,SAAS;CACxB,OAAO;AACT;AAEA,SAAS,aAAa,iBAAiB,eAAe,cAAc;CAMlE,MAAM,UAAU,4BAA4B,EAJ1C,MAAM,EACJ,MAAM,cAAc,OAAO,KAC7B,EAE0C,GAAM,aAAa;CAC/D,MAAM,iBAAiB,QAAQ,IAAI,YAAY;CAC/C,OAAO,gBAAgB,mDAAmD;CAC1E,MAAM,WAAW,KAAK,MAAM,eAAe,SAAS,MAAM,CAAC;CAC3D,SAAS,SAAS;CAClB,QAAQ,IAAI,cAAc,OAAO,KAAK,GAAG,KAAK,UAAU,UAAU,MAAM,CAAC,EAAE,KAAK,MAAM,CAAC;CAEvF,KAAK,MAAM,CAAC,MAAM,SAAS,SAAS;EAClC,MAAM,cAAc,KAAK,KAAK,iBAAiB,GAAG,KAAK,MAAM,GAAG,CAAC;EACjE,GAAG,UAAU,KAAK,QAAQ,WAAW,GAAG,EAAE,WAAW,KAAK,CAAC;EAC3D,GAAG,cAAc,aAAa,IAAI;CACpC;AACF;AAEA,SAAS,YAAY,WAAmB,YAA4B;CAClE,MAAM,oBAAoB,KAAK,QAAQ,SAAS;CAChD,MAAM,qBAAqB,KAAK,QAAQ,UAAU;CAClD,2BAA2B,kBAAkB;CAE7C,MAAM,MAAM,GAAG,aAAa,cAAc;CAC1C,OAAO,IAAI,UAAU,KAAK,sBAAsB,gBAAgB;CAChE,MAAM,YAAY,IAAI,SAAS,KAAK,GAAG;CACvC,MAAM,iBAAiB,GAAG,SAAS,mBAAmB,GAAG;CAEzD,IAAI;EACF,MAAM,WAAW,GAAG,UAAU,cAAc,CAAC,CAAC;EAC9C,MAAM,SAAS,YAAY,gBAAgB,GAAG,GAAG,cAAc;EAC/D,OAAO,OAAO,UAAU,CAAC,MAAM,KAAK,4BAA4B;EAChE,OAAO,OAAO,UAAU,CAAC,MAAM,GAAG,8BAA8B,OAAO,UAAU,CAAC,GAAG;EAErF,MAAM,gBAAgB,OAAO,aAAa,CAAC;EAC3C,MAAM,UAAU,YAAY,gBAAgB,eAAe,GAAG,sBAAsB;EACpF,MAAM,gBAAgB,KAAK,MAAM,YAAY,SAAS,SAAS,CAAC,CAAC,SAAS,MAAM,CAAC;EACjF,OACE,eAAe,SAAS,gBAAgB,cAAc,QACtD,sCACF;EAEA,MAAM,gBAAgB,cAAc,OAAO,UAAU,CAAC;EACtD,MAAM,eAAsB,CAAC;EAC7B,MAAM,6BAAa,IAAI,IAAY;EACnC,IAAI,aAAa;EACjB,IAAI,WAAW,IAAI;EAEnB,GAAG,UAAU,KAAK,KAAK,oBAAoB,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;EACzE,OAAO,WAAW,UAAU;GAC1B,MAAM,SAAS,YAAY,gBAAgB,GAAG,UAAU,oBAAoB,CAAC,CAAC,UAAU,CAAC;GACzF,YAAY;GACZ,IAAI,WAAW,GACb;GAEF,OAAO,WAAW,GAAG,sCAAsC,WAAW,EAAE,IAAI,QAAQ;GACpF,OACE,aAAa,cAAc,QAC3B,8DACF;GAGA,MAAM,cADa,YAAY,gBAAgB,GAAG,UAAU,oBACxC,CAAA,CAAW,aAAa,CAAC;GAC7C,YAAY;GACZ,MAAM,eAAe,YACnB,gBACA,aACA,UACA,eAAe,aAAa,GAC9B;GACA,YAAY;GAEZ,MAAM,WAAW,cAAc;GAC/B,OAAO,UAAU,eAAe,aAAa,EAAE,iBAAiB;GAChE,MAAM,eAAe,YAAY,cAAc,SAAS;GACxD,MAAM,aAAa,cAAc,UAAU,cAAc,YAAY,UAAU;GAC/E,MAAM,cAAc,KAAK,KAAK,oBAAoB,GAAG,WAAW,MAAM,GAAG,CAAC;GAC1E,GAAG,cAAc,aAAa,YAAY;GAC1C,aAAa,KAAK;IAChB,WAAW,KAAK,QAAQ,UAAU,CAAC,CAAC,MAAM,CAAC;IAC3C,MAAM;IACN,MAAM,SAAS;GACjB,CAAC;GACD,cAAc;GAEd,IAAI,aAAa,QAAQ,GACvB,QAAQ,IAAI,aAAa,WAAW,KAAK,cAAc,OAAO,QAAQ;EAE1E;EAEA,OACE,eAAe,cAAc,QAC7B,kBAAkB,WAAW,6BAA6B,cAAc,QAC1E;EACA,OACE,aAAa,UACb,kBAAkB,WAAW,SAAS,qCACxC;EACA,aAAa,oBAAoB,eAAe,YAAY;EAE5D,MAAM,iBAAiB,KAAK,SAAS,QAAQ,IAAI,GAAG,kBAAkB,KAAK;EAC3E,QAAQ,IAAI,YAAY,WAAW,gCAAgC,gBAAgB;EACnF,OAAO;CACT,UAAU;EACR,GAAG,UAAU,cAAc;CAC7B;AACF"}
package/package.json CHANGED
@@ -1,8 +1,12 @@
1
1
  {
2
2
  "name": "risupack",
3
- "version": "0.1.4",
3
+ "version": "0.2.2",
4
4
  "description": "Command-line tools for packing and unpacking RisuAI modules",
5
5
  "license": "AGPL-3.0-only",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/enzi221/risupack.git"
9
+ },
6
10
  "bin": {
7
11
  "risupack": "dist/cli.js"
8
12
  },
@@ -21,7 +25,8 @@
21
25
  "build": "vp build && tsc --project tsconfig.build.json",
22
26
  "check": "tsc --noEmit",
23
27
  "prepack": "npm run check && npm run build",
24
- "prepare": "vp config"
28
+ "prepare": "vp config",
29
+ "test": "vp test"
25
30
  },
26
31
  "devDependencies": {
27
32
  "@types/node": "^24.3.0",
@@ -1 +0,0 @@
1
- {"version":3,"file":"unpack-risum-CyOf_v7e.js","names":[],"sources":["../src/bundle.ts","../src/build-charx.ts","../src/inspect-risusave.ts","../src/unpack-charx.ts","../src/unpack-risum.ts"],"sourcesContent":["import fs from \"node:fs\";\nimport path from \"node:path\";\n\nconst REQUIRE_PATTERN = /require\\s*\\(?[\"']([^\"']+)[\"']\\)?/g;\n\ninterface BundleState {\n entryPath: string;\n hoistedComments: string[];\n includedModules: Set<string>;\n preloads: string[];\n totalInputBytes: number;\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes === 0) {\n return \"0 B\";\n }\n\n const base = 1024;\n const sizes = [\"B\", \"KB\", \"MB\"];\n const index = Math.floor(Math.log(bytes) / Math.log(base));\n return `${Number.parseFloat((bytes / Math.pow(base, index)).toFixed(2))} ${sizes[index]}`;\n}\n\nfunction resolveModulePath(moduleName: string): string {\n return `${moduleName.replace(/\\./g, \"/\")}.lua`;\n}\n\nfunction minifyLua(content: string, hoistedComments: string[]): string {\n const tokenPattern =\n /(--\\[(=*)\\[[\\s\\S]*?\\]\\2\\])|(--.*)|(\\[(=*)\\[[\\s\\S]*?\\]\\5\\])|(\"([^\"\\\\]|\\\\.)*\")|('([^'\\\\]|\\\\.)*')/g;\n\n return content\n .replace(\n tokenPattern,\n (match: string, longComment?: string, _equals?: string, shortComment?: string) => {\n if (!longComment && !shortComment) {\n return match;\n }\n if (shortComment?.startsWith(\"--!\") || (longComment && /^--\\[(=*)\\[!/.test(match))) {\n hoistedComments.push(match);\n }\n return \" \";\n },\n )\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line.length > 0)\n .join(\"\\n\");\n}\n\nfunction processModule(moduleName: string, state: BundleState): void {\n if (state.includedModules.has(moduleName)) {\n return;\n }\n\n const rootDirectory = path.dirname(path.resolve(state.entryPath));\n const modulePath = path.join(rootDirectory, resolveModulePath(moduleName));\n if (!fs.existsSync(modulePath)) {\n console.warn(`Warning: Module '${moduleName}' not found`);\n return;\n }\n\n const rawContent = fs.readFileSync(modulePath, \"utf8\");\n state.includedModules.add(moduleName);\n state.totalInputBytes += fs.statSync(modulePath).size;\n\n for (const match of rawContent.matchAll(new RegExp(REQUIRE_PATTERN.source, \"g\"))) {\n const dependency = match[1];\n if (dependency) {\n processModule(dependency, state);\n }\n }\n\n const minifiedContent = minifyLua(rawContent, state.hoistedComments);\n state.preloads.push(`package.preload[\"${moduleName}\"]=function(...)${minifiedContent} end`);\n}\n\nfunction bundleLua(entryPath: string, outputArgument: string): string {\n const resolvedEntryPath = path.resolve(entryPath);\n if (!fs.existsSync(resolvedEntryPath)) {\n throw new Error(`Entry file not found: ${entryPath}`);\n }\n\n let outputPath = path.resolve(outputArgument);\n if (fs.existsSync(outputPath) && fs.statSync(outputPath).isDirectory()) {\n outputPath = path.join(outputPath, path.basename(resolvedEntryPath));\n }\n if (path.extname(outputPath) !== \".lua\") {\n outputPath += \".lua\";\n }\n\n const state: BundleState = {\n entryPath: resolvedEntryPath,\n hoistedComments: [],\n includedModules: new Set(),\n preloads: [],\n totalInputBytes: fs.statSync(resolvedEntryPath).size,\n };\n const mainContent = fs.readFileSync(resolvedEntryPath, \"utf8\");\n\n for (const match of mainContent.matchAll(new RegExp(REQUIRE_PATTERN.source, \"g\"))) {\n const moduleName = match[1];\n if (moduleName) {\n processModule(moduleName, state);\n }\n }\n\n const mainMinified = minifyLua(mainContent, state.hoistedComments);\n const hoisted = state.hoistedComments.length > 0 ? `${state.hoistedComments.join(\"\\n\")}\\n` : \"\";\n const output = `${hoisted}${state.preloads.join(\"\\n\")}\\n${mainMinified}`;\n\n fs.mkdirSync(path.dirname(outputPath), { recursive: true });\n fs.writeFileSync(outputPath, output, \"utf8\");\n\n const outputBytes = fs.statSync(outputPath).size;\n const reduction = ((state.totalInputBytes - outputBytes) / state.totalInputBytes) * 100;\n console.log(\n `Bundled ${path.relative(process.cwd(), resolvedEntryPath)} to ${path.relative(process.cwd(), outputPath)}`,\n );\n console.log(\n `${state.includedModules.size} modules, ${formatBytes(state.totalInputBytes)} to ${formatBytes(outputBytes)}, ${reduction.toFixed(2)}% reduction`,\n );\n return outputPath;\n}\n\nexport { bundleLua };\n","import crypto from \"node:crypto\";\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport zlib from \"node:zlib\";\n\nimport { bundleLua } from \"./bundle.js\";\n\nconst DEFAULT_ICON = Buffer.from(\n \"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M/wHwAEAQH/69v17QAAAABJRU5ErkJggg==\",\n \"base64\",\n);\nconst RPACK_MAP_PATH = path.join(\n path.dirname(fileURLToPath(import.meta.url)),\n \"..\",\n \"vendor\",\n \"rpack\",\n \"rpack_map.bin\",\n);\n\nconst CRC32_TABLE = (() => {\n const table = new Uint32Array(256);\n for (let index = 0; index < table.length; index += 1) {\n let value = index;\n for (let bit = 0; bit < 8; bit += 1) {\n if ((value & 1) !== 0) {\n value = 0xedb88320 ^ (value >>> 1);\n } else {\n value >>>= 1;\n }\n }\n table[index] = value >>> 0;\n }\n return table;\n})();\n\nfunction assert(condition: unknown, message: string): asserts condition {\n if (!condition) {\n throw new Error(message);\n }\n}\n\nfunction calculateCRC32(data) {\n let value = 0xffffffff;\n for (const byte of data) {\n value = CRC32_TABLE[(value ^ byte) & 0xff] ^ (value >>> 8);\n }\n return (value ^ 0xffffffff) >>> 0;\n}\n\nfunction createUUID(seed) {\n const bytes = crypto.createHash(\"sha256\").update(seed).digest().subarray(0, 16);\n bytes[6] = (bytes[6] & 0x0f) | 0x50;\n bytes[8] = (bytes[8] & 0x3f) | 0x80;\n const hex = bytes.toString(\"hex\");\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n}\n\nfunction detectImageType(data) {\n if (data.subarray(0, 8).equals(Buffer.from(\"89504e470d0a1a0a\", \"hex\"))) {\n return \"PNG\";\n }\n if (data.subarray(0, 3).equals(Buffer.from(\"ffd8ff\", \"hex\"))) {\n return \"JPEG\";\n }\n if (\n data.subarray(0, 6).toString(\"ascii\") === \"GIF87a\" ||\n data.subarray(0, 6).toString(\"ascii\") === \"GIF89a\"\n ) {\n return \"GIF\";\n }\n if (\n data.subarray(0, 4).toString(\"ascii\") === \"RIFF\" &&\n data.subarray(8, 12).toString(\"ascii\") === \"WEBP\"\n ) {\n return \"WEBP\";\n }\n return \"Unknown\";\n}\n\nfunction getAssetCategory(extension) {\n const audio = new Set([\"flac\", \"mp3\", \"ogg\", \"wav\"]);\n const code = new Set([\"js\", \"lua\", \"ts\"]);\n const fonts = new Set([\"otf\", \"ttf\", \"woff\", \"woff2\"]);\n const images = new Set([\"avif\", \"gif\", \"jpeg\", \"jpg\", \"png\", \"webp\"]);\n const models = new Set([\"mmd\", \"obj\"]);\n const video = new Set([\"avi\", \"mkv\", \"mov\", \"mp4\", \"webm\"]);\n\n if (audio.has(extension)) {\n return \"audio\";\n }\n if (code.has(extension)) {\n return \"code\";\n }\n if (fonts.has(extension)) {\n return \"fonts\";\n }\n if (images.has(extension)) {\n return \"image\";\n }\n if (models.has(extension)) {\n return \"model\";\n }\n if (extension === \"onnx\" || extension === \"safetensors\" || extension === \"cpkt\") {\n return \"ai\";\n }\n if (video.has(extension)) {\n return \"video\";\n }\n return \"other\";\n}\n\nfunction readSource(manifestDirectory, source, label) {\n if (typeof source === \"string\") {\n return fs.readFileSync(path.resolve(manifestDirectory, source), \"utf8\");\n }\n assert(source && typeof source === \"object\", `${label} must be a file path or source object`);\n if (typeof source.content === \"string\") {\n return source.content;\n }\n assert(typeof source.file === \"string\", `${label}.file must be a string`);\n return fs.readFileSync(path.resolve(manifestDirectory, source.file), \"utf8\");\n}\n\nfunction sanitizeArchiveName(name: string): string {\n const sanitized = Array.from(name, (character) =>\n character.charCodeAt(0) < 32 ? \"_\" : character,\n )\n .join(\"\")\n .replace(/[<>:\"/\\\\|?*]/g, \"_\")\n .trim();\n return sanitized.slice(0, 100) || \"asset\";\n}\n\nfunction sortKeysDeep(value) {\n if (Array.isArray(value)) {\n return value.map(sortKeysDeep);\n }\n if (value && typeof value === \"object\" && !Buffer.isBuffer(value)) {\n const sorted = {};\n for (const key of Object.keys(value).sort()) {\n if (value[key] !== undefined) {\n sorted[key] = sortKeysDeep(value[key]);\n }\n }\n return sorted;\n }\n return value;\n}\n\nfunction parseFrontmatter(content, fileName) {\n const normalized = content.replace(/\\r\\n/g, \"\\n\");\n assert(normalized.startsWith(\"---\\n\"), `Missing frontmatter in ${fileName}`);\n const end = normalized.indexOf(\"\\n---\\n\", 4);\n assert(end !== -1, `Unclosed frontmatter in ${fileName}`);\n const metadata: Record<string, string | boolean> = {};\n for (const line of normalized.slice(4, end).split(\"\\n\")) {\n if (line.trim() === \"\") {\n continue;\n }\n const separator = line.indexOf(\":\");\n assert(separator !== -1, `Invalid frontmatter line in ${fileName}: ${line}`);\n const key = line.slice(0, separator).trim();\n const rawValue = line.slice(separator + 1).trim();\n assert(key !== \"\", `Empty frontmatter key in ${fileName}`);\n if (rawValue === \"true\") {\n metadata[key] = true;\n } else if (rawValue === \"false\") {\n metadata[key] = false;\n } else {\n metadata[key] = rawValue;\n }\n }\n return {\n body: normalized.slice(end + 5),\n metadata,\n };\n}\n\nfunction parseRegexBody(content, fileName) {\n const normalized = content.replace(/^\\n+/, \"\").replace(/\\n$/, \"\");\n const match = normalized.match(/^IN:\\s*\\n([\\s\\S]*?)\\nOUT:\\s*(?:\\n([\\s\\S]*))?$/);\n assert(match, `Invalid regex body in ${fileName}`);\n return {\n in: match[1],\n out: match[2] ?? \"\",\n };\n}\n\nfunction parseRegexDocument(content, fileName) {\n const { body, metadata } = parseFrontmatter(content, fileName);\n const parsed = parseRegexBody(body, fileName);\n return {\n ableFlag: metadata.ableFlag ?? true,\n comment: metadata.comment ?? \"\",\n flag: metadata.flag,\n in: parsed.in,\n out: parsed.out,\n type: metadata.type ?? \"editdisplay\",\n };\n}\n\nfunction buildRegexScripts(manifestDirectory, regexGroups: any[] = []) {\n const scripts: any[] = [];\n for (const group of regexGroups) {\n if (typeof group === \"string\") {\n scripts.push(\n parseRegexDocument(readSource(manifestDirectory, group, `regex ${group}`), group),\n );\n continue;\n }\n if (group.in !== undefined || group.out !== undefined) {\n assert(\n typeof group.in === \"string\" && typeof group.out === \"string\",\n \"Inline regex entries require in and out\",\n );\n scripts.push({\n ableFlag: group.ableFlag ?? true,\n comment: group.comment ?? \"\",\n flag: group.flag,\n in: group.in,\n out: group.out,\n type: group.type ?? \"editdisplay\",\n });\n continue;\n }\n\n assert(\n typeof group.file === \"string\",\n \"Regex entries require a file path, or inline in and out fields\",\n );\n scripts.push(\n parseRegexDocument(\n readSource(manifestDirectory, group.file, `regex ${group.file}`),\n group.file,\n ),\n );\n }\n return scripts;\n}\n\nfunction buildLorebook(manifest, manifestDirectory) {\n const folderKeys = new Map<string, string>();\n const folderNames = new Set<string>(manifest.folders ?? []);\n for (const entry of manifest.lorebook ?? []) {\n if (entry.folder) {\n folderNames.add(entry.folder);\n }\n }\n for (const name of folderNames) {\n folderKeys.set(\n name,\n `\\uf000folder:${createUUID(`${manifest.namespace ?? manifest.name}:folder:${name}`)}`,\n );\n }\n\n const temporaryDirectory = fs.mkdtempSync(path.join(os.tmpdir(), \"risums-charx-lorebook-\"));\n try {\n const lorebook = (manifest.lorebook ?? []).map((entry, index) => {\n let content;\n if (entry.bundle) {\n assert(\n typeof entry.file === \"string\",\n `Bundled lorebook ${entry.comment ?? index + 1} requires a file`,\n );\n const entryPath = path.resolve(manifestDirectory, entry.file);\n const outputPath = entry.bundleOutput\n ? path.resolve(manifestDirectory, entry.bundleOutput)\n : path.join(temporaryDirectory, `lorebook-${index}.lua`);\n content = readBundledLua(entryPath, outputPath);\n } else {\n content = readSource(\n manifestDirectory,\n entry,\n `lorebook ${entry.comment ?? entry.file ?? \"\"}`,\n );\n }\n return {\n activationPercent: entry.activationPercent,\n alwaysActive: entry.alwaysActive ?? false,\n bookVersion: entry.bookVersion ?? 2,\n comment: entry.comment ?? path.basename(entry.file ?? \"Lorebook\"),\n content,\n extentions: entry.extentions,\n folder: entry.folder ? folderKeys.get(entry.folder) : undefined,\n insertorder: entry.insertOrder ?? 100,\n key: entry.key ?? \"\",\n mode: entry.mode ?? \"normal\",\n secondkey: entry.secondaryKey ?? \"\",\n selective: entry.selective ?? false,\n useRegex: entry.useRegex ?? false,\n };\n });\n\n for (const name of folderNames) {\n lorebook.push({\n alwaysActive: false,\n bookVersion: 2,\n comment: name,\n content: \"\",\n insertorder: 100,\n key: folderKeys.get(name),\n mode: \"folder\",\n secondkey: \"\",\n selective: false,\n useRegex: false,\n });\n }\n return lorebook;\n } finally {\n fs.rmSync(temporaryDirectory, { force: true, recursive: true });\n }\n}\n\nfunction readBundledLua(entryPath: string, outputPath: string): string {\n bundleLua(entryPath, outputPath);\n return fs.readFileSync(outputPath, \"utf8\");\n}\n\nfunction buildTriggers(manifest, manifestDirectory) {\n const temporaryDirectory = fs.mkdtempSync(path.join(os.tmpdir(), \"risums-charx-\"));\n try {\n return (manifest.triggers ?? []).map((trigger, index) => {\n let effect = trigger.effect;\n if (trigger.lua) {\n const entryPath = path.resolve(manifestDirectory, trigger.lua);\n let code;\n if (trigger.bundle ?? true) {\n const outputPath = trigger.bundleOutput\n ? path.resolve(manifestDirectory, trigger.bundleOutput)\n : path.join(temporaryDirectory, `trigger-${index}.lua`);\n code = readBundledLua(entryPath, outputPath);\n } else {\n code = fs.readFileSync(entryPath, \"utf8\");\n }\n effect = [{ code, type: \"triggerlua\" }];\n }\n assert(Array.isArray(effect), `Trigger ${index + 1} requires lua or effect`);\n return {\n comment: trigger.comment ?? \"\",\n conditions: trigger.conditions ?? [],\n effect,\n lowLevelAccess: trigger.lowLevelAccess,\n type: trigger.type ?? \"start\",\n };\n });\n } finally {\n fs.rmSync(temporaryDirectory, { force: true, recursive: true });\n }\n}\n\nfunction createRisuM(module, encodeMap) {\n const payload = Buffer.from(\n JSON.stringify(sortKeysDeep({ module, type: \"risuModule\" }), null, 2),\n \"utf8\",\n );\n const encoded = Buffer.allocUnsafe(payload.length);\n for (let index = 0; index < payload.length; index += 1) {\n encoded[index] = encodeMap[payload[index]];\n }\n const header = Buffer.alloc(6);\n header.writeUInt8(111, 0);\n header.writeUInt8(0, 1);\n header.writeUInt32LE(encoded.length, 2);\n return Buffer.concat([header, encoded, Buffer.from([0])]);\n}\n\nfunction createAssetFiles(manifest, manifestDirectory) {\n const cardAssets: any[] = [];\n const files: Array<{ data: Buffer; name: string }> = [];\n const takenNames = new Set<string>();\n\n function addAsset({ data, extension, name, type }) {\n const category = getAssetCategory(extension);\n const baseDirectory = `assets/${type === \"icon\" ? \"icon\" : \"other\"}/${category}`;\n const baseName = sanitizeArchiveName(name);\n let archiveName = baseName;\n let suffix = 0;\n while (takenNames.has(archiveName)) {\n suffix += 1;\n archiveName = `${baseName}_${suffix}`;\n }\n const archivePath = `${baseDirectory}/${archiveName}.${extension}`;\n takenNames.add(archiveName);\n cardAssets.push({\n ext: extension,\n name,\n type,\n uri: `embeded://${archivePath}`,\n });\n files.push({ data, name: archivePath });\n files.push({\n data: Buffer.from(JSON.stringify({ type: detectImageType(data) }, null, 2)),\n name: `x_meta/${archiveName}.json`,\n });\n }\n\n if (manifest.icon) {\n const iconPath = path.resolve(manifestDirectory, manifest.icon);\n const extension = path.extname(iconPath).slice(1).toLowerCase() || \"png\";\n addAsset({ data: fs.readFileSync(iconPath), extension, name: \"main\", type: \"icon\" });\n } else {\n addAsset({ data: DEFAULT_ICON, extension: \"png\", name: \"main\", type: \"icon\" });\n }\n\n for (const asset of manifest.assets ?? []) {\n assert(typeof asset.file === \"string\", \"Asset file must be a string\");\n const assetPath = path.resolve(manifestDirectory, asset.file);\n const extension = (asset.extension ?? path.extname(assetPath).slice(1)).toLowerCase();\n assert(extension !== \"\", `Cannot determine extension for ${asset.file}`);\n assert(/^[a-z0-9]+$/.test(extension), `Invalid extension for ${asset.file}: ${extension}`);\n addAsset({\n data: fs.readFileSync(assetPath),\n extension,\n name: asset.name ?? path.basename(assetPath, path.extname(assetPath)),\n type: \"x-risu-asset\",\n });\n }\n return { cardAssets, files };\n}\n\nfunction createCard(manifest, lorebook, cardAssets, sourceCard?: Record<string, any>) {\n const sourceData = sourceCard?.data ?? {};\n const sourceExtensions = sourceData.extensions ?? {};\n const sourceRisuAI = sourceExtensions.risuai ?? {};\n const entries = lorebook.map((entry) => ({\n case_sensitive: entry.extentions?.risu_case_sensitive ?? false,\n comment: entry.comment,\n constant: entry.alwaysActive,\n content: entry.content,\n enabled: true,\n extensions: {\n ...entry.extentions,\n risu_activationPercent: entry.activationPercent,\n risu_loreCache: entry.loreCache,\n },\n folder: entry.folder,\n insertion_order: entry.insertorder,\n keys: entry.key.split(\",\").map((key) => key.trim()),\n mode: entry.mode,\n name: entry.comment,\n secondary_keys: entry.selective\n ? entry.secondkey.split(\",\").map((key) => key.trim())\n : undefined,\n selective: entry.selective,\n use_regex: entry.useRegex,\n }));\n return {\n ...sourceCard,\n data: {\n ...sourceData,\n alternate_greetings: sourceData.alternate_greetings ?? [],\n assets: cardAssets,\n character_book: {\n entries,\n extensions: { risu_fullWordMatching: false },\n },\n character_version: manifest.version ?? sourceData.character_version ?? \"\",\n creation_date: sourceData.creation_date ?? 0,\n creator: manifest.creator ?? sourceData.creator ?? \"\",\n creator_notes: manifest.description ?? sourceData.creator_notes ?? \"\",\n description: sourceData.description ?? \"\",\n extensions: {\n ...sourceExtensions,\n moduleNoneImage: manifest.icon ? undefined : true,\n risuai: {\n ...sourceRisuAI,\n additionalText: sourceRisuAI.additionalText ?? \"\",\n backgroundHTML: manifest.CSS\n ? readSource(path.dirname(manifest.__path), manifest.CSS, \"CSS\")\n : \"\",\n bias: sourceRisuAI.bias ?? [],\n defaultVariables: sourceRisuAI.defaultVariables ?? \"\",\n hideChatIcon: manifest.hideIcon ?? false,\n inlayViewScreen: sourceRisuAI.inlayViewScreen ?? false,\n largePortrait: sourceRisuAI.largePortrait ?? false,\n license: manifest.license ?? \"\",\n lorePlus: sourceRisuAI.lorePlus ?? false,\n lowLevelAccess: manifest.lowLevelAccess ?? false,\n moduleNamespace: manifest.namespace,\n newGenData: sourceRisuAI.newGenData,\n prebuiltAssetCommand: sourceRisuAI.prebuiltAssetCommand ?? \"\",\n prebuiltAssetExclude: sourceRisuAI.prebuiltAssetExclude ?? [],\n prebuiltAssetStyle: sourceRisuAI.prebuiltAssetStyle ?? \"\",\n sdData: sourceRisuAI.sdData ?? [],\n toggles: manifest.toggles\n ? readSource(path.dirname(manifest.__path), manifest.toggles, \"toggles\")\n : \"\",\n utilityBot: sourceRisuAI.utilityBot ?? false,\n viewScreen: \"none\",\n virtualscript: sourceRisuAI.virtualscript ?? \"\",\n vits: sourceRisuAI.vits ?? {},\n },\n },\n first_mes: sourceData.first_mes ?? \"\",\n group_only_greetings: sourceData.group_only_greetings ?? [],\n mes_example: sourceData.mes_example ?? \"\",\n modification_date: process.env.SOURCE_DATE_EPOCH\n ? Number(process.env.SOURCE_DATE_EPOCH)\n : Math.floor(Date.now() / 1000),\n name: manifest.name,\n nickname: sourceData.nickname ?? \"\",\n personality: sourceData.personality ?? \"\",\n post_history_instructions: sourceData.post_history_instructions ?? \"\",\n scenario: sourceData.scenario ?? \"\",\n source: sourceData.source ?? [],\n system_prompt: sourceData.system_prompt ?? \"\",\n tags: manifest.tags ?? sourceData.tags ?? [],\n },\n spec: sourceCard?.spec ?? \"chara_card_v3\",\n spec_version: sourceCard?.spec_version ?? \"3.0\",\n };\n}\n\nfunction getDOSDateTime(date) {\n const year = Math.max(1980, date.getUTCFullYear());\n return {\n date: ((year - 1980) << 9) | ((date.getUTCMonth() + 1) << 5) | date.getUTCDate(),\n time:\n (date.getUTCHours() << 11) |\n (date.getUTCMinutes() << 5) |\n Math.floor(date.getUTCSeconds() / 2),\n };\n}\n\nfunction createZIP(files, timestamp) {\n assert(files.length <= 0xffff, \"ZIP contains too many files\");\n const centralRecords: Buffer[] = [];\n const localRecords: Buffer[] = [];\n let offset = 0;\n const { date, time } = getDOSDateTime(timestamp);\n\n for (const file of files) {\n const data = Buffer.from(file.data);\n const compressed = zlib.deflateRawSync(data, { level: 6 });\n const fileName = Buffer.from(file.name.replace(/\\\\/g, \"/\"), \"utf8\");\n const CRC32 = calculateCRC32(data);\n assert(\n data.length <= 0xffffffff && compressed.length <= 0xffffffff,\n `${file.name} exceeds ZIP32 limits`,\n );\n\n const localHeader = Buffer.alloc(30);\n localHeader.writeUInt32LE(0x04034b50, 0);\n localHeader.writeUInt16LE(20, 4);\n localHeader.writeUInt16LE(0x0800, 6);\n localHeader.writeUInt16LE(8, 8);\n localHeader.writeUInt16LE(time, 10);\n localHeader.writeUInt16LE(date, 12);\n localHeader.writeUInt32LE(CRC32, 14);\n localHeader.writeUInt32LE(compressed.length, 18);\n localHeader.writeUInt32LE(data.length, 22);\n localHeader.writeUInt16LE(fileName.length, 26);\n localHeader.writeUInt16LE(0, 28);\n localRecords.push(localHeader, fileName, compressed);\n\n const centralHeader = Buffer.alloc(46);\n centralHeader.writeUInt32LE(0x02014b50, 0);\n centralHeader.writeUInt16LE(20, 4);\n centralHeader.writeUInt16LE(20, 6);\n centralHeader.writeUInt16LE(0x0800, 8);\n centralHeader.writeUInt16LE(8, 10);\n centralHeader.writeUInt16LE(time, 12);\n centralHeader.writeUInt16LE(date, 14);\n centralHeader.writeUInt32LE(CRC32, 16);\n centralHeader.writeUInt32LE(compressed.length, 20);\n centralHeader.writeUInt32LE(data.length, 24);\n centralHeader.writeUInt16LE(fileName.length, 28);\n centralHeader.writeUInt16LE(0, 30);\n centralHeader.writeUInt16LE(0, 32);\n centralHeader.writeUInt16LE(0, 34);\n centralHeader.writeUInt16LE(0, 36);\n centralHeader.writeUInt32LE(0, 38);\n centralHeader.writeUInt32LE(offset, 42);\n centralRecords.push(centralHeader, fileName);\n offset += localHeader.length + fileName.length + compressed.length;\n }\n\n const centralDirectory = Buffer.concat(centralRecords);\n const end = Buffer.alloc(22);\n end.writeUInt32LE(0x06054b50, 0);\n end.writeUInt16LE(0, 4);\n end.writeUInt16LE(0, 6);\n end.writeUInt16LE(files.length, 8);\n end.writeUInt16LE(files.length, 10);\n end.writeUInt32LE(centralDirectory.length, 12);\n end.writeUInt32LE(offset, 16);\n end.writeUInt16LE(0, 20);\n return Buffer.concat([...localRecords, centralDirectory, end]);\n}\n\nfunction buildCharX(manifestPath: string, outputArgument?: string): string {\n const resolvedManifestPath = path.resolve(manifestPath);\n const manifestDirectory = path.dirname(resolvedManifestPath);\n const manifest = JSON.parse(fs.readFileSync(resolvedManifestPath, \"utf8\"));\n manifest.__path = resolvedManifestPath;\n assert(typeof manifest.name === \"string\" && manifest.name !== \"\", \"Manifest name is required\");\n\n const lorebook = buildLorebook(manifest, manifestDirectory);\n const regex = buildRegexScripts(manifestDirectory, manifest.regex);\n const trigger = buildTriggers(manifest, manifestDirectory);\n const { cardAssets, files: assetFiles } = createAssetFiles(manifest, manifestDirectory);\n const sourceCard = manifest.card\n ? JSON.parse(readSource(manifestDirectory, manifest.card, \"card\"))\n : undefined;\n const card = createCard(manifest, lorebook, cardAssets, sourceCard);\n const module = {\n description: `Module for ${manifest.name}`,\n id: createUUID(`${manifest.namespace ?? manifest.name}:module`),\n lorebook,\n name: `${manifest.name} Module`,\n regex,\n trigger,\n };\n\n const map = fs.readFileSync(RPACK_MAP_PATH);\n assert(map.length >= 256, `Invalid RPack map: ${RPACK_MAP_PATH}`);\n const files = [\n ...assetFiles,\n { data: Buffer.from(JSON.stringify(sortKeysDeep(card), null, 2)), name: \"card.json\" },\n { data: createRisuM(sortKeysDeep(module), map.subarray(0, 256)), name: \"module.risum\" },\n ].sort((left, right) => left.name.localeCompare(right.name));\n\n const outputPath = outputArgument\n ? path.resolve(outputArgument)\n : path.resolve(\n manifestDirectory,\n manifest.output ?? `../dist/${sanitizeArchiveName(manifest.name)}.charx`,\n );\n fs.mkdirSync(path.dirname(outputPath), { recursive: true });\n const timestamp = process.env.SOURCE_DATE_EPOCH\n ? new Date(Number(process.env.SOURCE_DATE_EPOCH) * 1000)\n : new Date();\n fs.writeFileSync(outputPath, createZIP(files, timestamp));\n console.log(`Built ${path.relative(process.cwd(), outputPath)} (${files.length} files)`);\n return outputPath;\n}\n\nexport { buildCharX };\n","import zlib from \"node:zlib\";\n\nconst MAGIC = Buffer.from(\"RISUSAVE\\0\");\nconst MODULE_BLOCK_TYPE = 5;\n\ninterface ModuleRecord {\n id?: unknown;\n name?: unknown;\n namespace?: unknown;\n [key: string]: unknown;\n}\n\nfunction parseModuleBlock(database: Buffer): ModuleRecord[] {\n if (!database.subarray(0, MAGIC.length).equals(MAGIC)) {\n throw new Error(\"Invalid RISUSAVE header\");\n }\n\n let offset = MAGIC.length;\n while (offset < database.length) {\n if (offset + 3 > database.length) {\n throw new Error(`Truncated block header at byte ${offset}`);\n }\n const type = database[offset];\n const compressed = database[offset + 1] === 1;\n const nameLength = database[offset + 2];\n offset += 3;\n\n if (offset + nameLength + 4 > database.length) {\n throw new Error(`Truncated block name at byte ${offset}`);\n }\n const name = database.subarray(offset, offset + nameLength).toString(\"utf8\");\n offset += nameLength;\n const contentLength = database.readUInt32LE(offset);\n offset += 4;\n\n if (offset + contentLength > database.length) {\n throw new Error(`Truncated ${name} block at byte ${offset}`);\n }\n let content = database.subarray(offset, offset + contentLength);\n offset += contentLength;\n\n if (type !== MODULE_BLOCK_TYPE) {\n continue;\n }\n if (compressed) {\n content = zlib.gunzipSync(content);\n }\n return JSON.parse(content.toString(\"utf8\")) as ModuleRecord[];\n }\n throw new Error(\"RISUSAVE module block not found\");\n}\n\nexport { parseModuleBlock };\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport zlib from \"node:zlib\";\n\nconst RPACK_MAP_PATH = path.join(\n path.dirname(fileURLToPath(import.meta.url)),\n \"..\",\n \"vendor\",\n \"rpack\",\n \"rpack_map.bin\",\n);\n\nconst CRC32_TABLE = (() => {\n const table = new Uint32Array(256);\n for (let index = 0; index < table.length; index += 1) {\n let value = index;\n for (let bit = 0; bit < 8; bit += 1) {\n if ((value & 1) !== 0) {\n value = 0xedb88320 ^ (value >>> 1);\n } else {\n value >>>= 1;\n }\n }\n table[index] = value >>> 0;\n }\n return table;\n})();\n\nfunction assert(condition: unknown, message: string): asserts condition {\n if (!condition) {\n throw new Error(message);\n }\n}\n\nfunction calculateCRC32(data) {\n let value = 0xffffffff;\n for (const byte of data) {\n value = CRC32_TABLE[(value ^ byte) & 0xff] ^ (value >>> 8);\n }\n return (value ^ 0xffffffff) >>> 0;\n}\n\nfunction decodeModule(data: Buffer, map: Buffer): Record<string, any> {\n assert(data.length >= 7, \"module.risum is truncated\");\n assert(data.readUInt8(0) === 111, \"Invalid module.risum magic number\");\n assert(data.readUInt8(1) === 0, `Unsupported module.risum version: ${data.readUInt8(1)}`);\n\n const encodedLength = data.readUInt32LE(2);\n assert(encodedLength <= data.length - 6, \"module.risum payload is truncated\");\n assert(map.length >= 256, `Invalid RPack map: ${RPACK_MAP_PATH}`);\n\n let decodeMap;\n if (map.length >= 512) {\n decodeMap = map.subarray(256, 512);\n } else {\n decodeMap = Buffer.alloc(256);\n const seen = new Set();\n for (let index = 0; index < 256; index += 1) {\n const encoded = map[index];\n assert(!seen.has(encoded), \"RPack encode map is not a permutation\");\n seen.add(encoded);\n decodeMap[encoded] = index;\n }\n }\n\n const encoded = data.subarray(6, 6 + encodedLength);\n const decoded = Buffer.allocUnsafe(encoded.length);\n for (let index = 0; index < encoded.length; index += 1) {\n decoded[index] = decodeMap[encoded[index]];\n }\n\n const parsed = JSON.parse(decoded.toString(\"utf8\"));\n assert(\n parsed && parsed.type === \"risuModule\" && parsed.module,\n \"module.risum does not contain a Risu module\",\n );\n return parsed;\n}\n\nfunction findEndOfCentralDirectory(archive) {\n const minimumOffset = Math.max(0, archive.length - 0xffff - 22);\n for (let offset = archive.length - 22; offset >= minimumOffset; offset -= 1) {\n if (archive.readUInt32LE(offset) === 0x06054b50) {\n const commentLength = archive.readUInt16LE(offset + 20);\n if (offset + 22 + commentLength === archive.length) {\n return offset;\n }\n }\n }\n throw new Error(\"ZIP end record not found\");\n}\n\nfunction normalizeEntryName(name) {\n assert(name !== \"\", \"ZIP entry has an empty name\");\n assert(!name.includes(\"\\0\"), `ZIP entry contains a null byte: ${JSON.stringify(name)}`);\n\n const normalized = name.replace(/\\\\/g, \"/\");\n assert(!normalized.startsWith(\"/\"), `ZIP entry uses an absolute path: ${name}`);\n assert(!/^[a-zA-Z]:/.test(normalized), `ZIP entry uses an absolute path: ${name}`);\n\n const parts = normalized.split(\"/\");\n assert(!parts.includes(\"..\"), `ZIP entry escapes the output directory: ${name}`);\n return parts.filter((part) => part !== \"\" && part !== \".\").join(\"/\");\n}\n\nfunction sanitizeSourceName(name: string, fallback: string): string {\n const sanitized = Array.from(name, (character) =>\n character.charCodeAt(0) < 32 ? \"_\" : character,\n )\n .join(\"\")\n .replace(/[<>:\"/\\\\|?*]/g, \"_\")\n .replace(/[. ]+$/g, \"\")\n .trim();\n return sanitized || fallback;\n}\n\nfunction sortKeysDeep(value) {\n if (Array.isArray(value)) {\n return value.map(sortKeysDeep);\n }\n if (value && typeof value === \"object\" && !Buffer.isBuffer(value)) {\n const sorted = {};\n for (const key of Object.keys(value).sort()) {\n if (value[key] !== undefined) {\n sorted[key] = sortKeysDeep(value[key]);\n }\n }\n return sorted;\n }\n return value;\n}\n\nfunction takeSourcePath(directory, label, extension, takenPaths) {\n const baseName = sanitizeSourceName(label, \"untitled\");\n const suffix = baseName.toLowerCase().endsWith(extension) ? \"\" : extension;\n let candidate = `${directory}/${baseName}${suffix}`;\n let collision = 1;\n while (takenPaths.has(candidate)) {\n collision += 1;\n candidate = `${directory}/${baseName}_${collision}${suffix}`;\n }\n takenPaths.add(candidate);\n return candidate;\n}\n\nfunction createRegexDocument(regex) {\n const frontmatter = [`ableFlag: ${regex.ableFlag ?? true}`, `comment: ${regex.comment ?? \"\"}`];\n if (regex.flag !== undefined) {\n frontmatter.push(`flag: ${regex.flag}`);\n }\n frontmatter.push(`type: ${regex.type ?? \"editdisplay\"}`);\n return `---\\n${frontmatter.join(\"\\n\")}\\n---\\n\\nIN:\\n${regex.in ?? \"\"}\\nOUT:\\n${regex.out ?? \"\"}\\n`;\n}\n\nfunction createExpandedModuleSources(\n card: Record<string, any>,\n decodedModule: Record<string, any>,\n): Map<string, Buffer> {\n const moduleData = decodedModule.module;\n const files = new Map<string, Buffer>();\n const folderNames = new Map<any, any>();\n const folders: any[] = [];\n const takenPaths = new Set<string>();\n\n for (const entry of moduleData.lorebook ?? []) {\n if (entry.mode !== \"folder\") {\n continue;\n }\n folderNames.set(entry.key, entry.comment);\n folders.push(entry.comment);\n }\n\n const lorebook: any[] = [];\n for (const entry of moduleData.lorebook ?? []) {\n if (entry.mode === \"folder\") {\n continue;\n }\n const file = takeSourcePath(\"lorebooks\", entry.comment, \".md\", takenPaths);\n files.set(file, Buffer.from(entry.content ?? \"\", \"utf8\"));\n lorebook.push({\n activationPercent: entry.activationPercent,\n alwaysActive: entry.alwaysActive ?? false,\n bookVersion: entry.bookVersion ?? 2,\n comment: entry.comment ?? \"\",\n extentions: entry.extentions,\n file,\n folder: folderNames.get(entry.folder),\n insertOrder: entry.insertorder ?? 100,\n key: entry.key ?? \"\",\n mode: entry.mode ?? \"normal\",\n secondaryKey: entry.secondkey ?? \"\",\n selective: entry.selective ?? false,\n useRegex: entry.useRegex ?? false,\n });\n }\n\n const regex: string[] = [];\n for (const entry of moduleData.regex ?? []) {\n const file = takeSourcePath(\"regex\", entry.comment, \".md\", takenPaths);\n files.set(file, Buffer.from(createRegexDocument(entry), \"utf8\"));\n regex.push(file);\n }\n\n const triggers: any[] = [];\n for (let index = 0; index < (moduleData.trigger ?? []).length; index += 1) {\n const trigger = moduleData.trigger[index];\n const luaEffect =\n trigger.effect?.length === 1 && trigger.effect[0].type === \"triggerlua\"\n ? trigger.effect[0]\n : undefined;\n if (!luaEffect || typeof luaEffect.code !== \"string\") {\n triggers.push(trigger);\n continue;\n }\n\n const label = trigger.comment || `trigger-${index + 1}`;\n const luaPath = takeSourcePath(\"triggers\", label, \".lua\", takenPaths);\n files.set(luaPath, Buffer.from(luaEffect.code, \"utf8\"));\n triggers.push({\n bundle: false,\n comment: trigger.comment ?? \"\",\n conditions: trigger.conditions ?? [],\n lowLevelAccess: trigger.lowLevelAccess,\n lua: luaPath,\n type: trigger.type ?? \"start\",\n });\n }\n\n const risuai = card.data?.extensions?.risuai ?? {};\n const manifest: Record<string, any> = {\n card: \"card.json\",\n creator: card.data?.creator,\n description: card.data?.creator_notes ?? moduleData.description ?? \"\",\n folders,\n hideIcon: risuai.hideChatIcon ?? moduleData.hideIcon ?? false,\n lorebook,\n lowLevelAccess: risuai.lowLevelAccess ?? moduleData.lowLevelAccess ?? false,\n name: card.data?.name ?? moduleData.name,\n namespace: risuai.moduleNamespace ?? moduleData.namespace,\n regex,\n tags: card.data?.tags,\n triggers,\n version: card.data?.character_version ?? \"\",\n };\n\n const CSS = risuai.backgroundHTML ?? moduleData.backgroundEmbedding;\n if (CSS) {\n manifest.CSS = \"style.html\";\n files.set(\"style.html\", Buffer.from(CSS, \"utf8\"));\n }\n const toggles = risuai.toggles ?? moduleData.customModuleToggle;\n if (toggles) {\n manifest.toggles = \"toggles.txt\";\n files.set(\"toggles.txt\", Buffer.from(toggles, \"utf8\"));\n }\n\n const mainIcon = card.data?.assets?.find(\n (asset) => asset.type === \"icon\" && asset.name === \"main\",\n );\n if (mainIcon?.uri?.startsWith(\"embeded://\")) {\n manifest.icon = mainIcon.uri.slice(\"embeded://\".length);\n }\n\n const assets: any[] = [];\n for (const asset of card.data?.assets ?? []) {\n if (asset === mainIcon || !asset.uri?.startsWith(\"embeded://\")) {\n continue;\n }\n assets.push({\n extension: asset.ext,\n file: asset.uri.slice(\"embeded://\".length),\n name: asset.name,\n });\n }\n if (assets.length > 0) {\n manifest.assets = assets;\n }\n\n files.set(\n \"charx.json\",\n Buffer.from(`${JSON.stringify(sortKeysDeep(manifest), null, 2)}\\n`, \"utf8\"),\n );\n return files;\n}\n\nfunction parseZIP(archive: Buffer) {\n const endOffset = findEndOfCentralDirectory(archive);\n const diskNumber = archive.readUInt16LE(endOffset + 4);\n const centralDisk = archive.readUInt16LE(endOffset + 6);\n const diskEntries = archive.readUInt16LE(endOffset + 8);\n const totalEntries = archive.readUInt16LE(endOffset + 10);\n const centralSize = archive.readUInt32LE(endOffset + 12);\n const centralOffset = archive.readUInt32LE(endOffset + 16);\n\n assert(diskNumber === 0 && centralDisk === 0, \"Multi-disk ZIP archives are not supported\");\n assert(diskEntries === totalEntries, \"Inconsistent ZIP entry count\");\n assert(\n totalEntries !== 0xffff && centralSize !== 0xffffffff && centralOffset !== 0xffffffff,\n \"ZIP64 is not supported\",\n );\n\n const zipOffset = endOffset - centralSize - centralOffset;\n assert(zipOffset >= 0, \"Invalid ZIP central directory offset\");\n\n const entries: any[] = [];\n const names = new Set();\n let offset = zipOffset + centralOffset;\n for (let index = 0; index < totalEntries; index += 1) {\n assert(offset + 46 <= archive.length, \"ZIP central directory is truncated\");\n assert(\n archive.readUInt32LE(offset) === 0x02014b50,\n `Invalid ZIP central record at byte ${offset}`,\n );\n\n const flags = archive.readUInt16LE(offset + 8);\n const method = archive.readUInt16LE(offset + 10);\n const expectedCRC32 = archive.readUInt32LE(offset + 16);\n const compressedSize = archive.readUInt32LE(offset + 20);\n const uncompressedSize = archive.readUInt32LE(offset + 24);\n const nameLength = archive.readUInt16LE(offset + 28);\n const extraLength = archive.readUInt16LE(offset + 30);\n const commentLength = archive.readUInt16LE(offset + 32);\n const diskStart = archive.readUInt16LE(offset + 34);\n const localOffset = archive.readUInt32LE(offset + 42);\n const recordLength = 46 + nameLength + extraLength + commentLength;\n\n assert(offset + recordLength <= archive.length, \"ZIP central record is truncated\");\n assert((flags & 1) === 0, \"Encrypted ZIP entries are not supported\");\n assert(method === 0 || method === 8, `Unsupported ZIP compression method: ${method}`);\n assert(diskStart === 0, \"Multi-disk ZIP entries are not supported\");\n assert(\n compressedSize !== 0xffffffff &&\n uncompressedSize !== 0xffffffff &&\n localOffset !== 0xffffffff,\n \"ZIP64 entries are not supported\",\n );\n\n const rawName = archive.subarray(offset + 46, offset + 46 + nameLength);\n const decodedName = rawName.toString(\"utf8\");\n const directory = decodedName.endsWith(\"/\") || decodedName.endsWith(\"\\\\\");\n const name = normalizeEntryName(decodedName);\n assert(name !== \"\", \"ZIP entry resolves to an empty path\");\n assert(!names.has(name), `Duplicate ZIP entry: ${name}`);\n names.add(name);\n\n entries.push({\n compressedSize,\n directory,\n expectedCRC32,\n localOffset: zipOffset + localOffset,\n method,\n name,\n uncompressedSize,\n });\n offset += recordLength;\n }\n\n assert(offset === endOffset, \"ZIP central directory size does not match its records\");\n return entries;\n}\n\nfunction readEntry(archive, entry) {\n const offset = entry.localOffset;\n assert(offset + 30 <= archive.length, `ZIP local record is truncated: ${entry.name}`);\n assert(archive.readUInt32LE(offset) === 0x04034b50, `Invalid ZIP local record: ${entry.name}`);\n\n const nameLength = archive.readUInt16LE(offset + 26);\n const extraLength = archive.readUInt16LE(offset + 28);\n const dataOffset = offset + 30 + nameLength + extraLength;\n const dataEnd = dataOffset + entry.compressedSize;\n assert(dataEnd <= archive.length, `ZIP entry data is truncated: ${entry.name}`);\n\n const compressed = archive.subarray(dataOffset, dataEnd);\n const data = entry.method === 0 ? Buffer.from(compressed) : zlib.inflateRawSync(compressed);\n assert(data.length === entry.uncompressedSize, `ZIP entry size mismatch: ${entry.name}`);\n assert(\n calculateCRC32(data) === entry.expectedCRC32,\n `ZIP entry checksum mismatch: ${entry.name}`,\n );\n assert(!entry.directory || data.length === 0, `ZIP directory entry contains data: ${entry.name}`);\n return data;\n}\n\nfunction assertEmptyOutputDirectory(outputDirectory) {\n if (!fs.existsSync(outputDirectory)) {\n return;\n }\n assert(\n fs.statSync(outputDirectory).isDirectory(),\n `Output path is not a directory: ${outputDirectory}`,\n );\n assert(\n fs.readdirSync(outputDirectory).length === 0,\n `Output directory is not empty: ${outputDirectory}`,\n );\n}\n\nfunction unpackCharX(inputPath: string, outputPath: string): string {\n const resolvedInputPath = path.resolve(inputPath);\n const resolvedOutputPath = path.resolve(outputPath);\n const archive = fs.readFileSync(resolvedInputPath);\n const entries = parseZIP(archive);\n const extracted = new Map<string, { data: Buffer; directory: boolean }>();\n\n for (const entry of entries) {\n extracted.set(entry.name, {\n data: readEntry(archive, entry),\n directory: entry.directory,\n });\n }\n\n const cardEntry = extracted.get(\"card.json\");\n assert(cardEntry, \"CharX archive does not contain card.json\");\n assert(!cardEntry.directory, \"card.json is a directory\");\n const card = JSON.parse(cardEntry.data.toString(\"utf8\"));\n\n let decodedModule;\n if (extracted.has(\"module.risum\")) {\n const moduleEntry = extracted.get(\"module.risum\");\n assert(moduleEntry, \"CharX archive does not contain module.risum\");\n assert(!moduleEntry.directory, \"module.risum is a directory\");\n const map = fs.readFileSync(RPACK_MAP_PATH);\n decodedModule = decodeModule(moduleEntry.data, map);\n }\n\n const expandedSources = decodedModule\n ? createExpandedModuleSources(card, decodedModule)\n : new Map();\n for (const name of expandedSources.keys()) {\n assert(\n !extracted.has(name),\n `Generated module source conflicts with an archive entry: ${name}`,\n );\n }\n\n assertEmptyOutputDirectory(resolvedOutputPath);\n fs.mkdirSync(resolvedOutputPath, { recursive: true });\n\n for (const [name, entry] of extracted) {\n if (name === \"module.risum\") {\n continue;\n }\n const destination = path.join(resolvedOutputPath, ...name.split(\"/\"));\n if (entry.directory) {\n fs.mkdirSync(destination, { recursive: true });\n continue;\n }\n fs.mkdirSync(path.dirname(destination), { recursive: true });\n fs.writeFileSync(destination, entry.data);\n }\n\n for (const [name, data] of expandedSources) {\n const destination = path.join(resolvedOutputPath, ...name.split(\"/\"));\n fs.mkdirSync(path.dirname(destination), { recursive: true });\n fs.writeFileSync(destination, data);\n }\n\n const relativeOutput = path.relative(process.cwd(), resolvedOutputPath) || \".\";\n console.log(\n `Unpacked ${entries.length - (decodedModule ? 1 : 0)} archive files to ${relativeOutput}`,\n );\n return resolvedOutputPath;\n}\n\nexport { createExpandedModuleSources, decodeModule, parseZIP, unpackCharX };\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\n\nimport { createExpandedModuleSources } from \"./unpack-charx.js\";\n\nconst RPACK_MAP_PATH = path.join(\n path.dirname(fileURLToPath(import.meta.url)),\n \"..\",\n \"vendor\",\n \"rpack\",\n \"rpack_map.bin\",\n);\n\nfunction assert(condition: unknown, message: string): asserts condition {\n if (!condition) {\n throw new Error(message);\n }\n}\n\nfunction assertEmptyOutputDirectory(outputDirectory) {\n if (!fs.existsSync(outputDirectory)) {\n return;\n }\n assert(\n fs.statSync(outputDirectory).isDirectory(),\n `Output path is not a directory: ${outputDirectory}`,\n );\n assert(\n fs.readdirSync(outputDirectory).length === 0,\n `Output directory is not empty: ${outputDirectory}`,\n );\n}\n\nfunction decodeRPack(data, decodeMap) {\n for (let index = 0; index < data.length; index += 1) {\n data[index] = decodeMap[data[index]];\n }\n return data;\n}\n\nfunction readExactly(fileDescriptor, length, position, label) {\n const data = Buffer.allocUnsafe(length);\n let read = 0;\n while (read < length) {\n const count = fs.readSync(fileDescriptor, data, read, length - read, position + read);\n assert(count > 0, `${label} is truncated at byte ${position + read}`);\n read += count;\n }\n return data;\n}\n\nfunction sanitizeAssetName(name: string, fallback: string): string {\n const sanitized = Array.from(name, (character) =>\n character.charCodeAt(0) < 32 ? \"_\" : character,\n )\n .join(\"\")\n .replace(/[<>:\"/\\\\|?*]/g, \"_\")\n .replace(/[. ]+$/g, \"\")\n .trim();\n return sanitized.slice(0, 180) || fallback;\n}\n\nfunction detectAssetExtension(data, fallback) {\n if (data.subarray(0, 8).equals(Buffer.from(\"89504e470d0a1a0a\", \"hex\"))) {\n return \"png\";\n }\n if (data.subarray(0, 3).equals(Buffer.from(\"ffd8ff\", \"hex\"))) {\n return \"jpg\";\n }\n if (\n data.subarray(0, 6).toString(\"ascii\") === \"GIF87a\" ||\n data.subarray(0, 6).toString(\"ascii\") === \"GIF89a\"\n ) {\n return \"gif\";\n }\n if (\n data.subarray(0, 4).toString(\"ascii\") === \"RIFF\" &&\n data.subarray(8, 12).toString(\"ascii\") === \"WEBP\"\n ) {\n return \"webp\";\n }\n if (data.subarray(4, 12).toString(\"ascii\").includes(\"ftypavif\")) {\n return \"avif\";\n }\n return /^[a-z0-9]+$/i.test(fallback ?? \"\") ? fallback.toLowerCase() : \"bin\";\n}\n\nfunction takeAssetPath(asset, data, index, takenPaths) {\n const extension = detectAssetExtension(data, asset[2]);\n const baseName = sanitizeAssetName(asset[0] ?? \"\", `asset_${index + 1}`);\n let candidate = `assets/${baseName}.${extension}`;\n let collision = 1;\n while (takenPaths.has(candidate)) {\n collision += 1;\n candidate = `assets/${baseName}_${collision}.${extension}`;\n }\n takenPaths.add(candidate);\n return candidate;\n}\n\nfunction writeSources(outputDirectory, decodedModule, assetSources) {\n const card = {\n data: {\n name: decodedModule.module.name,\n },\n };\n const sources = createExpandedModuleSources(card, decodedModule);\n const manifestSource = sources.get(\"charx.json\");\n assert(manifestSource, \"Expanded module sources do not contain charx.json\");\n const manifest = JSON.parse(manifestSource.toString(\"utf8\"));\n manifest.assets = assetSources;\n sources.set(\"charx.json\", Buffer.from(`${JSON.stringify(manifest, null, 2)}\\n`, \"utf8\"));\n\n for (const [name, data] of sources) {\n const destination = path.join(outputDirectory, ...name.split(\"/\"));\n fs.mkdirSync(path.dirname(destination), { recursive: true });\n fs.writeFileSync(destination, data);\n }\n}\n\nfunction unpackRisuM(inputPath: string, outputPath: string): string {\n const resolvedInputPath = path.resolve(inputPath);\n const resolvedOutputPath = path.resolve(outputPath);\n assertEmptyOutputDirectory(resolvedOutputPath);\n\n const map = fs.readFileSync(RPACK_MAP_PATH);\n assert(map.length >= 512, `Invalid RPack map: ${RPACK_MAP_PATH}`);\n const decodeMap = map.subarray(256, 512);\n const fileDescriptor = fs.openSync(resolvedInputPath, \"r\");\n\n try {\n const fileSize = fs.fstatSync(fileDescriptor).size;\n const header = readExactly(fileDescriptor, 6, 0, \"RISUM header\");\n assert(header.readUInt8(0) === 111, \"Invalid RISUM magic number\");\n assert(header.readUInt8(1) === 0, `Unsupported RISUM version: ${header.readUInt8(1)}`);\n\n const payloadLength = header.readUInt32LE(2);\n const payload = readExactly(fileDescriptor, payloadLength, 6, \"RISUM module payload\");\n const decodedModule = JSON.parse(decodeRPack(payload, decodeMap).toString(\"utf8\"));\n assert(\n decodedModule?.type === \"risuModule\" && decodedModule.module,\n \"RISUM does not contain a Risu module\",\n );\n\n const assetMetadata = decodedModule.module.assets ?? [];\n const assetSources: any[] = [];\n const takenPaths = new Set<string>();\n let assetIndex = 0;\n let position = 6 + payloadLength;\n\n fs.mkdirSync(path.join(resolvedOutputPath, \"assets\"), { recursive: true });\n while (position < fileSize) {\n const marker = readExactly(fileDescriptor, 1, position, \"RISUM asset marker\").readUInt8(0);\n position += 1;\n if (marker === 0) {\n break;\n }\n assert(marker === 1, `Invalid RISUM asset marker at byte ${position - 1}: ${marker}`);\n assert(\n assetIndex < assetMetadata.length,\n \"RISUM contains more asset blocks than asset metadata entries\",\n );\n\n const lengthData = readExactly(fileDescriptor, 4, position, \"RISUM asset length\");\n const assetLength = lengthData.readUInt32LE(0);\n position += 4;\n const encodedAsset = readExactly(\n fileDescriptor,\n assetLength,\n position,\n `RISUM asset ${assetIndex + 1}`,\n );\n position += assetLength;\n\n const metadata = assetMetadata[assetIndex];\n assert(metadata, `RISUM asset ${assetIndex + 1} has no metadata`);\n const decodedAsset = decodeRPack(encodedAsset, decodeMap);\n const sourcePath = takeAssetPath(metadata, decodedAsset, assetIndex, takenPaths);\n const destination = path.join(resolvedOutputPath, ...sourcePath.split(\"/\"));\n fs.writeFileSync(destination, decodedAsset);\n assetSources.push({\n extension: path.extname(sourcePath).slice(1),\n file: sourcePath,\n name: metadata[0],\n });\n assetIndex += 1;\n\n if (assetIndex % 500 === 0) {\n console.log(`Extracted ${assetIndex} / ${assetMetadata.length} assets`);\n }\n }\n\n assert(\n assetIndex === assetMetadata.length,\n `RISUM contains ${assetIndex} asset blocks but declares ${assetMetadata.length}`,\n );\n assert(\n position === fileSize,\n `RISUM contains ${fileSize - position} trailing bytes after the end marker`,\n );\n writeSources(resolvedOutputPath, decodedModule, assetSources);\n\n const relativeOutput = path.relative(process.cwd(), resolvedOutputPath) || \".\";\n console.log(`Unpacked ${assetIndex} assets and module sources to ${relativeOutput}`);\n return resolvedOutputPath;\n } finally {\n fs.closeSync(fileDescriptor);\n }\n}\n\nexport { unpackRisuM };\n"],"mappings":"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"}