werift 0.18.7 → 0.18.9
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/lib/ice/src/ice.d.ts +1 -0
- package/lib/ice/src/ice.js +4 -0
- package/lib/ice/src/ice.js.map +1 -1
- package/lib/rtp/src/helper.d.ts +1 -0
- package/lib/rtp/src/helper.js +6 -1
- package/lib/rtp/src/helper.js.map +1 -1
- package/lib/rtp/src/index.d.ts +1 -0
- package/lib/rtp/src/index.js +1 -0
- package/lib/rtp/src/index.js.map +1 -1
- package/lib/rtp/src/util.d.ts +12 -0
- package/lib/rtp/src/util.js +44 -0
- package/lib/rtp/src/util.js.map +1 -0
- package/lib/webrtc/src/index.d.ts +2 -0
- package/lib/webrtc/src/index.js +2 -0
- package/lib/webrtc/src/index.js.map +1 -1
- package/lib/webrtc/src/peerConnection.d.ts +8 -5
- package/lib/webrtc/src/peerConnection.js +8 -0
- package/lib/webrtc/src/peerConnection.js.map +1 -1
- package/lib/webrtc/src/transport/dtls.js +1 -1
- package/lib/webrtc/src/transport/dtls.js.map +1 -1
- package/lib/webrtc/src/utils.d.ts +8 -8
- package/lib/webrtc/src/utils.js +21 -38
- package/lib/webrtc/src/utils.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +2 -0
- package/src/peerConnection.ts +20 -4
- package/src/transport/dtls.ts +2 -1
- package/src/utils.ts +30 -35
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import { RtpPacket } from "../../rtp/src";
|
|
3
2
|
import { Direction } from "./media/rtpTransceiver";
|
|
3
|
+
import { MediaStreamTrack } from "./media/track";
|
|
4
4
|
import { RTCIceServer } from "./peerConnection";
|
|
5
5
|
export declare function fingerprint(file: Buffer, hashName: string): any;
|
|
6
6
|
export declare function isDtls(buf: Buffer): boolean;
|
|
7
|
-
export declare function
|
|
8
|
-
export declare function reverseSimulcastDirection(dir: "recv" | "send"): "recv" | "send";
|
|
7
|
+
export declare function reverseSimulcastDirection(dir: "recv" | "send"): "send" | "recv";
|
|
9
8
|
export declare const andDirection: (a: Direction, b: Direction) => "inactive" | "sendonly" | "recvonly" | "sendrecv";
|
|
10
9
|
export declare function reverseDirection(dir: Direction): Direction;
|
|
11
10
|
export declare const microTime: () => number;
|
|
@@ -25,11 +24,6 @@ export declare function parseIceServers(iceServers: RTCIceServer[]): {
|
|
|
25
24
|
turnUsername: string | undefined;
|
|
26
25
|
turnPassword: string | undefined;
|
|
27
26
|
};
|
|
28
|
-
export declare class RtpBuilder {
|
|
29
|
-
sequenceNumber: number;
|
|
30
|
-
timestamp: number;
|
|
31
|
-
create(payload: Buffer): RtpPacket;
|
|
32
|
-
}
|
|
33
27
|
/**
|
|
34
28
|
*
|
|
35
29
|
* @param signatureHash
|
|
@@ -40,3 +34,9 @@ export declare const createSelfSignedCertificate: (signatureHash: import(".").Si
|
|
|
40
34
|
keyPem: string;
|
|
41
35
|
signatureHash: import(".").SignatureHash;
|
|
42
36
|
}>;
|
|
37
|
+
export declare class MediaStreamTrackFactory {
|
|
38
|
+
static rtpSource({ port, kind, }: {
|
|
39
|
+
port?: number;
|
|
40
|
+
kind: "audio" | "video";
|
|
41
|
+
}): Promise<readonly [MediaStreamTrack, number, () => void]>;
|
|
42
|
+
}
|
package/lib/webrtc/src/utils.js
CHANGED
|
@@ -3,15 +3,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
6
|
+
exports.MediaStreamTrackFactory = exports.createSelfSignedCertificate = exports.parseIceServers = exports.compactNtp = exports.ntpTime = exports.timestampSeconds = exports.milliTime = exports.microTime = exports.reverseDirection = exports.andDirection = exports.reverseSimulcastDirection = exports.isDtls = exports.fingerprint = void 0;
|
|
7
7
|
/* eslint-disable prefer-const */
|
|
8
8
|
const crypto_1 = require("crypto");
|
|
9
9
|
const debug_1 = __importDefault(require("debug"));
|
|
10
|
+
const dgram_1 = require("dgram");
|
|
10
11
|
const perf_hooks_1 = require("perf_hooks");
|
|
11
12
|
const src_1 = require("../../common/src");
|
|
12
13
|
const cipher_1 = require("../../dtls/src/context/cipher");
|
|
13
|
-
const src_2 = require("../../rtp/src");
|
|
14
14
|
const rtpTransceiver_1 = require("./media/rtpTransceiver");
|
|
15
|
+
const track_1 = require("./media/track");
|
|
15
16
|
const now = require("nano-time");
|
|
16
17
|
const log = (0, debug_1.default)("werift:packages/webrtc/src/utils.ts");
|
|
17
18
|
function fingerprint(file, hashName) {
|
|
@@ -26,11 +27,6 @@ function isDtls(buf) {
|
|
|
26
27
|
return firstByte > 19 && firstByte < 64;
|
|
27
28
|
}
|
|
28
29
|
exports.isDtls = isDtls;
|
|
29
|
-
function isMedia(buf) {
|
|
30
|
-
const firstByte = buf[0];
|
|
31
|
-
return firstByte > 127 && firstByte < 192;
|
|
32
|
-
}
|
|
33
|
-
exports.isMedia = isMedia;
|
|
34
30
|
function reverseSimulcastDirection(dir) {
|
|
35
31
|
if (dir === "recv")
|
|
36
32
|
return "send";
|
|
@@ -93,41 +89,28 @@ function parseIceServers(iceServers) {
|
|
|
93
89
|
return options;
|
|
94
90
|
}
|
|
95
91
|
exports.parseIceServers = parseIceServers;
|
|
96
|
-
class RtpBuilder {
|
|
97
|
-
constructor() {
|
|
98
|
-
Object.defineProperty(this, "sequenceNumber", {
|
|
99
|
-
enumerable: true,
|
|
100
|
-
configurable: true,
|
|
101
|
-
writable: true,
|
|
102
|
-
value: (0, src_1.random16)()
|
|
103
|
-
});
|
|
104
|
-
Object.defineProperty(this, "timestamp", {
|
|
105
|
-
enumerable: true,
|
|
106
|
-
configurable: true,
|
|
107
|
-
writable: true,
|
|
108
|
-
value: (0, src_1.random32)()
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
create(payload) {
|
|
112
|
-
this.sequenceNumber = (0, src_1.uint16Add)(this.sequenceNumber, 1);
|
|
113
|
-
this.timestamp = (0, src_1.uint32Add)(this.timestamp, 960);
|
|
114
|
-
const header = new src_2.RtpHeader({
|
|
115
|
-
sequenceNumber: this.sequenceNumber,
|
|
116
|
-
timestamp: Number(this.timestamp),
|
|
117
|
-
payloadType: 96,
|
|
118
|
-
extension: true,
|
|
119
|
-
marker: false,
|
|
120
|
-
padding: false,
|
|
121
|
-
});
|
|
122
|
-
const rtp = new src_2.RtpPacket(header, payload);
|
|
123
|
-
return rtp;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
exports.RtpBuilder = RtpBuilder;
|
|
127
92
|
/**
|
|
128
93
|
*
|
|
129
94
|
* @param signatureHash
|
|
130
95
|
* @param namedCurveAlgorithm necessary when use ecdsa
|
|
131
96
|
*/
|
|
132
97
|
exports.createSelfSignedCertificate = cipher_1.CipherContext.createSelfSignedCertificateWithKey;
|
|
98
|
+
class MediaStreamTrackFactory {
|
|
99
|
+
static async rtpSource({ port, kind, }) {
|
|
100
|
+
port ?? (port = await (0, src_1.randomPort)());
|
|
101
|
+
const track = new track_1.MediaStreamTrack({ kind });
|
|
102
|
+
const udp = (0, dgram_1.createSocket)("udp4");
|
|
103
|
+
udp.bind(port);
|
|
104
|
+
const onMessage = (msg, rinfo) => {
|
|
105
|
+
track.writeRtp(msg);
|
|
106
|
+
};
|
|
107
|
+
udp.addListener("message", onMessage);
|
|
108
|
+
const dispose = () => {
|
|
109
|
+
udp.removeListener("message", onMessage);
|
|
110
|
+
udp.close();
|
|
111
|
+
};
|
|
112
|
+
return [track, port, dispose];
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
exports.MediaStreamTrackFactory = MediaStreamTrackFactory;
|
|
133
116
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/utils.ts"],"names":[],"mappings":";;;;;;AAAA,iCAAiC;AACjC,mCAAoC;AACpC,kDAA0B;AAC1B,2CAAyC;AAEzC,
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/utils.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable prefer-const */\nimport { createHash } from \"crypto\";\nimport debug from \"debug\";\nimport { createSocket, RemoteInfo } from \"dgram\";\nimport { performance } from \"perf_hooks\";\n\nimport { bufferReader, bufferWriter, randomPort } from \"../../common/src\";\nimport { CipherContext } from \"../../dtls/src/context/cipher\";\nimport { Address } from \"../../ice/src\";\nimport { Direction, Directions } from \"./media/rtpTransceiver\";\nimport { MediaStreamTrack } from \"./media/track\";\nimport { RTCIceServer } from \"./peerConnection\";\nconst now = require(\"nano-time\");\n\nconst log = debug(\"werift:packages/webrtc/src/utils.ts\");\n\nexport function fingerprint(file: Buffer, hashName: string) {\n const upper = (s: string) => s.toUpperCase();\n const colon = (s: any) => s.match(/(.{2})/g).join(\":\");\n\n const hash = createHash(hashName).update(file).digest(\"hex\");\n\n return colon(upper(hash));\n}\n\nexport function isDtls(buf: Buffer) {\n const firstByte = buf[0];\n return firstByte > 19 && firstByte < 64;\n}\n\nexport function reverseSimulcastDirection(dir: \"recv\" | \"send\") {\n if (dir === \"recv\") return \"send\";\n return \"recv\";\n}\n\nexport const andDirection = (a: Direction, b: Direction) =>\n Directions[Directions.indexOf(a) & Directions.indexOf(b)];\n\nexport function reverseDirection(dir: Direction): Direction {\n if (dir === \"sendonly\") return \"recvonly\";\n if (dir === \"recvonly\") return \"sendonly\";\n return dir;\n}\n\nexport const microTime = () => now.micro() as number;\n\nexport const milliTime = () => new Date().getTime();\n\nexport const timestampSeconds = () => Date.now() / 1000;\n\n/**https://datatracker.ietf.org/doc/html/rfc3550#section-4 */\nexport const ntpTime = () => {\n const now = performance.timeOrigin + performance.now() - Date.UTC(1900, 0, 1);\n\n const seconds = now / 1000;\n const [sec, msec] = seconds.toString().split(\".\").map(Number);\n\n const buf = bufferWriter([4, 4], [sec, msec]);\n\n return buf.readBigUInt64BE();\n};\n\n/**\n * https://datatracker.ietf.org/doc/html/rfc3550#section-4\n * @param ntp\n * @returns 32bit\n */\nexport const compactNtp = (ntp: bigint) => {\n const buf = bufferWriter([8], [ntp]);\n const [, sec, msec] = bufferReader(buf, [2, 2, 2, 2]);\n return bufferWriter([2, 2], [sec, msec]).readUInt32BE();\n};\n\nexport function parseIceServers(iceServers: RTCIceServer[]) {\n const url2Address = (url?: string) => {\n if (!url) return;\n const [address, port] = url.split(\":\");\n return [address, parseInt(port)] as Address;\n };\n\n const stunServer = url2Address(\n iceServers.find(({ urls }) => urls.includes(\"stun:\"))?.urls.slice(5)\n );\n const turnServer = url2Address(\n iceServers.find(({ urls }) => urls.includes(\"turn:\"))?.urls.slice(5)\n );\n const { credential, username } =\n iceServers.find(({ urls }) => urls.includes(\"turn:\")) || {};\n\n const options = {\n stunServer,\n turnServer,\n turnUsername: username,\n turnPassword: credential,\n };\n log(\"iceOptions\", options);\n return options;\n}\n\n/**\n *\n * @param signatureHash\n * @param namedCurveAlgorithm necessary when use ecdsa\n */\nexport const createSelfSignedCertificate =\n CipherContext.createSelfSignedCertificateWithKey;\n\nexport class MediaStreamTrackFactory {\n static async rtpSource({\n port,\n kind,\n }: {\n port?: number;\n kind: \"audio\" | \"video\";\n }) {\n port ??= await randomPort();\n const track = new MediaStreamTrack({ kind });\n\n const udp = createSocket(\"udp4\");\n udp.bind(port);\n const onMessage = (msg: Buffer, rinfo: RemoteInfo) => {\n track.writeRtp(msg);\n };\n udp.addListener(\"message\", onMessage);\n\n const dispose = () => {\n udp.removeListener(\"message\", onMessage);\n udp.close();\n };\n\n return [track, port, dispose] as const;\n }\n}\n"]}
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -6,6 +6,8 @@ export * from "./dataChannel";
|
|
|
6
6
|
export * from "./media/extension/rtcpFeedback";
|
|
7
7
|
export * from "./media/extension/rtpExtension";
|
|
8
8
|
export * from "./media/parameters";
|
|
9
|
+
export * from "./media/rtpReceiver";
|
|
10
|
+
export * from "./media/rtpSender";
|
|
9
11
|
export * from "./media/rtpTransceiver";
|
|
10
12
|
export * from "./media/track";
|
|
11
13
|
export * from "./nonstandard/recorder";
|
package/src/peerConnection.ts
CHANGED
|
@@ -9,6 +9,7 @@ import { Message } from "../../ice/src/stun/message";
|
|
|
9
9
|
import { Protocol } from "../../ice/src/types/model";
|
|
10
10
|
import {
|
|
11
11
|
Address,
|
|
12
|
+
CandidatePair,
|
|
12
13
|
deepMerge,
|
|
13
14
|
InterfaceAddresses,
|
|
14
15
|
Recvonly,
|
|
@@ -481,6 +482,7 @@ export class RTCPeerConnection extends EventTarget {
|
|
|
481
482
|
interfaceAddresses: this.config.iceInterfaceAddresses,
|
|
482
483
|
additionalHostAddresses: this.config.iceAdditionalHostAddresses,
|
|
483
484
|
filterStunResponse: this.config.iceFilterStunResponse,
|
|
485
|
+
filterCandidatePair: this.config.iceFilterCandidatePair,
|
|
484
486
|
useIpv4: this.config.iceUseIpv4,
|
|
485
487
|
useIpv6: this.config.iceUseIpv6,
|
|
486
488
|
});
|
|
@@ -835,10 +837,16 @@ export class RTCPeerConnection extends EventTarget {
|
|
|
835
837
|
return bundle;
|
|
836
838
|
}
|
|
837
839
|
|
|
838
|
-
async setRemoteDescription(sessionDescription: {
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
840
|
+
async setRemoteDescription(sessionDescription: RTCSessionDescriptionInit) {
|
|
841
|
+
if (
|
|
842
|
+
!sessionDescription.sdp ||
|
|
843
|
+
!sessionDescription.type ||
|
|
844
|
+
sessionDescription.type === "rollback" ||
|
|
845
|
+
sessionDescription.type === "pranswer"
|
|
846
|
+
) {
|
|
847
|
+
throw new Error("invalid sessionDescription");
|
|
848
|
+
}
|
|
849
|
+
|
|
842
850
|
// # parse and validate description
|
|
843
851
|
const remoteSdp = SessionDescription.parse(sessionDescription.sdp);
|
|
844
852
|
remoteSdp.type = sessionDescription.type;
|
|
@@ -1646,6 +1654,7 @@ export interface PeerConfig {
|
|
|
1646
1654
|
iceFilterStunResponse:
|
|
1647
1655
|
| ((message: Message, addr: Address, protocol: Protocol) => boolean)
|
|
1648
1656
|
| undefined;
|
|
1657
|
+
iceFilterCandidatePair: ((pair: CandidatePair) => boolean) | undefined;
|
|
1649
1658
|
dtls: Partial<{
|
|
1650
1659
|
keys: DtlsKeys;
|
|
1651
1660
|
}>;
|
|
@@ -1715,6 +1724,7 @@ export const defaultPeerConfig: PeerConfig = {
|
|
|
1715
1724
|
iceUseIpv4: true,
|
|
1716
1725
|
iceUseIpv6: true,
|
|
1717
1726
|
iceFilterStunResponse: undefined,
|
|
1727
|
+
iceFilterCandidatePair: undefined,
|
|
1718
1728
|
dtls: {},
|
|
1719
1729
|
bundlePolicy: "max-compat",
|
|
1720
1730
|
debug: {},
|
|
@@ -1737,3 +1747,9 @@ export interface RTCPeerConnectionIceEvent {
|
|
|
1737
1747
|
}
|
|
1738
1748
|
|
|
1739
1749
|
type Media = "audio" | "video";
|
|
1750
|
+
|
|
1751
|
+
export interface RTCSessionDescriptionInit {
|
|
1752
|
+
sdp?: string;
|
|
1753
|
+
type: RTCSdpType;
|
|
1754
|
+
}
|
|
1755
|
+
export type RTCSdpType = "answer" | "offer" | "pranswer" | "rollback";
|
package/src/transport/dtls.ts
CHANGED
|
@@ -20,6 +20,7 @@ import { CipherContext } from "../../../dtls/src/context/cipher";
|
|
|
20
20
|
import { Profile } from "../../../dtls/src/context/srtp";
|
|
21
21
|
import { Connection } from "../../../ice/src";
|
|
22
22
|
import {
|
|
23
|
+
isMedia,
|
|
23
24
|
isRtcp,
|
|
24
25
|
RtcpPacket,
|
|
25
26
|
RtcpPacketConverter,
|
|
@@ -31,7 +32,7 @@ import {
|
|
|
31
32
|
import { keyLength, saltLength } from "../../../rtp/src/srtp/const";
|
|
32
33
|
import { RtpRouter } from "../media/router";
|
|
33
34
|
import { PeerConfig } from "../peerConnection";
|
|
34
|
-
import { fingerprint, isDtls
|
|
35
|
+
import { fingerprint, isDtls } from "../utils";
|
|
35
36
|
import { RTCIceTransport } from "./ice";
|
|
36
37
|
|
|
37
38
|
const log = debug("werift:packages/webrtc/src/transport/dtls.ts");
|
package/src/utils.ts
CHANGED
|
@@ -1,20 +1,14 @@
|
|
|
1
1
|
/* eslint-disable prefer-const */
|
|
2
2
|
import { createHash } from "crypto";
|
|
3
3
|
import debug from "debug";
|
|
4
|
+
import { createSocket, RemoteInfo } from "dgram";
|
|
4
5
|
import { performance } from "perf_hooks";
|
|
5
6
|
|
|
6
|
-
import {
|
|
7
|
-
bufferReader,
|
|
8
|
-
bufferWriter,
|
|
9
|
-
random16,
|
|
10
|
-
random32,
|
|
11
|
-
uint16Add,
|
|
12
|
-
uint32Add,
|
|
13
|
-
} from "../../common/src";
|
|
7
|
+
import { bufferReader, bufferWriter, randomPort } from "../../common/src";
|
|
14
8
|
import { CipherContext } from "../../dtls/src/context/cipher";
|
|
15
9
|
import { Address } from "../../ice/src";
|
|
16
|
-
import { RtpHeader, RtpPacket } from "../../rtp/src";
|
|
17
10
|
import { Direction, Directions } from "./media/rtpTransceiver";
|
|
11
|
+
import { MediaStreamTrack } from "./media/track";
|
|
18
12
|
import { RTCIceServer } from "./peerConnection";
|
|
19
13
|
const now = require("nano-time");
|
|
20
14
|
|
|
@@ -34,11 +28,6 @@ export function isDtls(buf: Buffer) {
|
|
|
34
28
|
return firstByte > 19 && firstByte < 64;
|
|
35
29
|
}
|
|
36
30
|
|
|
37
|
-
export function isMedia(buf: Buffer) {
|
|
38
|
-
const firstByte = buf[0];
|
|
39
|
-
return firstByte > 127 && firstByte < 192;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
31
|
export function reverseSimulcastDirection(dir: "recv" | "send") {
|
|
43
32
|
if (dir === "recv") return "send";
|
|
44
33
|
return "recv";
|
|
@@ -108,27 +97,6 @@ export function parseIceServers(iceServers: RTCIceServer[]) {
|
|
|
108
97
|
return options;
|
|
109
98
|
}
|
|
110
99
|
|
|
111
|
-
export class RtpBuilder {
|
|
112
|
-
sequenceNumber = random16();
|
|
113
|
-
timestamp = random32();
|
|
114
|
-
|
|
115
|
-
create(payload: Buffer) {
|
|
116
|
-
this.sequenceNumber = uint16Add(this.sequenceNumber, 1);
|
|
117
|
-
this.timestamp = uint32Add(this.timestamp, 960);
|
|
118
|
-
|
|
119
|
-
const header = new RtpHeader({
|
|
120
|
-
sequenceNumber: this.sequenceNumber,
|
|
121
|
-
timestamp: Number(this.timestamp),
|
|
122
|
-
payloadType: 96,
|
|
123
|
-
extension: true,
|
|
124
|
-
marker: false,
|
|
125
|
-
padding: false,
|
|
126
|
-
});
|
|
127
|
-
const rtp = new RtpPacket(header, payload);
|
|
128
|
-
return rtp;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
|
|
132
100
|
/**
|
|
133
101
|
*
|
|
134
102
|
* @param signatureHash
|
|
@@ -136,3 +104,30 @@ export class RtpBuilder {
|
|
|
136
104
|
*/
|
|
137
105
|
export const createSelfSignedCertificate =
|
|
138
106
|
CipherContext.createSelfSignedCertificateWithKey;
|
|
107
|
+
|
|
108
|
+
export class MediaStreamTrackFactory {
|
|
109
|
+
static async rtpSource({
|
|
110
|
+
port,
|
|
111
|
+
kind,
|
|
112
|
+
}: {
|
|
113
|
+
port?: number;
|
|
114
|
+
kind: "audio" | "video";
|
|
115
|
+
}) {
|
|
116
|
+
port ??= await randomPort();
|
|
117
|
+
const track = new MediaStreamTrack({ kind });
|
|
118
|
+
|
|
119
|
+
const udp = createSocket("udp4");
|
|
120
|
+
udp.bind(port);
|
|
121
|
+
const onMessage = (msg: Buffer, rinfo: RemoteInfo) => {
|
|
122
|
+
track.writeRtp(msg);
|
|
123
|
+
};
|
|
124
|
+
udp.addListener("message", onMessage);
|
|
125
|
+
|
|
126
|
+
const dispose = () => {
|
|
127
|
+
udp.removeListener("message", onMessage);
|
|
128
|
+
udp.close();
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
return [track, port, dispose] as const;
|
|
132
|
+
}
|
|
133
|
+
}
|