@sarakusha/ebml 0.0.4

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 (66) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/README.md +43 -0
  3. package/build/CancelError.cjs +14 -0
  4. package/build/CancelError.cjs.map +1 -0
  5. package/build/CancelError.d.cts +1 -0
  6. package/build/CancelError.d.mts +7 -0
  7. package/build/CancelError.d.mts.map +1 -0
  8. package/build/CancelError.mjs +10 -0
  9. package/build/CancelError.mjs.map +1 -0
  10. package/build/Deferred-7Cu0KIje.mjs +28 -0
  11. package/build/Deferred-7Cu0KIje.mjs.map +1 -0
  12. package/build/Deferred-CB69mtbF.cjs +33 -0
  13. package/build/Deferred-CB69mtbF.cjs.map +1 -0
  14. package/build/Element-8JyOKTYb.cjs +73 -0
  15. package/build/Element-8JyOKTYb.cjs.map +1 -0
  16. package/build/Element-CC4E6wMR.d.mts +134 -0
  17. package/build/Element-CC4E6wMR.d.mts.map +1 -0
  18. package/build/Element-ChEar-fo.mjs +20 -0
  19. package/build/Element-ChEar-fo.mjs.map +1 -0
  20. package/build/FadeTransform.cjs +90 -0
  21. package/build/FadeTransform.cjs.map +1 -0
  22. package/build/FadeTransform.d.cts +1 -0
  23. package/build/FadeTransform.d.mts +17 -0
  24. package/build/FadeTransform.d.mts.map +1 -0
  25. package/build/FadeTransform.mjs +86 -0
  26. package/build/FadeTransform.mjs.map +1 -0
  27. package/build/RangeFetcher.cjs +63 -0
  28. package/build/RangeFetcher.cjs.map +1 -0
  29. package/build/RangeFetcher.d.cts +1 -0
  30. package/build/RangeFetcher.d.mts +14 -0
  31. package/build/RangeFetcher.d.mts.map +1 -0
  32. package/build/RangeFetcher.mjs +59 -0
  33. package/build/RangeFetcher.mjs.map +1 -0
  34. package/build/ReducingValve.cjs +129 -0
  35. package/build/ReducingValve.cjs.map +1 -0
  36. package/build/ReducingValve.d.cts +1 -0
  37. package/build/ReducingValve.d.mts +17 -0
  38. package/build/ReducingValve.d.mts.map +1 -0
  39. package/build/ReducingValve.mjs +125 -0
  40. package/build/ReducingValve.mjs.map +1 -0
  41. package/build/VideoChunkGenerator.cjs +131 -0
  42. package/build/VideoChunkGenerator.cjs.map +1 -0
  43. package/build/VideoChunkGenerator.d.cts +1 -0
  44. package/build/VideoChunkGenerator.d.mts +13 -0
  45. package/build/VideoChunkGenerator.d.mts.map +1 -0
  46. package/build/VideoChunkGenerator.mjs +127 -0
  47. package/build/VideoChunkGenerator.mjs.map +1 -0
  48. package/build/VideoFrameGenerator.cjs +133 -0
  49. package/build/VideoFrameGenerator.cjs.map +1 -0
  50. package/build/VideoFrameGenerator.d.cts +1 -0
  51. package/build/VideoFrameGenerator.d.mts +10 -0
  52. package/build/VideoFrameGenerator.d.mts.map +1 -0
  53. package/build/VideoFrameGenerator.mjs +129 -0
  54. package/build/VideoFrameGenerator.mjs.map +1 -0
  55. package/build/index.cjs +6315 -0
  56. package/build/index.cjs.map +1 -0
  57. package/build/index.d.cts +1 -0
  58. package/build/index.d.mts +31 -0
  59. package/build/index.d.mts.map +1 -0
  60. package/build/index.mjs +6292 -0
  61. package/build/index.mjs.map +1 -0
  62. package/build/tools-CYLlbo9J.mjs +79 -0
  63. package/build/tools-CYLlbo9J.mjs.map +1 -0
  64. package/build/tools-DQrZvGBN.cjs +138 -0
  65. package/build/tools-DQrZvGBN.cjs.map +1 -0
  66. package/package.json +213 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
+
5
+ ### 0.0.4 (2026-05-25)
package/README.md ADDED
@@ -0,0 +1,43 @@
1
+ # @sarakusha/ebml
2
+
3
+ Yet another library for parsing [EBML](http://ebml.sourceforge.net/). The main difference from existing libraries is browser support.
4
+ Instead of a [Node Stream API](https://nodejs.org/api/stream.html#stream_class_stream_transform) and buffers, the [Web Streams API](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API) and typed arrays (```Uint8Array```) are used. Of course you can use it for node.js too. Another difference is that the library is built automatically from official [EBML](https://raw.githubusercontent.com/ietf-wg-cellar/ebml-specification/master/ebml.xml) and [matroska](https://raw.githubusercontent.com/ietf-wg-cellar/matroska-specification/master/ebml_matroska.xml) specifications.
5
+
6
+ > This library is written in typescript from scratch and is not a fork of existing libraries.
7
+
8
+ # Caveat
9
+ This version of the library only supports EBML decoding.
10
+
11
+ # Usage
12
+
13
+ The EbmlDecoder class is implemented as a [```TransformStream``` ](https://developer.mozilla.org/en-US/docs/Web/API/TransformStream) of the Streams API. The input to this transform function should be binary EBML, provided in a Uint8Array. The output of the stream is a series of ```Element``` objects.
14
+
15
+ ```ts
16
+ // The base interface
17
+ interface Element {
18
+ // The id of the EBML tag in hexadecimal format.
19
+ id: HexID;
20
+ // The data type of the EBML tag
21
+ type: ElementType;
22
+ // The name of the EBML tag
23
+ name: string;
24
+ // The total size of the tag in bytes
25
+ size: number;
26
+ // Tag attributes from the official specification.
27
+ spec?: ElementSpec;
28
+ }
29
+
30
+ type ElementType =
31
+ | 'master' /* master element (contains other EBML sub-elements of the next lower level) */
32
+ | 'uinteger' /* unsigned integer. Some of these are UIDs, coded as 128-bit numbers */
33
+ | 'integer' /* signed integer */
34
+ | 'float' /* IEEE-754 floating point number */
35
+ | 'string' /* printable ASCII text string */
36
+ | 'utf-8' /* printable utf-8 Unicode text string */
37
+ | 'date' /* a 64-bit signed timestamp, in nanoseconds after (or before) `2001-01-01T00:00UTC` */
38
+ | 'binary' /* binary data, otherwise uninterpreted */
39
+ | 'unknown';
40
+ ```
41
+ There are two base 'flavors' of `Element`:
42
+ * ```MasterElement``` is element that contains one or more child elements.
43
+ * ```ContentElement``` is a tag element only contains data.
@@ -0,0 +1,14 @@
1
+ Object.defineProperties(exports, {
2
+ __esModule: { value: true },
3
+ [Symbol.toStringTag]: { value: "Module" }
4
+ });
5
+ //#region src/CancelError.ts
6
+ var CancelError = class extends Error {
7
+ constructor(message = "Canceled by user") {
8
+ super(message);
9
+ }
10
+ };
11
+ //#endregion
12
+ exports.default = CancelError;
13
+
14
+ //# sourceMappingURL=CancelError.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CancelError.cjs","names":[],"sources":["../src/CancelError.ts"],"sourcesContent":["export default class CancelError extends Error {\n constructor(message = 'Canceled by user') {\n super(message);\n }\n}\n"],"mappings":";;;;;AAAA,IAAqB,cAArB,cAAyC,MAAM;CAC7C,YAAY,UAAU,oBAAoB;EACxC,MAAM,OAAO;CACf;AACF"}
@@ -0,0 +1 @@
1
+ export type * from './CancelError.d.mts'
@@ -0,0 +1,7 @@
1
+ //#region src/CancelError.d.ts
2
+ declare class CancelError extends Error {
3
+ constructor(message?: string);
4
+ }
5
+ //#endregion
6
+ export { CancelError as default };
7
+ //# sourceMappingURL=CancelError.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CancelError.d.mts","names":[],"sources":["../src/CancelError.ts"],"mappings":";cAAqB,WAAA,SAAoB,KAAK;cAChC,OAAA;AAAA"}
@@ -0,0 +1,10 @@
1
+ //#region src/CancelError.ts
2
+ var CancelError = class extends Error {
3
+ constructor(message = "Canceled by user") {
4
+ super(message);
5
+ }
6
+ };
7
+ //#endregion
8
+ export { CancelError as default };
9
+
10
+ //# sourceMappingURL=CancelError.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CancelError.mjs","names":[],"sources":["../src/CancelError.ts"],"sourcesContent":["export default class CancelError extends Error {\n constructor(message = 'Canceled by user') {\n super(message);\n }\n}\n"],"mappings":";AAAA,IAAqB,cAArB,cAAyC,MAAM;CAC7C,YAAY,UAAU,oBAAoB;EACxC,MAAM,OAAO;CACf;AACF"}
@@ -0,0 +1,28 @@
1
+ //#region src/Deferred.ts
2
+ var Deferred = class {
3
+ promise;
4
+ #resolve;
5
+ #reject;
6
+ constructor() {
7
+ this.promise = new Promise((resolve, reject) => {
8
+ this.#resolve = resolve;
9
+ this.#reject = reject;
10
+ });
11
+ }
12
+ resolve = (result) => {
13
+ const resolve = this.#resolve;
14
+ this.#resolve = void 0;
15
+ this.#reject = void 0;
16
+ if (resolve) resolve(result);
17
+ };
18
+ reject = (err) => {
19
+ const reject = this.#reject;
20
+ this.#resolve = void 0;
21
+ this.#reject = void 0;
22
+ if (reject) reject(err);
23
+ };
24
+ };
25
+ //#endregion
26
+ export { Deferred as t };
27
+
28
+ //# sourceMappingURL=Deferred-7Cu0KIje.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Deferred-7Cu0KIje.mjs","names":["#resolve","#reject"],"sources":["../src/Deferred.ts"],"sourcesContent":["export default class Deferred<T = void> {\n readonly promise: Promise<T>;\n\n #resolve: undefined | ((result: T) => void);\n\n #reject: undefined | ((error: Error) => void);\n\n constructor() {\n this.promise = new Promise<T>((resolve, reject) => {\n this.#resolve = resolve;\n this.#reject = reject;\n });\n }\n\n readonly resolve = (result: T): void => {\n const resolve = this.#resolve;\n this.#resolve = undefined;\n this.#reject = undefined;\n if (resolve) {\n resolve(result);\n }\n };\n\n readonly reject = (err: Error): void => {\n const reject = this.#reject;\n this.#resolve = undefined;\n this.#reject = undefined;\n if (reject) {\n reject(err);\n }\n };\n}\n"],"mappings":";AAAA,IAAqB,WAArB,MAAwC;CACtC;CAEA;CAEA;CAEA,cAAc;EACZ,KAAK,UAAU,IAAI,SAAY,SAAS,WAAW;GACjD,KAAKA,WAAW;GAChB,KAAKC,UAAU;EACjB,CAAC;CACH;CAEA,WAAoB,WAAoB;EACtC,MAAM,UAAU,KAAKD;EACrB,KAAKA,WAAW,KAAA;EAChB,KAAKC,UAAU,KAAA;EACf,IAAI,SACF,QAAQ,MAAM;CAElB;CAEA,UAAmB,QAAqB;EACtC,MAAM,SAAS,KAAKA;EACpB,KAAKD,WAAW,KAAA;EAChB,KAAKC,UAAU,KAAA;EACf,IAAI,QACF,OAAO,GAAG;CAEd;AACF"}
@@ -0,0 +1,33 @@
1
+ //#region src/Deferred.ts
2
+ var Deferred = class {
3
+ promise;
4
+ #resolve;
5
+ #reject;
6
+ constructor() {
7
+ this.promise = new Promise((resolve, reject) => {
8
+ this.#resolve = resolve;
9
+ this.#reject = reject;
10
+ });
11
+ }
12
+ resolve = (result) => {
13
+ const resolve = this.#resolve;
14
+ this.#resolve = void 0;
15
+ this.#reject = void 0;
16
+ if (resolve) resolve(result);
17
+ };
18
+ reject = (err) => {
19
+ const reject = this.#reject;
20
+ this.#resolve = void 0;
21
+ this.#reject = void 0;
22
+ if (reject) reject(err);
23
+ };
24
+ };
25
+ //#endregion
26
+ Object.defineProperty(exports, "Deferred", {
27
+ enumerable: true,
28
+ get: function() {
29
+ return Deferred;
30
+ }
31
+ });
32
+
33
+ //# sourceMappingURL=Deferred-CB69mtbF.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Deferred-CB69mtbF.cjs","names":["#resolve","#reject"],"sources":["../src/Deferred.ts"],"sourcesContent":["export default class Deferred<T = void> {\n readonly promise: Promise<T>;\n\n #resolve: undefined | ((result: T) => void);\n\n #reject: undefined | ((error: Error) => void);\n\n constructor() {\n this.promise = new Promise<T>((resolve, reject) => {\n this.#resolve = resolve;\n this.#reject = reject;\n });\n }\n\n readonly resolve = (result: T): void => {\n const resolve = this.#resolve;\n this.#resolve = undefined;\n this.#reject = undefined;\n if (resolve) {\n resolve(result);\n }\n };\n\n readonly reject = (err: Error): void => {\n const reject = this.#reject;\n this.#resolve = undefined;\n this.#reject = undefined;\n if (reject) {\n reject(err);\n }\n };\n}\n"],"mappings":";AAAA,IAAqB,WAArB,MAAwC;CACtC;CAEA;CAEA;CAEA,cAAc;EACZ,KAAK,UAAU,IAAI,SAAY,SAAS,WAAW;GACjD,KAAKA,WAAW;GAChB,KAAKC,UAAU;EACjB,CAAC;CACH;CAEA,WAAoB,WAAoB;EACtC,MAAM,UAAU,KAAKD;EACrB,KAAKA,WAAW,KAAA;EAChB,KAAKC,UAAU,KAAA;EACf,IAAI,SACF,QAAQ,MAAM;CAElB;CAEA,UAAmB,QAAqB;EACtC,MAAM,SAAS,KAAKA;EACpB,KAAKD,WAAW,KAAA;EAChB,KAAKC,UAAU,KAAA;EACf,IAAI,QACF,OAAO,GAAG;CAEd;AACF"}
@@ -0,0 +1,73 @@
1
+ //#region src/Element.ts
2
+ let BlockLacing = /* @__PURE__ */ function(BlockLacing) {
3
+ BlockLacing[BlockLacing["None"] = 0] = "None";
4
+ BlockLacing[BlockLacing["Xiph"] = 1] = "Xiph";
5
+ BlockLacing[BlockLacing["EBML"] = 2] = "EBML";
6
+ BlockLacing[BlockLacing["FixedSize"] = 3] = "FixedSize";
7
+ return BlockLacing;
8
+ }({});
9
+ const isMasterElement = (element) => element.type === "master";
10
+ const isContentElement = (element) => element.type !== "master";
11
+ const isBlockElement = (element) => element.id === "0xA1";
12
+ const isBlockGroupElement = (element) => element.name === "BlockGroup";
13
+ const isSimpleBlockElement = (element) => element.id === "0xA3";
14
+ const isTrackType = (value) => value.name === "TrackType";
15
+ const isTimestamp = (value) => value.name === "Timestamp";
16
+ const isDuration = (value) => value.name === "Duration";
17
+ //#endregion
18
+ Object.defineProperty(exports, "BlockLacing", {
19
+ enumerable: true,
20
+ get: function() {
21
+ return BlockLacing;
22
+ }
23
+ });
24
+ Object.defineProperty(exports, "isBlockElement", {
25
+ enumerable: true,
26
+ get: function() {
27
+ return isBlockElement;
28
+ }
29
+ });
30
+ Object.defineProperty(exports, "isBlockGroupElement", {
31
+ enumerable: true,
32
+ get: function() {
33
+ return isBlockGroupElement;
34
+ }
35
+ });
36
+ Object.defineProperty(exports, "isContentElement", {
37
+ enumerable: true,
38
+ get: function() {
39
+ return isContentElement;
40
+ }
41
+ });
42
+ Object.defineProperty(exports, "isDuration", {
43
+ enumerable: true,
44
+ get: function() {
45
+ return isDuration;
46
+ }
47
+ });
48
+ Object.defineProperty(exports, "isMasterElement", {
49
+ enumerable: true,
50
+ get: function() {
51
+ return isMasterElement;
52
+ }
53
+ });
54
+ Object.defineProperty(exports, "isSimpleBlockElement", {
55
+ enumerable: true,
56
+ get: function() {
57
+ return isSimpleBlockElement;
58
+ }
59
+ });
60
+ Object.defineProperty(exports, "isTimestamp", {
61
+ enumerable: true,
62
+ get: function() {
63
+ return isTimestamp;
64
+ }
65
+ });
66
+ Object.defineProperty(exports, "isTrackType", {
67
+ enumerable: true,
68
+ get: function() {
69
+ return isTrackType;
70
+ }
71
+ });
72
+
73
+ //# sourceMappingURL=Element-8JyOKTYb.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Element-8JyOKTYb.cjs","names":[],"sources":["../src/Element.ts"],"sourcesContent":["import type { ElementSpec, ElementType, HexID } from './ElementSpec';\n\nexport const enum BlockLacing {\n None,\n Xiph,\n EBML,\n FixedSize,\n}\n\ninterface ContentTypeMap extends Record<ElementType, number | bigint | string | Date | Uint8Array> {\n uinteger: number | bigint;\n integer: number | bigint;\n float: number;\n string: string;\n 'utf-8': string;\n date: Date;\n binary: number;\n unknown: Uint8Array;\n}\n\nexport interface Element {\n id: HexID;\n type: ElementType;\n name: string;\n size: number;\n spec?: ElementSpec;\n}\n\ntype ContentElementType = Exclude<ElementType, 'master'>;\n\nexport interface ContentElement<T extends ContentElementType = ContentElementType> extends Element {\n type: T;\n data: Uint8Array;\n value: ContentTypeMap[T];\n}\n\nexport interface MasterElement extends Element {\n type: 'master';\n isClosing?: true;\n}\n\nexport interface BlockElement extends ContentElement<'binary'> {\n id: '0xA1';\n /** the coded information in the element */\n payload: Uint8Array;\n /** unsigned integer indicating the payload's track */\n track: number;\n /** the block's Timecode value */\n value: number;\n /** the codec SHOULD decode this frame but not display it */\n invisible?: true;\n /** Lacing is only useful for small contiguous data to save space.\n * This is usually the case for audio tracks and not the case for\n * video -- which use a lot of data -- or subtitle tracks -- which have long gaps. */\n lacing?: BlockLacing;\n}\n\nexport interface SimpleBlockElement extends Omit<BlockElement, 'id'> {\n id: '0xA3';\n /** set to `true` if the payload starts an I frame */\n keyframe?: true;\n /** the frames of the Block can be discarded during playing if needed */\n discardable?: true;\n}\n\nexport const isMasterElement = (element: Element): element is MasterElement =>\n element.type === 'master';\n\nexport const isContentElement = (element: Element): element is ContentElement<ContentElementType> =>\n element.type !== 'master';\n\nexport const isBlockElement = (element: Element): element is BlockElement => element.id === '0xA1';\n\nexport const isBlockGroupElement = (element: Element): element is MasterElement =>\n element.name === 'BlockGroup';\n\nexport const isSimpleBlockElement = (element: Element): element is SimpleBlockElement =>\n element.id === '0xA3';\n\nexport const isTrackType = (value: Element): value is ContentElement<'uinteger'> =>\n value.name === 'TrackType';\n\nexport const isTimestamp = (value: Element): value is ContentElement<'uinteger'> =>\n value.name === 'Timestamp';\n\nexport const isDuration = (value: Element): value is ContentElement<'float'> =>\n value.name === 'Duration';\n"],"mappings":";AAEA,IAAkB,cAAX,yBAAA,aAAA;CACL,YAAA,YAAA,UAAA,KAAA;CACA,YAAA,YAAA,UAAA,KAAA;CACA,YAAA,YAAA,UAAA,KAAA;CACA,YAAA,YAAA,eAAA,KAAA;;AACF,EAAA,CAAA,CAAA;AA0DA,MAAa,mBAAmB,YAC9B,QAAQ,SAAS;AAEnB,MAAa,oBAAoB,YAC/B,QAAQ,SAAS;AAEnB,MAAa,kBAAkB,YAA8C,QAAQ,OAAO;AAE5F,MAAa,uBAAuB,YAClC,QAAQ,SAAS;AAEnB,MAAa,wBAAwB,YACnC,QAAQ,OAAO;AAEjB,MAAa,eAAe,UAC1B,MAAM,SAAS;AAEjB,MAAa,eAAe,UAC1B,MAAM,SAAS;AAEjB,MAAa,cAAc,UACzB,MAAM,SAAS"}
@@ -0,0 +1,134 @@
1
+ //#region src/ElementSpec.d.ts
2
+ type ElementType = 'master' | 'uinteger' | 'integer' | 'float' | 'string' | 'utf-8' | 'date' | 'binary' | 'unknown';
3
+ type HexID = `0x${string}`;
4
+ type Count = `${bigint}`;
5
+ type TRUE = '1';
6
+ type Purpose = 'definition' | 'rationale' | 'usage notes';
7
+ type Documentation<P extends Purpose = 'definition'> = {
8
+ '#text': string;
9
+ '@_lang': string;
10
+ '@_purpose': P;
11
+ };
12
+ type ExtraDocumentation = [Documentation, Documentation<'rationale'> | Documentation<'usage notes'>];
13
+ type WebmExtension = {
14
+ '@_type': 'webmproject.org';
15
+ '@_webm': TRUE;
16
+ };
17
+ type MatroskaExtension = {
18
+ '@_type': 'libmatroska';
19
+ '@_cppname': string;
20
+ };
21
+ type DivXExtension = {
22
+ '@_type': 'divx.com';
23
+ '@_divx': TRUE;
24
+ };
25
+ type StreamCopyExtension = {
26
+ '@_type': 'stream copy';
27
+ '@_keep': TRUE;
28
+ };
29
+ type Extension = WebmExtension | MatroskaExtension | DivXExtension | StreamCopyExtension;
30
+ type EnumValue = {
31
+ documentation?: Documentation | Documentation[];
32
+ '@_value': string;
33
+ '@_label': string;
34
+ };
35
+ type EnumRestriction = {
36
+ enum: EnumValue[];
37
+ };
38
+ type Restriction = EnumRestriction;
39
+ type PathChain = `\\${string}`;
40
+ type MAXIMUM_ALLOWED_LEVEL = 8;
41
+ type Last<T extends string[]> = T extends [...unknown[], infer L] ? L : never;
42
+ type ConcatPrevious<T extends string[]> = Last<T> extends string ? `${Last<T>}${PathChain}` : never;
43
+ type Mapped<N extends number, Result extends string[] = [PathChain]> = Result['length'] extends N ? Result : Mapped<N, [...Result, ConcatPrevious<Result>]>;
44
+ /**
45
+ * https://stackoverflow.com/a/70720063/5267202
46
+ */
47
+ type Path = Mapped<MAXIMUM_ALLOWED_LEVEL>[number];
48
+ type ElementSpec = {
49
+ '@_name': string;
50
+ '@_path': Path;
51
+ '@_id': HexID;
52
+ '@_type': ElementType;
53
+ '@_range'?: string;
54
+ '@_default'?: string;
55
+ '@_minOccurs'?: Count;
56
+ '@_maxOccurs'?: Count;
57
+ '@_length'?: Count;
58
+ '@_minver'?: Count;
59
+ '@_maxver'?: Count;
60
+ '@_unknownsizeallowed'?: TRUE;
61
+ '@_recurring'?: TRUE;
62
+ '@_recursive'?: TRUE;
63
+ documentation?: Documentation | ExtraDocumentation;
64
+ extension?: Extension | Extension[];
65
+ restriction?: Restriction;
66
+ };
67
+ //#endregion
68
+ //#region src/Element.d.ts
69
+ declare const enum BlockLacing {
70
+ None = 0,
71
+ Xiph = 1,
72
+ EBML = 2,
73
+ FixedSize = 3
74
+ }
75
+ interface ContentTypeMap extends Record<ElementType, number | bigint | string | Date | Uint8Array> {
76
+ uinteger: number | bigint;
77
+ integer: number | bigint;
78
+ float: number;
79
+ string: string;
80
+ 'utf-8': string;
81
+ date: Date;
82
+ binary: number;
83
+ unknown: Uint8Array;
84
+ }
85
+ interface Element {
86
+ id: HexID;
87
+ type: ElementType;
88
+ name: string;
89
+ size: number;
90
+ spec?: ElementSpec;
91
+ }
92
+ type ContentElementType = Exclude<ElementType, 'master'>;
93
+ interface ContentElement<T extends ContentElementType = ContentElementType> extends Element {
94
+ type: T;
95
+ data: Uint8Array;
96
+ value: ContentTypeMap[T];
97
+ }
98
+ interface MasterElement extends Element {
99
+ type: 'master';
100
+ isClosing?: true;
101
+ }
102
+ interface BlockElement extends ContentElement<'binary'> {
103
+ id: '0xA1';
104
+ /** the coded information in the element */
105
+ payload: Uint8Array;
106
+ /** unsigned integer indicating the payload's track */
107
+ track: number;
108
+ /** the block's Timecode value */
109
+ value: number;
110
+ /** the codec SHOULD decode this frame but not display it */
111
+ invisible?: true;
112
+ /** Lacing is only useful for small contiguous data to save space.
113
+ * This is usually the case for audio tracks and not the case for
114
+ * video -- which use a lot of data -- or subtitle tracks -- which have long gaps. */
115
+ lacing?: BlockLacing;
116
+ }
117
+ interface SimpleBlockElement extends Omit<BlockElement, 'id'> {
118
+ id: '0xA3';
119
+ /** set to `true` if the payload starts an I frame */
120
+ keyframe?: true;
121
+ /** the frames of the Block can be discarded during playing if needed */
122
+ discardable?: true;
123
+ }
124
+ declare const isMasterElement: (element: Element) => element is MasterElement;
125
+ declare const isContentElement: (element: Element) => element is ContentElement<ContentElementType>;
126
+ declare const isBlockElement: (element: Element) => element is BlockElement;
127
+ declare const isBlockGroupElement: (element: Element) => element is MasterElement;
128
+ declare const isSimpleBlockElement: (element: Element) => element is SimpleBlockElement;
129
+ declare const isTrackType: (value: Element) => value is ContentElement<"uinteger">;
130
+ declare const isTimestamp: (value: Element) => value is ContentElement<"uinteger">;
131
+ declare const isDuration: (value: Element) => value is ContentElement<"float">;
132
+ //#endregion
133
+ export { MasterElement as a, isBlockGroupElement as c, isMasterElement as d, isSimpleBlockElement as f, Element as i, isContentElement as l, isTrackType as m, BlockLacing as n, SimpleBlockElement as o, isTimestamp as p, ContentElement as r, isBlockElement as s, BlockElement as t, isDuration as u };
134
+ //# sourceMappingURL=Element-CC4E6wMR.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Element-CC4E6wMR.d.mts","names":[],"sources":["../src/ElementSpec.ts","../src/Element.ts"],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ //#region src/Element.ts
2
+ let BlockLacing = /* @__PURE__ */ function(BlockLacing) {
3
+ BlockLacing[BlockLacing["None"] = 0] = "None";
4
+ BlockLacing[BlockLacing["Xiph"] = 1] = "Xiph";
5
+ BlockLacing[BlockLacing["EBML"] = 2] = "EBML";
6
+ BlockLacing[BlockLacing["FixedSize"] = 3] = "FixedSize";
7
+ return BlockLacing;
8
+ }({});
9
+ const isMasterElement = (element) => element.type === "master";
10
+ const isContentElement = (element) => element.type !== "master";
11
+ const isBlockElement = (element) => element.id === "0xA1";
12
+ const isBlockGroupElement = (element) => element.name === "BlockGroup";
13
+ const isSimpleBlockElement = (element) => element.id === "0xA3";
14
+ const isTrackType = (value) => value.name === "TrackType";
15
+ const isTimestamp = (value) => value.name === "Timestamp";
16
+ const isDuration = (value) => value.name === "Duration";
17
+ //#endregion
18
+ export { isDuration as a, isTimestamp as c, isContentElement as i, isTrackType as l, isBlockElement as n, isMasterElement as o, isBlockGroupElement as r, isSimpleBlockElement as s, BlockLacing as t };
19
+
20
+ //# sourceMappingURL=Element-ChEar-fo.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Element-ChEar-fo.mjs","names":[],"sources":["../src/Element.ts"],"sourcesContent":["import type { ElementSpec, ElementType, HexID } from './ElementSpec';\n\nexport const enum BlockLacing {\n None,\n Xiph,\n EBML,\n FixedSize,\n}\n\ninterface ContentTypeMap extends Record<ElementType, number | bigint | string | Date | Uint8Array> {\n uinteger: number | bigint;\n integer: number | bigint;\n float: number;\n string: string;\n 'utf-8': string;\n date: Date;\n binary: number;\n unknown: Uint8Array;\n}\n\nexport interface Element {\n id: HexID;\n type: ElementType;\n name: string;\n size: number;\n spec?: ElementSpec;\n}\n\ntype ContentElementType = Exclude<ElementType, 'master'>;\n\nexport interface ContentElement<T extends ContentElementType = ContentElementType> extends Element {\n type: T;\n data: Uint8Array;\n value: ContentTypeMap[T];\n}\n\nexport interface MasterElement extends Element {\n type: 'master';\n isClosing?: true;\n}\n\nexport interface BlockElement extends ContentElement<'binary'> {\n id: '0xA1';\n /** the coded information in the element */\n payload: Uint8Array;\n /** unsigned integer indicating the payload's track */\n track: number;\n /** the block's Timecode value */\n value: number;\n /** the codec SHOULD decode this frame but not display it */\n invisible?: true;\n /** Lacing is only useful for small contiguous data to save space.\n * This is usually the case for audio tracks and not the case for\n * video -- which use a lot of data -- or subtitle tracks -- which have long gaps. */\n lacing?: BlockLacing;\n}\n\nexport interface SimpleBlockElement extends Omit<BlockElement, 'id'> {\n id: '0xA3';\n /** set to `true` if the payload starts an I frame */\n keyframe?: true;\n /** the frames of the Block can be discarded during playing if needed */\n discardable?: true;\n}\n\nexport const isMasterElement = (element: Element): element is MasterElement =>\n element.type === 'master';\n\nexport const isContentElement = (element: Element): element is ContentElement<ContentElementType> =>\n element.type !== 'master';\n\nexport const isBlockElement = (element: Element): element is BlockElement => element.id === '0xA1';\n\nexport const isBlockGroupElement = (element: Element): element is MasterElement =>\n element.name === 'BlockGroup';\n\nexport const isSimpleBlockElement = (element: Element): element is SimpleBlockElement =>\n element.id === '0xA3';\n\nexport const isTrackType = (value: Element): value is ContentElement<'uinteger'> =>\n value.name === 'TrackType';\n\nexport const isTimestamp = (value: Element): value is ContentElement<'uinteger'> =>\n value.name === 'Timestamp';\n\nexport const isDuration = (value: Element): value is ContentElement<'float'> =>\n value.name === 'Duration';\n"],"mappings":";AAEA,IAAkB,cAAX,yBAAA,aAAA;CACL,YAAA,YAAA,UAAA,KAAA;CACA,YAAA,YAAA,UAAA,KAAA;CACA,YAAA,YAAA,UAAA,KAAA;CACA,YAAA,YAAA,eAAA,KAAA;;AACF,EAAA,CAAA,CAAA;AA0DA,MAAa,mBAAmB,YAC9B,QAAQ,SAAS;AAEnB,MAAa,oBAAoB,YAC/B,QAAQ,SAAS;AAEnB,MAAa,kBAAkB,YAA8C,QAAQ,OAAO;AAE5F,MAAa,uBAAuB,YAClC,QAAQ,SAAS;AAEnB,MAAa,wBAAwB,YACnC,QAAQ,OAAO;AAEjB,MAAa,eAAe,UAC1B,MAAM,SAAS;AAEjB,MAAa,eAAe,UAC1B,MAAM,SAAS;AAEjB,MAAa,cAAc,UACzB,MAAM,SAAS"}
@@ -0,0 +1,90 @@
1
+ Object.defineProperties(exports, {
2
+ __esModule: { value: true },
3
+ [Symbol.toStringTag]: { value: "Module" }
4
+ });
5
+ const require_Deferred = require("./Deferred-CB69mtbF.cjs");
6
+ //#region src/FadeTransform.ts
7
+ const easeOutCubic = (t, b, c, d) => c * ((t = t / d - 1) * t * t + 1) + b;
8
+ var FadeTransform = class extends TransformStream {
9
+ setDisableFadeOut;
10
+ constructor({ disableIn, disableOut, duration: fadeDuration = 200 } = {}) {
11
+ let deferred;
12
+ let last;
13
+ let ctx = null;
14
+ let init = {};
15
+ let disableFadeOut = disableOut;
16
+ const initialize = (chunk) => {
17
+ if (!ctx) ctx = new OffscreenCanvas(chunk.displayWidth, chunk.displayHeight).getContext("2d");
18
+ if (!init) {
19
+ const { displayWidth, displayHeight, visibleRect, duration, timestamp } = chunk;
20
+ init = {
21
+ displayWidth,
22
+ displayHeight,
23
+ visibleRect: visibleRect ?? void 0,
24
+ duration: duration ?? void 0,
25
+ timestamp: timestamp ?? void 0
26
+ };
27
+ }
28
+ };
29
+ super({
30
+ transform(chunk, controller) {
31
+ if (!disableFadeOut) {
32
+ last?.close();
33
+ last = chunk.clone();
34
+ }
35
+ const timestamp = chunk.timestamp ? chunk.timestamp : 0;
36
+ if (!disableIn && timestamp / 1e3 < fadeDuration) {
37
+ if (!ctx) initialize(chunk);
38
+ if (ctx) {
39
+ const brightness = easeOutCubic(timestamp / 1e3, 0, 100, fadeDuration);
40
+ ctx.filter = `brightness(${brightness}%)`;
41
+ ctx.drawImage(chunk, 0, 0);
42
+ chunk.close();
43
+ init.timestamp = timestamp;
44
+ const frame = new VideoFrame(ctx.canvas, init);
45
+ controller.enqueue(frame);
46
+ return;
47
+ }
48
+ }
49
+ controller.enqueue(chunk);
50
+ },
51
+ flush: async (controller) => {
52
+ if (last && last.timestamp && !disableFadeOut) {
53
+ if (!ctx) initialize(last);
54
+ if (ctx) {
55
+ deferred = new require_Deferred.Deferred();
56
+ const context = ctx;
57
+ const orig = last;
58
+ const { timestamp: start } = last;
59
+ const duration = last.duration ? last.duration / 1e3 : 33;
60
+ const fadeOut = (time) => {
61
+ context.filter = `brightness(${easeOutCubic(Math.max(0, fadeDuration - time), 0, 100, fadeDuration)}%)`;
62
+ context.drawImage(orig, 0, 0);
63
+ init.timestamp = start + time * 1e3;
64
+ const frame = new VideoFrame(context.canvas, init);
65
+ controller.enqueue(frame);
66
+ const next = time + duration;
67
+ if (next > fadeDuration) {
68
+ orig.close();
69
+ deferred?.resolve();
70
+ } else setTimeout(() => fadeOut(next), 0);
71
+ };
72
+ fadeOut(duration);
73
+ }
74
+ }
75
+ await deferred?.promise;
76
+ }
77
+ });
78
+ this.setDisableFadeOut = (value) => {
79
+ disableFadeOut = value;
80
+ if (disableFadeOut) {
81
+ last?.close();
82
+ last = void 0;
83
+ }
84
+ };
85
+ }
86
+ };
87
+ //#endregion
88
+ exports.default = FadeTransform;
89
+
90
+ //# sourceMappingURL=FadeTransform.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FadeTransform.cjs","names":["Deferred"],"sources":["../src/FadeTransform.ts"],"sourcesContent":["import Deferred from './Deferred';\n\nexport type FadeOptions = {\n disableIn?: boolean;\n disableOut?: boolean;\n duration?: number;\n};\n\nconst easeOutCubic = (t: number, b: number, c: number, d: number) =>\n // eslint-disable-next-line no-param-reassign\n c * ((t = t / d - 1) * t * t + 1) + b;\n\nexport default class FadeTransform extends TransformStream<VideoFrame, VideoFrame> {\n setDisableFadeOut: (value?: boolean) => void;\n\n constructor({ disableIn, disableOut, duration: fadeDuration = 200 }: FadeOptions = {}) {\n let deferred: Deferred | undefined;\n let last: VideoFrame | undefined;\n let ctx: OffscreenCanvasRenderingContext2D | null = null;\n let init: VideoFrameInit = {};\n let disableFadeOut = disableOut;\n const initialize = (chunk: VideoFrame): void => {\n if (!ctx) {\n const offscreen = new OffscreenCanvas(chunk.displayWidth, chunk.displayHeight);\n ctx = offscreen.getContext('2d');\n }\n if (!init) {\n const { displayWidth, displayHeight, visibleRect, duration, timestamp } = chunk;\n init = {\n displayWidth,\n displayHeight,\n visibleRect: visibleRect ?? undefined,\n duration: duration ?? undefined,\n timestamp: timestamp ?? undefined,\n };\n }\n };\n super({\n transform(chunk, controller) {\n if (!disableFadeOut) {\n last?.close();\n last = chunk.clone();\n }\n const timestamp = chunk.timestamp ? chunk.timestamp : 0;\n if (!disableIn && timestamp / 1000 < fadeDuration) {\n if (!ctx) initialize(chunk);\n if (ctx) {\n const brightness = easeOutCubic(timestamp / 1000, 0, 100, fadeDuration);\n ctx.filter = `brightness(${brightness}%)`;\n ctx.drawImage(chunk, 0, 0);\n chunk.close();\n init.timestamp = timestamp;\n const frame = new VideoFrame(ctx.canvas as unknown as ImageBitmap, init);\n controller.enqueue(frame);\n return;\n }\n }\n controller.enqueue(chunk);\n },\n flush: async (controller) => {\n if (last && last.timestamp && !disableFadeOut) {\n if (!ctx) initialize(last);\n if (ctx) {\n deferred = new Deferred();\n const context = ctx;\n const orig = last;\n const { timestamp: start } = last;\n const duration = last.duration ? last.duration / 1000 : 33;\n const fadeOut = (time: number) => {\n const brightness = easeOutCubic(\n Math.max(0, fadeDuration - time),\n 0,\n 100,\n fadeDuration,\n );\n context.filter = `brightness(${brightness}%)`;\n context.drawImage(orig, 0, 0);\n init.timestamp = start + time * 1000;\n const frame = new VideoFrame(context.canvas as unknown as ImageBitmap, init);\n controller.enqueue(frame);\n const next = time + duration;\n if (next > fadeDuration) {\n orig.close();\n deferred?.resolve();\n } else setTimeout(() => fadeOut(next), 0);\n };\n fadeOut(duration);\n }\n }\n await deferred?.promise;\n },\n });\n this.setDisableFadeOut = (value?: boolean) => {\n disableFadeOut = value;\n if (disableFadeOut) {\n last?.close();\n last = undefined;\n }\n };\n }\n}\n"],"mappings":";;;;;;AAQA,MAAM,gBAAgB,GAAW,GAAW,GAAW,MAErD,MAAM,IAAI,IAAI,IAAI,KAAK,IAAI,IAAI,KAAK;AAEtC,IAAqB,gBAArB,cAA2C,gBAAwC;CACjF;CAEA,YAAY,EAAE,WAAW,YAAY,UAAU,eAAe,QAAqB,CAAC,GAAG;EACrF,IAAI;EACJ,IAAI;EACJ,IAAI,MAAgD;EACpD,IAAI,OAAuB,CAAC;EAC5B,IAAI,iBAAiB;EACrB,MAAM,cAAc,UAA4B;GAC9C,IAAI,CAAC,KAEH,MAAM,IADgB,gBAAgB,MAAM,cAAc,MAAM,aAClD,EAAE,WAAW,IAAI;GAEjC,IAAI,CAAC,MAAM;IACT,MAAM,EAAE,cAAc,eAAe,aAAa,UAAU,cAAc;IAC1E,OAAO;KACL;KACA;KACA,aAAa,eAAe,KAAA;KAC5B,UAAU,YAAY,KAAA;KACtB,WAAW,aAAa,KAAA;IAC1B;GACF;EACF;EACA,MAAM;GACJ,UAAU,OAAO,YAAY;IAC3B,IAAI,CAAC,gBAAgB;KACnB,MAAM,MAAM;KACZ,OAAO,MAAM,MAAM;IACrB;IACA,MAAM,YAAY,MAAM,YAAY,MAAM,YAAY;IACtD,IAAI,CAAC,aAAa,YAAY,MAAO,cAAc;KACjD,IAAI,CAAC,KAAK,WAAW,KAAK;KAC1B,IAAI,KAAK;MACP,MAAM,aAAa,aAAa,YAAY,KAAM,GAAG,KAAK,YAAY;MACtE,IAAI,SAAS,cAAc,WAAW;MACtC,IAAI,UAAU,OAAO,GAAG,CAAC;MACzB,MAAM,MAAM;MACZ,KAAK,YAAY;MACjB,MAAM,QAAQ,IAAI,WAAW,IAAI,QAAkC,IAAI;MACvE,WAAW,QAAQ,KAAK;MACxB;KACF;IACF;IACA,WAAW,QAAQ,KAAK;GAC1B;GACA,OAAO,OAAO,eAAe;IAC3B,IAAI,QAAQ,KAAK,aAAa,CAAC,gBAAgB;KAC7C,IAAI,CAAC,KAAK,WAAW,IAAI;KACzB,IAAI,KAAK;MACP,WAAW,IAAIA,iBAAAA,SAAS;MACxB,MAAM,UAAU;MAChB,MAAM,OAAO;MACb,MAAM,EAAE,WAAW,UAAU;MAC7B,MAAM,WAAW,KAAK,WAAW,KAAK,WAAW,MAAO;MACxD,MAAM,WAAW,SAAiB;OAOhC,QAAQ,SAAS,cANE,aACjB,KAAK,IAAI,GAAG,eAAe,IAAI,GAC/B,GACA,KACA,YAEsC,EAAE;OAC1C,QAAQ,UAAU,MAAM,GAAG,CAAC;OAC5B,KAAK,YAAY,QAAQ,OAAO;OAChC,MAAM,QAAQ,IAAI,WAAW,QAAQ,QAAkC,IAAI;OAC3E,WAAW,QAAQ,KAAK;OACxB,MAAM,OAAO,OAAO;OACpB,IAAI,OAAO,cAAc;QACvB,KAAK,MAAM;QACX,UAAU,QAAQ;OACpB,OAAO,iBAAiB,QAAQ,IAAI,GAAG,CAAC;MAC1C;MACA,QAAQ,QAAQ;KAClB;IACF;IACA,MAAM,UAAU;GAClB;EACF,CAAC;EACD,KAAK,qBAAqB,UAAoB;GAC5C,iBAAiB;GACjB,IAAI,gBAAgB;IAClB,MAAM,MAAM;IACZ,OAAO,KAAA;GACT;EACF;CACF;AACF"}
@@ -0,0 +1 @@
1
+ export type * from './FadeTransform.d.mts'
@@ -0,0 +1,17 @@
1
+ //#region src/FadeTransform.d.ts
2
+ type FadeOptions = {
3
+ disableIn?: boolean;
4
+ disableOut?: boolean;
5
+ duration?: number;
6
+ };
7
+ declare class FadeTransform extends TransformStream<VideoFrame, VideoFrame> {
8
+ setDisableFadeOut: (value?: boolean) => void;
9
+ constructor({
10
+ disableIn,
11
+ disableOut,
12
+ duration: fadeDuration
13
+ }?: FadeOptions);
14
+ }
15
+ //#endregion
16
+ export { FadeOptions, FadeTransform as default };
17
+ //# sourceMappingURL=FadeTransform.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FadeTransform.d.mts","names":[],"sources":["../src/FadeTransform.ts"],"mappings":";KAEY,WAAA;EACV,SAAA;EACA,UAAA;EACA,QAAA;AAAA;AAAA,cAOmB,aAAA,SAAsB,eAAA,CAAgB,UAAA,EAAY,UAAA;EACrE,iBAAA,GAAoB,KAAA;;IAEN,SAAA;IAAW,UAAA;IAAY,QAAA,EAAU;EAAA,IAAsB,WAAA;AAAA"}
@@ -0,0 +1,86 @@
1
+ import { t as Deferred } from "./Deferred-7Cu0KIje.mjs";
2
+ //#region src/FadeTransform.ts
3
+ const easeOutCubic = (t, b, c, d) => c * ((t = t / d - 1) * t * t + 1) + b;
4
+ var FadeTransform = class extends TransformStream {
5
+ setDisableFadeOut;
6
+ constructor({ disableIn, disableOut, duration: fadeDuration = 200 } = {}) {
7
+ let deferred;
8
+ let last;
9
+ let ctx = null;
10
+ let init = {};
11
+ let disableFadeOut = disableOut;
12
+ const initialize = (chunk) => {
13
+ if (!ctx) ctx = new OffscreenCanvas(chunk.displayWidth, chunk.displayHeight).getContext("2d");
14
+ if (!init) {
15
+ const { displayWidth, displayHeight, visibleRect, duration, timestamp } = chunk;
16
+ init = {
17
+ displayWidth,
18
+ displayHeight,
19
+ visibleRect: visibleRect ?? void 0,
20
+ duration: duration ?? void 0,
21
+ timestamp: timestamp ?? void 0
22
+ };
23
+ }
24
+ };
25
+ super({
26
+ transform(chunk, controller) {
27
+ if (!disableFadeOut) {
28
+ last?.close();
29
+ last = chunk.clone();
30
+ }
31
+ const timestamp = chunk.timestamp ? chunk.timestamp : 0;
32
+ if (!disableIn && timestamp / 1e3 < fadeDuration) {
33
+ if (!ctx) initialize(chunk);
34
+ if (ctx) {
35
+ const brightness = easeOutCubic(timestamp / 1e3, 0, 100, fadeDuration);
36
+ ctx.filter = `brightness(${brightness}%)`;
37
+ ctx.drawImage(chunk, 0, 0);
38
+ chunk.close();
39
+ init.timestamp = timestamp;
40
+ const frame = new VideoFrame(ctx.canvas, init);
41
+ controller.enqueue(frame);
42
+ return;
43
+ }
44
+ }
45
+ controller.enqueue(chunk);
46
+ },
47
+ flush: async (controller) => {
48
+ if (last && last.timestamp && !disableFadeOut) {
49
+ if (!ctx) initialize(last);
50
+ if (ctx) {
51
+ deferred = new Deferred();
52
+ const context = ctx;
53
+ const orig = last;
54
+ const { timestamp: start } = last;
55
+ const duration = last.duration ? last.duration / 1e3 : 33;
56
+ const fadeOut = (time) => {
57
+ context.filter = `brightness(${easeOutCubic(Math.max(0, fadeDuration - time), 0, 100, fadeDuration)}%)`;
58
+ context.drawImage(orig, 0, 0);
59
+ init.timestamp = start + time * 1e3;
60
+ const frame = new VideoFrame(context.canvas, init);
61
+ controller.enqueue(frame);
62
+ const next = time + duration;
63
+ if (next > fadeDuration) {
64
+ orig.close();
65
+ deferred?.resolve();
66
+ } else setTimeout(() => fadeOut(next), 0);
67
+ };
68
+ fadeOut(duration);
69
+ }
70
+ }
71
+ await deferred?.promise;
72
+ }
73
+ });
74
+ this.setDisableFadeOut = (value) => {
75
+ disableFadeOut = value;
76
+ if (disableFadeOut) {
77
+ last?.close();
78
+ last = void 0;
79
+ }
80
+ };
81
+ }
82
+ };
83
+ //#endregion
84
+ export { FadeTransform as default };
85
+
86
+ //# sourceMappingURL=FadeTransform.mjs.map