Browse Source

Add callstats support

master
hristoterezov 9 years ago
parent
commit
b8682c6a83

+ 89
- 8
JitsiConference.js View File

@@ -12,6 +12,7 @@ var JitsiParticipant = require("./JitsiParticipant");
12 12
 var Statistics = require("./modules/statistics/statistics");
13 13
 var JitsiDTMFManager = require('./modules/DTMF/JitsiDTMFManager');
14 14
 var JitsiTrackEvents = require("./JitsiTrackEvents");
15
+var Settings = require("./modules/settings/Settings");
15 16
 
16 17
 /**
17 18
  * Creates a JitsiConference object with the given name and properties.
@@ -32,12 +33,22 @@ function JitsiConference(options) {
32 33
     this.connection = this.options.connection;
33 34
     this.xmpp = this.connection.xmpp;
34 35
     this.eventEmitter = new EventEmitter();
35
-    this.room = this.xmpp.createRoom(this.options.name, this.options.config);
36
+    var confID = this.options.name  + '@' + this.xmpp.options.hosts.muc;
37
+    this.settings = new Settings(confID);
38
+    this.room = this.xmpp.createRoom(this.options.name, this.options.config,
39
+        this.settings);
36 40
     this.room.updateDeviceAvailability(RTC.getDeviceAvailability());
37 41
     this.rtc = new RTC(this.room, options);
38
-    if(!RTC.options.disableAudioLevels)
39
-        this.statistics = new Statistics();
42
+    this.statistics = new Statistics({
43
+        disableAudioLevels: RTC.options.disableAudioLevels,
44
+        callStatsID: this.options.config.callStatsID,
45
+        callStatsSecret: this.options.config.callStatsSecret,
46
+        disableThirdPartyRequests: this.options.config.disableThirdPartyRequests
47
+    });
40 48
     setupListeners(this);
49
+    JitsiMeetJS._gumFailedHandler.push(function(error) {
50
+        this.statistics.sendGetUserMediaFailed(error);
51
+    }.bind(this));
41 52
     this.participants = {};
42 53
     this.lastDominantSpeaker = null;
43 54
     this.dtmfManager = null;
@@ -259,9 +270,12 @@ JitsiConference.prototype.addTrack = function (track) {
259 270
         track.muteHandler = this._fireMuteChangeEvent.bind(this, track);
260 271
         track.stopHandler = this.removeTrack.bind(this, track);
261 272
         track.audioLevelHandler = this._fireAudioLevelChangeEvent.bind(this);
262
-        track.addEventListener(JitsiTrackEvents.TRACK_MUTE_CHANGED, track.muteHandler);
263
-        track.addEventListener(JitsiTrackEvents.TRACK_STOPPED, track.stopHandler);
264
-        track.addEventListener(JitsiTrackEvents.TRACK_AUDIO_LEVEL_CHANGED, track.audioLevelHandler);
273
+        track.addEventListener(JitsiTrackEvents.TRACK_MUTE_CHANGED,
274
+            track.muteHandler);
275
+        track.addEventListener(JitsiTrackEvents.TRACK_STOPPED,
276
+            track.stopHandler);
277
+        track.addEventListener(JitsiTrackEvents.TRACK_AUDIO_LEVEL_CHANGED,
278
+            track.audioLevelHandler);
265 279
         this.eventEmitter.emit(JitsiConferenceEvents.TRACK_ADDED, track);
266 280
     }.bind(this));
267 281
 };
@@ -717,6 +731,29 @@ JitsiConference.prototype.getLogs = function () {
717 731
     return data;
718 732
 };
719 733
 
734
+/**
735
+ * Sends the given feedback through CallStats if enabled.
736
+ *
737
+ * @param overallFeedback an integer between 1 and 5 indicating the
738
+ * user feedback
739
+ * @param detailedFeedback detailed feedback from the user. Not yet used
740
+ */
741
+JitsiConference.prototype.sendFeedback =
742
+function(overallFeedback, detailedFeedback){
743
+    this.statistics.sendFeedback(overallFeedback, detailedFeedback);
744
+}
745
+
746
+/**
747
+ * Returns true if the callstats integration is enabled, otherwise returns
748
+ * false.
749
+ *
750
+ * @returns true if the callstats integration is enabled, otherwise returns
751
+ * false.
752
+ */
753
+JitsiConference.prototype.isCallstatsEnabled = function () {
754
+    return this.statistics.isCallstatsEnabled();
755
+}
756
+
720 757
 /**
721 758
  * Setups the listeners needed for the conference.
722 759
  * @param conference the conference
@@ -724,8 +761,7 @@ JitsiConference.prototype.getLogs = function () {
724 761
 function setupListeners(conference) {
725 762
     conference.xmpp.addListener(XMPPEvents.CALL_INCOMING, function (event) {
726 763
         conference.rtc.onIncommingCall(event);
727
-        if(conference.statistics)
728
-            conference.statistics.startRemoteStats(event.peerconnection);
764
+        conference.statistics.startRemoteStats(event.peerconnection);
729 765
     });
730 766
 
731 767
     conference.room.addListener(XMPPEvents.REMOTE_STREAM_RECEIVED,
@@ -907,6 +943,51 @@ function setupListeners(conference) {
907 943
         // RTC.addListener(RTCEvents.AVAILABLE_DEVICES_CHANGED, function (devices) {
908 944
         //     conference.room.updateDeviceAvailability(devices);
909 945
         // });
946
+
947
+        conference.room.addListener(XMPPEvents.PEERCONNECTION_READY,
948
+            function (session) {
949
+                conference.statistics.startCallStats(
950
+                    session, conference.settings);
951
+            });
952
+
953
+        conference.room.addListener(XMPPEvents.CONFERENCE_SETUP_FAILED,
954
+            function () {
955
+                conference.statistics.sendSetupFailedEvent();
956
+            });
957
+
958
+        conference.on(JitsiConferenceEvents.TRACK_MUTE_CHANGED,
959
+            function (track) {
960
+                if(!track.isLocal())
961
+                    return;
962
+                var type = (track.getType() === "audio")? "audio" : "video";
963
+                conference.statistics.sendMuteEvent(track.isMuted(), type);
964
+            });
965
+
966
+        conference.room.addListener(XMPPEvents.CREATE_OFFER_FAILED, function (e, pc) {
967
+            conference.statistics.sendCreateOfferFailed(e, pc);
968
+        });
969
+
970
+        conference.room.addListener(XMPPEvents.CREATE_ANSWER_FAILED, function (e, pc) {
971
+            conference.statistics.sendCreateAnswerFailed(e, pc);
972
+        });
973
+
974
+        conference.room.addListener(XMPPEvents.SET_LOCAL_DESCRIPTION_FAILED,
975
+            function (e, pc) {
976
+                conference.statistics.sendSetLocalDescFailed(e, pc);
977
+            }
978
+        );
979
+
980
+        conference.room.addListener(XMPPEvents.SET_REMOTE_DESCRIPTION_FAILED,
981
+            function (e, pc) {
982
+                conference.statistics.sendSetRemoteDescFailed(e, pc);
983
+            }
984
+        );
985
+
986
+        conference.room.addListener(XMPPEvents.ADD_ICE_CANDIDATE_FAILED,
987
+            function (e, pc) {
988
+                conference.statistics.sendAddIceCandidateFailed(e, pc);
989
+            }
990
+        );
910 991
     }
911 992
 }
912 993
 

+ 9
- 1
JitsiMeetJS.js View File

@@ -43,6 +43,10 @@ var LibJitsiMeet = {
43 43
         track: JitsiTrackErrors
44 44
     },
45 45
     logLevels: Logger.levels,
46
+    /**
47
+     * Array of functions that will receive the GUM error.
48
+     */
49
+    _gumFailedHandler: [],
46 50
     init: function (options) {
47 51
         return RTC.init(options || {});
48 52
     },
@@ -90,6 +94,10 @@ var LibJitsiMeet = {
90 94
                     }
91 95
                 return tracks;
92 96
             }).catch(function (error) {
97
+                this._gumFailedHandler.forEach(function (handler) {
98
+                    handler(error);
99
+                });
100
+                Statistics.sendGetUserMediaFailed(error);
93 101
                 if(error === JitsiTrackErrors.UNSUPPORTED_RESOLUTION) {
94 102
                     var oldResolution = options.resolution || '360';
95 103
                     var newResolution = getLowerResolution(oldResolution);
@@ -99,7 +107,7 @@ var LibJitsiMeet = {
99 107
                     return LibJitsiMeet.createLocalTracks(options);
100 108
                 }
101 109
                 return Promise.reject(error);
102
-            });
110
+            }.bind(this));
103 111
     },
104 112
     /**
105 113
      * Checks if its possible to enumerate available cameras/micropones.

+ 8280
- 309
lib-jitsi-meet.js
File diff suppressed because it is too large
View File


+ 16
- 12
lib-jitsi-meet.min.js
File diff suppressed because it is too large
View File


+ 0
- 2
modules/RTC/JitsiRemoteTrack.js View File

@@ -70,6 +70,4 @@ JitsiRemoteTrack.prototype.isLocal = function () {
70 70
 
71 71
 delete JitsiRemoteTrack.prototype.stop;
72 72
 
73
-delete JitsiRemoteTrack.prototype.start;
74
-
75 73
 module.exports = JitsiRemoteTrack;

+ 25
- 3
modules/settings/Settings.js View File

@@ -1,5 +1,7 @@
1
-
2 1
 var logger = require("jitsi-meet-logger").getLogger(__filename);
2
+
3
+var UsernameGenerator = require('../util/UsernameGenerator');
4
+
3 5
 function supportsLocalStorage() {
4 6
     try {
5 7
         return 'localStorage' in window && window.localStorage !== null;
@@ -22,6 +24,7 @@ function Settings(conferenceID) {
22 24
     this.userId;
23 25
     this.confSettings = null;
24 26
     this.conferenceID = conferenceID;
27
+    this.callStatsUserName;
25 28
     if (supportsLocalStorage()) {
26 29
         if(!window.localStorage.getItem(conferenceID))
27 30
             this.confSettings = {};
@@ -33,11 +36,21 @@ function Settings(conferenceID) {
33 36
                 this.confSettings.jitsiMeetId);
34 37
             this.save();
35 38
         }
39
+        if (!this.confSettings.callStatsUserName) {
40
+            this.confSettings.callStatsUserName
41
+                = UsernameGenerator.generateUsername();
42
+            logger.log('generated callstats uid',
43
+                this.confSettings.callStatsUserName);
44
+            this.save();
45
+        }
46
+
36 47
         this.userId = this.confSettings.jitsiMeetId || '';
37 48
         this.displayName = this.confSettings.displayname || '';
49
+        this.callStatsUserName = this.confSettings.callStatsUserName || '';
38 50
     } else {
39 51
         logger.log("local storage is not supported");
40 52
         this.userId = generateUniqueId();
53
+        this.callStatsUserName = UsernameGenerator.generateUsername();
41 54
     }
42 55
 }
43 56
 
@@ -52,12 +65,21 @@ Settings.prototype.setDisplayName = function (newDisplayName) {
52 65
         this.confSettings.displayname = displayName;
53 66
     this.save();
54 67
     return this.displayName;
55
-},
68
+}
69
+
56 70
 Settings.prototype.getSettings = function () {
57 71
     return {
58 72
         displayName: this.displayName,
59 73
         uid: this.userId
60 74
     };
61
-},
75
+}
76
+
77
+/**
78
+ * Returns fake username for callstats
79
+ * @returns {string} fake username for callstats
80
+ */
81
+Settings.prototype.getCallStatsUserName = function () {
82
+    return this.callStatsUserName;
83
+}
62 84
 
63 85
 module.exports = Settings;

+ 227
- 49
modules/statistics/CallStats.js View File

@@ -1,79 +1,257 @@
1
-/* global config, $, APP, Strophe, callstats */
1
+/* global $, Strophe, callstats */
2 2
 var logger = require("jitsi-meet-logger").getLogger(__filename);
3 3
 
4 4
 var jsSHA = require('jssha');
5 5
 var io = require('socket.io-client');
6
+
7
+/**
8
+ * @const
9
+ * @see http://www.callstats.io/api/#enumeration-of-wrtcfuncnames
10
+ */
11
+var wrtcFuncNames = {
12
+    createOffer:          "createOffer",
13
+    createAnswer:         "createAnswer",
14
+    setLocalDescription:  "setLocalDescription",
15
+    setRemoteDescription: "setRemoteDescription",
16
+    addIceCandidate:      "addIceCandidate",
17
+    getUserMedia:         "getUserMedia"
18
+};
19
+
6 20
 var callStats = null;
7 21
 
8 22
 function initCallback (err, msg) {
9
-    logger.log("Initializing Status: err="+err+" msg="+msg);
23
+    logger.log("CallStats Status: err=" + err + " msg=" + msg);
10 24
 }
11 25
 
12
-var CallStats = {
13
-    init: function (jingleSession) {
26
+/**
27
+ * Returns a function which invokes f in a try/catch block, logs any exception
28
+ * to the console, and then swallows it.
29
+ *
30
+ * @param f the function to invoke in a try/catch block
31
+ * @return a function which invokes f in a try/catch block, logs any exception
32
+ * to the console, and then swallows it
33
+ */
34
+function _try_catch (f) {
35
+    return function () {
36
+        try {
37
+            f.apply(this, arguments);
38
+        } catch (e) {
39
+            logger.error(e);
40
+        }
41
+    };
42
+}
14 43
 
15
-        if(!config.callStatsID || !config.callStatsSecret || callStats !== null)
44
+/**
45
+ * Creates new CallStats instance that handles all callstats API calls.
46
+ * @param peerConnection {JingleSessionPC} the session object
47
+ * @param Settings {Settings} the settings instance. Declared in
48
+ * /modules/settings/Settings.js
49
+ * @param options {object} credentials for callstats.
50
+ */
51
+var CallStats = _try_catch(function(jingleSession, Settings, options) {
52
+    try{
53
+        //check weather that should work with more than 1 peerconnection
54
+        if(!callStats) {
55
+            callStats = new callstats($, io, jsSHA);
56
+        } else {
16 57
             return;
17
-
18
-        callStats = new callstats($, io, jsSHA);
58
+        }
19 59
 
20 60
         this.session = jingleSession;
21 61
         this.peerconnection = jingleSession.peerconnection.peerconnection;
22 62
 
23
-        this.userID =  APP.xmpp.myResource();
63
+        this.userID = Settings.getCallStatsUserName();
24 64
 
65
+    //FIXME:  change it to something else (maybe roomName)
25 66
         var location = window.location;
26 67
         this.confID = location.hostname + location.pathname;
27 68
 
28 69
         //userID is generated or given by the origin server
29
-        callStats.initialize(config.callStatsID,
30
-            config.callStatsSecret,
70
+        callStats.initialize(options.callStatsID,
71
+            options.callStatsSecret,
31 72
             this.userID,
32 73
             initCallback);
33 74
 
34
-        var usage = callStats.fabricUsage.multiplex;
35
-
36 75
         callStats.addNewFabric(this.peerconnection,
37 76
             Strophe.getResourceFromJid(jingleSession.peerjid),
38
-            usage,
77
+            callStats.fabricUsage.multiplex,
39 78
             this.confID,
40 79
             this.pcCallback.bind(this));
41
-    },
42
-    pcCallback: function (err, msg) {
43
-        if (!callStats)
44
-            return;
45
-        logger.log("Monitoring status: "+ err + " msg: " + msg);
46
-        callStats.sendFabricEvent(this.peerconnection,
47
-            callStats.fabricEvent.fabricSetup, this.confID);
48
-    },
49
-    sendMuteEvent: function (mute, type) {
50
-        if (!callStats)
51
-            return;
52
-        var event = null;
53
-        if (type === "video") {
54
-            event = (mute? callStats.fabricEvent.videoPause :
55
-                callStats.fabricEvent.videoResume);
56
-        }
57
-        else {
58
-            event = (mute? callStats.fabricEvent.audioMute :
59
-                callStats.fabricEvent.audioUnmute);
60
-        }
61
-        callStats.sendFabricEvent(this.peerconnection, event, this.confID);
62
-    },
63
-    sendTerminateEvent: function () {
64
-        if(!callStats) {
65
-            return;
66
-        }
67
-        callStats.sendFabricEvent(this.peerconnection,
68
-            callStats.fabricEvent.fabricTerminated, this.confID);
69
-    },
70
-    sendSetupFailedEvent: function () {
71
-        if(!callStats) {
72
-            return;
73
-        }
74
-        callStats.sendFabricEvent(this.peerconnection,
75
-            callStats.fabricEvent.fabricSetupFailed, this.confID);
80
+    } catch (e) {
81
+        // The callstats.io API failed to initialize (e.g. because its
82
+        // download failed to succeed in general or on time). Further
83
+        // attempts to utilize it cannot possibly succeed.
84
+        callStats = null;
85
+        logger.error(e);
86
+    }
87
+    // notify callstats about failures if there were any
88
+    if (CallStats.pendingErrors.length) {
89
+        CallStats.pendingErrors.forEach(function (error) {
90
+            CallStats._reportError.call(this, error.type, error.error,
91
+                error.pc);
92
+        }, this);
93
+        CallStats.pendingErrors.length = 0;
76 94
     }
95
+});
77 96
 
97
+// some errors may happen before CallStats init
98
+// in this case we accumulate them in this array
99
+// and send them to callstats on init
100
+CallStats.pendingErrors = [];
101
+
102
+CallStats.prototype.pcCallback = _try_catch(function (err, msg) {
103
+    if (!callStats) {
104
+        return;
105
+    }
106
+    logger.log("Monitoring status: "+ err + " msg: " + msg);
107
+    callStats.sendFabricEvent(this.peerconnection,
108
+        callStats.fabricEvent.fabricSetup, this.confID);
109
+});
110
+
111
+/**
112
+ * Notifies CallStats for mute events
113
+ * @param mute {boolean} true for muted and false for not muted
114
+ * @param type {String} "audio"/"video"
115
+ */
116
+CallStats.prototype.sendMuteEvent = _try_catch(function (mute, type) {
117
+    if (!callStats) {
118
+        return;
119
+    }
120
+    var event = null;
121
+    if (type === "video") {
122
+        event = (mute? callStats.fabricEvent.videoPause :
123
+            callStats.fabricEvent.videoResume);
124
+    }
125
+    else {
126
+        event = (mute? callStats.fabricEvent.audioMute :
127
+            callStats.fabricEvent.audioUnmute);
128
+    }
129
+    callStats.sendFabricEvent(this.peerconnection, event, this.confID);
130
+});
131
+
132
+/**
133
+ * Notifies CallStats for connection setup errors
134
+ */
135
+CallStats.prototype.sendTerminateEvent = _try_catch(function () {
136
+    if(!callStats) {
137
+        return;
138
+    }
139
+    callStats.sendFabricEvent(this.peerconnection,
140
+        callStats.fabricEvent.fabricTerminated, this.confID);
141
+});
142
+
143
+/**
144
+ * Notifies CallStats for connection setup errors
145
+ */
146
+CallStats.prototype.sendSetupFailedEvent = _try_catch(function () {
147
+    if(!callStats) {
148
+        return;
149
+    }
150
+    callStats.sendFabricEvent(this.peerconnection,
151
+        callStats.fabricEvent.fabricSetupFailed, this.confID);
152
+});
153
+
154
+/**
155
+ * Sends the given feedback through CallStats.
156
+ *
157
+ * @param overallFeedback an integer between 1 and 5 indicating the
158
+ * user feedback
159
+ * @param detailedFeedback detailed feedback from the user. Not yet used
160
+ */
161
+CallStats.prototype.sendFeedback = _try_catch(
162
+function(overallFeedback, detailedFeedback) {
163
+    if(!callStats) {
164
+        return;
165
+    }
166
+    var feedbackString =    '{"userID":"' + this.userID + '"' +
167
+                            ', "overall":' + overallFeedback +
168
+                            ', "comment": "' + detailedFeedback + '"}';
169
+
170
+    var feedbackJSON = JSON.parse(feedbackString);
171
+
172
+    callStats.sendUserFeedback(this.confID, feedbackJSON);
173
+});
174
+
175
+/**
176
+ * Reports an error to callstats.
177
+ *
178
+ * @param type the type of the error, which will be one of the wrtcFuncNames
179
+ * @param e the error
180
+ * @param pc the peerconnection
181
+ * @private
182
+ */
183
+CallStats._reportError = function (type, e, pc) {
184
+    if (callStats) {
185
+        callStats.reportError(pc, this.confID, type, e);
186
+    } else {
187
+        CallStats.pendingErrors.push({ type: type, error: e, pc: pc});
188
+    }
189
+    // else just ignore it
78 190
 };
79
-module.exports = CallStats;
191
+
192
+/**
193
+ * Notifies CallStats that getUserMedia failed.
194
+ *
195
+ * @param {Error} e error to send
196
+ * @param {CallStats} cs callstats instance related to the error (optional)
197
+ */
198
+CallStats.sendGetUserMediaFailed = _try_catch(function (e, cs) {
199
+    CallStats._reportError.call(cs, wrtcFuncNames.getUserMedia, e, null);
200
+});
201
+
202
+/**
203
+ * Notifies CallStats that peer connection failed to create offer.
204
+ *
205
+ * @param {Error} e error to send
206
+ * @param {RTCPeerConnection} pc connection on which failure occured.
207
+ * @param {CallStats} cs callstats instance related to the error (optional)
208
+ */
209
+CallStats.sendCreateOfferFailed = _try_catch(function (e, pc, cs) {
210
+    CallStats._reportError.call(cs, wrtcFuncNames.createOffer, e, pc);
211
+});
212
+
213
+/**
214
+ * Notifies CallStats that peer connection failed to create answer.
215
+ *
216
+ * @param {Error} e error to send
217
+ * @param {RTCPeerConnection} pc connection on which failure occured.
218
+ * @param {CallStats} cs callstats instance related to the error (optional)
219
+ */
220
+CallStats.sendCreateAnswerFailed = _try_catch(function (e, pc, cs) {
221
+    CallStats._reportError.call(cs, wrtcFuncNames.createAnswer, e, pc);
222
+});
223
+
224
+/**
225
+ * Notifies CallStats that peer connection failed to set local description.
226
+ *
227
+ * @param {Error} e error to send
228
+ * @param {RTCPeerConnection} pc connection on which failure occured.
229
+ * @param {CallStats} cs callstats instance related to the error (optional)
230
+ */
231
+CallStats.sendSetLocalDescFailed = _try_catch(function (e, pc, cs) {
232
+    CallStats._reportError.call(cs, wrtcFuncNames.setLocalDescription, e, pc);
233
+});
234
+
235
+/**
236
+ * Notifies CallStats that peer connection failed to set remote description.
237
+ *
238
+ * @param {Error} e error to send
239
+ * @param {RTCPeerConnection} pc connection on which failure occured.
240
+ * @param {CallStats} cs callstats instance related to the error (optional)
241
+ */
242
+CallStats.sendSetRemoteDescFailed = _try_catch(function (e, pc, cs) {
243
+    CallStats._reportError.call(cs, wrtcFuncNames.setRemoteDescription, e, pc);
244
+});
245
+
246
+/**
247
+ * Notifies CallStats that peer connection failed to add ICE candidate.
248
+ *
249
+ * @param {Error} e error to send
250
+ * @param {RTCPeerConnection} pc connection on which failure occured.
251
+ * @param {CallStats} cs callstats instance related to the error (optional)
252
+ */
253
+CallStats.sendAddIceCandidateFailed = _try_catch(function (e, pc, cs) {
254
+    CallStats._reportError.call(cs, wrtcFuncNames.addIceCandidate, e, pc);
255
+});
256
+
257
+module.exports = CallStats;

+ 194
- 85
modules/statistics/statistics.js View File

@@ -3,29 +3,51 @@ var LocalStats = require("./LocalStatsCollector.js");
3 3
 var RTPStats = require("./RTPStatsCollector.js");
4 4
 var EventEmitter = require("events");
5 5
 var StatisticsEvents = require("../../service/statistics/Events");
6
-//var StreamEventTypes = require("../../service/RTC/StreamEventTypes.js");
7
-//var XMPPEvents = require("../../service/xmpp/XMPPEvents");
8
-//var CallStats = require("./CallStats");
9
-//var RTCEvents = require("../../service/RTC/RTCEvents");
10
-
11
-//
12
-//function onDisposeConference(onUnload) {
13
-//    CallStats.sendTerminateEvent();
14
-//    stopRemote();
15
-//    if(onUnload) {
16
-//        stopLocal();
17
-//        eventEmitter.removeAllListeners();
18
-//    }
19
-//}
6
+var CallStats = require("./CallStats");
7
+
8
+// Since callstats.io is a third party, we cannot guarantee the quality of
9
+// their service. More specifically, their server may take noticeably long
10
+// time to respond. Consequently, it is in our best interest (in the sense
11
+// that the intergration of callstats.io is pretty important to us but not
12
+// enough to allow it to prevent people from joining a conference) to (1)
13
+// start downloading their API as soon as possible and (2) do the
14
+// downloading asynchronously.
15
+function loadCallStatsAPI() {
16
+    (function (d, src) {
17
+        var elementName = 'script';
18
+        var newScript = d.createElement(elementName);
19
+        var referenceNode = d.getElementsByTagName(elementName)[0];
20
+
21
+        newScript.async = true;
22
+        newScript.src = src;
23
+        referenceNode.parentNode.insertBefore(newScript, referenceNode);
24
+    })(document, 'https://api.callstats.io/static/callstats.min.js');
25
+    // FIXME At the time of this writing, we hope that the callstats.io API will
26
+    // have loaded by the time we needed it (i.e. CallStats.init is invoked).
27
+}
20 28
 
21 29
 var eventEmitter = new EventEmitter();
22 30
 
23
-function Statistics() {
31
+function Statistics(options) {
24 32
     this.rtpStats = null;
25 33
     this.eventEmitter = new EventEmitter();
34
+    this.options = options || {};
35
+    this.callStatsIntegrationEnabled
36
+        = this.options.callStatsID && this.options.callStatsSecret
37
+        // Even though AppID and AppSecret may be specified, the integration of
38
+        // callstats.io may be disabled because of globally-disallowed requests
39
+        // to any third parties.
40
+        && (this.options.disableThirdPartyRequests !== true);
41
+    if(this.callStatsIntegrationEnabled)
42
+        loadCallStatsAPI();
43
+    this.audioLevelsEnabled = !this.disableAudioLevels || true;
44
+    this.callStats = null;
26 45
 }
27 46
 
28 47
 Statistics.prototype.startRemoteStats = function (peerconnection) {
48
+    if(!this.audioLevelsEnabled)
49
+        return;
50
+
29 51
     if (this.rtpStats) {
30 52
         this.rtpStats.stop();
31 53
     }
@@ -37,6 +59,8 @@ Statistics.prototype.startRemoteStats = function (peerconnection) {
37 59
 Statistics.localStats = [];
38 60
 
39 61
 Statistics.startLocalStats = function (stream, callback) {
62
+    if(!this.audioLevelsEnabled)
63
+        return;
40 64
     var localStats = new LocalStats(stream, 200, callback);
41 65
     this.localStats.push(localStats);
42 66
     localStats.start();
@@ -44,32 +68,50 @@ Statistics.startLocalStats = function (stream, callback) {
44 68
 
45 69
 Statistics.prototype.addAudioLevelListener = function(listener)
46 70
 {
71
+    if(!this.audioLevelsEnabled)
72
+        return;
47 73
     this.eventEmitter.on(StatisticsEvents.AUDIO_LEVEL, listener);
48 74
 }
49 75
 
50 76
 Statistics.prototype.removeAudioLevelListener = function(listener)
51 77
 {
78
+    if(!this.audioLevelsEnabled)
79
+        return;
52 80
     this.eventEmitter.removeListener(StatisticsEvents.AUDIO_LEVEL, listener);
53 81
 }
54 82
 
55 83
 Statistics.prototype.dispose = function () {
56
-    Statistics.stopAllLocalStats();
57
-    this.stopRemote();
58
-    if(this.eventEmitter)
59
-        this.eventEmitter.removeAllListeners();
84
+    if(this.audioLevelsEnabled) {
85
+        Statistics.stopAllLocalStats();
86
+        this.stopRemote();
87
+        if(this.eventEmitter)
88
+            this.eventEmitter.removeAllListeners();
60 89
 
61
-    if(eventEmitter)
62
-        eventEmitter.removeAllListeners();
90
+        if(eventEmitter)
91
+            eventEmitter.removeAllListeners();
92
+    }
93
+
94
+    if(this.callstats)
95
+    {
96
+        this.callstats.sendTerminateEvent();
97
+        this.callstats = null;
98
+    }
63 99
 }
64 100
 
65 101
 
66 102
 Statistics.stopAllLocalStats = function () {
103
+    if(!this.audioLevelsEnabled)
104
+        return;
105
+
67 106
     for(var i = 0; i < this.localStats.length; i++)
68 107
         this.localStats[i].stop();
69 108
     this.localStats = [];
70 109
 }
71 110
 
72 111
 Statistics.stopLocalStats = function (stream) {
112
+    if(!this.audioLevelsEnabled)
113
+        return;
114
+
73 115
     for(var i = 0; i < Statistics.localStats.length; i++)
74 116
         if(Statistics.localStats[i].stream === stream){
75 117
             var localStats = Statistics.localStats.splice(i, 1);
@@ -79,7 +121,7 @@ Statistics.stopLocalStats = function (stream) {
79 121
 }
80 122
 
81 123
 Statistics.prototype.stopRemote = function () {
82
-    if (this.rtpStats) {
124
+    if (this.rtpStats && this.audioLevelsEnabled) {
83 125
         this.rtpStats.stop();
84 126
         this.eventEmitter.emit(StatisticsEvents.STOP);
85 127
         this.rtpStats = null;
@@ -97,77 +139,144 @@ Statistics.prototype.stopRemote = function () {
97 139
  *              at this time.
98 140
  */
99 141
 Statistics.prototype.getPeerSSRCAudioLevel = function (peerJid, ssrc) {
100
-
142
+    if(!this.audioLevelsEnabled)
143
+        return;
101 144
     var peerStats = this.rtpStats.jid2stats[peerJid];
102 145
 
103 146
     return peerStats ? peerStats.ssrc2AudioLevel[ssrc] : null;
104 147
 };
105 148
 
106
-Statistics.LOCAL_JID = require("../../service/statistics/constants").LOCAL_JID;
107 149
 
108
-//
109
-//var statistics = {
110
-//    /**
111
-//     * Indicates that this audio level is for local jid.
112
-//     * @type {string}
113
-//     */
114
-//    LOCAL_JID: 'local',
115
-//
116
-//    addConnectionStatsListener: function(listener)
117
-//    {
118
-//        eventEmitter.on("statistics.connectionstats", listener);
119
-//    },
120
-//
121
-//    removeConnectionStatsListener: function(listener)
122
-//    {
123
-//        eventEmitter.removeListener("statistics.connectionstats", listener);
124
-//    },
125
-//
126
-//
127
-//    addRemoteStatsStopListener: function(listener)
128
-//    {
129
-//        eventEmitter.on("statistics.stop", listener);
130
-//    },
131
-//
132
-//    removeRemoteStatsStopListener: function(listener)
133
-//    {
134
-//        eventEmitter.removeListener("statistics.stop", listener);
135
-//    },
136
-//
137
-//
138
-//    stopRemoteStatistics: function()
139
-//    {
140
-//        stopRemote();
141
-//    },
142
-//
143
-////    Already implemented with the constructor
144
-//    start: function () {
145
-//        APP.RTC.addStreamListener(onStreamCreated,
146
-//            StreamEventTypes.EVENT_TYPE_LOCAL_CREATED);
147
-//        APP.xmpp.addListener(XMPPEvents.DISPOSE_CONFERENCE, onDisposeConference);
148
-//        //FIXME: we may want to change CALL INCOMING event to onnegotiationneeded
149
-//        APP.xmpp.addListener(XMPPEvents.CALL_INCOMING, function (event) {
150
-//            startRemoteStats(event.peerconnection);
151
-////            CallStats.init(event);
152
-//        });
153
-////        APP.xmpp.addListener(XMPPEvents.PEERCONNECTION_READY, function (session) {
154
-////            CallStats.init(session);
155
-////        });
156
-//        //FIXME: that event is changed to TRACK_MUTE_CHANGED
157
-////        APP.RTC.addListener(RTCEvents.AUDIO_MUTE, function (mute) {
158
-////            CallStats.sendMuteEvent(mute, "audio");
159
-////        });
160
-////        APP.xmpp.addListener(XMPPEvents.CONFERENCE_SETUP_FAILED, function () {
161
-////            CallStats.sendSetupFailedEvent();
162
-////        });
163
-//        //FIXME: that event is changed to TRACK_MUTE_CHANGED
164
-////        APP.RTC.addListener(RTCEvents.VIDEO_MUTE, function (mute) {
165
-////            CallStats.sendMuteEvent(mute, "video");
166
-////        });
167
-//    }
168
-//};
150
+//CALSTATS METHODS
151
+
152
+/**
153
+ * Initializes the callstats.io API.
154
+ * @param peerConnection {JingleSessionPC} the session object
155
+ * @param Settings {Settings} the settings instance. Declared in
156
+ * /modules/settings/Settings.js
157
+ */
158
+Statistics.prototype.startCallStats = function (session, settings) {
159
+    if(this.callStatsIntegrationEnabled) {
160
+        this.callstats = new CallStats(session, settings, this.options);
161
+    }
162
+}
163
+
164
+/**
165
+ * Returns true if the callstats integration is enabled, otherwise returns
166
+ * false.
167
+ *
168
+ * @returns true if the callstats integration is enabled, otherwise returns
169
+ * false.
170
+ */
171
+Statistics.prototype.isCallstatsEnabled = function () {
172
+    return this.callStatsIntegrationEnabled;
173
+}
174
+
175
+/**
176
+ * Notifies CallStats for connection setup errors
177
+ */
178
+Statistics.prototype.sendSetupFailedEvent = function () {
179
+    if(this.callStatsIntegrationEnabled && this.callstats)
180
+        this.callstats.sendSetupFailedEvent();
181
+}
182
+
183
+/**
184
+ * Notifies CallStats for mute events
185
+ * @param mute {boolean} true for muted and false for not muted
186
+ * @param type {String} "audio"/"video"
187
+ */
188
+Statistics.prototype.sendMuteEvent = function (muted, type) {
189
+    if(this.callStatsIntegrationEnabled && this.callstats)
190
+        this.callstats.sendMuteEvent(muted, type);
191
+}
192
+
193
+/**
194
+ * Notifies CallStats that getUserMedia failed.
195
+ *
196
+ * @param {Error} e error to send
197
+ */
198
+Statistics.prototype.sendGetUserMediaFailed = function (e) {
199
+    if(this.callStatsIntegrationEnabled)
200
+        CallStats.sendGetUserMediaFailed(e, this.callstats);
201
+};
202
+
203
+/**
204
+ * Notifies CallStats that getUserMedia failed.
205
+ *
206
+ * @param {Error} e error to send
207
+ */
208
+Statistics.sendGetUserMediaFailed = function (e) {
209
+    CallStats.sendGetUserMediaFailed(e, null);
210
+};
211
+
212
+/**
213
+ * Notifies CallStats that peer connection failed to create offer.
214
+ *
215
+ * @param {Error} e error to send
216
+ * @param {RTCPeerConnection} pc connection on which failure occured.
217
+ */
218
+Statistics.prototype.sendCreateOfferFailed = function (e, pc) {
219
+    if(this.callStatsIntegrationEnabled)
220
+        CallStats.sendCreateOfferFailed(e, pc, this.callstats);
221
+};
222
+
223
+/**
224
+ * Notifies CallStats that peer connection failed to create answer.
225
+ *
226
+ * @param {Error} e error to send
227
+ * @param {RTCPeerConnection} pc connection on which failure occured.
228
+ */
229
+Statistics.prototype.sendCreateAnswerFailed = function (e, pc) {
230
+    if(this.callStatsIntegrationEnabled)
231
+        CallStats.sendCreateAnswerFailed(e, pc, this.callstats);
232
+};
169 233
 
234
+/**
235
+ * Notifies CallStats that peer connection failed to set local description.
236
+ *
237
+ * @param {Error} e error to send
238
+ * @param {RTCPeerConnection} pc connection on which failure occured.
239
+ */
240
+Statistics.prototype.sendSetLocalDescFailed = function (e, pc) {
241
+    if(this.callStatsIntegrationEnabled)
242
+        CallStats.sendSetLocalDescFailed(e, pc, this.callstats);
243
+}
170 244
 
245
+/**
246
+ * Notifies CallStats that peer connection failed to set remote description.
247
+ *
248
+ * @param {Error} e error to send
249
+ * @param {RTCPeerConnection} pc connection on which failure occured.
250
+ */
251
+Statistics.prototype.sendSetRemoteDescFailed = function (e, pc) {
252
+    if(this.callStatsIntegrationEnabled)
253
+        CallStats.sendSetRemoteDescFailed(e, pc, this.callstats);
254
+}
171 255
 
256
+/**
257
+ * Notifies CallStats that peer connection failed to add ICE candidate.
258
+ *
259
+ * @param {Error} e error to send
260
+ * @param {RTCPeerConnection} pc connection on which failure occured.
261
+ */
262
+Statistics.prototype.sendAddIceCandidateFailed = function (e, pc) {
263
+    if(this.callStatsIntegrationEnabled)
264
+        CallStats.sendAddIceCandidateFailed(e, pc, this.callstats);
265
+}
266
+
267
+/**
268
+ * Sends the given feedback through CallStats.
269
+ *
270
+ * @param overallFeedback an integer between 1 and 5 indicating the
271
+ * user feedback
272
+ * @param detailedFeedback detailed feedback from the user. Not yet used
273
+ */
274
+Statistics.prototype.sendFeedback =
275
+function(overallFeedback, detailedFeedback){
276
+    if(this.callStatsIntegrationEnabled && this.callstats)
277
+        this.callstats.sendFeedback(overallFeedback, detailedFeedback);
278
+}
279
+
280
+Statistics.LOCAL_JID = require("../../service/statistics/constants").LOCAL_JID;
172 281
 
173 282
 module.exports = Statistics;

+ 429
- 0
modules/util/UsernameGenerator.js View File

@@ -0,0 +1,429 @@
1
+var RandomUtil = require('./RandomUtil');
2
+
3
+/**
4
+ * from faker.js - Copyright (c) 2014-2015 Matthew Bergman & Marak Squires
5
+ * MIT License
6
+ * http://github.com/marak/faker.js/
7
+ *
8
+ * @const
9
+ */
10
+var names = [
11
+  "Aaliyah", "Aaron", "Abagail", "Abbey", "Abbie", "Abbigail",
12
+  "Abby", "Abdiel", "Abdul", "Abdullah", "Abe", "Abel", "Abelardo", "Abigail",
13
+  "Abigale", "Abigayle", "Abner", "Abraham", "Ada", "Adah", "Adalberto",
14
+  "Adaline", "Adam", "Adan", "Addie", "Addison", "Adela", "Adelbert", "Adele",
15
+  "Adelia", "Adeline", "Adell", "Adella", "Adelle", "Aditya", "Adolf", "Adolfo",
16
+  "Adolph", "Adolphus", "Adonis", "Adrain", "Adrian", "Adriana", "Adrianna",
17
+  "Adriel", "Adrien", "Adrienne", "Afton", "Aglae", "Agnes", "Agustin",
18
+  "Agustina", "Ahmad", "Ahmed", "Aida", "Aidan", "Aiden", "Aileen", "Aimee",
19
+  "Aisha", "Aiyana", "Akeem", "Al", "Alaina", "Alan", "Alana", "Alanis",
20
+  "Alanna", "Alayna", "Alba", "Albert", "Alberta", "Albertha", "Alberto",
21
+  "Albin", "Albina", "Alda", "Alden", "Alec", "Aleen", "Alejandra",
22
+  "Alejandrin", "Alek", "Alena", "Alene", "Alessandra", "Alessandro", "Alessia",
23
+  "Aletha", "Alex", "Alexa", "Alexander", "Alexandra", "Alexandre",
24
+  "Alexandrea", "Alexandria", "Alexandrine", "Alexandro", "Alexane", "Alexanne",
25
+  "Alexie", "Alexis", "Alexys", "Alexzander", "Alf", "Alfonso", "Alfonzo",
26
+  "Alford", "Alfred", "Alfreda", "Alfredo", "Ali", "Alia", "Alice", "Alicia",
27
+  "Alisa", "Alisha", "Alison", "Alivia", "Aliya", "Aliyah", "Aliza", "Alize",
28
+  "Allan", "Allen", "Allene", "Allie", "Allison", "Ally", "Alphonso", "Alta",
29
+  "Althea", "Alva", "Alvah", "Alvena", "Alvera", "Alverta", "Alvina", "Alvis",
30
+  "Alyce", "Alycia", "Alysa", "Alysha", "Alyson", "Alysson", "Amalia", "Amanda",
31
+  "Amani", "Amara", "Amari", "Amaya", "Amber", "Ambrose", "Amelia", "Amelie",
32
+  "Amely", "America", "Americo", "Amie", "Amina", "Amir", "Amira", "Amiya",
33
+  "Amos", "Amparo", "Amy", "Amya", "Ana", "Anabel", "Anabelle", "Anahi",
34
+  "Anais", "Anastacio", "Anastasia", "Anderson", "Andre", "Andreane",
35
+  "Andreanne", "Andres", "Andrew", "Andy", "Angel", "Angela", "Angelica",
36
+  "Angelina", "Angeline", "Angelita", "Angelo", "Angie", "Angus", "Anibal",
37
+  "Anika", "Anissa", "Anita", "Aniya", "Aniyah", "Anjali", "Anna", "Annabel",
38
+  "Annabell", "Annabelle", "Annalise", "Annamae", "Annamarie", "Anne",
39
+  "Annetta", "Annette", "Annie", "Ansel", "Ansley", "Anthony", "Antoinette",
40
+  "Antone", "Antonetta", "Antonette", "Antonia", "Antonietta", "Antonina",
41
+  "Antonio", "Antwan", "Antwon", "Anya", "April", "Ara", "Araceli", "Aracely",
42
+  "Arch", "Archibald", "Ardella", "Arden", "Ardith", "Arely", "Ari", "Ariane",
43
+  "Arianna", "Aric", "Ariel", "Arielle", "Arjun", "Arlene", "Arlie", "Arlo",
44
+  "Armand", "Armando", "Armani", "Arnaldo", "Arne", "Arno", "Arnold", "Arnoldo",
45
+  "Arnulfo", "Aron", "Art", "Arthur", "Arturo", "Arvel", "Arvid", "Arvilla",
46
+  "Aryanna", "Asa", "Asha", "Ashlee", "Ashleigh", "Ashley", "Ashly", "Ashlynn",
47
+  "Ashton", "Ashtyn", "Asia", "Assunta", "Astrid", "Athena", "Aubree", "Aubrey",
48
+  "Audie", "Audra", "Audreanne", "Audrey", "August", "Augusta", "Augustine",
49
+  "Augustus", "Aurelia", "Aurelie", "Aurelio", "Aurore", "Austen", "Austin",
50
+  "Austyn", "Autumn", "Ava", "Avery", "Avis", "Axel", "Ayana", "Ayden", "Ayla",
51
+  "Aylin", "Baby", "Bailee", "Bailey", "Barbara", "Barney", "Baron", "Barrett",
52
+  "Barry", "Bart", "Bartholome", "Barton", "Baylee", "Beatrice", "Beau",
53
+  "Beaulah", "Bell", "Bella", "Belle", "Ben", "Benedict", "Benjamin", "Bennett",
54
+  "Bennie", "Benny", "Benton", "Berenice", "Bernadette", "Bernadine", "Bernard",
55
+  "Bernardo", "Berneice", "Bernhard", "Bernice", "Bernie", "Berniece",
56
+  "Bernita", "Berry", "Bert", "Berta", "Bertha", "Bertram", "Bertrand", "Beryl",
57
+  "Bessie", "Beth", "Bethany", "Bethel", "Betsy", "Bette", "Bettie", "Betty",
58
+  "Bettye", "Beulah", "Beverly", "Bianka", "Bill", "Billie", "Billy", "Birdie",
59
+  "Blair", "Blaise", "Blake", "Blanca", "Blanche", "Blaze", "Bo", "Bobbie",
60
+  "Bobby", "Bonita", "Bonnie", "Boris", "Boyd", "Brad", "Braden", "Bradford",
61
+  "Bradley", "Bradly", "Brady", "Braeden", "Brain", "Brandi", "Brando",
62
+  "Brandon", "Brandt", "Brandy", "Brandyn", "Brannon", "Branson", "Brant",
63
+  "Braulio", "Braxton", "Brayan", "Breana", "Breanna", "Breanne", "Brenda",
64
+  "Brendan", "Brenden", "Brendon", "Brenna", "Brennan", "Brennon", "Brent",
65
+  "Bret", "Brett", "Bria", "Brian", "Briana", "Brianne", "Brice", "Bridget",
66
+  "Bridgette", "Bridie", "Brielle", "Brigitte", "Brionna", "Brisa", "Britney",
67
+  "Brittany", "Brock", "Broderick", "Brody", "Brook", "Brooke", "Brooklyn",
68
+  "Brooks", "Brown", "Bruce", "Bryana", "Bryce", "Brycen", "Bryon", "Buck",
69
+  "Bud", "Buddy", "Buford", "Bulah", "Burdette", "Burley", "Burnice", "Buster",
70
+  "Cade", "Caden", "Caesar", "Caitlyn", "Cale", "Caleb", "Caleigh", "Cali",
71
+  "Calista", "Callie", "Camden", "Cameron", "Camila", "Camilla", "Camille",
72
+  "Camren", "Camron", "Camryn", "Camylle", "Candace", "Candelario", "Candice",
73
+  "Candida", "Candido", "Cara", "Carey", "Carissa", "Carlee", "Carleton",
74
+  "Carley", "Carli", "Carlie", "Carlo", "Carlos", "Carlotta", "Carmel",
75
+  "Carmela", "Carmella", "Carmelo", "Carmen", "Carmine", "Carol", "Carolanne",
76
+  "Carole", "Carolina", "Caroline", "Carolyn", "Carolyne", "Carrie", "Carroll",
77
+  "Carson", "Carter", "Cary", "Casandra", "Casey", "Casimer", "Casimir",
78
+  "Casper", "Cassandra", "Cassandre", "Cassidy", "Cassie", "Catalina",
79
+  "Caterina", "Catharine", "Catherine", "Cathrine", "Cathryn", "Cathy", "Cayla",
80
+  "Ceasar", "Cecelia", "Cecil", "Cecile", "Cecilia", "Cedrick", "Celestine",
81
+  "Celestino", "Celia", "Celine", "Cesar", "Chad", "Chadd", "Chadrick", "Chaim",
82
+  "Chance", "Chandler", "Chanel", "Chanelle", "Charity", "Charlene", "Charles",
83
+  "Charley", "Charlie", "Charlotte", "Chase", "Chasity", "Chauncey", "Chaya",
84
+  "Chaz", "Chelsea", "Chelsey", "Chelsie", "Chesley", "Chester", "Chet",
85
+  "Cheyanne", "Cheyenne", "Chloe", "Chris", "Christ", "Christa", "Christelle",
86
+  "Christian", "Christiana", "Christina", "Christine", "Christop", "Christophe",
87
+  "Christopher", "Christy", "Chyna", "Ciara", "Cicero", "Cielo", "Cierra",
88
+  "Cindy", "Citlalli", "Clair", "Claire", "Clara", "Clarabelle", "Clare",
89
+  "Clarissa", "Clark", "Claud", "Claude", "Claudia", "Claudie", "Claudine",
90
+  "Clay", "Clemens", "Clement", "Clementina", "Clementine", "Clemmie", "Cleo",
91
+  "Cleora", "Cleta", "Cletus", "Cleve", "Cleveland", "Clifford", "Clifton",
92
+  "Clint", "Clinton", "Clotilde", "Clovis", "Cloyd", "Clyde", "Coby", "Cody",
93
+  "Colby", "Cole", "Coleman", "Colin", "Colleen", "Collin", "Colt", "Colten",
94
+  "Colton", "Columbus", "Concepcion", "Conner", "Connie", "Connor", "Conor",
95
+  "Conrad", "Constance", "Constantin", "Consuelo", "Cooper", "Cora", "Coralie",
96
+  "Corbin", "Cordelia", "Cordell", "Cordia", "Cordie", "Corene", "Corine",
97
+  "Cornelius", "Cornell", "Corrine", "Cortez", "Cortney", "Cory", "Coty",
98
+  "Courtney", "Coy", "Craig", "Crawford", "Creola", "Cristal", "Cristian",
99
+  "Cristina", "Cristobal", "Cristopher", "Cruz", "Crystal", "Crystel", "Cullen",
100
+  "Curt", "Curtis", "Cydney", "Cynthia", "Cyril", "Cyrus", "Dagmar", "Dahlia",
101
+  "Daija", "Daisha", "Daisy", "Dakota", "Dale", "Dallas", "Dallin", "Dalton",
102
+  "Damaris", "Dameon", "Damian", "Damien", "Damion", "Damon", "Dan", "Dana",
103
+  "Dandre", "Dane", "D'angelo", "Dangelo", "Danial", "Daniela", "Daniella",
104
+  "Danielle", "Danika", "Dannie", "Danny", "Dante", "Danyka", "Daphne",
105
+  "Daphnee", "Daphney", "Darby", "Daren", "Darian", "Dariana", "Darien",
106
+  "Dario", "Darion", "Darius", "Darlene", "Daron", "Darrel", "Darrell",
107
+  "Darren", "Darrick", "Darrin", "Darrion", "Darron", "Darryl", "Darwin",
108
+  "Daryl", "Dashawn", "Dasia", "Dave", "David", "Davin", "Davion", "Davon",
109
+  "Davonte", "Dawn", "Dawson", "Dax", "Dayana", "Dayna", "Dayne", "Dayton",
110
+  "Dean", "Deangelo", "Deanna", "Deborah", "Declan", "Dedric", "Dedrick", "Dee",
111
+  "Deion", "Deja", "Dejah", "Dejon", "Dejuan", "Delaney", "Delbert", "Delfina",
112
+  "Delia", "Delilah", "Dell", "Della", "Delmer", "Delores", "Delpha", "Delphia",
113
+  "Delphine", "Delta", "Demarco", "Demarcus", "Demario", "Demetris",
114
+  "Demetrius", "Demond", "Dena", "Denis", "Dennis", "Deon", "Deondre",
115
+  "Deontae", "Deonte", "Dereck", "Derek", "Derick", "Deron", "Derrick",
116
+  "Deshaun", "Deshawn", "Desiree", "Desmond", "Dessie", "Destany", "Destin",
117
+  "Destinee", "Destiney", "Destini", "Destiny", "Devan", "Devante", "Deven",
118
+  "Devin", "Devon", "Devonte", "Devyn", "Dewayne", "Dewitt", "Dexter",
119
+  "Diamond", "Diana", "Dianna", "Diego", "Dillan", "Dillon", "Dimitri", "Dina",
120
+  "Dino", "Dion", "Dixie", "Dock", "Dolly", "Dolores", "Domenic", "Domenica",
121
+  "Domenick", "Domenico", "Domingo", "Dominic", "Dominique", "Don", "Donald",
122
+  "Donato", "Donavon", "Donna", "Donnell", "Donnie", "Donny", "Dora", "Dorcas",
123
+  "Dorian", "Doris", "Dorothea", "Dorothy", "Dorris", "Dortha", "Dorthy",
124
+  "Doug", "Douglas", "Dovie", "Doyle", "Drake", "Drew", "Duane", "Dudley",
125
+  "Dulce", "Duncan", "Durward", "Dustin", "Dusty", "Dwight", "Dylan", "Earl",
126
+  "Earlene", "Earline", "Earnest", "Earnestine", "Easter", "Easton", "Ebba",
127
+  "Ebony", "Ed", "Eda", "Edd", "Eddie", "Eden", "Edgar", "Edgardo", "Edison",
128
+  "Edmond", "Edmund", "Edna", "Eduardo", "Edward", "Edwardo", "Edwin", "Edwina",
129
+  "Edyth", "Edythe", "Effie", "Efrain", "Efren", "Eileen", "Einar", "Eino",
130
+  "Eladio", "Elaina", "Elbert", "Elda", "Eldon", "Eldora", "Eldred", "Eldridge",
131
+  "Eleanora", "Eleanore", "Eleazar", "Electa", "Elena", "Elenor", "Elenora",
132
+  "Eleonore", "Elfrieda", "Eli", "Elian", "Eliane", "Elias", "Eliezer",
133
+  "Elijah", "Elinor", "Elinore", "Elisa", "Elisabeth", "Elise", "Eliseo",
134
+  "Elisha", "Elissa", "Eliza", "Elizabeth", "Ella", "Ellen", "Ellie", "Elliot",
135
+  "Elliott", "Ellis", "Ellsworth", "Elmer", "Elmira", "Elmo", "Elmore", "Elna",
136
+  "Elnora", "Elody", "Eloisa", "Eloise", "Elouise", "Eloy", "Elroy", "Elsa",
137
+  "Else", "Elsie", "Elta", "Elton", "Elva", "Elvera", "Elvie", "Elvis", "Elwin",
138
+  "Elwyn", "Elyse", "Elyssa", "Elza", "Emanuel", "Emelia", "Emelie", "Emely",
139
+  "Emerald", "Emerson", "Emery", "Emie", "Emil", "Emile", "Emilia", "Emiliano",
140
+  "Emilie", "Emilio", "Emily", "Emma", "Emmalee", "Emmanuel", "Emmanuelle",
141
+  "Emmet", "Emmett", "Emmie", "Emmitt", "Emmy", "Emory", "Ena", "Enid", "Enoch",
142
+  "Enola", "Enos", "Enrico", "Enrique", "Ephraim", "Era", "Eriberto", "Eric",
143
+  "Erica", "Erich", "Erick", "Ericka", "Erik", "Erika", "Erin", "Erling",
144
+  "Erna", "Ernest", "Ernestina", "Ernestine", "Ernesto", "Ernie", "Ervin",
145
+  "Erwin", "Eryn", "Esmeralda", "Esperanza", "Esta", "Esteban", "Estefania",
146
+  "Estel", "Estell", "Estella", "Estelle", "Estevan", "Esther", "Estrella",
147
+  "Etha", "Ethan", "Ethel", "Ethelyn", "Ethyl", "Ettie", "Eudora", "Eugene",
148
+  "Eugenia", "Eula", "Eulah", "Eulalia", "Euna", "Eunice", "Eusebio", "Eva",
149
+  "Evalyn", "Evan", "Evangeline", "Evans", "Eve", "Eveline", "Evelyn",
150
+  "Everardo", "Everett", "Everette", "Evert", "Evie", "Ewald", "Ewell",
151
+  "Ezekiel", "Ezequiel", "Ezra", "Fabian", "Fabiola", "Fae", "Fannie", "Fanny",
152
+  "Fatima", "Faustino", "Fausto", "Favian", "Fay", "Faye", "Federico",
153
+  "Felicia", "Felicita", "Felicity", "Felipa", "Felipe", "Felix", "Felton",
154
+  "Fermin", "Fern", "Fernando", "Ferne", "Fidel", "Filiberto", "Filomena",
155
+  "Finn", "Fiona", "Flavie", "Flavio", "Fleta", "Fletcher", "Flo", "Florence",
156
+  "Florencio", "Florian", "Florida", "Florine", "Flossie", "Floy", "Floyd",
157
+  "Ford", "Forest", "Forrest", "Foster", "Frances", "Francesca", "Francesco",
158
+  "Francis", "Francisca", "Francisco", "Franco", "Frank", "Frankie", "Franz",
159
+  "Fred", "Freda", "Freddie", "Freddy", "Frederic", "Frederick", "Frederik",
160
+  "Frederique", "Fredrick", "Fredy", "Freeda", "Freeman", "Freida", "Frida",
161
+  "Frieda", "Friedrich", "Fritz", "Furman", "Gabe", "Gabriel", "Gabriella",
162
+  "Gabrielle", "Gaetano", "Gage", "Gail", "Gardner", "Garett", "Garfield",
163
+  "Garland", "Garnet", "Garnett", "Garret", "Garrett", "Garrick", "Garrison",
164
+  "Garry", "Garth", "Gaston", "Gavin", "Gay", "Gayle", "Gaylord", "Gene",
165
+  "General", "Genesis", "Genevieve", "Gennaro", "Genoveva", "Geo", "Geoffrey",
166
+  "George", "Georgette", "Georgiana", "Georgianna", "Geovanni", "Geovanny",
167
+  "Geovany", "Gerald", "Geraldine", "Gerard", "Gerardo", "Gerda", "Gerhard",
168
+  "Germaine", "German", "Gerry", "Gerson", "Gertrude", "Gia", "Gianni",
169
+  "Gideon", "Gilbert", "Gilberto", "Gilda", "Giles", "Gillian", "Gina", "Gino",
170
+  "Giovani", "Giovanna", "Giovanni", "Giovanny", "Gisselle", "Giuseppe",
171
+  "Gladyce", "Gladys", "Glen", "Glenda", "Glenna", "Glennie", "Gloria",
172
+  "Godfrey", "Golda", "Golden", "Gonzalo", "Gordon", "Grace", "Gracie",
173
+  "Graciela", "Grady", "Graham", "Grant", "Granville", "Grayce", "Grayson",
174
+  "Green", "Greg", "Gregg", "Gregoria", "Gregorio", "Gregory", "Greta",
175
+  "Gretchen", "Greyson", "Griffin", "Grover", "Guadalupe", "Gudrun", "Guido",
176
+  "Guillermo", "Guiseppe", "Gunnar", "Gunner", "Gus", "Gussie", "Gust",
177
+  "Gustave", "Guy", "Gwen", "Gwendolyn", "Hadley", "Hailee", "Hailey", "Hailie",
178
+  "Hal", "Haleigh", "Haley", "Halie", "Halle", "Hallie", "Hank", "Hanna",
179
+  "Hannah", "Hans", "Hardy", "Harley", "Harmon", "Harmony", "Harold",
180
+  "Harrison", "Harry", "Harvey", "Haskell", "Hassan", "Hassie", "Hattie",
181
+  "Haven", "Hayden", "Haylee", "Hayley", "Haylie", "Hazel", "Hazle", "Heath",
182
+  "Heather", "Heaven", "Heber", "Hector", "Heidi", "Helen", "Helena", "Helene",
183
+  "Helga", "Hellen", "Helmer", "Heloise", "Henderson", "Henri", "Henriette",
184
+  "Henry", "Herbert", "Herman", "Hermann", "Hermina", "Herminia", "Herminio",
185
+  "Hershel", "Herta", "Hertha", "Hester", "Hettie", "Hilario", "Hilbert",
186
+  "Hilda", "Hildegard", "Hillard", "Hillary", "Hilma", "Hilton", "Hipolito",
187
+  "Hiram", "Hobart", "Holden", "Hollie", "Hollis", "Holly", "Hope", "Horace",
188
+  "Horacio", "Hortense", "Hosea", "Houston", "Howard", "Howell", "Hoyt",
189
+  "Hubert", "Hudson", "Hugh", "Hulda", "Humberto", "Hunter", "Hyman", "Ian",
190
+  "Ibrahim", "Icie", "Ida", "Idell", "Idella", "Ignacio", "Ignatius", "Ike",
191
+  "Ila", "Ilene", "Iliana", "Ima", "Imani", "Imelda", "Immanuel", "Imogene",
192
+  "Ines", "Irma", "Irving", "Irwin", "Isaac", "Isabel", "Isabell", "Isabella",
193
+  "Isabelle", "Isac", "Isadore", "Isai", "Isaiah", "Isaias", "Isidro", "Ismael",
194
+  "Isobel", "Isom", "Israel", "Issac", "Itzel", "Iva", "Ivah", "Ivory", "Ivy",
195
+  "Izabella", "Izaiah", "Jabari", "Jace", "Jacey", "Jacinthe", "Jacinto",
196
+  "Jack", "Jackeline", "Jackie", "Jacklyn", "Jackson", "Jacky", "Jaclyn",
197
+  "Jacquelyn", "Jacques", "Jacynthe", "Jada", "Jade", "Jaden", "Jadon", "Jadyn",
198
+  "Jaeden", "Jaida", "Jaiden", "Jailyn", "Jaime", "Jairo", "Jakayla", "Jake",
199
+  "Jakob", "Jaleel", "Jalen", "Jalon", "Jalyn", "Jamaal", "Jamal", "Jamar",
200
+  "Jamarcus", "Jamel", "Jameson", "Jamey", "Jamie", "Jamil", "Jamir", "Jamison",
201
+  "Jammie", "Jan", "Jana", "Janae", "Jane", "Janelle", "Janessa", "Janet",
202
+  "Janice", "Janick", "Janie", "Janis", "Janiya", "Jannie", "Jany", "Jaquan",
203
+  "Jaquelin", "Jaqueline", "Jared", "Jaren", "Jarod", "Jaron", "Jarred",
204
+  "Jarrell", "Jarret", "Jarrett", "Jarrod", "Jarvis", "Jasen", "Jasmin",
205
+  "Jason", "Jasper", "Jaunita", "Javier", "Javon", "Javonte", "Jay", "Jayce",
206
+  "Jaycee", "Jayda", "Jayde", "Jayden", "Jaydon", "Jaylan", "Jaylen", "Jaylin",
207
+  "Jaylon", "Jayme", "Jayne", "Jayson", "Jazlyn", "Jazmin", "Jazmyn", "Jazmyne",
208
+  "Jean", "Jeanette", "Jeanie", "Jeanne", "Jed", "Jedediah", "Jedidiah", "Jeff",
209
+  "Jefferey", "Jeffery", "Jeffrey", "Jeffry", "Jena", "Jenifer", "Jennie",
210
+  "Jennifer", "Jennings", "Jennyfer", "Jensen", "Jerad", "Jerald", "Jeramie",
211
+  "Jeramy", "Jerel", "Jeremie", "Jeremy", "Jermain", "Jermaine", "Jermey",
212
+  "Jerod", "Jerome", "Jeromy", "Jerrell", "Jerrod", "Jerrold", "Jerry", "Jess",
213
+  "Jesse", "Jessica", "Jessie", "Jessika", "Jessy", "Jessyca", "Jesus", "Jett",
214
+  "Jettie", "Jevon", "Jewel", "Jewell", "Jillian", "Jimmie", "Jimmy", "Jo",
215
+  "Joan", "Joana", "Joanie", "Joanne", "Joannie", "Joanny", "Joany", "Joaquin",
216
+  "Jocelyn", "Jodie", "Jody", "Joe", "Joel", "Joelle", "Joesph", "Joey",
217
+  "Johan", "Johann", "Johanna", "Johathan", "John", "Johnathan", "Johnathon",
218
+  "Johnnie", "Johnny", "Johnpaul", "Johnson", "Jolie", "Jon", "Jonas",
219
+  "Jonatan", "Jonathan", "Jonathon", "Jordan", "Jordane", "Jordi", "Jordon",
220
+  "Jordy", "Jordyn", "Jorge", "Jose", "Josefa", "Josefina", "Joseph",
221
+  "Josephine", "Josh", "Joshua", "Joshuah", "Josiah", "Josiane", "Josianne",
222
+  "Josie", "Josue", "Jovan", "Jovani", "Jovanny", "Jovany", "Joy", "Joyce",
223
+  "Juana", "Juanita", "Judah", "Judd", "Jude", "Judge", "Judson", "Judy",
224
+  "Jules", "Julia", "Julian", "Juliana", "Julianne", "Julie", "Julien",
225
+  "Juliet", "Julio", "Julius", "June", "Junior", "Junius", "Justen", "Justice",
226
+  "Justina", "Justine", "Juston", "Justus", "Justyn", "Juvenal", "Juwan",
227
+  "Kacey", "Kaci", "Kacie", "Kade", "Kaden", "Kadin", "Kaela", "Kaelyn", "Kaia",
228
+  "Kailee", "Kailey", "Kailyn", "Kaitlin", "Kaitlyn", "Kale", "Kaleb",
229
+  "Kaleigh", "Kaley", "Kali", "Kallie", "Kameron", "Kamille", "Kamren",
230
+  "Kamron", "Kamryn", "Kane", "Kara", "Kareem", "Karelle", "Karen", "Kari",
231
+  "Kariane", "Karianne", "Karina", "Karine", "Karl", "Karlee", "Karley",
232
+  "Karli", "Karlie", "Karolann", "Karson", "Kasandra", "Kasey", "Kassandra",
233
+  "Katarina", "Katelin", "Katelyn", "Katelynn", "Katharina", "Katherine",
234
+  "Katheryn", "Kathleen", "Kathlyn", "Kathryn", "Kathryne", "Katlyn", "Katlynn",
235
+  "Katrina", "Katrine", "Kattie", "Kavon", "Kay", "Kaya", "Kaycee", "Kayden",
236
+  "Kayla", "Kaylah", "Kaylee", "Kayleigh", "Kayley", "Kayli", "Kaylie",
237
+  "Kaylin", "Keagan", "Keanu", "Keara", "Keaton", "Keegan", "Keeley", "Keely",
238
+  "Keenan", "Keira", "Keith", "Kellen", "Kelley", "Kelli", "Kellie", "Kelly",
239
+  "Kelsi", "Kelsie", "Kelton", "Kelvin", "Ken", "Kendall", "Kendra", "Kendrick",
240
+  "Kenna", "Kennedi", "Kennedy", "Kenneth", "Kennith", "Kenny", "Kenton",
241
+  "Kenya", "Kenyatta", "Kenyon", "Keon", "Keshaun", "Keshawn", "Keven", "Kevin",
242
+  "Kevon", "Keyon", "Keyshawn", "Khalid", "Khalil", "Kian", "Kiana", "Kianna",
243
+  "Kiara", "Kiarra", "Kiel", "Kiera", "Kieran", "Kiley", "Kim", "Kimberly",
244
+  "King", "Kip", "Kira", "Kirk", "Kirsten", "Kirstin", "Kitty", "Kobe", "Koby",
245
+  "Kody", "Kolby", "Kole", "Korbin", "Korey", "Kory", "Kraig", "Kris", "Krista",
246
+  "Kristian", "Kristin", "Kristina", "Kristofer", "Kristoffer", "Kristopher",
247
+  "Kristy", "Krystal", "Krystel", "Krystina", "Kurt", "Kurtis", "Kyla", "Kyle",
248
+  "Kylee", "Kyleigh", "Kyler", "Kylie", "Kyra", "Lacey", "Lacy", "Ladarius",
249
+  "Lafayette", "Laila", "Laisha", "Lamar", "Lambert", "Lamont", "Lance",
250
+  "Landen", "Lane", "Laney", "Larissa", "Laron", "Larry", "Larue", "Laura",
251
+  "Laurel", "Lauren", "Laurence", "Lauretta", "Lauriane", "Laurianne", "Laurie",
252
+  "Laurine", "Laury", "Lauryn", "Lavada", "Lavern", "Laverna", "Laverne",
253
+  "Lavina", "Lavinia", "Lavon", "Lavonne", "Lawrence", "Lawson", "Layla",
254
+  "Layne", "Lazaro", "Lea", "Leann", "Leanna", "Leanne", "Leatha", "Leda",
255
+  "Lee", "Leif", "Leila", "Leilani", "Lela", "Lelah", "Leland", "Lelia",
256
+  "Lempi", "Lemuel", "Lenna", "Lennie", "Lenny", "Lenora", "Lenore", "Leo",
257
+  "Leola", "Leon", "Leonard", "Leonardo", "Leone", "Leonel", "Leonie", "Leonor",
258
+  "Leonora", "Leopold", "Leopoldo", "Leora", "Lera", "Lesley", "Leslie",
259
+  "Lesly", "Lessie", "Lester", "Leta", "Letha", "Letitia", "Levi", "Lew",
260
+  "Lewis", "Lexi", "Lexie", "Lexus", "Lia", "Liam", "Liana", "Libbie", "Libby",
261
+  "Lila", "Lilian", "Liliana", "Liliane", "Lilla", "Lillian", "Lilliana",
262
+  "Lillie", "Lilly", "Lily", "Lilyan", "Lina", "Lincoln", "Linda", "Lindsay",
263
+  "Lindsey", "Linnea", "Linnie", "Linwood", "Lionel", "Lisa", "Lisandro",
264
+  "Lisette", "Litzy", "Liza", "Lizeth", "Lizzie", "Llewellyn", "Lloyd", "Logan",
265
+  "Lois", "Lola", "Lolita", "Loma", "Lon", "London", "Lonie", "Lonnie", "Lonny",
266
+  "Lonzo", "Lora", "Loraine", "Loren", "Lorena", "Lorenz", "Lorenza", "Lorenzo",
267
+  "Lori", "Lorine", "Lorna", "Lottie", "Lou", "Louie", "Louisa", "Lourdes",
268
+  "Louvenia", "Lowell", "Loy", "Loyal", "Loyce", "Lucas", "Luciano", "Lucie",
269
+  "Lucienne", "Lucile", "Lucinda", "Lucio", "Lucious", "Lucius", "Lucy",
270
+  "Ludie", "Ludwig", "Lue", "Luella", "Luigi", "Luis", "Luisa", "Lukas", "Lula",
271
+  "Lulu", "Luna", "Lupe", "Lura", "Lurline", "Luther", "Luz", "Lyda", "Lydia",
272
+  "Lyla", "Lynn", "Lyric", "Lysanne", "Mabel", "Mabelle", "Mable", "Mac",
273
+  "Macey", "Maci", "Macie", "Mack", "Mackenzie", "Macy", "Madaline", "Madalyn",
274
+  "Maddison", "Madeline", "Madelyn", "Madelynn", "Madge", "Madie", "Madilyn",
275
+  "Madisen", "Madison", "Madisyn", "Madonna", "Madyson", "Mae", "Maegan",
276
+  "Maeve", "Mafalda", "Magali", "Magdalen", "Magdalena", "Maggie", "Magnolia",
277
+  "Magnus", "Maia", "Maida", "Maiya", "Major", "Makayla", "Makenna", "Makenzie",
278
+  "Malachi", "Malcolm", "Malika", "Malinda", "Mallie", "Mallory", "Malvina",
279
+  "Mandy", "Manley", "Manuel", "Manuela", "Mara", "Marc", "Marcel", "Marcelina",
280
+  "Marcelino", "Marcella", "Marcelle", "Marcellus", "Marcelo", "Marcia",
281
+  "Marco", "Marcos", "Marcus", "Margaret", "Margarete", "Margarett",
282
+  "Margaretta", "Margarette", "Margarita", "Marge", "Margie", "Margot",
283
+  "Margret", "Marguerite", "Maria", "Mariah", "Mariam", "Marian", "Mariana",
284
+  "Mariane", "Marianna", "Marianne", "Mariano", "Maribel", "Marie", "Mariela",
285
+  "Marielle", "Marietta", "Marilie", "Marilou", "Marilyne", "Marina", "Mario",
286
+  "Marion", "Marisa", "Marisol", "Maritza", "Marjolaine", "Marjorie", "Marjory",
287
+  "Mark", "Markus", "Marlee", "Marlen", "Marlene", "Marley", "Marlin", "Marlon",
288
+  "Marques", "Marquis", "Marquise", "Marshall", "Marta", "Martin", "Martina",
289
+  "Martine", "Marty", "Marvin", "Mary", "Maryam", "Maryjane", "Maryse", "Mason",
290
+  "Mateo", "Mathew", "Mathias", "Mathilde", "Matilda", "Matilde", "Matt",
291
+  "Matteo", "Mattie", "Maud", "Maude", "Maudie", "Maureen", "Maurice",
292
+  "Mauricio", "Maurine", "Maverick", "Mavis", "Max", "Maxie", "Maxime",
293
+  "Maximilian", "Maximillia", "Maximillian", "Maximo", "Maximus", "Maxine",
294
+  "Maxwell", "May", "Maya", "Maybell", "Maybelle", "Maye", "Maymie", "Maynard",
295
+  "Mayra", "Mazie", "Mckayla", "Mckenna", "Mckenzie", "Meagan", "Meaghan",
296
+  "Meda", "Megane", "Meggie", "Meghan", "Mekhi", "Melany", "Melba", "Melisa",
297
+  "Melissa", "Mellie", "Melody", "Melvin", "Melvina", "Melyna", "Melyssa",
298
+  "Mercedes", "Meredith", "Merl", "Merle", "Merlin", "Merritt", "Mertie",
299
+  "Mervin", "Meta", "Mia", "Micaela", "Micah", "Michael", "Michaela", "Michale",
300
+  "Micheal", "Michel", "Michele", "Michelle", "Miguel", "Mikayla", "Mike",
301
+  "Mikel", "Milan", "Miles", "Milford", "Miller", "Millie", "Milo", "Milton",
302
+  "Mina", "Minerva", "Minnie", "Miracle", "Mireille", "Mireya", "Misael",
303
+  "Missouri", "Misty", "Mitchel", "Mitchell", "Mittie", "Modesta", "Modesto",
304
+  "Mohamed", "Mohammad", "Mohammed", "Moises", "Mollie", "Molly", "Mona",
305
+  "Monica", "Monique", "Monroe", "Monserrat", "Monserrate", "Montana", "Monte",
306
+  "Monty", "Morgan", "Moriah", "Morris", "Mortimer", "Morton", "Mose", "Moses",
307
+  "Moshe", "Mossie", "Mozell", "Mozelle", "Muhammad", "Muriel", "Murl",
308
+  "Murphy", "Murray", "Mustafa", "Mya", "Myah", "Mylene", "Myles", "Myra",
309
+  "Myriam", "Myrl", "Myrna", "Myron", "Myrtice", "Myrtie", "Myrtis", "Myrtle",
310
+  "Nadia", "Nakia", "Name", "Nannie", "Naomi", "Naomie", "Napoleon", "Narciso",
311
+  "Nash", "Nasir", "Nat", "Natalia", "Natalie", "Natasha", "Nathan",
312
+  "Nathanael", "Nathanial", "Nathaniel", "Nathen", "Nayeli", "Neal", "Ned",
313
+  "Nedra", "Neha", "Neil", "Nelda", "Nella", "Nelle", "Nellie", "Nels",
314
+  "Nelson", "Neoma", "Nestor", "Nettie", "Neva", "Newell", "Newton", "Nia",
315
+  "Nicholas", "Nicholaus", "Nichole", "Nick", "Nicklaus", "Nickolas", "Nico",
316
+  "Nicola", "Nicolas", "Nicole", "Nicolette", "Nigel", "Nikita", "Nikki",
317
+  "Nikko", "Niko", "Nikolas", "Nils", "Nina", "Noah", "Noble", "Noe", "Noel",
318
+  "Noelia", "Noemi", "Noemie", "Noemy", "Nola", "Nolan", "Nona", "Nora",
319
+  "Norbert", "Norberto", "Norene", "Norma", "Norris", "Norval", "Norwood",
320
+  "Nova", "Novella", "Nya", "Nyah", "Nyasia", "Obie", "Oceane", "Ocie",
321
+  "Octavia", "Oda", "Odell", "Odessa", "Odie", "Ofelia", "Okey", "Ola", "Olaf",
322
+  "Ole", "Olen", "Oleta", "Olga", "Olin", "Oliver", "Ollie", "Oma", "Omari",
323
+  "Omer", "Ona", "Onie", "Opal", "Ophelia", "Ora", "Oral", "Oran", "Oren",
324
+  "Orie", "Orin", "Orion", "Orland", "Orlando", "Orlo", "Orpha", "Orrin",
325
+  "Orval", "Orville", "Osbaldo", "Osborne", "Oscar", "Osvaldo", "Oswald",
326
+  "Oswaldo", "Otha", "Otho", "Otilia", "Otis", "Ottilie", "Ottis", "Otto",
327
+  "Ova", "Owen", "Ozella", "Pablo", "Paige", "Palma", "Pamela", "Pansy",
328
+  "Paolo", "Paris", "Parker", "Pascale", "Pasquale", "Pat", "Patience",
329
+  "Patricia", "Patrick", "Patsy", "Pattie", "Paul", "Paula", "Pauline",
330
+  "Paxton", "Payton", "Pearl", "Pearlie", "Pearline", "Pedro", "Peggie",
331
+  "Penelope", "Percival", "Percy", "Perry", "Pete", "Peter", "Petra", "Peyton",
332
+  "Philip", "Phoebe", "Phyllis", "Pierce", "Pierre", "Pietro", "Pink", "Pinkie",
333
+  "Piper", "Polly", "Porter", "Precious", "Presley", "Preston", "Price",
334
+  "Prince", "Princess", "Priscilla", "Providenci", "Prudence", "Queen",
335
+  "Queenie", "Quentin", "Quincy", "Quinn", "Quinten", "Quinton", "Rachael",
336
+  "Rachel", "Rachelle", "Rae", "Raegan", "Rafael", "Rafaela", "Raheem",
337
+  "Rahsaan", "Rahul", "Raina", "Raleigh", "Ralph", "Ramiro", "Ramon", "Ramona",
338
+  "Randal", "Randall", "Randi", "Randy", "Ransom", "Raoul", "Raphael",
339
+  "Raphaelle", "Raquel", "Rashad", "Rashawn", "Rasheed", "Raul", "Raven", "Ray",
340
+  "Raymond", "Raymundo", "Reagan", "Reanna", "Reba", "Rebeca", "Rebecca",
341
+  "Rebeka", "Rebekah", "Reece", "Reed", "Reese", "Regan", "Reggie", "Reginald",
342
+  "Reid", "Reilly", "Reina", "Reinhold", "Remington", "Rene", "Renee", "Ressie",
343
+  "Reta", "Retha", "Retta", "Reuben", "Reva", "Rex", "Rey", "Reyes", "Reymundo",
344
+  "Reyna", "Reynold", "Rhea", "Rhett", "Rhianna", "Rhiannon", "Rhoda",
345
+  "Ricardo", "Richard", "Richie", "Richmond", "Rick", "Rickey", "Rickie",
346
+  "Ricky", "Rico", "Rigoberto", "Riley", "Rita", "River", "Robb", "Robbie",
347
+  "Robert", "Roberta", "Roberto", "Robin", "Robyn", "Rocio", "Rocky", "Rod",
348
+  "Roderick", "Rodger", "Rodolfo", "Rodrick", "Rodrigo", "Roel", "Rogelio",
349
+  "Roger", "Rogers", "Rolando", "Rollin", "Roma", "Romaine", "Roman", "Ron",
350
+  "Ronaldo", "Ronny", "Roosevelt", "Rory", "Rosa", "Rosalee", "Rosalia",
351
+  "Rosalind", "Rosalinda", "Rosalyn", "Rosamond", "Rosanna", "Rosario",
352
+  "Roscoe", "Rose", "Rosella", "Roselyn", "Rosemarie", "Rosemary", "Rosendo",
353
+  "Rosetta", "Rosie", "Rosina", "Roslyn", "Ross", "Rossie", "Rowan", "Rowena",
354
+  "Rowland", "Roxane", "Roxanne", "Roy", "Royal", "Royce", "Rozella", "Ruben",
355
+  "Rubie", "Ruby", "Rubye", "Rudolph", "Rudy", "Rupert", "Russ", "Russel",
356
+  "Russell", "Rusty", "Ruth", "Ruthe", "Ruthie", "Ryan", "Ryann", "Ryder",
357
+  "Rylan", "Rylee", "Ryleigh", "Ryley", "Sabina", "Sabrina", "Sabryna", "Sadie",
358
+  "Sadye", "Sage", "Saige", "Sallie", "Sally", "Salma", "Salvador", "Salvatore",
359
+  "Sam", "Samanta", "Samantha", "Samara", "Samir", "Sammie", "Sammy", "Samson",
360
+  "Sandra", "Sandrine", "Sandy", "Sanford", "Santa", "Santiago", "Santina",
361
+  "Santino", "Santos", "Sarah", "Sarai", "Sarina", "Sasha", "Saul", "Savanah",
362
+  "Savanna", "Savannah", "Savion", "Scarlett", "Schuyler", "Scot", "Scottie",
363
+  "Scotty", "Seamus", "Sean", "Sebastian", "Sedrick", "Selena", "Selina",
364
+  "Selmer", "Serena", "Serenity", "Seth", "Shad", "Shaina", "Shakira", "Shana",
365
+  "Shane", "Shanel", "Shanelle", "Shania", "Shanie", "Shaniya", "Shanna",
366
+  "Shannon", "Shanny", "Shanon", "Shany", "Sharon", "Shaun", "Shawn", "Shawna",
367
+  "Shaylee", "Shayna", "Shayne", "Shea", "Sheila", "Sheldon", "Shemar",
368
+  "Sheridan", "Sherman", "Sherwood", "Shirley", "Shyann", "Shyanne", "Sibyl",
369
+  "Sid", "Sidney", "Sienna", "Sierra", "Sigmund", "Sigrid", "Sigurd", "Silas",
370
+  "Sim", "Simeon", "Simone", "Sincere", "Sister", "Skye", "Skyla", "Skylar",
371
+  "Sofia", "Soledad", "Solon", "Sonia", "Sonny", "Sonya", "Sophia", "Sophie",
372
+  "Spencer", "Stacey", "Stacy", "Stan", "Stanford", "Stanley", "Stanton",
373
+  "Stefan", "Stefanie", "Stella", "Stephan", "Stephania", "Stephanie",
374
+  "Stephany", "Stephen", "Stephon", "Sterling", "Steve", "Stevie", "Stewart",
375
+  "Stone", "Stuart", "Summer", "Sunny", "Susan", "Susana", "Susanna", "Susie",
376
+  "Suzanne", "Sven", "Syble", "Sydnee", "Sydney", "Sydni", "Sydnie", "Sylvan",
377
+  "Sylvester", "Sylvia", "Tabitha", "Tad", "Talia", "Talon", "Tamara", "Tamia",
378
+  "Tania", "Tanner", "Tanya", "Tara", "Taryn", "Tate", "Tatum", "Tatyana",
379
+  "Taurean", "Tavares", "Taya", "Taylor", "Teagan", "Ted", "Telly", "Terence",
380
+  "Teresa", "Terrance", "Terrell", "Terrence", "Terrill", "Terry", "Tess",
381
+  "Tessie", "Tevin", "Thad", "Thaddeus", "Thalia", "Thea", "Thelma", "Theo",
382
+  "Theodora", "Theodore", "Theresa", "Therese", "Theresia", "Theron", "Thomas",
383
+  "Thora", "Thurman", "Tia", "Tiana", "Tianna", "Tiara", "Tierra", "Tiffany",
384
+  "Tillman", "Timmothy", "Timmy", "Timothy", "Tina", "Tito", "Titus", "Tobin",
385
+  "Toby", "Tod", "Tom", "Tomas", "Tomasa", "Tommie", "Toney", "Toni", "Tony",
386
+  "Torey", "Torrance", "Torrey", "Toy", "Trace", "Tracey", "Tracy", "Travis",
387
+  "Travon", "Tre", "Tremaine", "Tremayne", "Trent", "Trenton", "Tressa",
388
+  "Tressie", "Treva", "Trever", "Trevion", "Trevor", "Trey", "Trinity",
389
+  "Trisha", "Tristian", "Tristin", "Triston", "Troy", "Trudie", "Trycia",
390
+  "Trystan", "Turner", "Twila", "Tyler", "Tyra", "Tyree", "Tyreek", "Tyrel",
391
+  "Tyrell", "Tyrese", "Tyrique", "Tyshawn", "Tyson", "Ubaldo", "Ulices",
392
+  "Ulises", "Una", "Unique", "Urban", "Uriah", "Uriel", "Ursula", "Vada",
393
+  "Valentin", "Valentina", "Valentine", "Valerie", "Vallie", "Van", "Vance",
394
+  "Vanessa", "Vaughn", "Veda", "Velda", "Vella", "Velma", "Velva", "Vena",
395
+  "Verda", "Verdie", "Vergie", "Verla", "Verlie", "Vern", "Verna", "Verner",
396
+  "Vernice", "Vernie", "Vernon", "Verona", "Veronica", "Vesta", "Vicenta",
397
+  "Vicente", "Vickie", "Vicky", "Victor", "Victoria", "Vida", "Vidal", "Vilma",
398
+  "Vince", "Vincent", "Vincenza", "Vincenzo", "Vinnie", "Viola", "Violet",
399
+  "Violette", "Virgie", "Virgil", "Virginia", "Virginie", "Vita", "Vito",
400
+  "Viva", "Vivian", "Viviane", "Vivianne", "Vivien", "Vivienne", "Vladimir",
401
+  "Wade", "Waino", "Waldo", "Walker", "Wallace", "Walter", "Walton", "Wanda",
402
+  "Ward", "Warren", "Watson", "Wava", "Waylon", "Wayne", "Webster", "Weldon",
403
+  "Wellington", "Wendell", "Wendy", "Werner", "Westley", "Weston", "Whitney",
404
+  "Wilber", "Wilbert", "Wilburn", "Wiley", "Wilford", "Wilfred", "Wilfredo",
405
+  "Wilfrid", "Wilhelm", "Wilhelmine", "Will", "Willa", "Willard", "William",
406
+  "Willie", "Willis", "Willow", "Willy", "Wilma", "Wilmer", "Wilson", "Wilton",
407
+  "Winfield", "Winifred", "Winnifred", "Winona", "Winston", "Woodrow", "Wyatt",
408
+  "Wyman", "Xander", "Xavier", "Xzavier", "Yadira", "Yasmeen", "Yasmin",
409
+  "Yasmine", "Yazmin", "Yesenia", "Yessenia", "Yolanda", "Yoshiko", "Yvette",
410
+  "Yvonne", "Zachariah", "Zachary", "Zachery", "Zack", "Zackary", "Zackery",
411
+  "Zakary", "Zander", "Zane", "Zaria", "Zechariah", "Zelda", "Zella", "Zelma",
412
+  "Zena", "Zetta", "Zion", "Zita", "Zoe", "Zoey", "Zoie", "Zoila", "Zola",
413
+  "Zora", "Zula"
414
+];
415
+
416
+/**
417
+ * Generate random username.
418
+ * @returns {string} random username
419
+ */
420
+function generateUsername () {
421
+  var name = RandomUtil.randomElement(names);
422
+  var suffix = RandomUtil.randomAlphanumStr(3);
423
+
424
+  return name + '-' +  suffix;
425
+}
426
+
427
+module.exports = {
428
+  generateUsername: generateUsername
429
+};

+ 3
- 2
modules/xmpp/ChatRoom.js View File

@@ -59,7 +59,7 @@ function filterNodeFromPresenceJSON(pres, nodeName){
59 59
     return res;
60 60
 }
61 61
 
62
-function ChatRoom(connection, jid, password, XMPP, options) {
62
+function ChatRoom(connection, jid, password, XMPP, options, settings) {
63 63
     this.eventEmitter = new EventEmitter();
64 64
     this.xmpp = XMPP;
65 65
     this.connection = connection;
@@ -75,7 +75,8 @@ function ChatRoom(connection, jid, password, XMPP, options) {
75 75
     this.focusMucJid = null;
76 76
     this.bridgeIsDown = false;
77 77
     this.options = options || {};
78
-    this.moderator = new Moderator(this.roomjid, this.xmpp, this.eventEmitter);
78
+    this.moderator = new Moderator(this.roomjid, this.xmpp, this.eventEmitter,
79
+        settings);
79 80
     this.initPresenceMap();
80 81
     this.session = null;
81 82
     var self = this;

+ 23
- 12
modules/xmpp/TraceablePeerConnection.js View File

@@ -23,7 +23,9 @@ function TraceablePeerConnection(ice_config, constraints, session) {
23 23
     var Interop = require('sdp-interop').Interop;
24 24
     this.interop = new Interop();
25 25
     var Simulcast = require('sdp-simulcast');
26
-    this.simulcast = new Simulcast({numOfLayers: 3, explodeRemoteSimulcast: false});
26
+    this.simulcast = new Simulcast({numOfLayers: 3,
27
+        explodeRemoteSimulcast: false});
28
+    this.eventEmitter = this.session.room.eventEmitter;
27 29
 
28 30
     // override as desired
29 31
     this.trace = function (what, info) {
@@ -324,7 +326,8 @@ TraceablePeerConnection.prototype.setLocalDescription
324 326
     // if we're running on FF, transform to Plan A first.
325 327
     if (RTCBrowserType.usesUnifiedPlan()) {
326 328
         description = this.interop.toUnifiedPlan(description);
327
-        this.trace('setLocalDescription::postTransform (Plan A)', dumpSDP(description));
329
+        this.trace('setLocalDescription::postTransform (Plan A)',
330
+            dumpSDP(description));
328 331
     }
329 332
 
330 333
     var self = this;
@@ -335,14 +338,11 @@ TraceablePeerConnection.prototype.setLocalDescription
335 338
         },
336 339
         function (err) {
337 340
             self.trace('setLocalDescriptionOnFailure', err);
341
+            self.eventEmitter.emit(XMPPEvents.SET_LOCAL_DESCRIPTION_FAILED,
342
+                err, self.peerconnection);
338 343
             failureCallback(err);
339 344
         }
340 345
     );
341
-    /*
342
-     if (this.statsinterval === null && this.maxstats > 0) {
343
-     // start gathering stats
344
-     }
345
-     */
346 346
 };
347 347
 
348 348
 TraceablePeerConnection.prototype.setRemoteDescription
@@ -370,6 +370,8 @@ TraceablePeerConnection.prototype.setRemoteDescription
370 370
         },
371 371
         function (err) {
372 372
             self.trace('setRemoteDescriptionOnFailure', err);
373
+            self.eventEmitter.emit(XMPPEvents.SET_REMOTE_DESCRIPTION_FAILED,
374
+                err, self.peerconnection);
373 375
             failureCallback(err);
374 376
         }
375 377
     );
@@ -411,14 +413,18 @@ TraceablePeerConnection.prototype.createOffer
411 413
                 self.trace('createOfferOnSuccess::mungeLocalVideoSSRC', dumpSDP(offer));
412 414
             }
413 415
 
414
-            if (!self.session.room.options.disableSimulcast && self.simulcast.isSupported()) {
416
+            if (!self.session.room.options.disableSimulcast
417
+                 && self.simulcast.isSupported()) {
415 418
                 offer = self.simulcast.mungeLocalDescription(offer);
416
-                self.trace('createOfferOnSuccess::postTransform (simulcast)', dumpSDP(offer));
419
+                self.trace('createOfferOnSuccess::postTransform (simulcast)',
420
+                    dumpSDP(offer));
417 421
             }
418 422
             successCallback(offer);
419 423
         },
420 424
         function(err) {
421 425
             self.trace('createOfferOnFailure', err);
426
+            self.eventEmitter.emit(XMPPEvents.CREATE_OFFER_FAILED, err,
427
+                self.peerconnection);
422 428
             failureCallback(err);
423 429
         },
424 430
         constraints
@@ -435,7 +441,8 @@ TraceablePeerConnection.prototype.createAnswer
435 441
             // if we're running on FF, transform to Plan A first.
436 442
             if (RTCBrowserType.usesUnifiedPlan()) {
437 443
                 answer = self.interop.toPlanB(answer);
438
-                self.trace('createAnswerOnSuccess::postTransform (Plan B)', dumpSDP(answer));
444
+                self.trace('createAnswerOnSuccess::postTransform (Plan B)',
445
+                    dumpSDP(answer));
439 446
             }
440 447
 
441 448
             if (RTCBrowserType.isChrome())
@@ -444,14 +451,18 @@ TraceablePeerConnection.prototype.createAnswer
444 451
                 self.trace('createAnswerOnSuccess::mungeLocalVideoSSRC', dumpSDP(answer));
445 452
             }
446 453
 
447
-            if (!self.session.room.options.disableSimulcast && self.simulcast.isSupported()) {
454
+            if (!self.session.room.options.disableSimulcast
455
+                && self.simulcast.isSupported()) {
448 456
                 answer = self.simulcast.mungeLocalDescription(answer);
449
-                self.trace('createAnswerOnSuccess::postTransform (simulcast)', dumpSDP(answer));
457
+                self.trace('createAnswerOnSuccess::postTransform (simulcast)',
458
+                    dumpSDP(answer));
450 459
             }
451 460
             successCallback(answer);
452 461
         },
453 462
         function(err) {
454 463
             self.trace('createAnswerOnFailure', err);
464
+            self.eventEmitter.emit(XMPPEvents.CREATE_ANSWER_FAILED, err,
465
+                self.peerconnection);
455 466
             failureCallback(err);
456 467
         },
457 468
         constraints

+ 2
- 7
modules/xmpp/moderator.js View File

@@ -2,7 +2,6 @@
2 2
 
3 3
 var logger = require("jitsi-meet-logger").getLogger(__filename);
4 4
 var XMPPEvents = require("../../service/xmpp/XMPPEvents");
5
-var Settings = require("../settings/Settings");
6 5
 
7 6
 var AuthenticationEvents
8 7
     = require("../../service/authentication/AuthenticationEvents");
@@ -22,18 +21,14 @@ function createExpBackoffTimer(step) {
22 21
     };
23 22
 }
24 23
 
25
-
26
-
27
-
28
-
29
-function Moderator(roomName, xmpp, emitter) {
24
+function Moderator(roomName, xmpp, emitter, settings) {
30 25
     this.roomName = roomName;
31 26
     this.xmppService = xmpp;
32 27
     this.getNextTimeout = createExpBackoffTimer(1000);
33 28
     this.getNextErrorTimeout = createExpBackoffTimer(1000);
34 29
     // External authentication stuff
35 30
     this.externalAuthEnabled = false;
36
-    this.settings = new Settings(roomName);
31
+    this.settings = settings;
37 32
     // Sip gateway can be enabled by configuring Jigasi host in config.js or
38 33
     // it will be enabled automatically if focus detects the component through
39 34
     // service discovery.

+ 3
- 2
modules/xmpp/strophe.emuc.js View File

@@ -24,13 +24,14 @@ module.exports = function(XMPP) {
24 24
             this.connection.addHandler(this.onMute.bind(this),
25 25
                 'http://jitsi.org/jitmeet/audio', 'iq', 'set',null,null);
26 26
         },
27
-        createRoom: function (jid, password, options) {
27
+        createRoom: function (jid, password, options, settings) {
28 28
             var roomJid = Strophe.getBareJidFromJid(jid);
29 29
             if (this.rooms[roomJid]) {
30 30
                 logger.error("You are already in the room!");
31 31
                 return;
32 32
             }
33
-            this.rooms[roomJid] = new ChatRoom(this.connection, jid, password, XMPP, options);
33
+            this.rooms[roomJid] = new ChatRoom(this.connection, jid,
34
+                password, XMPP, options, settings);
34 35
             return this.rooms[roomJid];
35 36
         },
36 37
         doLeave: function (jid) {

+ 2
- 2
modules/xmpp/xmpp.js View File

@@ -186,7 +186,7 @@ XMPP.prototype.connect = function (jid, password) {
186 186
     return this._connect(jid, password);
187 187
 };
188 188
 
189
-XMPP.prototype.createRoom = function (roomName, options) {
189
+XMPP.prototype.createRoom = function (roomName, options, settings) {
190 190
     var roomjid = roomName  + '@' + this.options.hosts.muc;
191 191
 
192 192
     if (options.useNicks) {
@@ -204,7 +204,7 @@ XMPP.prototype.createRoom = function (roomName, options) {
204 204
         roomjid += '/' + tmpJid;
205 205
     }
206 206
 
207
-    return this.connection.emuc.createRoom(roomjid, null, options);
207
+    return this.connection.emuc.createRoom(roomjid, null, options, settings);
208 208
 }
209 209
 
210 210
 XMPP.prototype.addListener = function(type, listener) {

+ 21
- 1
service/xmpp/XMPPEvents.js View File

@@ -102,6 +102,26 @@ var XMPPEvents = {
102 102
     /**
103 103
      * Indicates that phone number changed.
104 104
      */
105
-    PHONE_NUMBER_CHANGED: "conference.phoneNumberChanged"
105
+    PHONE_NUMBER_CHANGED: "conference.phoneNumberChanged",
106
+    /**
107
+     * Indicates error while create offer call.
108
+     */
109
+    CREATE_OFFER_FAILED: "xmpp.create_offer_failed",
110
+    /**
111
+     * Indicates error while create answer call.
112
+     */
113
+    CREATE_ANSWER_FAILED: "xmpp.create_answer_failed",
114
+    /**
115
+     * Indicates error while set local description.
116
+     */
117
+    SET_LOCAL_DESCRIPTION_FAILED: "xmpp.set_local_description_failed",
118
+    /**
119
+     * Indicates error while set remote description.
120
+     */
121
+    SET_REMOTE_DESCRIPTION_FAILED: "xmpp.set_remote_description_failed",
122
+    /**
123
+     * Indicates error while adding ice candidate.
124
+     */
125
+    ADD_ICE_CANDIDATE_FAILED: "xmpp.add_ice_candidate_failed"
106 126
 };
107 127
 module.exports = XMPPEvents;

Loading…
Cancel
Save