@character-foundry/character-foundry 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/README.md +70 -0
  2. package/dist/app-framework.cjs +1742 -0
  3. package/dist/app-framework.cjs.map +1 -0
  4. package/dist/app-framework.d.cts +881 -0
  5. package/dist/app-framework.d.ts +881 -2
  6. package/dist/app-framework.js +1718 -1
  7. package/dist/app-framework.js.map +1 -1
  8. package/dist/charx.cjs +917 -0
  9. package/dist/charx.cjs.map +1 -0
  10. package/dist/charx.d.cts +640 -0
  11. package/dist/charx.d.ts +640 -2
  12. package/dist/charx.js +893 -1
  13. package/dist/charx.js.map +1 -1
  14. package/dist/core.cjs +668 -0
  15. package/dist/core.cjs.map +1 -0
  16. package/dist/core.d.cts +363 -0
  17. package/dist/core.d.ts +363 -2
  18. package/dist/core.js +644 -1
  19. package/dist/core.js.map +1 -1
  20. package/dist/exporter.cjs +7539 -0
  21. package/dist/exporter.cjs.map +1 -0
  22. package/dist/exporter.d.cts +681 -0
  23. package/dist/exporter.d.ts +681 -2
  24. package/dist/exporter.js +7522 -1
  25. package/dist/exporter.js.map +1 -1
  26. package/dist/federation.cjs +3915 -0
  27. package/dist/federation.cjs.map +1 -0
  28. package/dist/federation.d.cts +2951 -0
  29. package/dist/federation.d.ts +2951 -2
  30. package/dist/federation.js +3891 -1
  31. package/dist/federation.js.map +1 -1
  32. package/dist/index.cjs +9109 -0
  33. package/dist/index.cjs.map +1 -0
  34. package/dist/index.d.cts +1119 -0
  35. package/dist/index.d.ts +1113 -20
  36. package/dist/index.js +9092 -26
  37. package/dist/index.js.map +1 -1
  38. package/dist/loader.cjs +8923 -0
  39. package/dist/loader.cjs.map +1 -0
  40. package/dist/loader.d.cts +1037 -0
  41. package/dist/loader.d.ts +1037 -2
  42. package/dist/loader.js +8906 -1
  43. package/dist/loader.js.map +1 -1
  44. package/dist/lorebook.cjs +865 -0
  45. package/dist/lorebook.cjs.map +1 -0
  46. package/dist/lorebook.d.cts +1008 -0
  47. package/dist/lorebook.d.ts +1008 -2
  48. package/dist/lorebook.js +841 -1
  49. package/dist/lorebook.js.map +1 -1
  50. package/dist/media.cjs +6660 -0
  51. package/dist/media.cjs.map +1 -0
  52. package/dist/media.d.cts +87 -0
  53. package/dist/media.d.ts +87 -2
  54. package/dist/media.js +6643 -1
  55. package/dist/media.js.map +1 -1
  56. package/dist/normalizer.cjs +502 -0
  57. package/dist/normalizer.cjs.map +1 -0
  58. package/dist/normalizer.d.cts +1216 -0
  59. package/dist/normalizer.d.ts +1216 -2
  60. package/dist/normalizer.js +478 -1
  61. package/dist/normalizer.js.map +1 -1
  62. package/dist/png.cjs +778 -0
  63. package/dist/png.cjs.map +1 -0
  64. package/dist/png.d.cts +786 -0
  65. package/dist/png.d.ts +786 -2
  66. package/dist/png.js +754 -1
  67. package/dist/png.js.map +1 -1
  68. package/dist/schemas.cjs +799 -0
  69. package/dist/schemas.cjs.map +1 -0
  70. package/dist/schemas.d.cts +2178 -0
  71. package/dist/schemas.d.ts +2178 -2
  72. package/dist/schemas.js +775 -1
  73. package/dist/schemas.js.map +1 -1
  74. package/dist/tokenizers.cjs +153 -0
  75. package/dist/tokenizers.cjs.map +1 -0
  76. package/dist/tokenizers.d.cts +155 -0
  77. package/dist/tokenizers.d.ts +155 -2
  78. package/dist/tokenizers.js +129 -1
  79. package/dist/tokenizers.js.map +1 -1
  80. package/dist/voxta.cjs +7995 -0
  81. package/dist/voxta.cjs.map +1 -0
  82. package/dist/voxta.d.cts +1349 -0
  83. package/dist/voxta.d.ts +1349 -2
  84. package/dist/voxta.js +7978 -1
  85. package/dist/voxta.js.map +1 -1
  86. package/package.json +177 -45
  87. package/dist/app-framework.d.ts.map +0 -1
  88. package/dist/charx.d.ts.map +0 -1
  89. package/dist/core.d.ts.map +0 -1
  90. package/dist/exporter.d.ts.map +0 -1
  91. package/dist/federation.d.ts.map +0 -1
  92. package/dist/index.d.ts.map +0 -1
  93. package/dist/loader.d.ts.map +0 -1
  94. package/dist/lorebook.d.ts.map +0 -1
  95. package/dist/media.d.ts.map +0 -1
  96. package/dist/normalizer.d.ts.map +0 -1
  97. package/dist/png.d.ts.map +0 -1
  98. package/dist/schemas.d.ts.map +0 -1
  99. package/dist/tokenizers.d.ts.map +0 -1
  100. package/dist/voxta.d.ts.map +0 -1
package/dist/core.js CHANGED
@@ -1,2 +1,645 @@
1
- export * from '@character-foundry/core';
1
+ // ../core/dist/index.js
2
+ function readUInt32BE(data, offset) {
3
+ return (data[offset] << 24 | data[offset + 1] << 16 | data[offset + 2] << 8 | data[offset + 3]) >>> 0;
4
+ }
5
+ function writeUInt32BE(data, value, offset) {
6
+ data[offset] = value >>> 24 & 255;
7
+ data[offset + 1] = value >>> 16 & 255;
8
+ data[offset + 2] = value >>> 8 & 255;
9
+ data[offset + 3] = value & 255;
10
+ }
11
+ function readUInt16BE(data, offset) {
12
+ return (data[offset] << 8 | data[offset + 1]) >>> 0;
13
+ }
14
+ function writeUInt16BE(data, value, offset) {
15
+ data[offset] = value >>> 8 & 255;
16
+ data[offset + 1] = value & 255;
17
+ }
18
+ function indexOf(data, search, fromIndex = 0) {
19
+ outer: for (let i = fromIndex; i <= data.length - search.length; i++) {
20
+ for (let j = 0; j < search.length; j++) {
21
+ if (data[i + j] !== search[j]) continue outer;
22
+ }
23
+ return i;
24
+ }
25
+ return -1;
26
+ }
27
+ function concat(...arrays) {
28
+ const totalLength = arrays.reduce((sum, arr) => sum + arr.length, 0);
29
+ const result = new Uint8Array(totalLength);
30
+ let offset = 0;
31
+ for (const arr of arrays) {
32
+ result.set(arr, offset);
33
+ offset += arr.length;
34
+ }
35
+ return result;
36
+ }
37
+ function slice(data, start, end) {
38
+ return data.subarray(start, end);
39
+ }
40
+ function copy(data, start, end) {
41
+ return data.slice(start, end);
42
+ }
43
+ function fromString(str) {
44
+ return new TextEncoder().encode(str);
45
+ }
46
+ function toString(data) {
47
+ return new TextDecoder().decode(data);
48
+ }
49
+ function fromLatin1(str) {
50
+ const result = new Uint8Array(str.length);
51
+ for (let i = 0; i < str.length; i++) {
52
+ result[i] = str.charCodeAt(i) & 255;
53
+ }
54
+ return result;
55
+ }
56
+ function toLatin1(data) {
57
+ let result = "";
58
+ for (let i = 0; i < data.length; i++) {
59
+ result += String.fromCharCode(data[i]);
60
+ }
61
+ return result;
62
+ }
63
+ function equals(a, b) {
64
+ if (a.length !== b.length) return false;
65
+ for (let i = 0; i < a.length; i++) {
66
+ if (a[i] !== b[i]) return false;
67
+ }
68
+ return true;
69
+ }
70
+ function alloc(size) {
71
+ return new Uint8Array(size);
72
+ }
73
+ function from(data) {
74
+ if (data instanceof Uint8Array) {
75
+ return data;
76
+ }
77
+ if (data instanceof ArrayBuffer) {
78
+ return new Uint8Array(data);
79
+ }
80
+ return new Uint8Array(data);
81
+ }
82
+ function isBinaryData(value) {
83
+ return value instanceof Uint8Array;
84
+ }
85
+ function toUint8Array(data) {
86
+ if (data instanceof Uint8Array) {
87
+ if (Object.getPrototypeOf(data).constructor.name === "Buffer") {
88
+ return new Uint8Array(data.buffer, data.byteOffset, data.byteLength);
89
+ }
90
+ return data;
91
+ }
92
+ return new Uint8Array(data);
93
+ }
94
+ function toHex(data) {
95
+ return Array.from(data).map((b) => b.toString(16).padStart(2, "0")).join("");
96
+ }
97
+ function fromHex(hex) {
98
+ const bytes = new Uint8Array(hex.length / 2);
99
+ for (let i = 0; i < bytes.length; i++) {
100
+ bytes[i] = parseInt(hex.substr(i * 2, 2), 16);
101
+ }
102
+ return bytes;
103
+ }
104
+ var isNode = typeof process !== "undefined" && process.versions != null && process.versions.node != null;
105
+ function encode(data) {
106
+ if (isNode) {
107
+ return Buffer.from(data).toString("base64");
108
+ }
109
+ let binary = "";
110
+ for (let i = 0; i < data.length; i++) {
111
+ binary += String.fromCharCode(data[i]);
112
+ }
113
+ return btoa(binary);
114
+ }
115
+ function decode(base64) {
116
+ if (isNode) {
117
+ return new Uint8Array(Buffer.from(base64, "base64"));
118
+ }
119
+ const binary = atob(base64);
120
+ const result = new Uint8Array(binary.length);
121
+ for (let i = 0; i < binary.length; i++) {
122
+ result[i] = binary.charCodeAt(i);
123
+ }
124
+ return result;
125
+ }
126
+ function isBase64(str) {
127
+ if (str.length === 0) return false;
128
+ const base64Regex = /^[A-Za-z0-9+/]*={0,2}$/;
129
+ return base64Regex.test(str) && str.length % 4 === 0;
130
+ }
131
+ function encodeUrlSafe(data) {
132
+ return encode(data).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
133
+ }
134
+ function decodeUrlSafe(base64) {
135
+ let padded = base64.replace(/-/g, "+").replace(/_/g, "/");
136
+ while (padded.length % 4 !== 0) {
137
+ padded += "=";
138
+ }
139
+ return decode(padded);
140
+ }
141
+ var ENCODE_CHUNK_SIZE = 64 * 1024;
142
+ function encodeChunked(data) {
143
+ if (isNode) {
144
+ return Buffer.from(data).toString("base64");
145
+ }
146
+ const chunks = [];
147
+ for (let i = 0; i < data.length; i += ENCODE_CHUNK_SIZE) {
148
+ const chunk = data.subarray(i, Math.min(i + ENCODE_CHUNK_SIZE, data.length));
149
+ let binary = "";
150
+ for (let j = 0; j < chunk.length; j++) {
151
+ binary += String.fromCharCode(chunk[j]);
152
+ }
153
+ chunks.push(binary);
154
+ }
155
+ return btoa(chunks.join(""));
156
+ }
157
+ var FOUNDRY_ERROR_MARKER = /* @__PURE__ */ Symbol.for("@character-foundry/core:FoundryError");
158
+ var FoundryError = class extends Error {
159
+ constructor(message, code) {
160
+ super(message);
161
+ this.code = code;
162
+ this.name = "FoundryError";
163
+ if (Error.captureStackTrace) {
164
+ Error.captureStackTrace(this, this.constructor);
165
+ }
166
+ }
167
+ /** @internal Marker for cross-module identification */
168
+ [FOUNDRY_ERROR_MARKER] = true;
169
+ };
170
+ var ParseError = class extends FoundryError {
171
+ constructor(message, format) {
172
+ super(message, "PARSE_ERROR");
173
+ this.format = format;
174
+ this.name = "ParseError";
175
+ }
176
+ };
177
+ var ValidationError = class extends FoundryError {
178
+ constructor(message, field) {
179
+ super(message, "VALIDATION_ERROR");
180
+ this.field = field;
181
+ this.name = "ValidationError";
182
+ }
183
+ };
184
+ var AssetNotFoundError = class extends FoundryError {
185
+ constructor(uri) {
186
+ super(`Asset not found: ${uri}`, "ASSET_NOT_FOUND");
187
+ this.uri = uri;
188
+ this.name = "AssetNotFoundError";
189
+ }
190
+ };
191
+ var FormatNotSupportedError = class extends FoundryError {
192
+ constructor(format, operation) {
193
+ const msg = operation ? `Format '${format}' not supported for ${operation}` : `Format not supported: ${format}`;
194
+ super(msg, "FORMAT_NOT_SUPPORTED");
195
+ this.format = format;
196
+ this.name = "FormatNotSupportedError";
197
+ }
198
+ };
199
+ var SizeLimitError = class extends FoundryError {
200
+ constructor(actualSize, maxSize, context) {
201
+ const actualMB = (actualSize / 1024 / 1024).toFixed(2);
202
+ const maxMB = (maxSize / 1024 / 1024).toFixed(2);
203
+ const msg = context ? `${context}: Size ${actualMB}MB exceeds limit ${maxMB}MB` : `Size ${actualMB}MB exceeds limit ${maxMB}MB`;
204
+ super(msg, "SIZE_LIMIT_EXCEEDED");
205
+ this.actualSize = actualSize;
206
+ this.maxSize = maxSize;
207
+ this.name = "SizeLimitError";
208
+ }
209
+ };
210
+ var PathTraversalError = class extends FoundryError {
211
+ constructor(path) {
212
+ super(`Unsafe path detected: ${path}`, "PATH_TRAVERSAL");
213
+ this.path = path;
214
+ this.name = "PathTraversalError";
215
+ }
216
+ };
217
+ var DataLossError = class extends FoundryError {
218
+ constructor(lostFields, targetFormat) {
219
+ const fields = lostFields.slice(0, 3).join(", ");
220
+ const more = lostFields.length > 3 ? ` and ${lostFields.length - 3} more` : "";
221
+ super(
222
+ `Export to ${targetFormat} would lose: ${fields}${more}`,
223
+ "DATA_LOSS"
224
+ );
225
+ this.lostFields = lostFields;
226
+ this.targetFormat = targetFormat;
227
+ this.name = "DataLossError";
228
+ }
229
+ };
230
+ function isFoundryError(error) {
231
+ return error instanceof Error && FOUNDRY_ERROR_MARKER in error && error[FOUNDRY_ERROR_MARKER] === true;
232
+ }
233
+ function wrapError(error, context) {
234
+ if (isFoundryError(error)) {
235
+ return error;
236
+ }
237
+ const message = error instanceof Error ? error.message : String(error);
238
+ return new FoundryError(
239
+ context ? `${context}: ${message}` : message,
240
+ "UNKNOWN_ERROR"
241
+ );
242
+ }
243
+ function toDataURL(buffer, mimeType) {
244
+ const base64 = encodeChunked(buffer);
245
+ return `data:${mimeType};base64,${base64}`;
246
+ }
247
+ function fromDataURL(dataUrl) {
248
+ if (!dataUrl.startsWith("data:")) {
249
+ throw new ValidationError('Invalid data URL: must start with "data:"', "dataUrl");
250
+ }
251
+ const commaIndex = dataUrl.indexOf(",");
252
+ if (commaIndex === -1) {
253
+ throw new ValidationError("Invalid data URL: missing comma separator", "dataUrl");
254
+ }
255
+ const header = dataUrl.slice(5, commaIndex);
256
+ const data = dataUrl.slice(commaIndex + 1);
257
+ let mimeType = "text/plain";
258
+ let isBase642 = false;
259
+ const parts = header.split(";");
260
+ for (const part of parts) {
261
+ if (part === "base64") {
262
+ isBase642 = true;
263
+ } else if (part && !part.includes("=")) {
264
+ mimeType = part;
265
+ }
266
+ }
267
+ if (!isBase642) {
268
+ throw new ValidationError("Non-base64 data URLs are not supported", "dataUrl");
269
+ }
270
+ const buffer = decode(data);
271
+ return { buffer, mimeType };
272
+ }
273
+ function isDataURL(str) {
274
+ if (!str.startsWith("data:")) return false;
275
+ const commaIndex = str.indexOf(",");
276
+ if (commaIndex === -1) return false;
277
+ const header = str.slice(5, commaIndex);
278
+ return header.includes("base64");
279
+ }
280
+ function normalizeURI(uri) {
281
+ const trimmed = uri.trim();
282
+ if (trimmed.startsWith("embedded://")) {
283
+ return "embeded://" + trimmed.substring("embedded://".length);
284
+ }
285
+ if (trimmed.startsWith("__asset:")) {
286
+ const id = trimmed.substring("__asset:".length);
287
+ return `pngchunk:${id}`;
288
+ }
289
+ if (trimmed.startsWith("asset:")) {
290
+ const id = trimmed.substring("asset:".length);
291
+ return `pngchunk:${id}`;
292
+ }
293
+ if (trimmed.startsWith("chara-ext-asset_:")) {
294
+ const id = trimmed.substring("chara-ext-asset_:".length);
295
+ return `pngchunk:${id}`;
296
+ }
297
+ if (trimmed.startsWith("chara-ext-asset_")) {
298
+ const id = trimmed.substring("chara-ext-asset_".length);
299
+ return `pngchunk:${id}`;
300
+ }
301
+ return trimmed;
302
+ }
303
+ function parseURI(uri) {
304
+ const trimmed = uri.trim();
305
+ const normalized = normalizeURI(trimmed);
306
+ if (trimmed.startsWith("__asset:") || trimmed.startsWith("asset:") || trimmed.startsWith("chara-ext-asset_") || trimmed.startsWith("pngchunk:")) {
307
+ let assetId;
308
+ if (trimmed.startsWith("__asset:")) {
309
+ assetId = trimmed.substring("__asset:".length);
310
+ } else if (trimmed.startsWith("asset:")) {
311
+ assetId = trimmed.substring("asset:".length);
312
+ } else if (trimmed.startsWith("chara-ext-asset_:")) {
313
+ assetId = trimmed.substring("chara-ext-asset_:".length);
314
+ } else if (trimmed.startsWith("pngchunk:")) {
315
+ assetId = trimmed.substring("pngchunk:".length);
316
+ } else {
317
+ assetId = trimmed.substring("chara-ext-asset_".length);
318
+ }
319
+ const candidates = [
320
+ assetId,
321
+ // "0" or "filename.png"
322
+ trimmed,
323
+ // Original URI
324
+ `asset:${assetId}`,
325
+ // "asset:0"
326
+ `__asset:${assetId}`,
327
+ // "__asset:0"
328
+ `__asset_${assetId}`,
329
+ // "__asset_0"
330
+ `chara-ext-asset_${assetId}`,
331
+ // "chara-ext-asset_0"
332
+ `chara-ext-asset_:${assetId}`,
333
+ // "chara-ext-asset_:0"
334
+ `pngchunk:${assetId}`
335
+ // "pngchunk:0"
336
+ ];
337
+ return {
338
+ scheme: "pngchunk",
339
+ originalUri: uri,
340
+ normalizedUri: normalized,
341
+ chunkKey: assetId,
342
+ chunkCandidates: candidates
343
+ };
344
+ }
345
+ if (trimmed === "ccdefault:" || trimmed.startsWith("ccdefault:")) {
346
+ return {
347
+ scheme: "ccdefault",
348
+ originalUri: uri,
349
+ normalizedUri: normalized
350
+ };
351
+ }
352
+ if (trimmed.startsWith("embeded://") || trimmed.startsWith("embedded://")) {
353
+ const path = trimmed.startsWith("embeded://") ? trimmed.substring("embeded://".length) : trimmed.substring("embedded://".length);
354
+ return {
355
+ scheme: "embeded",
356
+ originalUri: uri,
357
+ normalizedUri: normalized,
358
+ path
359
+ };
360
+ }
361
+ if (trimmed.startsWith("https://")) {
362
+ return {
363
+ scheme: "https",
364
+ originalUri: uri,
365
+ normalizedUri: normalized,
366
+ url: trimmed
367
+ };
368
+ }
369
+ if (trimmed.startsWith("http://")) {
370
+ return {
371
+ scheme: "http",
372
+ originalUri: uri,
373
+ normalizedUri: normalized,
374
+ url: trimmed
375
+ };
376
+ }
377
+ if (trimmed.startsWith("data:")) {
378
+ const parsed = parseDataURI(trimmed);
379
+ return {
380
+ scheme: "data",
381
+ originalUri: uri,
382
+ normalizedUri: normalized,
383
+ ...parsed
384
+ };
385
+ }
386
+ if (trimmed.startsWith("file://")) {
387
+ const path = trimmed.substring("file://".length);
388
+ return {
389
+ scheme: "file",
390
+ originalUri: uri,
391
+ normalizedUri: normalized,
392
+ path
393
+ };
394
+ }
395
+ if (/^[a-zA-Z0-9_-]+$/.test(trimmed)) {
396
+ return {
397
+ scheme: "internal",
398
+ originalUri: uri,
399
+ normalizedUri: normalized,
400
+ path: trimmed
401
+ };
402
+ }
403
+ return {
404
+ scheme: "unknown",
405
+ originalUri: uri,
406
+ normalizedUri: normalized
407
+ };
408
+ }
409
+ function parseDataURI(uri) {
410
+ const match = uri.match(/^data:([^;,]+)?(;base64)?,(.*)$/);
411
+ if (!match) {
412
+ return {};
413
+ }
414
+ return {
415
+ mimeType: match[1] || "text/plain",
416
+ encoding: match[2] ? "base64" : void 0,
417
+ data: match[3]
418
+ };
419
+ }
420
+ function isImageExt(ext) {
421
+ const imageExts = ["png", "jpg", "jpeg", "webp", "gif", "avif", "bmp", "svg"];
422
+ return imageExts.includes(ext.toLowerCase());
423
+ }
424
+ function isAudioExt(ext) {
425
+ const audioExts = ["mp3", "wav", "ogg", "flac", "m4a", "aac"];
426
+ return audioExts.includes(ext.toLowerCase());
427
+ }
428
+ function isVideoExt(ext) {
429
+ const videoExts = ["mp4", "webm", "avi", "mov", "mkv"];
430
+ return videoExts.includes(ext.toLowerCase());
431
+ }
432
+ function isURISafe(uri, options = {}) {
433
+ const parsed = parseURI(uri);
434
+ switch (parsed.scheme) {
435
+ case "embeded":
436
+ case "ccdefault":
437
+ case "internal":
438
+ case "data":
439
+ case "https":
440
+ case "pngchunk":
441
+ return true;
442
+ case "http":
443
+ return options.allowHttp === true;
444
+ case "file":
445
+ return options.allowFile === true;
446
+ case "unknown":
447
+ default:
448
+ return false;
449
+ }
450
+ }
451
+ function getExtensionFromURI(uri) {
452
+ const parsed = parseURI(uri);
453
+ if (parsed.path) {
454
+ const parts = parsed.path.split(".");
455
+ if (parts.length > 1) {
456
+ return parts[parts.length - 1].toLowerCase();
457
+ }
458
+ }
459
+ if (parsed.url) {
460
+ const urlParts = parsed.url.split("?")[0].split(".");
461
+ if (urlParts.length > 1) {
462
+ return urlParts[urlParts.length - 1].toLowerCase();
463
+ }
464
+ }
465
+ if (parsed.mimeType) {
466
+ return getExtFromMimeType(parsed.mimeType);
467
+ }
468
+ return "unknown";
469
+ }
470
+ function getMimeTypeFromExt(ext) {
471
+ const extToMime = {
472
+ // Images
473
+ "png": "image/png",
474
+ "jpg": "image/jpeg",
475
+ "jpeg": "image/jpeg",
476
+ "webp": "image/webp",
477
+ "gif": "image/gif",
478
+ "avif": "image/avif",
479
+ "svg": "image/svg+xml",
480
+ "bmp": "image/bmp",
481
+ "ico": "image/x-icon",
482
+ // Audio
483
+ "mp3": "audio/mpeg",
484
+ "wav": "audio/wav",
485
+ "ogg": "audio/ogg",
486
+ "flac": "audio/flac",
487
+ "m4a": "audio/mp4",
488
+ "aac": "audio/aac",
489
+ // Video
490
+ "mp4": "video/mp4",
491
+ "webm": "video/webm",
492
+ "avi": "video/x-msvideo",
493
+ "mov": "video/quicktime",
494
+ "mkv": "video/x-matroska",
495
+ // Text/Data
496
+ "json": "application/json",
497
+ "txt": "text/plain",
498
+ "html": "text/html",
499
+ "css": "text/css",
500
+ "js": "application/javascript"
501
+ };
502
+ return extToMime[ext.toLowerCase()] || "application/octet-stream";
503
+ }
504
+ function getExtFromMimeType(mimeType) {
505
+ const mimeToExt = {
506
+ "image/png": "png",
507
+ "image/jpeg": "jpg",
508
+ "image/webp": "webp",
509
+ "image/gif": "gif",
510
+ "image/avif": "avif",
511
+ "image/svg+xml": "svg",
512
+ "image/bmp": "bmp",
513
+ "image/x-icon": "ico",
514
+ "audio/mpeg": "mp3",
515
+ "audio/wav": "wav",
516
+ "audio/ogg": "ogg",
517
+ "audio/flac": "flac",
518
+ "audio/mp4": "m4a",
519
+ "audio/aac": "aac",
520
+ "video/mp4": "mp4",
521
+ "video/webm": "webm",
522
+ "video/x-msvideo": "avi",
523
+ "video/quicktime": "mov",
524
+ "video/x-matroska": "mkv",
525
+ "application/json": "json",
526
+ "text/plain": "txt",
527
+ "text/html": "html",
528
+ "text/css": "css",
529
+ "application/javascript": "js"
530
+ };
531
+ return mimeToExt[mimeType] || "bin";
532
+ }
533
+ function buildDataURI(data, mimeType, isBase642 = true) {
534
+ if (isBase642) {
535
+ return `data:${mimeType};base64,${data}`;
536
+ }
537
+ return `data:${mimeType},${encodeURIComponent(data)}`;
538
+ }
539
+ function isAnimatedImage(data, mimeType) {
540
+ if (data.length > 12 && data[0] === 82 && data[1] === 73 && data[2] === 70 && data[3] === 70 && // RIFF
541
+ data[8] === 87 && data[9] === 69 && data[10] === 66 && data[11] === 80) {
542
+ if (data[12] === 86 && data[13] === 80 && data[14] === 56 && data[15] === 88) {
543
+ const flags = data[20];
544
+ return (flags & 2) !== 0;
545
+ }
546
+ return false;
547
+ }
548
+ if (data.length > 8 && data[0] === 137 && data[1] === 80 && data[2] === 78 && data[3] === 71) {
549
+ const actlSig = fromLatin1("acTL");
550
+ const idatSig = fromLatin1("IDAT");
551
+ const actlIndex = indexOf(data, actlSig);
552
+ if (actlIndex === -1) return false;
553
+ const idatIndex = indexOf(data, idatSig);
554
+ return idatIndex === -1 || actlIndex < idatIndex;
555
+ }
556
+ if (data.length > 6 && data[0] === 71 && data[1] === 73 && data[2] === 70) {
557
+ const netscape = fromLatin1("NETSCAPE2.0");
558
+ return indexOf(data, netscape) !== -1;
559
+ }
560
+ return false;
561
+ }
562
+ function formatUUID(bytes) {
563
+ const hex = Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
564
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;
565
+ }
566
+ function mathRandomUUID() {
567
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
568
+ const r = Math.random() * 16 | 0;
569
+ const v = c === "x" ? r : r & 3 | 8;
570
+ return v.toString(16);
571
+ });
572
+ }
573
+ function generateUUID() {
574
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
575
+ return crypto.randomUUID();
576
+ }
577
+ if (typeof crypto !== "undefined" && typeof crypto.getRandomValues === "function") {
578
+ const bytes = new Uint8Array(16);
579
+ crypto.getRandomValues(bytes);
580
+ bytes[6] = bytes[6] & 15 | 64;
581
+ bytes[8] = bytes[8] & 63 | 128;
582
+ return formatUUID(bytes);
583
+ }
584
+ if (typeof process !== "undefined" && process.env?.NODE_ENV === "development") {
585
+ console.warn("[character-foundry/core] generateUUID: Using insecure Math.random() fallback");
586
+ }
587
+ return mathRandomUUID();
588
+ }
589
+ function isValidUUID(uuid) {
590
+ return /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(uuid);
591
+ }
592
+ export {
593
+ AssetNotFoundError,
594
+ DataLossError,
595
+ FormatNotSupportedError,
596
+ FoundryError,
597
+ ParseError,
598
+ PathTraversalError,
599
+ SizeLimitError,
600
+ ValidationError,
601
+ alloc,
602
+ decode as base64Decode,
603
+ decodeUrlSafe as base64DecodeUrlSafe,
604
+ encode as base64Encode,
605
+ encodeChunked as base64EncodeChunked,
606
+ encodeUrlSafe as base64EncodeUrlSafe,
607
+ buildDataURI,
608
+ concat,
609
+ copy,
610
+ equals,
611
+ from,
612
+ fromDataURL,
613
+ fromHex,
614
+ fromLatin1,
615
+ fromString,
616
+ generateUUID,
617
+ getExtFromMimeType,
618
+ getExtensionFromURI,
619
+ getMimeTypeFromExt,
620
+ indexOf,
621
+ isAnimatedImage,
622
+ isAudioExt,
623
+ isBase64,
624
+ isBinaryData,
625
+ isDataURL,
626
+ isFoundryError,
627
+ isImageExt,
628
+ isURISafe,
629
+ isValidUUID,
630
+ isVideoExt,
631
+ normalizeURI,
632
+ parseURI,
633
+ readUInt16BE,
634
+ readUInt32BE,
635
+ slice,
636
+ toDataURL,
637
+ toHex,
638
+ toLatin1,
639
+ toString,
640
+ toUint8Array,
641
+ wrapError,
642
+ writeUInt16BE,
643
+ writeUInt32BE
644
+ };
2
645
  //# sourceMappingURL=core.js.map