@ac-kit/format-osc 0.0.0-stage → 0.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.
Files changed (84) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/LICENSE +28 -0
  3. package/README.md +132 -2
  4. package/dist/errors.d.ts +34 -0
  5. package/dist/errors.d.ts.map +1 -0
  6. package/dist/errors.js +40 -0
  7. package/dist/errors.js.map +1 -0
  8. package/dist/framing/_decode-framed-packet.d.ts +9 -0
  9. package/dist/framing/_decode-framed-packet.d.ts.map +1 -0
  10. package/dist/framing/_decode-framed-packet.js +23 -0
  11. package/dist/framing/_decode-framed-packet.js.map +1 -0
  12. package/dist/framing/osc-datagram-codec.d.ts +17 -0
  13. package/dist/framing/osc-datagram-codec.d.ts.map +1 -0
  14. package/dist/framing/osc-datagram-codec.js +21 -0
  15. package/dist/framing/osc-datagram-codec.js.map +1 -0
  16. package/dist/framing/osc-datagram-decoder.d.ts +22 -0
  17. package/dist/framing/osc-datagram-decoder.d.ts.map +1 -0
  18. package/dist/framing/osc-datagram-decoder.js +26 -0
  19. package/dist/framing/osc-datagram-decoder.js.map +1 -0
  20. package/dist/framing/osc-datagram-encoder.d.ts +8 -0
  21. package/dist/framing/osc-datagram-encoder.d.ts.map +1 -0
  22. package/dist/framing/osc-datagram-encoder.js +9 -0
  23. package/dist/framing/osc-datagram-encoder.js.map +1 -0
  24. package/dist/framing/osc-size-prefixed-codec.d.ts +19 -0
  25. package/dist/framing/osc-size-prefixed-codec.d.ts.map +1 -0
  26. package/dist/framing/osc-size-prefixed-codec.js +23 -0
  27. package/dist/framing/osc-size-prefixed-codec.js.map +1 -0
  28. package/dist/framing/osc-size-prefixed-decoder.d.ts +40 -0
  29. package/dist/framing/osc-size-prefixed-decoder.d.ts.map +1 -0
  30. package/dist/framing/osc-size-prefixed-decoder.js +59 -0
  31. package/dist/framing/osc-size-prefixed-decoder.js.map +1 -0
  32. package/dist/framing/osc-size-prefixed-encoder.d.ts +10 -0
  33. package/dist/framing/osc-size-prefixed-encoder.d.ts.map +1 -0
  34. package/dist/framing/osc-size-prefixed-encoder.js +20 -0
  35. package/dist/framing/osc-size-prefixed-encoder.js.map +1 -0
  36. package/dist/index.d.ts +14 -0
  37. package/dist/index.d.ts.map +1 -0
  38. package/dist/index.js +14 -0
  39. package/dist/index.js.map +1 -0
  40. package/dist/packet/_bundle-marker.d.ts +3 -0
  41. package/dist/packet/_bundle-marker.d.ts.map +1 -0
  42. package/dist/packet/_bundle-marker.js +3 -0
  43. package/dist/packet/_bundle-marker.js.map +1 -0
  44. package/dist/packet/_osc-writer.d.ts +31 -0
  45. package/dist/packet/_osc-writer.d.ts.map +1 -0
  46. package/dist/packet/_osc-writer.js +72 -0
  47. package/dist/packet/_osc-writer.js.map +1 -0
  48. package/dist/packet/_read-osc-packet.d.ts +19 -0
  49. package/dist/packet/_read-osc-packet.d.ts.map +1 -0
  50. package/dist/packet/_read-osc-packet.js +290 -0
  51. package/dist/packet/_read-osc-packet.js.map +1 -0
  52. package/dist/packet/_write-osc-packet.d.ts +12 -0
  53. package/dist/packet/_write-osc-packet.d.ts.map +1 -0
  54. package/dist/packet/_write-osc-packet.js +155 -0
  55. package/dist/packet/_write-osc-packet.js.map +1 -0
  56. package/dist/packet/decode-osc-packet.d.ts +48 -0
  57. package/dist/packet/decode-osc-packet.d.ts.map +1 -0
  58. package/dist/packet/decode-osc-packet.js +39 -0
  59. package/dist/packet/decode-osc-packet.js.map +1 -0
  60. package/dist/packet/encode-osc-packet.d.ts +32 -0
  61. package/dist/packet/encode-osc-packet.d.ts.map +1 -0
  62. package/dist/packet/encode-osc-packet.js +37 -0
  63. package/dist/packet/encode-osc-packet.js.map +1 -0
  64. package/dist/packet/osc-packet.d.ts +104 -0
  65. package/dist/packet/osc-packet.d.ts.map +1 -0
  66. package/dist/packet/osc-packet.js +2 -0
  67. package/dist/packet/osc-packet.js.map +1 -0
  68. package/dist/time-tag/_ntp.d.ts +13 -0
  69. package/dist/time-tag/_ntp.d.ts.map +1 -0
  70. package/dist/time-tag/_ntp.js +19 -0
  71. package/dist/time-tag/_ntp.js.map +1 -0
  72. package/dist/time-tag/osc-time-tag-from-date.d.ts +29 -0
  73. package/dist/time-tag/osc-time-tag-from-date.d.ts.map +1 -0
  74. package/dist/time-tag/osc-time-tag-from-date.js +48 -0
  75. package/dist/time-tag/osc-time-tag-from-date.js.map +1 -0
  76. package/dist/time-tag/osc-time-tag-to-date.d.ts +21 -0
  77. package/dist/time-tag/osc-time-tag-to-date.d.ts.map +1 -0
  78. package/dist/time-tag/osc-time-tag-to-date.js +26 -0
  79. package/dist/time-tag/osc-time-tag-to-date.js.map +1 -0
  80. package/dist/time-tag/osc-time-tag.d.ts +29 -0
  81. package/dist/time-tag/osc-time-tag.d.ts.map +1 -0
  82. package/dist/time-tag/osc-time-tag.js +16 -0
  83. package/dist/time-tag/osc-time-tag.js.map +1 -0
  84. package/package.json +60 -3
@@ -0,0 +1,155 @@
1
+ import { encodeTextUtf8 } from "@ac-kit/core";
2
+ import { assertOscTimeTag_ } from "../time-tag/_ntp.js";
3
+ import { BUNDLE_MARKER_ } from "./_bundle-marker.js";
4
+ const INT32_MIN_ = -2147483648;
5
+ const INT32_MAX_ = 2147483647;
6
+ const INT64_MIN_ = -(2n ** 63n);
7
+ const INT64_MAX_ = 2n ** 63n - 1n;
8
+ const TYPE_TAGS_ = {
9
+ int32: "i",
10
+ float32: "f",
11
+ string: "s",
12
+ blob: "b",
13
+ int64: "h",
14
+ timeTag: "t",
15
+ float64: "d",
16
+ symbol: "S",
17
+ char: "c",
18
+ rgba: "r",
19
+ midi: "m",
20
+ true: "T",
21
+ false: "F",
22
+ nil: "N",
23
+ impulse: "I",
24
+ array: "[",
25
+ };
26
+ /**
27
+ * Appends `packet` to `writer` — the single implementation of the OSC write
28
+ * grammar, OSC 1.0 §"OSC Packets" through §"OSC Bundles".
29
+ *
30
+ * A type tag string is always written, `,` alone for no arguments, as OSC 1.1
31
+ * requires. Recursion depth is the caller's own nesting; nothing here bounds
32
+ * it.
33
+ */
34
+ export function writeOscPacket_(writer, packet) {
35
+ if (packet.kind === "message") {
36
+ if (!packet.address.startsWith("/")) {
37
+ throw new RangeError(`encodeOscPacket: address must begin with "/", got ${JSON.stringify(packet.address)}`);
38
+ }
39
+ writer.writePadded(encodeOscString_(packet.address, "address"), 1);
40
+ writer.writePadded(encodeTextUtf8(`,${typeTagsOf_(packet.arguments)}`), 1);
41
+ writeArguments_(writer, packet.arguments);
42
+ return;
43
+ }
44
+ assertOscTimeTag_(packet.timeTag, "encodeOscPacket: bundle time tag");
45
+ writer.writePadded(BUNDLE_MARKER_, 0);
46
+ writer.writeUint32(packet.timeTag.seconds);
47
+ writer.writeUint32(packet.timeTag.fraction);
48
+ for (const element of packet.elements) {
49
+ const sizeOffset = writer.allocate(4);
50
+ const start = writer.length;
51
+ writeOscPacket_(writer, element);
52
+ writer.patchUint32(sizeOffset, writer.length - start);
53
+ }
54
+ }
55
+ function typeTagsOf_(items) {
56
+ let tags = "";
57
+ for (const item of items) {
58
+ tags += TYPE_TAGS_[item.type];
59
+ if (item.type === "array") {
60
+ tags += `${typeTagsOf_(item.items)}]`;
61
+ }
62
+ }
63
+ return tags;
64
+ }
65
+ function writeArguments_(writer, items) {
66
+ for (const item of items) {
67
+ switch (item.type) {
68
+ case "int32":
69
+ if (!Number.isInteger(item.value) ||
70
+ item.value < INT32_MIN_ ||
71
+ item.value > INT32_MAX_) {
72
+ throw new RangeError(`encodeOscPacket: int32 must be an integer in -2^31..2^31-1, got ${item.value}`);
73
+ }
74
+ writer.writeUint32(item.value);
75
+ break;
76
+ case "float32":
77
+ writer.writeFloat32(item.value);
78
+ break;
79
+ case "string":
80
+ case "symbol":
81
+ writer.writePadded(encodeOscString_(item.value, item.type), 1);
82
+ break;
83
+ case "blob":
84
+ if (item.value.length > INT32_MAX_) {
85
+ throw new RangeError(`encodeOscPacket: blob of ${item.value.length} bytes exceeds the int32 size field`);
86
+ }
87
+ writer.writeUint32(item.value.length);
88
+ writer.writePadded(item.value, 0);
89
+ break;
90
+ case "int64":
91
+ if (item.value < INT64_MIN_ || item.value > INT64_MAX_) {
92
+ throw new RangeError(`encodeOscPacket: int64 must be in -2^63..2^63-1, got ${item.value}`);
93
+ }
94
+ writer.writeUint64(BigInt.asUintN(64, item.value));
95
+ break;
96
+ case "timeTag":
97
+ assertOscTimeTag_(item.value, "encodeOscPacket: timeTag argument");
98
+ writer.writeUint32(item.value.seconds);
99
+ writer.writeUint32(item.value.fraction);
100
+ break;
101
+ case "float64":
102
+ writer.writeFloat64(item.value);
103
+ break;
104
+ case "char":
105
+ writer.writeUint32(charCodePoint_(item.value));
106
+ break;
107
+ case "rgba":
108
+ writer.writeBytes4(byte_(item.red, "rgba red"), byte_(item.green, "rgba green"), byte_(item.blue, "rgba blue"), byte_(item.alpha, "rgba alpha"));
109
+ break;
110
+ case "midi":
111
+ writer.writeBytes4(byte_(item.port, "midi port"), byte_(item.status, "midi status"), byte_(item.data1, "midi data1"), byte_(item.data2, "midi data2"));
112
+ break;
113
+ case "true":
114
+ case "false":
115
+ case "nil":
116
+ case "impulse":
117
+ break;
118
+ case "array":
119
+ writeArguments_(writer, item.items);
120
+ break;
121
+ default:
122
+ item;
123
+ }
124
+ }
125
+ }
126
+ /**
127
+ * UTF-8 bytes of an OSC-string. A NUL would end the string early on the wire,
128
+ * and a lone surrogate would be replaced by U+FFFD, so both are refused rather
129
+ * than sent as something else.
130
+ */
131
+ function encodeOscString_(text, what) {
132
+ if (text.includes("\0")) {
133
+ throw new RangeError(`encodeOscPacket: ${what} contains a NUL character`);
134
+ }
135
+ if (!text.isWellFormed()) {
136
+ throw new RangeError(`encodeOscPacket: ${what} contains a lone surrogate`);
137
+ }
138
+ return encodeTextUtf8(text);
139
+ }
140
+ function charCodePoint_(value) {
141
+ const codePoint = value.codePointAt(0);
142
+ if (codePoint === undefined ||
143
+ value.length !== (codePoint > 0xffff ? 2 : 1) ||
144
+ (codePoint >= 0xd800 && codePoint <= 0xdfff)) {
145
+ throw new RangeError(`encodeOscPacket: char must be exactly one code point, got ${JSON.stringify(value)}`);
146
+ }
147
+ return codePoint;
148
+ }
149
+ function byte_(value, what) {
150
+ if (!Number.isInteger(value) || value < 0 || value > 0xff) {
151
+ throw new RangeError(`encodeOscPacket: ${what} must be an integer in 0..255, got ${value}`);
152
+ }
153
+ return value;
154
+ }
155
+ //# sourceMappingURL=_write-osc-packet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_write-osc-packet.js","sourceRoot":"","sources":["../../src/packet/_write-osc-packet.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ import type { OscPacket } from "./osc-packet.js";
2
+ /** Options for {@link decodeOscPacket} and the decoders built on it. */
3
+ export type DecodeOscPacketOptions = {
4
+ /**
5
+ * How many bundles and arrays may enclose one another, counted together: a
6
+ * top-level bundle is one level, an array in a message inside it a second. 0
7
+ * refuses every bundle and array. Defaults to 32 — no OSC implementation in
8
+ * use nests more than a few levels, and the bound keeps a hostile packet from
9
+ * exhausting the stack. Recursion depth, and so stack use, grows with it.
10
+ */
11
+ maxDepth?: number;
12
+ };
13
+ /**
14
+ * Decodes one whole OSC packet: the bytes of a datagram, or the content of a
15
+ * stream frame. For a transport, prefer the codecs, which handle the framing
16
+ * and report malformed packets as decode results.
17
+ *
18
+ * `bytes` must be exactly one packet; nothing after it is ignored. The decoder
19
+ * is strict where OSC is a network boundary:
20
+ *
21
+ * - Strings and blobs must be padded with NUL bytes, and a packet or bundle
22
+ * element must be a multiple of 4 bytes long;
23
+ * - An unknown type tag is an error, since the size of its data is unknowable;
24
+ * - Every bundle element must fit its bundle, and every argument its message;
25
+ * - Strings are decoded as UTF-8 and must be valid. OSC 1.0 specifies ASCII, of
26
+ * which UTF-8 is a superset, and UTF-8 is what OSC 1.1 implementations send.
27
+ * A byte order mark is kept as U+FEFF.
28
+ *
29
+ * A message with no type tag string, which OSC 1.0 asks receivers to tolerate
30
+ * from older senders, decodes with no arguments when nothing follows its
31
+ * address. If bytes do follow, their types cannot be known, and the message is
32
+ * an error rather than silently losing them.
33
+ *
34
+ * Time is O(n) in `bytes.length`. The result copies every blob, so it never
35
+ * aliases `bytes`.
36
+ *
37
+ * @example
38
+ * ```ts
39
+ * decodeOscPacket(datagram);
40
+ * // { kind: "message", address: "/oscillator/4/frequency", arguments: [{ type: "float32", value: 440 }] }
41
+ * ```;
42
+ *
43
+ * @throws {OscPacketError} When `bytes` is not a well-formed packet; its
44
+ * `offset` is the byte offset in `bytes` where decoding gave up.
45
+ * @throws {RangeError} When `options.maxDepth` is not a non-negative integer.
46
+ */
47
+ export declare function decodeOscPacket(bytes: Uint8Array, options?: DecodeOscPacketOptions): OscPacket;
48
+ //# sourceMappingURL=decode-osc-packet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decode-osc-packet.d.ts","sourceRoot":"","sources":["../../src/packet/decode-osc-packet.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,wEAAwE;AACxE,MAAM,MAAM,sBAAsB,GAAG;IACpC;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,eAAe,CAC9B,KAAK,EAAE,UAAU,EACjB,OAAO,CAAC,EAAE,sBAAsB,GAC9B,SAAS,CAEX"}
@@ -0,0 +1,39 @@
1
+ import { readOscPacket_, resolveMaxDepth_ } from "./_read-osc-packet.js";
2
+ /**
3
+ * Decodes one whole OSC packet: the bytes of a datagram, or the content of a
4
+ * stream frame. For a transport, prefer the codecs, which handle the framing
5
+ * and report malformed packets as decode results.
6
+ *
7
+ * `bytes` must be exactly one packet; nothing after it is ignored. The decoder
8
+ * is strict where OSC is a network boundary:
9
+ *
10
+ * - Strings and blobs must be padded with NUL bytes, and a packet or bundle
11
+ * element must be a multiple of 4 bytes long;
12
+ * - An unknown type tag is an error, since the size of its data is unknowable;
13
+ * - Every bundle element must fit its bundle, and every argument its message;
14
+ * - Strings are decoded as UTF-8 and must be valid. OSC 1.0 specifies ASCII, of
15
+ * which UTF-8 is a superset, and UTF-8 is what OSC 1.1 implementations send.
16
+ * A byte order mark is kept as U+FEFF.
17
+ *
18
+ * A message with no type tag string, which OSC 1.0 asks receivers to tolerate
19
+ * from older senders, decodes with no arguments when nothing follows its
20
+ * address. If bytes do follow, their types cannot be known, and the message is
21
+ * an error rather than silently losing them.
22
+ *
23
+ * Time is O(n) in `bytes.length`. The result copies every blob, so it never
24
+ * aliases `bytes`.
25
+ *
26
+ * @example
27
+ * ```ts
28
+ * decodeOscPacket(datagram);
29
+ * // { kind: "message", address: "/oscillator/4/frequency", arguments: [{ type: "float32", value: 440 }] }
30
+ * ```;
31
+ *
32
+ * @throws {OscPacketError} When `bytes` is not a well-formed packet; its
33
+ * `offset` is the byte offset in `bytes` where decoding gave up.
34
+ * @throws {RangeError} When `options.maxDepth` is not a non-negative integer.
35
+ */
36
+ export function decodeOscPacket(bytes, options) {
37
+ return readOscPacket_(bytes, resolveMaxDepth_(options?.maxDepth));
38
+ }
39
+ //# sourceMappingURL=decode-osc-packet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"decode-osc-packet.js","sourceRoot":"","sources":["../../src/packet/decode-osc-packet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAezE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,UAAU,eAAe,CAC9B,KAAiB,EACjB,OAAgC;IAEhC,OAAO,cAAc,CAAC,KAAK,EAAE,gBAAgB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC;AACnE,CAAC"}
@@ -0,0 +1,32 @@
1
+ import type { OscPacket } from "./osc-packet.js";
2
+ /**
3
+ * Encodes one OSC packet: the bytes of a datagram, or the content of a stream
4
+ * frame. For a transport, prefer the codecs, which add the framing it needs.
5
+ *
6
+ * Every message gets a type tag string — `,` alone when it has no arguments.
7
+ * Strings are written as UTF-8 with their NUL terminator, strings and blobs are
8
+ * padded with NUL bytes to a multiple of 4, and numbers are big-endian. A
9
+ * `float32` argument is rounded to binary32 as `Math.fround` would, so 1.234
10
+ * reads back as 1.2339999675750732.
11
+ *
12
+ * Time and memory are O(n) in the encoded size.
13
+ *
14
+ * @example
15
+ * ```ts
16
+ * encodeOscPacket({
17
+ * kind: "message",
18
+ * address: "/oscillator/4/frequency",
19
+ * arguments: [{ type: "float32", value: 440 }],
20
+ * }); // 32 bytes, ending 2c 66 00 00 43 dc 00 00
21
+ * ```;
22
+ *
23
+ * @returns A fresh buffer, a multiple of 4 bytes long.
24
+ * @throws {RangeError} When the packet cannot be written as given: an address
25
+ * not beginning with `/`; a string, symbol or address containing U+0000 or a
26
+ * lone surrogate; an `int32` that is not an integer in −2^31..2^31 − 1; an
27
+ * `int64` outside −2^63..2^63 − 1; a time tag field that is not an unsigned
28
+ * 32-bit integer; a `char` that is not exactly one code point; an `rgba` or
29
+ * `midi` byte that is not an integer in 0–255.
30
+ */
31
+ export declare function encodeOscPacket(packet: OscPacket): Uint8Array<ArrayBuffer>;
32
+ //# sourceMappingURL=encode-osc-packet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encode-osc-packet.d.ts","sourceRoot":"","sources":["../../src/packet/encode-osc-packet.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,GAAG,UAAU,CAAC,WAAW,CAAC,CAK1E"}
@@ -0,0 +1,37 @@
1
+ import { OscWriter_ } from "./_osc-writer.js";
2
+ import { writeOscPacket_ } from "./_write-osc-packet.js";
3
+ /**
4
+ * Encodes one OSC packet: the bytes of a datagram, or the content of a stream
5
+ * frame. For a transport, prefer the codecs, which add the framing it needs.
6
+ *
7
+ * Every message gets a type tag string — `,` alone when it has no arguments.
8
+ * Strings are written as UTF-8 with their NUL terminator, strings and blobs are
9
+ * padded with NUL bytes to a multiple of 4, and numbers are big-endian. A
10
+ * `float32` argument is rounded to binary32 as `Math.fround` would, so 1.234
11
+ * reads back as 1.2339999675750732.
12
+ *
13
+ * Time and memory are O(n) in the encoded size.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * encodeOscPacket({
18
+ * kind: "message",
19
+ * address: "/oscillator/4/frequency",
20
+ * arguments: [{ type: "float32", value: 440 }],
21
+ * }); // 32 bytes, ending 2c 66 00 00 43 dc 00 00
22
+ * ```;
23
+ *
24
+ * @returns A fresh buffer, a multiple of 4 bytes long.
25
+ * @throws {RangeError} When the packet cannot be written as given: an address
26
+ * not beginning with `/`; a string, symbol or address containing U+0000 or a
27
+ * lone surrogate; an `int32` that is not an integer in −2^31..2^31 − 1; an
28
+ * `int64` outside −2^63..2^63 − 1; a time tag field that is not an unsigned
29
+ * 32-bit integer; a `char` that is not exactly one code point; an `rgba` or
30
+ * `midi` byte that is not an integer in 0–255.
31
+ */
32
+ export function encodeOscPacket(packet) {
33
+ const writer = new OscWriter_();
34
+ writeOscPacket_(writer, packet);
35
+ return writer.finish();
36
+ }
37
+ //# sourceMappingURL=encode-osc-packet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encode-osc-packet.js","sourceRoot":"","sources":["../../src/packet/encode-osc-packet.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,UAAU,eAAe,CAAC,MAAiB;IAChD,MAAM,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;IAChC,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEhC,OAAO,MAAM,CAAC,MAAM,EAAE,CAAC;AACxB,CAAC"}
@@ -0,0 +1,104 @@
1
+ import type { OscTimeTag } from "../time-tag/osc-time-tag.js";
2
+ /**
3
+ * One argument of an OSC message, discriminated by `type`. Each variant names
4
+ * the type tag it travels under:
5
+ *
6
+ * - `int32` (`i`) — a signed 32-bit integer, −2^31 to 2^31 − 1.
7
+ * - `float32` (`f`) — an IEEE 754 binary32; a `number` is rounded to it on
8
+ * encode, as `Math.fround` would.
9
+ * - `string` (`s`) — text, sent as UTF-8; never contains U+0000.
10
+ * - `blob` (`b`) — arbitrary bytes.
11
+ * - `int64` (`h`) — a signed 64-bit integer, as a `bigint`.
12
+ * - `timeTag` (`t`) — an NTP time tag.
13
+ * - `float64` (`d`) — an IEEE 754 binary64.
14
+ * - `symbol` (`S`) — text like `string`, for systems that tell symbols apart.
15
+ * - `char` (`c`) — one character, sent as its code point in 32 bits.
16
+ * - `rgba` (`r`) — a 32-bit colour, each channel 0–255.
17
+ * - `midi` (`m`) — a 4-byte MIDI message: port, status and two data bytes, each
18
+ * 0–255.
19
+ * - `true` (`T`), `false` (`F`), `nil` (`N`), `impulse` (`I`) — values carried by
20
+ * the tag alone. `impulse` is OSC 1.1's name for the tag OSC 1.0 calls
21
+ * Infinitum.
22
+ * - `array` (`[` … `]`) — a nested list of arguments.
23
+ *
24
+ * The types beyond `i`, `f`, `s` and `b` are the ones OSC 1.0 lists as
25
+ * non-standard and OSC 1.1 makes standard.
26
+ */
27
+ export type OscArgument = {
28
+ type: "int32";
29
+ value: number;
30
+ } | {
31
+ type: "float32";
32
+ value: number;
33
+ } | {
34
+ type: "string";
35
+ value: string;
36
+ } | {
37
+ type: "blob";
38
+ value: Uint8Array;
39
+ } | {
40
+ type: "int64";
41
+ value: bigint;
42
+ } | {
43
+ type: "timeTag";
44
+ value: OscTimeTag;
45
+ } | {
46
+ type: "float64";
47
+ value: number;
48
+ } | {
49
+ type: "symbol";
50
+ value: string;
51
+ } | {
52
+ type: "char";
53
+ /** Exactly one Unicode code point; OSC 1.0 calls for ASCII. */
54
+ value: string;
55
+ } | {
56
+ type: "rgba";
57
+ red: number;
58
+ green: number;
59
+ blue: number;
60
+ alpha: number;
61
+ } | {
62
+ type: "midi";
63
+ port: number;
64
+ status: number;
65
+ data1: number;
66
+ data2: number;
67
+ } | {
68
+ type: "true";
69
+ } | {
70
+ type: "false";
71
+ } | {
72
+ type: "nil";
73
+ } | {
74
+ type: "impulse";
75
+ } | {
76
+ type: "array";
77
+ items: OscArgument[];
78
+ };
79
+ /**
80
+ * An OSC message: an address pattern and the arguments for the methods it
81
+ * matches.
82
+ */
83
+ export type OscMessage = {
84
+ kind: "message";
85
+ /**
86
+ * The OSC address pattern, beginning with `/`. It may hold the wildcards of
87
+ * OSC address pattern matching; this package carries it as text.
88
+ */
89
+ address: string;
90
+ arguments: OscArgument[];
91
+ };
92
+ /**
93
+ * An OSC bundle: packets to be acted on together, at the instant `timeTag`
94
+ * names.
95
+ */
96
+ export type OscBundle = {
97
+ kind: "bundle";
98
+ timeTag: OscTimeTag;
99
+ /** Messages and nested bundles, in order. */
100
+ elements: OscPacket[];
101
+ };
102
+ /** The unit of OSC transmission: a message or a bundle. */
103
+ export type OscPacket = OscMessage | OscBundle;
104
+ //# sourceMappingURL=osc-packet.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"osc-packet.d.ts","sourceRoot":"","sources":["../../src/packet/osc-packet.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAE9D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,MAAM,WAAW,GACpB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,GACnC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,GACtC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjC;IACA,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,KAAK,EAAE,MAAM,CAAC;CACb,GACD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACzE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC5E;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,OAAO,CAAA;CAAE,GACjB;IAAE,IAAI,EAAE,KAAK,CAAA;CAAE,GACf;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,WAAW,EAAE,CAAA;CAAE,CAAC;AAE3C;;;GAGG;AACH,MAAM,MAAM,UAAU,GAAG;IACxB,IAAI,EAAE,SAAS,CAAC;IAChB;;;OAGG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,WAAW,EAAE,CAAC;CACzB,CAAC;AAEF;;;GAGG;AACH,MAAM,MAAM,SAAS,GAAG;IACvB,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE,UAAU,CAAC;IACpB,6CAA6C;IAC7C,QAAQ,EAAE,SAAS,EAAE,CAAC;CACtB,CAAC;AAEF,2DAA2D;AAC3D,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=osc-packet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"osc-packet.js","sourceRoot":"","sources":["../../src/packet/osc-packet.ts"],"names":[],"mappings":""}
@@ -0,0 +1,13 @@
1
+ import type { OscTimeTag } from "./osc-time-tag.js";
2
+ /** 2^32: one NTP era in seconds, and one second in `fraction` units. */
3
+ export declare const TWO_POW_32_ = 4294967296;
4
+ /** 2^31: `seconds` values at or above it are in NTP era 0 (RFC 4330 §3). */
5
+ export declare const TWO_POW_31_ = 2147483648;
6
+ /** Seconds from 1900-01-01T00:00:00Z to the Unix epoch, 1970-01-01T00:00:00Z. */
7
+ export declare const NTP_UNIX_OFFSET_SECONDS_ = 2208988800;
8
+ /**
9
+ * Throws a `RangeError` unless both fields of `tag` are unsigned 32-bit
10
+ * integers. `what` names the value in the message.
11
+ */
12
+ export declare function assertOscTimeTag_(tag: OscTimeTag, what: string): void;
13
+ //# sourceMappingURL=_ntp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_ntp.d.ts","sourceRoot":"","sources":["../../src/time-tag/_ntp.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,wEAAwE;AACxE,eAAO,MAAM,WAAW,aAAgB,CAAC;AAEzC,4EAA4E;AAC5E,eAAO,MAAM,WAAW,aAAgB,CAAC;AAEzC,iFAAiF;AACjF,eAAO,MAAM,wBAAwB,aAAgB,CAAC;AAEtD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAMrE"}
@@ -0,0 +1,19 @@
1
+ /** 2^32: one NTP era in seconds, and one second in `fraction` units. */
2
+ export const TWO_POW_32_ = 4294967296;
3
+ /** 2^31: `seconds` values at or above it are in NTP era 0 (RFC 4330 §3). */
4
+ export const TWO_POW_31_ = 2147483648;
5
+ /** Seconds from 1900-01-01T00:00:00Z to the Unix epoch, 1970-01-01T00:00:00Z. */
6
+ export const NTP_UNIX_OFFSET_SECONDS_ = 2208988800;
7
+ /**
8
+ * Throws a `RangeError` unless both fields of `tag` are unsigned 32-bit
9
+ * integers. `what` names the value in the message.
10
+ */
11
+ export function assertOscTimeTag_(tag, what) {
12
+ if (!isUint32_(tag.seconds) || !isUint32_(tag.fraction)) {
13
+ throw new RangeError(`${what}: seconds and fraction must be integers in 0..2^32-1, got ${tag.seconds} and ${tag.fraction}`);
14
+ }
15
+ }
16
+ function isUint32_(value) {
17
+ return Number.isInteger(value) && value >= 0 && value < TWO_POW_32_;
18
+ }
19
+ //# sourceMappingURL=_ntp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"_ntp.js","sourceRoot":"","sources":["../../src/time-tag/_ntp.ts"],"names":[],"mappings":"AAEA,wEAAwE;AACxE,MAAM,CAAC,MAAM,WAAW,GAAG,UAAa,CAAC;AAEzC,4EAA4E;AAC5E,MAAM,CAAC,MAAM,WAAW,GAAG,UAAa,CAAC;AAEzC,iFAAiF;AACjF,MAAM,CAAC,MAAM,wBAAwB,GAAG,UAAa,CAAC;AAEtD;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAe,EAAE,IAAY;IAC9D,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,UAAU,CACnB,GAAG,IAAI,6DAA6D,GAAG,CAAC,OAAO,QAAQ,GAAG,CAAC,QAAQ,EAAE,CACrG,CAAC;IACH,CAAC;AACF,CAAC;AAED,SAAS,SAAS,CAAC,KAAa;IAC/B,OAAO,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,KAAK,GAAG,WAAW,CAAC;AACrE,CAAC"}
@@ -0,0 +1,29 @@
1
+ import type { OscTimeTag } from "./osc-time-tag.js";
2
+ /**
3
+ * Converts an instant to the OSC time tag naming it.
4
+ *
5
+ * The 32-bit `seconds` field wraps every 2^32 s (about 136 years), so a tag is
6
+ * read with the RFC 4330 §3 rule: a value with its most significant bit set is
7
+ * in NTP era 0 (from 1900), one with it clear is in era 1 (from
8
+ * 2036-02-07T06:28:16Z). The instants that rule can name, and so the ones this
9
+ * accepts, run from 1968-01-20T03:14:08Z inclusive to 2104-02-26T09:42:24Z
10
+ * exclusive.
11
+ *
12
+ * The fraction is rounded to the nearest 2^-32 s, so a whole number of
13
+ * milliseconds survives {@link oscTimeTagToDate} exactly. A fractional `number`
14
+ * keeps its sub-millisecond part as far as `number` resolves it.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * oscTimeTagFromDate(0); // { seconds: 2208988800, fraction: 0 }
19
+ * oscTimeTagFromDate(new Date("2036-02-07T06:28:16.500Z")); // { seconds: 0, fraction: 2147483648 }
20
+ * ```;
21
+ *
22
+ * @param date - The instant, as a `Date` or as milliseconds since the Unix
23
+ * epoch (`Date.now()`, `performance.timeOrigin + performance.now()`).
24
+ * @returns A fresh time tag. Never {@link OSC_TIME_TAG_IMMEDIATELY}, except for
25
+ * the one instant 2^-32 s after the 2036 rollover, which the two share.
26
+ * @throws {RangeError} When `date` is invalid or outside the range above.
27
+ */
28
+ export declare function oscTimeTagFromDate(date: Date | number): OscTimeTag;
29
+ //# sourceMappingURL=osc-time-tag-from-date.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"osc-time-tag-from-date.d.ts","sourceRoot":"","sources":["../../src/time-tag/osc-time-tag-from-date.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,GAAG,UAAU,CA0BlE"}
@@ -0,0 +1,48 @@
1
+ import { NTP_UNIX_OFFSET_SECONDS_, TWO_POW_31_, TWO_POW_32_ } from "./_ntp.js";
2
+ /**
3
+ * Converts an instant to the OSC time tag naming it.
4
+ *
5
+ * The 32-bit `seconds` field wraps every 2^32 s (about 136 years), so a tag is
6
+ * read with the RFC 4330 §3 rule: a value with its most significant bit set is
7
+ * in NTP era 0 (from 1900), one with it clear is in era 1 (from
8
+ * 2036-02-07T06:28:16Z). The instants that rule can name, and so the ones this
9
+ * accepts, run from 1968-01-20T03:14:08Z inclusive to 2104-02-26T09:42:24Z
10
+ * exclusive.
11
+ *
12
+ * The fraction is rounded to the nearest 2^-32 s, so a whole number of
13
+ * milliseconds survives {@link oscTimeTagToDate} exactly. A fractional `number`
14
+ * keeps its sub-millisecond part as far as `number` resolves it.
15
+ *
16
+ * @example
17
+ * ```ts
18
+ * oscTimeTagFromDate(0); // { seconds: 2208988800, fraction: 0 }
19
+ * oscTimeTagFromDate(new Date("2036-02-07T06:28:16.500Z")); // { seconds: 0, fraction: 2147483648 }
20
+ * ```;
21
+ *
22
+ * @param date - The instant, as a `Date` or as milliseconds since the Unix
23
+ * epoch (`Date.now()`, `performance.timeOrigin + performance.now()`).
24
+ * @returns A fresh time tag. Never {@link OSC_TIME_TAG_IMMEDIATELY}, except for
25
+ * the one instant 2^-32 s after the 2036 rollover, which the two share.
26
+ * @throws {RangeError} When `date` is invalid or outside the range above.
27
+ */
28
+ export function oscTimeTagFromDate(date) {
29
+ const milliseconds = typeof date === "number" ? date : date.getTime();
30
+ if (!Number.isFinite(milliseconds)) {
31
+ throw new RangeError(`oscTimeTagFromDate: invalid date ${String(date)}`);
32
+ }
33
+ let unixSeconds = Math.floor(milliseconds / 1000);
34
+ let fraction = Math.round(((milliseconds - unixSeconds * 1000) * TWO_POW_32_) / 1000);
35
+ if (fraction === TWO_POW_32_) {
36
+ fraction = 0;
37
+ unixSeconds += 1;
38
+ }
39
+ const ntpSeconds = unixSeconds + NTP_UNIX_OFFSET_SECONDS_;
40
+ if (ntpSeconds < TWO_POW_31_ || ntpSeconds >= TWO_POW_32_ + TWO_POW_31_) {
41
+ throw new RangeError(`oscTimeTagFromDate: ${new Date(milliseconds).toISOString()} is outside the range an NTP time tag names (1968-01-20T03:14:08Z to 2104-02-26T09:42:24Z)`);
42
+ }
43
+ return {
44
+ seconds: ntpSeconds >= TWO_POW_32_ ? ntpSeconds - TWO_POW_32_ : ntpSeconds,
45
+ fraction,
46
+ };
47
+ }
48
+ //# sourceMappingURL=osc-time-tag-from-date.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"osc-time-tag-from-date.js","sourceRoot":"","sources":["../../src/time-tag/osc-time-tag-from-date.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAG/E;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAmB;IACrD,MAAM,YAAY,GAAG,OAAO,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;IACtE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,UAAU,CAAC,oCAAoC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC1E,CAAC;IAED,IAAI,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAClD,IAAI,QAAQ,GAAG,IAAI,CAAC,KAAK,CACxB,CAAC,CAAC,YAAY,GAAG,WAAW,GAAG,IAAI,CAAC,GAAG,WAAW,CAAC,GAAG,IAAI,CAC1D,CAAC;IACF,IAAI,QAAQ,KAAK,WAAW,EAAE,CAAC;QAC9B,QAAQ,GAAG,CAAC,CAAC;QACb,WAAW,IAAI,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,UAAU,GAAG,WAAW,GAAG,wBAAwB,CAAC;IAC1D,IAAI,UAAU,GAAG,WAAW,IAAI,UAAU,IAAI,WAAW,GAAG,WAAW,EAAE,CAAC;QACzE,MAAM,IAAI,UAAU,CACnB,uBAAuB,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,4FAA4F,CACvJ,CAAC;IACH,CAAC;IAED,OAAO;QACN,OAAO,EAAE,UAAU,IAAI,WAAW,CAAC,CAAC,CAAC,UAAU,GAAG,WAAW,CAAC,CAAC,CAAC,UAAU;QAC1E,QAAQ;KACR,CAAC;AACH,CAAC"}
@@ -0,0 +1,21 @@
1
+ import type { OscTimeTag } from "./osc-time-tag.js";
2
+ /**
3
+ * Converts an OSC time tag to the instant it names.
4
+ *
5
+ * `seconds` is read with the RFC 4330 §3 era rule {@link oscTimeTagFromDate}
6
+ * documents, so every tag maps to an instant between 1968-01-20T03:14:08Z and
7
+ * 2104-02-26T09:42:24Z. {@link OSC_TIME_TAG_IMMEDIATELY} is not an instant:
8
+ * test for it with {@link isOscTimeTagImmediately} first.
9
+ *
10
+ * A `Date` holds whole milliseconds, so the fraction is rounded to the nearest
11
+ * millisecond (a half rounds up), at most 0.5 ms from the tag.
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * oscTimeTagToDate({ seconds: 2208988800, fraction: 0 }).toISOString(); // "1970-01-01T00:00:00.000Z"
16
+ * ```;
17
+ *
18
+ * @throws {RangeError} When a field of `tag` is not an unsigned 32-bit integer.
19
+ */
20
+ export declare function oscTimeTagToDate(tag: OscTimeTag): Date;
21
+ //# sourceMappingURL=osc-time-tag-to-date.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"osc-time-tag-to-date.d.ts","sourceRoot":"","sources":["../../src/time-tag/osc-time-tag-to-date.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,CAUtD"}
@@ -0,0 +1,26 @@
1
+ import { assertOscTimeTag_, NTP_UNIX_OFFSET_SECONDS_, TWO_POW_31_, TWO_POW_32_, } from "./_ntp.js";
2
+ /**
3
+ * Converts an OSC time tag to the instant it names.
4
+ *
5
+ * `seconds` is read with the RFC 4330 §3 era rule {@link oscTimeTagFromDate}
6
+ * documents, so every tag maps to an instant between 1968-01-20T03:14:08Z and
7
+ * 2104-02-26T09:42:24Z. {@link OSC_TIME_TAG_IMMEDIATELY} is not an instant:
8
+ * test for it with {@link isOscTimeTagImmediately} first.
9
+ *
10
+ * A `Date` holds whole milliseconds, so the fraction is rounded to the nearest
11
+ * millisecond (a half rounds up), at most 0.5 ms from the tag.
12
+ *
13
+ * @example
14
+ * ```ts
15
+ * oscTimeTagToDate({ seconds: 2208988800, fraction: 0 }).toISOString(); // "1970-01-01T00:00:00.000Z"
16
+ * ```;
17
+ *
18
+ * @throws {RangeError} When a field of `tag` is not an unsigned 32-bit integer.
19
+ */
20
+ export function oscTimeTagToDate(tag) {
21
+ assertOscTimeTag_(tag, "oscTimeTagToDate");
22
+ const ntpSeconds = tag.seconds >= TWO_POW_31_ ? tag.seconds : tag.seconds + TWO_POW_32_;
23
+ return new Date((ntpSeconds - NTP_UNIX_OFFSET_SECONDS_) * 1000 +
24
+ Math.round((tag.fraction * 1000) / TWO_POW_32_));
25
+ }
26
+ //# sourceMappingURL=osc-time-tag-to-date.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"osc-time-tag-to-date.js","sourceRoot":"","sources":["../../src/time-tag/osc-time-tag-to-date.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,iBAAiB,EACjB,wBAAwB,EACxB,WAAW,EACX,WAAW,GACX,MAAM,WAAW,CAAC;AAGnB;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,gBAAgB,CAAC,GAAe;IAC/C,iBAAiB,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC;IAE3C,MAAM,UAAU,GACf,GAAG,CAAC,OAAO,IAAI,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,GAAG,WAAW,CAAC;IAEtE,OAAO,IAAI,IAAI,CACd,CAAC,UAAU,GAAG,wBAAwB,CAAC,GAAG,IAAI;QAC7C,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,WAAW,CAAC,CAChD,CAAC;AACH,CAAC"}