@clearmist-labs/comic-archive-handler 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +137 -0
- package/dist/index.d.mts +584 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +2157 -0
- package/dist/index.mjs.map +1 -0
- package/dist/rolldown-runtime-D7D4PA-g.mjs +13 -0
- package/docs/API.md +809 -0
- package/package.json +82 -0
- package/schemas/ComicInfo v2.1.xsd +127 -0
- package/schemas/LICENSE-MetronInfo.txt +504 -0
- package/schemas/MetronInfo v1.1.xsd +355 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,584 @@
|
|
|
1
|
+
import { Writable } from "node:stream";
|
|
2
|
+
//#region src/types.d.ts
|
|
3
|
+
export type ArchiveType = 'zip' | 'rar' | 'tar' | 'asar' | '7z' | 'ace' | 'unknown';
|
|
4
|
+
/** A Buffer of the archive's full bytes, or a filesystem path to it. */
|
|
5
|
+
export type ArchiveInput = Buffer | string;
|
|
6
|
+
export type MetadataSchema = 'ComicInfo' | 'MetronInfo';
|
|
7
|
+
export type ImageOutputFormat = 'webp' | 'jpg' | 'png';
|
|
8
|
+
export interface WebpOptions {
|
|
9
|
+
/** Default 92. */
|
|
10
|
+
quality?: number;
|
|
11
|
+
/** libwebp's `-m` compression method (0-6). Default 6. */
|
|
12
|
+
effort?: number;
|
|
13
|
+
/** libwebp's `-sharp_yuv`. Default true. */
|
|
14
|
+
smartSubsample?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface JpegOptions {
|
|
17
|
+
/** Default 90. */
|
|
18
|
+
quality?: number;
|
|
19
|
+
}
|
|
20
|
+
export interface PngOptions {
|
|
21
|
+
/** Only has an effect when `palette` is true. */
|
|
22
|
+
quality?: number;
|
|
23
|
+
/** Zlib compression level (0-9). */
|
|
24
|
+
compressionLevel?: number;
|
|
25
|
+
/** Enables lossy palette quantization (required for `quality` to matter). */
|
|
26
|
+
palette?: boolean;
|
|
27
|
+
}
|
|
28
|
+
export interface ImageConvertOptions {
|
|
29
|
+
webp?: WebpOptions;
|
|
30
|
+
jpeg?: JpegOptions;
|
|
31
|
+
png?: PngOptions;
|
|
32
|
+
}
|
|
33
|
+
/** Shared by every archive-producing operation. */
|
|
34
|
+
export interface ArchiveWriteOptions {
|
|
35
|
+
/**
|
|
36
|
+
* Directory to stage temporary files in when the source or target format
|
|
37
|
+
* requires real filesystem access (asar writes, any 7z operation).
|
|
38
|
+
* Defaults to a fresh directory under `os.tmpdir()`. If that isn't
|
|
39
|
+
* writable and no override is given, a FilesystemAccessError is thrown.
|
|
40
|
+
*/
|
|
41
|
+
tempDir?: string;
|
|
42
|
+
/**
|
|
43
|
+
* When given, the result is streamed directly here and the function
|
|
44
|
+
* resolves `Promise<void>` instead of collecting a final Buffer.
|
|
45
|
+
*/
|
|
46
|
+
output?: string | Writable;
|
|
47
|
+
}
|
|
48
|
+
export interface ConvertArchiveOptions extends ArchiveWriteOptions {
|
|
49
|
+
image?: {
|
|
50
|
+
format: ImageOutputFormat;
|
|
51
|
+
options?: ImageConvertOptions;
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
export interface AddMetadataOptions extends ArchiveWriteOptions {
|
|
55
|
+
overwrite?: boolean;
|
|
56
|
+
}
|
|
57
|
+
export interface RenameOptions extends ArchiveWriteOptions {
|
|
58
|
+
start?: number;
|
|
59
|
+
pad?: number;
|
|
60
|
+
}
|
|
61
|
+
export interface StripOptions extends ArchiveWriteOptions {
|
|
62
|
+
extraKeepExtensions?: string[];
|
|
63
|
+
}
|
|
64
|
+
export interface ComicCredit {
|
|
65
|
+
name: string;
|
|
66
|
+
role: string;
|
|
67
|
+
/** MetronInfo Credits > Credit > Creator `id` attribute. */
|
|
68
|
+
creatorId?: string;
|
|
69
|
+
/** MetronInfo Credits > Credit > Roles > Role `id` attribute for this role. */
|
|
70
|
+
roleId?: string;
|
|
71
|
+
}
|
|
72
|
+
export interface ComicStoryArc {
|
|
73
|
+
name: string;
|
|
74
|
+
number?: number;
|
|
75
|
+
/** MetronInfo Arcs > Arc `id` attribute. */
|
|
76
|
+
id?: string;
|
|
77
|
+
}
|
|
78
|
+
export interface ComicPage {
|
|
79
|
+
index: number;
|
|
80
|
+
type?: string;
|
|
81
|
+
doublePage?: boolean;
|
|
82
|
+
imageSize?: number;
|
|
83
|
+
imageWidth?: number;
|
|
84
|
+
imageHeight?: number;
|
|
85
|
+
key?: string;
|
|
86
|
+
bookmark?: string;
|
|
87
|
+
}
|
|
88
|
+
export interface ComicDate {
|
|
89
|
+
year?: number;
|
|
90
|
+
month?: number;
|
|
91
|
+
day?: number;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* MetronInfo represents most list values (Genre, Tag, Character, Team,
|
|
95
|
+
* Location, Reprint, Story, Publisher > Imprint) as an element with a
|
|
96
|
+
* required text value and an optional `id` attribute linking it back to
|
|
97
|
+
* Metron's database. Plain strings are accepted anywhere this type is
|
|
98
|
+
* expected and are written without an `id` attribute.
|
|
99
|
+
*/
|
|
100
|
+
export interface MetronResource {
|
|
101
|
+
name: string;
|
|
102
|
+
id?: string;
|
|
103
|
+
}
|
|
104
|
+
export interface ComicAlternativeName extends MetronResource {
|
|
105
|
+
/** Two-letter language code. Defaults to "en" per the schema. */
|
|
106
|
+
lang?: string;
|
|
107
|
+
}
|
|
108
|
+
export interface ComicUniverse {
|
|
109
|
+
name: string;
|
|
110
|
+
designation?: string;
|
|
111
|
+
id?: string;
|
|
112
|
+
}
|
|
113
|
+
export interface ComicPrice {
|
|
114
|
+
amount: number;
|
|
115
|
+
/** Two-letter ISO country code. */
|
|
116
|
+
country: string;
|
|
117
|
+
}
|
|
118
|
+
export interface ComicUrl {
|
|
119
|
+
url: string;
|
|
120
|
+
primary?: boolean;
|
|
121
|
+
}
|
|
122
|
+
/** MetronInfo IDS > ID: a link to an external database record. */
|
|
123
|
+
export interface ComicIdentifier {
|
|
124
|
+
source: string;
|
|
125
|
+
value: string;
|
|
126
|
+
primary?: boolean;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Canonical metadata shape: a superset/union of ComicInfo.xml and
|
|
130
|
+
* MetronInfo.xml fields. Conversion to either schema is intentionally lossy
|
|
131
|
+
* for fields the target schema has no equivalent for; see
|
|
132
|
+
* src/metadata/schema.ts for the authoritative field-mapping table.
|
|
133
|
+
*/
|
|
134
|
+
export interface ComicMetadata {
|
|
135
|
+
title?: string;
|
|
136
|
+
series?: string;
|
|
137
|
+
seriesSort?: string;
|
|
138
|
+
volume?: string;
|
|
139
|
+
number?: string;
|
|
140
|
+
/** Shared: ComicInfo `AlternateNumber` <-> MetronInfo `AlternativeNumber`. */
|
|
141
|
+
alternateNumber?: string;
|
|
142
|
+
count?: number;
|
|
143
|
+
pageCount?: number;
|
|
144
|
+
summary?: string;
|
|
145
|
+
notes?: string;
|
|
146
|
+
publisher?: string;
|
|
147
|
+
imprint?: string;
|
|
148
|
+
format?: string;
|
|
149
|
+
language?: string;
|
|
150
|
+
ageRating?: string;
|
|
151
|
+
communityRating?: number;
|
|
152
|
+
coverDate?: ComicDate;
|
|
153
|
+
storeDate?: ComicDate;
|
|
154
|
+
genres?: (string | MetronResource)[];
|
|
155
|
+
tags?: (string | MetronResource)[];
|
|
156
|
+
characters?: (string | MetronResource)[];
|
|
157
|
+
teams?: (string | MetronResource)[];
|
|
158
|
+
locations?: (string | MetronResource)[];
|
|
159
|
+
storyArcs?: ComicStoryArc[];
|
|
160
|
+
credits?: ComicCredit[];
|
|
161
|
+
web?: (string | ComicUrl)[];
|
|
162
|
+
/** ComicInfo `GTIN`, or MetronInfo `GTIN > ISBN`. */
|
|
163
|
+
gtin?: string;
|
|
164
|
+
/** MetronInfo `GTIN > UPC`. MetronInfo allows ISBN and UPC to coexist. */
|
|
165
|
+
gtinUpc?: string;
|
|
166
|
+
/** ComicInfo-only. */
|
|
167
|
+
blackAndWhite?: boolean;
|
|
168
|
+
/** ComicInfo-only. */
|
|
169
|
+
manga?: string;
|
|
170
|
+
pages?: ComicPage[];
|
|
171
|
+
/** ComicInfo-only: a series this issue is an alternate printing/edition of. */
|
|
172
|
+
alternateSeries?: string;
|
|
173
|
+
/** ComicInfo-only: issue count for `alternateSeries`. */
|
|
174
|
+
alternateCount?: number;
|
|
175
|
+
/** ComicInfo-only: scanning/rip group notes. */
|
|
176
|
+
scanInformation?: string;
|
|
177
|
+
/** ComicInfo-only: umbrella grouping across a series (e.g. a crossover event). */
|
|
178
|
+
seriesGroup?: string;
|
|
179
|
+
/** ComicInfo-only. */
|
|
180
|
+
mainCharacterOrTeam?: string;
|
|
181
|
+
/** ComicInfo-only: reviewer notes/text. */
|
|
182
|
+
review?: string;
|
|
183
|
+
/** MetronInfo-only: external database links (Comic Vine, Metron, etc). */
|
|
184
|
+
identifiers?: ComicIdentifier[];
|
|
185
|
+
/** MetronInfo Publisher `id` attribute. */
|
|
186
|
+
publisherId?: string;
|
|
187
|
+
/** MetronInfo Publisher > Imprint `id` attribute. */
|
|
188
|
+
imprintId?: string;
|
|
189
|
+
/** MetronInfo Series `id` attribute. */
|
|
190
|
+
seriesId?: string;
|
|
191
|
+
/** MetronInfo Series `lang` attribute. Defaults to "en" per the schema. */
|
|
192
|
+
seriesLang?: string;
|
|
193
|
+
/** MetronInfo Series > StartYear. */
|
|
194
|
+
seriesStartYear?: number;
|
|
195
|
+
/** MetronInfo Series > IssueCount. */
|
|
196
|
+
seriesIssueCount?: number;
|
|
197
|
+
/** MetronInfo Series > VolumeCount. */
|
|
198
|
+
seriesVolumeCount?: number;
|
|
199
|
+
/** MetronInfo Series > AlternativeNames. */
|
|
200
|
+
seriesAlternativeNames?: ComicAlternativeName[];
|
|
201
|
+
/** MetronInfo-only: volume label used for manga. */
|
|
202
|
+
mangaVolume?: string;
|
|
203
|
+
/** MetronInfo-only. */
|
|
204
|
+
collectionTitle?: string;
|
|
205
|
+
/** MetronInfo-only: story titles collected in this issue. */
|
|
206
|
+
stories?: (string | MetronResource)[];
|
|
207
|
+
/** MetronInfo-only. */
|
|
208
|
+
prices?: ComicPrice[];
|
|
209
|
+
/** MetronInfo-only: other issues this one reprints. */
|
|
210
|
+
reprints?: (string | MetronResource)[];
|
|
211
|
+
/** MetronInfo-only. */
|
|
212
|
+
universes?: ComicUniverse[];
|
|
213
|
+
/** MetronInfo CommunityRating > RatingCount (pairs with `communityRating` as the average). */
|
|
214
|
+
communityRatingCount?: number;
|
|
215
|
+
/** MetronInfo-only, ISO 8601 datetime string. */
|
|
216
|
+
lastModified?: string;
|
|
217
|
+
/** Round-trip escape hatch: original ComicInfo-only fields, kept only when source and target schema are the same. */
|
|
218
|
+
comicInfoExtra?: Record<string, unknown>;
|
|
219
|
+
/** Round-trip escape hatch: original MetronInfo-only fields, kept only when source and target schema are the same. */
|
|
220
|
+
metronInfoExtra?: Record<string, unknown>;
|
|
221
|
+
}
|
|
222
|
+
//#endregion
|
|
223
|
+
//#region src/benchmark/types.d.ts
|
|
224
|
+
/** Archive container formats that can actually be written (excludes 'rar', 'ace', and 'unknown'). */
|
|
225
|
+
type WritableArchiveType = Extract<ArchiveType, 'zip' | 'tar' | 'asar' | '7z'>;
|
|
226
|
+
export declare const WRITABLE_ARCHIVE_TYPES: readonly WritableArchiveType[];
|
|
227
|
+
export declare const BENCHMARK_IMAGE_FORMATS: readonly ImageOutputFormat[];
|
|
228
|
+
/** Conventional comic archive extension for each writable container format. */
|
|
229
|
+
export declare const ARCHIVE_TYPE_EXTENSIONS: Record<WritableArchiveType, string>;
|
|
230
|
+
interface BenchmarkArchiveOptions {
|
|
231
|
+
/** Staging directory for extraction and any asar/7z operations. Defaults to a fresh directory under the OS temp dir. */
|
|
232
|
+
tempDir?: string;
|
|
233
|
+
/** Directory the dated report subdirectory is created under. Defaults to "./reports" (relative to `process.cwd()`). */
|
|
234
|
+
reportsDir?: string;
|
|
235
|
+
/** Number of timed archive-creation runs to average per variant. Defaults to 3, minimum 1. */
|
|
236
|
+
creationIterations?: number;
|
|
237
|
+
/** Number of random single-entry reads to average per variant. Defaults to 10, minimum 1. */
|
|
238
|
+
seekSamples?: number;
|
|
239
|
+
/** Image formats to benchmark. Defaults to all of `BENCHMARK_IMAGE_FORMATS` (webp, png, jpg). Must be non-empty. */
|
|
240
|
+
imageFormats?: ImageOutputFormat[];
|
|
241
|
+
/** Image encode options applied uniformly across every generated variant. */
|
|
242
|
+
image?: ImageConvertOptions;
|
|
243
|
+
}
|
|
244
|
+
interface BenchmarkVariantResult {
|
|
245
|
+
archiveType: WritableArchiveType;
|
|
246
|
+
imageFormat: ImageOutputFormat;
|
|
247
|
+
fileName: string;
|
|
248
|
+
filePath: string;
|
|
249
|
+
fileSizeBytes: number;
|
|
250
|
+
pageCount: number;
|
|
251
|
+
/** Average size of one image entry after conversion, in bytes. Independent of container choice for a given image format. */
|
|
252
|
+
avgImageSizeBytes: number;
|
|
253
|
+
/** Average wall-clock time to create this archive, in milliseconds. */
|
|
254
|
+
avgCreationMs: number;
|
|
255
|
+
/** Average wall-clock time to read one random image entry, in milliseconds. */
|
|
256
|
+
avgSeekMs: number;
|
|
257
|
+
}
|
|
258
|
+
interface BenchmarkArchiveResult {
|
|
259
|
+
sourcePath: string;
|
|
260
|
+
/** ISO 8601 timestamp of when the benchmark run started. */
|
|
261
|
+
generatedAt: string;
|
|
262
|
+
reportDir: string;
|
|
263
|
+
reportPath: string;
|
|
264
|
+
/** Every entry from the source archive, extracted here for inspection. */
|
|
265
|
+
sourceDir: string;
|
|
266
|
+
archivesDir: string;
|
|
267
|
+
variants: BenchmarkVariantResult[];
|
|
268
|
+
}
|
|
269
|
+
//#endregion
|
|
270
|
+
//#region src/errors.d.ts
|
|
271
|
+
export declare class UnsupportedOperationError extends Error {
|
|
272
|
+
constructor(message: string);
|
|
273
|
+
}
|
|
274
|
+
export declare class ArchiveFormatError extends Error {
|
|
275
|
+
constructor(message: string);
|
|
276
|
+
}
|
|
277
|
+
export declare class MetadataNotFoundError extends Error {
|
|
278
|
+
constructor(message: string);
|
|
279
|
+
}
|
|
280
|
+
export declare class FilesystemAccessError extends Error {
|
|
281
|
+
constructor(message: string);
|
|
282
|
+
}
|
|
283
|
+
export declare class SevenZipUnavailableError extends Error {
|
|
284
|
+
constructor(message: string);
|
|
285
|
+
}
|
|
286
|
+
export declare class NoImagesFoundError extends Error {
|
|
287
|
+
constructor(message: string);
|
|
288
|
+
}
|
|
289
|
+
//#endregion
|
|
290
|
+
//#region src/detect.d.ts
|
|
291
|
+
export declare function detectArchiveType(input: ArchiveInput): Promise<ArchiveType>;
|
|
292
|
+
export declare function isZip(input: ArchiveInput): Promise<boolean>;
|
|
293
|
+
export declare function isRar(input: ArchiveInput): Promise<boolean>;
|
|
294
|
+
export declare function isTar(input: ArchiveInput): Promise<boolean>;
|
|
295
|
+
export declare function isAsar(input: ArchiveInput): Promise<boolean>;
|
|
296
|
+
export declare function is7z(input: ArchiveInput): Promise<boolean>;
|
|
297
|
+
export declare function isAce(input: ArchiveInput): Promise<boolean>;
|
|
298
|
+
//#endregion
|
|
299
|
+
//#region src/convertArchive.d.ts
|
|
300
|
+
export declare function convertArchive(input: ArchiveInput, targetType: Exclude<ArchiveType, 'unknown'>, options?: ConvertArchiveOptions): Promise<Buffer | void>;
|
|
301
|
+
//#endregion
|
|
302
|
+
//#region src/extractArchive.d.ts
|
|
303
|
+
export interface ExtractArchiveOptions {
|
|
304
|
+
/** Temporary staging directory for archive formats that require real files to read (7z). */
|
|
305
|
+
tempDir?: string;
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Extracts every entry in an archive to real files under `destDir`,
|
|
309
|
+
* preserving relative paths (`destDir` is created if missing). Throws
|
|
310
|
+
* `ArchiveFormatError` for an undetectable/unknown format, or
|
|
311
|
+
* `UnsupportedOperationError` for ACE. Returns the archive-relative entry
|
|
312
|
+
* paths that were written, in archive iteration order.
|
|
313
|
+
*/
|
|
314
|
+
export declare function extractArchive(input: ArchiveInput, destDir: string, options?: ExtractArchiveOptions): Promise<string[]>;
|
|
315
|
+
//#endregion
|
|
316
|
+
//#region src/metadata/comicInfo.d.ts
|
|
317
|
+
export declare function metadataToComicInfoXml(metadata: ComicMetadata): string;
|
|
318
|
+
export declare function comicInfoXmlToMetadata(xml: string | Buffer): ComicMetadata;
|
|
319
|
+
//#endregion
|
|
320
|
+
//#region src/metadata/metronInfo.d.ts
|
|
321
|
+
export declare function metadataToMetronInfoXml(metadata: ComicMetadata): string;
|
|
322
|
+
export declare function metronInfoXmlToMetadata(xml: string | Buffer): ComicMetadata;
|
|
323
|
+
//#endregion
|
|
324
|
+
//#region src/metadata/validate.d.ts
|
|
325
|
+
interface MetadataValidationIssue {
|
|
326
|
+
message: string;
|
|
327
|
+
line?: number;
|
|
328
|
+
}
|
|
329
|
+
interface MetadataValidationResult {
|
|
330
|
+
valid: boolean;
|
|
331
|
+
issues: MetadataValidationIssue[];
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Validates an XML document against the bundled ComicInfo.xml or
|
|
335
|
+
* MetronInfo.xml XSD. Returns `{ valid: true, issues: [] }` when the
|
|
336
|
+
* document conforms, or `{ valid: false, issues }` with one entry per
|
|
337
|
+
* schema violation (element/attribute name and line number, where
|
|
338
|
+
* available) otherwise.
|
|
339
|
+
*/
|
|
340
|
+
export declare function validateMetadataXml(xml: string | Buffer, schema: MetadataSchema): Promise<MetadataValidationResult>;
|
|
341
|
+
//#endregion
|
|
342
|
+
//#region src/metadata/schema.d.ts
|
|
343
|
+
/**
|
|
344
|
+
* Authoritative field-mapping table between the canonical ComicMetadata
|
|
345
|
+
* shape and each external XML schema (ComicInfo.xml v2.1, MetronInfo.xml
|
|
346
|
+
* v1.1 — see `schemas/`). Conversion is intentionally lossy in both
|
|
347
|
+
* directions; a field with no equivalent in the target schema is dropped
|
|
348
|
+
* unless the source and target schema happen to be the same one (in which
|
|
349
|
+
* case `comicInfoExtra`/`metronInfoExtra` round-trips it).
|
|
350
|
+
*
|
|
351
|
+
* | Canonical field | ComicInfo.xml | MetronInfo.xml |
|
|
352
|
+
* |-------------------------|-----------------------------------------------------|------------------------------------------------|
|
|
353
|
+
* | title | Title | (no equivalent — dropped) |
|
|
354
|
+
* | series | Series | Series > Name |
|
|
355
|
+
* | seriesSort | (no equivalent) | Series > SortName |
|
|
356
|
+
* | seriesId / seriesLang | (no equivalent) | Series `id`/`lang` attributes |
|
|
357
|
+
* | seriesStartYear | (no equivalent) | Series > StartYear |
|
|
358
|
+
* | seriesIssueCount | (no equivalent) | Series > IssueCount |
|
|
359
|
+
* | seriesVolumeCount | (no equivalent) | Series > VolumeCount |
|
|
360
|
+
* | seriesAlternativeNames | (no equivalent) | Series > AlternativeNames > AlternativeName[] |
|
|
361
|
+
* | seriesGroup | SeriesGroup | (no equivalent — dropped) |
|
|
362
|
+
* | volume | Volume | Series > Volume |
|
|
363
|
+
* | number | Number | Number |
|
|
364
|
+
* | alternateNumber | AlternateNumber | AlternativeNumber |
|
|
365
|
+
* | alternateSeries | AlternateSeries | (no equivalent — dropped) |
|
|
366
|
+
* | alternateCount | AlternateCount | (no equivalent — dropped) |
|
|
367
|
+
* | count | Count | (no equivalent) |
|
|
368
|
+
* | pageCount | PageCount | PageCount |
|
|
369
|
+
* | summary | Summary | Summary |
|
|
370
|
+
* | notes | Notes | Notes |
|
|
371
|
+
* | review | Review | (no equivalent — dropped) |
|
|
372
|
+
* | scanInformation | ScanInformation | (no equivalent — dropped) |
|
|
373
|
+
* | publisher / publisherId | Publisher | Publisher > Name / `id` attribute |
|
|
374
|
+
* | imprint / imprintId | Imprint | Publisher > Imprint / `id` attribute |
|
|
375
|
+
* | collectionTitle | (no equivalent) | CollectionTitle |
|
|
376
|
+
* | mangaVolume | (no equivalent) | MangaVolume |
|
|
377
|
+
* | format | Format | Series > Format |
|
|
378
|
+
* | language | LanguageISO | (no equivalent) |
|
|
379
|
+
* | ageRating | AgeRating | AgeRating |
|
|
380
|
+
* | communityRating(Count) | CommunityRating | CommunityRating > AverageRating / RatingCount |
|
|
381
|
+
* | coverDate | Year / Month / Day | CoverDate (YYYY-MM-DD) |
|
|
382
|
+
* | storeDate | (no equivalent) | StoreDate (YYYY-MM-DD) |
|
|
383
|
+
* | lastModified | (no equivalent) | LastModified |
|
|
384
|
+
* | genres | Genre (comma-separated string) | Genres > Genre[] (`id` attribute preserved) |
|
|
385
|
+
* | tags | Tags (comma-separated string) | Tags > Tag[] (`id` attribute preserved) |
|
|
386
|
+
* | characters | Characters (comma-separated string) | Characters > Character[] (`id` attribute) |
|
|
387
|
+
* | teams | Teams (comma-separated string) | Teams > Team[] (`id` attribute) |
|
|
388
|
+
* | locations | Locations (comma-separated string) | Locations > Location[] (`id` attribute) |
|
|
389
|
+
* | storyArcs | StoryArc / StoryArcNumber (parallel comma lists) | Arcs > Arc[] (Name + Number + `id`) |
|
|
390
|
+
* | mainCharacterOrTeam | MainCharacterOrTeam | (no equivalent — dropped) |
|
|
391
|
+
* | stories | (no equivalent) | Stories > Story[] |
|
|
392
|
+
* | reprints | (no equivalent) | Reprints > Reprint[] |
|
|
393
|
+
* | universes | (no equivalent) | Universes > Universe[] |
|
|
394
|
+
* | identifiers | (no equivalent) | IDS > ID[] |
|
|
395
|
+
* | prices | (no equivalent) | Prices > Price[] |
|
|
396
|
+
* | credits | Writer/Penciller/Inker/Colorist/Letterer/CoverArtist/Editor/Translator (comma-separated per role) | Credits > Credit[] (Creator + Roles > Role[], `id` attributes) |
|
|
397
|
+
* | web | Web (single URL) | URLs > URL[] (`primary` attribute) |
|
|
398
|
+
* | gtin | GTIN | GTIN > ISBN |
|
|
399
|
+
* | gtinUpc | (no equivalent) | GTIN > UPC |
|
|
400
|
+
* | blackAndWhite | BlackAndWhite (Yes/No) | (no equivalent — ComicInfo-only) |
|
|
401
|
+
* | manga | Manga | (no equivalent — ComicInfo-only) |
|
|
402
|
+
* | pages | Pages > Page[] (Image/Type/DoublePage/... attrs) | (no equivalent — ComicInfo-only) |
|
|
403
|
+
*/
|
|
404
|
+
export declare const COMIC_INFO_CREDIT_ROLES: readonly ["Writer", "Penciller", "Inker", "Colorist", "Letterer", "CoverArtist", "Editor", "Translator"];
|
|
405
|
+
type ComicInfoCreditRole = (typeof COMIC_INFO_CREDIT_ROLES)[number];
|
|
406
|
+
/** ComicInfo.xml `YesNo` simple type. */
|
|
407
|
+
export declare const COMIC_INFO_YES_NO_VALUES: readonly ["Unknown", "No", "Yes"];
|
|
408
|
+
/** ComicInfo.xml `Manga` simple type. */
|
|
409
|
+
export declare const COMIC_INFO_MANGA_VALUES: readonly ["Unknown", "No", "Yes", "YesAndRightToLeft"];
|
|
410
|
+
/** ComicInfo.xml `AgeRating` simple type. */
|
|
411
|
+
export declare const COMIC_INFO_AGE_RATING_VALUES: readonly ["Unknown", "Adults Only 18+", "Early Childhood", "Everyone", "Everyone 10+", "G", "Kids to Adults", "M", "MA15+", "Mature 17+", "PG", "R18+", "Rating Pending", "Teen", "X18+"];
|
|
412
|
+
/** ComicInfo.xml `ComicPageType` simple type. */
|
|
413
|
+
export declare const COMIC_INFO_PAGE_TYPE_VALUES: readonly ["FrontCover", "InnerCover", "Roundup", "Story", "Advertisement", "Editorial", "Letters", "Preview", "BackCover", "Other", "Deleted"];
|
|
414
|
+
/** MetronInfo.xml `formatType` simple type (Series > Format). */
|
|
415
|
+
export declare const METRON_FORMAT_VALUES: readonly ["Annual", "Digital Chapter", "Graphic Novel", "Hardcover", "Limited Series", "Omnibus", "One-Shot", "Single Issue", "Trade Paperback"];
|
|
416
|
+
/** MetronInfo.xml `informationSource` simple type (IDS > ID `source` attribute). */
|
|
417
|
+
export declare const METRON_INFORMATION_SOURCE_VALUES: readonly ["AniList", "Comic Vine", "Grand Comics Database", "Kitsu", "MangaDex", "MangaUpdates", "Marvel", "Metron", "MyAnimeList", "League of Comic Geeks"];
|
|
418
|
+
/** MetronInfo.xml `roleValues` simple type (Credits > Credit > Roles > Role). */
|
|
419
|
+
export declare const METRON_ROLE_VALUES: readonly ["Writer", "Script", "Story", "Plot", "Interviewer", "Artist", "Penciller", "Breakdowns", "Illustrator", "Layouts", "Inker", "Embellisher", "Finishes", "Ink Assists", "Colorist", "Color Separations", "Color Assists", "Color Flats", "Digital Art Technician", "Gray Tone", "Letterer", "Cover", "Editor", "Consulting Editor", "Assistant Editor", "Associate Editor", "Group Editor", "Senior Editor", "Managing Editor", "Collection Editor", "Production", "Designer", "Logo Design", "Translator", "Supervising Editor", "Executive Editor", "Editor In Chief", "President", "Publisher", "Chief Creative Officer", "Executive Producer", "Other"];
|
|
420
|
+
/** MetronInfo.xml `ageRatingType` simple type. */
|
|
421
|
+
export declare const METRON_AGE_RATING_VALUES: readonly ["Unknown", "Everyone", "Teen", "Teen Plus", "Mature", "Explicit", "Adult"];
|
|
422
|
+
export declare function splitCommaList(value?: string): string[] | undefined;
|
|
423
|
+
export declare function joinCommaList(values?: string[]): string | undefined;
|
|
424
|
+
/** Extracts the plain text value from a resource that may carry a MetronInfo `id` attribute. */
|
|
425
|
+
export declare function resourceName(item: string | MetronResource): string;
|
|
426
|
+
/** Extracts the MetronInfo `id` attribute from a resource, if any. */
|
|
427
|
+
export declare function resourceId(item: string | MetronResource): string | undefined;
|
|
428
|
+
export declare function joinResourceNames(values?: (string | MetronResource)[]): string | undefined;
|
|
429
|
+
declare namespace index_d_exports {
|
|
430
|
+
export { COMIC_INFO_AGE_RATING_VALUES, COMIC_INFO_CREDIT_ROLES, COMIC_INFO_MANGA_VALUES, COMIC_INFO_PAGE_TYPE_VALUES, COMIC_INFO_YES_NO_VALUES, ComicInfoCreditRole, METRON_AGE_RATING_VALUES, METRON_FORMAT_VALUES, METRON_INFORMATION_SOURCE_VALUES, METRON_ROLE_VALUES, MetadataValidationIssue, MetadataValidationResult, addMetadataToArchive, comicInfoXmlToMetadata, hasComicMetadata, joinCommaList, joinResourceNames, metadataToComicInfoXml, metadataToMetronInfoXml, metadataToXml, metronInfoXmlToMetadata, readArchiveMetadata, resourceId, resourceName, splitCommaList, validateMetadataXml, xmlToMetadata };
|
|
431
|
+
}
|
|
432
|
+
export declare function metadataToXml(metadata: ComicMetadata, schema: MetadataSchema): string;
|
|
433
|
+
export declare function xmlToMetadata(xml: string | Buffer, schema: MetadataSchema): ComicMetadata;
|
|
434
|
+
export declare function hasComicMetadata(input: ArchiveInput): Promise<{
|
|
435
|
+
present: boolean;
|
|
436
|
+
schema?: MetadataSchema;
|
|
437
|
+
path?: string;
|
|
438
|
+
}>;
|
|
439
|
+
export declare function readArchiveMetadata(input: ArchiveInput): Promise<{
|
|
440
|
+
schema: MetadataSchema;
|
|
441
|
+
metadata: ComicMetadata;
|
|
442
|
+
} | null>;
|
|
443
|
+
export declare function addMetadataToArchive(input: ArchiveInput, metadata: ComicMetadata, schema: MetadataSchema, options?: AddMetadataOptions): Promise<Buffer | void>;
|
|
444
|
+
//#endregion
|
|
445
|
+
//#region src/images/convert.d.ts
|
|
446
|
+
export declare function convertImageBuffer(image: Buffer, format: ImageOutputFormat, options?: ImageConvertOptions): Promise<Buffer>;
|
|
447
|
+
export declare function convertArchiveImages(input: ArchiveInput, format: ImageOutputFormat, options?: ImageConvertOptions & ArchiveWriteOptions): Promise<Buffer | void>;
|
|
448
|
+
//#endregion
|
|
449
|
+
//#region src/images/phash.d.ts
|
|
450
|
+
/**
|
|
451
|
+
* Standard 8x8 DCT perceptual hash: resize to 32x32 greyscale, run a 2D
|
|
452
|
+
* DCT-II, threshold the top-left 8x8 block against the median of that block
|
|
453
|
+
* (excluding the DC term at [0][0] from the median calculation, though it is
|
|
454
|
+
* still included positionally as bit 0). Returned as a bigint since JS
|
|
455
|
+
* `Number` cannot losslessly represent all 64-bit patterns.
|
|
456
|
+
*/
|
|
457
|
+
export declare function computeImagePHash(image: Buffer): Promise<bigint>;
|
|
458
|
+
export declare function phashToHex(hash: bigint): string;
|
|
459
|
+
export declare function hammingDistance(a: bigint, b: bigint): number;
|
|
460
|
+
export declare function computeArchiveImagePHash(input: ArchiveInput, entryPath: string): Promise<bigint>;
|
|
461
|
+
//#endregion
|
|
462
|
+
//#region src/images/isImage.d.ts
|
|
463
|
+
export declare const IMAGE_EXTENSIONS: readonly ["jpg", "jpeg", "png", "gif", "webp", "bmp", "tiff", "tif"];
|
|
464
|
+
export declare function getExtension(entryPath: string): string;
|
|
465
|
+
export declare function isImagePath(entryPath: string): boolean;
|
|
466
|
+
//#endregion
|
|
467
|
+
//#region src/hashing/sha256.d.ts
|
|
468
|
+
export declare function sha256ArchiveEntry(input: ArchiveInput, entryPath: string): Promise<string>;
|
|
469
|
+
/**
|
|
470
|
+
* SHA256 of the whole archive file — except for asar, where only the
|
|
471
|
+
* content region (bytes after the header) is hashed, so header/index
|
|
472
|
+
* reordering never changes the content hash.
|
|
473
|
+
*/
|
|
474
|
+
export declare function sha256Archive(input: ArchiveInput): Promise<string>;
|
|
475
|
+
//#endregion
|
|
476
|
+
//#region src/rename.d.ts
|
|
477
|
+
/**
|
|
478
|
+
* Renames image entries to the standard `P#####` pattern in natural sort
|
|
479
|
+
* order of their current names, leaving non-image entries (like
|
|
480
|
+
* ComicInfo.xml/MetronInfo.xml) untouched.
|
|
481
|
+
*
|
|
482
|
+
* This requires two passes over the archive: `listEntries` is called once to
|
|
483
|
+
* collect image paths (metadata only — no content is read, so no
|
|
484
|
+
* decompression work is wasted) to compute the sort-order rename map, then
|
|
485
|
+
* called again to stream entries out under their new names. Streaming
|
|
486
|
+
* adapters (zip in particular) can't be "rewound" mid-read, so the second
|
|
487
|
+
* pass re-invokes `listEntries` from the start rather than reusing entry
|
|
488
|
+
* objects collected in the first pass.
|
|
489
|
+
*/
|
|
490
|
+
export declare function renameArchiveImagesSequentially(input: ArchiveInput, options?: RenameOptions): Promise<Buffer | void>;
|
|
491
|
+
//#endregion
|
|
492
|
+
//#region src/strip.d.ts
|
|
493
|
+
export declare function stripNonEssentialFiles(input: ArchiveInput, options?: StripOptions): Promise<Buffer | void>;
|
|
494
|
+
//#endregion
|
|
495
|
+
//#region src/listFiles.d.ts
|
|
496
|
+
export declare function listArchiveFiles(input: ArchiveInput): Promise<string[]>;
|
|
497
|
+
//#endregion
|
|
498
|
+
//#region src/benchmark/benchmarkArchive.d.ts
|
|
499
|
+
/**
|
|
500
|
+
* Extracts a comic archive, validates it contains image files, then
|
|
501
|
+
* generates one archive per (writable container format) x (page image
|
|
502
|
+
* format) combination, benchmarks each variant's creation speed and random
|
|
503
|
+
* single-file read speed, and writes a markdown report summarizing the
|
|
504
|
+
* results.
|
|
505
|
+
*
|
|
506
|
+
* Images are re-encoded to each target format once per image format, before
|
|
507
|
+
* any timing starts; `avgCreationMs` measures only packaging already-encoded
|
|
508
|
+
* entries into the target container, not the image re-encoding cost.
|
|
509
|
+
*
|
|
510
|
+
* Throws `ArchiveFormatError` (undetectable format) or
|
|
511
|
+
* `UnsupportedOperationError` (ACE) if `filePath` is not extractable,
|
|
512
|
+
* `NoImagesFoundError` if the archive contains no image files, and
|
|
513
|
+
* `RangeError` if `options.imageFormats` is empty or names an unsupported
|
|
514
|
+
* format.
|
|
515
|
+
*/
|
|
516
|
+
export declare function benchmarkArchive(filePath: string, options?: BenchmarkArchiveOptions): Promise<BenchmarkArchiveResult>;
|
|
517
|
+
//#endregion
|
|
518
|
+
//#region src/benchmark/report.d.ts
|
|
519
|
+
export declare function renderBenchmarkReportMarkdown(result: BenchmarkArchiveResult): string;
|
|
520
|
+
//#endregion
|
|
521
|
+
//#region src/index.d.ts
|
|
522
|
+
declare const comicArchiveHandler: {
|
|
523
|
+
convertImageBuffer: typeof convertImageBuffer;
|
|
524
|
+
convertArchiveImages: typeof convertArchiveImages;
|
|
525
|
+
computeImagePHash: typeof computeImagePHash;
|
|
526
|
+
phashToHex: typeof phashToHex;
|
|
527
|
+
computeArchiveImagePHash: typeof computeArchiveImagePHash;
|
|
528
|
+
hammingDistance: typeof hammingDistance;
|
|
529
|
+
IMAGE_EXTENSIONS: readonly ["jpg", "jpeg", "png", "gif", "webp", "bmp", "tiff", "tif"];
|
|
530
|
+
isImagePath: typeof isImagePath;
|
|
531
|
+
sha256ArchiveEntry: typeof sha256ArchiveEntry;
|
|
532
|
+
sha256Archive: typeof sha256Archive;
|
|
533
|
+
renameArchiveImagesSequentially: typeof renameArchiveImagesSequentially;
|
|
534
|
+
stripNonEssentialFiles: typeof stripNonEssentialFiles;
|
|
535
|
+
listArchiveFiles: typeof listArchiveFiles;
|
|
536
|
+
benchmarkArchive: typeof benchmarkArchive;
|
|
537
|
+
renderBenchmarkReportMarkdown: typeof renderBenchmarkReportMarkdown;
|
|
538
|
+
WRITABLE_ARCHIVE_TYPES: readonly WritableArchiveType[];
|
|
539
|
+
BENCHMARK_IMAGE_FORMATS: readonly ImageOutputFormat[];
|
|
540
|
+
ARCHIVE_TYPE_EXTENSIONS: Record<WritableArchiveType, string>;
|
|
541
|
+
metadataToXml(metadata: ComicMetadata, schema: MetadataSchema): string;
|
|
542
|
+
xmlToMetadata(xml: string | Buffer, schema: MetadataSchema): ComicMetadata;
|
|
543
|
+
hasComicMetadata(input: ArchiveInput): Promise<{
|
|
544
|
+
present: boolean;
|
|
545
|
+
schema?: MetadataSchema;
|
|
546
|
+
path?: string;
|
|
547
|
+
}>;
|
|
548
|
+
readArchiveMetadata(input: ArchiveInput): Promise<{
|
|
549
|
+
schema: MetadataSchema;
|
|
550
|
+
metadata: ComicMetadata;
|
|
551
|
+
} | null>;
|
|
552
|
+
addMetadataToArchive(input: ArchiveInput, metadata: ComicMetadata, schema: MetadataSchema, options?: AddMetadataOptions): Promise<Buffer | void>;
|
|
553
|
+
metadataToComicInfoXml: typeof metadataToComicInfoXml;
|
|
554
|
+
comicInfoXmlToMetadata: typeof comicInfoXmlToMetadata;
|
|
555
|
+
metadataToMetronInfoXml: typeof metadataToMetronInfoXml;
|
|
556
|
+
metronInfoXmlToMetadata: typeof metronInfoXmlToMetadata;
|
|
557
|
+
validateMetadataXml: typeof validateMetadataXml;
|
|
558
|
+
COMIC_INFO_CREDIT_ROLES: readonly ["Writer", "Penciller", "Inker", "Colorist", "Letterer", "CoverArtist", "Editor", "Translator"];
|
|
559
|
+
COMIC_INFO_YES_NO_VALUES: readonly ["Unknown", "No", "Yes"];
|
|
560
|
+
COMIC_INFO_MANGA_VALUES: readonly ["Unknown", "No", "Yes", "YesAndRightToLeft"];
|
|
561
|
+
COMIC_INFO_AGE_RATING_VALUES: readonly ["Unknown", "Adults Only 18+", "Early Childhood", "Everyone", "Everyone 10+", "G", "Kids to Adults", "M", "MA15+", "Mature 17+", "PG", "R18+", "Rating Pending", "Teen", "X18+"];
|
|
562
|
+
COMIC_INFO_PAGE_TYPE_VALUES: readonly ["FrontCover", "InnerCover", "Roundup", "Story", "Advertisement", "Editorial", "Letters", "Preview", "BackCover", "Other", "Deleted"];
|
|
563
|
+
METRON_FORMAT_VALUES: readonly ["Annual", "Digital Chapter", "Graphic Novel", "Hardcover", "Limited Series", "Omnibus", "One-Shot", "Single Issue", "Trade Paperback"];
|
|
564
|
+
METRON_INFORMATION_SOURCE_VALUES: readonly ["AniList", "Comic Vine", "Grand Comics Database", "Kitsu", "MangaDex", "MangaUpdates", "Marvel", "Metron", "MyAnimeList", "League of Comic Geeks"];
|
|
565
|
+
METRON_ROLE_VALUES: readonly ["Writer", "Script", "Story", "Plot", "Interviewer", "Artist", "Penciller", "Breakdowns", "Illustrator", "Layouts", "Inker", "Embellisher", "Finishes", "Ink Assists", "Colorist", "Color Separations", "Color Assists", "Color Flats", "Digital Art Technician", "Gray Tone", "Letterer", "Cover", "Editor", "Consulting Editor", "Assistant Editor", "Associate Editor", "Group Editor", "Senior Editor", "Managing Editor", "Collection Editor", "Production", "Designer", "Logo Design", "Translator", "Supervising Editor", "Executive Editor", "Editor In Chief", "President", "Publisher", "Chief Creative Officer", "Executive Producer", "Other"];
|
|
566
|
+
METRON_AGE_RATING_VALUES: readonly ["Unknown", "Everyone", "Teen", "Teen Plus", "Mature", "Explicit", "Adult"];
|
|
567
|
+
splitCommaList: typeof splitCommaList;
|
|
568
|
+
joinCommaList: typeof joinCommaList;
|
|
569
|
+
resourceName: typeof resourceName;
|
|
570
|
+
resourceId: typeof resourceId;
|
|
571
|
+
joinResourceNames: typeof joinResourceNames;
|
|
572
|
+
convertArchive: typeof convertArchive;
|
|
573
|
+
extractArchive: typeof extractArchive;
|
|
574
|
+
detectArchiveType(input: ArchiveInput): Promise<ArchiveType>;
|
|
575
|
+
isZip(input: ArchiveInput): Promise<boolean>;
|
|
576
|
+
isRar(input: ArchiveInput): Promise<boolean>;
|
|
577
|
+
isTar(input: ArchiveInput): Promise<boolean>;
|
|
578
|
+
isAsar(input: ArchiveInput): Promise<boolean>;
|
|
579
|
+
is7z(input: ArchiveInput): Promise<boolean>;
|
|
580
|
+
isAce(input: ArchiveInput): Promise<boolean>;
|
|
581
|
+
};
|
|
582
|
+
//#endregion
|
|
583
|
+
export { type BenchmarkArchiveOptions, type BenchmarkArchiveResult, type BenchmarkVariantResult, type ComicInfoCreditRole, type MetadataValidationIssue, type MetadataValidationResult, type WritableArchiveType, comicArchiveHandler as default };
|
|
584
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/benchmark/types.ts","../src/errors.ts","../src/detect.ts","../src/convertArchive.ts","../src/extractArchive.ts","../src/metadata/comicInfo.ts","../src/metadata/metronInfo.ts","../src/metadata/validate.ts","../src/metadata/schema.ts","../src/metadata/index.ts","../src/images/convert.ts","../src/images/phash.ts","../src/images/isImage.ts","../src/hashing/sha256.ts","../src/rename.ts","../src/strip.ts","../src/listFiles.ts","../src/benchmark/benchmarkArchive.ts","../src/benchmark/report.ts","../src/index.ts"],"mappings":";;YAEY;;YAGA,eAAe;YAEf;YAEA;iBAEK;;EAEf;;EAEA;;EAEA;;iBAGe;;EAEf;;iBAGe;;EAEf;;EAEA;;EAEA;;iBAGe;EACf,OAAO;EACP,OAAO;EACP,MAAM;;;iBAIS;;;;;;;EAOf;;;;;EAKA,kBAAkB;;iBAGH,8BAA8B;EAC7C;IAAU,QAAQ;IAAmB,UAAU;;;iBAGhC,2BAA2B;EAC1C;;iBAGe,sBAAsB;EACrC;EACA;;iBAGe,qBAAqB;EACpC;;iBAGe;EACf;EACA;;EAEA;;EAEA;;iBAGe;EACf;EACA;;EAEA;;iBAGe;EACf;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;iBAGe;EACf;EACA;EACA;;;;;;;;;iBAUe;EACf;EACA;;iBAGe,6BAA6B;;EAE5C;;iBAGe;EACf;EACA;EACA;;iBAGe;EACf;;EAEA;;iBAGe;EACf;EACA;;;iBAIe;EACf;EACA;EACA;;;;;;;;iBASe;EACf;EACA;EACA;EACA;EACA;;EAEA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,YAAY;EACZ,YAAY;EACZ,mBAAmB;EACnB,iBAAiB;EACjB,uBAAuB;EACvB,kBAAkB;EAClB,sBAAsB;EACtB,YAAY;EACZ,UAAU;EACV,gBAAgB;;EAEhB;;EAEA;;EAEA;;EAEA;EACA,QAAQ;;EAGR;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA;;EAGA,cAAc;;EAEd;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA;;EAEA,yBAAyB;;EAEzB;;EAEA;;EAEA,oBAAoB;;EAEpB,SAAS;;EAET,qBAAqB;;EAErB,YAAY;;EAEZ;;EAEA;;EAGA,iBAAiB;;EAEjB,kBAAkB;;;;;KC/OR,sBAAsB,QAAQ;qBAE7B,iCAAiC;qBAEjC,kCAAkC;;qBAGlC,yBAAyB,OAAO;UAO5B;;EAEf;;EAEA;;EAEA;;EAEA;;EAEA,eAAe;;EAEf,QAAQ;;UAGO;EACf,aAAa;EACb,aAAa;EACb;EACA;EACA;EACA;;EAEA;;EAEA;;EAEA;;UAGe;EACf;;EAEA;EACA;EACA;;EAEA;EACA;EACA,UAAU;;;;qBCxDC,kCAAkC;EACjC,YAAA;;qBAMD,2BAA2B;EAC1B,YAAA;;qBAMD,8BAA8B;EAC7B,YAAA;;qBAMD,8BAA8B;EAC7B,YAAA;;qBAMD,iCAAiC;EAChC,YAAA;;qBAMD,2BAA2B;EAC1B,YAAA;;;;wBCNQ,kBAAkB,OAAO,eAAe,QAAQ;wBAWhD,MAAM,OAAO,eAAe;wBAI5B,MAAM,OAAO,eAAe;wBAI5B,MAAM,OAAO,eAAe;wBAI5B,OAAO,OAAO,eAAe;wBAI7B,KAAK,OAAO,eAAe;wBAI3B,MAAM,OAAO,eAAe;;;wBC7C5B,eACpB,OAAO,cACP,YAAY,QAAQ,yBACpB,UAAS,wBACR,QAAQ;;;iBCZM;;EAEf;;;;;;;;;wBAUoB,eAAe,OAAO,cAAc,iBAAiB,UAAS,wBAA6B;;;wBCsCjG,uBAAuB,UAAU;wBAsKjC,uBAAuB,cAAc,SAAS;;;wBCX9C,wBAAwB,UAAU;wBA0JlC,wBAAwB,cAAc,SAAS;;;UC1W9C;EACf;EACA;;UAGe;EACf;EACA,QAAQ;;;;;;;;;wBA2BY,oBAAoB,cAAc,QAAQ,QAAQ,iBAAiB,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBCsCpF;KAWD,8BAA8B;;qBAG7B;;qBAGA;;qBAGA;;qBAmBA;;qBAeA;;qBAaA;;qBAcA;;qBA8CA;wBAEG,eAAe;wBAWf,cAAc;;wBAKd,aAAa,eAAe;;wBAK5B,WAAW,eAAe;wBAI1B,kBAAkB,mBAAmB;;;;wBC/LrC,cAAc,UAAU,eAAe,QAAQ;wBAI/C,cAAc,cAAc,QAAQ,QAAQ,iBAAiB;wBAIvD,iBAAiB,OAAO,eAAe;EAAU;EAAkB,SAAS;EAAgB;;wBA2B5F,oBAAoB,OAAO,eAAe;EAAU,QAAQ;EAAgB,UAAU;;wBAiBtF,qBACpB,OAAO,cACP,UAAU,eACV,QAAQ,gBACR,UAAS,qBACR,QAAQ;;;wBCtFW,mBAAmB,OAAO,QAAQ,QAAQ,mBAAmB,UAAS,sBAA2B,QAAQ;wBA6BzG,qBACpB,OAAO,cACP,QAAQ,mBACR,UAAS,sBAAsB,sBAC9B,QAAQ;;;;;;;;;;wBCMW,kBAAkB,OAAO,SAAS;wBA6BxC,WAAW;wBAIX,gBAAgB,WAAW;wBAUrB,yBAAyB,OAAO,cAAc,oBAAoB;;;qBC7F3E;wBAEG,aAAa;wBAKb,YAAY;;;wBCUN,mBAAmB,OAAO,cAAc,oBAAoB;;;;;;wBAgB5D,cAAc,OAAO,eAAe;;;;;;;;;;;;;;;;wBCZpC,gCAAgC,OAAO,cAAc,UAAS,gBAAqB,QAAQ;;;wBCd3F,uBAAuB,OAAO,cAAc,UAAS,eAAoB,QAAQ;;;wBCHjF,iBAAiB,OAAO,eAAe;;;;;;;;;;;;;;;;;;;;wBCkEvC,iBAAiB,kBAAkB,UAAS,0BAA+B,QAAQ;;;wBCZzF,8BAA8B,QAAQ;;;cCxBhD;;;;;;;;;;;;;;;;;;;;;;;IA0ByM;IAAuB"}
|