taglib-wasm 1.8.3 → 2.1.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/README.md +8 -1
- package/dist/disc-folder.d.ts +19 -0
- package/dist/disc-folder.d.ts.map +1 -0
- package/dist/disc-folder.js +550 -0
- package/dist/index.browser.d.ts +3 -4
- package/dist/index.browser.d.ts.map +1 -1
- package/dist/index.browser.js +187 -176
- package/dist/index.d.ts +3 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -12
- package/dist/simple.browser.js +172 -33
- package/dist/src/constants/complex-properties.d.ts +0 -114
- package/dist/src/constants/complex-properties.d.ts.map +1 -1
- package/dist/src/constants/complex-properties.js +0 -55
- package/dist/src/constants/index.d.ts +0 -1
- package/dist/src/constants/index.d.ts.map +1 -1
- package/dist/src/constants/index.js +0 -1
- package/dist/src/constants/utilities.d.ts +13 -0
- package/dist/src/constants/utilities.d.ts.map +1 -1
- package/dist/src/constants/utilities.js +9 -1
- package/dist/src/file-utils/import-operations.d.ts.map +1 -1
- package/dist/src/file-utils/import-operations.js +1 -1
- package/dist/src/folder-api/file-processors.d.ts.map +1 -1
- package/dist/src/folder-api/file-processors.js +6 -5
- package/dist/src/folder-api/scan-for-albums.js +3 -3
- package/dist/src/folder-api/scan-operations.js +2 -2
- package/dist/src/msgpack/decoder.d.ts +2 -2
- package/dist/src/msgpack/decoder.d.ts.map +1 -1
- package/dist/src/msgpack/decoder.js +5 -6
- package/dist/src/msgpack/encoder.d.ts.map +1 -1
- package/dist/src/msgpack/encoder.js +9 -6
- package/dist/src/msgpack/index.d.ts +1 -1
- package/dist/src/msgpack/index.d.ts.map +1 -1
- package/dist/src/msgpack/types.d.ts +10 -0
- package/dist/src/msgpack/types.d.ts.map +1 -1
- package/dist/src/msgpack/utils.d.ts +2 -1
- package/dist/src/msgpack/utils.d.ts.map +1 -1
- package/dist/src/runtime/module-loader-browser.d.ts.map +1 -1
- package/dist/src/runtime/module-loader.d.ts.map +1 -1
- package/dist/src/runtime/module-loader.js +3 -3
- package/dist/src/runtime/platform-io.js +1 -1
- package/dist/src/runtime/unified-loader/module-loading.d.ts.map +1 -1
- package/dist/src/runtime/unified-loader/module-loading.js +1 -1
- package/dist/src/runtime/wasi-adapter/file-handle.d.ts +8 -0
- package/dist/src/runtime/wasi-adapter/file-handle.d.ts.map +1 -1
- package/dist/src/runtime/wasi-adapter/file-handle.js +44 -4
- package/dist/src/runtime/wasi-fs-deno.d.ts.map +1 -1
- package/dist/src/runtime/wasi-fs-deno.js +1 -1
- package/dist/src/simple/batch-operations.d.ts.map +1 -1
- package/dist/src/simple/batch-operations.js +14 -10
- package/dist/src/simple/picture-operations.js +1 -1
- package/dist/src/taglib/audio-file-base.d.ts +15 -9
- package/dist/src/taglib/audio-file-base.d.ts.map +1 -1
- package/dist/src/taglib/audio-file-base.js +35 -4
- package/dist/src/taglib/audio-file-impl.d.ts +2 -2
- package/dist/src/taglib/audio-file-impl.d.ts.map +1 -1
- package/dist/src/taglib/audio-file-impl.js +25 -13
- package/dist/src/taglib/audio-file-interface.d.ts +27 -6
- package/dist/src/taglib/audio-file-interface.d.ts.map +1 -1
- package/dist/src/taglib/auto-dispose.d.ts +6 -0
- package/dist/src/taglib/auto-dispose.d.ts.map +1 -0
- package/dist/src/taglib/auto-dispose.js +13 -0
- package/dist/src/taglib/embind-adapter.d.ts +2 -2
- package/dist/src/taglib/embind-adapter.d.ts.map +1 -1
- package/dist/src/taglib/embind-adapter.js +17 -0
- package/dist/src/taglib/extra-state-registry.d.ts.map +1 -1
- package/dist/src/taglib/extra-state-registry.js +9 -0
- package/dist/src/taglib/metadata-extent.d.ts.map +1 -1
- package/dist/src/taglib/metadata-extent.js +44 -1
- package/dist/src/taglib/mutable-tag.d.ts +15 -15
- package/dist/src/taglib/mutable-tag.d.ts.map +1 -1
- package/dist/src/taglib/save-reconstruct.d.ts.map +1 -1
- package/dist/src/taglib/taglib-class.d.ts.map +1 -1
- package/dist/src/types/tags.d.ts +0 -4
- package/dist/src/types/tags.d.ts.map +1 -1
- package/dist/src/utils/mirror-fields.d.ts +2 -0
- package/dist/src/utils/mirror-fields.d.ts.map +1 -1
- package/dist/src/utils/mirror-fields.js +11 -3
- package/dist/src/utils/node-fs.d.ts +10 -10
- package/dist/src/utils/node-fs.d.ts.map +1 -1
- package/dist/src/utils/node-fs.js +2 -1
- package/dist/src/utils/tag-mapping.d.ts.map +1 -1
- package/dist/src/utils/tag-mapping.js +1 -1
- package/dist/src/version.d.ts +1 -1
- package/dist/src/version.js +1 -1
- package/dist/src/wasm.d.ts +20 -1
- package/dist/src/wasm.d.ts.map +1 -1
- package/dist/src/web-utils/canvas.d.ts.map +1 -1
- package/dist/src/web-utils/canvas.js +6 -1
- package/dist/src/web-utils/data-url.js +1 -1
- package/dist/taglib-wasi.wasm +0 -0
- package/dist/taglib-web.wasm +0 -0
- package/dist/taglib-wrapper.js +1 -1
- package/package.json +23 -15
- package/dist/src/constants/tags.d.ts +0 -81
- package/dist/src/constants/tags.d.ts.map +0 -1
- package/dist/src/constants/tags.js +0 -86
package/dist/index.js
CHANGED
|
@@ -51,13 +51,12 @@ import {
|
|
|
51
51
|
FormatMappings,
|
|
52
52
|
getAllProperties,
|
|
53
53
|
getAllPropertyKeys,
|
|
54
|
-
getAllTagNames,
|
|
55
54
|
getPropertiesByFormat,
|
|
56
55
|
getPropertyMetadata,
|
|
57
56
|
isValidProperty,
|
|
58
|
-
isValidTagName,
|
|
59
57
|
PROPERTIES,
|
|
60
|
-
|
|
58
|
+
propertyValue,
|
|
59
|
+
propertyValues
|
|
61
60
|
} from "./src/constants.js";
|
|
62
61
|
import {
|
|
63
62
|
copyCoverArt,
|
|
@@ -95,10 +94,6 @@ import {
|
|
|
95
94
|
PICTURE_TYPE_NAMES,
|
|
96
95
|
PICTURE_TYPE_VALUES
|
|
97
96
|
} from "./src/types.js";
|
|
98
|
-
import {
|
|
99
|
-
COMPLEX_PROPERTIES,
|
|
100
|
-
COMPLEX_PROPERTY_KEY
|
|
101
|
-
} from "./src/constants/complex-properties.js";
|
|
102
97
|
import { RatingUtils } from "./src/utils/rating.js";
|
|
103
98
|
import * as bwf from "./src/bwf/bext.js";
|
|
104
99
|
import { loadTagLibModule } from "./src/runtime/module-loader.js";
|
|
@@ -106,8 +101,6 @@ export {
|
|
|
106
101
|
AudioFileImpl,
|
|
107
102
|
BITRATE_CONTROL_MODE_NAMES,
|
|
108
103
|
BITRATE_CONTROL_MODE_VALUES,
|
|
109
|
-
COMPLEX_PROPERTIES,
|
|
110
|
-
COMPLEX_PROPERTY_KEY,
|
|
111
104
|
EnvironmentError,
|
|
112
105
|
FileOperationError,
|
|
113
106
|
FormatMappings,
|
|
@@ -122,7 +115,6 @@ export {
|
|
|
122
115
|
TagLib,
|
|
123
116
|
TagLibError,
|
|
124
117
|
TagLibInitializationError,
|
|
125
|
-
Tags,
|
|
126
118
|
UnsupportedFormatError,
|
|
127
119
|
addPicture,
|
|
128
120
|
applyCoverArt,
|
|
@@ -149,7 +141,6 @@ export {
|
|
|
149
141
|
findPictureByType,
|
|
150
142
|
getAllProperties,
|
|
151
143
|
getAllPropertyKeys,
|
|
152
|
-
getAllTagNames,
|
|
153
144
|
getPropertiesByFormat,
|
|
154
145
|
getPropertyMetadata,
|
|
155
146
|
groupAlbums,
|
|
@@ -168,11 +159,12 @@ export {
|
|
|
168
159
|
isUnsupportedFormatError,
|
|
169
160
|
isValidAudioFile,
|
|
170
161
|
isValidProperty,
|
|
171
|
-
isValidTagName,
|
|
172
162
|
loadPictureFromFile,
|
|
173
163
|
loadTagLibModule,
|
|
174
164
|
pictureToDataURL,
|
|
175
165
|
prepareWasmForEmbedding,
|
|
166
|
+
propertyValue,
|
|
167
|
+
propertyValues,
|
|
176
168
|
readCoverArt,
|
|
177
169
|
readFormat,
|
|
178
170
|
readMetadata,
|
package/dist/simple.browser.js
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
3
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4
|
-
var __esm = (fn, res) => function __init() {
|
|
5
|
-
|
|
4
|
+
var __esm = (fn, res, err) => function __init() {
|
|
5
|
+
if (err) throw err[0];
|
|
6
|
+
try {
|
|
7
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
8
|
+
} catch (e) {
|
|
9
|
+
throw err = [e], e;
|
|
10
|
+
}
|
|
6
11
|
};
|
|
7
12
|
var __export = (target, all) => {
|
|
8
13
|
for (var name in all)
|
|
@@ -1648,6 +1653,23 @@ var init_mutable_tag_impl = __esm({
|
|
|
1648
1653
|
}
|
|
1649
1654
|
});
|
|
1650
1655
|
|
|
1656
|
+
// src/taglib/auto-dispose.ts
|
|
1657
|
+
function registerAutoDispose(target, handle) {
|
|
1658
|
+
registry.register(target, handle, target);
|
|
1659
|
+
}
|
|
1660
|
+
function unregisterAutoDispose(target) {
|
|
1661
|
+
registry.unregister(target);
|
|
1662
|
+
}
|
|
1663
|
+
var registry;
|
|
1664
|
+
var init_auto_dispose = __esm({
|
|
1665
|
+
"src/taglib/auto-dispose.ts"() {
|
|
1666
|
+
"use strict";
|
|
1667
|
+
registry = new FinalizationRegistry((handle) => {
|
|
1668
|
+
handle.destroy();
|
|
1669
|
+
});
|
|
1670
|
+
}
|
|
1671
|
+
});
|
|
1672
|
+
|
|
1651
1673
|
// src/taglib/audio-file-base.ts
|
|
1652
1674
|
var LYRICS_PROPERTY_KEY, LYRICS_WIRE_KEY, EMPTY_KEY_SET, BaseAudioFileImpl;
|
|
1653
1675
|
var init_audio_file_base = __esm({
|
|
@@ -1657,6 +1679,7 @@ var init_audio_file_base = __esm({
|
|
|
1657
1679
|
init_errors2();
|
|
1658
1680
|
init_mp4_item_names();
|
|
1659
1681
|
init_mutable_tag_impl();
|
|
1682
|
+
init_auto_dispose();
|
|
1660
1683
|
LYRICS_PROPERTY_KEY = "lyrics";
|
|
1661
1684
|
LYRICS_WIRE_KEY = toTagLibKey(LYRICS_PROPERTY_KEY);
|
|
1662
1685
|
EMPTY_KEY_SET = /* @__PURE__ */ new Set();
|
|
@@ -1677,6 +1700,7 @@ var init_audio_file_base = __esm({
|
|
|
1677
1700
|
this.isPartiallyLoaded = isPartiallyLoaded;
|
|
1678
1701
|
this.partialLoadOptions = partialLoadOptions;
|
|
1679
1702
|
this.partialKeysAtLoad = isPartiallyLoaded ? new Set(Object.keys(fileHandle.getProperties())) : void 0;
|
|
1703
|
+
registerAutoDispose(this, fileHandle);
|
|
1680
1704
|
}
|
|
1681
1705
|
/**
|
|
1682
1706
|
* Wire-key text properties present in the partial header at load but now
|
|
@@ -1736,16 +1760,36 @@ var init_audio_file_base = __esm({
|
|
|
1736
1760
|
this.handle.setProperties(translated);
|
|
1737
1761
|
}
|
|
1738
1762
|
getProperty(key) {
|
|
1739
|
-
const
|
|
1740
|
-
|
|
1763
|
+
const wireKey = toTagLibKey(fromTagLibKey(key));
|
|
1764
|
+
const values = this.handle.getProperties()[wireKey]?.filter(
|
|
1765
|
+
(v) => v !== ""
|
|
1766
|
+
);
|
|
1767
|
+
if (values !== void 0 && values.length > 0) return values;
|
|
1741
1768
|
if (!this.isMP4()) return void 0;
|
|
1742
|
-
const remapped = this.properties()[key]?.
|
|
1743
|
-
return remapped
|
|
1769
|
+
const remapped = this.properties()[key]?.filter((v) => v !== "");
|
|
1770
|
+
return remapped !== void 0 && remapped.length > 0 ? remapped : void 0;
|
|
1744
1771
|
}
|
|
1745
1772
|
setProperty(key, value) {
|
|
1746
1773
|
const wireKey = toTagLibKey(fromTagLibKey(key));
|
|
1747
1774
|
const atomNames = mp4FreeformAtomNames([wireKey]);
|
|
1748
1775
|
if (atomNames.length > 0 && this.isMP4()) {
|
|
1776
|
+
if (value === "") {
|
|
1777
|
+
const prior = this.handle.getMp4ItemRemovals?.() ?? [];
|
|
1778
|
+
this.handle.setMp4ItemRemovals?.([
|
|
1779
|
+
.../* @__PURE__ */ new Set([...prior, ...atomNames])
|
|
1780
|
+
]);
|
|
1781
|
+
if (this.module.isWasi) {
|
|
1782
|
+
this.handle.setProperties({
|
|
1783
|
+
...this.handle.getProperties(),
|
|
1784
|
+
[wireKey]: []
|
|
1785
|
+
});
|
|
1786
|
+
} else {
|
|
1787
|
+
const rest = { ...this.handle.getProperties() };
|
|
1788
|
+
delete rest[wireKey];
|
|
1789
|
+
this.handle.setProperties(rest);
|
|
1790
|
+
}
|
|
1791
|
+
return;
|
|
1792
|
+
}
|
|
1749
1793
|
this.handle.setProperties({
|
|
1750
1794
|
...this.handle.getProperties(),
|
|
1751
1795
|
[wireKey]: [value],
|
|
@@ -1755,6 +1799,14 @@ var init_audio_file_base = __esm({
|
|
|
1755
1799
|
}
|
|
1756
1800
|
this.handle.setProperty(wireKey, value);
|
|
1757
1801
|
}
|
|
1802
|
+
/**
|
|
1803
|
+
* The empty-string clearing contract, named (taglib-qyw2): both backends
|
|
1804
|
+
* remove the property when the written value is empty, and setProperty's
|
|
1805
|
+
* wire-key normalization + MP4 freeform atom-name handling apply unchanged.
|
|
1806
|
+
*/
|
|
1807
|
+
removeProperty(key) {
|
|
1808
|
+
this.setProperty(key, "");
|
|
1809
|
+
}
|
|
1758
1810
|
isMP4() {
|
|
1759
1811
|
return this.handle.isMP4();
|
|
1760
1812
|
}
|
|
@@ -1787,6 +1839,7 @@ var init_audio_file_base = __esm({
|
|
|
1787
1839
|
return this.handle.isValid();
|
|
1788
1840
|
}
|
|
1789
1841
|
dispose() {
|
|
1842
|
+
unregisterAutoDispose(this);
|
|
1790
1843
|
if (this.fileHandle) {
|
|
1791
1844
|
this.fileHandle.destroy();
|
|
1792
1845
|
this.fileHandle = null;
|
|
@@ -1860,6 +1913,7 @@ function isValidBitrateMode(value) {
|
|
|
1860
1913
|
}
|
|
1861
1914
|
function wrapEmbindHandle(raw) {
|
|
1862
1915
|
const stagedId3v2Frames = {};
|
|
1916
|
+
let destroyed = false;
|
|
1863
1917
|
const overrides = {
|
|
1864
1918
|
getTagData() {
|
|
1865
1919
|
const tw = raw.getTag();
|
|
@@ -1939,6 +1993,22 @@ function wrapEmbindHandle(raw) {
|
|
|
1939
1993
|
stripId3Tags(opts) {
|
|
1940
1994
|
raw.stripId3Tags(opts);
|
|
1941
1995
|
},
|
|
1996
|
+
destroy() {
|
|
1997
|
+
if (destroyed) return;
|
|
1998
|
+
destroyed = true;
|
|
1999
|
+
raw.destroy();
|
|
2000
|
+
},
|
|
2001
|
+
get destroyed() {
|
|
2002
|
+
return destroyed;
|
|
2003
|
+
},
|
|
2004
|
+
// taglib-qyw2: the PropertyMap erase pass computes freeform item names
|
|
2005
|
+
// from the property table (upper-cased) and misses the restored exact-case
|
|
2006
|
+
// atom (taglib-bnhl), so clears queue the exact name here; the imperative
|
|
2007
|
+
// Embind model applies removeItem immediately, before setProperties.
|
|
2008
|
+
setMp4ItemRemovals(removals) {
|
|
2009
|
+
const handle = raw;
|
|
2010
|
+
for (const name of removals) handle.removeMP4Item(name);
|
|
2011
|
+
},
|
|
1942
2012
|
getAudioProperties() {
|
|
1943
2013
|
const pw = raw.getAudioProperties();
|
|
1944
2014
|
if (!pw) return null;
|
|
@@ -2038,6 +2108,15 @@ var init_extra_state_registry = __esm({
|
|
|
2038
2108
|
else if (complete) target.setIxml(null);
|
|
2039
2109
|
}
|
|
2040
2110
|
},
|
|
2111
|
+
{
|
|
2112
|
+
name: "_mp4ItemRemovals",
|
|
2113
|
+
copy(target, source, complete) {
|
|
2114
|
+
const v = source.getMp4ItemRemovals?.();
|
|
2115
|
+
if (complete || v !== void 0 && v.length > 0) {
|
|
2116
|
+
target.setMp4ItemRemovals?.(v ?? []);
|
|
2117
|
+
}
|
|
2118
|
+
}
|
|
2119
|
+
},
|
|
2041
2120
|
{
|
|
2042
2121
|
name: "id3v2Frames",
|
|
2043
2122
|
copy(target, source) {
|
|
@@ -2226,7 +2305,7 @@ var init_audio_file_impl = __esm({
|
|
|
2226
2305
|
mimeType: pic.mimeType,
|
|
2227
2306
|
data: pic.data,
|
|
2228
2307
|
type: PICTURE_TYPE_NAMES[pic.type] ?? "Other",
|
|
2229
|
-
description: pic.description
|
|
2308
|
+
...pic.description !== void 0 ? { description: pic.description } : {}
|
|
2230
2309
|
}));
|
|
2231
2310
|
}
|
|
2232
2311
|
setPictures(pictures) {
|
|
@@ -2251,13 +2330,20 @@ var init_audio_file_impl = __esm({
|
|
|
2251
2330
|
getChapters() {
|
|
2252
2331
|
const sorted = sortChapters(this.handle.getChapters());
|
|
2253
2332
|
const trackEndMs = this.audioProperties()?.durationMs;
|
|
2254
|
-
return sorted.map((c, i) =>
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2333
|
+
return sorted.map((c, i) => {
|
|
2334
|
+
const endTimeMs = inferEndTimeMs(sorted, i, trackEndMs);
|
|
2335
|
+
return {
|
|
2336
|
+
startTimeMs: c.startTimeMs,
|
|
2337
|
+
...endTimeMs !== void 0 ? { endTimeMs } : {},
|
|
2338
|
+
// Truthiness, not !== undefined: an empty CHAP title/id must read back
|
|
2339
|
+
// as ABSENT (the old `c.title || undefined` contract; the Embind
|
|
2340
|
+
// reader emits "" unconditionally, WASI omits — coalescing keeps the
|
|
2341
|
+
// backends agreeing).
|
|
2342
|
+
...c.title ? { title: c.title } : {},
|
|
2343
|
+
...c.id ? { id: c.id } : {},
|
|
2344
|
+
...c.source !== void 0 ? { source: c.source } : {}
|
|
2345
|
+
};
|
|
2346
|
+
});
|
|
2261
2347
|
}
|
|
2262
2348
|
setChapters(chapters, options) {
|
|
2263
2349
|
const fmt = this.getFormat();
|
|
@@ -2271,10 +2357,10 @@ var init_audio_file_impl = __esm({
|
|
|
2271
2357
|
const style = options?.mp4ChapterStyle ?? "quicktime";
|
|
2272
2358
|
const source = fmt === "MP4" ? style : "id3";
|
|
2273
2359
|
const raw = sorted.map((c, i) => ({
|
|
2274
|
-
id: c.id,
|
|
2360
|
+
...c.id !== void 0 ? { id: c.id } : {},
|
|
2275
2361
|
startTimeMs: c.startTimeMs,
|
|
2276
2362
|
endTimeMs: inferEndTimeMs(sorted, i, trackEndMs) ?? c.startTimeMs,
|
|
2277
|
-
title: c.title,
|
|
2363
|
+
...c.title !== void 0 ? { title: c.title } : {},
|
|
2278
2364
|
source
|
|
2279
2365
|
}));
|
|
2280
2366
|
this.handle.setChapters(raw, style);
|
|
@@ -2301,8 +2387,9 @@ var init_audio_file_impl = __esm({
|
|
|
2301
2387
|
return this.handle.getRatings().map(
|
|
2302
2388
|
(r) => ({
|
|
2303
2389
|
rating: r.rating,
|
|
2304
|
-
email: r.email
|
|
2305
|
-
|
|
2390
|
+
...r.email !== void 0 && r.email !== "" ? { email: r.email } : {},
|
|
2391
|
+
// 0 must read back as ABSENT (old `r.counter || undefined` contract).
|
|
2392
|
+
...r.counter !== 0 ? { counter: r.counter } : {}
|
|
2306
2393
|
})
|
|
2307
2394
|
);
|
|
2308
2395
|
}
|
|
@@ -2333,7 +2420,11 @@ var init_audio_file_impl = __esm({
|
|
|
2333
2420
|
return ratings.length > 0 ? normalized(ratings[0].rating) : void 0;
|
|
2334
2421
|
}
|
|
2335
2422
|
setRating(rating, email) {
|
|
2336
|
-
this.setRatings([{
|
|
2423
|
+
this.setRatings([{
|
|
2424
|
+
rating,
|
|
2425
|
+
...email !== void 0 ? { email } : {},
|
|
2426
|
+
counter: 0
|
|
2427
|
+
}]);
|
|
2337
2428
|
}
|
|
2338
2429
|
getId3v2Frames(id) {
|
|
2339
2430
|
assertMp3(this.getFormat());
|
|
@@ -2446,7 +2537,24 @@ function isMpegFrameSync(bytes, at = 0) {
|
|
|
2446
2537
|
if (version === 1 || layer === 0) return false;
|
|
2447
2538
|
const bitrateIndex = bytes[at + 2] >> 4 & 15;
|
|
2448
2539
|
const sampleRateIndex = bytes[at + 2] >> 2 & 3;
|
|
2449
|
-
|
|
2540
|
+
if (bitrateIndex === 0 || bitrateIndex === 15 || sampleRateIndex === 3) {
|
|
2541
|
+
return false;
|
|
2542
|
+
}
|
|
2543
|
+
const mpeg1 = version === 3;
|
|
2544
|
+
const layerIndex = layer ^ 3;
|
|
2545
|
+
const bitrate = MPEG_BITRATES[mpeg1 ? 0 : 1][layerIndex][bitrateIndex];
|
|
2546
|
+
const sampleRateTable = mpeg1 ? 0 : version === 2 ? 1 : 2;
|
|
2547
|
+
const sampleRate = MPEG_SAMPLE_RATES[sampleRateTable][sampleRateIndex];
|
|
2548
|
+
const samplesPerFrame = layerIndex === 2 ? mpeg1 ? 1152 : 576 : layerIndex === 1 ? 1152 : 384;
|
|
2549
|
+
let frameLength = Math.floor(samplesPerFrame * bitrate * 125 / sampleRate);
|
|
2550
|
+
if ((bytes[at + 2] & 2) !== 0) frameLength += layerIndex === 0 ? 4 : 1;
|
|
2551
|
+
if (frameLength === 0) return false;
|
|
2552
|
+
const next = at + frameLength;
|
|
2553
|
+
if (bytes.length < next + 4) return false;
|
|
2554
|
+
const mask = 4294839296;
|
|
2555
|
+
const header = ((bytes[at] << 24 | bytes[at + 1] << 16 | bytes[at + 2] << 8 | bytes[at + 3]) >>> 0 & mask) >>> 0;
|
|
2556
|
+
const nextHeader = ((bytes[next] << 24 | bytes[next + 1] << 16 | bytes[next + 2] << 8 | bytes[next + 3]) >>> 0 & mask) >>> 0;
|
|
2557
|
+
return header === nextHeader;
|
|
2450
2558
|
}
|
|
2451
2559
|
function containerEnd(bytes, at, limit) {
|
|
2452
2560
|
if (at >= bytes.length) return bytes.length < limit ? null : void 0;
|
|
@@ -2489,9 +2597,36 @@ function trailerFitsInFooter(tail, footerSize) {
|
|
|
2489
2597
|
}
|
|
2490
2598
|
return true;
|
|
2491
2599
|
}
|
|
2600
|
+
var MPEG_BITRATES, MPEG_SAMPLE_RATES;
|
|
2492
2601
|
var init_metadata_extent = __esm({
|
|
2493
2602
|
"src/taglib/metadata-extent.ts"() {
|
|
2494
2603
|
"use strict";
|
|
2604
|
+
MPEG_BITRATES = [
|
|
2605
|
+
[
|
|
2606
|
+
[0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0],
|
|
2607
|
+
// Layer I
|
|
2608
|
+
[0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0],
|
|
2609
|
+
// Layer II
|
|
2610
|
+
[0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0]
|
|
2611
|
+
// Layer III
|
|
2612
|
+
],
|
|
2613
|
+
[
|
|
2614
|
+
[0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0],
|
|
2615
|
+
// Layer I
|
|
2616
|
+
[0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0],
|
|
2617
|
+
// Layer II
|
|
2618
|
+
[0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0]
|
|
2619
|
+
// Layer III
|
|
2620
|
+
]
|
|
2621
|
+
];
|
|
2622
|
+
MPEG_SAMPLE_RATES = [
|
|
2623
|
+
[44100, 48e3, 32e3],
|
|
2624
|
+
// MPEG-1
|
|
2625
|
+
[22050, 24e3, 16e3],
|
|
2626
|
+
// MPEG-2
|
|
2627
|
+
[11025, 12e3, 8e3]
|
|
2628
|
+
// MPEG-2.5
|
|
2629
|
+
];
|
|
2495
2630
|
}
|
|
2496
2631
|
});
|
|
2497
2632
|
|
|
@@ -2626,7 +2761,7 @@ function mapPropertiesToExtendedTag(props) {
|
|
|
2626
2761
|
const num = parseLeadingInt(values[0]);
|
|
2627
2762
|
if (num !== void 0) tag[camelKey] = num;
|
|
2628
2763
|
} else if (camelKey === "compilation") {
|
|
2629
|
-
tag[camelKey] = values[0] === "1";
|
|
2764
|
+
tag[camelKey] = values[0] === "1" || values[0] === "true";
|
|
2630
2765
|
} else if (camelKey === "itunesAdvisory") {
|
|
2631
2766
|
tag[camelKey] = values;
|
|
2632
2767
|
if (values[0] === "1") tag.advisory = "explicit";
|
|
@@ -2763,7 +2898,7 @@ var VERSION;
|
|
|
2763
2898
|
var init_version = __esm({
|
|
2764
2899
|
"src/version.ts"() {
|
|
2765
2900
|
"use strict";
|
|
2766
|
-
VERSION = "1.
|
|
2901
|
+
VERSION = "2.1.0";
|
|
2767
2902
|
}
|
|
2768
2903
|
});
|
|
2769
2904
|
|
|
@@ -3236,7 +3371,7 @@ async function readPictureMetadata(file) {
|
|
|
3236
3371
|
return pictures.map((pic) => ({
|
|
3237
3372
|
type: pic.type,
|
|
3238
3373
|
mimeType: pic.mimeType,
|
|
3239
|
-
description: pic.description,
|
|
3374
|
+
...pic.description !== void 0 ? { description: pic.description } : {},
|
|
3240
3375
|
size: pic.data.length
|
|
3241
3376
|
}));
|
|
3242
3377
|
}
|
|
@@ -3310,10 +3445,10 @@ function extractDynamics(audioFile) {
|
|
|
3310
3445
|
"replayGainAlbumPeak"
|
|
3311
3446
|
];
|
|
3312
3447
|
for (const field of fields) {
|
|
3313
|
-
const val = audioFile.getProperty(field);
|
|
3314
|
-
if (val) dynamics[field] = val;
|
|
3448
|
+
const val = audioFile.getProperty(field)?.[0];
|
|
3449
|
+
if (val !== void 0) dynamics[field] = val;
|
|
3315
3450
|
}
|
|
3316
|
-
let appleSoundCheck = audioFile.getProperty("appleSoundCheck");
|
|
3451
|
+
let appleSoundCheck = audioFile.getProperty("appleSoundCheck")?.[0];
|
|
3317
3452
|
if (!appleSoundCheck && audioFile.isMP4()) {
|
|
3318
3453
|
appleSoundCheck = audioFile.getMP4Item("----:com.apple.iTunes:iTunNORM");
|
|
3319
3454
|
}
|
|
@@ -3339,23 +3474,27 @@ async function readMetadata(file) {
|
|
|
3339
3474
|
`File may be corrupted or in an unsupported format. File: ${name}`
|
|
3340
3475
|
);
|
|
3341
3476
|
}
|
|
3477
|
+
const dynamics = extractDynamics(audioFile);
|
|
3342
3478
|
return {
|
|
3343
3479
|
tags: readExtendedTag(audioFile),
|
|
3344
3480
|
properties: audioFile.audioProperties(),
|
|
3345
3481
|
hasCoverArt: audioFile.getPictures().length > 0,
|
|
3346
|
-
dynamics:
|
|
3482
|
+
...dynamics !== void 0 ? { dynamics } : {}
|
|
3347
3483
|
};
|
|
3348
3484
|
} finally {
|
|
3349
3485
|
audioFile.dispose();
|
|
3350
3486
|
}
|
|
3351
3487
|
}
|
|
3352
3488
|
async function readMetadataBatch(files, options = {}) {
|
|
3353
|
-
return executeBatch(files, options, (audioFile) =>
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3489
|
+
return executeBatch(files, options, (audioFile) => {
|
|
3490
|
+
const dynamics = extractDynamics(audioFile);
|
|
3491
|
+
return {
|
|
3492
|
+
tags: readExtendedTag(audioFile),
|
|
3493
|
+
properties: audioFile.audioProperties(),
|
|
3494
|
+
hasCoverArt: audioFile.getPictures().length > 0,
|
|
3495
|
+
...dynamics !== void 0 ? { dynamics } : {}
|
|
3496
|
+
};
|
|
3497
|
+
});
|
|
3359
3498
|
}
|
|
3360
3499
|
|
|
3361
3500
|
// 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;
|
|
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
|
-
};
|
|
@@ -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,
|
|
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,4 +1,5 @@
|
|
|
1
1
|
import { PROPERTIES, type PropertyKey } from "./properties.js";
|
|
2
|
+
import type { PropertyMap } from "../types/tags.js";
|
|
2
3
|
import type { PropertyMetadata } from "./property-types.js";
|
|
3
4
|
/**
|
|
4
5
|
* Type guard to check if a string is a valid property key
|
|
@@ -23,4 +24,16 @@ export declare function getAllProperties(): readonly [
|
|
|
23
24
|
* Filter properties by supported format
|
|
24
25
|
*/
|
|
25
26
|
export declare function getPropertiesByFormat(format: string): PropertyKey[];
|
|
27
|
+
/**
|
|
28
|
+
* All values for a property key in a PropertyMap; `[]` when absent
|
|
29
|
+
* (taglib-lk8u). Removes the narrowing filter at the call site: the map's
|
|
30
|
+
* index signature must admit undefined, so a bare read is
|
|
31
|
+
* `string[] | undefined` even for known keys.
|
|
32
|
+
*/
|
|
33
|
+
export declare function propertyValues(props: PropertyMap, key: string): string[];
|
|
34
|
+
/**
|
|
35
|
+
* First value for a property key in a PropertyMap; `undefined` when absent.
|
|
36
|
+
* The common single-value read, without the `?.[0]` at every call site.
|
|
37
|
+
*/
|
|
38
|
+
export declare function propertyValue(props: PropertyMap, key: string): string | undefined;
|
|
26
39
|
//# sourceMappingURL=utilities.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../../../src/constants/utilities.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,IAAI,WAAW,CAE/D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,WAAW,EACvD,GAAG,EAAE,CAAC,GACL,gBAAgB,GAAG,SAAS,CAE9B;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,SAAS,WAAW,EAAE,CAE3D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,SAAS;IAC3C,WAAW;IACX,OAAO,UAAU,CAAC,WAAW,CAAC;CAC/B,EAAE,CAKF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,EAAE,CAInE"}
|
|
1
|
+
{"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../../../src/constants/utilities.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAE5D;;GAEG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,IAAI,WAAW,CAE/D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,SAAS,WAAW,EACvD,GAAG,EAAE,CAAC,GACL,gBAAgB,GAAG,SAAS,CAE9B;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,SAAS,WAAW,EAAE,CAE3D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,SAAS;IAC3C,WAAW;IACX,OAAO,UAAU,CAAC,WAAW,CAAC;CAC/B,EAAE,CAKF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,EAAE,CAInE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAExE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,WAAW,EAClB,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,SAAS,CAEpB"}
|