taglib-wasm 1.8.3 → 2.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.
Files changed (71) hide show
  1. package/README.md +8 -1
  2. package/dist/disc-folder.d.ts +19 -0
  3. package/dist/disc-folder.d.ts.map +1 -0
  4. package/dist/disc-folder.js +550 -0
  5. package/dist/index.browser.d.ts +3 -4
  6. package/dist/index.browser.d.ts.map +1 -1
  7. package/dist/index.browser.js +171 -173
  8. package/dist/index.d.ts +3 -4
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +1 -13
  11. package/dist/simple.browser.js +164 -30
  12. package/dist/src/constants/complex-properties.d.ts +0 -114
  13. package/dist/src/constants/complex-properties.d.ts.map +1 -1
  14. package/dist/src/constants/complex-properties.js +0 -55
  15. package/dist/src/constants/index.d.ts +0 -1
  16. package/dist/src/constants/index.d.ts.map +1 -1
  17. package/dist/src/constants/index.js +0 -1
  18. package/dist/src/file-utils/import-operations.d.ts.map +1 -1
  19. package/dist/src/file-utils/import-operations.js +1 -1
  20. package/dist/src/folder-api/file-processors.d.ts.map +1 -1
  21. package/dist/src/folder-api/file-processors.js +6 -5
  22. package/dist/src/folder-api/scan-for-albums.js +3 -3
  23. package/dist/src/folder-api/scan-operations.js +2 -2
  24. package/dist/src/msgpack/decoder.d.ts.map +1 -1
  25. package/dist/src/msgpack/decoder.js +5 -6
  26. package/dist/src/msgpack/encoder.d.ts.map +1 -1
  27. package/dist/src/msgpack/encoder.js +4 -3
  28. package/dist/src/runtime/module-loader.d.ts.map +1 -1
  29. package/dist/src/runtime/module-loader.js +3 -3
  30. package/dist/src/runtime/wasi-adapter/file-handle.d.ts +8 -0
  31. package/dist/src/runtime/wasi-adapter/file-handle.d.ts.map +1 -1
  32. package/dist/src/runtime/wasi-adapter/file-handle.js +32 -1
  33. package/dist/src/simple/batch-operations.d.ts.map +1 -1
  34. package/dist/src/simple/batch-operations.js +14 -10
  35. package/dist/src/simple/picture-operations.js +1 -1
  36. package/dist/src/taglib/audio-file-base.d.ts +15 -9
  37. package/dist/src/taglib/audio-file-base.d.ts.map +1 -1
  38. package/dist/src/taglib/audio-file-base.js +35 -4
  39. package/dist/src/taglib/audio-file-impl.d.ts +2 -2
  40. package/dist/src/taglib/audio-file-impl.d.ts.map +1 -1
  41. package/dist/src/taglib/audio-file-impl.js +25 -13
  42. package/dist/src/taglib/audio-file-interface.d.ts +27 -6
  43. package/dist/src/taglib/audio-file-interface.d.ts.map +1 -1
  44. package/dist/src/taglib/auto-dispose.d.ts +6 -0
  45. package/dist/src/taglib/auto-dispose.d.ts.map +1 -0
  46. package/dist/src/taglib/auto-dispose.js +13 -0
  47. package/dist/src/taglib/embind-adapter.d.ts +2 -2
  48. package/dist/src/taglib/embind-adapter.d.ts.map +1 -1
  49. package/dist/src/taglib/embind-adapter.js +17 -0
  50. package/dist/src/taglib/extra-state-registry.d.ts.map +1 -1
  51. package/dist/src/taglib/extra-state-registry.js +9 -0
  52. package/dist/src/taglib/metadata-extent.d.ts.map +1 -1
  53. package/dist/src/taglib/metadata-extent.js +44 -1
  54. package/dist/src/taglib/mutable-tag.d.ts +15 -15
  55. package/dist/src/taglib/mutable-tag.d.ts.map +1 -1
  56. package/dist/src/taglib/save-reconstruct.d.ts.map +1 -1
  57. package/dist/src/taglib/taglib-class.d.ts.map +1 -1
  58. package/dist/src/types/tags.d.ts +0 -4
  59. package/dist/src/types/tags.d.ts.map +1 -1
  60. package/dist/src/version.d.ts +1 -1
  61. package/dist/src/version.js +1 -1
  62. package/dist/src/wasm.d.ts +20 -1
  63. package/dist/src/wasm.d.ts.map +1 -1
  64. package/dist/src/web-utils/canvas.d.ts.map +1 -1
  65. package/dist/src/web-utils/canvas.js +6 -1
  66. package/dist/src/web-utils/data-url.js +1 -1
  67. package/dist/taglib-wasi.wasm +0 -0
  68. package/package.json +18 -10
  69. package/dist/src/constants/tags.d.ts +0 -81
  70. package/dist/src/constants/tags.d.ts.map +0 -1
  71. package/dist/src/constants/tags.js +0 -86
@@ -1648,6 +1648,23 @@ var init_mutable_tag_impl = __esm({
1648
1648
  }
1649
1649
  });
1650
1650
 
1651
+ // src/taglib/auto-dispose.ts
1652
+ function registerAutoDispose(target, handle) {
1653
+ registry.register(target, handle, target);
1654
+ }
1655
+ function unregisterAutoDispose(target) {
1656
+ registry.unregister(target);
1657
+ }
1658
+ var registry;
1659
+ var init_auto_dispose = __esm({
1660
+ "src/taglib/auto-dispose.ts"() {
1661
+ "use strict";
1662
+ registry = new FinalizationRegistry((handle) => {
1663
+ handle.destroy();
1664
+ });
1665
+ }
1666
+ });
1667
+
1651
1668
  // src/taglib/audio-file-base.ts
1652
1669
  var LYRICS_PROPERTY_KEY, LYRICS_WIRE_KEY, EMPTY_KEY_SET, BaseAudioFileImpl;
1653
1670
  var init_audio_file_base = __esm({
@@ -1657,6 +1674,7 @@ var init_audio_file_base = __esm({
1657
1674
  init_errors2();
1658
1675
  init_mp4_item_names();
1659
1676
  init_mutable_tag_impl();
1677
+ init_auto_dispose();
1660
1678
  LYRICS_PROPERTY_KEY = "lyrics";
1661
1679
  LYRICS_WIRE_KEY = toTagLibKey(LYRICS_PROPERTY_KEY);
1662
1680
  EMPTY_KEY_SET = /* @__PURE__ */ new Set();
@@ -1677,6 +1695,7 @@ var init_audio_file_base = __esm({
1677
1695
  this.isPartiallyLoaded = isPartiallyLoaded;
1678
1696
  this.partialLoadOptions = partialLoadOptions;
1679
1697
  this.partialKeysAtLoad = isPartiallyLoaded ? new Set(Object.keys(fileHandle.getProperties())) : void 0;
1698
+ registerAutoDispose(this, fileHandle);
1680
1699
  }
1681
1700
  /**
1682
1701
  * Wire-key text properties present in the partial header at load but now
@@ -1736,16 +1755,36 @@ var init_audio_file_base = __esm({
1736
1755
  this.handle.setProperties(translated);
1737
1756
  }
1738
1757
  getProperty(key) {
1739
- const value = this.handle.getProperty(toTagLibKey(fromTagLibKey(key)));
1740
- if (value !== "") return value;
1758
+ const wireKey = toTagLibKey(fromTagLibKey(key));
1759
+ const values = this.handle.getProperties()[wireKey]?.filter(
1760
+ (v) => v !== ""
1761
+ );
1762
+ if (values !== void 0 && values.length > 0) return values;
1741
1763
  if (!this.isMP4()) return void 0;
1742
- const remapped = this.properties()[key]?.[0];
1743
- return remapped === "" ? void 0 : remapped;
1764
+ const remapped = this.properties()[key]?.filter((v) => v !== "");
1765
+ return remapped !== void 0 && remapped.length > 0 ? remapped : void 0;
1744
1766
  }
1745
1767
  setProperty(key, value) {
1746
1768
  const wireKey = toTagLibKey(fromTagLibKey(key));
1747
1769
  const atomNames = mp4FreeformAtomNames([wireKey]);
1748
1770
  if (atomNames.length > 0 && this.isMP4()) {
1771
+ if (value === "") {
1772
+ const prior = this.handle.getMp4ItemRemovals?.() ?? [];
1773
+ this.handle.setMp4ItemRemovals?.([
1774
+ .../* @__PURE__ */ new Set([...prior, ...atomNames])
1775
+ ]);
1776
+ if (this.module.isWasi) {
1777
+ this.handle.setProperties({
1778
+ ...this.handle.getProperties(),
1779
+ [wireKey]: []
1780
+ });
1781
+ } else {
1782
+ const rest = { ...this.handle.getProperties() };
1783
+ delete rest[wireKey];
1784
+ this.handle.setProperties(rest);
1785
+ }
1786
+ return;
1787
+ }
1749
1788
  this.handle.setProperties({
1750
1789
  ...this.handle.getProperties(),
1751
1790
  [wireKey]: [value],
@@ -1755,6 +1794,14 @@ var init_audio_file_base = __esm({
1755
1794
  }
1756
1795
  this.handle.setProperty(wireKey, value);
1757
1796
  }
1797
+ /**
1798
+ * The empty-string clearing contract, named (taglib-qyw2): both backends
1799
+ * remove the property when the written value is empty, and setProperty's
1800
+ * wire-key normalization + MP4 freeform atom-name handling apply unchanged.
1801
+ */
1802
+ removeProperty(key) {
1803
+ this.setProperty(key, "");
1804
+ }
1758
1805
  isMP4() {
1759
1806
  return this.handle.isMP4();
1760
1807
  }
@@ -1787,6 +1834,7 @@ var init_audio_file_base = __esm({
1787
1834
  return this.handle.isValid();
1788
1835
  }
1789
1836
  dispose() {
1837
+ unregisterAutoDispose(this);
1790
1838
  if (this.fileHandle) {
1791
1839
  this.fileHandle.destroy();
1792
1840
  this.fileHandle = null;
@@ -1860,6 +1908,7 @@ function isValidBitrateMode(value) {
1860
1908
  }
1861
1909
  function wrapEmbindHandle(raw) {
1862
1910
  const stagedId3v2Frames = {};
1911
+ let destroyed = false;
1863
1912
  const overrides = {
1864
1913
  getTagData() {
1865
1914
  const tw = raw.getTag();
@@ -1939,6 +1988,22 @@ function wrapEmbindHandle(raw) {
1939
1988
  stripId3Tags(opts) {
1940
1989
  raw.stripId3Tags(opts);
1941
1990
  },
1991
+ destroy() {
1992
+ if (destroyed) return;
1993
+ destroyed = true;
1994
+ raw.destroy();
1995
+ },
1996
+ get destroyed() {
1997
+ return destroyed;
1998
+ },
1999
+ // taglib-qyw2: the PropertyMap erase pass computes freeform item names
2000
+ // from the property table (upper-cased) and misses the restored exact-case
2001
+ // atom (taglib-bnhl), so clears queue the exact name here; the imperative
2002
+ // Embind model applies removeItem immediately, before setProperties.
2003
+ setMp4ItemRemovals(removals) {
2004
+ const handle = raw;
2005
+ for (const name of removals) handle.removeMP4Item(name);
2006
+ },
1942
2007
  getAudioProperties() {
1943
2008
  const pw = raw.getAudioProperties();
1944
2009
  if (!pw) return null;
@@ -2038,6 +2103,15 @@ var init_extra_state_registry = __esm({
2038
2103
  else if (complete) target.setIxml(null);
2039
2104
  }
2040
2105
  },
2106
+ {
2107
+ name: "_mp4ItemRemovals",
2108
+ copy(target, source, complete) {
2109
+ const v = source.getMp4ItemRemovals?.();
2110
+ if (complete || v !== void 0 && v.length > 0) {
2111
+ target.setMp4ItemRemovals?.(v ?? []);
2112
+ }
2113
+ }
2114
+ },
2041
2115
  {
2042
2116
  name: "id3v2Frames",
2043
2117
  copy(target, source) {
@@ -2226,7 +2300,7 @@ var init_audio_file_impl = __esm({
2226
2300
  mimeType: pic.mimeType,
2227
2301
  data: pic.data,
2228
2302
  type: PICTURE_TYPE_NAMES[pic.type] ?? "Other",
2229
- description: pic.description
2303
+ ...pic.description !== void 0 ? { description: pic.description } : {}
2230
2304
  }));
2231
2305
  }
2232
2306
  setPictures(pictures) {
@@ -2251,13 +2325,20 @@ var init_audio_file_impl = __esm({
2251
2325
  getChapters() {
2252
2326
  const sorted = sortChapters(this.handle.getChapters());
2253
2327
  const trackEndMs = this.audioProperties()?.durationMs;
2254
- return sorted.map((c, i) => ({
2255
- startTimeMs: c.startTimeMs,
2256
- endTimeMs: inferEndTimeMs(sorted, i, trackEndMs),
2257
- title: c.title || void 0,
2258
- id: c.id || void 0,
2259
- source: c.source
2260
- }));
2328
+ return sorted.map((c, i) => {
2329
+ const endTimeMs = inferEndTimeMs(sorted, i, trackEndMs);
2330
+ return {
2331
+ startTimeMs: c.startTimeMs,
2332
+ ...endTimeMs !== void 0 ? { endTimeMs } : {},
2333
+ // Truthiness, not !== undefined: an empty CHAP title/id must read back
2334
+ // as ABSENT (the old `c.title || undefined` contract; the Embind
2335
+ // reader emits "" unconditionally, WASI omits — coalescing keeps the
2336
+ // backends agreeing).
2337
+ ...c.title ? { title: c.title } : {},
2338
+ ...c.id ? { id: c.id } : {},
2339
+ ...c.source !== void 0 ? { source: c.source } : {}
2340
+ };
2341
+ });
2261
2342
  }
2262
2343
  setChapters(chapters, options) {
2263
2344
  const fmt = this.getFormat();
@@ -2271,10 +2352,10 @@ var init_audio_file_impl = __esm({
2271
2352
  const style = options?.mp4ChapterStyle ?? "quicktime";
2272
2353
  const source = fmt === "MP4" ? style : "id3";
2273
2354
  const raw = sorted.map((c, i) => ({
2274
- id: c.id,
2355
+ ...c.id !== void 0 ? { id: c.id } : {},
2275
2356
  startTimeMs: c.startTimeMs,
2276
2357
  endTimeMs: inferEndTimeMs(sorted, i, trackEndMs) ?? c.startTimeMs,
2277
- title: c.title,
2358
+ ...c.title !== void 0 ? { title: c.title } : {},
2278
2359
  source
2279
2360
  }));
2280
2361
  this.handle.setChapters(raw, style);
@@ -2301,8 +2382,9 @@ var init_audio_file_impl = __esm({
2301
2382
  return this.handle.getRatings().map(
2302
2383
  (r) => ({
2303
2384
  rating: r.rating,
2304
- email: r.email || void 0,
2305
- counter: r.counter || void 0
2385
+ ...r.email !== void 0 && r.email !== "" ? { email: r.email } : {},
2386
+ // 0 must read back as ABSENT (old `r.counter || undefined` contract).
2387
+ ...r.counter !== 0 ? { counter: r.counter } : {}
2306
2388
  })
2307
2389
  );
2308
2390
  }
@@ -2333,7 +2415,11 @@ var init_audio_file_impl = __esm({
2333
2415
  return ratings.length > 0 ? normalized(ratings[0].rating) : void 0;
2334
2416
  }
2335
2417
  setRating(rating, email) {
2336
- this.setRatings([{ rating, email, counter: 0 }]);
2418
+ this.setRatings([{
2419
+ rating,
2420
+ ...email !== void 0 ? { email } : {},
2421
+ counter: 0
2422
+ }]);
2337
2423
  }
2338
2424
  getId3v2Frames(id) {
2339
2425
  assertMp3(this.getFormat());
@@ -2446,7 +2532,24 @@ function isMpegFrameSync(bytes, at = 0) {
2446
2532
  if (version === 1 || layer === 0) return false;
2447
2533
  const bitrateIndex = bytes[at + 2] >> 4 & 15;
2448
2534
  const sampleRateIndex = bytes[at + 2] >> 2 & 3;
2449
- return bitrateIndex !== 0 && bitrateIndex !== 15 && sampleRateIndex !== 3;
2535
+ if (bitrateIndex === 0 || bitrateIndex === 15 || sampleRateIndex === 3) {
2536
+ return false;
2537
+ }
2538
+ const mpeg1 = version === 3;
2539
+ const layerIndex = layer ^ 3;
2540
+ const bitrate = MPEG_BITRATES[mpeg1 ? 0 : 1][layerIndex][bitrateIndex];
2541
+ const sampleRateTable = mpeg1 ? 0 : version === 2 ? 1 : 2;
2542
+ const sampleRate = MPEG_SAMPLE_RATES[sampleRateTable][sampleRateIndex];
2543
+ const samplesPerFrame = layerIndex === 2 ? mpeg1 ? 1152 : 576 : layerIndex === 1 ? 1152 : 384;
2544
+ let frameLength = Math.floor(samplesPerFrame * bitrate * 125 / sampleRate);
2545
+ if ((bytes[at + 2] & 2) !== 0) frameLength += layerIndex === 0 ? 4 : 1;
2546
+ if (frameLength === 0) return false;
2547
+ const next = at + frameLength;
2548
+ if (bytes.length < next + 4) return false;
2549
+ const mask = 4294839296;
2550
+ const header = ((bytes[at] << 24 | bytes[at + 1] << 16 | bytes[at + 2] << 8 | bytes[at + 3]) >>> 0 & mask) >>> 0;
2551
+ const nextHeader = ((bytes[next] << 24 | bytes[next + 1] << 16 | bytes[next + 2] << 8 | bytes[next + 3]) >>> 0 & mask) >>> 0;
2552
+ return header === nextHeader;
2450
2553
  }
2451
2554
  function containerEnd(bytes, at, limit) {
2452
2555
  if (at >= bytes.length) return bytes.length < limit ? null : void 0;
@@ -2489,9 +2592,36 @@ function trailerFitsInFooter(tail, footerSize) {
2489
2592
  }
2490
2593
  return true;
2491
2594
  }
2595
+ var MPEG_BITRATES, MPEG_SAMPLE_RATES;
2492
2596
  var init_metadata_extent = __esm({
2493
2597
  "src/taglib/metadata-extent.ts"() {
2494
2598
  "use strict";
2599
+ MPEG_BITRATES = [
2600
+ [
2601
+ [0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0],
2602
+ // Layer I
2603
+ [0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0],
2604
+ // Layer II
2605
+ [0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0]
2606
+ // Layer III
2607
+ ],
2608
+ [
2609
+ [0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0],
2610
+ // Layer I
2611
+ [0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0],
2612
+ // Layer II
2613
+ [0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0]
2614
+ // Layer III
2615
+ ]
2616
+ ];
2617
+ MPEG_SAMPLE_RATES = [
2618
+ [44100, 48e3, 32e3],
2619
+ // MPEG-1
2620
+ [22050, 24e3, 16e3],
2621
+ // MPEG-2
2622
+ [11025, 12e3, 8e3]
2623
+ // MPEG-2.5
2624
+ ];
2495
2625
  }
2496
2626
  });
2497
2627
 
@@ -2763,7 +2893,7 @@ var VERSION;
2763
2893
  var init_version = __esm({
2764
2894
  "src/version.ts"() {
2765
2895
  "use strict";
2766
- VERSION = "1.8.3";
2896
+ VERSION = "2.0.0";
2767
2897
  }
2768
2898
  });
2769
2899
 
@@ -3236,7 +3366,7 @@ async function readPictureMetadata(file) {
3236
3366
  return pictures.map((pic) => ({
3237
3367
  type: pic.type,
3238
3368
  mimeType: pic.mimeType,
3239
- description: pic.description,
3369
+ ...pic.description !== void 0 ? { description: pic.description } : {},
3240
3370
  size: pic.data.length
3241
3371
  }));
3242
3372
  }
@@ -3310,10 +3440,10 @@ function extractDynamics(audioFile) {
3310
3440
  "replayGainAlbumPeak"
3311
3441
  ];
3312
3442
  for (const field of fields) {
3313
- const val = audioFile.getProperty(field);
3314
- if (val) dynamics[field] = val;
3443
+ const val = audioFile.getProperty(field)?.[0];
3444
+ if (val !== void 0) dynamics[field] = val;
3315
3445
  }
3316
- let appleSoundCheck = audioFile.getProperty("appleSoundCheck");
3446
+ let appleSoundCheck = audioFile.getProperty("appleSoundCheck")?.[0];
3317
3447
  if (!appleSoundCheck && audioFile.isMP4()) {
3318
3448
  appleSoundCheck = audioFile.getMP4Item("----:com.apple.iTunes:iTunNORM");
3319
3449
  }
@@ -3339,23 +3469,27 @@ async function readMetadata(file) {
3339
3469
  `File may be corrupted or in an unsupported format. File: ${name}`
3340
3470
  );
3341
3471
  }
3472
+ const dynamics = extractDynamics(audioFile);
3342
3473
  return {
3343
3474
  tags: readExtendedTag(audioFile),
3344
3475
  properties: audioFile.audioProperties(),
3345
3476
  hasCoverArt: audioFile.getPictures().length > 0,
3346
- dynamics: extractDynamics(audioFile)
3477
+ ...dynamics !== void 0 ? { dynamics } : {}
3347
3478
  };
3348
3479
  } finally {
3349
3480
  audioFile.dispose();
3350
3481
  }
3351
3482
  }
3352
3483
  async function readMetadataBatch(files, options = {}) {
3353
- return executeBatch(files, options, (audioFile) => ({
3354
- tags: readExtendedTag(audioFile),
3355
- properties: audioFile.audioProperties(),
3356
- hasCoverArt: audioFile.getPictures().length > 0,
3357
- dynamics: extractDynamics(audioFile)
3358
- }));
3484
+ return executeBatch(files, options, (audioFile) => {
3485
+ const dynamics = extractDynamics(audioFile);
3486
+ return {
3487
+ tags: readExtendedTag(audioFile),
3488
+ properties: audioFile.audioProperties(),
3489
+ hasCoverArt: audioFile.getPictures().length > 0,
3490
+ ...dynamics !== void 0 ? { dynamics } : {}
3491
+ };
3492
+ });
3359
3493
  }
3360
3494
 
3361
3495
  // src/simple/index.ts
@@ -21,8 +21,6 @@
21
21
  * file.setRatings([{ rating: 0.8, email: "user@example.com" }]);
22
22
  * ```
23
23
  */
24
- import type { Picture } from "../types.js";
25
- import type { Chapter } from "../types/chapters.js";
26
24
  /**
27
25
  * Rating metadata representing track popularity/rating.
28
26
  * Uses normalized 0.0-1.0 scale for cross-format compatibility.
@@ -76,116 +74,4 @@ export interface UnsyncedLyrics {
76
74
  * Used as escape hatch when type is not known at compile time.
77
75
  */
78
76
  export type VariantMap = Record<string, unknown>;
79
- /**
80
- * Type map linking complex property keys to their value types.
81
- *
82
- * This is a descriptive type map, not the accessor surface — each complex
83
- * property is reached through its own typed method:
84
- *
85
- * @example
86
- * ```typescript
87
- * const ratings = file.getRatings(); // Rating[]
88
- * const pictures = file.getPictures(); // Picture[]
89
- * const chapters = file.getChapters(); // Chapter[]
90
- * ```
91
- *
92
- * Consumers can extend via module augmentation:
93
- * ```typescript
94
- * declare module "taglib-wasm" {
95
- * interface ComplexPropertyValueMap {
96
- * MY_CUSTOM: { foo: string };
97
- * }
98
- * }
99
- * ```
100
- */
101
- export interface ComplexPropertyValueMap {
102
- /** Cover art and embedded images */
103
- PICTURE: Picture;
104
- /** Track/album rating (normalized 0.0-1.0) */
105
- RATING: Rating;
106
- /** Unsynchronized lyrics text */
107
- LYRICS: UnsyncedLyrics;
108
- /** Chapter markers (ID3v2 CHAP frames) */
109
- CHAPTER: Chapter;
110
- }
111
- /**
112
- * Union type of all valid complex property keys.
113
- */
114
- export type ComplexPropertyKey = keyof ComplexPropertyValueMap;
115
- /**
116
- * Rich metadata object for complex properties.
117
- * Contains descriptions, format support info, and underlying format mappings.
118
- *
119
- * Use this for introspection, documentation, or format-aware operations.
120
- */
121
- export declare const COMPLEX_PROPERTIES: {
122
- readonly PICTURE: {
123
- readonly key: "PICTURE";
124
- readonly description: "Embedded album art or images";
125
- readonly type: "binary";
126
- readonly supportedFormats: readonly ["ID3v2", "MP4", "Vorbis", "FLAC"];
127
- readonly mappings: {
128
- readonly id3v2: {
129
- readonly frame: "APIC";
130
- };
131
- readonly mp4: "covr";
132
- readonly vorbis: "METADATA_BLOCK_PICTURE";
133
- readonly flac: "PICTURE";
134
- };
135
- };
136
- readonly RATING: {
137
- readonly key: "RATING";
138
- readonly description: "Track rating (normalized 0.0-1.0)";
139
- readonly type: "object";
140
- readonly supportedFormats: readonly ["ID3v2", "Vorbis", "MP4"];
141
- readonly mappings: {
142
- readonly id3v2: {
143
- readonly frame: "POPM";
144
- };
145
- readonly vorbis: "RATING";
146
- readonly mp4: "----:com.apple.iTunes:RATING";
147
- };
148
- };
149
- readonly LYRICS: {
150
- readonly key: "LYRICS";
151
- readonly description: "Unsynchronized lyrics text";
152
- readonly type: "object";
153
- readonly supportedFormats: readonly ["ID3v2", "Vorbis", "MP4"];
154
- readonly mappings: {
155
- readonly id3v2: {
156
- readonly frame: "USLT";
157
- };
158
- readonly vorbis: "LYRICS";
159
- readonly mp4: "©lyr";
160
- };
161
- };
162
- readonly CHAPTER: {
163
- readonly key: "CHAPTER";
164
- readonly description: "Chapter markers with time ranges";
165
- readonly type: "object";
166
- readonly supportedFormats: readonly ["ID3v2"];
167
- readonly mappings: {
168
- readonly id3v2: {
169
- readonly frame: "CHAP";
170
- };
171
- };
172
- };
173
- };
174
- /**
175
- * Type for the simple key map.
176
- */
177
- export type ComplexPropertyKeyMap = {
178
- readonly [K in ComplexPropertyKey]: K;
179
- };
180
- /**
181
- * Simple string map for daily use.
182
- * Avoids the `.key` ceremony when you just need the key string.
183
- *
184
- * @example
185
- * ```typescript
186
- * // Instead of: COMPLEX_PROPERTIES.RATING.key
187
- * COMPLEX_PROPERTY_KEY.RATING; // "RATING"
188
- * ```
189
- */
190
- export declare const COMPLEX_PROPERTY_KEY: ComplexPropertyKeyMap;
191
77
  //# sourceMappingURL=complex-properties.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"complex-properties.d.ts","sourceRoot":"","sources":["../../../src/constants/complex-properties.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAEpD;;;;;;;;GAQG;AACH,MAAM,WAAW,MAAM;IACrB,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,qEAAqE;IACrE,EAAE,EAAE,MAAM,CAAC;IACX,0DAA0D;IAC1D,IAAI,EAAE,UAAU,CAAC;IACjB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,uBAAuB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEjD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,WAAW,uBAAuB;IACtC,oCAAoC;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC;IACf,iCAAiC;IACjC,MAAM,EAAE,cAAc,CAAC;IACvB,0CAA0C;IAC1C,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,uBAAuB,CAAC;AAE/D;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4CrB,CAAC;AAEX;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,CAAC,IAAI,kBAAkB,GAAG,CAAC;CACtC,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,oBAAoB,EAAE,qBAKzB,CAAC"}
1
+ {"version":3,"file":"complex-properties.d.ts","sourceRoot":"","sources":["../../../src/constants/complex-properties.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH;;;;;;;;GAQG;AACH,MAAM,WAAW,MAAM;IACrB,6DAA6D;IAC7D,MAAM,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4CAA4C;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,UAAU;IACzB,qEAAqE;IACrE,EAAE,EAAE,MAAM,CAAC;IACX,0DAA0D;IAC1D,IAAI,EAAE,UAAU,CAAC;IACjB;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,uBAAuB;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC"}
@@ -1,55 +0,0 @@
1
- const COMPLEX_PROPERTIES = {
2
- PICTURE: {
3
- key: "PICTURE",
4
- description: "Embedded album art or images",
5
- type: "binary",
6
- supportedFormats: ["ID3v2", "MP4", "Vorbis", "FLAC"],
7
- mappings: {
8
- id3v2: { frame: "APIC" },
9
- mp4: "covr",
10
- vorbis: "METADATA_BLOCK_PICTURE",
11
- flac: "PICTURE"
12
- }
13
- },
14
- RATING: {
15
- key: "RATING",
16
- description: "Track rating (normalized 0.0-1.0)",
17
- type: "object",
18
- supportedFormats: ["ID3v2", "Vorbis", "MP4"],
19
- mappings: {
20
- id3v2: { frame: "POPM" },
21
- vorbis: "RATING",
22
- mp4: "----:com.apple.iTunes:RATING"
23
- }
24
- },
25
- LYRICS: {
26
- key: "LYRICS",
27
- description: "Unsynchronized lyrics text",
28
- type: "object",
29
- supportedFormats: ["ID3v2", "Vorbis", "MP4"],
30
- mappings: {
31
- id3v2: { frame: "USLT" },
32
- vorbis: "LYRICS",
33
- mp4: "\xA9lyr"
34
- }
35
- },
36
- CHAPTER: {
37
- key: "CHAPTER",
38
- description: "Chapter markers with time ranges",
39
- type: "object",
40
- supportedFormats: ["ID3v2"],
41
- mappings: {
42
- id3v2: { frame: "CHAP" }
43
- }
44
- }
45
- };
46
- const COMPLEX_PROPERTY_KEY = {
47
- PICTURE: "PICTURE",
48
- RATING: "RATING",
49
- LYRICS: "LYRICS",
50
- CHAPTER: "CHAPTER"
51
- };
52
- export {
53
- COMPLEX_PROPERTIES,
54
- COMPLEX_PROPERTY_KEY
55
- };
@@ -3,7 +3,6 @@
3
3
  * Maintains backward compatibility by re-exporting all constants and utilities
4
4
  */
5
5
  export * from "./properties.js";
6
- export * from "./tags.js";
7
6
  export * from "./format-mappings.js";
8
7
  export * from "./utilities.js";
9
8
  export * from "./complex-properties.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/constants/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,cAAc,iBAAiB,CAAC;AAGhC,cAAc,WAAW,CAAC;AAG1B,cAAc,sBAAsB,CAAC;AAGrC,cAAc,gBAAgB,CAAC;AAG/B,cAAc,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/constants/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,cAAc,iBAAiB,CAAC;AAGhC,cAAc,sBAAsB,CAAC;AAGrC,cAAc,gBAAgB,CAAC;AAG/B,cAAc,yBAAyB,CAAC"}
@@ -1,5 +1,4 @@
1
1
  export * from "./properties.js";
2
- export * from "./tags.js";
3
2
  export * from "./format-mappings.js";
4
3
  export * from "./utilities.js";
5
4
  export * from "./complex-properties.js";
@@ -1 +1 @@
1
- {"version":3,"file":"import-operations.d.ts","sourceRoot":"","sources":["../../../src/file-utils/import-operations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAOxD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IACP,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACjB,GACL,OAAO,CAAC,IAAI,CAAC,CAMf;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,WAAW,EACjB,OAAO,GAAE;IACP,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACjB,GACL,OAAO,CAAC,IAAI,CAAC,CAaf;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE,WAA0B,EAChC,OAAO,GAAE;IACP,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACjB,GACL,OAAO,CAAC,OAAO,CAAC,CAUlB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAEf"}
1
+ {"version":3,"file":"import-operations.d.ts","sourceRoot":"","sources":["../../../src/file-utils/import-operations.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAOxD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,cAAc,CAClC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE;IACP,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACjB,GACL,OAAO,CAAC,IAAI,CAAC,CAMf;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,WAAW,EACjB,OAAO,GAAE;IACP,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACjB,GACL,OAAO,CAAC,IAAI,CAAC,CAef;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,EAAE,MAAM,EACjB,IAAI,GAAE,WAA0B,EAChC,OAAO,GAAE;IACP,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACjB,GACL,OAAO,CAAC,OAAO,CAAC,CAUlB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,IAAI,CAAC,CAEf"}
@@ -16,7 +16,7 @@ async function importPictureWithType(audioPath, imagePath, type, options = {}) {
16
16
  mimeType,
17
17
  data: imageData,
18
18
  type,
19
- description: options.description
19
+ ...options.description !== void 0 ? { description: options.description } : {}
20
20
  };
21
21
  const modifiedBuffer = await replacePictureByType(audioPath, picture);
22
22
  await writeFileData(audioPath, modifiedBuffer);
@@ -1 +1 @@
1
- {"version":3,"file":"file-processors.d.ts","sourceRoot":"","sources":["../../../src/folder-api/file-processors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAEV,iBAAiB,EAElB,MAAM,YAAY,CAAC;AAGpB,wBAAsB,YAAY,CAAC,CAAC,EAClC,KAAK,EAAE,MAAM,EAAE,EACf,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,EACvC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,CAAC,EAAE,CAAC,CAYd;AAED,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,iBAAiB,EAAE,OAAO,EAC1B,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,EAC5E,SAAS,CAAC,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,EAC7B,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,iBAAiB,CAAC,CAoD5B"}
1
+ {"version":3,"file":"file-processors.d.ts","sourceRoot":"","sources":["../../../src/folder-api/file-processors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAC3C,OAAO,KAAK,EAEV,iBAAiB,EAElB,MAAM,YAAY,CAAC;AAGpB,wBAAsB,YAAY,CAAC,CAAC,EAClC,KAAK,EAAE,MAAM,EAAE,EACf,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,EACvC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,CAAC,EAAE,CAAC,CAYd;AAED,wBAAsB,qBAAqB,CACzC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,iBAAiB,EAAE,OAAO,EAC1B,UAAU,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,EAC5E,SAAS,CAAC,EAAE;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,EAC7B,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,iBAAiB,CAAC,CAuD5B"}
@@ -31,12 +31,12 @@ async function processFileWithTagLib(filePath, taglib, includeProperties, onProg
31
31
  "replayGainAlbumPeak"
32
32
  ];
33
33
  for (const field of fieldNames) {
34
- const value = audioFile.getProperty(field);
35
- if (value) {
34
+ const value = audioFile.getProperty(field)?.[0];
35
+ if (value !== void 0) {
36
36
  dynamics[field] = value;
37
37
  }
38
38
  }
39
- let appleSoundCheck = audioFile.getProperty("appleSoundCheck");
39
+ let appleSoundCheck = audioFile.getProperty("appleSoundCheck")?.[0];
40
40
  if (!appleSoundCheck && audioFile.isMP4()) {
41
41
  appleSoundCheck = audioFile.getMP4Item("----:com.apple.iTunes:iTunNORM");
42
42
  }
@@ -45,12 +45,13 @@ async function processFileWithTagLib(filePath, taglib, includeProperties, onProg
45
45
  const current = ++processed.count;
46
46
  onProgress?.(current, totalFound, filePath);
47
47
  }
48
+ const withDynamics = Object.keys(dynamics).length > 0 ? dynamics : void 0;
48
49
  return {
49
50
  path: filePath,
50
51
  tags,
51
- properties,
52
+ ...properties !== void 0 ? { properties } : {},
52
53
  hasCoverArt,
53
- dynamics: Object.keys(dynamics).length > 0 ? dynamics : void 0
54
+ ...withDynamics !== void 0 ? { dynamics: withDynamics } : {}
54
55
  };
55
56
  } finally {
56
57
  audioFile.dispose();
@@ -11,9 +11,9 @@ async function scanForAlbums(folderPath, options = {}) {
11
11
  } = options;
12
12
  const scan = await scanFolder(folderPath, scanOptions);
13
13
  return groupAlbums(scan, {
14
- minFolderConfidence,
15
- flatDiscPrefixes,
16
- folderFallback,
14
+ ...minFolderConfidence !== void 0 ? { minFolderConfidence } : {},
15
+ ...flatDiscPrefixes !== void 0 ? { flatDiscPrefixes } : {},
16
+ ...folderFallback !== void 0 ? { folderFallback } : {},
17
17
  scanRoot: folderPath
18
18
  });
19
19
  }
@@ -62,9 +62,9 @@ async function scanFolder(folderPath, options = {}) {
62
62
  const processOpts = {
63
63
  includeProperties,
64
64
  continueOnError,
65
- onProgress,
65
+ ...onProgress !== void 0 ? { onProgress } : {},
66
66
  totalFound,
67
- signal
67
+ ...signal !== void 0 ? { signal } : {}
68
68
  };
69
69
  const items = await scanWithTagLib(taglib, filePaths, processOpts);
70
70
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"decoder.d.ts","sourceRoot":"","sources":["../../../src/msgpack/decoder.ts"],"names":[],"mappings":"AAAA,sFAAsF;AAEtF,OAAO,EAAU,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAE/D,OAAO,KAAK,EACV,eAAe,EACf,WAAW,EACX,OAAO,EACP,WAAW,EACZ,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAatD,wBAAgB,aAAa,CAAC,aAAa,EAAE,UAAU,GAAG,WAAW,CAapE;AAED,wBAAgB,qBAAqB,CACnC,aAAa,EAAE,UAAU,GACxB,eAAe,CAiBjB;AAED,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,UAAU,GAAG,WAAW,CASxE;AAED,wBAAgB,aAAa,CAAC,aAAa,EAAE,UAAU,GAAG,OAAO,CAWhE;AAED,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,UAAU,GAAG,OAAO,EAAE,CAavE;AAED,wBAAgB,iBAAiB,CAAC,CAAC,GAAG,OAAO,EAC3C,aAAa,EAAE,UAAU,EACzB,OAAO,GAAE,OAAO,CAAC,cAAc,CAAM,GACpC,CAAC,CAUH;AA2BD,wBAAgB,qBAAqB,CACnC,aAAa,EAAE,UAAU,GACxB,WAAW,GAAG,eAAe,GAAG,OAAO,GAAG,WAAW,CAiCvD;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAc9D;AAaD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,GAAG;IACtD,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,mBAAmB,CAAC;CAC3B,CAuBA;AAED,wBAAgB,iBAAiB,CAC/B,aAAa,EAAE,UAAU,GACxB,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC,CAqBpE"}
1
+ {"version":3,"file":"decoder.d.ts","sourceRoot":"","sources":["../../../src/msgpack/decoder.ts"],"names":[],"mappings":"AAAA,sFAAsF;AAEtF,OAAO,EAAU,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAE/D,OAAO,KAAK,EACV,eAAe,EACf,WAAW,EACX,OAAO,EACP,WAAW,EACZ,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAYtD,wBAAgB,aAAa,CAAC,aAAa,EAAE,UAAU,GAAG,WAAW,CAapE;AAED,wBAAgB,qBAAqB,CACnC,aAAa,EAAE,UAAU,GACxB,eAAe,CAiBjB;AAED,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,UAAU,GAAG,WAAW,CASxE;AAED,wBAAgB,aAAa,CAAC,aAAa,EAAE,UAAU,GAAG,OAAO,CAWhE;AAED,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,UAAU,GAAG,OAAO,EAAE,CAavE;AAED,wBAAgB,iBAAiB,CAAC,CAAC,GAAG,OAAO,EAC3C,aAAa,EAAE,UAAU,EACzB,OAAO,GAAE,OAAO,CAAC,cAAc,CAAM,GACpC,CAAC,CAUH;AA2BD,wBAAgB,qBAAqB,CACnC,aAAa,EAAE,UAAU,GACxB,WAAW,GAAG,eAAe,GAAG,OAAO,GAAG,WAAW,CAiCvD;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAc9D;AAaD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,UAAU,GAAG;IACtD,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,IAAI,EAAE,mBAAmB,CAAC;CAC3B,CAuBA;AAED,wBAAgB,iBAAiB,CAC/B,aAAa,EAAE,UAAU,GACxB,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC,CAqBpE"}