livekit-client 2.5.6 → 2.5.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. package/README.md +2 -2
  2. package/dist/livekit-client.e2ee.worker.js +1 -1
  3. package/dist/livekit-client.e2ee.worker.js.map +1 -1
  4. package/dist/livekit-client.e2ee.worker.mjs +628 -603
  5. package/dist/livekit-client.e2ee.worker.mjs.map +1 -1
  6. package/dist/livekit-client.esm.mjs +2160 -1949
  7. package/dist/livekit-client.esm.mjs.map +1 -1
  8. package/dist/livekit-client.umd.js +1 -1
  9. package/dist/livekit-client.umd.js.map +1 -1
  10. package/dist/src/e2ee/worker/FrameCryptor.d.ts +2 -2
  11. package/dist/src/e2ee/worker/FrameCryptor.d.ts.map +1 -1
  12. package/dist/src/index.d.ts +2 -2
  13. package/dist/src/index.d.ts.map +1 -1
  14. package/dist/src/room/Room.d.ts +4 -1
  15. package/dist/src/room/Room.d.ts.map +1 -1
  16. package/dist/src/room/events.d.ts +7 -3
  17. package/dist/src/room/events.d.ts.map +1 -1
  18. package/dist/src/room/participant/LocalParticipant.d.ts +7 -0
  19. package/dist/src/room/participant/LocalParticipant.d.ts.map +1 -1
  20. package/dist/src/room/participant/Participant.d.ts +1 -1
  21. package/dist/src/room/participant/Participant.d.ts.map +1 -1
  22. package/dist/src/room/track/Track.d.ts +1 -1
  23. package/dist/src/room/track/Track.d.ts.map +1 -1
  24. package/dist/src/room/utils.d.ts +1 -1
  25. package/dist/src/room/utils.d.ts.map +1 -1
  26. package/dist/src/test/mocks.d.ts +1 -1
  27. package/dist/src/test/mocks.d.ts.map +1 -1
  28. package/dist/ts4.2/src/e2ee/worker/FrameCryptor.d.ts +2 -2
  29. package/dist/ts4.2/src/index.d.ts +2 -2
  30. package/dist/ts4.2/src/room/Room.d.ts +4 -1
  31. package/dist/ts4.2/src/room/events.d.ts +7 -3
  32. package/dist/ts4.2/src/room/participant/LocalParticipant.d.ts +7 -0
  33. package/dist/ts4.2/src/room/participant/Participant.d.ts +1 -1
  34. package/dist/ts4.2/src/room/track/Track.d.ts +1 -1
  35. package/dist/ts4.2/src/room/utils.d.ts +1 -1
  36. package/dist/ts4.2/src/test/mocks.d.ts +1 -1
  37. package/package.json +14 -15
  38. package/src/e2ee/worker/FrameCryptor.test.ts +249 -2
  39. package/src/e2ee/worker/FrameCryptor.ts +3 -3
  40. package/src/e2ee/worker/ParticipantKeyHandler.test.ts +122 -0
  41. package/src/e2ee/worker/ParticipantKeyHandler.ts +1 -1
  42. package/src/e2ee/worker/e2ee.worker.ts +1 -1
  43. package/src/index.ts +2 -0
  44. package/src/room/Room.ts +24 -10
  45. package/src/room/events.ts +7 -2
  46. package/src/room/participant/LocalParticipant.ts +22 -0
  47. package/src/room/participant/Participant.ts +3 -2
  48. package/src/room/track/LocalTrackPublication.ts +1 -1
  49. package/src/room/track/Track.ts +1 -1
  50. package/src/room/track/utils.ts +1 -1
  51. package/src/room/utils.ts +1 -1
  52. package/src/test/mocks.ts +1 -1
@@ -3672,6 +3672,11 @@ const TimeSeriesMetric = /*@__PURE__*/proto3.makeMessageType("livekit.TimeSeries
3672
3672
  kind: "message",
3673
3673
  T: MetricSample,
3674
3674
  repeated: true
3675
+ }, {
3676
+ no: 5,
3677
+ name: "rid",
3678
+ kind: "scalar",
3679
+ T: 13 /* ScalarType.UINT32 */
3675
3680
  }]);
3676
3681
 
3677
3682
  /**
@@ -3739,6 +3744,11 @@ const EventMetric = /*@__PURE__*/proto3.makeMessageType("livekit.EventMetric", (
3739
3744
  name: "metadata",
3740
3745
  kind: "scalar",
3741
3746
  T: 9 /* ScalarType.STRING */
3747
+ }, {
3748
+ no: 9,
3749
+ name: "rid",
3750
+ kind: "scalar",
3751
+ T: 13 /* ScalarType.UINT32 */
3742
3752
  }]);
3743
3753
 
3744
3754
  // Copyright 2023 LiveKit, Inc.
@@ -3874,6 +3884,12 @@ const DisconnectReason = /*@__PURE__*/proto3.makeEnum("livekit.DisconnectReason"
3874
3884
  }, {
3875
3885
  no: 10,
3876
3886
  name: "ROOM_CLOSED"
3887
+ }, {
3888
+ no: 11,
3889
+ name: "USER_UNAVAILABLE"
3890
+ }, {
3891
+ no: 12,
3892
+ name: "USER_REJECTED"
3877
3893
  }]);
3878
3894
 
3879
3895
  /**
@@ -4419,6 +4435,24 @@ const DataPacket = /*@__PURE__*/proto3.makeMessageType("livekit.DataPacket", ()
4419
4435
  kind: "message",
4420
4436
  T: ChatMessage,
4421
4437
  oneof: "value"
4438
+ }, {
4439
+ no: 10,
4440
+ name: "rpc_request",
4441
+ kind: "message",
4442
+ T: RpcRequest,
4443
+ oneof: "value"
4444
+ }, {
4445
+ no: 11,
4446
+ name: "rpc_ack",
4447
+ kind: "message",
4448
+ T: RpcAck,
4449
+ oneof: "value"
4450
+ }, {
4451
+ no: 12,
4452
+ name: "rpc_response",
4453
+ kind: "message",
4454
+ T: RpcResponse,
4455
+ oneof: "value"
4422
4456
  }]);
4423
4457
 
4424
4458
  /**
@@ -4626,6 +4660,88 @@ const ChatMessage = /*@__PURE__*/proto3.makeMessageType("livekit.ChatMessage", (
4626
4660
  T: 8 /* ScalarType.BOOL */
4627
4661
  }]);
4628
4662
 
4663
+ /**
4664
+ * @generated from message livekit.RpcRequest
4665
+ */
4666
+ const RpcRequest = /*@__PURE__*/proto3.makeMessageType("livekit.RpcRequest", () => [{
4667
+ no: 1,
4668
+ name: "id",
4669
+ kind: "scalar",
4670
+ T: 9 /* ScalarType.STRING */
4671
+ }, {
4672
+ no: 2,
4673
+ name: "method",
4674
+ kind: "scalar",
4675
+ T: 9 /* ScalarType.STRING */
4676
+ }, {
4677
+ no: 3,
4678
+ name: "payload",
4679
+ kind: "scalar",
4680
+ T: 9 /* ScalarType.STRING */
4681
+ }, {
4682
+ no: 4,
4683
+ name: "response_timeout_ms",
4684
+ kind: "scalar",
4685
+ T: 13 /* ScalarType.UINT32 */
4686
+ }, {
4687
+ no: 5,
4688
+ name: "version",
4689
+ kind: "scalar",
4690
+ T: 13 /* ScalarType.UINT32 */
4691
+ }]);
4692
+
4693
+ /**
4694
+ * @generated from message livekit.RpcAck
4695
+ */
4696
+ const RpcAck = /*@__PURE__*/proto3.makeMessageType("livekit.RpcAck", () => [{
4697
+ no: 1,
4698
+ name: "request_id",
4699
+ kind: "scalar",
4700
+ T: 9 /* ScalarType.STRING */
4701
+ }]);
4702
+
4703
+ /**
4704
+ * @generated from message livekit.RpcResponse
4705
+ */
4706
+ const RpcResponse = /*@__PURE__*/proto3.makeMessageType("livekit.RpcResponse", () => [{
4707
+ no: 1,
4708
+ name: "request_id",
4709
+ kind: "scalar",
4710
+ T: 9 /* ScalarType.STRING */
4711
+ }, {
4712
+ no: 2,
4713
+ name: "payload",
4714
+ kind: "scalar",
4715
+ T: 9 /* ScalarType.STRING */,
4716
+ oneof: "value"
4717
+ }, {
4718
+ no: 3,
4719
+ name: "error",
4720
+ kind: "message",
4721
+ T: RpcError,
4722
+ oneof: "value"
4723
+ }]);
4724
+
4725
+ /**
4726
+ * @generated from message livekit.RpcError
4727
+ */
4728
+ const RpcError = /*@__PURE__*/proto3.makeMessageType("livekit.RpcError", () => [{
4729
+ no: 1,
4730
+ name: "code",
4731
+ kind: "scalar",
4732
+ T: 13 /* ScalarType.UINT32 */
4733
+ }, {
4734
+ no: 2,
4735
+ name: "message",
4736
+ kind: "scalar",
4737
+ T: 9 /* ScalarType.STRING */
4738
+ }, {
4739
+ no: 3,
4740
+ name: "data",
4741
+ kind: "scalar",
4742
+ T: 9 /* ScalarType.STRING */
4743
+ }]);
4744
+
4629
4745
  /**
4630
4746
  * @generated from message livekit.ParticipantTracks
4631
4747
  */
@@ -4750,6 +4866,11 @@ const ClientInfo = /*@__PURE__*/proto3.makeMessageType("livekit.ClientInfo", ()
4750
4866
  name: "network",
4751
4867
  kind: "scalar",
4752
4868
  T: 9 /* ScalarType.STRING */
4869
+ }, {
4870
+ no: 11,
4871
+ name: "other_sdks",
4872
+ kind: "scalar",
4873
+ T: 9 /* ScalarType.STRING */
4753
4874
  }]);
4754
4875
 
4755
4876
  /**
@@ -6094,13 +6215,11 @@ const TrackSubscribed = /*@__PURE__*/proto3.makeMessageType("livekit.TrackSubscr
6094
6215
  T: 9 /* ScalarType.STRING */
6095
6216
  }]);
6096
6217
 
6097
- var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
6098
-
6099
6218
  function getDefaultExportFromCjs (x) {
6100
6219
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
6101
6220
  }
6102
6221
 
6103
- var loglevel = {exports: {}};
6222
+ var loglevel$1 = {exports: {}};
6104
6223
 
6105
6224
  /*
6106
6225
  * loglevel - https://github.com/pimterry/loglevel
@@ -6108,315 +6227,323 @@ var loglevel = {exports: {}};
6108
6227
  * Copyright (c) 2013 Tim Perry
6109
6228
  * Licensed under the MIT license.
6110
6229
  */
6111
- (function (module) {
6112
- (function (root, definition) {
6113
-
6114
- if (module.exports) {
6115
- module.exports = definition();
6116
- } else {
6117
- root.log = definition();
6118
- }
6119
- })(commonjsGlobal, function () {
6120
-
6121
- // Slightly dubious tricks to cut down minimized file size
6122
- var noop = function () {};
6123
- var undefinedType = "undefined";
6124
- var isIE = typeof window !== undefinedType && typeof window.navigator !== undefinedType && /Trident\/|MSIE /.test(window.navigator.userAgent);
6125
- var logMethods = ["trace", "debug", "info", "warn", "error"];
6126
- var _loggersByName = {};
6127
- var defaultLogger = null;
6128
-
6129
- // Cross-browser bind equivalent that works at least back to IE6
6130
- function bindMethod(obj, methodName) {
6131
- var method = obj[methodName];
6132
- if (typeof method.bind === 'function') {
6133
- return method.bind(obj);
6230
+ var loglevel = loglevel$1.exports;
6231
+ var hasRequiredLoglevel;
6232
+ function requireLoglevel() {
6233
+ if (hasRequiredLoglevel) return loglevel$1.exports;
6234
+ hasRequiredLoglevel = 1;
6235
+ (function (module) {
6236
+ (function (root, definition) {
6237
+
6238
+ if (module.exports) {
6239
+ module.exports = definition();
6134
6240
  } else {
6135
- try {
6136
- return Function.prototype.bind.call(method, obj);
6137
- } catch (e) {
6138
- // Missing bind shim or IE8 + Modernizr, fallback to wrapping
6139
- return function () {
6140
- return Function.prototype.apply.apply(method, [obj, arguments]);
6141
- };
6241
+ root.log = definition();
6242
+ }
6243
+ })(loglevel, function () {
6244
+
6245
+ // Slightly dubious tricks to cut down minimized file size
6246
+ var noop = function () {};
6247
+ var undefinedType = "undefined";
6248
+ var isIE = typeof window !== undefinedType && typeof window.navigator !== undefinedType && /Trident\/|MSIE /.test(window.navigator.userAgent);
6249
+ var logMethods = ["trace", "debug", "info", "warn", "error"];
6250
+ var _loggersByName = {};
6251
+ var defaultLogger = null;
6252
+
6253
+ // Cross-browser bind equivalent that works at least back to IE6
6254
+ function bindMethod(obj, methodName) {
6255
+ var method = obj[methodName];
6256
+ if (typeof method.bind === 'function') {
6257
+ return method.bind(obj);
6258
+ } else {
6259
+ try {
6260
+ return Function.prototype.bind.call(method, obj);
6261
+ } catch (e) {
6262
+ // Missing bind shim or IE8 + Modernizr, fallback to wrapping
6263
+ return function () {
6264
+ return Function.prototype.apply.apply(method, [obj, arguments]);
6265
+ };
6266
+ }
6142
6267
  }
6143
6268
  }
6144
- }
6145
6269
 
6146
- // Trace() doesn't print the message in IE, so for that case we need to wrap it
6147
- function traceForIE() {
6148
- if (console.log) {
6149
- if (console.log.apply) {
6150
- console.log.apply(console, arguments);
6151
- } else {
6152
- // In old IE, native console methods themselves don't have apply().
6153
- Function.prototype.apply.apply(console.log, [console, arguments]);
6270
+ // Trace() doesn't print the message in IE, so for that case we need to wrap it
6271
+ function traceForIE() {
6272
+ if (console.log) {
6273
+ if (console.log.apply) {
6274
+ console.log.apply(console, arguments);
6275
+ } else {
6276
+ // In old IE, native console methods themselves don't have apply().
6277
+ Function.prototype.apply.apply(console.log, [console, arguments]);
6278
+ }
6154
6279
  }
6280
+ if (console.trace) console.trace();
6155
6281
  }
6156
- if (console.trace) console.trace();
6157
- }
6158
6282
 
6159
- // Build the best logging method possible for this env
6160
- // Wherever possible we want to bind, not wrap, to preserve stack traces
6161
- function realMethod(methodName) {
6162
- if (methodName === 'debug') {
6163
- methodName = 'log';
6164
- }
6165
- if (typeof console === undefinedType) {
6166
- return false; // No method possible, for now - fixed later by enableLoggingWhenConsoleArrives
6167
- } else if (methodName === 'trace' && isIE) {
6168
- return traceForIE;
6169
- } else if (console[methodName] !== undefined) {
6170
- return bindMethod(console, methodName);
6171
- } else if (console.log !== undefined) {
6172
- return bindMethod(console, 'log');
6173
- } else {
6174
- return noop;
6283
+ // Build the best logging method possible for this env
6284
+ // Wherever possible we want to bind, not wrap, to preserve stack traces
6285
+ function realMethod(methodName) {
6286
+ if (methodName === 'debug') {
6287
+ methodName = 'log';
6288
+ }
6289
+ if (typeof console === undefinedType) {
6290
+ return false; // No method possible, for now - fixed later by enableLoggingWhenConsoleArrives
6291
+ } else if (methodName === 'trace' && isIE) {
6292
+ return traceForIE;
6293
+ } else if (console[methodName] !== undefined) {
6294
+ return bindMethod(console, methodName);
6295
+ } else if (console.log !== undefined) {
6296
+ return bindMethod(console, 'log');
6297
+ } else {
6298
+ return noop;
6299
+ }
6175
6300
  }
6176
- }
6177
6301
 
6178
- // These private functions always need `this` to be set properly
6302
+ // These private functions always need `this` to be set properly
6179
6303
 
6180
- function replaceLoggingMethods() {
6181
- /*jshint validthis:true */
6182
- var level = this.getLevel();
6183
-
6184
- // Replace the actual methods.
6185
- for (var i = 0; i < logMethods.length; i++) {
6186
- var methodName = logMethods[i];
6187
- this[methodName] = i < level ? noop : this.methodFactory(methodName, level, this.name);
6188
- }
6304
+ function replaceLoggingMethods() {
6305
+ /*jshint validthis:true */
6306
+ var level = this.getLevel();
6189
6307
 
6190
- // Define log.log as an alias for log.debug
6191
- this.log = this.debug;
6308
+ // Replace the actual methods.
6309
+ for (var i = 0; i < logMethods.length; i++) {
6310
+ var methodName = logMethods[i];
6311
+ this[methodName] = i < level ? noop : this.methodFactory(methodName, level, this.name);
6312
+ }
6192
6313
 
6193
- // Return any important warnings.
6194
- if (typeof console === undefinedType && level < this.levels.SILENT) {
6195
- return "No console available for logging";
6196
- }
6197
- }
6314
+ // Define log.log as an alias for log.debug
6315
+ this.log = this.debug;
6198
6316
 
6199
- // In old IE versions, the console isn't present until you first open it.
6200
- // We build realMethod() replacements here that regenerate logging methods
6201
- function enableLoggingWhenConsoleArrives(methodName) {
6202
- return function () {
6203
- if (typeof console !== undefinedType) {
6204
- replaceLoggingMethods.call(this);
6205
- this[methodName].apply(this, arguments);
6317
+ // Return any important warnings.
6318
+ if (typeof console === undefinedType && level < this.levels.SILENT) {
6319
+ return "No console available for logging";
6206
6320
  }
6207
- };
6208
- }
6321
+ }
6209
6322
 
6210
- // By default, we use closely bound real methods wherever possible, and
6211
- // otherwise we wait for a console to appear, and then try again.
6212
- function defaultMethodFactory(methodName, _level, _loggerName) {
6213
- /*jshint validthis:true */
6214
- return realMethod(methodName) || enableLoggingWhenConsoleArrives.apply(this, arguments);
6215
- }
6216
- function Logger(name, factory) {
6217
- // Private instance variables.
6218
- var self = this;
6219
- /**
6220
- * The level inherited from a parent logger (or a global default). We
6221
- * cache this here rather than delegating to the parent so that it stays
6222
- * in sync with the actual logging methods that we have installed (the
6223
- * parent could change levels but we might not have rebuilt the loggers
6224
- * in this child yet).
6225
- * @type {number}
6226
- */
6227
- var inheritedLevel;
6228
- /**
6229
- * The default level for this logger, if any. If set, this overrides
6230
- * `inheritedLevel`.
6231
- * @type {number|null}
6232
- */
6233
- var defaultLevel;
6234
- /**
6235
- * A user-specific level for this logger. If set, this overrides
6236
- * `defaultLevel`.
6237
- * @type {number|null}
6238
- */
6239
- var userLevel;
6240
- var storageKey = "loglevel";
6241
- if (typeof name === "string") {
6242
- storageKey += ":" + name;
6243
- } else if (typeof name === "symbol") {
6244
- storageKey = undefined;
6245
- }
6246
- function persistLevelIfPossible(levelNum) {
6247
- var levelName = (logMethods[levelNum] || 'silent').toUpperCase();
6248
- if (typeof window === undefinedType || !storageKey) return;
6249
-
6250
- // Use localStorage if available
6251
- try {
6252
- window.localStorage[storageKey] = levelName;
6253
- return;
6254
- } catch (ignore) {}
6323
+ // In old IE versions, the console isn't present until you first open it.
6324
+ // We build realMethod() replacements here that regenerate logging methods
6325
+ function enableLoggingWhenConsoleArrives(methodName) {
6326
+ return function () {
6327
+ if (typeof console !== undefinedType) {
6328
+ replaceLoggingMethods.call(this);
6329
+ this[methodName].apply(this, arguments);
6330
+ }
6331
+ };
6332
+ }
6255
6333
 
6256
- // Use session cookie as fallback
6257
- try {
6258
- window.document.cookie = encodeURIComponent(storageKey) + "=" + levelName + ";";
6259
- } catch (ignore) {}
6334
+ // By default, we use closely bound real methods wherever possible, and
6335
+ // otherwise we wait for a console to appear, and then try again.
6336
+ function defaultMethodFactory(methodName, _level, _loggerName) {
6337
+ /*jshint validthis:true */
6338
+ return realMethod(methodName) || enableLoggingWhenConsoleArrives.apply(this, arguments);
6260
6339
  }
6261
- function getPersistedLevel() {
6262
- var storedLevel;
6263
- if (typeof window === undefinedType || !storageKey) return;
6264
- try {
6265
- storedLevel = window.localStorage[storageKey];
6266
- } catch (ignore) {}
6340
+ function Logger(name, factory) {
6341
+ // Private instance variables.
6342
+ var self = this;
6343
+ /**
6344
+ * The level inherited from a parent logger (or a global default). We
6345
+ * cache this here rather than delegating to the parent so that it stays
6346
+ * in sync with the actual logging methods that we have installed (the
6347
+ * parent could change levels but we might not have rebuilt the loggers
6348
+ * in this child yet).
6349
+ * @type {number}
6350
+ */
6351
+ var inheritedLevel;
6352
+ /**
6353
+ * The default level for this logger, if any. If set, this overrides
6354
+ * `inheritedLevel`.
6355
+ * @type {number|null}
6356
+ */
6357
+ var defaultLevel;
6358
+ /**
6359
+ * A user-specific level for this logger. If set, this overrides
6360
+ * `defaultLevel`.
6361
+ * @type {number|null}
6362
+ */
6363
+ var userLevel;
6364
+ var storageKey = "loglevel";
6365
+ if (typeof name === "string") {
6366
+ storageKey += ":" + name;
6367
+ } else if (typeof name === "symbol") {
6368
+ storageKey = undefined;
6369
+ }
6370
+ function persistLevelIfPossible(levelNum) {
6371
+ var levelName = (logMethods[levelNum] || 'silent').toUpperCase();
6372
+ if (typeof window === undefinedType || !storageKey) return;
6373
+
6374
+ // Use localStorage if available
6375
+ try {
6376
+ window.localStorage[storageKey] = levelName;
6377
+ return;
6378
+ } catch (ignore) {}
6267
6379
 
6268
- // Fallback to cookies if local storage gives us nothing
6269
- if (typeof storedLevel === undefinedType) {
6380
+ // Use session cookie as fallback
6270
6381
  try {
6271
- var cookie = window.document.cookie;
6272
- var cookieName = encodeURIComponent(storageKey);
6273
- var location = cookie.indexOf(cookieName + "=");
6274
- if (location !== -1) {
6275
- storedLevel = /^([^;]+)/.exec(cookie.slice(location + cookieName.length + 1))[1];
6276
- }
6382
+ window.document.cookie = encodeURIComponent(storageKey) + "=" + levelName + ";";
6277
6383
  } catch (ignore) {}
6278
6384
  }
6385
+ function getPersistedLevel() {
6386
+ var storedLevel;
6387
+ if (typeof window === undefinedType || !storageKey) return;
6388
+ try {
6389
+ storedLevel = window.localStorage[storageKey];
6390
+ } catch (ignore) {}
6391
+
6392
+ // Fallback to cookies if local storage gives us nothing
6393
+ if (typeof storedLevel === undefinedType) {
6394
+ try {
6395
+ var cookie = window.document.cookie;
6396
+ var cookieName = encodeURIComponent(storageKey);
6397
+ var location = cookie.indexOf(cookieName + "=");
6398
+ if (location !== -1) {
6399
+ storedLevel = /^([^;]+)/.exec(cookie.slice(location + cookieName.length + 1))[1];
6400
+ }
6401
+ } catch (ignore) {}
6402
+ }
6279
6403
 
6280
- // If the stored level is not valid, treat it as if nothing was stored.
6281
- if (self.levels[storedLevel] === undefined) {
6282
- storedLevel = undefined;
6404
+ // If the stored level is not valid, treat it as if nothing was stored.
6405
+ if (self.levels[storedLevel] === undefined) {
6406
+ storedLevel = undefined;
6407
+ }
6408
+ return storedLevel;
6283
6409
  }
6284
- return storedLevel;
6285
- }
6286
- function clearPersistedLevel() {
6287
- if (typeof window === undefinedType || !storageKey) return;
6410
+ function clearPersistedLevel() {
6411
+ if (typeof window === undefinedType || !storageKey) return;
6288
6412
 
6289
- // Use localStorage if available
6290
- try {
6291
- window.localStorage.removeItem(storageKey);
6292
- } catch (ignore) {}
6413
+ // Use localStorage if available
6414
+ try {
6415
+ window.localStorage.removeItem(storageKey);
6416
+ } catch (ignore) {}
6293
6417
 
6294
- // Use session cookie as fallback
6295
- try {
6296
- window.document.cookie = encodeURIComponent(storageKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC";
6297
- } catch (ignore) {}
6298
- }
6299
- function normalizeLevel(input) {
6300
- var level = input;
6301
- if (typeof level === "string" && self.levels[level.toUpperCase()] !== undefined) {
6302
- level = self.levels[level.toUpperCase()];
6418
+ // Use session cookie as fallback
6419
+ try {
6420
+ window.document.cookie = encodeURIComponent(storageKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC";
6421
+ } catch (ignore) {}
6303
6422
  }
6304
- if (typeof level === "number" && level >= 0 && level <= self.levels.SILENT) {
6305
- return level;
6306
- } else {
6307
- throw new TypeError("log.setLevel() called with invalid level: " + input);
6423
+ function normalizeLevel(input) {
6424
+ var level = input;
6425
+ if (typeof level === "string" && self.levels[level.toUpperCase()] !== undefined) {
6426
+ level = self.levels[level.toUpperCase()];
6427
+ }
6428
+ if (typeof level === "number" && level >= 0 && level <= self.levels.SILENT) {
6429
+ return level;
6430
+ } else {
6431
+ throw new TypeError("log.setLevel() called with invalid level: " + input);
6432
+ }
6433
+ }
6434
+
6435
+ /*
6436
+ *
6437
+ * Public logger API - see https://github.com/pimterry/loglevel for details
6438
+ *
6439
+ */
6440
+
6441
+ self.name = name;
6442
+ self.levels = {
6443
+ "TRACE": 0,
6444
+ "DEBUG": 1,
6445
+ "INFO": 2,
6446
+ "WARN": 3,
6447
+ "ERROR": 4,
6448
+ "SILENT": 5
6449
+ };
6450
+ self.methodFactory = factory || defaultMethodFactory;
6451
+ self.getLevel = function () {
6452
+ if (userLevel != null) {
6453
+ return userLevel;
6454
+ } else if (defaultLevel != null) {
6455
+ return defaultLevel;
6456
+ } else {
6457
+ return inheritedLevel;
6458
+ }
6459
+ };
6460
+ self.setLevel = function (level, persist) {
6461
+ userLevel = normalizeLevel(level);
6462
+ if (persist !== false) {
6463
+ // defaults to true
6464
+ persistLevelIfPossible(userLevel);
6465
+ }
6466
+
6467
+ // NOTE: in v2, this should call rebuild(), which updates children.
6468
+ return replaceLoggingMethods.call(self);
6469
+ };
6470
+ self.setDefaultLevel = function (level) {
6471
+ defaultLevel = normalizeLevel(level);
6472
+ if (!getPersistedLevel()) {
6473
+ self.setLevel(level, false);
6474
+ }
6475
+ };
6476
+ self.resetLevel = function () {
6477
+ userLevel = null;
6478
+ clearPersistedLevel();
6479
+ replaceLoggingMethods.call(self);
6480
+ };
6481
+ self.enableAll = function (persist) {
6482
+ self.setLevel(self.levels.TRACE, persist);
6483
+ };
6484
+ self.disableAll = function (persist) {
6485
+ self.setLevel(self.levels.SILENT, persist);
6486
+ };
6487
+ self.rebuild = function () {
6488
+ if (defaultLogger !== self) {
6489
+ inheritedLevel = normalizeLevel(defaultLogger.getLevel());
6490
+ }
6491
+ replaceLoggingMethods.call(self);
6492
+ if (defaultLogger === self) {
6493
+ for (var childName in _loggersByName) {
6494
+ _loggersByName[childName].rebuild();
6495
+ }
6496
+ }
6497
+ };
6498
+
6499
+ // Initialize all the internal levels.
6500
+ inheritedLevel = normalizeLevel(defaultLogger ? defaultLogger.getLevel() : "WARN");
6501
+ var initialLevel = getPersistedLevel();
6502
+ if (initialLevel != null) {
6503
+ userLevel = normalizeLevel(initialLevel);
6308
6504
  }
6505
+ replaceLoggingMethods.call(self);
6309
6506
  }
6310
6507
 
6311
6508
  /*
6312
6509
  *
6313
- * Public logger API - see https://github.com/pimterry/loglevel for details
6510
+ * Top-level API
6314
6511
  *
6315
6512
  */
6316
6513
 
6317
- self.name = name;
6318
- self.levels = {
6319
- "TRACE": 0,
6320
- "DEBUG": 1,
6321
- "INFO": 2,
6322
- "WARN": 3,
6323
- "ERROR": 4,
6324
- "SILENT": 5
6325
- };
6326
- self.methodFactory = factory || defaultMethodFactory;
6327
- self.getLevel = function () {
6328
- if (userLevel != null) {
6329
- return userLevel;
6330
- } else if (defaultLevel != null) {
6331
- return defaultLevel;
6332
- } else {
6333
- return inheritedLevel;
6514
+ defaultLogger = new Logger();
6515
+ defaultLogger.getLogger = function getLogger(name) {
6516
+ if (typeof name !== "symbol" && typeof name !== "string" || name === "") {
6517
+ throw new TypeError("You must supply a name when creating a logger.");
6334
6518
  }
6335
- };
6336
- self.setLevel = function (level, persist) {
6337
- userLevel = normalizeLevel(level);
6338
- if (persist !== false) {
6339
- // defaults to true
6340
- persistLevelIfPossible(userLevel);
6519
+ var logger = _loggersByName[name];
6520
+ if (!logger) {
6521
+ logger = _loggersByName[name] = new Logger(name, defaultLogger.methodFactory);
6341
6522
  }
6342
-
6343
- // NOTE: in v2, this should call rebuild(), which updates children.
6344
- return replaceLoggingMethods.call(self);
6523
+ return logger;
6345
6524
  };
6346
- self.setDefaultLevel = function (level) {
6347
- defaultLevel = normalizeLevel(level);
6348
- if (!getPersistedLevel()) {
6349
- self.setLevel(level, false);
6525
+
6526
+ // Grab the current global log variable in case of overwrite
6527
+ var _log = typeof window !== undefinedType ? window.log : undefined;
6528
+ defaultLogger.noConflict = function () {
6529
+ if (typeof window !== undefinedType && window.log === defaultLogger) {
6530
+ window.log = _log;
6350
6531
  }
6532
+ return defaultLogger;
6351
6533
  };
6352
- self.resetLevel = function () {
6353
- userLevel = null;
6354
- clearPersistedLevel();
6355
- replaceLoggingMethods.call(self);
6356
- };
6357
- self.enableAll = function (persist) {
6358
- self.setLevel(self.levels.TRACE, persist);
6534
+ defaultLogger.getLoggers = function getLoggers() {
6535
+ return _loggersByName;
6359
6536
  };
6360
- self.disableAll = function (persist) {
6361
- self.setLevel(self.levels.SILENT, persist);
6362
- };
6363
- self.rebuild = function () {
6364
- if (defaultLogger !== self) {
6365
- inheritedLevel = normalizeLevel(defaultLogger.getLevel());
6366
- }
6367
- replaceLoggingMethods.call(self);
6368
- if (defaultLogger === self) {
6369
- for (var childName in _loggersByName) {
6370
- _loggersByName[childName].rebuild();
6371
- }
6372
- }
6373
- };
6374
-
6375
- // Initialize all the internal levels.
6376
- inheritedLevel = normalizeLevel(defaultLogger ? defaultLogger.getLevel() : "WARN");
6377
- var initialLevel = getPersistedLevel();
6378
- if (initialLevel != null) {
6379
- userLevel = normalizeLevel(initialLevel);
6380
- }
6381
- replaceLoggingMethods.call(self);
6382
- }
6383
-
6384
- /*
6385
- *
6386
- * Top-level API
6387
- *
6388
- */
6389
6537
 
6390
- defaultLogger = new Logger();
6391
- defaultLogger.getLogger = function getLogger(name) {
6392
- if (typeof name !== "symbol" && typeof name !== "string" || name === "") {
6393
- throw new TypeError("You must supply a name when creating a logger.");
6394
- }
6395
- var logger = _loggersByName[name];
6396
- if (!logger) {
6397
- logger = _loggersByName[name] = new Logger(name, defaultLogger.methodFactory);
6398
- }
6399
- return logger;
6400
- };
6401
-
6402
- // Grab the current global log variable in case of overwrite
6403
- var _log = typeof window !== undefinedType ? window.log : undefined;
6404
- defaultLogger.noConflict = function () {
6405
- if (typeof window !== undefinedType && window.log === defaultLogger) {
6406
- window.log = _log;
6407
- }
6538
+ // ES6 default export, for compatibility
6539
+ defaultLogger['default'] = defaultLogger;
6408
6540
  return defaultLogger;
6409
- };
6410
- defaultLogger.getLoggers = function getLoggers() {
6411
- return _loggersByName;
6412
- };
6541
+ });
6542
+ })(loglevel$1);
6543
+ return loglevel$1.exports;
6544
+ }
6413
6545
 
6414
- // ES6 default export, for compatibility
6415
- defaultLogger['default'] = defaultLogger;
6416
- return defaultLogger;
6417
- });
6418
- })(loglevel);
6419
- var loglevelExports = loglevel.exports;
6546
+ var loglevelExports = requireLoglevel();
6420
6547
 
6421
6548
  var LogLevel;
6422
6549
  (function (LogLevel) {
@@ -6552,383 +6679,390 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
6552
6679
 
6553
6680
  var events = {exports: {}};
6554
6681
 
6555
- var R = typeof Reflect === 'object' ? Reflect : null;
6556
- var ReflectApply = R && typeof R.apply === 'function' ? R.apply : function ReflectApply(target, receiver, args) {
6557
- return Function.prototype.apply.call(target, receiver, args);
6558
- };
6559
- var ReflectOwnKeys;
6560
- if (R && typeof R.ownKeys === 'function') {
6561
- ReflectOwnKeys = R.ownKeys;
6562
- } else if (Object.getOwnPropertySymbols) {
6563
- ReflectOwnKeys = function ReflectOwnKeys(target) {
6564
- return Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target));
6682
+ var hasRequiredEvents;
6683
+ function requireEvents() {
6684
+ if (hasRequiredEvents) return events.exports;
6685
+ hasRequiredEvents = 1;
6686
+ var R = typeof Reflect === 'object' ? Reflect : null;
6687
+ var ReflectApply = R && typeof R.apply === 'function' ? R.apply : function ReflectApply(target, receiver, args) {
6688
+ return Function.prototype.apply.call(target, receiver, args);
6565
6689
  };
6566
- } else {
6567
- ReflectOwnKeys = function ReflectOwnKeys(target) {
6568
- return Object.getOwnPropertyNames(target);
6569
- };
6570
- }
6571
- function ProcessEmitWarning(warning) {
6572
- if (console && console.warn) console.warn(warning);
6573
- }
6574
- var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {
6575
- return value !== value;
6576
- };
6577
- function EventEmitter() {
6578
- EventEmitter.init.call(this);
6579
- }
6580
- events.exports = EventEmitter;
6581
- events.exports.once = once;
6582
-
6583
- // Backwards-compat with node 0.10.x
6584
- EventEmitter.EventEmitter = EventEmitter;
6585
- EventEmitter.prototype._events = undefined;
6586
- EventEmitter.prototype._eventsCount = 0;
6587
- EventEmitter.prototype._maxListeners = undefined;
6588
-
6589
- // By default EventEmitters will print a warning if more than 10 listeners are
6590
- // added to it. This is a useful default which helps finding memory leaks.
6591
- var defaultMaxListeners = 10;
6592
- function checkListener(listener) {
6593
- if (typeof listener !== 'function') {
6594
- throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
6595
- }
6596
- }
6597
- Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
6598
- enumerable: true,
6599
- get: function () {
6600
- return defaultMaxListeners;
6601
- },
6602
- set: function (arg) {
6603
- if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {
6604
- throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.');
6605
- }
6606
- defaultMaxListeners = arg;
6690
+ var ReflectOwnKeys;
6691
+ if (R && typeof R.ownKeys === 'function') {
6692
+ ReflectOwnKeys = R.ownKeys;
6693
+ } else if (Object.getOwnPropertySymbols) {
6694
+ ReflectOwnKeys = function ReflectOwnKeys(target) {
6695
+ return Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target));
6696
+ };
6697
+ } else {
6698
+ ReflectOwnKeys = function ReflectOwnKeys(target) {
6699
+ return Object.getOwnPropertyNames(target);
6700
+ };
6607
6701
  }
6608
- });
6609
- EventEmitter.init = function () {
6610
- if (this._events === undefined || this._events === Object.getPrototypeOf(this)._events) {
6611
- this._events = Object.create(null);
6612
- this._eventsCount = 0;
6702
+ function ProcessEmitWarning(warning) {
6703
+ if (console && console.warn) console.warn(warning);
6613
6704
  }
6614
- this._maxListeners = this._maxListeners || undefined;
6615
- };
6616
-
6617
- // Obviously not all Emitters should be limited to 10. This function allows
6618
- // that to be increased. Set to zero for unlimited.
6619
- EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
6620
- if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {
6621
- throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.');
6705
+ var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) {
6706
+ return value !== value;
6707
+ };
6708
+ function EventEmitter() {
6709
+ EventEmitter.init.call(this);
6622
6710
  }
6623
- this._maxListeners = n;
6624
- return this;
6625
- };
6626
- function _getMaxListeners(that) {
6627
- if (that._maxListeners === undefined) return EventEmitter.defaultMaxListeners;
6628
- return that._maxListeners;
6629
- }
6630
- EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
6631
- return _getMaxListeners(this);
6632
- };
6633
- EventEmitter.prototype.emit = function emit(type) {
6634
- var args = [];
6635
- for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);
6636
- var doError = type === 'error';
6637
- var events = this._events;
6638
- if (events !== undefined) doError = doError && events.error === undefined;else if (!doError) return false;
6639
-
6640
- // If there is no 'error' event listener then throw.
6641
- if (doError) {
6642
- var er;
6643
- if (args.length > 0) er = args[0];
6644
- if (er instanceof Error) {
6645
- // Note: The comments on the `throw` lines are intentional, they show
6646
- // up in Node's output if this results in an unhandled exception.
6647
- throw er; // Unhandled 'error' event
6648
- }
6649
- // At least give some kind of context to the user
6650
- var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));
6651
- err.context = er;
6652
- throw err; // Unhandled 'error' event
6653
- }
6654
- var handler = events[type];
6655
- if (handler === undefined) return false;
6656
- if (typeof handler === 'function') {
6657
- ReflectApply(handler, this, args);
6658
- } else {
6659
- var len = handler.length;
6660
- var listeners = arrayClone(handler, len);
6661
- for (var i = 0; i < len; ++i) ReflectApply(listeners[i], this, args);
6711
+ events.exports = EventEmitter;
6712
+ events.exports.once = once;
6713
+
6714
+ // Backwards-compat with node 0.10.x
6715
+ EventEmitter.EventEmitter = EventEmitter;
6716
+ EventEmitter.prototype._events = undefined;
6717
+ EventEmitter.prototype._eventsCount = 0;
6718
+ EventEmitter.prototype._maxListeners = undefined;
6719
+
6720
+ // By default EventEmitters will print a warning if more than 10 listeners are
6721
+ // added to it. This is a useful default which helps finding memory leaks.
6722
+ var defaultMaxListeners = 10;
6723
+ function checkListener(listener) {
6724
+ if (typeof listener !== 'function') {
6725
+ throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener);
6726
+ }
6662
6727
  }
6663
- return true;
6664
- };
6665
- function _addListener(target, type, listener, prepend) {
6666
- var m;
6667
- var events;
6668
- var existing;
6669
- checkListener(listener);
6670
- events = target._events;
6671
- if (events === undefined) {
6672
- events = target._events = Object.create(null);
6673
- target._eventsCount = 0;
6674
- } else {
6675
- // To avoid recursion in the case that type === "newListener"! Before
6676
- // adding it to the listeners, first emit "newListener".
6677
- if (events.newListener !== undefined) {
6678
- target.emit('newListener', type, listener.listener ? listener.listener : listener);
6728
+ Object.defineProperty(EventEmitter, 'defaultMaxListeners', {
6729
+ enumerable: true,
6730
+ get: function () {
6731
+ return defaultMaxListeners;
6732
+ },
6733
+ set: function (arg) {
6734
+ if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) {
6735
+ throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.');
6736
+ }
6737
+ defaultMaxListeners = arg;
6738
+ }
6739
+ });
6740
+ EventEmitter.init = function () {
6741
+ if (this._events === undefined || this._events === Object.getPrototypeOf(this)._events) {
6742
+ this._events = Object.create(null);
6743
+ this._eventsCount = 0;
6744
+ }
6745
+ this._maxListeners = this._maxListeners || undefined;
6746
+ };
6679
6747
 
6680
- // Re-assign `events` because a newListener handler could have caused the
6681
- // this._events to be assigned to a new object
6682
- events = target._events;
6748
+ // Obviously not all Emitters should be limited to 10. This function allows
6749
+ // that to be increased. Set to zero for unlimited.
6750
+ EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) {
6751
+ if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) {
6752
+ throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.');
6683
6753
  }
6684
- existing = events[type];
6754
+ this._maxListeners = n;
6755
+ return this;
6756
+ };
6757
+ function _getMaxListeners(that) {
6758
+ if (that._maxListeners === undefined) return EventEmitter.defaultMaxListeners;
6759
+ return that._maxListeners;
6685
6760
  }
6686
- if (existing === undefined) {
6687
- // Optimize the case of one listener. Don't need the extra array object.
6688
- existing = events[type] = listener;
6689
- ++target._eventsCount;
6690
- } else {
6691
- if (typeof existing === 'function') {
6692
- // Adding the second element, need to change to array.
6693
- existing = events[type] = prepend ? [listener, existing] : [existing, listener];
6694
- // If we've already got an array, just append.
6695
- } else if (prepend) {
6696
- existing.unshift(listener);
6761
+ EventEmitter.prototype.getMaxListeners = function getMaxListeners() {
6762
+ return _getMaxListeners(this);
6763
+ };
6764
+ EventEmitter.prototype.emit = function emit(type) {
6765
+ var args = [];
6766
+ for (var i = 1; i < arguments.length; i++) args.push(arguments[i]);
6767
+ var doError = type === 'error';
6768
+ var events = this._events;
6769
+ if (events !== undefined) doError = doError && events.error === undefined;else if (!doError) return false;
6770
+
6771
+ // If there is no 'error' event listener then throw.
6772
+ if (doError) {
6773
+ var er;
6774
+ if (args.length > 0) er = args[0];
6775
+ if (er instanceof Error) {
6776
+ // Note: The comments on the `throw` lines are intentional, they show
6777
+ // up in Node's output if this results in an unhandled exception.
6778
+ throw er; // Unhandled 'error' event
6779
+ }
6780
+ // At least give some kind of context to the user
6781
+ var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : ''));
6782
+ err.context = er;
6783
+ throw err; // Unhandled 'error' event
6784
+ }
6785
+ var handler = events[type];
6786
+ if (handler === undefined) return false;
6787
+ if (typeof handler === 'function') {
6788
+ ReflectApply(handler, this, args);
6697
6789
  } else {
6698
- existing.push(listener);
6790
+ var len = handler.length;
6791
+ var listeners = arrayClone(handler, len);
6792
+ for (var i = 0; i < len; ++i) ReflectApply(listeners[i], this, args);
6699
6793
  }
6794
+ return true;
6795
+ };
6796
+ function _addListener(target, type, listener, prepend) {
6797
+ var m;
6798
+ var events;
6799
+ var existing;
6800
+ checkListener(listener);
6801
+ events = target._events;
6802
+ if (events === undefined) {
6803
+ events = target._events = Object.create(null);
6804
+ target._eventsCount = 0;
6805
+ } else {
6806
+ // To avoid recursion in the case that type === "newListener"! Before
6807
+ // adding it to the listeners, first emit "newListener".
6808
+ if (events.newListener !== undefined) {
6809
+ target.emit('newListener', type, listener.listener ? listener.listener : listener);
6700
6810
 
6701
- // Check for listener leak
6702
- m = _getMaxListeners(target);
6703
- if (m > 0 && existing.length > m && !existing.warned) {
6704
- existing.warned = true;
6705
- // No error code for this since it is a Warning
6706
- // eslint-disable-next-line no-restricted-syntax
6707
- var w = new Error('Possible EventEmitter memory leak detected. ' + existing.length + ' ' + String(type) + ' listeners ' + 'added. Use emitter.setMaxListeners() to ' + 'increase limit');
6708
- w.name = 'MaxListenersExceededWarning';
6709
- w.emitter = target;
6710
- w.type = type;
6711
- w.count = existing.length;
6712
- ProcessEmitWarning(w);
6811
+ // Re-assign `events` because a newListener handler could have caused the
6812
+ // this._events to be assigned to a new object
6813
+ events = target._events;
6814
+ }
6815
+ existing = events[type];
6713
6816
  }
6817
+ if (existing === undefined) {
6818
+ // Optimize the case of one listener. Don't need the extra array object.
6819
+ existing = events[type] = listener;
6820
+ ++target._eventsCount;
6821
+ } else {
6822
+ if (typeof existing === 'function') {
6823
+ // Adding the second element, need to change to array.
6824
+ existing = events[type] = prepend ? [listener, existing] : [existing, listener];
6825
+ // If we've already got an array, just append.
6826
+ } else if (prepend) {
6827
+ existing.unshift(listener);
6828
+ } else {
6829
+ existing.push(listener);
6830
+ }
6831
+
6832
+ // Check for listener leak
6833
+ m = _getMaxListeners(target);
6834
+ if (m > 0 && existing.length > m && !existing.warned) {
6835
+ existing.warned = true;
6836
+ // No error code for this since it is a Warning
6837
+ // eslint-disable-next-line no-restricted-syntax
6838
+ var w = new Error('Possible EventEmitter memory leak detected. ' + existing.length + ' ' + String(type) + ' listeners ' + 'added. Use emitter.setMaxListeners() to ' + 'increase limit');
6839
+ w.name = 'MaxListenersExceededWarning';
6840
+ w.emitter = target;
6841
+ w.type = type;
6842
+ w.count = existing.length;
6843
+ ProcessEmitWarning(w);
6844
+ }
6845
+ }
6846
+ return target;
6714
6847
  }
6715
- return target;
6716
- }
6717
- EventEmitter.prototype.addListener = function addListener(type, listener) {
6718
- return _addListener(this, type, listener, false);
6719
- };
6720
- EventEmitter.prototype.on = EventEmitter.prototype.addListener;
6721
- EventEmitter.prototype.prependListener = function prependListener(type, listener) {
6722
- return _addListener(this, type, listener, true);
6723
- };
6724
- function onceWrapper() {
6725
- if (!this.fired) {
6726
- this.target.removeListener(this.type, this.wrapFn);
6727
- this.fired = true;
6728
- if (arguments.length === 0) return this.listener.call(this.target);
6729
- return this.listener.apply(this.target, arguments);
6730
- }
6731
- }
6732
- function _onceWrap(target, type, listener) {
6733
- var state = {
6734
- fired: false,
6735
- wrapFn: undefined,
6736
- target: target,
6737
- type: type,
6738
- listener: listener
6848
+ EventEmitter.prototype.addListener = function addListener(type, listener) {
6849
+ return _addListener(this, type, listener, false);
6850
+ };
6851
+ EventEmitter.prototype.on = EventEmitter.prototype.addListener;
6852
+ EventEmitter.prototype.prependListener = function prependListener(type, listener) {
6853
+ return _addListener(this, type, listener, true);
6854
+ };
6855
+ function onceWrapper() {
6856
+ if (!this.fired) {
6857
+ this.target.removeListener(this.type, this.wrapFn);
6858
+ this.fired = true;
6859
+ if (arguments.length === 0) return this.listener.call(this.target);
6860
+ return this.listener.apply(this.target, arguments);
6861
+ }
6862
+ }
6863
+ function _onceWrap(target, type, listener) {
6864
+ var state = {
6865
+ fired: false,
6866
+ wrapFn: undefined,
6867
+ target: target,
6868
+ type: type,
6869
+ listener: listener
6870
+ };
6871
+ var wrapped = onceWrapper.bind(state);
6872
+ wrapped.listener = listener;
6873
+ state.wrapFn = wrapped;
6874
+ return wrapped;
6875
+ }
6876
+ EventEmitter.prototype.once = function once(type, listener) {
6877
+ checkListener(listener);
6878
+ this.on(type, _onceWrap(this, type, listener));
6879
+ return this;
6880
+ };
6881
+ EventEmitter.prototype.prependOnceListener = function prependOnceListener(type, listener) {
6882
+ checkListener(listener);
6883
+ this.prependListener(type, _onceWrap(this, type, listener));
6884
+ return this;
6739
6885
  };
6740
- var wrapped = onceWrapper.bind(state);
6741
- wrapped.listener = listener;
6742
- state.wrapFn = wrapped;
6743
- return wrapped;
6744
- }
6745
- EventEmitter.prototype.once = function once(type, listener) {
6746
- checkListener(listener);
6747
- this.on(type, _onceWrap(this, type, listener));
6748
- return this;
6749
- };
6750
- EventEmitter.prototype.prependOnceListener = function prependOnceListener(type, listener) {
6751
- checkListener(listener);
6752
- this.prependListener(type, _onceWrap(this, type, listener));
6753
- return this;
6754
- };
6755
6886
 
6756
- // Emits a 'removeListener' event if and only if the listener was removed.
6757
- EventEmitter.prototype.removeListener = function removeListener(type, listener) {
6758
- var list, events, position, i, originalListener;
6759
- checkListener(listener);
6760
- events = this._events;
6761
- if (events === undefined) return this;
6762
- list = events[type];
6763
- if (list === undefined) return this;
6764
- if (list === listener || list.listener === listener) {
6765
- if (--this._eventsCount === 0) this._events = Object.create(null);else {
6766
- delete events[type];
6767
- if (events.removeListener) this.emit('removeListener', type, list.listener || listener);
6768
- }
6769
- } else if (typeof list !== 'function') {
6770
- position = -1;
6771
- for (i = list.length - 1; i >= 0; i--) {
6772
- if (list[i] === listener || list[i].listener === listener) {
6773
- originalListener = list[i].listener;
6774
- position = i;
6775
- break;
6887
+ // Emits a 'removeListener' event if and only if the listener was removed.
6888
+ EventEmitter.prototype.removeListener = function removeListener(type, listener) {
6889
+ var list, events, position, i, originalListener;
6890
+ checkListener(listener);
6891
+ events = this._events;
6892
+ if (events === undefined) return this;
6893
+ list = events[type];
6894
+ if (list === undefined) return this;
6895
+ if (list === listener || list.listener === listener) {
6896
+ if (--this._eventsCount === 0) this._events = Object.create(null);else {
6897
+ delete events[type];
6898
+ if (events.removeListener) this.emit('removeListener', type, list.listener || listener);
6899
+ }
6900
+ } else if (typeof list !== 'function') {
6901
+ position = -1;
6902
+ for (i = list.length - 1; i >= 0; i--) {
6903
+ if (list[i] === listener || list[i].listener === listener) {
6904
+ originalListener = list[i].listener;
6905
+ position = i;
6906
+ break;
6907
+ }
6908
+ }
6909
+ if (position < 0) return this;
6910
+ if (position === 0) list.shift();else {
6911
+ spliceOne(list, position);
6776
6912
  }
6913
+ if (list.length === 1) events[type] = list[0];
6914
+ if (events.removeListener !== undefined) this.emit('removeListener', type, originalListener || listener);
6777
6915
  }
6778
- if (position < 0) return this;
6779
- if (position === 0) list.shift();else {
6780
- spliceOne(list, position);
6916
+ return this;
6917
+ };
6918
+ EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
6919
+ EventEmitter.prototype.removeAllListeners = function removeAllListeners(type) {
6920
+ var listeners, events, i;
6921
+ events = this._events;
6922
+ if (events === undefined) return this;
6923
+
6924
+ // not listening for removeListener, no need to emit
6925
+ if (events.removeListener === undefined) {
6926
+ if (arguments.length === 0) {
6927
+ this._events = Object.create(null);
6928
+ this._eventsCount = 0;
6929
+ } else if (events[type] !== undefined) {
6930
+ if (--this._eventsCount === 0) this._events = Object.create(null);else delete events[type];
6931
+ }
6932
+ return this;
6781
6933
  }
6782
- if (list.length === 1) events[type] = list[0];
6783
- if (events.removeListener !== undefined) this.emit('removeListener', type, originalListener || listener);
6784
- }
6785
- return this;
6786
- };
6787
- EventEmitter.prototype.off = EventEmitter.prototype.removeListener;
6788
- EventEmitter.prototype.removeAllListeners = function removeAllListeners(type) {
6789
- var listeners, events, i;
6790
- events = this._events;
6791
- if (events === undefined) return this;
6792
-
6793
- // not listening for removeListener, no need to emit
6794
- if (events.removeListener === undefined) {
6934
+
6935
+ // emit removeListener for all listeners on all events
6795
6936
  if (arguments.length === 0) {
6937
+ var keys = Object.keys(events);
6938
+ var key;
6939
+ for (i = 0; i < keys.length; ++i) {
6940
+ key = keys[i];
6941
+ if (key === 'removeListener') continue;
6942
+ this.removeAllListeners(key);
6943
+ }
6944
+ this.removeAllListeners('removeListener');
6796
6945
  this._events = Object.create(null);
6797
6946
  this._eventsCount = 0;
6798
- } else if (events[type] !== undefined) {
6799
- if (--this._eventsCount === 0) this._events = Object.create(null);else delete events[type];
6947
+ return this;
6800
6948
  }
6801
- return this;
6802
- }
6803
-
6804
- // emit removeListener for all listeners on all events
6805
- if (arguments.length === 0) {
6806
- var keys = Object.keys(events);
6807
- var key;
6808
- for (i = 0; i < keys.length; ++i) {
6809
- key = keys[i];
6810
- if (key === 'removeListener') continue;
6811
- this.removeAllListeners(key);
6949
+ listeners = events[type];
6950
+ if (typeof listeners === 'function') {
6951
+ this.removeListener(type, listeners);
6952
+ } else if (listeners !== undefined) {
6953
+ // LIFO order
6954
+ for (i = listeners.length - 1; i >= 0; i--) {
6955
+ this.removeListener(type, listeners[i]);
6956
+ }
6812
6957
  }
6813
- this.removeAllListeners('removeListener');
6814
- this._events = Object.create(null);
6815
- this._eventsCount = 0;
6816
6958
  return this;
6959
+ };
6960
+ function _listeners(target, type, unwrap) {
6961
+ var events = target._events;
6962
+ if (events === undefined) return [];
6963
+ var evlistener = events[type];
6964
+ if (evlistener === undefined) return [];
6965
+ if (typeof evlistener === 'function') return unwrap ? [evlistener.listener || evlistener] : [evlistener];
6966
+ return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
6817
6967
  }
6818
- listeners = events[type];
6819
- if (typeof listeners === 'function') {
6820
- this.removeListener(type, listeners);
6821
- } else if (listeners !== undefined) {
6822
- // LIFO order
6823
- for (i = listeners.length - 1; i >= 0; i--) {
6824
- this.removeListener(type, listeners[i]);
6968
+ EventEmitter.prototype.listeners = function listeners(type) {
6969
+ return _listeners(this, type, true);
6970
+ };
6971
+ EventEmitter.prototype.rawListeners = function rawListeners(type) {
6972
+ return _listeners(this, type, false);
6973
+ };
6974
+ EventEmitter.listenerCount = function (emitter, type) {
6975
+ if (typeof emitter.listenerCount === 'function') {
6976
+ return emitter.listenerCount(type);
6977
+ } else {
6978
+ return listenerCount.call(emitter, type);
6825
6979
  }
6826
- }
6827
- return this;
6828
- };
6829
- function _listeners(target, type, unwrap) {
6830
- var events = target._events;
6831
- if (events === undefined) return [];
6832
- var evlistener = events[type];
6833
- if (evlistener === undefined) return [];
6834
- if (typeof evlistener === 'function') return unwrap ? [evlistener.listener || evlistener] : [evlistener];
6835
- return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length);
6836
- }
6837
- EventEmitter.prototype.listeners = function listeners(type) {
6838
- return _listeners(this, type, true);
6839
- };
6840
- EventEmitter.prototype.rawListeners = function rawListeners(type) {
6841
- return _listeners(this, type, false);
6842
- };
6843
- EventEmitter.listenerCount = function (emitter, type) {
6844
- if (typeof emitter.listenerCount === 'function') {
6845
- return emitter.listenerCount(type);
6846
- } else {
6847
- return listenerCount.call(emitter, type);
6848
- }
6849
- };
6850
- EventEmitter.prototype.listenerCount = listenerCount;
6851
- function listenerCount(type) {
6852
- var events = this._events;
6853
- if (events !== undefined) {
6854
- var evlistener = events[type];
6855
- if (typeof evlistener === 'function') {
6856
- return 1;
6857
- } else if (evlistener !== undefined) {
6858
- return evlistener.length;
6980
+ };
6981
+ EventEmitter.prototype.listenerCount = listenerCount;
6982
+ function listenerCount(type) {
6983
+ var events = this._events;
6984
+ if (events !== undefined) {
6985
+ var evlistener = events[type];
6986
+ if (typeof evlistener === 'function') {
6987
+ return 1;
6988
+ } else if (evlistener !== undefined) {
6989
+ return evlistener.length;
6990
+ }
6859
6991
  }
6992
+ return 0;
6860
6993
  }
6861
- return 0;
6862
- }
6863
- EventEmitter.prototype.eventNames = function eventNames() {
6864
- return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];
6865
- };
6866
- function arrayClone(arr, n) {
6867
- var copy = new Array(n);
6868
- for (var i = 0; i < n; ++i) copy[i] = arr[i];
6869
- return copy;
6870
- }
6871
- function spliceOne(list, index) {
6872
- for (; index + 1 < list.length; index++) list[index] = list[index + 1];
6873
- list.pop();
6874
- }
6875
- function unwrapListeners(arr) {
6876
- var ret = new Array(arr.length);
6877
- for (var i = 0; i < ret.length; ++i) {
6878
- ret[i] = arr[i].listener || arr[i];
6994
+ EventEmitter.prototype.eventNames = function eventNames() {
6995
+ return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : [];
6996
+ };
6997
+ function arrayClone(arr, n) {
6998
+ var copy = new Array(n);
6999
+ for (var i = 0; i < n; ++i) copy[i] = arr[i];
7000
+ return copy;
6879
7001
  }
6880
- return ret;
6881
- }
6882
- function once(emitter, name) {
6883
- return new Promise(function (resolve, reject) {
6884
- function errorListener(err) {
6885
- emitter.removeListener(name, resolver);
6886
- reject(err);
7002
+ function spliceOne(list, index) {
7003
+ for (; index + 1 < list.length; index++) list[index] = list[index + 1];
7004
+ list.pop();
7005
+ }
7006
+ function unwrapListeners(arr) {
7007
+ var ret = new Array(arr.length);
7008
+ for (var i = 0; i < ret.length; ++i) {
7009
+ ret[i] = arr[i].listener || arr[i];
6887
7010
  }
6888
- function resolver() {
6889
- if (typeof emitter.removeListener === 'function') {
6890
- emitter.removeListener('error', errorListener);
7011
+ return ret;
7012
+ }
7013
+ function once(emitter, name) {
7014
+ return new Promise(function (resolve, reject) {
7015
+ function errorListener(err) {
7016
+ emitter.removeListener(name, resolver);
7017
+ reject(err);
6891
7018
  }
6892
- resolve([].slice.call(arguments));
6893
- }
6894
- eventTargetAgnosticAddListener(emitter, name, resolver, {
6895
- once: true
6896
- });
6897
- if (name !== 'error') {
6898
- addErrorHandlerIfEventEmitter(emitter, errorListener, {
7019
+ function resolver() {
7020
+ if (typeof emitter.removeListener === 'function') {
7021
+ emitter.removeListener('error', errorListener);
7022
+ }
7023
+ resolve([].slice.call(arguments));
7024
+ }
7025
+ eventTargetAgnosticAddListener(emitter, name, resolver, {
6899
7026
  once: true
6900
7027
  });
7028
+ if (name !== 'error') {
7029
+ addErrorHandlerIfEventEmitter(emitter, errorListener, {
7030
+ once: true
7031
+ });
7032
+ }
7033
+ });
7034
+ }
7035
+ function addErrorHandlerIfEventEmitter(emitter, handler, flags) {
7036
+ if (typeof emitter.on === 'function') {
7037
+ eventTargetAgnosticAddListener(emitter, 'error', handler, flags);
6901
7038
  }
6902
- });
6903
- }
6904
- function addErrorHandlerIfEventEmitter(emitter, handler, flags) {
6905
- if (typeof emitter.on === 'function') {
6906
- eventTargetAgnosticAddListener(emitter, 'error', handler, flags);
6907
7039
  }
6908
- }
6909
- function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
6910
- if (typeof emitter.on === 'function') {
6911
- if (flags.once) {
6912
- emitter.once(name, listener);
6913
- } else {
6914
- emitter.on(name, listener);
6915
- }
6916
- } else if (typeof emitter.addEventListener === 'function') {
6917
- // EventTarget does not have `error` event semantics like Node
6918
- // EventEmitters, we do not listen for `error` events here.
6919
- emitter.addEventListener(name, function wrapListener(arg) {
6920
- // IE does not have builtin `{ once: true }` support so we
6921
- // have to do it manually.
7040
+ function eventTargetAgnosticAddListener(emitter, name, listener, flags) {
7041
+ if (typeof emitter.on === 'function') {
6922
7042
  if (flags.once) {
6923
- emitter.removeEventListener(name, wrapListener);
6924
- }
6925
- listener(arg);
6926
- });
6927
- } else {
6928
- throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof emitter);
7043
+ emitter.once(name, listener);
7044
+ } else {
7045
+ emitter.on(name, listener);
7046
+ }
7047
+ } else if (typeof emitter.addEventListener === 'function') {
7048
+ // EventTarget does not have `error` event semantics like Node
7049
+ // EventEmitters, we do not listen for `error` events here.
7050
+ emitter.addEventListener(name, function wrapListener(arg) {
7051
+ // IE does not have builtin `{ once: true }` support so we
7052
+ // have to do it manually.
7053
+ if (flags.once) {
7054
+ emitter.removeEventListener(name, wrapListener);
7055
+ }
7056
+ listener(arg);
7057
+ });
7058
+ } else {
7059
+ throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof emitter);
7060
+ }
6929
7061
  }
7062
+ return events.exports;
6930
7063
  }
6931
- var eventsExports = events.exports;
7064
+
7065
+ var eventsExports = requireEvents();
6932
7066
 
6933
7067
  /*
6934
7068
  * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved.
@@ -8639,746 +8773,753 @@ var safariShim = /*#__PURE__*/Object.freeze({
8639
8773
  var sdp$1 = {exports: {}};
8640
8774
 
8641
8775
  /* eslint-env node */
8642
- (function (module) {
8643
-
8644
- // SDP helpers.
8645
- const SDPUtils = {};
8646
-
8647
- // Generate an alphanumeric identifier for cname or mids.
8648
- // TODO: use UUIDs instead? https://gist.github.com/jed/982883
8649
- SDPUtils.generateIdentifier = function () {
8650
- return Math.random().toString(36).substring(2, 12);
8651
- };
8652
-
8653
- // The RTCP CNAME used by all peerconnections from the same JS.
8654
- SDPUtils.localCName = SDPUtils.generateIdentifier();
8776
+ var hasRequiredSdp;
8777
+ function requireSdp() {
8778
+ if (hasRequiredSdp) return sdp$1.exports;
8779
+ hasRequiredSdp = 1;
8780
+ (function (module) {
8781
+
8782
+ // SDP helpers.
8783
+ const SDPUtils = {};
8784
+
8785
+ // Generate an alphanumeric identifier for cname or mids.
8786
+ // TODO: use UUIDs instead? https://gist.github.com/jed/982883
8787
+ SDPUtils.generateIdentifier = function () {
8788
+ return Math.random().toString(36).substring(2, 12);
8789
+ };
8655
8790
 
8656
- // Splits SDP into lines, dealing with both CRLF and LF.
8657
- SDPUtils.splitLines = function (blob) {
8658
- return blob.trim().split('\n').map(line => line.trim());
8659
- };
8660
- // Splits SDP into sessionpart and mediasections. Ensures CRLF.
8661
- SDPUtils.splitSections = function (blob) {
8662
- const parts = blob.split('\nm=');
8663
- return parts.map((part, index) => (index > 0 ? 'm=' + part : part).trim() + '\r\n');
8664
- };
8791
+ // The RTCP CNAME used by all peerconnections from the same JS.
8792
+ SDPUtils.localCName = SDPUtils.generateIdentifier();
8665
8793
 
8666
- // Returns the session description.
8667
- SDPUtils.getDescription = function (blob) {
8668
- const sections = SDPUtils.splitSections(blob);
8669
- return sections && sections[0];
8670
- };
8794
+ // Splits SDP into lines, dealing with both CRLF and LF.
8795
+ SDPUtils.splitLines = function (blob) {
8796
+ return blob.trim().split('\n').map(line => line.trim());
8797
+ };
8798
+ // Splits SDP into sessionpart and mediasections. Ensures CRLF.
8799
+ SDPUtils.splitSections = function (blob) {
8800
+ const parts = blob.split('\nm=');
8801
+ return parts.map((part, index) => (index > 0 ? 'm=' + part : part).trim() + '\r\n');
8802
+ };
8671
8803
 
8672
- // Returns the individual media sections.
8673
- SDPUtils.getMediaSections = function (blob) {
8674
- const sections = SDPUtils.splitSections(blob);
8675
- sections.shift();
8676
- return sections;
8677
- };
8804
+ // Returns the session description.
8805
+ SDPUtils.getDescription = function (blob) {
8806
+ const sections = SDPUtils.splitSections(blob);
8807
+ return sections && sections[0];
8808
+ };
8678
8809
 
8679
- // Returns lines that start with a certain prefix.
8680
- SDPUtils.matchPrefix = function (blob, prefix) {
8681
- return SDPUtils.splitLines(blob).filter(line => line.indexOf(prefix) === 0);
8682
- };
8810
+ // Returns the individual media sections.
8811
+ SDPUtils.getMediaSections = function (blob) {
8812
+ const sections = SDPUtils.splitSections(blob);
8813
+ sections.shift();
8814
+ return sections;
8815
+ };
8683
8816
 
8684
- // Parses an ICE candidate line. Sample input:
8685
- // candidate:702786350 2 udp 41819902 8.8.8.8 60769 typ relay raddr 8.8.8.8
8686
- // rport 55996"
8687
- // Input can be prefixed with a=.
8688
- SDPUtils.parseCandidate = function (line) {
8689
- let parts;
8690
- // Parse both variants.
8691
- if (line.indexOf('a=candidate:') === 0) {
8692
- parts = line.substring(12).split(' ');
8693
- } else {
8694
- parts = line.substring(10).split(' ');
8695
- }
8696
- const candidate = {
8697
- foundation: parts[0],
8698
- component: {
8699
- 1: 'rtp',
8700
- 2: 'rtcp'
8701
- }[parts[1]] || parts[1],
8702
- protocol: parts[2].toLowerCase(),
8703
- priority: parseInt(parts[3], 10),
8704
- ip: parts[4],
8705
- address: parts[4],
8706
- // address is an alias for ip.
8707
- port: parseInt(parts[5], 10),
8708
- // skip parts[6] == 'typ'
8709
- type: parts[7]
8817
+ // Returns lines that start with a certain prefix.
8818
+ SDPUtils.matchPrefix = function (blob, prefix) {
8819
+ return SDPUtils.splitLines(blob).filter(line => line.indexOf(prefix) === 0);
8710
8820
  };
8711
- for (let i = 8; i < parts.length; i += 2) {
8712
- switch (parts[i]) {
8713
- case 'raddr':
8714
- candidate.relatedAddress = parts[i + 1];
8715
- break;
8716
- case 'rport':
8717
- candidate.relatedPort = parseInt(parts[i + 1], 10);
8718
- break;
8719
- case 'tcptype':
8720
- candidate.tcpType = parts[i + 1];
8721
- break;
8722
- case 'ufrag':
8723
- candidate.ufrag = parts[i + 1]; // for backward compatibility.
8724
- candidate.usernameFragment = parts[i + 1];
8725
- break;
8726
- default:
8727
- // extension handling, in particular ufrag. Don't overwrite.
8728
- if (candidate[parts[i]] === undefined) {
8729
- candidate[parts[i]] = parts[i + 1];
8730
- }
8731
- break;
8732
- }
8733
- }
8734
- return candidate;
8735
- };
8736
8821
 
8737
- // Translates a candidate object into SDP candidate attribute.
8738
- // This does not include the a= prefix!
8739
- SDPUtils.writeCandidate = function (candidate) {
8740
- const sdp = [];
8741
- sdp.push(candidate.foundation);
8742
- const component = candidate.component;
8743
- if (component === 'rtp') {
8744
- sdp.push(1);
8745
- } else if (component === 'rtcp') {
8746
- sdp.push(2);
8747
- } else {
8748
- sdp.push(component);
8749
- }
8750
- sdp.push(candidate.protocol.toUpperCase());
8751
- sdp.push(candidate.priority);
8752
- sdp.push(candidate.address || candidate.ip);
8753
- sdp.push(candidate.port);
8754
- const type = candidate.type;
8755
- sdp.push('typ');
8756
- sdp.push(type);
8757
- if (type !== 'host' && candidate.relatedAddress && candidate.relatedPort) {
8758
- sdp.push('raddr');
8759
- sdp.push(candidate.relatedAddress);
8760
- sdp.push('rport');
8761
- sdp.push(candidate.relatedPort);
8762
- }
8763
- if (candidate.tcpType && candidate.protocol.toLowerCase() === 'tcp') {
8764
- sdp.push('tcptype');
8765
- sdp.push(candidate.tcpType);
8766
- }
8767
- if (candidate.usernameFragment || candidate.ufrag) {
8768
- sdp.push('ufrag');
8769
- sdp.push(candidate.usernameFragment || candidate.ufrag);
8770
- }
8771
- return 'candidate:' + sdp.join(' ');
8772
- };
8822
+ // Parses an ICE candidate line. Sample input:
8823
+ // candidate:702786350 2 udp 41819902 8.8.8.8 60769 typ relay raddr 8.8.8.8
8824
+ // rport 55996"
8825
+ // Input can be prefixed with a=.
8826
+ SDPUtils.parseCandidate = function (line) {
8827
+ let parts;
8828
+ // Parse both variants.
8829
+ if (line.indexOf('a=candidate:') === 0) {
8830
+ parts = line.substring(12).split(' ');
8831
+ } else {
8832
+ parts = line.substring(10).split(' ');
8833
+ }
8834
+ const candidate = {
8835
+ foundation: parts[0],
8836
+ component: {
8837
+ 1: 'rtp',
8838
+ 2: 'rtcp'
8839
+ }[parts[1]] || parts[1],
8840
+ protocol: parts[2].toLowerCase(),
8841
+ priority: parseInt(parts[3], 10),
8842
+ ip: parts[4],
8843
+ address: parts[4],
8844
+ // address is an alias for ip.
8845
+ port: parseInt(parts[5], 10),
8846
+ // skip parts[6] == 'typ'
8847
+ type: parts[7]
8848
+ };
8849
+ for (let i = 8; i < parts.length; i += 2) {
8850
+ switch (parts[i]) {
8851
+ case 'raddr':
8852
+ candidate.relatedAddress = parts[i + 1];
8853
+ break;
8854
+ case 'rport':
8855
+ candidate.relatedPort = parseInt(parts[i + 1], 10);
8856
+ break;
8857
+ case 'tcptype':
8858
+ candidate.tcpType = parts[i + 1];
8859
+ break;
8860
+ case 'ufrag':
8861
+ candidate.ufrag = parts[i + 1]; // for backward compatibility.
8862
+ candidate.usernameFragment = parts[i + 1];
8863
+ break;
8864
+ default:
8865
+ // extension handling, in particular ufrag. Don't overwrite.
8866
+ if (candidate[parts[i]] === undefined) {
8867
+ candidate[parts[i]] = parts[i + 1];
8868
+ }
8869
+ break;
8870
+ }
8871
+ }
8872
+ return candidate;
8873
+ };
8773
8874
 
8774
- // Parses an ice-options line, returns an array of option tags.
8775
- // Sample input:
8776
- // a=ice-options:foo bar
8777
- SDPUtils.parseIceOptions = function (line) {
8778
- return line.substring(14).split(' ');
8779
- };
8875
+ // Translates a candidate object into SDP candidate attribute.
8876
+ // This does not include the a= prefix!
8877
+ SDPUtils.writeCandidate = function (candidate) {
8878
+ const sdp = [];
8879
+ sdp.push(candidate.foundation);
8880
+ const component = candidate.component;
8881
+ if (component === 'rtp') {
8882
+ sdp.push(1);
8883
+ } else if (component === 'rtcp') {
8884
+ sdp.push(2);
8885
+ } else {
8886
+ sdp.push(component);
8887
+ }
8888
+ sdp.push(candidate.protocol.toUpperCase());
8889
+ sdp.push(candidate.priority);
8890
+ sdp.push(candidate.address || candidate.ip);
8891
+ sdp.push(candidate.port);
8892
+ const type = candidate.type;
8893
+ sdp.push('typ');
8894
+ sdp.push(type);
8895
+ if (type !== 'host' && candidate.relatedAddress && candidate.relatedPort) {
8896
+ sdp.push('raddr');
8897
+ sdp.push(candidate.relatedAddress);
8898
+ sdp.push('rport');
8899
+ sdp.push(candidate.relatedPort);
8900
+ }
8901
+ if (candidate.tcpType && candidate.protocol.toLowerCase() === 'tcp') {
8902
+ sdp.push('tcptype');
8903
+ sdp.push(candidate.tcpType);
8904
+ }
8905
+ if (candidate.usernameFragment || candidate.ufrag) {
8906
+ sdp.push('ufrag');
8907
+ sdp.push(candidate.usernameFragment || candidate.ufrag);
8908
+ }
8909
+ return 'candidate:' + sdp.join(' ');
8910
+ };
8780
8911
 
8781
- // Parses a rtpmap line, returns RTCRtpCoddecParameters. Sample input:
8782
- // a=rtpmap:111 opus/48000/2
8783
- SDPUtils.parseRtpMap = function (line) {
8784
- let parts = line.substring(9).split(' ');
8785
- const parsed = {
8786
- payloadType: parseInt(parts.shift(), 10) // was: id
8912
+ // Parses an ice-options line, returns an array of option tags.
8913
+ // Sample input:
8914
+ // a=ice-options:foo bar
8915
+ SDPUtils.parseIceOptions = function (line) {
8916
+ return line.substring(14).split(' ');
8787
8917
  };
8788
- parts = parts[0].split('/');
8789
- parsed.name = parts[0];
8790
- parsed.clockRate = parseInt(parts[1], 10); // was: clockrate
8791
- parsed.channels = parts.length === 3 ? parseInt(parts[2], 10) : 1;
8792
- // legacy alias, got renamed back to channels in ORTC.
8793
- parsed.numChannels = parsed.channels;
8794
- return parsed;
8795
- };
8796
8918
 
8797
- // Generates a rtpmap line from RTCRtpCodecCapability or
8798
- // RTCRtpCodecParameters.
8799
- SDPUtils.writeRtpMap = function (codec) {
8800
- let pt = codec.payloadType;
8801
- if (codec.preferredPayloadType !== undefined) {
8802
- pt = codec.preferredPayloadType;
8803
- }
8804
- const channels = codec.channels || codec.numChannels || 1;
8805
- return 'a=rtpmap:' + pt + ' ' + codec.name + '/' + codec.clockRate + (channels !== 1 ? '/' + channels : '') + '\r\n';
8806
- };
8919
+ // Parses a rtpmap line, returns RTCRtpCoddecParameters. Sample input:
8920
+ // a=rtpmap:111 opus/48000/2
8921
+ SDPUtils.parseRtpMap = function (line) {
8922
+ let parts = line.substring(9).split(' ');
8923
+ const parsed = {
8924
+ payloadType: parseInt(parts.shift(), 10) // was: id
8925
+ };
8926
+ parts = parts[0].split('/');
8927
+ parsed.name = parts[0];
8928
+ parsed.clockRate = parseInt(parts[1], 10); // was: clockrate
8929
+ parsed.channels = parts.length === 3 ? parseInt(parts[2], 10) : 1;
8930
+ // legacy alias, got renamed back to channels in ORTC.
8931
+ parsed.numChannels = parsed.channels;
8932
+ return parsed;
8933
+ };
8807
8934
 
8808
- // Parses a extmap line (headerextension from RFC 5285). Sample input:
8809
- // a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
8810
- // a=extmap:2/sendonly urn:ietf:params:rtp-hdrext:toffset
8811
- SDPUtils.parseExtmap = function (line) {
8812
- const parts = line.substring(9).split(' ');
8813
- return {
8814
- id: parseInt(parts[0], 10),
8815
- direction: parts[0].indexOf('/') > 0 ? parts[0].split('/')[1] : 'sendrecv',
8816
- uri: parts[1],
8817
- attributes: parts.slice(2).join(' ')
8935
+ // Generates a rtpmap line from RTCRtpCodecCapability or
8936
+ // RTCRtpCodecParameters.
8937
+ SDPUtils.writeRtpMap = function (codec) {
8938
+ let pt = codec.payloadType;
8939
+ if (codec.preferredPayloadType !== undefined) {
8940
+ pt = codec.preferredPayloadType;
8941
+ }
8942
+ const channels = codec.channels || codec.numChannels || 1;
8943
+ return 'a=rtpmap:' + pt + ' ' + codec.name + '/' + codec.clockRate + (channels !== 1 ? '/' + channels : '') + '\r\n';
8818
8944
  };
8819
- };
8820
8945
 
8821
- // Generates an extmap line from RTCRtpHeaderExtensionParameters or
8822
- // RTCRtpHeaderExtension.
8823
- SDPUtils.writeExtmap = function (headerExtension) {
8824
- return 'a=extmap:' + (headerExtension.id || headerExtension.preferredId) + (headerExtension.direction && headerExtension.direction !== 'sendrecv' ? '/' + headerExtension.direction : '') + ' ' + headerExtension.uri + (headerExtension.attributes ? ' ' + headerExtension.attributes : '') + '\r\n';
8825
- };
8946
+ // Parses a extmap line (headerextension from RFC 5285). Sample input:
8947
+ // a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
8948
+ // a=extmap:2/sendonly urn:ietf:params:rtp-hdrext:toffset
8949
+ SDPUtils.parseExtmap = function (line) {
8950
+ const parts = line.substring(9).split(' ');
8951
+ return {
8952
+ id: parseInt(parts[0], 10),
8953
+ direction: parts[0].indexOf('/') > 0 ? parts[0].split('/')[1] : 'sendrecv',
8954
+ uri: parts[1],
8955
+ attributes: parts.slice(2).join(' ')
8956
+ };
8957
+ };
8826
8958
 
8827
- // Parses a fmtp line, returns dictionary. Sample input:
8828
- // a=fmtp:96 vbr=on;cng=on
8829
- // Also deals with vbr=on; cng=on
8830
- SDPUtils.parseFmtp = function (line) {
8831
- const parsed = {};
8832
- let kv;
8833
- const parts = line.substring(line.indexOf(' ') + 1).split(';');
8834
- for (let j = 0; j < parts.length; j++) {
8835
- kv = parts[j].trim().split('=');
8836
- parsed[kv[0].trim()] = kv[1];
8837
- }
8838
- return parsed;
8839
- };
8959
+ // Generates an extmap line from RTCRtpHeaderExtensionParameters or
8960
+ // RTCRtpHeaderExtension.
8961
+ SDPUtils.writeExtmap = function (headerExtension) {
8962
+ return 'a=extmap:' + (headerExtension.id || headerExtension.preferredId) + (headerExtension.direction && headerExtension.direction !== 'sendrecv' ? '/' + headerExtension.direction : '') + ' ' + headerExtension.uri + (headerExtension.attributes ? ' ' + headerExtension.attributes : '') + '\r\n';
8963
+ };
8840
8964
 
8841
- // Generates a fmtp line from RTCRtpCodecCapability or RTCRtpCodecParameters.
8842
- SDPUtils.writeFmtp = function (codec) {
8843
- let line = '';
8844
- let pt = codec.payloadType;
8845
- if (codec.preferredPayloadType !== undefined) {
8846
- pt = codec.preferredPayloadType;
8847
- }
8848
- if (codec.parameters && Object.keys(codec.parameters).length) {
8849
- const params = [];
8850
- Object.keys(codec.parameters).forEach(param => {
8851
- if (codec.parameters[param] !== undefined) {
8852
- params.push(param + '=' + codec.parameters[param]);
8853
- } else {
8854
- params.push(param);
8855
- }
8856
- });
8857
- line += 'a=fmtp:' + pt + ' ' + params.join(';') + '\r\n';
8858
- }
8859
- return line;
8860
- };
8965
+ // Parses a fmtp line, returns dictionary. Sample input:
8966
+ // a=fmtp:96 vbr=on;cng=on
8967
+ // Also deals with vbr=on; cng=on
8968
+ SDPUtils.parseFmtp = function (line) {
8969
+ const parsed = {};
8970
+ let kv;
8971
+ const parts = line.substring(line.indexOf(' ') + 1).split(';');
8972
+ for (let j = 0; j < parts.length; j++) {
8973
+ kv = parts[j].trim().split('=');
8974
+ parsed[kv[0].trim()] = kv[1];
8975
+ }
8976
+ return parsed;
8977
+ };
8861
8978
 
8862
- // Parses a rtcp-fb line, returns RTCPRtcpFeedback object. Sample input:
8863
- // a=rtcp-fb:98 nack rpsi
8864
- SDPUtils.parseRtcpFb = function (line) {
8865
- const parts = line.substring(line.indexOf(' ') + 1).split(' ');
8866
- return {
8867
- type: parts.shift(),
8868
- parameter: parts.join(' ')
8979
+ // Generates a fmtp line from RTCRtpCodecCapability or RTCRtpCodecParameters.
8980
+ SDPUtils.writeFmtp = function (codec) {
8981
+ let line = '';
8982
+ let pt = codec.payloadType;
8983
+ if (codec.preferredPayloadType !== undefined) {
8984
+ pt = codec.preferredPayloadType;
8985
+ }
8986
+ if (codec.parameters && Object.keys(codec.parameters).length) {
8987
+ const params = [];
8988
+ Object.keys(codec.parameters).forEach(param => {
8989
+ if (codec.parameters[param] !== undefined) {
8990
+ params.push(param + '=' + codec.parameters[param]);
8991
+ } else {
8992
+ params.push(param);
8993
+ }
8994
+ });
8995
+ line += 'a=fmtp:' + pt + ' ' + params.join(';') + '\r\n';
8996
+ }
8997
+ return line;
8869
8998
  };
8870
- };
8871
8999
 
8872
- // Generate a=rtcp-fb lines from RTCRtpCodecCapability or RTCRtpCodecParameters.
8873
- SDPUtils.writeRtcpFb = function (codec) {
8874
- let lines = '';
8875
- let pt = codec.payloadType;
8876
- if (codec.preferredPayloadType !== undefined) {
8877
- pt = codec.preferredPayloadType;
8878
- }
8879
- if (codec.rtcpFeedback && codec.rtcpFeedback.length) {
8880
- // FIXME: special handling for trr-int?
8881
- codec.rtcpFeedback.forEach(fb => {
8882
- lines += 'a=rtcp-fb:' + pt + ' ' + fb.type + (fb.parameter && fb.parameter.length ? ' ' + fb.parameter : '') + '\r\n';
8883
- });
8884
- }
8885
- return lines;
8886
- };
9000
+ // Parses a rtcp-fb line, returns RTCPRtcpFeedback object. Sample input:
9001
+ // a=rtcp-fb:98 nack rpsi
9002
+ SDPUtils.parseRtcpFb = function (line) {
9003
+ const parts = line.substring(line.indexOf(' ') + 1).split(' ');
9004
+ return {
9005
+ type: parts.shift(),
9006
+ parameter: parts.join(' ')
9007
+ };
9008
+ };
8887
9009
 
8888
- // Parses a RFC 5576 ssrc media attribute. Sample input:
8889
- // a=ssrc:3735928559 cname:something
8890
- SDPUtils.parseSsrcMedia = function (line) {
8891
- const sp = line.indexOf(' ');
8892
- const parts = {
8893
- ssrc: parseInt(line.substring(7, sp), 10)
9010
+ // Generate a=rtcp-fb lines from RTCRtpCodecCapability or RTCRtpCodecParameters.
9011
+ SDPUtils.writeRtcpFb = function (codec) {
9012
+ let lines = '';
9013
+ let pt = codec.payloadType;
9014
+ if (codec.preferredPayloadType !== undefined) {
9015
+ pt = codec.preferredPayloadType;
9016
+ }
9017
+ if (codec.rtcpFeedback && codec.rtcpFeedback.length) {
9018
+ // FIXME: special handling for trr-int?
9019
+ codec.rtcpFeedback.forEach(fb => {
9020
+ lines += 'a=rtcp-fb:' + pt + ' ' + fb.type + (fb.parameter && fb.parameter.length ? ' ' + fb.parameter : '') + '\r\n';
9021
+ });
9022
+ }
9023
+ return lines;
8894
9024
  };
8895
- const colon = line.indexOf(':', sp);
8896
- if (colon > -1) {
8897
- parts.attribute = line.substring(sp + 1, colon);
8898
- parts.value = line.substring(colon + 1);
8899
- } else {
8900
- parts.attribute = line.substring(sp + 1);
8901
- }
8902
- return parts;
8903
- };
8904
9025
 
8905
- // Parse a ssrc-group line (see RFC 5576). Sample input:
8906
- // a=ssrc-group:semantics 12 34
8907
- SDPUtils.parseSsrcGroup = function (line) {
8908
- const parts = line.substring(13).split(' ');
8909
- return {
8910
- semantics: parts.shift(),
8911
- ssrcs: parts.map(ssrc => parseInt(ssrc, 10))
9026
+ // Parses a RFC 5576 ssrc media attribute. Sample input:
9027
+ // a=ssrc:3735928559 cname:something
9028
+ SDPUtils.parseSsrcMedia = function (line) {
9029
+ const sp = line.indexOf(' ');
9030
+ const parts = {
9031
+ ssrc: parseInt(line.substring(7, sp), 10)
9032
+ };
9033
+ const colon = line.indexOf(':', sp);
9034
+ if (colon > -1) {
9035
+ parts.attribute = line.substring(sp + 1, colon);
9036
+ parts.value = line.substring(colon + 1);
9037
+ } else {
9038
+ parts.attribute = line.substring(sp + 1);
9039
+ }
9040
+ return parts;
8912
9041
  };
8913
- };
8914
9042
 
8915
- // Extracts the MID (RFC 5888) from a media section.
8916
- // Returns the MID or undefined if no mid line was found.
8917
- SDPUtils.getMid = function (mediaSection) {
8918
- const mid = SDPUtils.matchPrefix(mediaSection, 'a=mid:')[0];
8919
- if (mid) {
8920
- return mid.substring(6);
8921
- }
8922
- };
9043
+ // Parse a ssrc-group line (see RFC 5576). Sample input:
9044
+ // a=ssrc-group:semantics 12 34
9045
+ SDPUtils.parseSsrcGroup = function (line) {
9046
+ const parts = line.substring(13).split(' ');
9047
+ return {
9048
+ semantics: parts.shift(),
9049
+ ssrcs: parts.map(ssrc => parseInt(ssrc, 10))
9050
+ };
9051
+ };
8923
9052
 
8924
- // Parses a fingerprint line for DTLS-SRTP.
8925
- SDPUtils.parseFingerprint = function (line) {
8926
- const parts = line.substring(14).split(' ');
8927
- return {
8928
- algorithm: parts[0].toLowerCase(),
8929
- // algorithm is case-sensitive in Edge.
8930
- value: parts[1].toUpperCase() // the definition is upper-case in RFC 4572.
9053
+ // Extracts the MID (RFC 5888) from a media section.
9054
+ // Returns the MID or undefined if no mid line was found.
9055
+ SDPUtils.getMid = function (mediaSection) {
9056
+ const mid = SDPUtils.matchPrefix(mediaSection, 'a=mid:')[0];
9057
+ if (mid) {
9058
+ return mid.substring(6);
9059
+ }
8931
9060
  };
8932
- };
8933
9061
 
8934
- // Extracts DTLS parameters from SDP media section or sessionpart.
8935
- // FIXME: for consistency with other functions this should only
8936
- // get the fingerprint line as input. See also getIceParameters.
8937
- SDPUtils.getDtlsParameters = function (mediaSection, sessionpart) {
8938
- const lines = SDPUtils.matchPrefix(mediaSection + sessionpart, 'a=fingerprint:');
8939
- // Note: a=setup line is ignored since we use the 'auto' role in Edge.
8940
- return {
8941
- role: 'auto',
8942
- fingerprints: lines.map(SDPUtils.parseFingerprint)
9062
+ // Parses a fingerprint line for DTLS-SRTP.
9063
+ SDPUtils.parseFingerprint = function (line) {
9064
+ const parts = line.substring(14).split(' ');
9065
+ return {
9066
+ algorithm: parts[0].toLowerCase(),
9067
+ // algorithm is case-sensitive in Edge.
9068
+ value: parts[1].toUpperCase() // the definition is upper-case in RFC 4572.
9069
+ };
8943
9070
  };
8944
- };
8945
9071
 
8946
- // Serializes DTLS parameters to SDP.
8947
- SDPUtils.writeDtlsParameters = function (params, setupType) {
8948
- let sdp = 'a=setup:' + setupType + '\r\n';
8949
- params.fingerprints.forEach(fp => {
8950
- sdp += 'a=fingerprint:' + fp.algorithm + ' ' + fp.value + '\r\n';
8951
- });
8952
- return sdp;
8953
- };
9072
+ // Extracts DTLS parameters from SDP media section or sessionpart.
9073
+ // FIXME: for consistency with other functions this should only
9074
+ // get the fingerprint line as input. See also getIceParameters.
9075
+ SDPUtils.getDtlsParameters = function (mediaSection, sessionpart) {
9076
+ const lines = SDPUtils.matchPrefix(mediaSection + sessionpart, 'a=fingerprint:');
9077
+ // Note: a=setup line is ignored since we use the 'auto' role in Edge.
9078
+ return {
9079
+ role: 'auto',
9080
+ fingerprints: lines.map(SDPUtils.parseFingerprint)
9081
+ };
9082
+ };
8954
9083
 
8955
- // Parses a=crypto lines into
8956
- // https://rawgit.com/aboba/edgertc/master/msortc-rs4.html#dictionary-rtcsrtpsdesparameters-members
8957
- SDPUtils.parseCryptoLine = function (line) {
8958
- const parts = line.substring(9).split(' ');
8959
- return {
8960
- tag: parseInt(parts[0], 10),
8961
- cryptoSuite: parts[1],
8962
- keyParams: parts[2],
8963
- sessionParams: parts.slice(3)
9084
+ // Serializes DTLS parameters to SDP.
9085
+ SDPUtils.writeDtlsParameters = function (params, setupType) {
9086
+ let sdp = 'a=setup:' + setupType + '\r\n';
9087
+ params.fingerprints.forEach(fp => {
9088
+ sdp += 'a=fingerprint:' + fp.algorithm + ' ' + fp.value + '\r\n';
9089
+ });
9090
+ return sdp;
8964
9091
  };
8965
- };
8966
- SDPUtils.writeCryptoLine = function (parameters) {
8967
- return 'a=crypto:' + parameters.tag + ' ' + parameters.cryptoSuite + ' ' + (typeof parameters.keyParams === 'object' ? SDPUtils.writeCryptoKeyParams(parameters.keyParams) : parameters.keyParams) + (parameters.sessionParams ? ' ' + parameters.sessionParams.join(' ') : '') + '\r\n';
8968
- };
8969
9092
 
8970
- // Parses the crypto key parameters into
8971
- // https://rawgit.com/aboba/edgertc/master/msortc-rs4.html#rtcsrtpkeyparam*
8972
- SDPUtils.parseCryptoKeyParams = function (keyParams) {
8973
- if (keyParams.indexOf('inline:') !== 0) {
8974
- return null;
8975
- }
8976
- const parts = keyParams.substring(7).split('|');
8977
- return {
8978
- keyMethod: 'inline',
8979
- keySalt: parts[0],
8980
- lifeTime: parts[1],
8981
- mkiValue: parts[2] ? parts[2].split(':')[0] : undefined,
8982
- mkiLength: parts[2] ? parts[2].split(':')[1] : undefined
9093
+ // Parses a=crypto lines into
9094
+ // https://rawgit.com/aboba/edgertc/master/msortc-rs4.html#dictionary-rtcsrtpsdesparameters-members
9095
+ SDPUtils.parseCryptoLine = function (line) {
9096
+ const parts = line.substring(9).split(' ');
9097
+ return {
9098
+ tag: parseInt(parts[0], 10),
9099
+ cryptoSuite: parts[1],
9100
+ keyParams: parts[2],
9101
+ sessionParams: parts.slice(3)
9102
+ };
9103
+ };
9104
+ SDPUtils.writeCryptoLine = function (parameters) {
9105
+ return 'a=crypto:' + parameters.tag + ' ' + parameters.cryptoSuite + ' ' + (typeof parameters.keyParams === 'object' ? SDPUtils.writeCryptoKeyParams(parameters.keyParams) : parameters.keyParams) + (parameters.sessionParams ? ' ' + parameters.sessionParams.join(' ') : '') + '\r\n';
8983
9106
  };
8984
- };
8985
- SDPUtils.writeCryptoKeyParams = function (keyParams) {
8986
- return keyParams.keyMethod + ':' + keyParams.keySalt + (keyParams.lifeTime ? '|' + keyParams.lifeTime : '') + (keyParams.mkiValue && keyParams.mkiLength ? '|' + keyParams.mkiValue + ':' + keyParams.mkiLength : '');
8987
- };
8988
9107
 
8989
- // Extracts all SDES parameters.
8990
- SDPUtils.getCryptoParameters = function (mediaSection, sessionpart) {
8991
- const lines = SDPUtils.matchPrefix(mediaSection + sessionpart, 'a=crypto:');
8992
- return lines.map(SDPUtils.parseCryptoLine);
8993
- };
9108
+ // Parses the crypto key parameters into
9109
+ // https://rawgit.com/aboba/edgertc/master/msortc-rs4.html#rtcsrtpkeyparam*
9110
+ SDPUtils.parseCryptoKeyParams = function (keyParams) {
9111
+ if (keyParams.indexOf('inline:') !== 0) {
9112
+ return null;
9113
+ }
9114
+ const parts = keyParams.substring(7).split('|');
9115
+ return {
9116
+ keyMethod: 'inline',
9117
+ keySalt: parts[0],
9118
+ lifeTime: parts[1],
9119
+ mkiValue: parts[2] ? parts[2].split(':')[0] : undefined,
9120
+ mkiLength: parts[2] ? parts[2].split(':')[1] : undefined
9121
+ };
9122
+ };
9123
+ SDPUtils.writeCryptoKeyParams = function (keyParams) {
9124
+ return keyParams.keyMethod + ':' + keyParams.keySalt + (keyParams.lifeTime ? '|' + keyParams.lifeTime : '') + (keyParams.mkiValue && keyParams.mkiLength ? '|' + keyParams.mkiValue + ':' + keyParams.mkiLength : '');
9125
+ };
8994
9126
 
8995
- // Parses ICE information from SDP media section or sessionpart.
8996
- // FIXME: for consistency with other functions this should only
8997
- // get the ice-ufrag and ice-pwd lines as input.
8998
- SDPUtils.getIceParameters = function (mediaSection, sessionpart) {
8999
- const ufrag = SDPUtils.matchPrefix(mediaSection + sessionpart, 'a=ice-ufrag:')[0];
9000
- const pwd = SDPUtils.matchPrefix(mediaSection + sessionpart, 'a=ice-pwd:')[0];
9001
- if (!(ufrag && pwd)) {
9002
- return null;
9003
- }
9004
- return {
9005
- usernameFragment: ufrag.substring(12),
9006
- password: pwd.substring(10)
9127
+ // Extracts all SDES parameters.
9128
+ SDPUtils.getCryptoParameters = function (mediaSection, sessionpart) {
9129
+ const lines = SDPUtils.matchPrefix(mediaSection + sessionpart, 'a=crypto:');
9130
+ return lines.map(SDPUtils.parseCryptoLine);
9007
9131
  };
9008
- };
9009
9132
 
9010
- // Serializes ICE parameters to SDP.
9011
- SDPUtils.writeIceParameters = function (params) {
9012
- let sdp = 'a=ice-ufrag:' + params.usernameFragment + '\r\n' + 'a=ice-pwd:' + params.password + '\r\n';
9013
- if (params.iceLite) {
9014
- sdp += 'a=ice-lite\r\n';
9015
- }
9016
- return sdp;
9017
- };
9133
+ // Parses ICE information from SDP media section or sessionpart.
9134
+ // FIXME: for consistency with other functions this should only
9135
+ // get the ice-ufrag and ice-pwd lines as input.
9136
+ SDPUtils.getIceParameters = function (mediaSection, sessionpart) {
9137
+ const ufrag = SDPUtils.matchPrefix(mediaSection + sessionpart, 'a=ice-ufrag:')[0];
9138
+ const pwd = SDPUtils.matchPrefix(mediaSection + sessionpart, 'a=ice-pwd:')[0];
9139
+ if (!(ufrag && pwd)) {
9140
+ return null;
9141
+ }
9142
+ return {
9143
+ usernameFragment: ufrag.substring(12),
9144
+ password: pwd.substring(10)
9145
+ };
9146
+ };
9018
9147
 
9019
- // Parses the SDP media section and returns RTCRtpParameters.
9020
- SDPUtils.parseRtpParameters = function (mediaSection) {
9021
- const description = {
9022
- codecs: [],
9023
- headerExtensions: [],
9024
- fecMechanisms: [],
9025
- rtcp: []
9148
+ // Serializes ICE parameters to SDP.
9149
+ SDPUtils.writeIceParameters = function (params) {
9150
+ let sdp = 'a=ice-ufrag:' + params.usernameFragment + '\r\n' + 'a=ice-pwd:' + params.password + '\r\n';
9151
+ if (params.iceLite) {
9152
+ sdp += 'a=ice-lite\r\n';
9153
+ }
9154
+ return sdp;
9026
9155
  };
9027
- const lines = SDPUtils.splitLines(mediaSection);
9028
- const mline = lines[0].split(' ');
9029
- description.profile = mline[2];
9030
- for (let i = 3; i < mline.length; i++) {
9031
- // find all codecs from mline[3..]
9032
- const pt = mline[i];
9033
- const rtpmapline = SDPUtils.matchPrefix(mediaSection, 'a=rtpmap:' + pt + ' ')[0];
9034
- if (rtpmapline) {
9035
- const codec = SDPUtils.parseRtpMap(rtpmapline);
9036
- const fmtps = SDPUtils.matchPrefix(mediaSection, 'a=fmtp:' + pt + ' ');
9037
- // Only the first a=fmtp:<pt> is considered.
9038
- codec.parameters = fmtps.length ? SDPUtils.parseFmtp(fmtps[0]) : {};
9039
- codec.rtcpFeedback = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-fb:' + pt + ' ').map(SDPUtils.parseRtcpFb);
9040
- description.codecs.push(codec);
9041
- // parse FEC mechanisms from rtpmap lines.
9042
- switch (codec.name.toUpperCase()) {
9043
- case 'RED':
9044
- case 'ULPFEC':
9045
- description.fecMechanisms.push(codec.name.toUpperCase());
9046
- break;
9156
+
9157
+ // Parses the SDP media section and returns RTCRtpParameters.
9158
+ SDPUtils.parseRtpParameters = function (mediaSection) {
9159
+ const description = {
9160
+ codecs: [],
9161
+ headerExtensions: [],
9162
+ fecMechanisms: [],
9163
+ rtcp: []
9164
+ };
9165
+ const lines = SDPUtils.splitLines(mediaSection);
9166
+ const mline = lines[0].split(' ');
9167
+ description.profile = mline[2];
9168
+ for (let i = 3; i < mline.length; i++) {
9169
+ // find all codecs from mline[3..]
9170
+ const pt = mline[i];
9171
+ const rtpmapline = SDPUtils.matchPrefix(mediaSection, 'a=rtpmap:' + pt + ' ')[0];
9172
+ if (rtpmapline) {
9173
+ const codec = SDPUtils.parseRtpMap(rtpmapline);
9174
+ const fmtps = SDPUtils.matchPrefix(mediaSection, 'a=fmtp:' + pt + ' ');
9175
+ // Only the first a=fmtp:<pt> is considered.
9176
+ codec.parameters = fmtps.length ? SDPUtils.parseFmtp(fmtps[0]) : {};
9177
+ codec.rtcpFeedback = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-fb:' + pt + ' ').map(SDPUtils.parseRtcpFb);
9178
+ description.codecs.push(codec);
9179
+ // parse FEC mechanisms from rtpmap lines.
9180
+ switch (codec.name.toUpperCase()) {
9181
+ case 'RED':
9182
+ case 'ULPFEC':
9183
+ description.fecMechanisms.push(codec.name.toUpperCase());
9184
+ break;
9185
+ }
9047
9186
  }
9048
9187
  }
9049
- }
9050
- SDPUtils.matchPrefix(mediaSection, 'a=extmap:').forEach(line => {
9051
- description.headerExtensions.push(SDPUtils.parseExtmap(line));
9052
- });
9053
- const wildcardRtcpFb = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-fb:* ').map(SDPUtils.parseRtcpFb);
9054
- description.codecs.forEach(codec => {
9055
- wildcardRtcpFb.forEach(fb => {
9056
- const duplicate = codec.rtcpFeedback.find(existingFeedback => {
9057
- return existingFeedback.type === fb.type && existingFeedback.parameter === fb.parameter;
9188
+ SDPUtils.matchPrefix(mediaSection, 'a=extmap:').forEach(line => {
9189
+ description.headerExtensions.push(SDPUtils.parseExtmap(line));
9190
+ });
9191
+ const wildcardRtcpFb = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-fb:* ').map(SDPUtils.parseRtcpFb);
9192
+ description.codecs.forEach(codec => {
9193
+ wildcardRtcpFb.forEach(fb => {
9194
+ const duplicate = codec.rtcpFeedback.find(existingFeedback => {
9195
+ return existingFeedback.type === fb.type && existingFeedback.parameter === fb.parameter;
9196
+ });
9197
+ if (!duplicate) {
9198
+ codec.rtcpFeedback.push(fb);
9199
+ }
9058
9200
  });
9059
- if (!duplicate) {
9060
- codec.rtcpFeedback.push(fb);
9061
- }
9062
9201
  });
9063
- });
9064
- // FIXME: parse rtcp.
9065
- return description;
9066
- };
9067
-
9068
- // Generates parts of the SDP media section describing the capabilities /
9069
- // parameters.
9070
- SDPUtils.writeRtpDescription = function (kind, caps) {
9071
- let sdp = '';
9202
+ // FIXME: parse rtcp.
9203
+ return description;
9204
+ };
9072
9205
 
9073
- // Build the mline.
9074
- sdp += 'm=' + kind + ' ';
9075
- sdp += caps.codecs.length > 0 ? '9' : '0'; // reject if no codecs.
9076
- sdp += ' ' + (caps.profile || 'UDP/TLS/RTP/SAVPF') + ' ';
9077
- sdp += caps.codecs.map(codec => {
9078
- if (codec.preferredPayloadType !== undefined) {
9079
- return codec.preferredPayloadType;
9206
+ // Generates parts of the SDP media section describing the capabilities /
9207
+ // parameters.
9208
+ SDPUtils.writeRtpDescription = function (kind, caps) {
9209
+ let sdp = '';
9210
+
9211
+ // Build the mline.
9212
+ sdp += 'm=' + kind + ' ';
9213
+ sdp += caps.codecs.length > 0 ? '9' : '0'; // reject if no codecs.
9214
+ sdp += ' ' + (caps.profile || 'UDP/TLS/RTP/SAVPF') + ' ';
9215
+ sdp += caps.codecs.map(codec => {
9216
+ if (codec.preferredPayloadType !== undefined) {
9217
+ return codec.preferredPayloadType;
9218
+ }
9219
+ return codec.payloadType;
9220
+ }).join(' ') + '\r\n';
9221
+ sdp += 'c=IN IP4 0.0.0.0\r\n';
9222
+ sdp += 'a=rtcp:9 IN IP4 0.0.0.0\r\n';
9223
+
9224
+ // Add a=rtpmap lines for each codec. Also fmtp and rtcp-fb.
9225
+ caps.codecs.forEach(codec => {
9226
+ sdp += SDPUtils.writeRtpMap(codec);
9227
+ sdp += SDPUtils.writeFmtp(codec);
9228
+ sdp += SDPUtils.writeRtcpFb(codec);
9229
+ });
9230
+ let maxptime = 0;
9231
+ caps.codecs.forEach(codec => {
9232
+ if (codec.maxptime > maxptime) {
9233
+ maxptime = codec.maxptime;
9234
+ }
9235
+ });
9236
+ if (maxptime > 0) {
9237
+ sdp += 'a=maxptime:' + maxptime + '\r\n';
9080
9238
  }
9081
- return codec.payloadType;
9082
- }).join(' ') + '\r\n';
9083
- sdp += 'c=IN IP4 0.0.0.0\r\n';
9084
- sdp += 'a=rtcp:9 IN IP4 0.0.0.0\r\n';
9085
-
9086
- // Add a=rtpmap lines for each codec. Also fmtp and rtcp-fb.
9087
- caps.codecs.forEach(codec => {
9088
- sdp += SDPUtils.writeRtpMap(codec);
9089
- sdp += SDPUtils.writeFmtp(codec);
9090
- sdp += SDPUtils.writeRtcpFb(codec);
9091
- });
9092
- let maxptime = 0;
9093
- caps.codecs.forEach(codec => {
9094
- if (codec.maxptime > maxptime) {
9095
- maxptime = codec.maxptime;
9239
+ if (caps.headerExtensions) {
9240
+ caps.headerExtensions.forEach(extension => {
9241
+ sdp += SDPUtils.writeExtmap(extension);
9242
+ });
9096
9243
  }
9097
- });
9098
- if (maxptime > 0) {
9099
- sdp += 'a=maxptime:' + maxptime + '\r\n';
9100
- }
9101
- if (caps.headerExtensions) {
9102
- caps.headerExtensions.forEach(extension => {
9103
- sdp += SDPUtils.writeExtmap(extension);
9104
- });
9105
- }
9106
- // FIXME: write fecMechanisms.
9107
- return sdp;
9108
- };
9244
+ // FIXME: write fecMechanisms.
9245
+ return sdp;
9246
+ };
9109
9247
 
9110
- // Parses the SDP media section and returns an array of
9111
- // RTCRtpEncodingParameters.
9112
- SDPUtils.parseRtpEncodingParameters = function (mediaSection) {
9113
- const encodingParameters = [];
9114
- const description = SDPUtils.parseRtpParameters(mediaSection);
9115
- const hasRed = description.fecMechanisms.indexOf('RED') !== -1;
9116
- const hasUlpfec = description.fecMechanisms.indexOf('ULPFEC') !== -1;
9117
-
9118
- // filter a=ssrc:... cname:, ignore PlanB-msid
9119
- const ssrcs = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:').map(line => SDPUtils.parseSsrcMedia(line)).filter(parts => parts.attribute === 'cname');
9120
- const primarySsrc = ssrcs.length > 0 && ssrcs[0].ssrc;
9121
- let secondarySsrc;
9122
- const flows = SDPUtils.matchPrefix(mediaSection, 'a=ssrc-group:FID').map(line => {
9123
- const parts = line.substring(17).split(' ');
9124
- return parts.map(part => parseInt(part, 10));
9125
- });
9126
- if (flows.length > 0 && flows[0].length > 1 && flows[0][0] === primarySsrc) {
9127
- secondarySsrc = flows[0][1];
9128
- }
9129
- description.codecs.forEach(codec => {
9130
- if (codec.name.toUpperCase() === 'RTX' && codec.parameters.apt) {
9131
- let encParam = {
9132
- ssrc: primarySsrc,
9133
- codecPayloadType: parseInt(codec.parameters.apt, 10)
9134
- };
9135
- if (primarySsrc && secondarySsrc) {
9136
- encParam.rtx = {
9137
- ssrc: secondarySsrc
9138
- };
9139
- }
9140
- encodingParameters.push(encParam);
9141
- if (hasRed) {
9142
- encParam = JSON.parse(JSON.stringify(encParam));
9143
- encParam.fec = {
9248
+ // Parses the SDP media section and returns an array of
9249
+ // RTCRtpEncodingParameters.
9250
+ SDPUtils.parseRtpEncodingParameters = function (mediaSection) {
9251
+ const encodingParameters = [];
9252
+ const description = SDPUtils.parseRtpParameters(mediaSection);
9253
+ const hasRed = description.fecMechanisms.indexOf('RED') !== -1;
9254
+ const hasUlpfec = description.fecMechanisms.indexOf('ULPFEC') !== -1;
9255
+
9256
+ // filter a=ssrc:... cname:, ignore PlanB-msid
9257
+ const ssrcs = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:').map(line => SDPUtils.parseSsrcMedia(line)).filter(parts => parts.attribute === 'cname');
9258
+ const primarySsrc = ssrcs.length > 0 && ssrcs[0].ssrc;
9259
+ let secondarySsrc;
9260
+ const flows = SDPUtils.matchPrefix(mediaSection, 'a=ssrc-group:FID').map(line => {
9261
+ const parts = line.substring(17).split(' ');
9262
+ return parts.map(part => parseInt(part, 10));
9263
+ });
9264
+ if (flows.length > 0 && flows[0].length > 1 && flows[0][0] === primarySsrc) {
9265
+ secondarySsrc = flows[0][1];
9266
+ }
9267
+ description.codecs.forEach(codec => {
9268
+ if (codec.name.toUpperCase() === 'RTX' && codec.parameters.apt) {
9269
+ let encParam = {
9144
9270
  ssrc: primarySsrc,
9145
- mechanism: hasUlpfec ? 'red+ulpfec' : 'red'
9271
+ codecPayloadType: parseInt(codec.parameters.apt, 10)
9146
9272
  };
9273
+ if (primarySsrc && secondarySsrc) {
9274
+ encParam.rtx = {
9275
+ ssrc: secondarySsrc
9276
+ };
9277
+ }
9147
9278
  encodingParameters.push(encParam);
9279
+ if (hasRed) {
9280
+ encParam = JSON.parse(JSON.stringify(encParam));
9281
+ encParam.fec = {
9282
+ ssrc: primarySsrc,
9283
+ mechanism: hasUlpfec ? 'red+ulpfec' : 'red'
9284
+ };
9285
+ encodingParameters.push(encParam);
9286
+ }
9148
9287
  }
9149
- }
9150
- });
9151
- if (encodingParameters.length === 0 && primarySsrc) {
9152
- encodingParameters.push({
9153
- ssrc: primarySsrc
9154
9288
  });
9155
- }
9289
+ if (encodingParameters.length === 0 && primarySsrc) {
9290
+ encodingParameters.push({
9291
+ ssrc: primarySsrc
9292
+ });
9293
+ }
9156
9294
 
9157
- // we support both b=AS and b=TIAS but interpret AS as TIAS.
9158
- let bandwidth = SDPUtils.matchPrefix(mediaSection, 'b=');
9159
- if (bandwidth.length) {
9160
- if (bandwidth[0].indexOf('b=TIAS:') === 0) {
9161
- bandwidth = parseInt(bandwidth[0].substring(7), 10);
9162
- } else if (bandwidth[0].indexOf('b=AS:') === 0) {
9163
- // use formula from JSEP to convert b=AS to TIAS value.
9164
- bandwidth = parseInt(bandwidth[0].substring(5), 10) * 1000 * 0.95 - 50 * 40 * 8;
9165
- } else {
9166
- bandwidth = undefined;
9295
+ // we support both b=AS and b=TIAS but interpret AS as TIAS.
9296
+ let bandwidth = SDPUtils.matchPrefix(mediaSection, 'b=');
9297
+ if (bandwidth.length) {
9298
+ if (bandwidth[0].indexOf('b=TIAS:') === 0) {
9299
+ bandwidth = parseInt(bandwidth[0].substring(7), 10);
9300
+ } else if (bandwidth[0].indexOf('b=AS:') === 0) {
9301
+ // use formula from JSEP to convert b=AS to TIAS value.
9302
+ bandwidth = parseInt(bandwidth[0].substring(5), 10) * 1000 * 0.95 - 50 * 40 * 8;
9303
+ } else {
9304
+ bandwidth = undefined;
9305
+ }
9306
+ encodingParameters.forEach(params => {
9307
+ params.maxBitrate = bandwidth;
9308
+ });
9167
9309
  }
9168
- encodingParameters.forEach(params => {
9169
- params.maxBitrate = bandwidth;
9170
- });
9171
- }
9172
- return encodingParameters;
9173
- };
9310
+ return encodingParameters;
9311
+ };
9174
9312
 
9175
- // parses http://draft.ortc.org/#rtcrtcpparameters*
9176
- SDPUtils.parseRtcpParameters = function (mediaSection) {
9177
- const rtcpParameters = {};
9178
-
9179
- // Gets the first SSRC. Note that with RTX there might be multiple
9180
- // SSRCs.
9181
- const remoteSsrc = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:').map(line => SDPUtils.parseSsrcMedia(line)).filter(obj => obj.attribute === 'cname')[0];
9182
- if (remoteSsrc) {
9183
- rtcpParameters.cname = remoteSsrc.value;
9184
- rtcpParameters.ssrc = remoteSsrc.ssrc;
9185
- }
9186
-
9187
- // Edge uses the compound attribute instead of reducedSize
9188
- // compound is !reducedSize
9189
- const rsize = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-rsize');
9190
- rtcpParameters.reducedSize = rsize.length > 0;
9191
- rtcpParameters.compound = rsize.length === 0;
9192
-
9193
- // parses the rtcp-mux attrіbute.
9194
- // Note that Edge does not support unmuxed RTCP.
9195
- const mux = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-mux');
9196
- rtcpParameters.mux = mux.length > 0;
9197
- return rtcpParameters;
9198
- };
9199
- SDPUtils.writeRtcpParameters = function (rtcpParameters) {
9200
- let sdp = '';
9201
- if (rtcpParameters.reducedSize) {
9202
- sdp += 'a=rtcp-rsize\r\n';
9203
- }
9204
- if (rtcpParameters.mux) {
9205
- sdp += 'a=rtcp-mux\r\n';
9206
- }
9207
- if (rtcpParameters.ssrc !== undefined && rtcpParameters.cname) {
9208
- sdp += 'a=ssrc:' + rtcpParameters.ssrc + ' cname:' + rtcpParameters.cname + '\r\n';
9209
- }
9210
- return sdp;
9211
- };
9313
+ // parses http://draft.ortc.org/#rtcrtcpparameters*
9314
+ SDPUtils.parseRtcpParameters = function (mediaSection) {
9315
+ const rtcpParameters = {};
9316
+
9317
+ // Gets the first SSRC. Note that with RTX there might be multiple
9318
+ // SSRCs.
9319
+ const remoteSsrc = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:').map(line => SDPUtils.parseSsrcMedia(line)).filter(obj => obj.attribute === 'cname')[0];
9320
+ if (remoteSsrc) {
9321
+ rtcpParameters.cname = remoteSsrc.value;
9322
+ rtcpParameters.ssrc = remoteSsrc.ssrc;
9323
+ }
9324
+
9325
+ // Edge uses the compound attribute instead of reducedSize
9326
+ // compound is !reducedSize
9327
+ const rsize = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-rsize');
9328
+ rtcpParameters.reducedSize = rsize.length > 0;
9329
+ rtcpParameters.compound = rsize.length === 0;
9330
+
9331
+ // parses the rtcp-mux attrіbute.
9332
+ // Note that Edge does not support unmuxed RTCP.
9333
+ const mux = SDPUtils.matchPrefix(mediaSection, 'a=rtcp-mux');
9334
+ rtcpParameters.mux = mux.length > 0;
9335
+ return rtcpParameters;
9336
+ };
9337
+ SDPUtils.writeRtcpParameters = function (rtcpParameters) {
9338
+ let sdp = '';
9339
+ if (rtcpParameters.reducedSize) {
9340
+ sdp += 'a=rtcp-rsize\r\n';
9341
+ }
9342
+ if (rtcpParameters.mux) {
9343
+ sdp += 'a=rtcp-mux\r\n';
9344
+ }
9345
+ if (rtcpParameters.ssrc !== undefined && rtcpParameters.cname) {
9346
+ sdp += 'a=ssrc:' + rtcpParameters.ssrc + ' cname:' + rtcpParameters.cname + '\r\n';
9347
+ }
9348
+ return sdp;
9349
+ };
9212
9350
 
9213
- // parses either a=msid: or a=ssrc:... msid lines and returns
9214
- // the id of the MediaStream and MediaStreamTrack.
9215
- SDPUtils.parseMsid = function (mediaSection) {
9216
- let parts;
9217
- const spec = SDPUtils.matchPrefix(mediaSection, 'a=msid:');
9218
- if (spec.length === 1) {
9219
- parts = spec[0].substring(7).split(' ');
9220
- return {
9221
- stream: parts[0],
9222
- track: parts[1]
9223
- };
9224
- }
9225
- const planB = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:').map(line => SDPUtils.parseSsrcMedia(line)).filter(msidParts => msidParts.attribute === 'msid');
9226
- if (planB.length > 0) {
9227
- parts = planB[0].value.split(' ');
9228
- return {
9229
- stream: parts[0],
9230
- track: parts[1]
9231
- };
9232
- }
9233
- };
9351
+ // parses either a=msid: or a=ssrc:... msid lines and returns
9352
+ // the id of the MediaStream and MediaStreamTrack.
9353
+ SDPUtils.parseMsid = function (mediaSection) {
9354
+ let parts;
9355
+ const spec = SDPUtils.matchPrefix(mediaSection, 'a=msid:');
9356
+ if (spec.length === 1) {
9357
+ parts = spec[0].substring(7).split(' ');
9358
+ return {
9359
+ stream: parts[0],
9360
+ track: parts[1]
9361
+ };
9362
+ }
9363
+ const planB = SDPUtils.matchPrefix(mediaSection, 'a=ssrc:').map(line => SDPUtils.parseSsrcMedia(line)).filter(msidParts => msidParts.attribute === 'msid');
9364
+ if (planB.length > 0) {
9365
+ parts = planB[0].value.split(' ');
9366
+ return {
9367
+ stream: parts[0],
9368
+ track: parts[1]
9369
+ };
9370
+ }
9371
+ };
9234
9372
 
9235
- // SCTP
9236
- // parses draft-ietf-mmusic-sctp-sdp-26 first and falls back
9237
- // to draft-ietf-mmusic-sctp-sdp-05
9238
- SDPUtils.parseSctpDescription = function (mediaSection) {
9239
- const mline = SDPUtils.parseMLine(mediaSection);
9240
- const maxSizeLine = SDPUtils.matchPrefix(mediaSection, 'a=max-message-size:');
9241
- let maxMessageSize;
9242
- if (maxSizeLine.length > 0) {
9243
- maxMessageSize = parseInt(maxSizeLine[0].substring(19), 10);
9244
- }
9245
- if (isNaN(maxMessageSize)) {
9246
- maxMessageSize = 65536;
9247
- }
9248
- const sctpPort = SDPUtils.matchPrefix(mediaSection, 'a=sctp-port:');
9249
- if (sctpPort.length > 0) {
9250
- return {
9251
- port: parseInt(sctpPort[0].substring(12), 10),
9252
- protocol: mline.fmt,
9253
- maxMessageSize
9254
- };
9255
- }
9256
- const sctpMapLines = SDPUtils.matchPrefix(mediaSection, 'a=sctpmap:');
9257
- if (sctpMapLines.length > 0) {
9258
- const parts = sctpMapLines[0].substring(10).split(' ');
9259
- return {
9260
- port: parseInt(parts[0], 10),
9261
- protocol: parts[1],
9262
- maxMessageSize
9263
- };
9264
- }
9265
- };
9373
+ // SCTP
9374
+ // parses draft-ietf-mmusic-sctp-sdp-26 first and falls back
9375
+ // to draft-ietf-mmusic-sctp-sdp-05
9376
+ SDPUtils.parseSctpDescription = function (mediaSection) {
9377
+ const mline = SDPUtils.parseMLine(mediaSection);
9378
+ const maxSizeLine = SDPUtils.matchPrefix(mediaSection, 'a=max-message-size:');
9379
+ let maxMessageSize;
9380
+ if (maxSizeLine.length > 0) {
9381
+ maxMessageSize = parseInt(maxSizeLine[0].substring(19), 10);
9382
+ }
9383
+ if (isNaN(maxMessageSize)) {
9384
+ maxMessageSize = 65536;
9385
+ }
9386
+ const sctpPort = SDPUtils.matchPrefix(mediaSection, 'a=sctp-port:');
9387
+ if (sctpPort.length > 0) {
9388
+ return {
9389
+ port: parseInt(sctpPort[0].substring(12), 10),
9390
+ protocol: mline.fmt,
9391
+ maxMessageSize
9392
+ };
9393
+ }
9394
+ const sctpMapLines = SDPUtils.matchPrefix(mediaSection, 'a=sctpmap:');
9395
+ if (sctpMapLines.length > 0) {
9396
+ const parts = sctpMapLines[0].substring(10).split(' ');
9397
+ return {
9398
+ port: parseInt(parts[0], 10),
9399
+ protocol: parts[1],
9400
+ maxMessageSize
9401
+ };
9402
+ }
9403
+ };
9266
9404
 
9267
- // SCTP
9268
- // outputs the draft-ietf-mmusic-sctp-sdp-26 version that all browsers
9269
- // support by now receiving in this format, unless we originally parsed
9270
- // as the draft-ietf-mmusic-sctp-sdp-05 format (indicated by the m-line
9271
- // protocol of DTLS/SCTP -- without UDP/ or TCP/)
9272
- SDPUtils.writeSctpDescription = function (media, sctp) {
9273
- let output = [];
9274
- if (media.protocol !== 'DTLS/SCTP') {
9275
- output = ['m=' + media.kind + ' 9 ' + media.protocol + ' ' + sctp.protocol + '\r\n', 'c=IN IP4 0.0.0.0\r\n', 'a=sctp-port:' + sctp.port + '\r\n'];
9276
- } else {
9277
- output = ['m=' + media.kind + ' 9 ' + media.protocol + ' ' + sctp.port + '\r\n', 'c=IN IP4 0.0.0.0\r\n', 'a=sctpmap:' + sctp.port + ' ' + sctp.protocol + ' 65535\r\n'];
9278
- }
9279
- if (sctp.maxMessageSize !== undefined) {
9280
- output.push('a=max-message-size:' + sctp.maxMessageSize + '\r\n');
9281
- }
9282
- return output.join('');
9283
- };
9405
+ // SCTP
9406
+ // outputs the draft-ietf-mmusic-sctp-sdp-26 version that all browsers
9407
+ // support by now receiving in this format, unless we originally parsed
9408
+ // as the draft-ietf-mmusic-sctp-sdp-05 format (indicated by the m-line
9409
+ // protocol of DTLS/SCTP -- without UDP/ or TCP/)
9410
+ SDPUtils.writeSctpDescription = function (media, sctp) {
9411
+ let output = [];
9412
+ if (media.protocol !== 'DTLS/SCTP') {
9413
+ output = ['m=' + media.kind + ' 9 ' + media.protocol + ' ' + sctp.protocol + '\r\n', 'c=IN IP4 0.0.0.0\r\n', 'a=sctp-port:' + sctp.port + '\r\n'];
9414
+ } else {
9415
+ output = ['m=' + media.kind + ' 9 ' + media.protocol + ' ' + sctp.port + '\r\n', 'c=IN IP4 0.0.0.0\r\n', 'a=sctpmap:' + sctp.port + ' ' + sctp.protocol + ' 65535\r\n'];
9416
+ }
9417
+ if (sctp.maxMessageSize !== undefined) {
9418
+ output.push('a=max-message-size:' + sctp.maxMessageSize + '\r\n');
9419
+ }
9420
+ return output.join('');
9421
+ };
9284
9422
 
9285
- // Generate a session ID for SDP.
9286
- // https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-20#section-5.2.1
9287
- // recommends using a cryptographically random +ve 64-bit value
9288
- // but right now this should be acceptable and within the right range
9289
- SDPUtils.generateSessionId = function () {
9290
- return Math.random().toString().substr(2, 22);
9291
- };
9423
+ // Generate a session ID for SDP.
9424
+ // https://tools.ietf.org/html/draft-ietf-rtcweb-jsep-20#section-5.2.1
9425
+ // recommends using a cryptographically random +ve 64-bit value
9426
+ // but right now this should be acceptable and within the right range
9427
+ SDPUtils.generateSessionId = function () {
9428
+ return Math.random().toString().substr(2, 22);
9429
+ };
9292
9430
 
9293
- // Write boiler plate for start of SDP
9294
- // sessId argument is optional - if not supplied it will
9295
- // be generated randomly
9296
- // sessVersion is optional and defaults to 2
9297
- // sessUser is optional and defaults to 'thisisadapterortc'
9298
- SDPUtils.writeSessionBoilerplate = function (sessId, sessVer, sessUser) {
9299
- let sessionId;
9300
- const version = sessVer !== undefined ? sessVer : 2;
9301
- if (sessId) {
9302
- sessionId = sessId;
9303
- } else {
9304
- sessionId = SDPUtils.generateSessionId();
9305
- }
9306
- const user = sessUser || 'thisisadapterortc';
9307
- // FIXME: sess-id should be an NTP timestamp.
9308
- return 'v=0\r\n' + 'o=' + user + ' ' + sessionId + ' ' + version + ' IN IP4 127.0.0.1\r\n' + 's=-\r\n' + 't=0 0\r\n';
9309
- };
9431
+ // Write boiler plate for start of SDP
9432
+ // sessId argument is optional - if not supplied it will
9433
+ // be generated randomly
9434
+ // sessVersion is optional and defaults to 2
9435
+ // sessUser is optional and defaults to 'thisisadapterortc'
9436
+ SDPUtils.writeSessionBoilerplate = function (sessId, sessVer, sessUser) {
9437
+ let sessionId;
9438
+ const version = sessVer !== undefined ? sessVer : 2;
9439
+ if (sessId) {
9440
+ sessionId = sessId;
9441
+ } else {
9442
+ sessionId = SDPUtils.generateSessionId();
9443
+ }
9444
+ const user = sessUser || 'thisisadapterortc';
9445
+ // FIXME: sess-id should be an NTP timestamp.
9446
+ return 'v=0\r\n' + 'o=' + user + ' ' + sessionId + ' ' + version + ' IN IP4 127.0.0.1\r\n' + 's=-\r\n' + 't=0 0\r\n';
9447
+ };
9310
9448
 
9311
- // Gets the direction from the mediaSection or the sessionpart.
9312
- SDPUtils.getDirection = function (mediaSection, sessionpart) {
9313
- // Look for sendrecv, sendonly, recvonly, inactive, default to sendrecv.
9314
- const lines = SDPUtils.splitLines(mediaSection);
9315
- for (let i = 0; i < lines.length; i++) {
9316
- switch (lines[i]) {
9317
- case 'a=sendrecv':
9318
- case 'a=sendonly':
9319
- case 'a=recvonly':
9320
- case 'a=inactive':
9321
- return lines[i].substring(2);
9322
- // FIXME: What should happen here?
9449
+ // Gets the direction from the mediaSection or the sessionpart.
9450
+ SDPUtils.getDirection = function (mediaSection, sessionpart) {
9451
+ // Look for sendrecv, sendonly, recvonly, inactive, default to sendrecv.
9452
+ const lines = SDPUtils.splitLines(mediaSection);
9453
+ for (let i = 0; i < lines.length; i++) {
9454
+ switch (lines[i]) {
9455
+ case 'a=sendrecv':
9456
+ case 'a=sendonly':
9457
+ case 'a=recvonly':
9458
+ case 'a=inactive':
9459
+ return lines[i].substring(2);
9460
+ // FIXME: What should happen here?
9461
+ }
9323
9462
  }
9324
- }
9325
- if (sessionpart) {
9326
- return SDPUtils.getDirection(sessionpart);
9327
- }
9328
- return 'sendrecv';
9329
- };
9330
- SDPUtils.getKind = function (mediaSection) {
9331
- const lines = SDPUtils.splitLines(mediaSection);
9332
- const mline = lines[0].split(' ');
9333
- return mline[0].substring(2);
9334
- };
9335
- SDPUtils.isRejected = function (mediaSection) {
9336
- return mediaSection.split(' ', 2)[1] === '0';
9337
- };
9338
- SDPUtils.parseMLine = function (mediaSection) {
9339
- const lines = SDPUtils.splitLines(mediaSection);
9340
- const parts = lines[0].substring(2).split(' ');
9341
- return {
9342
- kind: parts[0],
9343
- port: parseInt(parts[1], 10),
9344
- protocol: parts[2],
9345
- fmt: parts.slice(3).join(' ')
9463
+ if (sessionpart) {
9464
+ return SDPUtils.getDirection(sessionpart);
9465
+ }
9466
+ return 'sendrecv';
9346
9467
  };
9347
- };
9348
- SDPUtils.parseOLine = function (mediaSection) {
9349
- const line = SDPUtils.matchPrefix(mediaSection, 'o=')[0];
9350
- const parts = line.substring(2).split(' ');
9351
- return {
9352
- username: parts[0],
9353
- sessionId: parts[1],
9354
- sessionVersion: parseInt(parts[2], 10),
9355
- netType: parts[3],
9356
- addressType: parts[4],
9357
- address: parts[5]
9468
+ SDPUtils.getKind = function (mediaSection) {
9469
+ const lines = SDPUtils.splitLines(mediaSection);
9470
+ const mline = lines[0].split(' ');
9471
+ return mline[0].substring(2);
9472
+ };
9473
+ SDPUtils.isRejected = function (mediaSection) {
9474
+ return mediaSection.split(' ', 2)[1] === '0';
9475
+ };
9476
+ SDPUtils.parseMLine = function (mediaSection) {
9477
+ const lines = SDPUtils.splitLines(mediaSection);
9478
+ const parts = lines[0].substring(2).split(' ');
9479
+ return {
9480
+ kind: parts[0],
9481
+ port: parseInt(parts[1], 10),
9482
+ protocol: parts[2],
9483
+ fmt: parts.slice(3).join(' ')
9484
+ };
9485
+ };
9486
+ SDPUtils.parseOLine = function (mediaSection) {
9487
+ const line = SDPUtils.matchPrefix(mediaSection, 'o=')[0];
9488
+ const parts = line.substring(2).split(' ');
9489
+ return {
9490
+ username: parts[0],
9491
+ sessionId: parts[1],
9492
+ sessionVersion: parseInt(parts[2], 10),
9493
+ netType: parts[3],
9494
+ addressType: parts[4],
9495
+ address: parts[5]
9496
+ };
9358
9497
  };
9359
- };
9360
9498
 
9361
- // a very naive interpretation of a valid SDP.
9362
- SDPUtils.isValidSDP = function (blob) {
9363
- if (typeof blob !== 'string' || blob.length === 0) {
9364
- return false;
9365
- }
9366
- const lines = SDPUtils.splitLines(blob);
9367
- for (let i = 0; i < lines.length; i++) {
9368
- if (lines[i].length < 2 || lines[i].charAt(1) !== '=') {
9499
+ // a very naive interpretation of a valid SDP.
9500
+ SDPUtils.isValidSDP = function (blob) {
9501
+ if (typeof blob !== 'string' || blob.length === 0) {
9369
9502
  return false;
9370
9503
  }
9371
- // TODO: check the modifier a bit more.
9504
+ const lines = SDPUtils.splitLines(blob);
9505
+ for (let i = 0; i < lines.length; i++) {
9506
+ if (lines[i].length < 2 || lines[i].charAt(1) !== '=') {
9507
+ return false;
9508
+ }
9509
+ // TODO: check the modifier a bit more.
9510
+ }
9511
+ return true;
9512
+ };
9513
+
9514
+ // Expose public methods.
9515
+ {
9516
+ module.exports = SDPUtils;
9372
9517
  }
9373
- return true;
9374
- };
9518
+ })(sdp$1);
9519
+ return sdp$1.exports;
9520
+ }
9375
9521
 
9376
- // Expose public methods.
9377
- {
9378
- module.exports = SDPUtils;
9379
- }
9380
- })(sdp$1);
9381
- var sdpExports = sdp$1.exports;
9522
+ var sdpExports = requireSdp();
9382
9523
  var SDPUtils = /*@__PURE__*/getDefaultExportFromCjs(sdpExports);
9383
9524
 
9384
9525
  var sdp = /*#__PURE__*/_mergeNamespaces({
@@ -10223,6 +10364,14 @@ class LivekitError extends Error {
10223
10364
  this.code = code;
10224
10365
  }
10225
10366
  }
10367
+ var ConnectionErrorReason;
10368
+ (function (ConnectionErrorReason) {
10369
+ ConnectionErrorReason[ConnectionErrorReason["NotAllowed"] = 0] = "NotAllowed";
10370
+ ConnectionErrorReason[ConnectionErrorReason["ServerUnreachable"] = 1] = "ServerUnreachable";
10371
+ ConnectionErrorReason[ConnectionErrorReason["InternalError"] = 2] = "InternalError";
10372
+ ConnectionErrorReason[ConnectionErrorReason["Cancelled"] = 3] = "Cancelled";
10373
+ ConnectionErrorReason[ConnectionErrorReason["LeaveRequest"] = 4] = "LeaveRequest";
10374
+ })(ConnectionErrorReason || (ConnectionErrorReason = {}));
10226
10375
  class ConnectionError extends LivekitError {
10227
10376
  constructor(message, reason, status) {
10228
10377
  super(1, message);
@@ -10572,7 +10721,7 @@ var RoomEvent;
10572
10721
  */
10573
10722
  RoomEvent["MediaDevicesError"] = "mediaDevicesError";
10574
10723
  /**
10575
- * A participant's permission has changed. Currently only fired on LocalParticipant.
10724
+ * A participant's permission has changed.
10576
10725
  * args: (prevPermissions: [[ParticipantPermission]], participant: [[Participant]])
10577
10726
  */
10578
10727
  RoomEvent["ParticipantPermissionsChanged"] = "participantPermissionsChanged";
@@ -10602,6 +10751,10 @@ var RoomEvent;
10602
10751
  * fired when the first remote participant has subscribed to the localParticipant's track
10603
10752
  */
10604
10753
  RoomEvent["LocalTrackSubscribed"] = "localTrackSubscribed";
10754
+ /**
10755
+ * fired when the client receives connection metrics from other participants
10756
+ */
10757
+ RoomEvent["MetricsReceived"] = "metricsReceived";
10605
10758
  })(RoomEvent || (RoomEvent = {}));
10606
10759
  var ParticipantEvent;
10607
10760
  (function (ParticipantEvent) {
@@ -10753,7 +10906,7 @@ var ParticipantEvent;
10753
10906
  /** @internal */
10754
10907
  ParticipantEvent["AudioStreamAcquired"] = "audioStreamAcquired";
10755
10908
  /**
10756
- * A participant's permission has changed. Currently only fired on LocalParticipant.
10909
+ * A participant's permission has changed.
10757
10910
  * args: (prevPermissions: [[ParticipantPermission]])
10758
10911
  */
10759
10912
  ParticipantEvent["ParticipantPermissionsChanged"] = "participantPermissionsChanged";
@@ -10995,7 +11148,7 @@ function getOSVersion(ua) {
10995
11148
  return ua.includes('mac os') ? getMatch(/\(.+?(\d+_\d+(:?_\d+)?)/, ua, 1).replace(/_/g, '.') : undefined;
10996
11149
  }
10997
11150
 
10998
- var version$1 = "2.5.6";
11151
+ var version$1 = "2.5.8";
10999
11152
 
11000
11153
  const version = version$1;
11001
11154
  const protocolVersion = 15;
@@ -13253,12 +13406,12 @@ class SignalClient {
13253
13406
  const resp = yield fetch("http".concat(url.substring(2), "/validate").concat(params));
13254
13407
  if (resp.status.toFixed(0).startsWith('4')) {
13255
13408
  const msg = yield resp.text();
13256
- reject(new ConnectionError(msg, 0 /* ConnectionErrorReason.NotAllowed */, resp.status));
13409
+ reject(new ConnectionError(msg, ConnectionErrorReason.NotAllowed, resp.status));
13257
13410
  } else {
13258
- reject(new ConnectionError('Internal error', 2 /* ConnectionErrorReason.InternalError */, resp.status));
13411
+ reject(new ConnectionError('Internal error', ConnectionErrorReason.InternalError, resp.status));
13259
13412
  }
13260
13413
  } catch (e) {
13261
- reject(new ConnectionError('server was not reachable', 1 /* ConnectionErrorReason.ServerUnreachable */));
13414
+ reject(new ConnectionError('server was not reachable', ConnectionErrorReason.ServerUnreachable));
13262
13415
  }
13263
13416
  return;
13264
13417
  }
@@ -13309,7 +13462,7 @@ class SignalClient {
13309
13462
  shouldProcessMessage = true;
13310
13463
  }
13311
13464
  } else if (this.isEstablishingConnection && resp.message.case === 'leave') {
13312
- reject(new ConnectionError('Received leave request while trying to (re)connect', 4 /* ConnectionErrorReason.LeaveRequest */));
13465
+ reject(new ConnectionError('Received leave request while trying to (re)connect', ConnectionErrorReason.LeaveRequest));
13313
13466
  } else if (!opts.reconnect) {
13314
13467
  // non-reconnect case, should receive join response first
13315
13468
  reject(new ConnectionError("did not receive join response, got ".concat((_c = resp.message) === null || _c === void 0 ? void 0 : _c.case, " instead")));
@@ -13795,671 +13948,699 @@ function createConnectionParams(token, info, opts) {
13795
13948
  return "?".concat(params.toString());
13796
13949
  }
13797
13950
 
13798
- var parser$1 = {};
13799
-
13800
- var grammar$2 = {exports: {}};
13801
-
13802
- var grammar$1 = grammar$2.exports = {
13803
- v: [{
13804
- name: 'version',
13805
- reg: /^(\d*)$/
13806
- }],
13807
- o: [{
13808
- // o=- 20518 0 IN IP4 203.0.113.1
13809
- // NB: sessionId will be a String in most cases because it is huge
13810
- name: 'origin',
13811
- reg: /^(\S*) (\d*) (\d*) (\S*) IP(\d) (\S*)/,
13812
- names: ['username', 'sessionId', 'sessionVersion', 'netType', 'ipVer', 'address'],
13813
- format: '%s %s %d %s IP%d %s'
13814
- }],
13815
- // default parsing of these only (though some of these feel outdated)
13816
- s: [{
13817
- name: 'name'
13818
- }],
13819
- i: [{
13820
- name: 'description'
13821
- }],
13822
- u: [{
13823
- name: 'uri'
13824
- }],
13825
- e: [{
13826
- name: 'email'
13827
- }],
13828
- p: [{
13829
- name: 'phone'
13830
- }],
13831
- z: [{
13832
- name: 'timezones'
13833
- }],
13834
- // TODO: this one can actually be parsed properly...
13835
- r: [{
13836
- name: 'repeats'
13837
- }],
13838
- // TODO: this one can also be parsed properly
13839
- // k: [{}], // outdated thing ignored
13840
- t: [{
13841
- // t=0 0
13842
- name: 'timing',
13843
- reg: /^(\d*) (\d*)/,
13844
- names: ['start', 'stop'],
13845
- format: '%d %d'
13846
- }],
13847
- c: [{
13848
- // c=IN IP4 10.47.197.26
13849
- name: 'connection',
13850
- reg: /^IN IP(\d) (\S*)/,
13851
- names: ['version', 'ip'],
13852
- format: 'IN IP%d %s'
13853
- }],
13854
- b: [{
13855
- // b=AS:4000
13856
- push: 'bandwidth',
13857
- reg: /^(TIAS|AS|CT|RR|RS):(\d*)/,
13858
- names: ['type', 'limit'],
13859
- format: '%s:%s'
13860
- }],
13861
- m: [{
13862
- // m=video 51744 RTP/AVP 126 97 98 34 31
13863
- // NB: special - pushes to session
13864
- // TODO: rtp/fmtp should be filtered by the payloads found here?
13865
- reg: /^(\w*) (\d*) ([\w/]*)(?: (.*))?/,
13866
- names: ['type', 'port', 'protocol', 'payloads'],
13867
- format: '%s %d %s %s'
13868
- }],
13869
- a: [{
13870
- // a=rtpmap:110 opus/48000/2
13871
- push: 'rtp',
13872
- reg: /^rtpmap:(\d*) ([\w\-.]*)(?:\s*\/(\d*)(?:\s*\/(\S*))?)?/,
13873
- names: ['payload', 'codec', 'rate', 'encoding'],
13874
- format: function (o) {
13875
- return o.encoding ? 'rtpmap:%d %s/%s/%s' : o.rate ? 'rtpmap:%d %s/%s' : 'rtpmap:%d %s';
13876
- }
13877
- }, {
13878
- // a=fmtp:108 profile-level-id=24;object=23;bitrate=64000
13879
- // a=fmtp:111 minptime=10; useinbandfec=1
13880
- push: 'fmtp',
13881
- reg: /^fmtp:(\d*) ([\S| ]*)/,
13882
- names: ['payload', 'config'],
13883
- format: 'fmtp:%d %s'
13884
- }, {
13885
- // a=control:streamid=0
13886
- name: 'control',
13887
- reg: /^control:(.*)/,
13888
- format: 'control:%s'
13889
- }, {
13890
- // a=rtcp:65179 IN IP4 193.84.77.194
13891
- name: 'rtcp',
13892
- reg: /^rtcp:(\d*)(?: (\S*) IP(\d) (\S*))?/,
13893
- names: ['port', 'netType', 'ipVer', 'address'],
13894
- format: function (o) {
13895
- return o.address != null ? 'rtcp:%d %s IP%d %s' : 'rtcp:%d';
13896
- }
13897
- }, {
13898
- // a=rtcp-fb:98 trr-int 100
13899
- push: 'rtcpFbTrrInt',
13900
- reg: /^rtcp-fb:(\*|\d*) trr-int (\d*)/,
13901
- names: ['payload', 'value'],
13902
- format: 'rtcp-fb:%s trr-int %d'
13903
- }, {
13904
- // a=rtcp-fb:98 nack rpsi
13905
- push: 'rtcpFb',
13906
- reg: /^rtcp-fb:(\*|\d*) ([\w-_]*)(?: ([\w-_]*))?/,
13907
- names: ['payload', 'type', 'subtype'],
13908
- format: function (o) {
13909
- return o.subtype != null ? 'rtcp-fb:%s %s %s' : 'rtcp-fb:%s %s';
13910
- }
13911
- }, {
13912
- // a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
13913
- // a=extmap:1/recvonly URI-gps-string
13914
- // a=extmap:3 urn:ietf:params:rtp-hdrext:encrypt urn:ietf:params:rtp-hdrext:smpte-tc 25@600/24
13915
- push: 'ext',
13916
- reg: /^extmap:(\d+)(?:\/(\w+))?(?: (urn:ietf:params:rtp-hdrext:encrypt))? (\S*)(?: (\S*))?/,
13917
- names: ['value', 'direction', 'encrypt-uri', 'uri', 'config'],
13918
- format: function (o) {
13919
- return 'extmap:%d' + (o.direction ? '/%s' : '%v') + (o['encrypt-uri'] ? ' %s' : '%v') + ' %s' + (o.config ? ' %s' : '');
13920
- }
13921
- }, {
13922
- // a=extmap-allow-mixed
13923
- name: 'extmapAllowMixed',
13924
- reg: /^(extmap-allow-mixed)/
13925
- }, {
13926
- // a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR|2^20|1:32
13927
- push: 'crypto',
13928
- reg: /^crypto:(\d*) ([\w_]*) (\S*)(?: (\S*))?/,
13929
- names: ['id', 'suite', 'config', 'sessionConfig'],
13930
- format: function (o) {
13931
- return o.sessionConfig != null ? 'crypto:%d %s %s %s' : 'crypto:%d %s %s';
13932
- }
13933
- }, {
13934
- // a=setup:actpass
13935
- name: 'setup',
13936
- reg: /^setup:(\w*)/,
13937
- format: 'setup:%s'
13938
- }, {
13939
- // a=connection:new
13940
- name: 'connectionType',
13941
- reg: /^connection:(new|existing)/,
13942
- format: 'connection:%s'
13943
- }, {
13944
- // a=mid:1
13945
- name: 'mid',
13946
- reg: /^mid:([^\s]*)/,
13947
- format: 'mid:%s'
13948
- }, {
13949
- // a=msid:0c8b064d-d807-43b4-b434-f92a889d8587 98178685-d409-46e0-8e16-7ef0db0db64a
13950
- name: 'msid',
13951
- reg: /^msid:(.*)/,
13952
- format: 'msid:%s'
13953
- }, {
13954
- // a=ptime:20
13955
- name: 'ptime',
13956
- reg: /^ptime:(\d*(?:\.\d*)*)/,
13957
- format: 'ptime:%d'
13958
- }, {
13959
- // a=maxptime:60
13960
- name: 'maxptime',
13961
- reg: /^maxptime:(\d*(?:\.\d*)*)/,
13962
- format: 'maxptime:%d'
13963
- }, {
13964
- // a=sendrecv
13965
- name: 'direction',
13966
- reg: /^(sendrecv|recvonly|sendonly|inactive)/
13967
- }, {
13968
- // a=ice-lite
13969
- name: 'icelite',
13970
- reg: /^(ice-lite)/
13971
- }, {
13972
- // a=ice-ufrag:F7gI
13973
- name: 'iceUfrag',
13974
- reg: /^ice-ufrag:(\S*)/,
13975
- format: 'ice-ufrag:%s'
13976
- }, {
13977
- // a=ice-pwd:x9cml/YzichV2+XlhiMu8g
13978
- name: 'icePwd',
13979
- reg: /^ice-pwd:(\S*)/,
13980
- format: 'ice-pwd:%s'
13981
- }, {
13982
- // a=fingerprint:SHA-1 00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33
13983
- name: 'fingerprint',
13984
- reg: /^fingerprint:(\S*) (\S*)/,
13985
- names: ['type', 'hash'],
13986
- format: 'fingerprint:%s %s'
13987
- }, {
13988
- // a=candidate:0 1 UDP 2113667327 203.0.113.1 54400 typ host
13989
- // a=candidate:1162875081 1 udp 2113937151 192.168.34.75 60017 typ host generation 0 network-id 3 network-cost 10
13990
- // a=candidate:3289912957 2 udp 1845501695 193.84.77.194 60017 typ srflx raddr 192.168.34.75 rport 60017 generation 0 network-id 3 network-cost 10
13991
- // a=candidate:229815620 1 tcp 1518280447 192.168.150.19 60017 typ host tcptype active generation 0 network-id 3 network-cost 10
13992
- // a=candidate:3289912957 2 tcp 1845501695 193.84.77.194 60017 typ srflx raddr 192.168.34.75 rport 60017 tcptype passive generation 0 network-id 3 network-cost 10
13993
- push: 'candidates',
13994
- reg: /^candidate:(\S*) (\d*) (\S*) (\d*) (\S*) (\d*) typ (\S*)(?: raddr (\S*) rport (\d*))?(?: tcptype (\S*))?(?: generation (\d*))?(?: network-id (\d*))?(?: network-cost (\d*))?/,
13995
- names: ['foundation', 'component', 'transport', 'priority', 'ip', 'port', 'type', 'raddr', 'rport', 'tcptype', 'generation', 'network-id', 'network-cost'],
13996
- format: function (o) {
13997
- var str = 'candidate:%s %d %s %d %s %d typ %s';
13998
- str += o.raddr != null ? ' raddr %s rport %d' : '%v%v';
13999
-
14000
- // NB: candidate has three optional chunks, so %void middles one if it's missing
14001
- str += o.tcptype != null ? ' tcptype %s' : '%v';
14002
- if (o.generation != null) {
14003
- str += ' generation %d';
14004
- }
14005
- str += o['network-id'] != null ? ' network-id %d' : '%v';
14006
- str += o['network-cost'] != null ? ' network-cost %d' : '%v';
14007
- return str;
14008
- }
14009
- }, {
14010
- // a=end-of-candidates (keep after the candidates line for readability)
14011
- name: 'endOfCandidates',
14012
- reg: /^(end-of-candidates)/
14013
- }, {
14014
- // a=remote-candidates:1 203.0.113.1 54400 2 203.0.113.1 54401 ...
14015
- name: 'remoteCandidates',
14016
- reg: /^remote-candidates:(.*)/,
14017
- format: 'remote-candidates:%s'
14018
- }, {
14019
- // a=ice-options:google-ice
14020
- name: 'iceOptions',
14021
- reg: /^ice-options:(\S*)/,
14022
- format: 'ice-options:%s'
14023
- }, {
14024
- // a=ssrc:2566107569 cname:t9YU8M1UxTF8Y1A1
14025
- push: 'ssrcs',
14026
- reg: /^ssrc:(\d*) ([\w_-]*)(?::(.*))?/,
14027
- names: ['id', 'attribute', 'value'],
14028
- format: function (o) {
14029
- var str = 'ssrc:%d';
14030
- if (o.attribute != null) {
14031
- str += ' %s';
14032
- if (o.value != null) {
14033
- str += ':%s';
14034
- }
14035
- }
14036
- return str;
14037
- }
14038
- }, {
14039
- // a=ssrc-group:FEC 1 2
14040
- // a=ssrc-group:FEC-FR 3004364195 1080772241
14041
- push: 'ssrcGroups',
14042
- // token-char = %x21 / %x23-27 / %x2A-2B / %x2D-2E / %x30-39 / %x41-5A / %x5E-7E
14043
- reg: /^ssrc-group:([\x21\x23\x24\x25\x26\x27\x2A\x2B\x2D\x2E\w]*) (.*)/,
14044
- names: ['semantics', 'ssrcs'],
14045
- format: 'ssrc-group:%s %s'
14046
- }, {
14047
- // a=msid-semantic: WMS Jvlam5X3SX1OP6pn20zWogvaKJz5Hjf9OnlV
14048
- name: 'msidSemantic',
14049
- reg: /^msid-semantic:\s?(\w*) (\S*)/,
14050
- names: ['semantic', 'token'],
14051
- format: 'msid-semantic: %s %s' // space after ':' is not accidental
14052
- }, {
14053
- // a=group:BUNDLE audio video
14054
- push: 'groups',
14055
- reg: /^group:(\w*) (.*)/,
14056
- names: ['type', 'mids'],
14057
- format: 'group:%s %s'
14058
- }, {
14059
- // a=rtcp-mux
14060
- name: 'rtcpMux',
14061
- reg: /^(rtcp-mux)/
14062
- }, {
14063
- // a=rtcp-rsize
14064
- name: 'rtcpRsize',
14065
- reg: /^(rtcp-rsize)/
14066
- }, {
14067
- // a=sctpmap:5000 webrtc-datachannel 1024
14068
- name: 'sctpmap',
14069
- reg: /^sctpmap:([\w_/]*) (\S*)(?: (\S*))?/,
14070
- names: ['sctpmapNumber', 'app', 'maxMessageSize'],
14071
- format: function (o) {
14072
- return o.maxMessageSize != null ? 'sctpmap:%s %s %s' : 'sctpmap:%s %s';
14073
- }
14074
- }, {
14075
- // a=x-google-flag:conference
14076
- name: 'xGoogleFlag',
14077
- reg: /^x-google-flag:([^\s]*)/,
14078
- format: 'x-google-flag:%s'
14079
- }, {
14080
- // a=rid:1 send max-width=1280;max-height=720;max-fps=30;depend=0
14081
- push: 'rids',
14082
- reg: /^rid:([\d\w]+) (\w+)(?: ([\S| ]*))?/,
14083
- names: ['id', 'direction', 'params'],
14084
- format: function (o) {
14085
- return o.params ? 'rid:%s %s %s' : 'rid:%s %s';
14086
- }
14087
- }, {
14088
- // a=imageattr:97 send [x=800,y=640,sar=1.1,q=0.6] [x=480,y=320] recv [x=330,y=250]
14089
- // a=imageattr:* send [x=800,y=640] recv *
14090
- // a=imageattr:100 recv [x=320,y=240]
14091
- push: 'imageattrs',
14092
- reg: new RegExp(
14093
- // a=imageattr:97
14094
- '^imageattr:(\\d+|\\*)' +
14095
- // send [x=800,y=640,sar=1.1,q=0.6] [x=480,y=320]
14096
- '[\\s\\t]+(send|recv)[\\s\\t]+(\\*|\\[\\S+\\](?:[\\s\\t]+\\[\\S+\\])*)' +
14097
- // recv [x=330,y=250]
14098
- '(?:[\\s\\t]+(recv|send)[\\s\\t]+(\\*|\\[\\S+\\](?:[\\s\\t]+\\[\\S+\\])*))?'),
14099
- names: ['pt', 'dir1', 'attrs1', 'dir2', 'attrs2'],
14100
- format: function (o) {
14101
- return 'imageattr:%s %s %s' + (o.dir2 ? ' %s %s' : '');
14102
- }
14103
- }, {
14104
- // a=simulcast:send 1,2,3;~4,~5 recv 6;~7,~8
14105
- // a=simulcast:recv 1;4,5 send 6;7
14106
- name: 'simulcast',
14107
- reg: new RegExp(
14108
- // a=simulcast:
14109
- '^simulcast:' +
14110
- // send 1,2,3;~4,~5
14111
- '(send|recv) ([a-zA-Z0-9\\-_~;,]+)' +
14112
- // space + recv 6;~7,~8
14113
- '(?:\\s?(send|recv) ([a-zA-Z0-9\\-_~;,]+))?' +
14114
- // end
14115
- '$'),
14116
- names: ['dir1', 'list1', 'dir2', 'list2'],
14117
- format: function (o) {
14118
- return 'simulcast:%s %s' + (o.dir2 ? ' %s %s' : '');
14119
- }
14120
- }, {
14121
- // old simulcast draft 03 (implemented by Firefox)
14122
- // https://tools.ietf.org/html/draft-ietf-mmusic-sdp-simulcast-03
14123
- // a=simulcast: recv pt=97;98 send pt=97
14124
- // a=simulcast: send rid=5;6;7 paused=6,7
14125
- name: 'simulcast_03',
14126
- reg: /^simulcast:[\s\t]+([\S+\s\t]+)$/,
14127
- names: ['value'],
14128
- format: 'simulcast: %s'
14129
- }, {
14130
- // a=framerate:25
14131
- // a=framerate:29.97
14132
- name: 'framerate',
14133
- reg: /^framerate:(\d+(?:$|\.\d+))/,
14134
- format: 'framerate:%s'
14135
- }, {
14136
- // RFC4570
14137
- // a=source-filter: incl IN IP4 239.5.2.31 10.1.15.5
14138
- name: 'sourceFilter',
14139
- reg: /^source-filter: *(excl|incl) (\S*) (IP4|IP6|\*) (\S*) (.*)/,
14140
- names: ['filterMode', 'netType', 'addressTypes', 'destAddress', 'srcList'],
14141
- format: 'source-filter: %s %s %s %s %s'
14142
- }, {
14143
- // a=bundle-only
14144
- name: 'bundleOnly',
14145
- reg: /^(bundle-only)/
14146
- }, {
14147
- // a=label:1
14148
- name: 'label',
14149
- reg: /^label:(.+)/,
14150
- format: 'label:%s'
14151
- }, {
14152
- // RFC version 26 for SCTP over DTLS
14153
- // https://tools.ietf.org/html/draft-ietf-mmusic-sctp-sdp-26#section-5
14154
- name: 'sctpPort',
14155
- reg: /^sctp-port:(\d+)$/,
14156
- format: 'sctp-port:%s'
14157
- }, {
14158
- // RFC version 26 for SCTP over DTLS
14159
- // https://tools.ietf.org/html/draft-ietf-mmusic-sctp-sdp-26#section-6
14160
- name: 'maxMessageSize',
14161
- reg: /^max-message-size:(\d+)$/,
14162
- format: 'max-message-size:%s'
14163
- }, {
14164
- // RFC7273
14165
- // a=ts-refclk:ptp=IEEE1588-2008:39-A7-94-FF-FE-07-CB-D0:37
14166
- push: 'tsRefClocks',
14167
- reg: /^ts-refclk:([^\s=]*)(?:=(\S*))?/,
14168
- names: ['clksrc', 'clksrcExt'],
14169
- format: function (o) {
14170
- return 'ts-refclk:%s' + (o.clksrcExt != null ? '=%s' : '');
14171
- }
14172
- }, {
14173
- // RFC7273
14174
- // a=mediaclk:direct=963214424
14175
- name: 'mediaClk',
14176
- reg: /^mediaclk:(?:id=(\S*))? *([^\s=]*)(?:=(\S*))?(?: *rate=(\d+)\/(\d+))?/,
14177
- names: ['id', 'mediaClockName', 'mediaClockValue', 'rateNumerator', 'rateDenominator'],
14178
- format: function (o) {
14179
- var str = 'mediaclk:';
14180
- str += o.id != null ? 'id=%s %s' : '%v%s';
14181
- str += o.mediaClockValue != null ? '=%s' : '';
14182
- str += o.rateNumerator != null ? ' rate=%s' : '';
14183
- str += o.rateDenominator != null ? '/%s' : '';
14184
- return str;
14185
- }
14186
- }, {
14187
- // a=keywds:keywords
14188
- name: 'keywords',
14189
- reg: /^keywds:(.+)$/,
14190
- format: 'keywds:%s'
14191
- }, {
14192
- // a=content:main
14193
- name: 'content',
14194
- reg: /^content:(.+)/,
14195
- format: 'content:%s'
14196
- },
14197
- // BFCP https://tools.ietf.org/html/rfc4583
14198
- {
14199
- // a=floorctrl:c-s
14200
- name: 'bfcpFloorCtrl',
14201
- reg: /^floorctrl:(c-only|s-only|c-s)/,
14202
- format: 'floorctrl:%s'
14203
- }, {
14204
- // a=confid:1
14205
- name: 'bfcpConfId',
14206
- reg: /^confid:(\d+)/,
14207
- format: 'confid:%s'
14208
- }, {
14209
- // a=userid:1
14210
- name: 'bfcpUserId',
14211
- reg: /^userid:(\d+)/,
14212
- format: 'userid:%s'
14213
- }, {
14214
- // a=floorid:1
14215
- name: 'bfcpFloorId',
14216
- reg: /^floorid:(.+) (?:m-stream|mstrm):(.+)/,
14217
- names: ['id', 'mStream'],
14218
- format: 'floorid:%s mstrm:%s'
14219
- }, {
14220
- // any a= that we don't understand is kept verbatim on media.invalid
14221
- push: 'invalid',
14222
- names: ['value']
14223
- }]
14224
- };
13951
+ var lib = {};
13952
+
13953
+ var parser = {};
13954
+
13955
+ var grammar = {exports: {}};
13956
+
13957
+ var hasRequiredGrammar;
13958
+ function requireGrammar() {
13959
+ if (hasRequiredGrammar) return grammar.exports;
13960
+ hasRequiredGrammar = 1;
13961
+ var grammar$1 = grammar.exports = {
13962
+ v: [{
13963
+ name: 'version',
13964
+ reg: /^(\d*)$/
13965
+ }],
13966
+ o: [{
13967
+ // o=- 20518 0 IN IP4 203.0.113.1
13968
+ // NB: sessionId will be a String in most cases because it is huge
13969
+ name: 'origin',
13970
+ reg: /^(\S*) (\d*) (\d*) (\S*) IP(\d) (\S*)/,
13971
+ names: ['username', 'sessionId', 'sessionVersion', 'netType', 'ipVer', 'address'],
13972
+ format: '%s %s %d %s IP%d %s'
13973
+ }],
13974
+ // default parsing of these only (though some of these feel outdated)
13975
+ s: [{
13976
+ name: 'name'
13977
+ }],
13978
+ i: [{
13979
+ name: 'description'
13980
+ }],
13981
+ u: [{
13982
+ name: 'uri'
13983
+ }],
13984
+ e: [{
13985
+ name: 'email'
13986
+ }],
13987
+ p: [{
13988
+ name: 'phone'
13989
+ }],
13990
+ z: [{
13991
+ name: 'timezones'
13992
+ }],
13993
+ // TODO: this one can actually be parsed properly...
13994
+ r: [{
13995
+ name: 'repeats'
13996
+ }],
13997
+ // TODO: this one can also be parsed properly
13998
+ // k: [{}], // outdated thing ignored
13999
+ t: [{
14000
+ // t=0 0
14001
+ name: 'timing',
14002
+ reg: /^(\d*) (\d*)/,
14003
+ names: ['start', 'stop'],
14004
+ format: '%d %d'
14005
+ }],
14006
+ c: [{
14007
+ // c=IN IP4 10.47.197.26
14008
+ name: 'connection',
14009
+ reg: /^IN IP(\d) (\S*)/,
14010
+ names: ['version', 'ip'],
14011
+ format: 'IN IP%d %s'
14012
+ }],
14013
+ b: [{
14014
+ // b=AS:4000
14015
+ push: 'bandwidth',
14016
+ reg: /^(TIAS|AS|CT|RR|RS):(\d*)/,
14017
+ names: ['type', 'limit'],
14018
+ format: '%s:%s'
14019
+ }],
14020
+ m: [{
14021
+ // m=video 51744 RTP/AVP 126 97 98 34 31
14022
+ // NB: special - pushes to session
14023
+ // TODO: rtp/fmtp should be filtered by the payloads found here?
14024
+ reg: /^(\w*) (\d*) ([\w/]*)(?: (.*))?/,
14025
+ names: ['type', 'port', 'protocol', 'payloads'],
14026
+ format: '%s %d %s %s'
14027
+ }],
14028
+ a: [{
14029
+ // a=rtpmap:110 opus/48000/2
14030
+ push: 'rtp',
14031
+ reg: /^rtpmap:(\d*) ([\w\-.]*)(?:\s*\/(\d*)(?:\s*\/(\S*))?)?/,
14032
+ names: ['payload', 'codec', 'rate', 'encoding'],
14033
+ format: function (o) {
14034
+ return o.encoding ? 'rtpmap:%d %s/%s/%s' : o.rate ? 'rtpmap:%d %s/%s' : 'rtpmap:%d %s';
14035
+ }
14036
+ }, {
14037
+ // a=fmtp:108 profile-level-id=24;object=23;bitrate=64000
14038
+ // a=fmtp:111 minptime=10; useinbandfec=1
14039
+ push: 'fmtp',
14040
+ reg: /^fmtp:(\d*) ([\S| ]*)/,
14041
+ names: ['payload', 'config'],
14042
+ format: 'fmtp:%d %s'
14043
+ }, {
14044
+ // a=control:streamid=0
14045
+ name: 'control',
14046
+ reg: /^control:(.*)/,
14047
+ format: 'control:%s'
14048
+ }, {
14049
+ // a=rtcp:65179 IN IP4 193.84.77.194
14050
+ name: 'rtcp',
14051
+ reg: /^rtcp:(\d*)(?: (\S*) IP(\d) (\S*))?/,
14052
+ names: ['port', 'netType', 'ipVer', 'address'],
14053
+ format: function (o) {
14054
+ return o.address != null ? 'rtcp:%d %s IP%d %s' : 'rtcp:%d';
14055
+ }
14056
+ }, {
14057
+ // a=rtcp-fb:98 trr-int 100
14058
+ push: 'rtcpFbTrrInt',
14059
+ reg: /^rtcp-fb:(\*|\d*) trr-int (\d*)/,
14060
+ names: ['payload', 'value'],
14061
+ format: 'rtcp-fb:%s trr-int %d'
14062
+ }, {
14063
+ // a=rtcp-fb:98 nack rpsi
14064
+ push: 'rtcpFb',
14065
+ reg: /^rtcp-fb:(\*|\d*) ([\w-_]*)(?: ([\w-_]*))?/,
14066
+ names: ['payload', 'type', 'subtype'],
14067
+ format: function (o) {
14068
+ return o.subtype != null ? 'rtcp-fb:%s %s %s' : 'rtcp-fb:%s %s';
14069
+ }
14070
+ }, {
14071
+ // a=extmap:2 urn:ietf:params:rtp-hdrext:toffset
14072
+ // a=extmap:1/recvonly URI-gps-string
14073
+ // a=extmap:3 urn:ietf:params:rtp-hdrext:encrypt urn:ietf:params:rtp-hdrext:smpte-tc 25@600/24
14074
+ push: 'ext',
14075
+ reg: /^extmap:(\d+)(?:\/(\w+))?(?: (urn:ietf:params:rtp-hdrext:encrypt))? (\S*)(?: (\S*))?/,
14076
+ names: ['value', 'direction', 'encrypt-uri', 'uri', 'config'],
14077
+ format: function (o) {
14078
+ return 'extmap:%d' + (o.direction ? '/%s' : '%v') + (o['encrypt-uri'] ? ' %s' : '%v') + ' %s' + (o.config ? ' %s' : '');
14079
+ }
14080
+ }, {
14081
+ // a=extmap-allow-mixed
14082
+ name: 'extmapAllowMixed',
14083
+ reg: /^(extmap-allow-mixed)/
14084
+ }, {
14085
+ // a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:PS1uQCVeeCFCanVmcjkpPywjNWhcYD0mXXtxaVBR|2^20|1:32
14086
+ push: 'crypto',
14087
+ reg: /^crypto:(\d*) ([\w_]*) (\S*)(?: (\S*))?/,
14088
+ names: ['id', 'suite', 'config', 'sessionConfig'],
14089
+ format: function (o) {
14090
+ return o.sessionConfig != null ? 'crypto:%d %s %s %s' : 'crypto:%d %s %s';
14091
+ }
14092
+ }, {
14093
+ // a=setup:actpass
14094
+ name: 'setup',
14095
+ reg: /^setup:(\w*)/,
14096
+ format: 'setup:%s'
14097
+ }, {
14098
+ // a=connection:new
14099
+ name: 'connectionType',
14100
+ reg: /^connection:(new|existing)/,
14101
+ format: 'connection:%s'
14102
+ }, {
14103
+ // a=mid:1
14104
+ name: 'mid',
14105
+ reg: /^mid:([^\s]*)/,
14106
+ format: 'mid:%s'
14107
+ }, {
14108
+ // a=msid:0c8b064d-d807-43b4-b434-f92a889d8587 98178685-d409-46e0-8e16-7ef0db0db64a
14109
+ name: 'msid',
14110
+ reg: /^msid:(.*)/,
14111
+ format: 'msid:%s'
14112
+ }, {
14113
+ // a=ptime:20
14114
+ name: 'ptime',
14115
+ reg: /^ptime:(\d*(?:\.\d*)*)/,
14116
+ format: 'ptime:%d'
14117
+ }, {
14118
+ // a=maxptime:60
14119
+ name: 'maxptime',
14120
+ reg: /^maxptime:(\d*(?:\.\d*)*)/,
14121
+ format: 'maxptime:%d'
14122
+ }, {
14123
+ // a=sendrecv
14124
+ name: 'direction',
14125
+ reg: /^(sendrecv|recvonly|sendonly|inactive)/
14126
+ }, {
14127
+ // a=ice-lite
14128
+ name: 'icelite',
14129
+ reg: /^(ice-lite)/
14130
+ }, {
14131
+ // a=ice-ufrag:F7gI
14132
+ name: 'iceUfrag',
14133
+ reg: /^ice-ufrag:(\S*)/,
14134
+ format: 'ice-ufrag:%s'
14135
+ }, {
14136
+ // a=ice-pwd:x9cml/YzichV2+XlhiMu8g
14137
+ name: 'icePwd',
14138
+ reg: /^ice-pwd:(\S*)/,
14139
+ format: 'ice-pwd:%s'
14140
+ }, {
14141
+ // a=fingerprint:SHA-1 00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33
14142
+ name: 'fingerprint',
14143
+ reg: /^fingerprint:(\S*) (\S*)/,
14144
+ names: ['type', 'hash'],
14145
+ format: 'fingerprint:%s %s'
14146
+ }, {
14147
+ // a=candidate:0 1 UDP 2113667327 203.0.113.1 54400 typ host
14148
+ // a=candidate:1162875081 1 udp 2113937151 192.168.34.75 60017 typ host generation 0 network-id 3 network-cost 10
14149
+ // a=candidate:3289912957 2 udp 1845501695 193.84.77.194 60017 typ srflx raddr 192.168.34.75 rport 60017 generation 0 network-id 3 network-cost 10
14150
+ // a=candidate:229815620 1 tcp 1518280447 192.168.150.19 60017 typ host tcptype active generation 0 network-id 3 network-cost 10
14151
+ // a=candidate:3289912957 2 tcp 1845501695 193.84.77.194 60017 typ srflx raddr 192.168.34.75 rport 60017 tcptype passive generation 0 network-id 3 network-cost 10
14152
+ push: 'candidates',
14153
+ reg: /^candidate:(\S*) (\d*) (\S*) (\d*) (\S*) (\d*) typ (\S*)(?: raddr (\S*) rport (\d*))?(?: tcptype (\S*))?(?: generation (\d*))?(?: network-id (\d*))?(?: network-cost (\d*))?/,
14154
+ names: ['foundation', 'component', 'transport', 'priority', 'ip', 'port', 'type', 'raddr', 'rport', 'tcptype', 'generation', 'network-id', 'network-cost'],
14155
+ format: function (o) {
14156
+ var str = 'candidate:%s %d %s %d %s %d typ %s';
14157
+ str += o.raddr != null ? ' raddr %s rport %d' : '%v%v';
14158
+
14159
+ // NB: candidate has three optional chunks, so %void middles one if it's missing
14160
+ str += o.tcptype != null ? ' tcptype %s' : '%v';
14161
+ if (o.generation != null) {
14162
+ str += ' generation %d';
14163
+ }
14164
+ str += o['network-id'] != null ? ' network-id %d' : '%v';
14165
+ str += o['network-cost'] != null ? ' network-cost %d' : '%v';
14166
+ return str;
14167
+ }
14168
+ }, {
14169
+ // a=end-of-candidates (keep after the candidates line for readability)
14170
+ name: 'endOfCandidates',
14171
+ reg: /^(end-of-candidates)/
14172
+ }, {
14173
+ // a=remote-candidates:1 203.0.113.1 54400 2 203.0.113.1 54401 ...
14174
+ name: 'remoteCandidates',
14175
+ reg: /^remote-candidates:(.*)/,
14176
+ format: 'remote-candidates:%s'
14177
+ }, {
14178
+ // a=ice-options:google-ice
14179
+ name: 'iceOptions',
14180
+ reg: /^ice-options:(\S*)/,
14181
+ format: 'ice-options:%s'
14182
+ }, {
14183
+ // a=ssrc:2566107569 cname:t9YU8M1UxTF8Y1A1
14184
+ push: 'ssrcs',
14185
+ reg: /^ssrc:(\d*) ([\w_-]*)(?::(.*))?/,
14186
+ names: ['id', 'attribute', 'value'],
14187
+ format: function (o) {
14188
+ var str = 'ssrc:%d';
14189
+ if (o.attribute != null) {
14190
+ str += ' %s';
14191
+ if (o.value != null) {
14192
+ str += ':%s';
14193
+ }
14194
+ }
14195
+ return str;
14196
+ }
14197
+ }, {
14198
+ // a=ssrc-group:FEC 1 2
14199
+ // a=ssrc-group:FEC-FR 3004364195 1080772241
14200
+ push: 'ssrcGroups',
14201
+ // token-char = %x21 / %x23-27 / %x2A-2B / %x2D-2E / %x30-39 / %x41-5A / %x5E-7E
14202
+ reg: /^ssrc-group:([\x21\x23\x24\x25\x26\x27\x2A\x2B\x2D\x2E\w]*) (.*)/,
14203
+ names: ['semantics', 'ssrcs'],
14204
+ format: 'ssrc-group:%s %s'
14205
+ }, {
14206
+ // a=msid-semantic: WMS Jvlam5X3SX1OP6pn20zWogvaKJz5Hjf9OnlV
14207
+ name: 'msidSemantic',
14208
+ reg: /^msid-semantic:\s?(\w*) (\S*)/,
14209
+ names: ['semantic', 'token'],
14210
+ format: 'msid-semantic: %s %s' // space after ':' is not accidental
14211
+ }, {
14212
+ // a=group:BUNDLE audio video
14213
+ push: 'groups',
14214
+ reg: /^group:(\w*) (.*)/,
14215
+ names: ['type', 'mids'],
14216
+ format: 'group:%s %s'
14217
+ }, {
14218
+ // a=rtcp-mux
14219
+ name: 'rtcpMux',
14220
+ reg: /^(rtcp-mux)/
14221
+ }, {
14222
+ // a=rtcp-rsize
14223
+ name: 'rtcpRsize',
14224
+ reg: /^(rtcp-rsize)/
14225
+ }, {
14226
+ // a=sctpmap:5000 webrtc-datachannel 1024
14227
+ name: 'sctpmap',
14228
+ reg: /^sctpmap:([\w_/]*) (\S*)(?: (\S*))?/,
14229
+ names: ['sctpmapNumber', 'app', 'maxMessageSize'],
14230
+ format: function (o) {
14231
+ return o.maxMessageSize != null ? 'sctpmap:%s %s %s' : 'sctpmap:%s %s';
14232
+ }
14233
+ }, {
14234
+ // a=x-google-flag:conference
14235
+ name: 'xGoogleFlag',
14236
+ reg: /^x-google-flag:([^\s]*)/,
14237
+ format: 'x-google-flag:%s'
14238
+ }, {
14239
+ // a=rid:1 send max-width=1280;max-height=720;max-fps=30;depend=0
14240
+ push: 'rids',
14241
+ reg: /^rid:([\d\w]+) (\w+)(?: ([\S| ]*))?/,
14242
+ names: ['id', 'direction', 'params'],
14243
+ format: function (o) {
14244
+ return o.params ? 'rid:%s %s %s' : 'rid:%s %s';
14245
+ }
14246
+ }, {
14247
+ // a=imageattr:97 send [x=800,y=640,sar=1.1,q=0.6] [x=480,y=320] recv [x=330,y=250]
14248
+ // a=imageattr:* send [x=800,y=640] recv *
14249
+ // a=imageattr:100 recv [x=320,y=240]
14250
+ push: 'imageattrs',
14251
+ reg: new RegExp(
14252
+ // a=imageattr:97
14253
+ '^imageattr:(\\d+|\\*)' +
14254
+ // send [x=800,y=640,sar=1.1,q=0.6] [x=480,y=320]
14255
+ '[\\s\\t]+(send|recv)[\\s\\t]+(\\*|\\[\\S+\\](?:[\\s\\t]+\\[\\S+\\])*)' +
14256
+ // recv [x=330,y=250]
14257
+ '(?:[\\s\\t]+(recv|send)[\\s\\t]+(\\*|\\[\\S+\\](?:[\\s\\t]+\\[\\S+\\])*))?'),
14258
+ names: ['pt', 'dir1', 'attrs1', 'dir2', 'attrs2'],
14259
+ format: function (o) {
14260
+ return 'imageattr:%s %s %s' + (o.dir2 ? ' %s %s' : '');
14261
+ }
14262
+ }, {
14263
+ // a=simulcast:send 1,2,3;~4,~5 recv 6;~7,~8
14264
+ // a=simulcast:recv 1;4,5 send 6;7
14265
+ name: 'simulcast',
14266
+ reg: new RegExp(
14267
+ // a=simulcast:
14268
+ '^simulcast:' +
14269
+ // send 1,2,3;~4,~5
14270
+ '(send|recv) ([a-zA-Z0-9\\-_~;,]+)' +
14271
+ // space + recv 6;~7,~8
14272
+ '(?:\\s?(send|recv) ([a-zA-Z0-9\\-_~;,]+))?' +
14273
+ // end
14274
+ '$'),
14275
+ names: ['dir1', 'list1', 'dir2', 'list2'],
14276
+ format: function (o) {
14277
+ return 'simulcast:%s %s' + (o.dir2 ? ' %s %s' : '');
14278
+ }
14279
+ }, {
14280
+ // old simulcast draft 03 (implemented by Firefox)
14281
+ // https://tools.ietf.org/html/draft-ietf-mmusic-sdp-simulcast-03
14282
+ // a=simulcast: recv pt=97;98 send pt=97
14283
+ // a=simulcast: send rid=5;6;7 paused=6,7
14284
+ name: 'simulcast_03',
14285
+ reg: /^simulcast:[\s\t]+([\S+\s\t]+)$/,
14286
+ names: ['value'],
14287
+ format: 'simulcast: %s'
14288
+ }, {
14289
+ // a=framerate:25
14290
+ // a=framerate:29.97
14291
+ name: 'framerate',
14292
+ reg: /^framerate:(\d+(?:$|\.\d+))/,
14293
+ format: 'framerate:%s'
14294
+ }, {
14295
+ // RFC4570
14296
+ // a=source-filter: incl IN IP4 239.5.2.31 10.1.15.5
14297
+ name: 'sourceFilter',
14298
+ reg: /^source-filter: *(excl|incl) (\S*) (IP4|IP6|\*) (\S*) (.*)/,
14299
+ names: ['filterMode', 'netType', 'addressTypes', 'destAddress', 'srcList'],
14300
+ format: 'source-filter: %s %s %s %s %s'
14301
+ }, {
14302
+ // a=bundle-only
14303
+ name: 'bundleOnly',
14304
+ reg: /^(bundle-only)/
14305
+ }, {
14306
+ // a=label:1
14307
+ name: 'label',
14308
+ reg: /^label:(.+)/,
14309
+ format: 'label:%s'
14310
+ }, {
14311
+ // RFC version 26 for SCTP over DTLS
14312
+ // https://tools.ietf.org/html/draft-ietf-mmusic-sctp-sdp-26#section-5
14313
+ name: 'sctpPort',
14314
+ reg: /^sctp-port:(\d+)$/,
14315
+ format: 'sctp-port:%s'
14316
+ }, {
14317
+ // RFC version 26 for SCTP over DTLS
14318
+ // https://tools.ietf.org/html/draft-ietf-mmusic-sctp-sdp-26#section-6
14319
+ name: 'maxMessageSize',
14320
+ reg: /^max-message-size:(\d+)$/,
14321
+ format: 'max-message-size:%s'
14322
+ }, {
14323
+ // RFC7273
14324
+ // a=ts-refclk:ptp=IEEE1588-2008:39-A7-94-FF-FE-07-CB-D0:37
14325
+ push: 'tsRefClocks',
14326
+ reg: /^ts-refclk:([^\s=]*)(?:=(\S*))?/,
14327
+ names: ['clksrc', 'clksrcExt'],
14328
+ format: function (o) {
14329
+ return 'ts-refclk:%s' + (o.clksrcExt != null ? '=%s' : '');
14330
+ }
14331
+ }, {
14332
+ // RFC7273
14333
+ // a=mediaclk:direct=963214424
14334
+ name: 'mediaClk',
14335
+ reg: /^mediaclk:(?:id=(\S*))? *([^\s=]*)(?:=(\S*))?(?: *rate=(\d+)\/(\d+))?/,
14336
+ names: ['id', 'mediaClockName', 'mediaClockValue', 'rateNumerator', 'rateDenominator'],
14337
+ format: function (o) {
14338
+ var str = 'mediaclk:';
14339
+ str += o.id != null ? 'id=%s %s' : '%v%s';
14340
+ str += o.mediaClockValue != null ? '=%s' : '';
14341
+ str += o.rateNumerator != null ? ' rate=%s' : '';
14342
+ str += o.rateDenominator != null ? '/%s' : '';
14343
+ return str;
14344
+ }
14345
+ }, {
14346
+ // a=keywds:keywords
14347
+ name: 'keywords',
14348
+ reg: /^keywds:(.+)$/,
14349
+ format: 'keywds:%s'
14350
+ }, {
14351
+ // a=content:main
14352
+ name: 'content',
14353
+ reg: /^content:(.+)/,
14354
+ format: 'content:%s'
14355
+ },
14356
+ // BFCP https://tools.ietf.org/html/rfc4583
14357
+ {
14358
+ // a=floorctrl:c-s
14359
+ name: 'bfcpFloorCtrl',
14360
+ reg: /^floorctrl:(c-only|s-only|c-s)/,
14361
+ format: 'floorctrl:%s'
14362
+ }, {
14363
+ // a=confid:1
14364
+ name: 'bfcpConfId',
14365
+ reg: /^confid:(\d+)/,
14366
+ format: 'confid:%s'
14367
+ }, {
14368
+ // a=userid:1
14369
+ name: 'bfcpUserId',
14370
+ reg: /^userid:(\d+)/,
14371
+ format: 'userid:%s'
14372
+ }, {
14373
+ // a=floorid:1
14374
+ name: 'bfcpFloorId',
14375
+ reg: /^floorid:(.+) (?:m-stream|mstrm):(.+)/,
14376
+ names: ['id', 'mStream'],
14377
+ format: 'floorid:%s mstrm:%s'
14378
+ }, {
14379
+ // any a= that we don't understand is kept verbatim on media.invalid
14380
+ push: 'invalid',
14381
+ names: ['value']
14382
+ }]
14383
+ };
14225
14384
 
14226
- // set sensible defaults to avoid polluting the grammar with boring details
14227
- Object.keys(grammar$1).forEach(function (key) {
14228
- var objs = grammar$1[key];
14229
- objs.forEach(function (obj) {
14230
- if (!obj.reg) {
14231
- obj.reg = /(.*)/;
14232
- }
14233
- if (!obj.format) {
14234
- obj.format = '%s';
14235
- }
14385
+ // set sensible defaults to avoid polluting the grammar with boring details
14386
+ Object.keys(grammar$1).forEach(function (key) {
14387
+ var objs = grammar$1[key];
14388
+ objs.forEach(function (obj) {
14389
+ if (!obj.reg) {
14390
+ obj.reg = /(.*)/;
14391
+ }
14392
+ if (!obj.format) {
14393
+ obj.format = '%s';
14394
+ }
14395
+ });
14236
14396
  });
14237
- });
14238
- var grammarExports = grammar$2.exports;
14397
+ return grammar.exports;
14398
+ }
14239
14399
 
14240
- (function (exports) {
14241
- var toIntIfInt = function (v) {
14242
- return String(Number(v)) === v ? Number(v) : v;
14243
- };
14244
- var attachProperties = function (match, location, names, rawName) {
14245
- if (rawName && !names) {
14246
- location[rawName] = toIntIfInt(match[1]);
14247
- } else {
14248
- for (var i = 0; i < names.length; i += 1) {
14249
- if (match[i + 1] != null) {
14250
- location[names[i]] = toIntIfInt(match[i + 1]);
14400
+ var hasRequiredParser;
14401
+ function requireParser() {
14402
+ if (hasRequiredParser) return parser;
14403
+ hasRequiredParser = 1;
14404
+ (function (exports) {
14405
+ var toIntIfInt = function (v) {
14406
+ return String(Number(v)) === v ? Number(v) : v;
14407
+ };
14408
+ var attachProperties = function (match, location, names, rawName) {
14409
+ if (rawName && !names) {
14410
+ location[rawName] = toIntIfInt(match[1]);
14411
+ } else {
14412
+ for (var i = 0; i < names.length; i += 1) {
14413
+ if (match[i + 1] != null) {
14414
+ location[names[i]] = toIntIfInt(match[i + 1]);
14415
+ }
14251
14416
  }
14252
14417
  }
14253
- }
14254
- };
14255
- var parseReg = function (obj, location, content) {
14256
- var needsBlank = obj.name && obj.names;
14257
- if (obj.push && !location[obj.push]) {
14258
- location[obj.push] = [];
14259
- } else if (needsBlank && !location[obj.name]) {
14260
- location[obj.name] = {};
14261
- }
14262
- var keyLocation = obj.push ? {} :
14263
- // blank object that will be pushed
14264
- needsBlank ? location[obj.name] : location; // otherwise, named location or root
14418
+ };
14419
+ var parseReg = function (obj, location, content) {
14420
+ var needsBlank = obj.name && obj.names;
14421
+ if (obj.push && !location[obj.push]) {
14422
+ location[obj.push] = [];
14423
+ } else if (needsBlank && !location[obj.name]) {
14424
+ location[obj.name] = {};
14425
+ }
14426
+ var keyLocation = obj.push ? {} :
14427
+ // blank object that will be pushed
14428
+ needsBlank ? location[obj.name] : location; // otherwise, named location or root
14265
14429
 
14266
- attachProperties(content.match(obj.reg), keyLocation, obj.names, obj.name);
14267
- if (obj.push) {
14268
- location[obj.push].push(keyLocation);
14269
- }
14270
- };
14271
- var grammar = grammarExports;
14272
- var validLine = RegExp.prototype.test.bind(/^([a-z])=(.*)/);
14273
- exports.parse = function (sdp) {
14274
- var session = {},
14275
- media = [],
14276
- location = session; // points at where properties go under (one of the above)
14277
-
14278
- // parse lines we understand
14279
- sdp.split(/(\r\n|\r|\n)/).filter(validLine).forEach(function (l) {
14280
- var type = l[0];
14281
- var content = l.slice(2);
14282
- if (type === 'm') {
14283
- media.push({
14284
- rtp: [],
14285
- fmtp: []
14286
- });
14287
- location = media[media.length - 1]; // point at latest media line
14430
+ attachProperties(content.match(obj.reg), keyLocation, obj.names, obj.name);
14431
+ if (obj.push) {
14432
+ location[obj.push].push(keyLocation);
14288
14433
  }
14289
- for (var j = 0; j < (grammar[type] || []).length; j += 1) {
14290
- var obj = grammar[type][j];
14291
- if (obj.reg.test(content)) {
14292
- return parseReg(obj, location, content);
14434
+ };
14435
+ var grammar = requireGrammar();
14436
+ var validLine = RegExp.prototype.test.bind(/^([a-z])=(.*)/);
14437
+ exports.parse = function (sdp) {
14438
+ var session = {},
14439
+ media = [],
14440
+ location = session; // points at where properties go under (one of the above)
14441
+
14442
+ // parse lines we understand
14443
+ sdp.split(/(\r\n|\r|\n)/).filter(validLine).forEach(function (l) {
14444
+ var type = l[0];
14445
+ var content = l.slice(2);
14446
+ if (type === 'm') {
14447
+ media.push({
14448
+ rtp: [],
14449
+ fmtp: []
14450
+ });
14451
+ location = media[media.length - 1]; // point at latest media line
14452
+ }
14453
+ for (var j = 0; j < (grammar[type] || []).length; j += 1) {
14454
+ var obj = grammar[type][j];
14455
+ if (obj.reg.test(content)) {
14456
+ return parseReg(obj, location, content);
14457
+ }
14293
14458
  }
14459
+ });
14460
+ session.media = media; // link it up
14461
+ return session;
14462
+ };
14463
+ var paramReducer = function (acc, expr) {
14464
+ var s = expr.split(/=(.+)/, 2);
14465
+ if (s.length === 2) {
14466
+ acc[s[0]] = toIntIfInt(s[1]);
14467
+ } else if (s.length === 1 && expr.length > 1) {
14468
+ acc[s[0]] = undefined;
14294
14469
  }
14295
- });
14296
- session.media = media; // link it up
14297
- return session;
14298
- };
14299
- var paramReducer = function (acc, expr) {
14300
- var s = expr.split(/=(.+)/, 2);
14301
- if (s.length === 2) {
14302
- acc[s[0]] = toIntIfInt(s[1]);
14303
- } else if (s.length === 1 && expr.length > 1) {
14304
- acc[s[0]] = undefined;
14305
- }
14306
- return acc;
14307
- };
14308
- exports.parseParams = function (str) {
14309
- return str.split(/;\s?/).reduce(paramReducer, {});
14310
- };
14470
+ return acc;
14471
+ };
14472
+ exports.parseParams = function (str) {
14473
+ return str.split(/;\s?/).reduce(paramReducer, {});
14474
+ };
14311
14475
 
14312
- // For backward compatibility - alias will be removed in 3.0.0
14313
- exports.parseFmtpConfig = exports.parseParams;
14314
- exports.parsePayloads = function (str) {
14315
- return str.toString().split(' ').map(Number);
14316
- };
14317
- exports.parseRemoteCandidates = function (str) {
14318
- var candidates = [];
14319
- var parts = str.split(' ').map(toIntIfInt);
14320
- for (var i = 0; i < parts.length; i += 3) {
14321
- candidates.push({
14322
- component: parts[i],
14323
- ip: parts[i + 1],
14324
- port: parts[i + 2]
14476
+ // For backward compatibility - alias will be removed in 3.0.0
14477
+ exports.parseFmtpConfig = exports.parseParams;
14478
+ exports.parsePayloads = function (str) {
14479
+ return str.toString().split(' ').map(Number);
14480
+ };
14481
+ exports.parseRemoteCandidates = function (str) {
14482
+ var candidates = [];
14483
+ var parts = str.split(' ').map(toIntIfInt);
14484
+ for (var i = 0; i < parts.length; i += 3) {
14485
+ candidates.push({
14486
+ component: parts[i],
14487
+ ip: parts[i + 1],
14488
+ port: parts[i + 2]
14489
+ });
14490
+ }
14491
+ return candidates;
14492
+ };
14493
+ exports.parseImageAttributes = function (str) {
14494
+ return str.split(' ').map(function (item) {
14495
+ return item.substring(1, item.length - 1).split(',').reduce(paramReducer, {});
14325
14496
  });
14326
- }
14327
- return candidates;
14328
- };
14329
- exports.parseImageAttributes = function (str) {
14330
- return str.split(' ').map(function (item) {
14331
- return item.substring(1, item.length - 1).split(',').reduce(paramReducer, {});
14332
- });
14497
+ };
14498
+ exports.parseSimulcastStreamList = function (str) {
14499
+ return str.split(';').map(function (stream) {
14500
+ return stream.split(',').map(function (format) {
14501
+ var scid,
14502
+ paused = false;
14503
+ if (format[0] !== '~') {
14504
+ scid = toIntIfInt(format);
14505
+ } else {
14506
+ scid = toIntIfInt(format.substring(1, format.length));
14507
+ paused = true;
14508
+ }
14509
+ return {
14510
+ scid: scid,
14511
+ paused: paused
14512
+ };
14513
+ });
14514
+ });
14515
+ };
14516
+ })(parser);
14517
+ return parser;
14518
+ }
14519
+
14520
+ var writer;
14521
+ var hasRequiredWriter;
14522
+ function requireWriter() {
14523
+ if (hasRequiredWriter) return writer;
14524
+ hasRequiredWriter = 1;
14525
+ var grammar = requireGrammar();
14526
+
14527
+ // customized util.format - discards excess arguments and can void middle ones
14528
+ var formatRegExp = /%[sdv%]/g;
14529
+ var format = function (formatStr) {
14530
+ var i = 1;
14531
+ var args = arguments;
14532
+ var len = args.length;
14533
+ return formatStr.replace(formatRegExp, function (x) {
14534
+ if (i >= len) {
14535
+ return x; // missing argument
14536
+ }
14537
+ var arg = args[i];
14538
+ i += 1;
14539
+ switch (x) {
14540
+ case '%%':
14541
+ return '%';
14542
+ case '%s':
14543
+ return String(arg);
14544
+ case '%d':
14545
+ return Number(arg);
14546
+ case '%v':
14547
+ return '';
14548
+ }
14549
+ });
14550
+ // NB: we discard excess arguments - they are typically undefined from makeLine
14333
14551
  };
14334
- exports.parseSimulcastStreamList = function (str) {
14335
- return str.split(';').map(function (stream) {
14336
- return stream.split(',').map(function (format) {
14337
- var scid,
14338
- paused = false;
14339
- if (format[0] !== '~') {
14340
- scid = toIntIfInt(format);
14552
+ var makeLine = function (type, obj, location) {
14553
+ var str = obj.format instanceof Function ? obj.format(obj.push ? location : location[obj.name]) : obj.format;
14554
+ var args = [type + '=' + str];
14555
+ if (obj.names) {
14556
+ for (var i = 0; i < obj.names.length; i += 1) {
14557
+ var n = obj.names[i];
14558
+ if (obj.name) {
14559
+ args.push(location[obj.name][n]);
14341
14560
  } else {
14342
- scid = toIntIfInt(format.substring(1, format.length));
14343
- paused = true;
14561
+ // for mLine and push attributes
14562
+ args.push(location[obj.names[i]]);
14344
14563
  }
14345
- return {
14346
- scid: scid,
14347
- paused: paused
14348
- };
14349
- });
14350
- });
14351
- };
14352
- })(parser$1);
14353
-
14354
- var grammar = grammarExports;
14355
-
14356
- // customized util.format - discards excess arguments and can void middle ones
14357
- var formatRegExp = /%[sdv%]/g;
14358
- var format = function (formatStr) {
14359
- var i = 1;
14360
- var args = arguments;
14361
- var len = args.length;
14362
- return formatStr.replace(formatRegExp, function (x) {
14363
- if (i >= len) {
14364
- return x; // missing argument
14365
- }
14366
- var arg = args[i];
14367
- i += 1;
14368
- switch (x) {
14369
- case '%%':
14370
- return '%';
14371
- case '%s':
14372
- return String(arg);
14373
- case '%d':
14374
- return Number(arg);
14375
- case '%v':
14376
- return '';
14377
- }
14378
- });
14379
- // NB: we discard excess arguments - they are typically undefined from makeLine
14380
- };
14381
- var makeLine = function (type, obj, location) {
14382
- var str = obj.format instanceof Function ? obj.format(obj.push ? location : location[obj.name]) : obj.format;
14383
- var args = [type + '=' + str];
14384
- if (obj.names) {
14385
- for (var i = 0; i < obj.names.length; i += 1) {
14386
- var n = obj.names[i];
14387
- if (obj.name) {
14388
- args.push(location[obj.name][n]);
14389
- } else {
14390
- // for mLine and push attributes
14391
- args.push(location[obj.names[i]]);
14392
14564
  }
14565
+ } else {
14566
+ args.push(location[obj.name]);
14393
14567
  }
14394
- } else {
14395
- args.push(location[obj.name]);
14396
- }
14397
- return format.apply(null, args);
14398
- };
14568
+ return format.apply(null, args);
14569
+ };
14399
14570
 
14400
- // RFC specified order
14401
- // TODO: extend this with all the rest
14402
- var defaultOuterOrder = ['v', 'o', 's', 'i', 'u', 'e', 'p', 'c', 'b', 't', 'r', 'z', 'a'];
14403
- var defaultInnerOrder = ['i', 'c', 'b', 'a'];
14404
- var writer$1 = function (session, opts) {
14405
- opts = opts || {};
14406
- // ensure certain properties exist
14407
- if (session.version == null) {
14408
- session.version = 0; // 'v=0' must be there (only defined version atm)
14409
- }
14410
- if (session.name == null) {
14411
- session.name = ' '; // 's= ' must be there if no meaningful name set
14412
- }
14413
- session.media.forEach(function (mLine) {
14414
- if (mLine.payloads == null) {
14415
- mLine.payloads = '';
14571
+ // RFC specified order
14572
+ // TODO: extend this with all the rest
14573
+ var defaultOuterOrder = ['v', 'o', 's', 'i', 'u', 'e', 'p', 'c', 'b', 't', 'r', 'z', 'a'];
14574
+ var defaultInnerOrder = ['i', 'c', 'b', 'a'];
14575
+ writer = function (session, opts) {
14576
+ opts = opts || {};
14577
+ // ensure certain properties exist
14578
+ if (session.version == null) {
14579
+ session.version = 0; // 'v=0' must be there (only defined version atm)
14416
14580
  }
14417
- });
14418
- var outerOrder = opts.outerOrder || defaultOuterOrder;
14419
- var innerOrder = opts.innerOrder || defaultInnerOrder;
14420
- var sdp = [];
14421
-
14422
- // loop through outerOrder for matching properties on session
14423
- outerOrder.forEach(function (type) {
14424
- grammar[type].forEach(function (obj) {
14425
- if (obj.name in session && session[obj.name] != null) {
14426
- sdp.push(makeLine(type, obj, session));
14427
- } else if (obj.push in session && session[obj.push] != null) {
14428
- session[obj.push].forEach(function (el) {
14429
- sdp.push(makeLine(type, obj, el));
14430
- });
14581
+ if (session.name == null) {
14582
+ session.name = ' '; // 's= ' must be there if no meaningful name set
14583
+ }
14584
+ session.media.forEach(function (mLine) {
14585
+ if (mLine.payloads == null) {
14586
+ mLine.payloads = '';
14431
14587
  }
14432
14588
  });
14433
- });
14589
+ var outerOrder = opts.outerOrder || defaultOuterOrder;
14590
+ var innerOrder = opts.innerOrder || defaultInnerOrder;
14591
+ var sdp = [];
14434
14592
 
14435
- // then for each media line, follow the innerOrder
14436
- session.media.forEach(function (mLine) {
14437
- sdp.push(makeLine('m', grammar.m[0], mLine));
14438
- innerOrder.forEach(function (type) {
14593
+ // loop through outerOrder for matching properties on session
14594
+ outerOrder.forEach(function (type) {
14439
14595
  grammar[type].forEach(function (obj) {
14440
- if (obj.name in mLine && mLine[obj.name] != null) {
14441
- sdp.push(makeLine(type, obj, mLine));
14442
- } else if (obj.push in mLine && mLine[obj.push] != null) {
14443
- mLine[obj.push].forEach(function (el) {
14596
+ if (obj.name in session && session[obj.name] != null) {
14597
+ sdp.push(makeLine(type, obj, session));
14598
+ } else if (obj.push in session && session[obj.push] != null) {
14599
+ session[obj.push].forEach(function (el) {
14444
14600
  sdp.push(makeLine(type, obj, el));
14445
14601
  });
14446
14602
  }
14447
14603
  });
14448
14604
  });
14449
- });
14450
- return sdp.join('\r\n') + '\r\n';
14451
- };
14452
14605
 
14453
- var parser = parser$1;
14454
- var writer = writer$1;
14455
- var write = writer;
14456
- var parse = parser.parse;
14457
- parser.parseParams;
14458
- parser.parseFmtpConfig; // Alias of parseParams().
14459
- parser.parsePayloads;
14460
- parser.parseRemoteCandidates;
14461
- parser.parseImageAttributes;
14462
- parser.parseSimulcastStreamList;
14606
+ // then for each media line, follow the innerOrder
14607
+ session.media.forEach(function (mLine) {
14608
+ sdp.push(makeLine('m', grammar.m[0], mLine));
14609
+ innerOrder.forEach(function (type) {
14610
+ grammar[type].forEach(function (obj) {
14611
+ if (obj.name in mLine && mLine[obj.name] != null) {
14612
+ sdp.push(makeLine(type, obj, mLine));
14613
+ } else if (obj.push in mLine && mLine[obj.push] != null) {
14614
+ mLine[obj.push].forEach(function (el) {
14615
+ sdp.push(makeLine(type, obj, el));
14616
+ });
14617
+ }
14618
+ });
14619
+ });
14620
+ });
14621
+ return sdp.join('\r\n') + '\r\n';
14622
+ };
14623
+ return writer;
14624
+ }
14625
+
14626
+ var hasRequiredLib;
14627
+ function requireLib() {
14628
+ if (hasRequiredLib) return lib;
14629
+ hasRequiredLib = 1;
14630
+ var parser = requireParser();
14631
+ var writer = requireWriter();
14632
+ lib.write = writer;
14633
+ lib.parse = parser.parse;
14634
+ lib.parseParams = parser.parseParams;
14635
+ lib.parseFmtpConfig = parser.parseFmtpConfig; // Alias of parseParams().
14636
+ lib.parsePayloads = parser.parsePayloads;
14637
+ lib.parseRemoteCandidates = parser.parseRemoteCandidates;
14638
+ lib.parseImageAttributes = parser.parseImageAttributes;
14639
+ lib.parseSimulcastStreamList = parser.parseSimulcastStreamList;
14640
+ return lib;
14641
+ }
14642
+
14643
+ var libExports = requireLib();
14463
14644
 
14464
14645
  /* The svc codec (av1/vp9) would use a very low bitrate at the begining and
14465
14646
  increase slowly by the bandwidth estimator until it reach the target bitrate. The
@@ -14589,7 +14770,7 @@ class PCTransport extends eventsExports.EventEmitter {
14589
14770
  this.remoteStereoMids = stereoMids;
14590
14771
  this.remoteNackMids = nackMids;
14591
14772
  } else if (sd.type === 'answer') {
14592
- const sdpParsed = parse((_a = sd.sdp) !== null && _a !== void 0 ? _a : '');
14773
+ const sdpParsed = libExports.parse((_a = sd.sdp) !== null && _a !== void 0 ? _a : '');
14593
14774
  sdpParsed.media.forEach(media => {
14594
14775
  if (media.type === 'audio') {
14595
14776
  // mung sdp for opus bitrate settings
@@ -14631,7 +14812,7 @@ class PCTransport extends eventsExports.EventEmitter {
14631
14812
  });
14632
14813
  }
14633
14814
  });
14634
- mungedSDP = write(sdpParsed);
14815
+ mungedSDP = libExports.write(sdpParsed);
14635
14816
  }
14636
14817
  yield this.setMungedSDP(sd, mungedSDP, true);
14637
14818
  this.pendingCandidates.forEach(candidate => {
@@ -14645,7 +14826,7 @@ class PCTransport extends eventsExports.EventEmitter {
14645
14826
  } else if (sd.type === 'answer') {
14646
14827
  this.emit(PCEvents.NegotiationComplete);
14647
14828
  if (sd.sdp) {
14648
- const sdpParsed = parse(sd.sdp);
14829
+ const sdpParsed = libExports.parse(sd.sdp);
14649
14830
  sdpParsed.media.forEach(media => {
14650
14831
  if (media.type === 'video') {
14651
14832
  this.emit(PCEvents.RTPVideoPayloadTypes, media.rtp);
@@ -14687,7 +14868,7 @@ class PCTransport extends eventsExports.EventEmitter {
14687
14868
  this.log.debug('original offer', Object.assign({
14688
14869
  sdp: offer.sdp
14689
14870
  }, this.logContext));
14690
- const sdpParsed = parse((_a = offer.sdp) !== null && _a !== void 0 ? _a : '');
14871
+ const sdpParsed = libExports.parse((_a = offer.sdp) !== null && _a !== void 0 ? _a : '');
14691
14872
  sdpParsed.media.forEach(media => {
14692
14873
  if (media.type === 'audio') {
14693
14874
  ensureAudioNackAndStereo(media, [], []);
@@ -14731,7 +14912,7 @@ class PCTransport extends eventsExports.EventEmitter {
14731
14912
  });
14732
14913
  }
14733
14914
  });
14734
- yield this.setMungedSDP(offer, write(sdpParsed));
14915
+ yield this.setMungedSDP(offer, libExports.write(sdpParsed));
14735
14916
  this.onOffer(offer);
14736
14917
  });
14737
14918
  }
@@ -14739,13 +14920,13 @@ class PCTransport extends eventsExports.EventEmitter {
14739
14920
  return __awaiter(this, void 0, void 0, function* () {
14740
14921
  var _a;
14741
14922
  const answer = yield this.pc.createAnswer();
14742
- const sdpParsed = parse((_a = answer.sdp) !== null && _a !== void 0 ? _a : '');
14923
+ const sdpParsed = libExports.parse((_a = answer.sdp) !== null && _a !== void 0 ? _a : '');
14743
14924
  sdpParsed.media.forEach(media => {
14744
14925
  if (media.type === 'audio') {
14745
14926
  ensureAudioNackAndStereo(media, this.remoteStereoMids, this.remoteNackMids);
14746
14927
  }
14747
14928
  });
14748
- yield this.setMungedSDP(answer, write(sdpParsed));
14929
+ yield this.setMungedSDP(answer, libExports.write(sdpParsed));
14749
14930
  return answer;
14750
14931
  });
14751
14932
  }
@@ -14953,7 +15134,7 @@ function extractStereoAndNackAudioFromOffer(offer) {
14953
15134
  var _a;
14954
15135
  const stereoMids = [];
14955
15136
  const nackMids = [];
14956
- const sdpParsed = parse((_a = offer.sdp) !== null && _a !== void 0 ? _a : '');
15137
+ const sdpParsed = libExports.parse((_a = offer.sdp) !== null && _a !== void 0 ? _a : '');
14957
15138
  let opusPayload = 0;
14958
15139
  sdpParsed.media.forEach(media => {
14959
15140
  var _a;
@@ -15276,7 +15457,7 @@ class PCTransportManager {
15276
15457
  const abortHandler = () => {
15277
15458
  this.log.warn('abort transport connection', this.logContext);
15278
15459
  CriticalTimers.clearTimeout(connectTimeout);
15279
- reject(new ConnectionError('room connection has been cancelled', 3 /* ConnectionErrorReason.Cancelled */));
15460
+ reject(new ConnectionError('room connection has been cancelled', ConnectionErrorReason.Cancelled));
15280
15461
  };
15281
15462
  if (abortController === null || abortController === void 0 ? void 0 : abortController.signal.aborted) {
15282
15463
  abortHandler();
@@ -15289,7 +15470,7 @@ class PCTransportManager {
15289
15470
  while (this.state !== PCTransportState.CONNECTED) {
15290
15471
  yield sleep(50); // FIXME we shouldn't rely on `sleep` in the connection paths, as it invokes `setTimeout` which can be drastically throttled by browser implementations
15291
15472
  if (abortController === null || abortController === void 0 ? void 0 : abortController.signal.aborted) {
15292
- reject(new ConnectionError('room connection has been cancelled', 3 /* ConnectionErrorReason.Cancelled */));
15473
+ reject(new ConnectionError('room connection has been cancelled', ConnectionErrorReason.Cancelled));
15293
15474
  return;
15294
15475
  }
15295
15476
  }
@@ -16745,7 +16926,7 @@ class RTCEngine extends eventsExports.EventEmitter {
16745
16926
  return joinResponse;
16746
16927
  } catch (e) {
16747
16928
  if (e instanceof ConnectionError) {
16748
- if (e.reason === 1 /* ConnectionErrorReason.ServerUnreachable */) {
16929
+ if (e.reason === ConnectionErrorReason.ServerUnreachable) {
16749
16930
  this.log.warn("Couldn't connect to server, attempt ".concat(this.joinAttempts, " of ").concat(this.maxJoinAttempts), this.logContext);
16750
16931
  if (this.joinAttempts < this.maxJoinAttempts) {
16751
16932
  return this.join(url, token, opts, abortSignal);
@@ -17247,7 +17428,7 @@ class RTCEngine extends eventsExports.EventEmitter {
17247
17428
  // in case a regionUrl is passed, the region URL takes precedence
17248
17429
  joinResponse = yield this.join(regionUrl !== null && regionUrl !== void 0 ? regionUrl : this.url, this.token, this.signalOpts);
17249
17430
  } catch (e) {
17250
- if (e instanceof ConnectionError && e.reason === 0 /* ConnectionErrorReason.NotAllowed */) {
17431
+ if (e instanceof ConnectionError && e.reason === ConnectionErrorReason.NotAllowed) {
17251
17432
  throw new UnexpectedConnectionState('could not reconnect, token might be expired');
17252
17433
  }
17253
17434
  throw new SignalReconnectError();
@@ -17304,10 +17485,10 @@ class RTCEngine extends eventsExports.EventEmitter {
17304
17485
  error
17305
17486
  }));
17306
17487
  }
17307
- if (error instanceof ConnectionError && error.reason === 0 /* ConnectionErrorReason.NotAllowed */) {
17488
+ if (error instanceof ConnectionError && error.reason === ConnectionErrorReason.NotAllowed) {
17308
17489
  throw new UnexpectedConnectionState('could not reconnect, token might be expired');
17309
17490
  }
17310
- if (error instanceof ConnectionError && error.reason === 4 /* ConnectionErrorReason.LeaveRequest */) {
17491
+ if (error instanceof ConnectionError && error.reason === ConnectionErrorReason.LeaveRequest) {
17311
17492
  throw error;
17312
17493
  }
17313
17494
  throw new SignalReconnectError(message);
@@ -17665,7 +17846,7 @@ class RegionUrlProvider {
17665
17846
  this.lastUpdateAt = Date.now();
17666
17847
  return regionSettings;
17667
17848
  } else {
17668
- throw new ConnectionError("Could not fetch region settings: ".concat(regionSettingsResponse.statusText), regionSettingsResponse.status === 401 ? 0 /* ConnectionErrorReason.NotAllowed */ : undefined, regionSettingsResponse.status);
17849
+ throw new ConnectionError("Could not fetch region settings: ".concat(regionSettingsResponse.statusText), regionSettingsResponse.status === 401 ? ConnectionErrorReason.NotAllowed : undefined, regionSettingsResponse.status);
17669
17850
  }
17670
17851
  });
17671
17852
  }
@@ -18504,7 +18685,7 @@ class LocalTrackPublication extends TrackPublication {
18504
18685
  features.add(AudioTrackFeature.TF_STEREO);
18505
18686
  }
18506
18687
  if (!((_a = this.options) === null || _a === void 0 ? void 0 : _a.dtx)) {
18507
- features.add(AudioTrackFeature.TF_STEREO);
18688
+ features.add(AudioTrackFeature.TF_NO_DTX);
18508
18689
  }
18509
18690
  if (this.track.enhancedNoiseCancellation) {
18510
18691
  features.add(AudioTrackFeature.TF_ENHANCED_NOISE_CANCELLATION);
@@ -18825,12 +19006,12 @@ class Participant extends eventsExports.EventEmitter {
18825
19006
  }
18826
19007
  /** @internal */
18827
19008
  setPermissions(permissions) {
18828
- var _a, _b, _c, _d, _e;
19009
+ var _a, _b, _c, _d, _e, _f;
18829
19010
  const prevPermissions = this.permissions;
18830
19011
  const changed = permissions.canPublish !== ((_a = this.permissions) === null || _a === void 0 ? void 0 : _a.canPublish) || permissions.canSubscribe !== ((_b = this.permissions) === null || _b === void 0 ? void 0 : _b.canSubscribe) || permissions.canPublishData !== ((_c = this.permissions) === null || _c === void 0 ? void 0 : _c.canPublishData) || permissions.hidden !== ((_d = this.permissions) === null || _d === void 0 ? void 0 : _d.hidden) || permissions.recorder !== ((_e = this.permissions) === null || _e === void 0 ? void 0 : _e.recorder) || permissions.canPublishSources.length !== this.permissions.canPublishSources.length || permissions.canPublishSources.some((value, index) => {
18831
19012
  var _a;
18832
19013
  return value !== ((_a = this.permissions) === null || _a === void 0 ? void 0 : _a.canPublishSources[index]);
18833
- });
19014
+ }) || permissions.canSubscribeMetrics !== ((_f = this.permissions) === null || _f === void 0 ? void 0 : _f.canSubscribeMetrics);
18834
19015
  this.permissions = permissions;
18835
19016
  if (changed) {
18836
19017
  this.emit(ParticipantEvent.ParticipantPermissionsChanged, prevPermissions);
@@ -20061,6 +20242,27 @@ class LocalParticipant extends Participant {
20061
20242
  }();
20062
20243
  });
20063
20244
  }
20245
+ /**
20246
+ * Publish SIP DTMF message to the room.
20247
+ *
20248
+ * @param code DTMF code
20249
+ * @param digit DTMF digit
20250
+ */
20251
+ publishDtmf(code, digit) {
20252
+ return __awaiter(this, void 0, void 0, function* () {
20253
+ const packet = new DataPacket({
20254
+ kind: DataPacket_Kind.RELIABLE,
20255
+ value: {
20256
+ case: 'sipDtmf',
20257
+ value: new SipDTMF({
20258
+ code: code,
20259
+ digit: digit
20260
+ })
20261
+ }
20262
+ });
20263
+ yield this.engine.sendDataPacket(packet, DataPacket_Kind.RELIABLE);
20264
+ });
20265
+ }
20064
20266
  sendChatMessage(text) {
20065
20267
  return __awaiter(this, void 0, void 0, function* () {
20066
20268
  const msg = {
@@ -20791,12 +20993,12 @@ class Room extends eventsExports.EventEmitter {
20791
20993
  this.abortController = undefined;
20792
20994
  resolve();
20793
20995
  } catch (e) {
20794
- if (this.regionUrlProvider && e instanceof ConnectionError && e.reason !== 3 /* ConnectionErrorReason.Cancelled */ && e.reason !== 0 /* ConnectionErrorReason.NotAllowed */) {
20996
+ if (this.regionUrlProvider && e instanceof ConnectionError && e.reason !== ConnectionErrorReason.Cancelled && e.reason !== ConnectionErrorReason.NotAllowed) {
20795
20997
  let nextUrl = null;
20796
20998
  try {
20797
20999
  nextUrl = yield this.regionUrlProvider.getNextBestRegionUrl((_a = this.abortController) === null || _a === void 0 ? void 0 : _a.signal);
20798
21000
  } catch (error) {
20799
- if (error instanceof ConnectionError && (error.status === 401 || error.reason === 3 /* ConnectionErrorReason.Cancelled */)) {
21001
+ if (error instanceof ConnectionError && (error.status === 401 || error.reason === ConnectionErrorReason.Cancelled)) {
20800
21002
  this.handleDisconnect(this.options.stopLocalTrackOnUnpublish);
20801
21003
  reject(error);
20802
21004
  return;
@@ -20841,6 +21043,7 @@ class Room extends eventsExports.EventEmitter {
20841
21043
  region: joinResponse.serverRegion
20842
21044
  };
20843
21045
  }
21046
+ this.serverInfo = serverInfo;
20844
21047
  this.log.debug("connected to Livekit Server ".concat(Object.entries(serverInfo).map(_ref => {
20845
21048
  let [key, value] = _ref;
20846
21049
  return "".concat(key, ": ").concat(value);
@@ -20849,10 +21052,10 @@ class Room extends eventsExports.EventEmitter {
20849
21052
  roomSid: (_b = joinResponse.room) === null || _b === void 0 ? void 0 : _b.sid,
20850
21053
  identity: (_c = joinResponse.participant) === null || _c === void 0 ? void 0 : _c.identity
20851
21054
  });
20852
- if (!joinResponse.serverVersion) {
21055
+ if (!serverInfo.version) {
20853
21056
  throw new UnsupportedServer('unknown server version');
20854
21057
  }
20855
- if (joinResponse.serverVersion === '0.15.1' && this.options.dynacast) {
21058
+ if (serverInfo.version === '0.15.1' && this.options.dynacast) {
20856
21059
  this.log.debug('disabling dynacast due to server version', this.logContext);
20857
21060
  // dynacast has a bug in 0.15.1, so we cannot use it then
20858
21061
  roomOptions.dynacast = false;
@@ -21223,9 +21426,12 @@ class Room extends eventsExports.EventEmitter {
21223
21426
  if (!pub || !pub.track) {
21224
21427
  return;
21225
21428
  }
21226
- pub.track.streamState = Track.streamStateFromProto(streamState.state);
21227
- participant.emit(ParticipantEvent.TrackStreamStateChanged, pub, pub.track.streamState);
21228
- this.emitWhenConnected(RoomEvent.TrackStreamStateChanged, pub, pub.track.streamState, participant);
21429
+ const newStreamState = Track.streamStateFromProto(streamState.state);
21430
+ if (newStreamState !== pub.track.streamState) {
21431
+ pub.track.streamState = newStreamState;
21432
+ participant.emit(ParticipantEvent.TrackStreamStateChanged, pub, pub.track.streamState);
21433
+ this.emitWhenConnected(RoomEvent.TrackStreamStateChanged, pub, pub.track.streamState, participant);
21434
+ }
21229
21435
  });
21230
21436
  };
21231
21437
  this.handleSubscriptionPermissionUpdate = update => {
@@ -21261,6 +21467,8 @@ class Room extends eventsExports.EventEmitter {
21261
21467
  this.handleSipDtmf(participant, packet.value.value);
21262
21468
  } else if (packet.value.case === 'chatMessage') {
21263
21469
  this.handleChatMessage(participant, packet.value.value);
21470
+ } else if (packet.value.case === 'metrics') {
21471
+ this.handleMetrics(packet.value.value, participant);
21264
21472
  }
21265
21473
  };
21266
21474
  this.handleUserPacket = (participant, userPacket, kind) => {
@@ -21287,6 +21495,9 @@ class Room extends eventsExports.EventEmitter {
21287
21495
  const msg = extractChatMessage(chatMessage);
21288
21496
  this.emit(RoomEvent.ChatMessage, msg, participant);
21289
21497
  };
21498
+ this.handleMetrics = (metrics, participant) => {
21499
+ this.emit(RoomEvent.MetricsReceived, metrics, participant);
21500
+ };
21290
21501
  this.handleAudioPlaybackStarted = () => {
21291
21502
  if (this.canPlaybackAudio) {
21292
21503
  return;
@@ -22879,5 +23090,5 @@ function isFacingModeValue(item) {
22879
23090
  return item === undefined || allowedValues.includes(item);
22880
23091
  }
22881
23092
 
22882
- export { AudioPresets, BaseKeyProvider, CheckStatus, Checker, ConnectionCheck, ConnectionError, ConnectionQuality, ConnectionState, CriticalTimers, CryptorError, CryptorErrorReason, CryptorEvent, DataPacket_Kind, DefaultReconnectPolicy, DeviceUnsupportedError, DisconnectReason, EncryptionEvent, EngineEvent, ExternalE2EEKeyProvider, KeyHandlerEvent, KeyProviderEvent, LivekitError, LocalAudioTrack, LocalParticipant, LocalTrack, LocalTrackPublication, LocalVideoTrack, LogLevel, LoggerNames, MediaDeviceFailure, Mutex, NegotiationError, Participant, ParticipantEvent, ParticipantInfo_Kind as ParticipantKind, PublishDataError, RemoteAudioTrack, RemoteParticipant, RemoteTrack, RemoteTrackPublication, RemoteVideoTrack, Room, RoomEvent, ScreenSharePresets, SignalRequestError, SubscriptionError, Track, TrackEvent, TrackInvalidError, TrackPublication, UnexpectedConnectionState, UnsupportedServer, VideoPreset, VideoPresets, VideoPresets43, VideoQuality, attachToElement, createAudioAnalyser, createE2EEKey, createKeyMaterialFromBuffer, createKeyMaterialFromString, createLocalAudioTrack, createLocalScreenTracks, createLocalTracks, createLocalVideoTrack, deriveKeys, detachTrack, extractProcessorsFromOptions, facingModeFromDeviceLabel, facingModeFromLocalTrack, getBrowser, getEmptyAudioStreamTrack, getEmptyVideoStreamTrack, getLogger, importKey, isBackupCodec, isBrowserSupported, isE2EESupported, isInsertableStreamSupported, isScriptTransformSupported, isVideoFrame, needsRbspUnescaping, parseRbsp, protocolVersion, ratchet, setLogExtension, setLogLevel, supportsAV1, supportsAdaptiveStream, supportsDynacast, supportsVP9, version, videoCodecs, writeRbsp };
23093
+ export { AudioPresets, BaseKeyProvider, CheckStatus, Checker, ConnectionCheck, ConnectionError, ConnectionErrorReason, ConnectionQuality, ConnectionState, CriticalTimers, CryptorError, CryptorErrorReason, CryptorEvent, DataPacket_Kind, DefaultReconnectPolicy, DeviceUnsupportedError, DisconnectReason, EncryptionEvent, EngineEvent, ExternalE2EEKeyProvider, KeyHandlerEvent, KeyProviderEvent, LivekitError, LocalAudioTrack, LocalParticipant, LocalTrack, LocalTrackPublication, LocalVideoTrack, LogLevel, LoggerNames, MediaDeviceFailure, Mutex, NegotiationError, Participant, ParticipantEvent, ParticipantInfo_Kind as ParticipantKind, PublishDataError, RemoteAudioTrack, RemoteParticipant, RemoteTrack, RemoteTrackPublication, RemoteVideoTrack, Room, RoomEvent, ScreenSharePresets, SignalRequestError, SubscriptionError, Track, TrackEvent, TrackInvalidError, TrackPublication, UnexpectedConnectionState, UnsupportedServer, VideoPreset, VideoPresets, VideoPresets43, VideoQuality, attachToElement, compareVersions, createAudioAnalyser, createE2EEKey, createKeyMaterialFromBuffer, createKeyMaterialFromString, createLocalAudioTrack, createLocalScreenTracks, createLocalTracks, createLocalVideoTrack, deriveKeys, detachTrack, extractProcessorsFromOptions, facingModeFromDeviceLabel, facingModeFromLocalTrack, getBrowser, getEmptyAudioStreamTrack, getEmptyVideoStreamTrack, getLogger, importKey, isBackupCodec, isBrowserSupported, isE2EESupported, isInsertableStreamSupported, isScriptTransformSupported, isVideoFrame, needsRbspUnescaping, parseRbsp, protocolVersion, ratchet, setLogExtension, setLogLevel, supportsAV1, supportsAdaptiveStream, supportsDynacast, supportsVP9, version, videoCodecs, writeRbsp };
22883
23094
  //# sourceMappingURL=livekit-client.esm.mjs.map