Full Code of muaz-khan/WebRTC-Experiment for AI

master bbcdbc13b3d7 cached
981 files
15.3 MB
4.1M tokens
2982 symbols
1 requests
Copy disabled (too large) Download .txt
Showing preview only (16,205K chars total). Download the full file to get everything.
Repository: muaz-khan/WebRTC-Experiment
Branch: master
Commit: bbcdbc13b3d7
Files: 981
Total size: 15.3 MB

Directory structure:
gitextract_ce2vii70/

├── .gitignore
├── Canvas-Designer/
│   ├── .gitignore
│   ├── .npmignore
│   ├── .travis.yml
│   ├── Gruntfile.js
│   ├── Help/
│   │   └── index.html
│   ├── LICENSE
│   ├── README.md
│   ├── bower.json
│   ├── canvas-designer-widget.js
│   ├── dev/
│   │   ├── amd.js
│   │   ├── arc-handler.js
│   │   ├── arrow-handler.js
│   │   ├── bezier-handler.js
│   │   ├── common.js
│   │   ├── data-uris.js
│   │   ├── decorator.js
│   │   ├── drag-helper.js
│   │   ├── draw-helper.js
│   │   ├── eraser-handler.js
│   │   ├── events-handler.js
│   │   ├── file-selector.js
│   │   ├── head.js
│   │   ├── image-handler.js
│   │   ├── line-handler.js
│   │   ├── marker-handler.js
│   │   ├── pdf-handler.js
│   │   ├── pencil-handler.js
│   │   ├── quadratic-handler.js
│   │   ├── rect-handler.js
│   │   ├── share-drawings.js
│   │   ├── tail.js
│   │   ├── text-handler.js
│   │   ├── webrtc-handler.js
│   │   └── zoom-handler.js
│   ├── index.html
│   ├── multiple.html
│   ├── package.json
│   ├── server.js
│   ├── simple.html
│   ├── widget.html
│   └── widget.js
├── Chrome-Extensions/
│   ├── .gitignore
│   ├── LICENSE
│   ├── README.md
│   ├── Screen-Capturing.js/
│   │   ├── README.md
│   │   ├── Screen-Capturing.js
│   │   ├── index.html
│   │   └── server.js
│   ├── desktopCapture/
│   │   ├── README.md
│   │   ├── background-script.js
│   │   ├── content-script.js
│   │   ├── different-api/
│   │   │   ├── background-script.js
│   │   │   └── manifest.json
│   │   └── manifest.json
│   ├── desktopCapture-p2p/
│   │   ├── README.md
│   │   ├── background/
│   │   │   ├── captureCamera.js
│   │   │   ├── captureDesktop.js
│   │   │   ├── captureTabUsingTabCapture.js
│   │   │   ├── common.js
│   │   │   ├── globals.js
│   │   │   ├── gotStream.js
│   │   │   ├── gotTabCaptureStream.js
│   │   │   ├── helpers/
│   │   │   │   ├── AntMediaWrapper.js
│   │   │   │   ├── CodecsHandler.js
│   │   │   │   ├── IceServersHandler.js
│   │   │   │   ├── MultiStreamsMixer.js
│   │   │   │   ├── adapter.js
│   │   │   │   ├── getStats.js
│   │   │   │   └── socket.io.js
│   │   │   ├── onAccessApproved.js
│   │   │   ├── online-offline.js
│   │   │   ├── runtimePort.js
│   │   │   ├── setDefaults.js
│   │   │   ├── setupWebRTCConnection.js
│   │   │   ├── shareStreamUsingAntMediaServer.js
│   │   │   └── shareStreamUsingRTCMultiConnection.js
│   │   ├── extension-pages/
│   │   │   ├── camera-mic.html
│   │   │   ├── camera-mic.js
│   │   │   ├── chat.html
│   │   │   ├── chat.js
│   │   │   ├── dropdown.html
│   │   │   ├── dropdown.js
│   │   │   ├── options.html
│   │   │   ├── options.js
│   │   │   ├── video.html
│   │   │   └── video.js
│   │   ├── index.html
│   │   ├── manifest.json
│   │   ├── screen-receivers/
│   │   │   └── ant/
│   │   │       └── index.html
│   │   └── server.js
│   ├── file-sharing/
│   │   ├── README.md
│   │   ├── background.js
│   │   ├── fonts/
│   │   │   └── MyriadPro-Light.otf
│   │   ├── info.html
│   │   ├── manifest.json
│   │   ├── options.html
│   │   ├── options.js
│   │   ├── popup.html
│   │   ├── popup.js
│   │   └── rmc-files-handler.js
│   ├── get-any-webrtc-peer-stream/
│   │   ├── RTCPeerConnection-override.js
│   │   ├── content-script.js
│   │   └── manifest.json
│   ├── getUserMedia-on-http/
│   │   ├── README.md
│   │   ├── background-script.js
│   │   ├── camera-mic.html
│   │   ├── camera-mic.js
│   │   ├── content-script.js
│   │   ├── example/
│   │   │   ├── index.html
│   │   │   └── index.js
│   │   ├── manifest.json
│   │   └── webrtc-handler.js
│   ├── screen-recording/
│   │   ├── README.md
│   │   ├── RecordRTC/
│   │   │   ├── DiskStorage.js
│   │   │   ├── EBML.js
│   │   │   ├── MediaStreamRecorder.js
│   │   │   ├── MultiStreamRecorder.js
│   │   │   ├── MultiStreamsMixer.js
│   │   │   ├── StereoAudioRecorder.js
│   │   │   └── getAllAudioVideoDevices.js
│   │   ├── background/
│   │   │   ├── background.badgeText.js
│   │   │   ├── background.common.js
│   │   │   ├── background.contentScript.js
│   │   │   ├── background.desktopCapture.js
│   │   │   ├── background.getUserMedia.js
│   │   │   ├── background.js
│   │   │   ├── background.messaging.js
│   │   │   ├── background.players.js
│   │   │   └── background.tabCapture.js
│   │   ├── camera-mic.html
│   │   ├── camera-mic.js
│   │   ├── dropdown.html
│   │   ├── dropdown.js
│   │   ├── manifest.json
│   │   ├── options.html
│   │   ├── options.js
│   │   ├── preview/
│   │   │   ├── preview.js
│   │   │   ├── preview.php.upload.js
│   │   │   └── preview.youtube.upload.js
│   │   ├── preview.html
│   │   ├── video.html
│   │   └── video.js
│   └── tabCapture/
│       ├── CodecsHandler.js
│       ├── IceServersHandler.js
│       ├── README.md
│       ├── index.html
│       ├── manifest.json
│       ├── options.html
│       ├── options.js
│       ├── shareStreamUsingRTCMultiConnection.js
│       ├── socket.io.js
│       └── tab-capturing.js
├── ConcatenateBlobs/
│   ├── ConcatenateBlobs.js
│   ├── README.md
│   ├── index.html
│   └── package.json
├── Conversation.js/
│   ├── AndroidRTC/
│   │   ├── fonts/
│   │   │   ├── MyriadPro-Bold.otf
│   │   │   ├── MyriadPro-Light.otf
│   │   │   └── MyriadPro-Regular.otf
│   │   ├── index.html
│   │   ├── manifest.json
│   │   ├── scripts/
│   │   │   ├── FileBufferReader.js
│   │   │   ├── RTCMultiConnection.js
│   │   │   ├── common-signaling.js
│   │   │   ├── conversation.js
│   │   │   └── ui-handler.js
│   │   └── styles/
│   │       └── ui-styles.css
│   ├── README.md
│   ├── conversation.js
│   ├── demos/
│   │   ├── common-signaling.js
│   │   ├── common-styles.css
│   │   ├── cross-language-chat.html
│   │   └── search-user.html
│   ├── package.json
│   └── server.js
├── DataChannel/
│   ├── .gitignore
│   ├── .jshintrc
│   ├── .npmignore
│   ├── .travis.yml
│   ├── DataChannel.js
│   ├── Gruntfile.js
│   ├── README.md
│   ├── auto-session-establishment.html
│   ├── bower.json
│   ├── dev/
│   │   ├── DataChannel.js
│   │   ├── DataConnector.js
│   │   ├── FileConverter.js
│   │   ├── FileReceiver.js
│   │   ├── FileSaver.js
│   │   ├── FileSender.js
│   │   ├── IceServersHandler.js
│   │   ├── RTCPeerConnection.js
│   │   ├── SocketConnector.js
│   │   ├── TextReceiver.js
│   │   ├── TextSender.js
│   │   ├── externalIceServers.js
│   │   ├── globals.js
│   │   ├── head.js
│   │   └── tail.js
│   ├── index.html
│   ├── package.json
│   ├── server.js
│   └── simple.html
├── DetectRTC/
│   ├── .gitignore
│   ├── .jshintrc
│   ├── .npmignore
│   ├── .travis.yml
│   ├── DetectRTC.js
│   ├── Gruntfile.js
│   ├── LICENSE
│   ├── README.md
│   ├── bower.json
│   ├── dev/
│   │   ├── CheckDeviceSupport.js
│   │   ├── DetectLocalIPAddress.js
│   │   ├── DetectRTC.js
│   │   ├── Objects.js
│   │   ├── common.js
│   │   ├── detectCaptureStream.js
│   │   ├── detectDesktopOS.js
│   │   ├── detectOSName.js
│   │   ├── detectPrivateBrowsing.js
│   │   ├── getBrowserInfo.js
│   │   ├── head.js
│   │   ├── isMobile.js
│   │   └── tail.js
│   ├── index.html
│   ├── npm-test.js
│   ├── package.json
│   ├── server.js
│   ├── simple-demos/
│   │   ├── select-cameras.html
│   │   └── simple-demo.html
│   └── test/
│       ├── CheckDeviceSupport.js
│       ├── DetectRTC.js
│       ├── browserstack.config.js
│       ├── detectOSName.js
│       ├── getBrowserInfo.js
│       └── html-test-files/
│           ├── CheckDeviceSupport.html
│           ├── DetectRTC.html
│           ├── detectOSName.html
│           └── getBrowserInfo.html
├── FileBufferReader/
│   ├── .gitignore
│   ├── .npmignore
│   ├── .travis.yml
│   ├── FileBufferReader.js
│   ├── Gruntfile.js
│   ├── LICENSE
│   ├── README.md
│   ├── bower.json
│   ├── demo/
│   │   ├── IceServersHandler.js
│   │   ├── PeerConnection.js
│   │   ├── PeerUI.js
│   │   ├── adapter-latest.js
│   │   └── index.html
│   ├── dev/
│   │   ├── FileBufferReader.js
│   │   ├── FileBufferReaderHelper.js
│   │   ├── FileBufferReceiver.js
│   │   ├── FileConverter.js
│   │   ├── FileSelector.js
│   │   ├── binarize.js
│   │   ├── common.js
│   │   ├── head.js
│   │   └── tail.js
│   ├── fbr-client/
│   │   ├── .gitignore
│   │   ├── .npmignore
│   │   ├── README.md
│   │   ├── demo/
│   │   │   ├── circular-progress-bar.css
│   │   │   ├── style.css
│   │   │   └── ui.js
│   │   ├── index.html
│   │   ├── package.json
│   │   └── server.js
│   ├── index.html
│   ├── package.json
│   └── server.js
├── Firefox-Extensions/
│   ├── README.md
│   ├── enable-screen-capturing/
│   │   ├── README.md
│   │   ├── content-script.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── test/
│   │       └── test-index.js
│   ├── enable-screen-capturing-old/
│   │   ├── README.md
│   │   ├── bootstrap.js
│   │   ├── enable-screen-capturing.xpi
│   │   └── install.rdf
│   └── enable-screen-capturing-old2/
│       ├── FirefoxScreenAddon.js
│       ├── README.md
│       ├── content-script.js
│       ├── index.js
│       ├── package.json
│       └── test/
│           └── test-index.js
├── LICENSE
├── MediaStreamRecorder/
│   ├── .gitignore
│   ├── .npmignore
│   ├── .travis.yml
│   ├── AudioStreamRecorder/
│   │   ├── FlashAudioRecorder.js
│   │   ├── FlashAudioRecorder.md
│   │   ├── MediaRecorderWrapper.js
│   │   ├── README.md
│   │   ├── StereoAudioRecorder.js
│   │   ├── StereoAudioRecorderHelper.js
│   │   └── lib/
│   │       ├── recorder.js/
│   │       │   ├── recorder.js
│   │       │   └── recorder.swf
│   │       └── wavencoder/
│   │           └── wavencoder.js
│   ├── FileSystem/
│   │   ├── FileReader.js
│   │   ├── FileWriter.js
│   │   └── README.md
│   ├── Gruntfile.js
│   ├── LICENSE
│   ├── MediaStreamRecorder.js
│   ├── README.md
│   ├── VideoStreamRecorder/
│   │   ├── GifRecorder.js
│   │   ├── README.md
│   │   ├── WhammyRecorder.js
│   │   ├── WhammyRecorderHelper.js
│   │   └── lib/
│   │       ├── gif-encoder.js
│   │       └── whammy.js
│   ├── bower.json
│   ├── common/
│   │   ├── ConcatenateBlobs.js
│   │   ├── Cross-Browser-Declarations.js
│   │   ├── MediaStreamRecorder.js
│   │   ├── MultiStreamRecorder.js
│   │   ├── MultiStreamsMixer.js
│   │   ├── OpentTokStreamRecorder.js
│   │   └── amd.js
│   ├── demos/
│   │   ├── MultiStreamRecorder.html
│   │   ├── README.md
│   │   ├── audio-recorder.html
│   │   ├── flash-audio-recorder-upload.html
│   │   ├── flash-audio-recorder.html
│   │   ├── gif-recorder.html
│   │   ├── index.html
│   │   ├── opentok-stream-recorder.html
│   │   └── video-recorder.html
│   ├── fake-keys/
│   │   ├── certificate.pem
│   │   └── privatekey.pem
│   ├── lib/
│   │   └── AjaxRequest/
│   │       └── AjaxRequest.js
│   ├── npm-test.js
│   ├── package.json
│   ├── server.js
│   └── tests/
│       └── flash-audio-recorder-memory-usage.html
├── MultiRTC/
│   ├── .gitignore
│   ├── MultiRTC-firebase/
│   │   ├── FileBufferReader.js
│   │   ├── README.md
│   │   ├── RTCMultiConnection.js
│   │   ├── firebase.js
│   │   ├── index.html
│   │   ├── linkify.js
│   │   ├── package.json
│   │   ├── scrol-bars.css
│   │   ├── style.css
│   │   ├── ui.main.js
│   │   ├── ui.peer-connection.js
│   │   ├── ui.settings.js
│   │   ├── ui.share-files.js
│   │   └── ui.users-list.js
│   ├── MultiRTC-socketio/
│   │   ├── README.md
│   │   ├── certificate.pem
│   │   ├── package.json
│   │   ├── privatekey.pem
│   │   ├── public/
│   │   │   ├── FileBufferReader.js
│   │   │   ├── RTCMultiConnection.js
│   │   │   ├── index.html
│   │   │   ├── linkify.js
│   │   │   ├── scrol-bars.css
│   │   │   ├── style.css
│   │   │   ├── ui.main.js
│   │   │   ├── ui.peer-connection.js
│   │   │   ├── ui.settings.js
│   │   │   ├── ui.share-files.js
│   │   │   └── ui.users-list.js
│   │   └── signaler.js
│   ├── MultiRTC-websocket/
│   │   ├── FileBufferReader.js
│   │   ├── README.md
│   │   ├── RTCMultiConnection.js
│   │   ├── index.html
│   │   ├── linkify.js
│   │   ├── package.json
│   │   ├── scrol-bars.css
│   │   ├── style.css
│   │   ├── ui.main.js
│   │   ├── ui.peer-connection.js
│   │   ├── ui.settings.js
│   │   ├── ui.share-files.js
│   │   └── ui.users-list.js
│   └── README.md
├── MultiStreamsMixer/
│   ├── .gitignore
│   ├── .npmignore
│   ├── .travis.yml
│   ├── Gruntfile.js
│   ├── LICENSE
│   ├── MultiStreamsMixer.js
│   ├── MultiStreamsMixer.ts
│   ├── README.md
│   ├── bower.json
│   ├── dev/
│   │   ├── README.md
│   │   ├── amd.js
│   │   ├── append-streams.js
│   │   ├── cross-browser-declarations.js
│   │   ├── draw-videos-on-canvas.js
│   │   ├── get-mixed-audio-stream.js
│   │   ├── get-mixed-stream.js
│   │   ├── get-mixed-video-stream.js
│   │   ├── get-video-element.js
│   │   ├── head.js
│   │   ├── init.js
│   │   ├── module.exports.js
│   │   ├── release-streams.js
│   │   ├── replace-streams.js
│   │   ├── start-drawing-frames.js
│   │   └── tail.js
│   ├── index.html
│   ├── npm-test.js
│   ├── package.json
│   └── server.js
├── PluginRTC/
│   ├── Plugin.EveryWhere.js
│   ├── Plugin.Temasys.js
│   └── README.md
├── Pluginfree-Screen-Sharing/
│   ├── README.md
│   ├── conference.js
│   └── index.html
├── Pre-recorded-Media-Streaming/
│   ├── MediaStreamer.js
│   ├── README.md
│   ├── index-2.html
│   ├── index-old.html
│   ├── index.html
│   └── streamer.js
├── README.md
├── RTCMultiConnection/
│   ├── .gitignore
│   ├── .jshintrc
│   ├── .npmignore
│   ├── .travis.yml
│   ├── CONTRIBUTING.md
│   ├── Gruntfile.js
│   ├── LICENSE.md
│   ├── README.md
│   ├── admin/
│   │   ├── admin-ui.js
│   │   └── index.html
│   ├── bower.json
│   ├── config.json
│   ├── demos/
│   │   ├── Audio-Conferencing.html
│   │   ├── Call-By-UserName.html
│   │   ├── One-to-One.html
│   │   ├── README.md
│   │   ├── SSEConnection/
│   │   │   ├── README.md
│   │   │   ├── SSE.php
│   │   │   ├── checkPresence.php
│   │   │   ├── enableCORS.php
│   │   │   ├── get-param.php
│   │   │   ├── publish.php
│   │   │   ├── rooms/
│   │   │   │   └── README.md
│   │   │   └── write-json.php
│   │   ├── SSEConnection.html
│   │   ├── Scalable-Broadcast.html
│   │   ├── Video-Conferencing.html
│   │   ├── camera-zoom.html
│   │   ├── dashboard/
│   │   │   ├── canvas-designer-old.html
│   │   │   ├── canvas-designer.html
│   │   │   ├── index-old.html
│   │   │   └── index.html
│   │   ├── file-sharing.html
│   │   ├── getStats.html
│   │   ├── index.html
│   │   ├── menu.js
│   │   ├── screen-sharing.html
│   │   ├── stylesheet.css
│   │   ├── text-chat-file-sharing.html
│   │   ├── translate-text-chat.html
│   │   ├── video-and-screen-sharing.html
│   │   ├── video-broadcasting.html
│   │   ├── video-conference/
│   │   │   ├── index.html
│   │   │   └── video-conference.html
│   │   ├── video-conferencing-chat-filesharing.html
│   │   └── vuejs-video-conferencing.html
│   ├── dev/
│   │   ├── BandwidthHandler.js
│   │   ├── BluetoothConnection.js
│   │   ├── CodecsHandler.js
│   │   ├── FileProgressBarHandler.js
│   │   ├── FileSelector.js
│   │   ├── FirebaseConnection.js
│   │   ├── IceServersHandler.js
│   │   ├── MediaStreamRecorder.js
│   │   ├── MultiPeersHandler.js
│   │   ├── MultiStreamsMixer.js
│   │   ├── OnIceCandidateHandler.js
│   │   ├── Plugin.EveryWhere.js
│   │   ├── PubNubConnection.js
│   │   ├── README.md
│   │   ├── RTCMultiConnection.js
│   │   ├── RTCPeerConnection.js
│   │   ├── RecordingHandler.js
│   │   ├── SSEConnection.js
│   │   ├── SignalRConnection.js
│   │   ├── SipConnection.js
│   │   ├── SocketConnection.js
│   │   ├── StreamHasData.js
│   │   ├── StreamsHandler.js
│   │   ├── TextSenderReceiver.js
│   │   ├── TranslationHandler.js
│   │   ├── WebSocketConnection.js
│   │   ├── WebSyncConnection.js
│   │   ├── XHRConnection.js
│   │   ├── amd.js
│   │   ├── enableV2Api.js
│   │   ├── getHTMLMediaElement.css
│   │   ├── getHTMLMediaElement.js
│   │   ├── getUserMedia.js
│   │   ├── globals.js
│   │   ├── gumadapter.js
│   │   ├── head.js
│   │   ├── ios-hacks.js
│   │   └── tail.js
│   ├── dist/
│   │   ├── README.md
│   │   └── RTCMultiConnection.js
│   ├── docs/
│   │   ├── README.md
│   │   ├── api.md
│   │   ├── getting-started.md
│   │   ├── how-to-use.md
│   │   ├── installation-guide.md
│   │   ├── ios-android.md
│   │   ├── tips-tricks.md
│   │   └── upgrade.md
│   ├── fake-keys/
│   │   ├── certificate.pem
│   │   └── privatekey.pem
│   ├── logs.json
│   ├── npm-test.js
│   ├── package.json
│   └── server.js
├── RTCMultiConnection-Server/
│   ├── .gitignore
│   ├── .npmignore
│   ├── LICENSE
│   ├── README.md
│   ├── bower.json
│   ├── config.json
│   ├── fake-keys/
│   │   ├── certificate.pem
│   │   └── privatekey.pem
│   ├── logs.json
│   ├── package.json
│   └── server.js
├── RTCMultiConnection-SignalR/
│   ├── LICENSE
│   ├── README.md
│   ├── RTCMultiConnection/
│   │   ├── Properties/
│   │   │   └── AssemblyInfo.cs
│   │   ├── RTCMultiConnection.csproj
│   │   ├── RTCMultiConnectionHub.cs
│   │   ├── RTCMultiConnectionSignaling.cs
│   │   ├── Scripts/
│   │   │   ├── RTCMultiConnection.js
│   │   │   ├── jquery-1.10.2.intellisense.js
│   │   │   ├── jquery-1.10.2.js
│   │   │   └── jquery.signalR-2.1.2.js
│   │   ├── SignalRConnection.js
│   │   ├── Web.Debug.config
│   │   ├── Web.Release.config
│   │   ├── Web.config
│   │   ├── index.html
│   │   └── packages.config
│   ├── RTCMultiConnection.sln
│   └── packages/
│       └── README.md
├── RTCPeerConnection/
│   ├── README.md
│   ├── RTCPeerConnection-Helpers.js
│   ├── RTCPeerConnection-v1.1.js
│   ├── RTCPeerConnection-v1.2.js
│   ├── RTCPeerConnection-v1.3.js
│   ├── RTCPeerConnection-v1.4.js
│   ├── RTCPeerConnection-v1.5.js
│   ├── RTCPeerConnection-v1.6.js
│   └── RTCPeerConnection.js
├── RTCall/
│   ├── README.md
│   ├── RTCall.js
│   └── index.html
├── Record-Entire-Meeting/
│   ├── .gitignore
│   ├── .npmignore
│   ├── Browser-Recording-Helper.js
│   ├── Concatenate-Recordings.js
│   ├── MediaStreamRecorder.js
│   ├── Nodejs-Recording-Handler.js
│   ├── README.md
│   ├── Write-Recordings-To-Disk.js
│   ├── fake-keys/
│   │   ├── certificate.pem
│   │   └── privatekey.pem
│   ├── index.html
│   ├── package.json
│   └── server.js
├── RecordRTC/
│   ├── .gitignore
│   ├── .jshintrc
│   ├── .npmignore
│   ├── .travis.yml
│   ├── CONTRIBUTING.md
│   ├── Canvas-Recording/
│   │   ├── Canvas-Animation-Recording-Plus-Microphone-Plus-Mp3.html
│   │   ├── Canvas-Animation-Recording-Plus-Microphone.html
│   │   ├── Canvas-Animation-Recording-Plus-Mp3.html
│   │   ├── Canvas-Animation-Recording.html
│   │   ├── README.md
│   │   ├── canvas-designer.js
│   │   ├── index.html
│   │   ├── record-canvas-drawings.html
│   │   ├── video.webm
│   │   └── webpage-recording.html
│   ├── Gruntfile.js
│   ├── LICENSE
│   ├── MRecordRTC/
│   │   ├── README.md
│   │   └── index.html
│   ├── PHP-and-FFmpeg/
│   │   ├── .htaccess
│   │   ├── README.md
│   │   ├── index.html
│   │   ├── save.php
│   │   └── uploads/
│   │       └── README.md
│   ├── README.md
│   ├── RecordRTC-over-Socketio/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── ffmpeg-output/
│   │   │   └── README.md
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── server.js
│   │   └── uploads/
│   │       └── README.md
│   ├── RecordRTC-to-ASPNETMVC/
│   │   ├── README.md
│   │   ├── RecordRTC_to_ASPNETMVC/
│   │   │   ├── Controllers/
│   │   │   │   ├── README.md
│   │   │   │   └── RecordRTCController.cs
│   │   │   ├── Global.asax
│   │   │   ├── Global.asax.cs
│   │   │   ├── Properties/
│   │   │   │   └── AssemblyInfo.cs
│   │   │   ├── RecordRTC_to_ASPNETMVC.csproj
│   │   │   ├── RecordRTC_to_ASPNETMVC.csproj.user
│   │   │   ├── Views/
│   │   │   │   ├── RecordRTC/
│   │   │   │   │   └── Index.cshtml
│   │   │   │   ├── Web.config
│   │   │   │   └── _ViewStart.cshtml
│   │   │   ├── Web.Debug.config
│   │   │   ├── Web.Release.config
│   │   │   ├── Web.config
│   │   │   ├── bin/
│   │   │   │   └── RecordRTC_to_ASPNETMVC.pdb
│   │   │   └── uploads/
│   │   │       └── README.md
│   │   └── RecordRTC_to_ASPNETMVC.sln
│   ├── RecordRTC-to-Nodejs/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── index.html
│   │   ├── package.json
│   │   └── server.js
│   ├── RecordRTC-to-PHP/
│   │   ├── .htaccess
│   │   ├── README.md
│   │   ├── delete.php
│   │   ├── index.html
│   │   ├── save.php
│   │   └── uploads/
│   │       └── README.md
│   ├── RecordRTC.js
│   ├── WebGL-Recording/
│   │   ├── README.md
│   │   ├── assets/
│   │   │   ├── DST-Canopy.ogg
│   │   │   ├── blank.cur
│   │   │   ├── duck.dae
│   │   │   ├── pickup.ogg
│   │   │   ├── scene.xml
│   │   │   ├── seymourplane_triangulate.dae
│   │   │   └── target.dae
│   │   ├── index.html
│   │   ├── logic.js
│   │   ├── plotly.html
│   │   ├── style.css
│   │   ├── vendor/
│   │   │   ├── README.md
│   │   │   ├── backbone-min.js
│   │   │   ├── buzz.js
│   │   │   ├── glge-compiled-min.js
│   │   │   ├── glge-compiled.js
│   │   │   └── underscore-min.js
│   │   └── view.js
│   ├── bower.json
│   ├── dev/
│   │   ├── CanvasRecorder.js
│   │   ├── Cross-Browser-Declarations.js
│   │   ├── DiskStorage.js
│   │   ├── GetRecorderType.js
│   │   ├── GifRecorder.js
│   │   ├── MRecordRTC.js
│   │   ├── MediaStreamRecorder.js
│   │   ├── MultiStreamRecorder.js
│   │   ├── MultiStreamsMixer.js
│   │   ├── README.md
│   │   ├── RecordRTC-Configuration.js
│   │   ├── RecordRTC.IndexedDB.js
│   │   ├── RecordRTC.js
│   │   ├── RecordRTC.promises.js
│   │   ├── StereoAudioRecorder.js
│   │   ├── Storage.js
│   │   ├── WebAssemblyRecorder.js
│   │   ├── Whammy.js
│   │   ├── WhammyRecorder.js
│   │   ├── amd.js
│   │   └── isMediaRecorderCompatible.js
│   ├── index.html
│   ├── libs/
│   │   ├── EBML.js
│   │   ├── gif-recorder.js
│   │   ├── webm-wasm.js
│   │   ├── webm-wasm.wasm
│   │   └── webm-worker.js
│   ├── npm-test.js
│   ├── package.json
│   ├── server.js
│   ├── simple-demos/
│   │   ├── 16khz-audio-recording.html
│   │   ├── README.md
│   │   ├── Record-Mp3-or-Wav.html
│   │   ├── RecordRTCPromisesHandler.html
│   │   ├── RecordRTC_Extension.html
│   │   ├── WebAssemblyRecorder.html
│   │   ├── audio-recording.html
│   │   ├── auto-stop-on-silence.html
│   │   ├── bitsPerSecond.html
│   │   ├── calculate-recording-duration.html
│   │   ├── destroy.html
│   │   ├── edge-audio-recording.html
│   │   ├── embedded-iframes.html
│   │   ├── gif-recording.html
│   │   ├── index.html
│   │   ├── isTypeSupported.html
│   │   ├── multi-audios-recording.html
│   │   ├── multi-cameras-recording.html
│   │   ├── onStateChanged.html
│   │   ├── onTimeStamp.html
│   │   ├── ondataavailable-StereoAudioRecorder.html
│   │   ├── ondataavailable.html
│   │   ├── pass-getUserMedia-constraints.html
│   │   ├── php-upload-jquery.html
│   │   ├── php-upload-simple-javascript.html
│   │   ├── preview-blob-size-during-recording.html
│   │   ├── raw-pcm.html
│   │   ├── record-cropped-screen.html
│   │   ├── recording-html-element.html
│   │   ├── reuse-same-instance.html
│   │   ├── screen-recording.html
│   │   ├── seeking-workaround.html
│   │   ├── setRecordingDuration.html
│   │   ├── show-animated-bar-on-video.html
│   │   ├── show-logo-on-recorded-video.html
│   │   ├── video-mirror-recording.html
│   │   ├── video-plus-screen-recording.html
│   │   └── video-recording.html
│   └── test/
│       ├── README.md
│       ├── audio-recording-using-StereoAudioRecorder.js
│       ├── audio-recording.js
│       ├── browserstack.config.js
│       ├── canvas-recording.js
│       ├── html-test-files/
│       │   ├── README.md
│       │   ├── audio-recording-using-StereoAudioRecorder.html
│       │   ├── audio-recording.html
│       │   ├── canvas-recording.html
│       │   ├── video-recording-using-WhammyRecorder.html
│       │   └── video-recording.html
│       ├── video-recording-using-WhammyRecorder.js
│       └── video-recording.js
├── Reliable-Signaler/
│   ├── README.md
│   ├── datachannel-client/
│   │   ├── README.md
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── server.js
│   │   └── style.css
│   ├── index.js
│   ├── package.json
│   ├── reliable-signaler.js
│   ├── rtcmulticonnection-client/
│   │   ├── README.md
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── server.js
│   │   └── style.css
│   ├── signaler.js
│   └── videoconferencing-client/
│       ├── README.md
│       ├── RTCPeerConnection-v1.5.js
│       ├── conference.js
│       ├── index.html
│       ├── package.json
│       ├── server.js
│       └── style.css
├── Signaling.md
├── Translator.js/
│   ├── README.md
│   ├── Robot-Speaker.js
│   ├── Translator.js
│   └── index.html
├── WebRTC-File-Sharing/
│   ├── File.js
│   ├── PeerConnection.js
│   ├── README.md
│   └── index.html
├── WebRTC-Scalable-Broadcast/
│   ├── .gitignore
│   ├── .npmignore
│   ├── README.md
│   ├── RTCMultiConnection.js
│   ├── WebRTC-Scalable-Broadcast.js
│   ├── index.html
│   ├── package.json
│   ├── server.js
│   └── share-files.html
├── audio-broadcast/
│   ├── README.md
│   ├── broadcast-ui.js
│   ├── broadcast.js
│   └── index.html
├── broadcast/
│   ├── README.md
│   ├── broadcast-ui.js
│   ├── broadcast.js
│   └── index.html
├── chat-hangout/
│   ├── README.md
│   ├── hangout-ui.js
│   ├── hangout.js
│   └── index.html
├── demos/
│   ├── MediaStreamTrack.getSources.html
│   ├── README.md
│   ├── audio-only-streaming.html
│   ├── client-side-datachannel.html
│   ├── client-side-socket-io.html
│   ├── client-side-websocket.html
│   ├── client-side.html
│   ├── remote-stream-recording.html
│   ├── screen-and-video-from-single-peer.html
│   └── switch-streams.html
├── desktop-sharing/
│   ├── README.md
│   ├── index.html
│   └── old.html
├── docs/
│   ├── How-to-Broadcast-Screen-using-WebRTC.html
│   ├── README.md
│   ├── RTP-usage.html
│   ├── STUN-or-TURN.html
│   ├── Share-Files-using-Filejs.html
│   ├── TURN-server-installation-guide.html
│   ├── WebRTC-PeerConnection.html
│   ├── WebRTC-Signaling-Concepts.html
│   ├── echo-cancellation.html
│   ├── how-file-broadcast-works.html
│   ├── how-to-WebRTC-video-conferencing.html
│   ├── how-to-broadcast-video-using-RTCWeb-APIs.html
│   ├── how-to-install-tabCapture-extension.html
│   ├── how-to-share-audio-only-streams.html
│   ├── how-to-switch-streams.html
│   ├── how-to-use-plugin-free-calls.html
│   ├── how-to-use-rtcdatachannel-and-rtcpeerconnectionjs.html
│   ├── how-to-use-rtcdatachannel.html
│   ├── how-to-use-rtcpeerconnection-js-v1.1.html
│   ├── rtc-datachannel-for-beginners.html
│   ├── webrtc-for-beginners.html
│   ├── webrtc-for-newbies.html
│   └── webrtcpedia/
│       └── index.html
├── experimental/
│   ├── README.md
│   ├── mozCaptureStreamUntilEnded/
│   │   ├── README.md
│   │   └── index.html
│   ├── remote-media-stream-attachment/
│   │   ├── README.md
│   │   └── index.html
│   └── remote-stream-recording.html
├── ffmpeg/
│   ├── LICENSE
│   ├── README.md
│   ├── audio-plus-canvas-recording.html
│   ├── audio-plus-screen-recording.html
│   ├── index.html
│   ├── merging-wav-and-webm-into-mp4.html
│   ├── server.js
│   ├── video-cropping.html
│   ├── wav-to-aac.html
│   ├── wav-to-ogg.html
│   ├── webm-to-mp4.html
│   └── worker-asm.js
├── file-hangout/
│   ├── README.md
│   ├── file-hangout.js
│   └── index.html
├── file-sharing/
│   ├── README.md
│   ├── data-connection.js
│   └── index.html
├── getDisplayMedia/
│   ├── README.md
│   └── index.html
├── getMediaElement/
│   ├── .npmignore
│   ├── README.md
│   ├── getAudioElement.html
│   ├── getMediaElement-v1.2/
│   │   ├── getMediaElement-v1.2.css
│   │   └── getMediaElement-v1.2.js
│   ├── getMediaElement.css
│   ├── getMediaElement.js
│   ├── getVideoElement.html
│   ├── index.html
│   └── package.json
├── getScreenId.js/
│   ├── .npmignore
│   ├── LICENSE
│   ├── README.md
│   ├── Screen-Capturing.js
│   ├── getScreenId.html
│   ├── getScreenId.js
│   ├── index.html
│   ├── package.json
│   └── server.js
├── getStats/
│   ├── .gitignore
│   ├── .npmignore
│   ├── .travis.yml
│   ├── Gruntfile.js
│   ├── LICENSE.md
│   ├── README.md
│   ├── bower.json
│   ├── dev/
│   │   ├── README.md
│   │   ├── bweforvideo.js
│   │   ├── candidate-pair.js
│   │   ├── dataSentReceived.js
│   │   ├── datachannel.js
│   │   ├── getStats.js
│   │   ├── globals.js
│   │   ├── googCertificate.js
│   │   ├── googCodecName.audio.js
│   │   ├── googCodecName.video.js
│   │   ├── head.js
│   │   ├── inbound-rtp.js
│   │   ├── local-candidate.js
│   │   ├── module.exports.js
│   │   ├── outbound-rtp.js
│   │   ├── parameters.js
│   │   ├── remote-candidate.js
│   │   ├── ssrc.js
│   │   ├── tail.js
│   │   ├── track.js
│   │   └── wrapper.js
│   ├── getStats.js
│   ├── index.html
│   ├── package.json
│   └── server.js
├── gumadapter/
│   ├── README.md
│   ├── gumadapter.js
│   └── package.json
├── hark/
│   ├── README.md
│   └── hark.js
├── meeting/
│   ├── README.md
│   ├── index.html
│   ├── meeting.js
│   └── simple.html
├── navigator.customGetUserMediaBar/
│   ├── README.md
│   ├── index.html
│   └── navigator.customGetUserMediaBar.js
├── one-to-many-audio-broadcasting/
│   ├── README.md
│   ├── index.html
│   └── meeting.js
├── one-to-many-video-broadcasting/
│   ├── README.md
│   ├── index.html
│   └── meeting.js
├── part-of-screen-sharing/
│   ├── README.md
│   ├── firebase/
│   │   └── index.html
│   ├── iframe/
│   │   ├── index.html
│   │   └── otherpage.html
│   ├── realtime-chat/
│   │   ├── No-WebRTC-Chat.html
│   │   ├── README.md
│   │   └── how-this-work.html
│   ├── screenshot-dev.js
│   ├── screenshot.js
│   └── webrtc-data-channel/
│       └── index.html
├── realtime-pluginfree-calls/
│   ├── README.md
│   ├── index.html
│   ├── js/
│   │   ├── PeerConnection.js
│   │   ├── linkify.js
│   │   └── script.js
│   ├── old/
│   │   ├── README.md
│   │   ├── call-initiator.js
│   │   ├── index.html
│   │   └── ui.js
│   ├── old2/
│   │   └── index.html
│   └── style.css
├── screen-broadcast/
│   ├── README.md
│   └── index.html
├── screen-sharing/
│   ├── README.md
│   ├── index.html
│   └── screen.js
├── server.js
├── socket.io/
│   ├── PeerConnection.js
│   ├── README.md
│   └── index.html
├── socketio-over-nodejs/
│   ├── README.md
│   ├── fake-keys/
│   │   ├── certificate.pem
│   │   └── privatekey.pem
│   ├── package.json
│   └── server.js
├── text-chat/
│   ├── README.md
│   ├── data-connection.js
│   └── index.html
├── video-conferencing/
│   ├── README.md
│   ├── conference.js
│   ├── index.html
│   └── server.js
├── webrtc-broadcasting/
│   ├── README.md
│   ├── broadcast.js
│   ├── index.html
│   └── server.js
├── websocket/
│   ├── PeerConnection.js
│   ├── README.md
│   └── index.html
└── websocket-over-nodejs/
    ├── README.md
    ├── fake-keys/
    │   ├── certificate.pem
    │   └── privatekey.pem
    ├── package.json
    └── server.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
RecordRTC/RecordRTC-to-Nodejs/uploads/
*.DS_Store
ffmpeg/ffmpeg_asm.js
node_modules
RecordRTC/node_modules
DetectRTC/node_modules
RTCMultiConnection/node_modules


================================================
FILE: Canvas-Designer/.gitignore
================================================
node_modules
bower_components

*.tar.gz
lib-cov

.*.swp
._*
.DS_Store
.git
.hg
.npmrc
.lock-wscript
.svn
.wafpickle-*
config.gypi
CVS
npm-debug.log

================================================
FILE: Canvas-Designer/.npmignore
================================================
# ignore everything
*

# but not these files...
!canvas-designer-widget.js
!widget.html
!widget.js
!widget.min.js
!dev/webrtc-handler.js
!index.html
!package.json
!bower.json
!server.js
!README.md

================================================
FILE: Canvas-Designer/.travis.yml
================================================

language: node_js
node_js:
  - "0.11"
install: npm install
before_script:
  - npm install grunt-cli@0.1.13 -g
  - npm install grunt@0.4.5
  - grunt --verbose
after_failure: npm install && grunt
matrix:
  fast_finish: true


================================================
FILE: Canvas-Designer/Gruntfile.js
================================================
'use strict';

module.exports = function(grunt) {
    require('load-grunt-tasks')(grunt, {
        pattern: 'grunt-*',
        config: 'package.json',
        scope: 'devDependencies'
    });

    var banner = '// Last time updated: <%= grunt.template.today("UTC:yyyy-mm-dd h:MM:ss TT Z") %>\n\n';

    // configure project
    grunt.initConfig({
        // make node configurations available
        pkg: grunt.file.readJSON('package.json'),
        concat: {
            options: {
                stripBanners: true,
                separator: '\n',
                banner: banner
            },
            dist: {
                src: [
                    'dev/head.js',
                    'dev/common.js',

                    'dev/draw-helper.js',
                    'dev/drag-helper.js',
                    'dev/pencil-handler.js',
                    'dev/marker-handler.js',
                    'dev/eraser-handler.js',
                    'dev/text-handler.js',
                    'dev/arc-handler.js',
                    'dev/line-handler.js',
                    'dev/arrow-handler.js',
                    'dev/rect-handler.js',
                    'dev/quadratic-handler.js',
                    'dev/bezier-handler.js',
                    'dev/zoom-handler.js',
                    'dev/file-selector.js',
                    'dev/image-handler.js',
                    'dev/pdf-handler.js',

                    'dev/data-uris.js',

                    'dev/decorator.js',
                    'dev/events-handler.js',

                    'dev/share-drawings.js',
                    'dev/webrtc-handler.js',
                    'dev/canvas-designer-widget.js',

                    'dev/tail.js'
                ],
                dest: 'widget.js',
            },
        },
        uglify: {
            options: {
                mangle: false,
                banner: banner
            },
            my_target: {
                files: {
                    'widget.min.js': ['widget.js']
                }
            }
        },
        jsbeautifier: {
            files: ['widget.js', 'dev/*.js'],
            options: {
                js: {
                    braceStyle: "collapse",
                    breakChainedMethods: false,
                    e4x: false,
                    evalCode: false,
                    indentChar: " ",
                    indentLevel: 0,
                    indentSize: 4,
                    indentWithTabs: false,
                    jslintHappy: false,
                    keepArrayIndentation: false,
                    keepFunctionIndentation: false,
                    maxPreserveNewlines: 10,
                    preserveNewlines: true,
                    spaceBeforeConditional: true,
                    spaceInParen: false,
                    unescapeStrings: false,
                    wrapLineLength: 0
                },
                html: {
                    braceStyle: "collapse",
                    indentChar: " ",
                    indentScripts: "keep",
                    indentSize: 4,
                    maxPreserveNewlines: 10,
                    preserveNewlines: true,
                    unformatted: ["a", "sub", "sup", "b", "i", "u"],
                    wrapLineLength: 0
                },
                css: {
                    indentChar: " ",
                    indentSize: 4
                }
            }
        },
        bump: {
            options: {
                files: ['package.json', 'bower.json'],
                updateConfigs: [],
                commit: true,
                commitMessage: 'v%VERSION%',
                commitFiles: ['package.json', 'bower.json'],
                createTag: true,
                tagName: '%VERSION%',
                tagMessage: '%VERSION%',
                push: false,
                pushTo: 'upstream',
                gitDescribeOptions: '--tags --always --abbrev=1 --dirty=-d'
            }
        },
        watch: {
          scripts: {
            files: ['dev/*.js'],
            tasks: ['concat', 'jsbeautifier', 'uglify'],
            options: {
              spawn: false,
            },
          },
        }
    });

    // enable plugins

    // set default tasks to run when grunt is called without parameters
    // http://gruntjs.com/api/grunt.task
    grunt.registerTask('default', ['concat', 'jsbeautifier', 'uglify']);
    grunt.loadNpmTasks('grunt-contrib-watch');
};


================================================
FILE: Canvas-Designer/Help/index.html
================================================
<!DOCTYPE html>
<html itemscope itemtype="http://schema.org/WebPage">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
	<meta name="viewport" content="width=device-width,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0, user-scalable=no">

	<title>Canvas Designer Help ® Muaz Khan</title>    
	<meta name="description" content="Help for HTML5 Canvas Designer ® Muaz Khan – A tool aimed to give you a full-fledged drawing surface and also auto generate appropriate code for you in different formats!">

	<meta name="author" content="Muaz Khan">
	<link rel="author" type="text/html" href="https://plus.google.com/+MuazKhan">

	<link href="../Style.css" rel="stylesheet">
	<style>
		.highlight {
			color: rgb(166, 20, 20);
		}
        html, body {
            overflow: auto;
            height: auto;
        }
        body {
            padding: 0 5%;
            -webkit-user-select: initial;
        }
        h1, footer {
            height: auto;
            margin: 0 -10%;
        }
	</style>
</head>
<body>
	<h1>Canvas Designer Help</h1>
	<div>
		<h2>
			Introducing the tool!
		</h2>
		<p>
			<a href="../" title="HTML5 Canvas Designer/Tool">Canvas Designer is a tool</a> aimed to give you a full-fledged drawing surface and also auto generate appropriate code for you in different formats!
		</p>
		<p>
			It targets <a href="http://www.w3c.org/TR/2dcontext/" title="HTML5 Canvas 2D Context">Canvas 2D Context</a> – i.e. it gives you a <strong>built-in IDE</strong> for <a href="http://www.w3c.org/TR/2dcontext/" title="HTML5 Canvas 2D Context">Canvas 2D API</a>s!
		</p>
	    <p>
	        Obviously, it is developed & designed solely by <a href="https://github.com/muaz-khan" rel="author" title="Muaz Khan's Google+ profile">Muaz Khan</a>!
	    </p>
	</div>
	<div>
		<h2>
			How files are arranged?
		</h2>
		<p>
			Each task or feature has a unique JavaScript file. It simplifies not only coding but also later edits and additions!
		</p>
		<ul>
			<li>
				<a href="../line-handler.js">line-handler.js</a> : for lines drawing!
			</li>
			<li>
				<a href="../arc-handler.js">arc-handler.js</a> : for arcs/circles drawing!
			</li>
			<li>
				<a href="../quadratic-handler.js">quadratic-handler.js</a> : for quadratic curves drawing!
			</li>
			<li>
				<a href="../bezier-handler.js">bezier-handler.js</a> : for bezier curves drawing!
			</li>
			<li>
				<a href="../rect-handler.js">rect-handler.js</a> : for rectangles drawing!
			</li>
		</ul>
		<p>
			Common task like output in textarea, global variables/objects etc. have been placed in <a href="../common.js">common.js</a> file.
		</p>
		<p>
			Dragging relevant code has been placed in <a href="../drag-helper.js">drag-helper.js</a> and drawing relevant code has been placed in <a href="../draw-helper.js">draw-helper.js</a> file. (<strong>Note:</strong> <a href="../draw-helper.js">draw-helper.js</a> is most important file in this project because functions it contains are repeatedly called from all portions of the project!)
		</p>
		<p>
			<a href="../events-handler.js">events-handler.js</a> is used to handle global events like mousemove, mouseup, mousedown and their touch relevant!
		</p>
		<p>
			There is a file <a href="../decorator.js">decorator.js</a> which is aimed to decorate the designer; i.e. to decorate the design surface, toolbox, etc.
		</p>
	</div>
	
	<div>
		<h2>
			How I store coordinates?
		</h2>
		<p>
			There is a global variable named points of type array which stores all x/y coordinates plus extra values in the following style:
		</p>
		<pre>
var points = [['shape', [x, y], [lineWidth, strokeStyle, fillStyle, globalAlpha, globalCompositeOperation, lineCap, lineJoin]]];
</pre>
		<p>
			i.e.
		</p>
		<pre>
var points = [path-name, path-coordinates, path-options];
</pre>
		<p>
			Where: 
		</p>
		<ol>
			<li>
				<code>path-name</code> can be line/arc/rect/quadratic/bezier etc.
			</li>
			<li>
				<code>path-coordinates</code> are the shape's x/y coordinates + width, height, radius etc.
			</li>
			<li>
				<code>path-options</code> are line-width, stroke/fill styles, global alpha/composite-operation, line cap/join etc.
			</li>
		</ol>
	</div>
	
	<div>
		<h2>
			Digging into the code!
		</h2>
		<p>
			<a href="../draw-helper.js">draw-helper.js</a> defines a method named "<code>redraw</code>" that is one of the most called functions in this project. <code>redraw</code> aimed to refresh all points on the drawing surface! By default, this function is called on each <code>mousedown</code>/<code>mouseup</code> event; however, in some cases, it is also called in <code>mousemove</code> event. (See <a href="../drag-helper.js">drag-helper.js</a> file)
		</p>
		<p>
			<a href="../common.js">common.js</a> defines second most called function "<code>updateTextArea</code>" which is aimed to update the output accordingly.
		</p>
		<p>
			In the top of <a href="../common.js">common.js</a> file; there is an object "<code>is</code>" which contains <code>Boolean</code> properties for selected toolbox shape(s). Mouse/Touch events in the <a href="../events-handler.js">events-handler.js</a> are using these properties to call appropriate objects!
		</p>
	</div>
	
	<div id="copy">
		<h2>
			How to copy and paste?
		</h2>
		<p>
			You can use <code>Ctrl + C</code> for copy and <code>Ctrl + V</code> for paste. You can also use <code>Ctrl + MouseDown</code> for directly copy and paste!
		</p>
		<p>
			You can copy in two formats:
		</p>
	    <ol>
	        <li>
	            Copy last path
	        </li>
	        <li>
	            Copy all paths (at a time!)
	        </li>
	    </ol>
	    <p>
	        <strong>Remember:</strong> <code>Ctrl + MouseDown</code> will only work if one option is selected: <code>DragAllPaths</code> or <code>DragLastPath</code> (from tool-box!)
	    </p>
	</div>
	
	<div id="undo">
		<h2>
			How to Undo?
		</h2>
		<p>
			You can undo using <strong>Ctrl + Z</strong>.
		</p>
		<p>
			You can also use <strong>Ctrl + A</strong> to select all drawing for dragging purpose!
		</p>
	</div>
	
	<div id="contribute">
		<h2>
			How to Contribute?
		</h2>
		<p>
			If you want to add new features in the <a href="../">Canvas Designer</a>; follow these steps:
		</p>
		<h2>
			1st Step: Add new toolbox icon!
		</h2>
		<p>
			You've to add something through which end-users can use/access your feature – you can add any HTML element for this purpose (e.g. checkbox, radio-button, button, etc.) – however I recommend you add new toolbox icon instead! (which is a <code>&lt;canvas&gt;</code> element!)
		</p>
		<pre>
&lt;div id="tool-box" class="tool-box"&gt;
	........................................
	&lt;canvas id="<span class="highlight">icon-unique-id</span>" width="40" height="40"&gt;&lt;/canvas&gt;
&lt;/div&gt;
</pre>
		<h2>
			2nd Step: Decorate the icon!
		</h2>
		<p>
			After adding above HTML code, if you refresh the page; you'll see an empty icon appended in the bottom of the toolbox. Now you've to decorate this icon so end users can understand it!
		</p>
		<p>
			Open <a href="../decorator.js">decorator.js</a> file and append following code anywhere in <a href="../decorator.js">the file</a>.
		</p>
		<pre>
function givenName() {
	var context = getContext('<span class="highlight">icon-unique-id</span>');

	// 2d context relevant code here! (decoration code!!!)

	bindEvent(context, '<span class="highlight">FeatureSelected</span>');
}
givenName();
</pre>
		<p>
			<code>FeatureSelected</code> is a global property used to understand the current state of your new toolbox icon (whether icon is selected or not). (Open <a href="../common.js">common.js</a> file)
		</p>
		<pre>
var is = {
	......................
	<span class="highlight">isFeatureSelected: false</span>,

	set: function (shape) {
		...................... = <span class="highlight">is.isFeatureSelected</span> = false;
		.............................................
	}
};
</pre>
		<h2>
			3rd Step: Create new JavaScript file
		</h2>
		<p>
			Now you've to create a new javascript file where you'll put all your "new feature" relevant code! Name the file like this: <strong>feature-handler.js</strong>
		</p>
		<pre>
var <span class="highlight">featureHandler</span> = {
	ismousedown: false,

	mousedown: function(e) {
		this.ismousedown = true;
	},
	
	mouseup: function(e) { 
		this.ismousedown = false;
	},
	
	mousemove: function(e) {
		if(this.ismousedown) { ... }
	}
};
</pre>
		<h2>
			4th Step: Bind mouse events
		</h2>
		<p>
			Now you've to bind mouse events to your newly created object. Open <a href="../events-handler.js">events-handler.js</a> and append following code:
		</p>
		<pre>
addEvent(canvas, isTouch ? 'touchstart' : 'mousedown', function (e) {
	............................................................
	<span class="highlight">else if (is.isFeatureSelected) featureHandler.mousedown(e);</span>
	............................................................
});

addEvent(document, isTouch ? 'touchend' : 'mouseup', function (e) {
	............................................................
	<span class="highlight">else if (is.isFeatureSelected) featureHandler.mouseup(e);</span>
	............................................................
});

addEvent(canvas, isTouch ? 'touchmove' : 'mousemove', function (e) {
	............................................................
	<span class="highlight">else if (is.isFeatureSelected) featureHandler.mousemove(e);</span>
	............................................................
});
</pre>
		<p>
			Now you are 80% done! I strongly recommend you place your feature's drawing relevant code in the <a href="../draw-helper.js">draw-helper.js</a> file as I did for other features! - Reusability!!
		</p>
		<h2>
			5th Step: Handle the output (textarea!)
		</h2>
		<p>
			This is the last step. You've to handle the output for textarea.
		</p>
		<p>
			Open <a href="../common.js">common.js</a> file; there is a function "updateTextArea" in the "common" object – which is aimed to output into textarea element.
		</p>
		<p>
			You don't have to change "updateTextArea". For simplicity purpose, code is separated in different functions/properties that you've to edit:
		</p>
		<ol>
			<li>
				<code>common.forLoop</code>
			</li>
			<li>
				<code>common.absoluteNOTShortened</code>
			</li>
			<li>
				<code>common.relativeShortened</code>
			</li>
			<li>
				<code>common.relativeNOTShortened</code>
			</li>
		</ol>
		<p>
			Wait! – You've to edit "<code>init</code>" function and <a href="../drag-helper.js">drag-helper.js</a> file too! – See below div.
		</p>
	</div>
	
	<div>
		<h2>
			What "init" function in <a href="../drag-helper.js">drag-helper.js</a> do?
		</h2>
		<p>
			This function is aimed to draw little transparent-red circles around the stretchable points of the shape so end-user can stretch the shape using those points! (To test it; draw a line, then click arrow [first-icon] on toolbox!) – This function is called on <code>mousemove</code> event.
		</p>
		<pre>
if (p[0] === '<span class="highlight">your-shape</span>') {

	tempContext.beginPath();

	tempContext.arc(point[0], point[1], 10, Math.PI * 2, 0, !1);
	tempContext.arc(point[2], point[3], 10, Math.PI * 2, 0, !1);
	
	<span class="highlight">// For additional circles, copy above line and only change point's index!</span>

	tempContext.fill();
}
</pre>
		<p>
			You've to edit other two functions in the <a href="../drag-helper.js">drag-helper.js</a> file (It is absolutely necessary because it helps change points accordingly while dragging the shape!):
		</p>
		<ol>
			<li>
				<code>dragHelper.dragLastPath</code>
			</li>
			<li>
				<code>dragHelper.dragAllPaths</code>
			</li>
		</ol>
		<pre>
/*≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡*/
// in "dragAllPaths":
if (p[0] === '<span class="highlight">your-shape-name</span>') {
	
	points[i] = [p[0], [
		getPoint(x, prevX, point[0]),
		getPoint(y, prevY, point[1]),
	], p[2]];
}

/*≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡*/
// in "dragLastPath":
if (p[0] === '<span class="highlight">your-shape-name</span>') {

	if (g.pointsToMove === '<span class="highlight">moveTo-points</span>' || isMoveAllPoints) {
		point[0] = getPoint(x, prevX, point[0]);
		point[1] = getPoint(y, prevY, point[1]);
	}

	points[points.length - 1] = [p[0], point, p[2]];
}

/*≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡*/
// in "mousedown" event (in the <a href="../drag-helper.js">same file</a>!)
if (p[0] === '<span class="highlight">your-shape-name</span>') {

	if (dHelper.isPointInPath(x, y, point[0], point[1])) {
		g.pointsToMove = '<span class="highlight">moveTo-points</span>';
	}
}
/*≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡*/
</pre>
		<p>
			Now you're 100% done!
		</p>
	</div>
	
	<div>
		<h2>
			How I drag shapes?
		</h2>
		<p>
			I did a detailed post about this: <a href="http://muaz-khan.blogspot.com/2012/02/draggingmoving-shapes-smoothly-using_12.html">Dragging/Moving shapes smoothly using Canvas 2d APIs</a>
		</p>
		<p>
			In the <a href="../drag-helper.js">drag-helper.js</a> file – "<code>global</code>" object contains following three properties:
		</p>
		<ol>
			<li>
				<code>prevX</code>
			</li>
			<li>
				<code>prevY</code>
			</li>
			<li>
				<code>pointsToMove</code>
			</li>
		</ol>
		<p>
			<code>prevX/prevY</code> aimed to save previous <code>mousedown</code> points so we can extract the dragged distance accordingly!
		</p>
		<p>
			<code>pointsToMove</code> aimed to understand which point of the shape is to move – e.g. first control points of the last Bezier curve or second control points (or moving/ending points!)
		</p>
		<pre>
<span class="highlight">dragHelper.getPoint</span>: function (point, prev, otherPoint) {
	if (point > prev) point = otherPoint + (point - prev);
	else point = otherPoint - (prev - point);

	return point;
}
</pre>
		<p>
			<code>dragHelper.getPoint</code> returns the dragged distance!
		</p>
	</div>
	
	<div id="relative-and-absolute">
		<h2>
			Explaining relative and absolute coordinates
		</h2>
		<p>
			By default, output in the textarea is provided in absolute coordinates. However, you can choose relative option too. Relative means points are relative to each other. If one or two points changes; all subsequent also changes, accordingly. Relative coordinates help you drag/move shape(s) at any portion of the screen without any bit of disturbance in the original shape!
		</p>
		<p>
			You can set pageX/pageY (or offset top/left) values to x-y objects and move whole shape on mousemove/mouseup/mousedown or at any other event!
		</p>
		<p>
			You can get shortened code for both formats: relative and absolute! Normal code is also provided there!
		</p>
	</div>

	<footer itemprop="breadcrumb">
		<a href="http://twitter.com/muazkh" title="@muazkh">©</a> <a href="https://plus.google.com/+MuazKhan" rel="author" title="Muaz Khan's Google+ profile">Muaz Khan</a>
		(<a href="mailto:muazkh@gmail.com" title="muazkh@gmail.com">Email</a>) ® <a href="../" title="Canvas-Designer: Drawing Tool">Canvas Designer</a>
		- <a href="https://github.com/muaz-khan/Canvas-Designer" title="Source code on Github">Source Code</a>
	</footer>
</body>
</html>

================================================
FILE: Canvas-Designer/LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2017 [Muaz Khan](https://github.com/muaz-khan)

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


================================================
FILE: Canvas-Designer/README.md
================================================
# [Canvas Designer](https://github.com/muaz-khan/Canvas-Designer) / [API Referencee](https://github.com/muaz-khan/Canvas-Designer#api-reference)

## Demo: https://www.webrtc-experiment.com/Canvas-Designer/

## Advance Demo: [demos/dashboard/](https://rtcmulticonnection.herokuapp.com/demos/dashboard/)

Multiple designers demo: https://www.webrtc-experiment.com/Canvas-Designer/multiple.html

### YouTube video:

* https://www.youtube.com/watch?v=pvAj5l_v3cM

[![npm](https://img.shields.io/npm/v/canvas-designer.svg)](https://npmjs.org/package/canvas-designer) [![downloads](https://img.shields.io/npm/dm/canvas-designer.svg)](https://npmjs.org/package/canvas-designer) [![Build Status: Linux](https://travis-ci.org/muaz-khan/Canvas-Designer.png?branch=master)](https://travis-ci.org/muaz-khan/Canvas-Designer)

> "Collaborative" [Canvas Designer](https://github.com/muaz-khan/Canvas-Designer) i.e. Canvas-Drawing tool allows you draw bezier/quadratic curves, rectangles, circles and lines. You can also set strokes, back/forth colors and much more. You can draw using pencils, erase drawing, type texts etc. You can [easily add your own tools](https://www.webrtc-experiment.com/Canvas-Designer/Help/#contribute).

**You can check all releases here:**

* https://github.com/muaz-khan/Canvas-Designer/releases

The specialty of this drawing-tool is that, it generates Canvas2D code for you; so simply draw and get the code! That code can be used in any javascript Canvas2D application.

**You can submit issues here:**

* https://github.com/muaz-khan/Canvas-Designer/issues

Also, you can collaborate your drawing with up to 15 users; and everything is synced from all users. So, if you draw a line and your friend-A draws quadratic curve and friend-B draws rectangle then everything will be synced among all users!

### Youtube Videos

* https://www.youtube.com/watch?v=oSSwMlBu8SY

Gif images:

* https://www.webrtc-experiment.com/images/Canvas-Designer.gif

<img src="https://i.imgur.com/uDbfy1F.png" />

# Built-in tools

You can use [`designer.setSelected`](https://github.com/muaz-khan/Canvas-Designer#setselected) or [`designer.setTools`](https://github.com/muaz-khan/Canvas-Designer#settools) for below tools.

1. `line` --- to draw straight lines
2. `pencil` --- to write/draw shapes
3. `dragSingle` --- to drag/ove and especially **resize** last selected shape
4. `dragMultiple` --- to drag/move all shapes
5. `eraser` --- to erase/clear specific portion of shapes
6. `rectangle` --- to draw rectangles
7. `arc` --- to draw circles
8. `bezier` --- to draw bezier curves
9. `quadratic` --- to draw quadratic curves
10. `text` --- to write texts on single or multiple lines, select font families/sizes and more
11. `image` --- add external images
12. `arrow` --- draw arrow lines
13. `marker` --- draw markers
14. `lineWidth` --- set line width
15. `colorsPicker` --- background and foreground colors picker
16. `extraOptions` --- extra options eg. lineCap, lineJoin, globalAlpha, globalCompositeOperation etc.
17. `pdf` --- to import PDF
18. `code` --- to enable/disable code view
19. `undo` --- undo recent shapes

The correct name for `dragSingle` should be: `drag-move-resize last-selected-shape`.

The correct name for `dragMultiple` should be: `drag-move all-shapes`.

### Upcoming tools

1. Allow users to add video-streams or screen-streams or existing-webm-mp4-videos
2. Resize all shapes at once (currently you can resize last selected shape only)

# Features

1. Draw single or multiple shapes of any kind (according to toolbox)
2. Drag/resize/adjust all the shapes in any possible direction
3. Rectangles and images can be resized in 4-directions

   Red transparent small circles helps you understand how to resize.

4. Undo drawings using `ctrl+z` keys (undo all shapes, undo last 10 or specific shapes, undo range of shapes or undo last shape)
5. Drag/move single or all the shapes without affecting any single coordinate

More importantly, you can use unlimited designers on a single page. Each will have its own surface and its own tools.

# Chinese, Arabic, other languages

You can install following chrome extension for multi-language input tools:

* https://chrome.google.com/webstore/detail/google-input-tools/mclkkofklkfljcocdinagocijmpgbhab?hl=en

Now type your own language text in any `<input>` box or anywhere, and simply copy that text.

Now click `T` tool icon from the tool-box and press `ctrl+v` to paste your own language's text.

**To repeat it:**

1. Type your own language texts anywhere and make sure to copy to clipboard using `ctrl+v`
2. Then click `T` icon, and then press `ctrl+v` to paste your copied text

You can paste any text: English, Arabic, Chinese etc.

# How to Use

1. Download/link `canvas-designer-widget.js` from [this github repository](https://github.com/muaz-khan/Canvas-Designer).
2. Set `designer.widgetHtmlURL` and `designer.widgetJsURL` in your HTML file.
3. Use this command to append widget in your HTML page:

   `var designer = new CanvasDesigner();`

   `designer.appendTo(document.body);`

```html
<!-- 1st step -->
<script src="https://www.webrtc-experiment.com/Canvas-Designer/canvas-designer-widget.js"></script>

<!-- 2nd step -->
<script>
var designer = new CanvasDesigner();

// both links are mandatory
// widget.html will internally use widget.js
designer.widgetHtmlURL = 'https://www.webrtc-experiment.com/Canvas-Designer/widget.html'; // you can place this file anywhere
designer.widgetJsURL = 'https://www.webrtc-experiment.com/Canvas-Designer/widget.js';     // you can place this file anywhere
</script>

<!-- 3rd i.e. last step -->
<script>
// <iframe> will be appended to "document.body"
designer.appendTo(document.body || document.documentElement);
</script>
```

# Complete Usage

```javascript
var designer = new CanvasDesigner();

websocket.onmessage = function(event) {
    designer.syncData( JSON.parse(event.data) );
};

designer.addSyncListener(function(data) {
    websocket.send(JSON.stringify(data));
});

designer.setSelected('pencil');

designer.setTools({
    pencil: true,
    text: true
});

designer.appendTo(document.documentElement);
```

It is having `designer.destroy()` method as well.

# Use [WebRTC](http://www.rtcmulticonnection.org/docs/)!

```javascript
webrtc.onmessage = function(event) {
    designer.syncData( event.data );
};

designer.addSyncListener(function(data) {
    webrtc.send(data);
});
```

# Use Socket.io

```javascript
socket.on('message', function(data) {
    designer.syncData( data );
});

designer.addSyncListener(function(data) {
    socket.emit('message', data);
});
```

# API Reference

## `widgetHtmlURL`

You can place `widget.html` file anywhere on your site.

```javascript
designer.widgetHtmlURL = '/html-files/widget.html';
```

By default `widget.html` is placed in the same directory of `index.html`.

```javascript
// here is default value
designer.widgetHtmlURL = 'widget.html';
```

Remember, `widget.html` is loaded using `<iframe>`.

## `widgetJsURL`

> **Note:** This file is **internally used** by `widget.html`.

You can place `widget.html` file anywhere on your site.

```javascript
designer.widgetJsURL = '/js-files/widget.min.js';
```

By default `widget.min.js` is placed in the same directory of `index.html`.

```javascript
// here is default value
designer.widgetJsURL = 'widget.min.js';
```

Remember, `widget.js` is loaded using `<iframe>`.

## `syncData`

Pass array-of-points that are shared by remote users using socket.io or websockets or XMPP or WebRTC.

```javascript
designer.syncData(arrayOfPoints);
```

An example to pass custom data on Canvas-Designer:

```javascript
var x = 0;
var y = 0;
var width = designer.iframe.clientWidth;
var height = designer.iframe.clientHeight;

var image = 'https://www.webrtc-experiment.com/images/RTCMultiConnection-STUN-TURN-usage.png';

var points = [
    ['image', [image, x, y, width, height, 1], ['2', '#6c96c8', 'rgba(0,0,0,0)', '1', 'source-over', 'round', 'round', '15px "Arial"']]
];

designer.syncData({
    startIndex: 0,
    points: points
});
```

## `clearCanvas`

Remove and clear all drawings from the canvas:

```javascript
designer.clearCanvas();
```

## `renderStream`

Call this method internally to fix video rendering issues.

```javascript
designer.renderStream();
```

## `addSyncListener`

This callback is invoked as soon as something new is drawn. An array-of-points is passed over this function. That array MUST be shared with remote users for collaboration.

```javascript
designer.addSyncListener(function(data) {
    designer.send(JSON.stringify(data));
});
```

## `setSelected`

This method allows you select specific tools.

* See list of [all tools](https://github.com/muaz-khan/Canvas-Designer#built-in-tools)

```javascript
designer.setSelected('rectangle');
```

## `setTools`

This method allows you choose between tools that **should be displayed** in the tools-panel.

* See list of [all tools](https://github.com/muaz-khan/Canvas-Designer#built-in-tools)

```javascript
designer.setTools({
    line: true,
    arrow: true,
    pencil: true,
    marker: true,
    dragSingle: true,
    dragMultiple: true,
    eraser: true,
    rectangle: true,
    arc: true,
    bezier: true,
    quadratic: true,
    text: true,
    image: true,
    pdf: true,
    zoom: true,
    lineWidth: true,
    colorsPicker: true,
    extraOptions: true,
    code: true,
    undo: true
});
```

## `icons`

You can force/set your own tool-icons:

```javascript
designer.icons = {
    line: '/icons/line.png',
    arrow: '/icons/arrow.png',
    pencil: '/icons/pencil.png',
    dragSingle: '/icons/dragSingle.png',
    dragMultiple: '/icons/dragMultiple.png',
    eraser: '/icons/eraser.png',
    rectangle: '/icons/rectangle.png',
    arc: '/icons/arc.png',
    bezier: '/icons/bezier.png',
    quadratic: '/icons/quadratic.png',
    text: '/icons/text.png',
    image: '/icons/image.png',
    pdf: '/icons/pdf.png',
    pdf_next: '/icons/pdf-next.png',
    pdf_prev: '/icons/pdf-prev.png',
    marker: '/icons/marker.png',
    zoom: '/icons/zoom.png',
    lineWidth: '/icons/lineWidth.png',
    colorsPicker: '/icons/colorsPicker.png',
    extraOptions: '/icons/extraOptions.png',
    code: '/icons/code.png'
};
```

You can set like this as well:

```javascript
designer.icons.line = '/icons/line.png';
```

Default values are `NULL` to force icons from `/dev/data-dris.js`.

## `appendTo`

CanvasDesigner is a widget; that widget should be appended to a DOM object. This method allows you pass `<body>` or any other HTMLDOMElement.

```javascript
designer.appendTo(document.body || document.documentElement);

// or
designer.appendTo(document.body || document.documentElement, function() {
    alert('iframe load callback');
});
```

The correct name for `appendTo` is: `append-iframe to target HTML-DOM-element`

## `destroy`

If you want to remove the widget from your HTMLDOMElement.

```javascript
designer.destroy();
```

## `iframe`

You can access designer iframe as following:

```javascript
designer.iframe.style.border = '5px solid red';

window.open(designer.iframe.src);
```

`designer.iframe` will be `null/undefined` until you call `appendTo`. So always use this code-block:

```javascript
if(!designer.iframe) {
    designer.appendTo(document.body);
}
designer.iframe.style.border = '5px solid red';
```

## `toDataURL`

Get data-URL of your drawings!

```javascript
designer.toDataURL('image/png', function(dataURL) {
    window.open(dataURL);
});
```

## `sync`

You can manually sync drawings by invoking `designer.sync` method:

```javascript
designer.sync();
```

Here is a real usecase:

```javascript
webrtcDataChannel.onopen = function() {
    if(designer.pointsLength > 0) {
        // you seems having data to be synced with new user!
        designer.sync();
    }
};
```

## `captureStream`

Get `MediaStream` object and share in realtime using `RTCPeerConnection.addStream` API.

```html
<script src="dev/webrtc-handler.js"></script>
<script>
designer.captureStream(function(stream) {
    var url = URL.createObjectURL(stream);
    videoPreview.src = url;

    rtcPeerConnection.addStream(stream);
    rtcPeerConnection.createOffer(success, failure, params);
});
</script>
```

## `pointsLength`

Each shape is considered as a `point`. This value allows you check number of shapes that are already drawn on the canvas-designer.

```javascript
(function looper() {
    document.getElementById('number-of-shapes').inenrHTML = designer.pointsLength;
    setTimeout(looper, 1000);
})();
```

Or a real usage:

```javascript
websocket.onopen = function() {
    if(designer.pointsLength > 0) {
        // you seems having data to be synced with existing users!
        designer.sync();
    }
};
```

## `undo`

You can either undo drawings by pressing `ctrl+z` on windows and `command+z` on Mac; however you can undo using `designer.undo` method as well:

```javascript
designer.undo();   // undo last shape
designer.undo(-1); // undo last shape

// undo shape from specific index
designer.undo(0);

// undo all shapes
designer.undo('all');

// undo last 10 shapes
designer.undo({
    numberOfLastShapes: 10
})

// to remove all occurrences of a specific shape
designer.undo('pencil');
designer.undo('arrow');
designer.undo('rect');
```

`designer.pointsLength` shows number of shapes; and `designer.undo` accepts shape-index as well.

<h2 align="center">Add New Tools</h2>

## First Step

Open [`widget.html`](https://github.com/muaz-khan/Canvas-Designer/blob/master/widget.html) and add your new tool-icon HTML.

```html
<div id="tool-box" class="tool-box"> <!-- search for this div; and include your HTML inside this div -->
    <canvas id="yourNewToolIcon" width="40" height="40"></canvas> <!-- here is your icon-HTML -->
</div>
```

## Second Step

Open [`decorator.js`](https://github.com/muaz-khan/Canvas-Designer/blob/master/dev/decorator.js) and decorate your new HTML icon.

```javascript
var tools = {
    yourNewToolIcon: true // add this line to make sure index.html can use it
};
```

Search for `decorateLine` method, and append following snippet quickly after that method:

```javascript
function decorateYourNewToolIcon() {
    var context = getContext('yourNewToolIcon');

    context.fillStyle = 'Gray';
    context.font = '9px Verdana';
    context.fillText('New', 16, 12);

    bindEvent(context, 'YourNewToolIconSelected');
}

if (tools.yourNewToolIcon === true) {
    decorateYourNewToolIcon();
} else document.getElementById('yourNewToolIcon').style.display = 'none';
```

## Third Step

Open [`common.js`](https://github.com/muaz-khan/Canvas-Designer/blob/master/dev/common.js) and add selection-states for your new tool-icon (i.e. whether your new tool icon is selected or not):

```javascript
var is = {
    isYourNewToolIconSelected: false, // add this line

    set: function (shape) {
        var cache = this;

        cache.isYourNewToolIconSelected = false; // add this line as well.

        // ..... don't modify anything else
        cache['is' + shape] = true;
    }
};
```

You merely need to set `isYourNewToolIconSelected:true` also `cache.isYourNewToolIconSelected=false`.

## Fourth Step

Create new file in the [`dev`](https://github.com/muaz-khan/Canvas-Designer/tree/master/dev) directory. Name this file as `yourNewToolIcon-handler.js`.

This file MUST look like this:

```javascript
var yourNewToolIconHandler = {
    ismousedown: false,

    mousedown: function(e) {
        this.ismousedown = true;
    },

    mouseup: function(e) {
        this.ismousedown = false;
    },

    mousemove: function(e) {
        if(this.ismousedown) { ... }
    }
};
```

You can check other `*-handler.js` from [`dev`](https://github.com/muaz-khan/Canvas-Designer/tree/master/dev) directory to get the idea how exactly it works.

Now open [`Gruntfile.js#L43`](https://github.com/muaz-khan/Canvas-Designer/blob/master/Gruntfile.js#L43) and add link to your new file: `dev/events-handler.js`.

Now compile all your changes using `grunt`.

## Fifth Step

Open [`events-handler.js`](https://github.com/muaz-khan/Canvas-Designer/blob/master/dev/events-handler.js) and make sure that your above `yourNewToolIconHandler` object is called for mouse up/down/move events.

```javascript
addEvent(canvas, isTouch ? 'touchstart' : 'mousedown', function (e) {

    // you merely need to add this line at the end of this method
    else if (is.isYourNewToolIconSelected) yourNewToolIconHandler.mousedown(e);
});

addEvent(document, isTouch ? 'touchend' : 'mouseup', function (e) {

    // you merely need to add this line at the end of this method
    else if (is.isYourNewToolIconSelected) yourNewToolIconHandler.mouseup(e);
});

addEvent(canvas, isTouch ? 'touchmove' : 'mousemove', function (e) {

    // you merely need to add this line at the end of this method
    else if (is.isYourNewToolIconSelected) yourNewToolIconHandler.mousemove(e);
});
```

First of all, we are checking whether your tool-icon is selected or not: `is.isYourNewToolIconSelected`

Then we are calling `yourNewToolIconHandler` dot `mousedown/mouseup/mousemove` events respectively.

## Sixth Step

Open [`draw-helper.js`](https://github.com/muaz-khan/Canvas-Designer/blob/master/dev/draw-helper.js). Make sure that your new tool-icon can be drawn on the `<canvas>` surface.

```javascript
yourNewToolIcon: function(context, point, options) {
    context.beginPath();
    context.moveTo(point[0], point[1]);
    context.whateverYouWantToDoHere(point[2], point[3]);

    this.handleOptions(context, options);
}
```

Usually `point[0]` is `x` coordinates; `point[1]` is `y` coordinates; `point[2]` is `width` and `point[3]` is `height`.

Different shapes can handle these points differently.

There is NO-limit for `point[index]`. You can add as many points as you want.

Complex shapes can add 10 or 20 points.

## Seventh Step

Open [`drag-helper.js`](https://github.com/muaz-khan/Canvas-Designer/blob/master/dev/drag-helper.js) and make sure that your new shape can be dragged/resized/move.

Search for `p[0] === 'line'` and add similar code-blocks for your shape (new-tool-icon) as well.

## Eighth Step

Open [`common.js`](https://github.com/muaz-khan/Canvas-Designer/blob/master/dev/common.js) and make sure that your new shape (tool-icon) is printed on the `<textarea>` as well.

This allows end-users to copy your shape's code and use anywhere on their own web-pages.

Open [`common.js`](https://github.com/muaz-khan/Canvas-Designer/blob/master/dev/common.js) file; there is a function [`updateTextArea`](https://github.com/muaz-khan/Canvas-Designer/blob/master/dev/common.js#L67) inside the "common" object – which is aimed to output into textarea element.

You don't have to change [`updateTextArea`](https://github.com/muaz-khan/Canvas-Designer/blob/master/dev/common.js#L67). For simplicity purpose, code is separated in different functions/properties that you've to edit:

1. [`forLoop`](https://github.com/muaz-khan/Canvas-Designer/blob/master/dev/common.js#L363)
2. [`absoluteNOTShortened`](https://github.com/muaz-khan/Canvas-Designer/blob/master/dev/common.js#L105)
3. [`relativeShortened`](https://github.com/muaz-khan/Canvas-Designer/blob/master/dev/common.js#L158)
4. [`relativeNOTShortened`](https://github.com/muaz-khan/Canvas-Designer/blob/master/dev/common.js#L281)

Search for `p[0] === 'line'` and add similar code-blocks for your shape (new-tool-icon) as well.

### For more information

* https://www.webrtc-experiment.com/Canvas-Designer/Help/#contribute


# Shortcut Keys

```
ctrl+t (to display text-fonts box)
ctrl+z (to undo last-single shape)
ctrl+a (to select all shapes)
ctrl+c (copy last-selected shape)
ctrl+v (paste last-copied shape)
```

`ctrl+mousedown` allows you quickly copy/paste all shapes. (i.e. ctrl button + mouse down)

# Signaling Server

* https://github.com/muaz-khan/RTCMultiConnection-Server

# Contributors

1. [Muaz Khan](https://github.com/muaz-khan)
2. [Oleg Aliullov](https://github.com/rashidovich2)

Please make pull-request to update this list.

# License

[Canvas Designer](https://github.com/muaz-khan/Canvas-Designer) is released under [MIT license](https://github.com/muaz-khan/RecordRTC/blob/master/LICENSE) . Copyright (c) [Muaz Khan](https://MuazKhan.com).


================================================
FILE: Canvas-Designer/bower.json
================================================
{
  "name": "canvas-designer",
  "preferGlobal": false,
  "version": "1.3.1",
  "author": {
    "name": "Muaz Khan",
    "email": "muazkh@gmail.com",
    "url": "https://muazkhan.com/"
  },
  "description": "Collaborative, extendable, JavaScript Canvas2D drawing tool, supporting dozens of builtin tools.",
  "main": "server.js",
  "repository": {
    "type": "git",
    "url": "https://github.com/muaz-khan/Canvas-Designer.git"
  },
  "keywords": [
    "canvas-designer",
    "drawing",
    "tool",
    "canvas2d",
    "javascript",
    "muaz",
    "muaz-khan"
  ],
  "analyze": false,
  "license": "MIT",
  "readmeFilename": "README.md",
  "bugs": {
    "url": "https://github.com/muaz-khan/Canvas-Designer/issues",
    "email": "muazkh@gmail.com"
  },
  "homepage": "https://www.webrtc-experiment.com/Canvas-Designer/",
  "ignore": [
        "**/.*",
        "node_modules"
   ],
  "_from": "canvas-designer@",
  "devDependencies": {
    "grunt": "0.4.5",
    "grunt-cli": "0.1.13",
    "load-grunt-tasks": "3.3.0",
    "grunt-contrib-concat": "0.5.1",
    "grunt-contrib-uglify": "0.9.2",
    "grunt-jsbeautifier": "0.2.10",
    "grunt-bump": "0.6.0"
  }
}


================================================
FILE: Canvas-Designer/canvas-designer-widget.js
================================================
// _______________
// Canvas-Designer

// Open-Sourced: https://github.com/muaz-khan/Canvas-Designer

// --------------------------------------------------
// Muaz Khan     - www.MuazKhan.com
// MIT License   - www.WebRTC-Experiment.com/licence
// --------------------------------------------------

function CanvasDesigner() {
    var designer = this;
    designer.iframe = null;

    var tools = {
        line: true,
        arrow: true,
        pencil: true,
        dragSingle: true,
        dragMultiple: true,
        eraser: true,
        rectangle: true,
        arc: true,
        bezier: true,
        quadratic: true,
        text: true,
        image: true,
        pdf: true,
        marker: true,
        zoom: true,
        lineWidth: true,
        colorsPicker: true,
        extraOptions: true,
        code: true
    };

    designer.icons = {
        line: null,
        arrow: null,
        pencil: null,
        dragSingle: null,
        dragMultiple: null,
        eraser: null,
        rectangle: null,
        arc: null,
        bezier: null,
        quadratic: null,
        text: null,
        image: null,
        pdf: null,
        pdf_next: null,
        pdf_prev: null,
        pdf_close: null,
        marker: null,
        zoom: null,
        lineWidth: null,
        colorsPicker: null,
        extraOptions: null,
        code: null
    };

    var selectedIcon = 'pencil';

    function syncData(data) {
        if (!designer.iframe) return;

        designer.postMessage({
            canvasDesignerSyncData: data
        });
    }

    var syncDataListener = function(data) {};
    var dataURLListener = function(dataURL) {};
    var captureStreamCallback = function() {};

    function onMessage(event) {
        if (!event.data || event.data.uid !== designer.uid) return;

        if(!!event.data.sdp) {
            webrtcHandler.createAnswer(event.data, function(response) {
                if(response.sdp) {
                    designer.postMessage(response);
                    return;
                }

                captureStreamCallback(response.stream);
            });
            return;
        }

        if (!!event.data.canvasDesignerSyncData) {
            designer.pointsLength = event.data.canvasDesignerSyncData.points.length;
            syncDataListener(event.data.canvasDesignerSyncData);
            return;
        }

        if (!!event.data.dataURL) {
            dataURLListener(event.data.dataURL);
            return;
        }
    }

    function getRandomString() {
        if (window.crypto && window.crypto.getRandomValues && navigator.userAgent.indexOf('Safari') === -1) {
            var a = window.crypto.getRandomValues(new Uint32Array(3)),
                token = '';
            for (var i = 0, l = a.length; i < l; i++) {
                token += a[i].toString(36);
            }
            return token;
        } else {
            return (Math.random() * new Date().getTime()).toString(36).replace(/\./g, '');
        }
    }

    designer.uid = getRandomString();

    designer.appendTo = function(parentNode, callback) {
        callback = callback || function() {};

        designer.iframe = document.createElement('iframe');
        
        // designer load callback
        designer.iframe.onload = function() {
            callback();
            callback = null;
        };

        designer.iframe.src = designer.widgetHtmlURL + '?widgetJsURL=' + designer.widgetJsURL + '&tools=' + JSON.stringify(tools) + '&selectedIcon=' + selectedIcon + '&icons=' + JSON.stringify(designer.icons);
        designer.iframe.style.width = '100%';
        designer.iframe.style.height = '100%';
        designer.iframe.style.border = 0;

        window.removeEventListener('message', onMessage);
        window.addEventListener('message', onMessage, false);

        parentNode.appendChild(designer.iframe);
    };

    designer.destroy = function() {
        if (designer.iframe) {
            designer.iframe.parentNode.removeChild(designer.iframe);
            designer.iframe = null;
        }
        window.removeEventListener('message', onMessage);
    };

    designer.addSyncListener = function(callback) {
        syncDataListener = callback;
    };

    designer.syncData = syncData;

    designer.setTools = function(_tools) {
        tools = _tools;
    };

    designer.setSelected = function(icon) {
        if (typeof tools[icon] !== 'undefined') {
            selectedIcon = icon;
        }
    };

    designer.toDataURL = function(format, callback) {
        dataURLListener = callback;

        if (!designer.iframe) return;
        designer.postMessage({
            genDataURL: true,
            format: format
        });
    };

    designer.sync = function() {
        if (!designer.iframe) return;
        designer.postMessage({
            syncPoints: true
        });
    };

    designer.pointsLength = 0;

    designer.undo = function(index) {
        if (!designer.iframe) return;

        if(typeof index === 'string' && tools[index]) {
            designer.postMessage({
                undo: true,
                tool: index
            });
            return;
        }

        designer.postMessage({
            undo: true,
            index: index || designer.pointsLength - 1 || -1
        });
    };

    designer.postMessage = function(message) {
        if (!designer.iframe) return;

        message.uid = designer.uid;
        designer.iframe.contentWindow.postMessage(message, '*');
    };

    designer.captureStream = function(callback) {
        if (!designer.iframe) return;

        captureStreamCallback = callback;
        designer.postMessage({
            captureStream: true
        });
    };

    designer.clearCanvas = function () {
        if (!designer.iframe) return;

        designer.postMessage({
            clearCanvas: true
        });
    };

    designer.renderStream = function() {
        if (!designer.iframe) return;

        designer.postMessage({
            renderStream: true
        });
    };

    designer.widgetHtmlURL = 'widget.html';
    designer.widgetJsURL = 'widget.min.js';
}


================================================
FILE: Canvas-Designer/dev/amd.js
================================================
var browserFakeUserAgent = 'Fake/5.0 (FakeOS) AppleWebKit/123 (KHTML, like Gecko) Fake/12.3.4567.89 Fake/123.45';

(function(that) {
    if (typeof window !== 'undefined') {
        return;
    }

    if (typeof window === 'undefined' && typeof global !== 'undefined') {
        global.navigator = {
            userAgent: browserFakeUserAgent,
            getUserMedia: function() {}
        };

        /*global window:true */
        that.window = global;
    } else if (typeof window === 'undefined') {
        // window = this;
    }

    if (typeof document === 'undefined') {
        /*global document:true */
        that.document = {};

        document.createElement = document.captureStream = document.mozCaptureStream = function() {
            return {};
        };
    }

    if (typeof location === 'undefined') {
        /*global location:true */
        that.location = {
            protocol: 'file:',
            href: '',
            hash: ''
        };
    }

    if (typeof screen === 'undefined') {
        /*global screen:true */
        that.screen = {
            width: 0,
            height: 0
        };
    }
})(typeof global !== 'undefined' ? global : window);

if (typeof CanvasDesigner !== 'undefined') {
    window.CanvasDesigner = CanvasDesigner;

    if (typeof module !== 'undefined' /* && !!module.exports*/ ) {
        module.exports = CanvasDesigner;
    }

    if (typeof define === 'function' && define.amd) {
        define('CanvasDesigner', [], function() {
            return CanvasDesigner;
        });
    }
}


================================================
FILE: Canvas-Designer/dev/arc-handler.js
================================================
var arcHandler = {
    global: {
        ismousedown: false,
        prevX: 0,
        prevY: 0,
        prevRadius: 0,
        isCircleDrawn: false,
        isCircledEnded: true,
        isClockwise: false,
        arcRangeContainer: null,
        arcRange: null
    },
    mousedown: function(e) {
        var g = this.global;

        var x = e.pageX - canvas.offsetLeft,
            y = e.pageY - canvas.offsetTop;

        g.prevX = x;
        g.prevY = y;

        g.ismousedown = true;
    },
    mouseup: function(e) {
        var g = this.global;

        var x = e.pageX - canvas.offsetLeft,
            y = e.pageY - canvas.offsetTop;

        if (g.ismousedown) {
            if (!g.isCircleDrawn && g.isCircledEnded) {
                var prevX = g.prevX,
                    prevY = g.prevY,
                    radius = ((x - prevX) + (y - prevY)) / 3;

                g.prevRadius = radius;
                g.isCircleDrawn = true;
                g.isCircleEnded = false;

                var c = (2 * Math.PI * radius) / 21,
                    angle,
                    xx = prevX > x ? prevX - x : x - prevX,
                    yy = prevY > y ? prevY - y : y - prevY;

                angle = (xx + yy) / (2 * c);
                points[points.length] = ['arc', [prevX + radius, prevY + radius, radius, angle, 1], drawHelper.getOptions()];

                var arcRange = g.arcRange,
                    arcRangeContainer = g.arcRangeContainer;

                arcRangeContainer.style.display = 'block';
                arcRange.focus();

                arcRangeContainer.style.top = (y + canvas.offsetTop + 20) + 'px';
                arcRangeContainer.style.left = x + 'px';

                arcRange.value = 2;
            } else if (g.isCircleDrawn && !g.isCircleEnded) {
                this.end();
            }
        }

        g.ismousedown = false;

        this.fixAllPoints();
    },
    mousemove: function(e) {
        var g = this.global;

        var x = e.pageX - canvas.offsetLeft,
            y = e.pageY - canvas.offsetTop;

        var ismousedown = g.ismousedown,
            isCircleDrawn = g.isCircleDrawn,
            isCircleEnded = g.isCircledEnded;

        if (ismousedown) {
            if (!isCircleDrawn && isCircleEnded) {
                var prevX = g.prevX,
                    prevY = g.prevY,
                    radius = ((x - prevX) + (y - prevY)) / 3;

                tempContext.clearRect(0, 0, 2000, 2000);

                drawHelper.arc(tempContext, [prevX + radius, prevY + radius, radius, Math.PI * 2, true]);
            }
        }
    },
    fixAllPoints: function() {
        var toFixed = this.toFixed;

        for (var i = 0; i < points.length; i++) {
            var p = points[i],
                point;
            if (p[0] === 'arc') {
                point = p[1];
                points[i] = ['arc', [toFixed(point[0]), toFixed(point[1]), toFixed(point[2]), toFixed(point[3]), point[4]],
                    p[2]
                ];
            }
        }
    },
    init: function() {
        var markIsClockwise = find('is-clockwise'),
            g = this.global;

        g.arcRangeContainer = find('arc-range-container');
        g.arcRange = find('arc-range');

        addEvent(markIsClockwise, 'change', function(e) {
            g.isClockwise = markIsClockwise.checked;

            g.arcRange.value = arcHandler.toFixed(g.arcRange.value);
            g.arcRange.focus();

            arcHandler.arcRangeHandler(e);

            if (!points.length) return;

            var p = points[points.length - 1],
                point = p[1];

            tempContext.clearRect(0, 0, innerWidth, innerHeight);
            drawHelper.arc(tempContext, [point[0], point[1], point[2], point[3], point[4]]);
        });

        var arcRange = g.arcRange;
        addEvent(arcRange, 'keydown', this.arcRangeHandler);
        addEvent(arcRange, 'focus', this.arcRangeHandler);
    },
    arcRangeHandler: function(e) {
        var g = arcHandler.global,
            arcRange = g.arcRange;

        var key = e.keyCode,
            value = +arcRange.value;
        if (key == 39 || key == 40) arcRange.value = (value < 2 ? value : 1.98) + .02;
        if (key == 37 || key == 38) arcRange.value = (value > 0 ? value : .02) - .02;

        if (!key || key == 13 || key == 39 || key == 40 || key == 37 || key == 38) {
            var range = Math.PI * arcHandler.toFixed(value);
            var p = points[points.length - 1];

            if (p[0] === 'arc') {
                var point = p[1];
                points[points.length - 1] = ['arc', [point[0], point[1], point[2], range, g.isClockwise ? 1 : 0],
                    p[2]
                ];

                drawHelper.redraw();
            }
        }
    },
    toFixed: function(input) {
        return Number(input).toFixed(1);
    },
    end: function() {
        var g = this.global;

        g.arcRangeContainer.style.display = 'none';
        g.arcRange.value = 2;

        g.isCircleDrawn = false;
        g.isCircleEnded = true;

        drawHelper.redraw();
    }
};

arcHandler.init();


================================================
FILE: Canvas-Designer/dev/arrow-handler.js
================================================
var arrowHandler = {
    ismousedown: false,
    prevX: 0,
    prevY: 0,
    arrowSize: 10,
    mousedown: function(e) {
        var x = e.pageX - canvas.offsetLeft,
            y = e.pageY - canvas.offsetTop;

        var t = this;

        t.prevX = x;
        t.prevY = y;

        t.ismousedown = true;
    },
    mouseup: function(e) {
        var x = e.pageX - canvas.offsetLeft,
            y = e.pageY - canvas.offsetTop;

        var t = this;
        if (t.ismousedown) {
            points[points.length] = ['arrow', [t.prevX, t.prevY, x, y], drawHelper.getOptions()];

            t.ismousedown = false;
        }
    },
    mousemove: function(e) {
        var x = e.pageX - canvas.offsetLeft,
            y = e.pageY - canvas.offsetTop;

        var t = this;

        if (t.ismousedown) {
            tempContext.clearRect(0, 0, innerWidth, innerHeight);

            drawHelper.arrow(tempContext, [t.prevX, t.prevY, x, y]);
        }
    }
};


================================================
FILE: Canvas-Designer/dev/bezier-handler.js
================================================
var bezierHandler = {
    global: {
        ismousedown: false,
        prevX: 0,
        prevY: 0,

        firstControlPointX: 0,
        firstControlPointY: 0,
        secondControlPointX: 0,
        secondControlPointY: 0,

        isFirstStep: true,
        isSecondStep: false,
        isLastStep: false
    },
    mousedown: function(e) {
        var g = this.global;

        var x = e.pageX - canvas.offsetLeft,
            y = e.pageY - canvas.offsetTop;

        if (!g.isLastStep && !g.isSecondStep) {
            g.prevX = x;
            g.prevY = y;
        }

        g.ismousedown = true;

        if (g.isLastStep && g.ismousedown) {
            this.end(x, y);
        }

        if (g.ismousedown && g.isSecondStep) {
            g.secondControlPointX = x;
            g.secondControlPointY = y;

            g.isSecondStep = false;
            g.isLastStep = true;
        }
    },
    mouseup: function(e) {
        var g = this.global;

        var x = e.pageX - canvas.offsetLeft,
            y = e.pageY - canvas.offsetTop;

        if (g.ismousedown && g.isFirstStep) {
            g.firstControlPointX = x;
            g.firstControlPointY = y;

            g.isFirstStep = false;
            g.isSecondStep = true;
        }
    },
    mousemove: function(e) {
        var x = e.pageX - canvas.offsetLeft,
            y = e.pageY - canvas.offsetTop;

        var g = this.global;

        tempContext.clearRect(0, 0, innerWidth, innerHeight);

        if (g.ismousedown && g.isFirstStep) {
            drawHelper.bezier(tempContext, [g.prevX, g.prevY, x, y, x, y, x, y]);
        }

        if (g.ismousedown && g.isSecondStep) {
            drawHelper.bezier(tempContext, [g.prevX, g.prevY, g.firstControlPointX, g.firstControlPointY, x, y, x, y]);
        }

        if (g.isLastStep) {
            drawHelper.bezier(tempContext, [g.prevX, g.prevY, g.firstControlPointX, g.firstControlPointY, g.secondControlPointX, g.secondControlPointY, x, y]);
        }
    },
    end: function(x, y) {
        var g = this.global;

        if (!g.ismousedown) return;

        g.isLastStep = g.isSecondStep = false;

        g.isFirstStep = true;
        g.ismousedown = false;

        g.secondControlPointX = g.secondControlPointX || g.firstControlPointX;
        g.secondControlPointY = g.secondControlPointY || g.firstControlPointY;

        x = x || g.secondControlPointX;
        y = y || g.secondControlPointY;

        points[points.length] = ['bezier', [g.prevX, g.prevY, g.firstControlPointX, g.firstControlPointY, g.secondControlPointX, g.secondControlPointY, x, y], drawHelper.getOptions()];
    }
};


================================================
FILE: Canvas-Designer/dev/common.js
================================================
var is = {
    isLine: false,
    isArrow: false,
    isArc: false,
    isDragLastPath: false,
    isDragAllPaths: false,
    isRectangle: false,
    isQuadraticCurve: false,
    isBezierCurve: false,
    isPencil: false,
    isMarker: true,
    isEraser: false,
    isText: false,
    isImage: false,
    isPdf: false,

    set: function(shape) {
        var cache = this;

        cache.isLine = cache.isArrow = cache.isArc = cache.isDragLastPath = cache.isDragAllPaths = cache.isRectangle = cache.isQuadraticCurve = cache.isBezierCurve = cache.isPencil = cache.isMarker = cache.isEraser = cache.isText = cache.isImage = cache.isPdf = false;
        cache['is' + shape] = true;
    }
};

function addEvent(element, eventType, callback) {
    if (eventType.split(' ').length > 1) {
        var events = eventType.split(' ');
        for (var i = 0; i < events.length; i++) {
            addEvent(element, events[i], callback);
        }
        return;
    }

    if (element.addEventListener) {
        element.addEventListener(eventType, callback, !1);
        return true;
    } else if (element.attachEvent) {
        return element.attachEvent('on' + eventType, callback);
    } else {
        element['on' + eventType] = callback;
    }
    return this;
}

function find(selector) {
    return document.getElementById(selector);
}

var points = [],
    textarea = find('code-text'),
    lineWidth = 2,
    strokeStyle = '#6c96c8',
    fillStyle = 'rgba(0,0,0,0)',
    globalAlpha = 1,
    globalCompositeOperation = 'source-over',
    lineCap = 'round',
    font = '15px "Arial"',
    lineJoin = 'round';

function getContext(id) {
    var canv = find(id),
        ctx = canv.getContext('2d');

    canv.setAttribute('width', innerWidth);
    canv.setAttribute('height', innerHeight);

    ctx.lineWidth = lineWidth;
    ctx.strokeStyle = strokeStyle;
    ctx.fillStyle = fillStyle;
    ctx.font = font;

    return ctx;
}

var context = getContext('main-canvas'),
    tempContext = getContext('temp-canvas');

var common = {
    updateTextArea: function() {
        var c = common,
            toFixed = c.toFixed,
            getPoint = c.getPoint,

            isAbsolutePoints = find('is-absolute-points').checked,
            isShortenCode = find('is-shorten-code').checked;

        if (isAbsolutePoints && isShortenCode) c.absoluteShortened();
        if (isAbsolutePoints && !isShortenCode) c.absoluteNOTShortened(toFixed);
        if (!isAbsolutePoints && isShortenCode) c.relativeShortened(toFixed, getPoint);
        if (!isAbsolutePoints && !isShortenCode) c.relativeNOTShortened(toFixed, getPoint);
    },
    toFixed: function(input) {
        return Number(input).toFixed(1);
    },
    getPoint: function(pointToCompare, compareWith, prefix) {
        if (pointToCompare > compareWith) pointToCompare = prefix + ' + ' + (pointToCompare - compareWith);
        else if (pointToCompare < compareWith) pointToCompare = prefix + ' - ' + (compareWith - pointToCompare);
        else pointToCompare = prefix;

        return pointToCompare;
    },
    absoluteShortened: function() {
        var output = '',
            length = points.length,
            i = 0,
            point;
        for (i; i < length; i++) {
            point = points[i];
            output += this.shortenHelper(point[0], point[1], point[2]);
        }

        output = output.substr(0, output.length - 2);
        textarea.value = 'var points = [' + output + '], length = points.length, point, p, i = 0;\n\n' + drawArrow.toString() + '\n\n' + this.forLoop;

        this.prevProps = null;
    },
    absoluteNOTShortened: function(toFixed) {
        var tempArray = [],
            i, point, p;

        for (i = 0; i < points.length; i++) {
            p = points[i];
            point = p[1];

            if (p[0] === 'pencil') {
                tempArray[i] = ['context.beginPath();\n' + 'context.moveTo(' + point[0] + ', ' + point[1] + ');\n' + 'context.lineTo(' + point[2] + ', ' + point[3] + ');\n' + this.strokeOrFill(p[2])];
            }

            if (p[0] === 'marker') {
                tempArray[i] = ['context.beginPath();\n' + 'context.moveTo(' + point[0] + ', ' + point[1] + ');\n' + 'context.lineTo(' + point[2] + ', ' + point[3] + ');\n' + this.strokeOrFill(p[2])];
            }

            if (p[0] === 'eraser') {
                tempArray[i] = ['context.beginPath();\n' + 'context.moveTo(' + point[0] + ', ' + point[1] + ');\n' + 'context.lineTo(' + point[2] + ', ' + point[3] + ');\n' + this.strokeOrFill(p[2])];
            }

            if (p[0] === 'line') {
                tempArray[i] = ['context.beginPath();\n' + 'context.moveTo(' + point[0] + ', ' + point[1] + ');\n' + 'context.lineTo(' + point[2] + ', ' + point[3] + ');\n' + this.strokeOrFill(p[2])];
            }

            if (p[0] === 'pencil') {
                tempArray[i] = ['context.beginPath();\n' + 'context.moveTo(' + point[0] + ', ' + point[1] + ');\n' + 'context.lineTo(' + point[2] + ', ' + point[3] + ');\n' + this.strokeOrFill(p[2])];
            }

            if (p[0] === 'text') {
                tempArray[i] = [this.strokeOrFill(p[2]) + '\ncontext.fillText(' + point[0] + ', ' + point[1] + ', ' + point[2] + ');'];
            }

            if (p[0] === 'arrow') {
                tempArray[i] = ['drawArrow(' + point[0] + ', ' + point[1] + ', ' + point[2] + ', ' + point[3] + ', \'' + p[2].join('\',\'') + '\');'];
            }

            if (p[0] === 'arc') {
                tempArray[i] = ['context.beginPath(); \n' + 'context.arc(' + toFixed(point[0]) + ',' + toFixed(point[1]) + ',' + toFixed(point[2]) + ',' + toFixed(point[3]) + ', 0,' + point[4] + '); \n' + this.strokeOrFill(p[2])];
            }

            if (p[0] === 'rect') {
                tempArray[i] = [this.strokeOrFill(p[2]) + '\n' + 'context.strokeRect(' + point[0] + ', ' + point[1] + ',' + point[2] + ',' + point[3] + ');\n' + 'context.fillRect(' + point[0] + ', ' + point[1] + ',' + point[2] + ',' + point[3] + ');'];
            }

            if (p[0] === 'quadratic') {
                tempArray[i] = ['context.beginPath();\n' + 'context.moveTo(' + point[0] + ', ' + point[1] + ');\n' + 'context.quadraticCurveTo(' + point[2] + ', ' + point[3] + ', ' + point[4] + ', ' + point[5] + ');\n' + this.strokeOrFill(p[2])];
            }

            if (p[0] === 'bezier') {
                tempArray[i] = ['context.beginPath();\n' + 'context.moveTo(' + point[0] + ', ' + point[1] + ');\n' + 'context.bezierCurveTo(' + point[2] + ', ' + point[3] + ', ' + point[4] + ', ' + point[5] + ', ' + point[6] + ', ' + point[7] + ');\n' + this.strokeOrFill(p[2])];
            }

        }
        textarea.value = tempArray.join('\n\n') + this.strokeFillText + '\n\n' + drawArrow.toString();

        this.prevProps = null;
    },
    relativeShortened: function(toFixed, getPoint) {
        var i = 0,
            point, p, length = points.length,
            output = '',
            x = 0,
            y = 0;

        for (i; i < length; i++) {
            p = points[i];
            point = p[1];

            if (i === 0) {
                x = point[0];
                y = point[1];
            }

            if (p[0] === 'text') {
                x = point[1];
                y = point[2];
            }

            if (p[0] === 'pencil') {
                output += this.shortenHelper(p[0], [
                    getPoint(point[0], x, 'x'),
                    getPoint(point[1], y, 'y'),
                    getPoint(point[2], x, 'x'),
                    getPoint(point[3], y, 'y')
                ], p[2]);
            }

            if (p[0] === 'marker') {
                output += this.shortenHelper(p[0], [
                    getPoint(point[0], x, 'x'),
                    getPoint(point[1], y, 'y'),
                    getPoint(point[2], x, 'x'),
                    getPoint(point[3], y, 'y')
                ], p[2]);
            }

            if (p[0] === 'eraser') {
                output += this.shortenHelper(p[0], [
                    getPoint(point[0], x, 'x'),
                    getPoint(point[1], y, 'y'),
                    getPoint(point[2], x, 'x'),
                    getPoint(point[3], y, 'y')
                ], p[2]);
            }

            if (p[0] === 'line') {
                output += this.shortenHelper(p[0], [
                    getPoint(point[0], x, 'x'),
                    getPoint(point[1], y, 'y'),
                    getPoint(point[2], x, 'x'),
                    getPoint(point[3], y, 'y')
                ], p[2]);
            }

            if (p[0] === 'pencil') {
                output += this.shortenHelper(p[0], [
                    getPoint(point[0], x, 'x'),
                    getPoint(point[1], y, 'y'),
                    getPoint(point[2], x, 'x'),
                    getPoint(point[3], y, 'y')
                ], p[2]);
            }

            if (p[0] === 'arrow') {
                output += this.shortenHelper(p[0], [
                    getPoint(point[0], x, 'x'),
                    getPoint(point[1], y, 'y'),
                    getPoint(point[2], x, 'x'),
                    getPoint(point[3], y, 'y')
                ], p[2]);
            }

            if (p[0] === 'text') {
                output += this.shortenHelper(p[0], [
                    point[0],
                    getPoint(point[1], x, 'x'),
                    getPoint(point[2], y, 'y')
                ], p[2]);
            }

            if (p[0] === 'arc') {
                output += this.shortenHelper(p[0], [
                    getPoint(point[0], x, 'x'),
                    getPoint(point[1], y, 'y'),
                    point[2],
                    point[3],
                    point[4]
                ], p[2]);
            }

            if (p[0] === 'rect') {
                output += this.shortenHelper(p[0], [
                    getPoint(point[0], x, 'x'),
                    getPoint(point[1], y, 'y'),
                    getPoint(point[2], x, 'x'),
                    getPoint(point[3], y, 'y')
                ], p[2]);
            }

            if (p[0] === 'quadratic') {
                output += this.shortenHelper(p[0], [
                    getPoint(point[0], x, 'x'),
                    getPoint(point[1], y, 'y'),
                    getPoint(point[2], x, 'x'),
                    getPoint(point[3], y, 'y'),
                    getPoint(point[4], x, 'x'),
                    getPoint(point[5], y, 'y')
                ], p[2]);
            }

            if (p[0] === 'bezier') {
                output += this.shortenHelper(p[0], [
                    getPoint(point[0], x, 'x'),
                    getPoint(point[1], y, 'y'),
                    getPoint(point[2], x, 'x'),
                    getPoint(point[3], y, 'y'),
                    getPoint(point[4], x, 'x'),
                    getPoint(point[5], y, 'y'),
                    getPoint(point[6], x, 'x'),
                    getPoint(point[7], y, 'y')
                ], p[2]);
            }
        }

        output = output.substr(0, output.length - 2);
        textarea.value = 'var x = ' + x + ', y = ' + y + ', points = [' + output + '], length = points.length, point, p, i = 0;\n\n' + drawArrow.toString() + '\n\n' + this.forLoop;

        this.prevProps = null;
    },
    relativeNOTShortened: function(toFixed, getPoint) {
        var i, point, p, length = points.length,
            output = '',
            x = 0,
            y = 0;

        for (i = 0; i < length; i++) {
            p = points[i];
            point = p[1];

            if (i === 0) {
                x = point[0];
                y = point[1];

                if (p[0] === 'text') {
                    x = point[1];
                    y = point[2];
                }

                output = 'var x = ' + x + ', y = ' + y + ';\n\n';
            }

            if (p[0] === 'arc') {
                output += 'context.beginPath();\n' + 'context.arc(' + getPoint(point[0], x, 'x') + ', ' + getPoint(point[1], y, 'y') + ', ' + point[2] + ', ' + point[3] + ', 0, ' + point[4] + ');\n'

                    +
                    this.strokeOrFill(p[2]);
            }

            if (p[0] === 'pencil') {
                output += 'context.beginPath();\n' + 'context.moveTo(' + getPoint(point[0], x, 'x') + ', ' + getPoint(point[1], y, 'y') + ');\n' + 'context.lineTo(' + getPoint(point[2], x, 'x') + ', ' + getPoint(point[3], y, 'y') + ');\n'

                    +
                    this.strokeOrFill(p[2]);
            }

            if (p[0] === 'marker') {
                output += 'context.beginPath();\n' + 'context.moveTo(' + getPoint(point[0], x, 'x') + ', ' + getPoint(point[1], y, 'y') + ');\n' + 'context.lineTo(' + getPoint(point[2], x, 'x') + ', ' + getPoint(point[3], y, 'y') + ');\n'

                    +
                    this.strokeOrFill(p[2]);
            }

            if (p[0] === 'eraser') {
                output += 'context.beginPath();\n' + 'context.moveTo(' + getPoint(point[0], x, 'x') + ', ' + getPoint(point[1], y, 'y') + ');\n' + 'context.lineTo(' + getPoint(point[2], x, 'x') + ', ' + getPoint(point[3], y, 'y') + ');\n'

                    +
                    this.strokeOrFill(p[2]);
            }

            if (p[0] === 'line') {
                output += 'context.beginPath();\n' + 'context.moveTo(' + getPoint(point[0], x, 'x') + ', ' + getPoint(point[1], y, 'y') + ');\n' + 'context.lineTo(' + getPoint(point[2], x, 'x') + ', ' + getPoint(point[3], y, 'y') + ');\n' + this.strokeOrFill(p[2]);
            }

            if (p[0] === 'pencil') {
                output += 'context.beginPath();\n' + 'context.moveTo(' + getPoint(point[0], x, 'x') + ', ' + getPoint(point[1], y, 'y') + ');\n' + 'context.lineTo(' + getPoint(point[2], x, 'x') + ', ' + getPoint(point[3], y, 'y') + ');\n' + this.strokeOrFill(p[2]);
            }

            if (p[0] === 'arrow') {
                output += 'drawArrow(' + getPoint(point[0], x, 'x') + ', ' + getPoint(point[1], y, 'y') + ', ' + getPoint(point[2], x, 'x') + ', ' + getPoint(point[3], y, 'y') + ', \'' + p[2].join('\',\'') + '\');\n';
            }

            if (p[0] === 'text') {
                output += this.strokeOrFill(p[2]) + '\n' + 'context.fillText(' + point[0] + ', ' + getPoint(point[1], x, 'x') + ', ' + getPoint(point[2], y, 'y') + ');';
            }

            if (p[0] === 'rect') {
                output += this.strokeOrFill(p[2]) + '\n' + 'context.strokeRect(' + getPoint(point[0], x, 'x') + ', ' + getPoint(point[1], y, 'y') + ', ' + getPoint(point[2], x, 'x') + ', ' + getPoint(point[3], y, 'y') + ');\n' + 'context.fillRect(' + getPoint(point[0], x, 'x') + ', ' + getPoint(point[1], y, 'y') + ', ' + getPoint(point[2], x, 'x') + ', ' + getPoint(point[3], y, 'y') + ');';
            }

            if (p[0] === 'quadratic') {
                output += 'context.beginPath();\n' + 'context.moveTo(' + getPoint(point[0], x, 'x') + ', ' + getPoint(point[1], y, 'y') + ');\n' + 'context.quadraticCurveTo(' + getPoint(point[2], x, 'x') + ', ' + getPoint(point[3], y, 'y') + ', ' + getPoint(point[4], x, 'x') + ', ' + getPoint(point[5], y, 'y') + ');\n'

                    +
                    this.strokeOrFill(p[2]);
            }

            if (p[0] === 'bezier') {
                output += 'context.beginPath();\n' + 'context.moveTo(' + getPoint(point[0], x, 'x') + ', ' + getPoint(point[1], y, 'y') + ');\n' + 'context.bezierCurveTo(' + getPoint(point[2], x, 'x') + ', ' + getPoint(point[3], y, 'y') + ', ' + getPoint(point[4], x, 'x') + ', ' + getPoint(point[5], y, 'y') + ', ' + getPoint(point[6], x, 'x') + ', ' + getPoint(point[7], y, 'y') + ');\n'

                    +
                    this.strokeOrFill(p[2]);
            }

            if (i !== length - 1) output += '\n\n';
        }
        textarea.value = output + this.strokeFillText + '\n\n' + drawArrow.toString();

        this.prevProps = null;
    },
    forLoop: 'for(i; i < length; i++) {\n' + '    p = points[i];\n' + '    point = p[1];\n' + '    context.beginPath();\n\n'

        // globals
        +
        '    if(p[2]) { \n' + '\tcontext.lineWidth = p[2][0];\n' + '\tcontext.strokeStyle = p[2][1];\n' + '\tcontext.fillStyle = p[2][2];\n'

        +
        '\tcontext.globalAlpha = p[2][3];\n' + '\tcontext.globalCompositeOperation = p[2][4];\n' + '\tcontext.lineCap = p[2][5];\n' + '\tcontext.lineJoin = p[2][6];\n' + '\tcontext.font = p[2][7];\n' + '    }\n\n'

        // line

        +
        '    if(p[0] === "line") { \n' + '\tcontext.moveTo(point[0], point[1]);\n' + '\tcontext.lineTo(point[2], point[3]);\n' + '    }\n\n'

        // arrow

        +
        '    if(p[0] === "arrow") { \n' + '\tdrawArrow(point[0], point[1], point[2], point[3], p[2]);\n' + '    }\n\n'

        // pencil

        +
        '    if(p[0] === "pencil") { \n' + '\tcontext.moveTo(point[0], point[1]);\n' + '\tcontext.lineTo(point[2], point[3]);\n' + '    }\n\n'

        // marker

        +
        '    if(p[0] === "marker") { \n' + '\tcontext.moveTo(point[0], point[1]);\n' + '\tcontext.lineTo(point[2], point[3]);\n' + '    }\n\n'


        // text

        +
        '    if(p[0] === "text") { \n' + '\tcontext.fillText(point[0], point[1], point[2]);\n' + '    }\n\n'

        // eraser

        +
        '    if(p[0] === "eraser") { \n' + '\tcontext.moveTo(point[0], point[1]);\n' + '\tcontext.lineTo(point[2], point[3]);\n' + '    }\n\n'

        // arc

        +
        '    if(p[0] === "arc") context.arc(point[0], point[1], point[2], point[3], 0, point[4]); \n\n'

        // rect

        +
        '    if(p[0] === "rect") {\n' + '\tcontext.strokeRect(point[0], point[1], point[2], point[3]);\n' + '\tcontext.fillRect(point[0], point[1], point[2], point[3]);\n'

        +
        '    }\n\n'

        // quadratic

        +
        '    if(p[0] === "quadratic") {\n' + '\tcontext.moveTo(point[0], point[1]);\n' + '\tcontext.quadraticCurveTo(point[2], point[3], point[4], point[5]);\n' + '    }\n\n'

        // bezier

        +
        '    if(p[0] === "bezier") {\n' + '\tcontext.moveTo(point[0], point[1]);\n' + '\tcontext.bezierCurveTo(point[2], point[3], point[4], point[5], point[6], point[7]);\n' + '    }\n\n'

        // end-fill

        +
        '    context.stroke();\n' + '    context.fill();\n'

        +
        '}',

    strokeFillText: '\n\nfunction strokeOrFill(lineWidth, strokeStyle, fillStyle, globalAlpha, globalCompositeOperation, lineCap, lineJoin, font) { \n' + '    if(lineWidth) { \n' + '\tcontext.globalAlpha = globalAlpha;\n' + '\tcontext.globalCompositeOperation = globalCompositeOperation;\n' + '\tcontext.lineCap = lineCap;\n' + '\tcontext.lineJoin = lineJoin;\n'

        +
        '\tcontext.lineWidth = lineWidth;\n' + '\tcontext.strokeStyle = strokeStyle;\n' + '\tcontext.fillStyle = fillStyle;\n' + '\tcontext.font = font;\n' + '    } \n\n'

        +
        '    context.stroke();\n' + '    context.fill();\n'

        +
        '}',
    strokeOrFill: function(p) {
        if (!this.prevProps || this.prevProps !== p.join(',')) {
            this.prevProps = p.join(',');

            return 'strokeOrFill(\'' + p.join('\', \'') + '\');';
        }

        return 'strokeOrFill();';
    },
    prevProps: null,
    shortenHelper: function(name, p1, p2) {
        var result = '[\'' + name + '\', [' + p1.join(', ') + ']';

        if (!this.prevProps || this.prevProps !== p2.join(',')) {
            this.prevProps = p2.join(',');
            result += ', [\'' + p2.join('\', \'') + '\']';
        }

        return result + '], ';
    }
};

function drawArrow(mx, my, lx, ly, options) {
    function getOptions(opt) {
        opt = opt || {};

        return [
            opt.lineWidth || 2,
            opt.strokeStyle || '#6c96c8',
            opt.fillStyle || 'rgba(0,0,0,0)',
            opt.globalAlpha || 1,
            opt.globalCompositeOperation || 'source-over',
            opt.lineCap || 'round',
            opt.lineJoin || 'round',
            opt.font || '15px "Arial"'
        ];
    }

    function handleOptions(opt, isNoFillStroke) {
        opt = opt || getOptions();

        context.globalAlpha = opt[3];
        context.globalCompositeOperation = opt[4];

        context.lineCap = opt[5];
        context.lineJoin = opt[6];
        context.lineWidth = opt[0];

        context.strokeStyle = opt[1];
        context.fillStyle = opt[2];

        context.font = opt[7];

        if (!isNoFillStroke) {
            context.stroke();
            context.fill();
        }
    }

    var arrowSize = 10;
    var angle = Math.atan2(ly - my, lx - mx);

    context.beginPath();
    context.moveTo(mx, my);
    context.lineTo(lx, ly);

    handleOptions();

    context.beginPath();
    context.moveTo(lx, ly);
    context.lineTo(lx - arrowSize * Math.cos(angle - Math.PI / 7), ly - arrowSize * Math.sin(angle - Math.PI / 7));
    context.lineTo(lx - arrowSize * Math.cos(angle + Math.PI / 7), ly - arrowSize * Math.sin(angle + Math.PI / 7));
    context.lineTo(lx, ly);
    context.lineTo(lx - arrowSize * Math.cos(angle - Math.PI / 7), ly - arrowSize * Math.sin(angle - Math.PI / 7));

    handleOptions();
}

function endLastPath() {
    var cache = is;

    if (cache.isArc) arcHandler.end();
    else if (cache.isQuadraticCurve) quadraticHandler.end();
    else if (cache.isBezierCurve) bezierHandler.end();

    drawHelper.redraw();

    if (textHandler.text && textHandler.text.length) {
        textHandler.appendPoints();
        textHandler.onShapeUnSelected();
    }
    textHandler.showOrHideTextTools('hide');
}

var copiedStuff = [],
    isControlKeyPressed;

function copy() {
    endLastPath();

    dragHelper.global.startingIndex = 0;

    if (find('copy-last').checked) {
        copiedStuff = points[points.length - 1];
        setSelection(find('drag-last-path'), 'DragLastPath');
    } else {
        copiedStuff = points;
        setSelection(find('drag-all-paths'), 'DragAllPaths');
    }
}

function paste() {
    endLastPath();

    dragHelper.global.startingIndex = 0;

    if (find('copy-last').checked) {
        points[points.length] = copiedStuff;

        dragHelper.global = {
            prevX: 0,
            prevY: 0,
            startingIndex: points.length - 1
        };

        dragHelper.dragAllPaths(0, 0);
        setSelection(find('drag-last-path'), 'DragLastPath');
    } else {

        dragHelper.global.startingIndex = points.length;
        points = points.concat(copiedStuff);
        setSelection(find('drag-all-paths'), 'DragAllPaths');
    }
}

// marker + pencil
function hexToR(h) {
    return parseInt((cutHex(h)).substring(0, 2), 16)
}

function hexToG(h) {
    return parseInt((cutHex(h)).substring(2, 4), 16)
}

function hexToB(h) {
    return parseInt((cutHex(h)).substring(4, 6), 16)
}

function cutHex(h) {
    return (h.charAt(0) == "#") ? h.substring(1, 7) : h
}

function clone(obj) {
    if (obj === null || typeof(obj) !== 'object' || 'isActiveClone' in obj)
        return obj;

    if (obj instanceof Date)
        var temp = new obj.constructor(); //or new Date(obj);
    else
        var temp = obj.constructor();

    for (var key in obj) {
        if (Object.prototype.hasOwnProperty.call(obj, key)) {
            obj['isActiveClone'] = null;
            temp[key] = clone(obj[key]);
            delete obj['isActiveClone'];
        }
    }

    return temp;
}

function hexToRGB(h) {
    return [
        hexToR(h),
        hexToG(h),
        hexToB(h)
    ]
}


================================================
FILE: Canvas-Designer/dev/data-uris.js
================================================
var icons = {};
if (params.icons) {
    try {
        icons = JSON.parse(params.icons);
    } catch (e) {
        icons = {};
    }
}

var data_uris = {
    line: icons.line || 'data:image/png;base64,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',
    arrow: icons.arrow || 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEwAACxMBAJqcGAAACbFJREFUeJztnW1wXFUZx//Pc3ebptmXhhdrFXAKIgo6DMgoKo6IL2h1GBUpM0Capq9QshsKooNiQ4FBhw4l2bSlrWGSTQGHMsP4NvBJ8WUcQBzFQe0oypsDERmaZjdpk+ze5/EDJLkbkqbtvbt3d8/5fbv/nPOcJ3P+e87es/eZC1gsFovFYrFYLBaLxWKxWIyAwk4gLOId2U+QYitEFKw35jKrnwk7pzAw0gDJjr7F6uLvYF46qUWUkwd6WnJh5hUGHHYCYSBCd3snHwAKKP4grHzCxLgVINnRd7EqPzHb30TkopHtbb+vdE5hYtYKsOnhRnV5z1x/ZuZepLobKplS2BhlgHhx7FYwzjxCkw/GsfiWiiVUBRizBSxuHzhX4P4RzJFJTVV2AhQlonWepgWX9bzRrlV/CyHNimOGAa7Y58SWjj7F4AumNMGrEeKzXS6yKu8H8G5Pj6dyg40X4ZEVbsVzrTBGbAHxpYfSJZMPQB3deKCnJTfc3XaQBNfP6HJhYumh6yqYYmjU/QqQbB9Y5rL+lYFFk5oC+/KZ1iu97RLt2UfB+PrktUBGouBzhjKtr1Qy30pT5yuAksu6yzv5AhkSRNMzWxa00C6QqYMgBsdc0fsAresPSV0bIJ4auIaBL3o1At00mrnq9ZltD+9Y+5oDurlEZFqeSO+9cmbbeqJuDdB07cC7VNHl1RT6q3ymtX+uPsPNL/YC+rtSVTPx67MnliXJKqBuDUBRuZcZJ3ikMXJ4A0A6Z6ctW0TJWQeRCY96MpHcU7ZEQ6YuDRBPZ5cz0VVeTUCduXtX/mu+vvnuln+A+PYSkbk1kR74QsBpVgV1Z4ATb+6NQ7HLqynkzyPNp2472hi5Exq3AnjOqwnc3UtuGmgKKM2qoe4MUBiP3kmEU6cVcZkja7Hls8WjDrJlxQRE1wIytV0weNnhCdkSaLJVQF0ZIJ7quxCQVKlK24a7Wv50rLFy21f9AaDuElFpU+L67AVzdKlJ6scAnfsWELgX4Kn7dhG80DQ2ftvxhmwoLvq+QF+eEhisjvZi/e6ov2Srh7oxQGLo8HdAOMerOcCGwT0bDh1vzDd2rhghQcmRMIHOTSxceNPxxqw26uKUK9aR/RC78iyYF0yr2p/LrGoLJH46+wADV3ukcYX7kXxm9fNBxA+T2l8BOjuZXdlTOvnyP3XpW4GNocVNgLzpURqgzp56OCaueQMkhk5fD+aLSkTidH5H65tzdDlmRnrWvKGgG0qGIFwcS+9dHdQYYVHTDm7c1P9ep0D7mRGfElV+ketZddkRT/yOC6VYqv9xJr50UhHBQYnw2Ye6WgaDHaty1PAKoBQt0k7v5AtkxInqxuAnHwBIHca1Akx9qWTGYkckE/xYlaNmDZBMZS8H4TKvxqBbhrat/k+5xhzubnuJoLd6NQK+GesY+Fq5xiw3NWmA5HUPNqtie4mo8mRucNF95R47P7goI4KSKiJW3dG8fney3GOXg5o0gEYKW8G0xCMVXIfWVeQZvkdWuBHQOoh4j5bfU2xo+GHZxy4DNWeAZPvAJSBa49VUcVcln+I9uH3lX5T4bq9GRNfG2vd+ulI5BEVtGWDTw40ua2lhh8j+PA5WvKwrn5M7APmnV2O4P0Jr38JK5+KHmjJA3B3rZOCMaUVUyVmLno7xiieTbRsT5fUlGtNZ8SR/r+K5+KBmzgGSqex5SvIMwM6kpio78z1tMx/prijxVP+eksISkaKrev7ojtXPHaFb1VAbK0DnExEX2uudfAhejSISehkXs34bwH89QoQcpxdX7HPm7lU91IQB4gdevoGJzvdqk4UdYeU0yWyFJQx8LL70UHtYOR0LVb8FJFL9Z0D1OTA3TmqzFXaEzTsKS0RGHQcfHu5ueynEtOalylcAJVXa7Z38uQo7wuYdhSXMTa5gV7X/YljVBoi3720lxue82lyFHWEzW2EJE1+aSPVfNVefaqBqDdCUfmiJslvyJO98hR1hM2thiaIrduODJ4WU0rxE5m8SDiwTXcTcXKrSM7FUdg3QP0cnIqh8QHS6FjBICDRKTM9DdPZfGw8AIHoawPSJIPNJXCxsA7CyHDn5pSr3p0Sq70sgfjzsPIKEIJ8fzrT9Muw8ZlKdWwDx5WGnEDSi+EbYOcxGVRpAQE+FnUPwcFX+T1W5BQBKb90B6KegR3kbRVgAUEtJFO8z/T4g0PtK03MHAC4cXWdSVfw237PygfI8qeSPKjXAsZPs6FusykOT1wIMj2RaFwcRO9beN8LMU3WBDcXG+Bs7V4wEETtsqnILsFQOawDDsQYwHGsAw7EGMBxrAMOxBjAcawDDsQYwHGsAw7EGMBxrAMOxBjAcawDDsQYwHGsAw7EGMBxrAMOxBjAcawDDsQYwHGsAw7EGMBxrAMOxBjAcawDDsQYwHGsAw7EGMBxrAMOxBjAcawDDsQYwHGsAw7EGMBxrAMOxBjAcawDDsQYwHGsAw7EGMBxrAMOxBjAcawDDsQYwHGsAw7EGMBxrAMOp2reG+YWBZDyd/WoQsQhomr9VbVK3BgAAAn4edg7VTpleGaMUu/GhEx13olie+O+EIm5SCtGXKjFWxNFTXNHRSowFAI5E5EDPNflyvHMoUAMk0/0fFeC7BKrKV6TVMgIMA3jMIbl7uLvt2aDiBmQApUQ6uxnQToDr5kVUVYlAQNic61l5VxArghNETvH0sjsJtBkgO/nlhkAgXNLw8Wd1/Omf/MZ/OJ/EUtnPMOHXR2rz9vJlOW7EYXBspqqET+a7W5/0E9n3XQCRbi71kfy04LobD+9Y+5rf2JZpTkjtPaVIsgvAVyY1VWwG8GU/cX2tAM3rdyfdhQuGPPv+WER5yYGelpyfuJbZSV73YLNGi68DiL6liNs0NpEY3LPh0PHG9HUSOBGNnlbypU/xbzv55WP4vquHAHlxWmEnv2DBaX5i+jJAJEIlXyKVtGL3/caipe8sVnZ8beO+DOC6GPNeE7TRTzzL/AjJIu+1o3LYTzxfBhih3IsQTwLC70/ecP/pfmJa5ibesfcsBi+bvBbISG58/BU/MX3fBibS/QMlr20XPA+mzSzYX2C4fuNbgKjAEdZzRHAHM6Y/YKr353pWrfUT2/9tILu3uRK5nIG3libGmYD+WDigUyYL5O11mj3rtUBGosS3+43t+3mA4a41LziCFkDsp71SiBSJ6OqhTKuv5R8I6IGQ4e2tj0JpOUQGg4hnOQKCVwnOpfnuVT8LIlygZ/cnb9wXG48cXglguQpOJbK7QBCowiXWlwF6rGlsbMDPwY/FYrFYLBaLxWKxWCwWi8VQ/g8rLAgk1CLo5gAAAABJRU5ErkJggg==',
    pencil: icons.pencil || 'data:image/png;base64,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',
    marker: icons.marker || 'data:image/png;base64,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',
    dragSingle: icons.dragSingle || 'data:image/png;base64,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',
    dragMultiple: icons.dragMultiple || 'data:image/png;base64,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',
    eraser: icons.eraser || 'data:image/png;base64,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',
    rectangle: icons.rectangle || 'data:image/png;base64,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',
    arc: icons.arc || 'data:image/png;base64,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',
    bezier: icons.bezier || 'data:image/png;base64,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',
    quadratic: icons.quadratic || 'data:image/png;base64,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',
    text: icons.text || 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAWVJREFUeJzt28ENgzAQAEETpf+WSQfJA6xD2ZkCjCWv7mFgLQAAAKDimN4A69y8/tczfm1+OA8ngDgBxAkgTgBxAogTQJx7gOf7dU9w6QxNgDgBxAkgTgBxAogTQJwA4t43rLH7ffa/G72LMQHiBBAngDgBxAkgTgBxAogTQJwA4gQQJ4A4AcQJIE4AcQKIu+N7gOl/C65+jzC9/1EmQJwA4gQQJ4A4AcQJIE4AcQKIE0CcAOIEECeAOAHECSBOAHECiBNAnADiBBAngDgBxAkgTgBxAogTQJwA4gQQJ4A4AcQJIE4AcQKIE0CcAOIEECeAOAHECSBOAHECiBNAnADiBBAngDgBxAkgTgBxAogTQJwA4gQQJ4A4AcQJIE4AcQKIE0CcAOIEECeAOAHECSBOAHECiBNAnADiBBAngDgBxAkgTgBxx/QGWOfm9b+esQkQJ4A4AcQJIE4AcQKIEwAAAABAxAcVTAXjELyg1wAAAABJRU5ErkJggg==',
    image: icons.image || 'data:image/png;base64,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',
    pdf: icons.pdf || 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEwAACxMBAJqcGAAAEFJJREFUeJztnXuQHMddx7/d89r38251ujvJsZGElNgWNiI4LgS6WHKCsBwTXDIkYBNsHIjLyKBQVCCYCFclIUSEJMakigQIsVOJyyUrdkVAbPlslew41oF1h6VEkmNFOr3uue/X7E43f9zpbuduT3e7O72zq5tPlapuemb619r5Tk8/fz/AYVlD7C5ALTDGPsI5f68dtgkhFwkhf08IYXbYF4VsdwFqgRByOyHkPhuLsIFzfj8hxLCxDJZC7S5Am3EfY+w/OOdt9eJcCeGfAMZYFMAdnPMdANYDWAkgWE9elFLJyrLVC2OMAeAWZ1sEcAnAECHkvwE8TSmdtNjGPIQJgHMeYoz9OYBHKKUeETbO/ftzUI+eALjVz6ICShD6xD1Q164WZ6MKjLE8gCcopY8RQpKi7AgRAGPsJs75fkqp0F/t0G9/ClqxiK6zF0WaAQ34sOKf/xLq+muF2qkGY+wsIeRuSukREflbLgDG2G2c8+cppe6q5/NFlOIpgDXemP7fR7+GkdeOYvVNGxA99TOhNQH1uhH+zB9BWXeNgMwplHAA1K1VPc0YyxNC7qCUvmS1aUsFwBjbQAj5IeZ848uJNC5+6/sYf+4QcifPWGlyBp9LQchXVXOWwTkwnsqiWBLTCfD8/DXovPPX0HXvHZADXtM5xliWUrqJEPITK21aJgDOOWWMHaGU3lyZPvnij3Dqk19COZ62ytSCeFwKIoJFwDjHRConTAQAoESDWLv3TxHu+yVTej6fnxgaGvqFW2655ZxVtizrBnLOPzr34Y/t78ePH3isKQ8fAHKFEibTecFtQoKOgBcuVVxPsDSRxPE/2IPx5w+Z0t1udzQYDP7k4MGD262yZVkNYBjGEUrppsvH2R+fxuCOR8BL5ZlrKCWIxIIIRwLQPAooEdMJ0bMFZEbTsL6nNgshBL4VQShutaF8GOco5HTEJzKIjybAKtRLNRUbv/9leCp6IOl0GgMDA4wQcl9fX9+TDRmHRQLgnK8GYPq4H/vIXyHx6tGZY82l4rr1vdBcihUmF6WYKSAzkgAXWB0QQuDrCkPzVm+81UohV8Q7Jy9AL+gzaeEtm/Dub+4xXff666+jUCgYALb29fW93IhNSz4BnPP3VR7nT18wPXxFkbHmPaua9vABQPO54F8ZBhFUywAA5xzpi3Hombwl+bk8GtZs6IUkz453xV8eQPHciOm6QCAAABJj7FuHDx/2N2LTqjZAT+VB8vCbppMrV3dCUZo/eqp6NAS6xYoA4EhdSqCYtkYEqqZg5aqoKS3x6qDp2OVyAQAopb2lUumRRuxZVQN0Vh4XzlyaNSBJCHc0JNKGUNwaAt0RECp21Ds9mkAhlbMkr3BH0NQ+KpwxD3RJ0mwNwRj7RH9/f91vlyUCoNT867Li7DfM41UFv4GLo7hVBEWLgAOZ0STyycZFIEkULs9s45LliwteSyntIoS8b8ELFkH4bKAst8T8DWSXikBPVHhNkB1LopCwQAQ1/G6c81vqtbOspoMVTUGwCSLIjCeRT2SF2phD3ePTy0oAACBrCoI9HaCS2P96djyFXJMGwAD46r1x2QkAAGRNRrAnAiqJ/TzlJjLITTRNBHWxLAUAAJKqTIlAcBslF88g28IiWLYCAABJlRHsjdbU4KqHfDyD7HhKqI16WdYCAKZa24FmiCCRRWZM2MKeuln2AgCmRBDsjUISOMMHAIVkDpnRhMg5qppxBDANlSUEeyKQVLHzFYVUHukWqgkcAVRApSkRyJrYmqCYyiE9kkArVAWOAOZAJYpgTxSyJrYmKKbzSF1KCF28shQcAVSB0CkRKIKnr/VMAelLk0LXLCyGI4AFIJQg0BOB7Gpsxc9i6Nki0hftE4EjgCtACEWwO9Lwsq/F0HM6UhfsEYEjgEUglCDQHYGywJp9qyjlp0QA1lwROAJYAoQQBLrDUD3iRZC8MAFuwaaZpeIIYIkQQuBfad0C0IUoFUpIXphsmuMGRwA1cFkEquDNJ+VCCV5ZgiR43QLgCKAOCAJdIWh+sSKQpjeg0CoicLuts+0IoE78sRBcASG73mdQZIpY0AsUzGsCY7EY1qxZY4kNRwD1QgBfLAh3UKwIZImCvHoU5ZEJU3pvby96enoWuGvpOAJoEG9nEK6QWBGQbA4jD+xB+fyoKV1RGh+pdARgAb6OINwh7+IXNkD5whgy33t5odNrn3766bpGqxwBWIS3IwBPpO61mY1ya0dHxzP9/f2uWm90BGAhnogfnqg9u6AIITsA7Fn0wjk4ArAYT9gHbzRgl/mava85AhCAO+yFt8M2EdSEIwBBuENe+GKtLwJHAAJxBbzwxYIt7ZHZEYBgXAEP/LGQ3cVYEEcATUDzu+HvCqEVqwJHAE1C87kR6ArBZlcJ83AE0ERUnwv+LtEua2rDEUCTUb0u+FdGWkYEjgBsQPWoU36LWkAEjgBsYsZvEbH3ETgCsBHZrSLQEwah9j0GRwA2o7imawLBLmsWwhFACyC7FNtE4AigRZA1BaHuqHDnVXNxBNBCSNqUyxrRfosqcQTQYkiKjFBPpGnbxh0BtCBUkZEpl1Fuwj5BRwAtCgMwlsyibIjdJ+gIoIUxDIaxZA7wiVt2ftWEQL1aMRjDaGcUIa+YrWhODdAGMABvT6ZRClm/4rjmGoAxtpYQ0jMnbTW1cTjzaid2wxr88jNfEJJ3zQLgnO8ihDxUmeY8/PbFeXLLHKcR2IYUCoWZf43SsACKgydQOnvJlEbOjcAz7WNPJgSFtDXBlJoF4VO+AqkiQVLllli4UcnIyAhOnz5tSV4NCyDz3CvI7O83pVHAFMM3M9I6vnFrhRACxa1C87uh+twtt6izUZxPwCJwzqHnitBzRUgTaXg7AlB9NW/CbVmcRmANGGUDqUtxpAWHpK0VxtgwgO8BGFzs2rk4NUAdFNN5GCUDwZ6w7Wv6AIBS+lJfX9/v13WvxWVZNpQLOtIXE3YXo2FsqwGo3wNUi9rFGFgmt6DLVOJxgVQJ6sCzeVOo+qo2vW5gCTGMWTKDpUzI67kicvE0PGH7QuM2im0CiD3+KWjXV3d1xnMF5F8fQvJf9kE/aYpKj/DDvwP/ztur3MShnzqL7POvIP3Mi+B6ad4lkU//Iby3Lx5l9ezmj4HnltbHzk9m4PJ5QJXWiJBaK7a3AXipDBafjahFXCpowAfP+98L9+abMbZ7L/IVoegrMUYnp/6gFFLYD3XdNVB33wvvb2zG6MN/B2Nyge4n4zDG41co1NIbeJwD2XgG/ljNzjlaAtsFUBw6hZEH/3Y2gRBo169B5xf/DFJHCNHP/DHO3/EweEVAagBgmRzO/frslARxa/D/5vsR2vVRqOuvRec/7Mal+/cAhjHPZvnCKM5/qKGo6yb0dB68w2/r+v56ab0Sc47i/51C4vHvAACkSACum9Yvflu+iNS3/xOTn/sGAEC7YS28H6g7qHZNcM6hZxeO8N3KtJ4AptHfOTfzN+1YuoOFzHMvo3xxHADg3Vp3UO2aKV0hxHsr07ICUK6dXXIw861fCoxDf+vteXmIpqzP/9S0A7a3AeZBCLQb1iD80D0AAGM8geLREzVlwaZb8GSBeD80EkD0rx+cl84NhsnPfr3GAs/e247YLgBt4zr0vvC1mWPiUkE9UxNJXC9h/NEnqnbprsgirXjqccN3V9/82/RS3QJoV2wXAJElSBFzF4olM8j/cBDJb+xHqaItsGQu+9hfQAcsmUH8S0/OS28kVEsLjAjXhe0CKA6ewOiu2fVuvGyAN9igkldEAQBGonrEbpYrIPP8Kw3ZmEszt3NZie0C4GUGZuGCESkSgDbdbSwOnbIs38WQBcccFkWbVlzVIaqC6KMfn5orYBzpZ15omm1VcDApUdheA9QLkSV4tmyaOpAo5O4YfB/aMtP1S/zTd1F6e7gpZZEUGbImNrikKNpXAC4NnXt3z0tn2Tzi//gUMvsONq0s7pC3FX1ALgnbBFAYOAZjZBKld2p7S/UTP0Pu4BvmRM5hJNLQj/8UuZfeWLBNob/1NogkwYhXbxzWg6Qq0AJiI4iJxDYBJL76nbruy+zvn7cIdamknjoAPHWgrnurQQjgjwVbbtVwLVxVjcBm44uFIAsOMS+atm0D2AuBb0VAePDIZuAIoEYkWYKvKwylzd/8yzgCWCJUonCFvXAHvW39zZ9L4wIgBFyek43BAD41rk6AtvzBCKWQFAmSJkP1aFA8Wlv+PxajYQG47t2BgYNHMDFwfCbtXVs2gU8Pw4YiPrxrXfPm5R1qo55egGnlg3d1F7b94Amsf2inRUVyaCY1C4BS+ihjbJ8pTZFx8+f/BJu//VmoQduiZzrUQc0CIIQkKaV3c853McZMKzVW7fhVfPDVf4Mn2rpBkhzM1DUQRAjhlNKvEEJ+Rdd10+J73zUrEVi1wprSOQinoZFASukbb7755uPJZPvu/1/uNDwUPDk5+VihUPgfKwrj0Hwa7gZu3769yDl/EcAvWlAehybjTAYtcxwBLHMcASxzHAEscxwBLHOEC6CFnGm1Fe0dMqZi2lQv1rivzwEAUKr83ai4aWhLBMAYM80QyqHZCaFCvuiIoEaKBR3Fit9MCQVM5630UWiJAAghpg383vf83MzfnAMj52vY3++AS+cmTMfe668zHZdK1r1QVn0CjlcehDbfBKkixMnEaALxcevW4l/NTIwmTb+VHPAieOtG0zW5nHV7Ka0SwGHG2IwXJ8njQvf9d5kuOPvTi7g4PA7WhFBo7QgzGC6cGcPwabPn9e4HPwxase2MMYZUyrqXyZJFoZTStGEYzwK453Ja70M7Mfnij5A9/g6Ay5+CCYyPJBAIeeFyqyACGzftAmcchZyOVCIDY46XEd+Na9Hz8d8ypY2NjcGY7/nsyh4yr4Blq4IppZ9njO2kdOqpUpeKd39zD4797qeROzHr7NEoG87nYAl4N1yLDf/6N6AV28455zh79my1y8frtWNZN5AQchTAlyvT1FgENz67Fys/difI3JXDDlUhiozuB+7Cjc/uhdoZNp0bHh5GNputdtuxuu3Ve2M1GGMa5/wFSunmuef0sTgm/+s1pAdPojSeBGft6VVLBIRKUDpD8G9ch+gHb4VSxS1eIpHA4ODgvC4gY4xzzldt3br1fF226yvywnDOg4yx/ZTSLVbnvVyJx+M4duwYyuWqn/of9PX1faDevC0fCZxeNHq7ruuPt1JQhXaEc44zZ85gaGhooYcPAI81YkPIh5kQUgLw8ODgYKGzs/OTsVgMUjXX8A5VMQwDo6OjGB4evmKfnzH29dtuu+1wI7aEtsz27dv3F1u2bLnu1KlTHw4EAvD5fFBV1Qk0WQXGGHRdRyaTQSqVAlvEZR3n/Eg2m93VqF3hHfEDBw5omqY9SSm9W7StZcRr5XL5zm3btk0sfumVEf4qbt++vXjo0KF7OOe7AbRXAMEWgzFWBvCFsbGxPisePtBk10b9/f29nPPdhJDfAxBtpu02J8U5/65hGF/ctm3bSSsztmUsdmBgQMlkMps45xs55z0AJEJIe3pbFkeBcz7KOX9rYmJiYOfOnfritzg41Mj/Ay7+WuPFMpM5AAAAAElFTkSuQmCC',
    zoom_in: icons.zoom_in || 'data:image/png;base64,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',
    zoom_out: icons.zoom_out || 'data:image/png;base64,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',
    lineWidth: icons.lineWidth || 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAACXBIWXMAAAsTAAALEwEAmpwYAAABgUlEQVR4nO3csU0DMRgF4AdKoKFhGsa5YViCHTIIomEVGlJAAwWhoYAj57N98vdJr7XQ70jBlvMSAAAAAAAAAAAAAAAAYHsuCq93k+QuyW3hdfnykuQpyWvrP+SnfZL7JMckH7JqjqdZ72ftTAWXSQ5pP5jRcjjNvrkp7YcxaqYZ+7O6x7QfxKh5nLE/vyrxT+BbkqsC6/B/70mulyzQxXcI7ZT4ADwXWIPzLJ59iQ/AQ4E1OE8Xs3cMbJNujoFJsouLoFr5vgjazdqZP7gK3pZur4IBAAAAAAAAAACAtjwK3ZZuH4XqB6j/LFw/wODp5ochU9oPY9RMM/ZndfoB2kU/wOD0A7CMfoBt0w8wuC5m7xjYJt0cAxP9ADWjH2Bg3V4FAwAAAAAAAAAAAG15FLot3T4K1Q9Q/1m4foDB080PQ6a0H8aomWbsz+r0A7SLfoDB6QdgGf0A26YfYHBdzN4xsE26OQYm+gFqRj/AwLq9CgYAAAAAAAAAAAAAAABq+gRzFKdEQnj1fQAAAABJRU5ErkJggg==',
    colorsPicker: icons.colorsPicker || 'data:image/png;base64,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',
    extraOptions: icons.extraOptions || 'data:image/png;base64,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',
    undo: icons.undo || 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABPxJREFUeNrsnVuIVVUYx9dpQiIdvOBtDGa8RILSQz4koWYvRZeXEkRztJd8ExGkSPBRSxDMB0ESxBBpSnyLMCGJChV6SSURpEkcZia8RjqpmTTT97HXYQYcZ87Za5+z917f7wd/BhT1eNZvfWutvdbeuzI0NOTALk/wFSAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAlBq9LyAkJeY5yWeSmabbz6gA70n6JX9LplkWwNoQME/yleSwZI7ktn6HzAFsoL3+R8kaBv5hnjTS63fR8DYrAL3eaAWg1xuuAPR6oxWAXm+4AtDrjVYA7fWfSNbSlPYqQLXX0/jGKgC93nAFoNcbrQD0esMVgF5vtALQ6w1XAHq90QqQR6//jwpgt9dXJE9LWqwKUAk91lWpVEI/Q4fkY0lnDv9/7f2/Sf5yyfEw/XlLck3SI+mT9PqfA0VswOD2y1mATt/4HQXuJPcl170oFyVnJeckl/zvIUDKsV4b/t2SVs5/Jb9Lzki+l/wg+aOMAuRxKniDL69DEUUrxDE/f5nWbAHKcix8ruTLyBp+tFyW7JY8jwDDrI+w14+Xu5IjkhctCzDPSK8fK/9IDrrkTiRTAmww2OvHii4tt/nrDlELoGP9FzT4Y6Mrh5diFaCTXl9T9KLShzEJMJexPlW6JDPKLsBGfxGEBk2XXyQL8xIgi82gQQchvCA5IVma27XkDIaADiZ+mawSXolhEniFxkydm5KVLANt56pkSQwXgqgG6dMtaY/hUjBzg/TR01ETY9kMWkc1SJW9sW0HUw3qiy6x34lFAOYG6aLf1eyYBGBuUH8OxCYAc4P6omcQl8UoQN5zg0G/M6enex8WXILv3Cj3cYS2XxHuCxh5gGRnrevfjPhT8qo/tTPJZ6pLnh/c7uXU4WqBZLrL/0aatyTHy34qeLxq0NXEXqWneVvH+UwtXoiXJZslR3M883DSJXczRTUEPG6l0Iwv+Ybv2fUyRfKGZJ9L7g9olgB6J9MKCwI0a26QVoCRTJa87ZL7AgaaIMEhKwJUWd/AlUIWAoxkkZ/HXG7wjmGbJQEaWQ2yFqCKHvPa6jd1GiHBRmsCNGpu0CgBqsxyydNL72UswNdWBci6GjRagCp6DPznDAXQW9jnWBUgy7lBswSorhz2ZyjBKusCZFENmilAlS2SBxkIsAcBwncY8xBAWe2G31eUNj/plUkECNthzEsA5U1/KTrkFPFMBAirBnkKoLwuuROwkbWc18Y9ilaBlX5PoejoDSHv++3euvfhXHL7fRCxvjSqx1eC6oMpioxeQv4g5Z99NvhfN/Dm0LFWCnkPASPZk2IY+Jw5QNjcoEgCTJB8W6cA3yBA2EqhSAIoz7j6NpJOI0D6atDnL8jMKNhne81PCmsR4FcESM98l7w+vq2An21HjQJ0I0A4RVwJPSU5VYMAvVwHCKeID7jQQ6qbXPIA67FoidF+SDjvkrME5sofDPOpS84RNKx6IUCx0aFgq1+tUAGMog+WPIAAttFl4ZVRfr2CADbQo+DbEcA2+iTW4whgF73w85HL+OVVCFAuLjh/GNQzIfQvLNLt4VAbrX4o0FfS9Ev7Lc5VACg3DAEIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgACAAIAAgApeN/AQYAUjtq/Zx6jVYAAAAASUVORK5CYII=',
    pdf_next: icons.pdf_next || 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAAYdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjEuMWMqnEsAAAYASURBVHhe7d3RjRs3EMZxPwRwAwFcQAA3EMANBK4gcAOBKwjcQOAKzh3EFcQdxB1cCdeBS1DyKVhYof/y6cghOeTMw+/l81niLme5XO5KenY6nVJgGKY4MExxYJjiwDDFgWGKA8MUB4YpDgxTHBimODBMcWCY4sAwxYFhigPDFAeGKQ4MUxwYpjgwTHFguIuHh4fT358/n/54//7sl9evH/Xrmzfnv7378OH8f798+fLvS/Hr7wDDVd3f3587Tp3444sXpx+ePzfx08uXp9/evj39+fHjSUVVvu/KMFyJOv33d+/OnUSd18PPr16dC22HYsDQOw3L6oCRnX6NThsaGco2rgJDr3TE6fxsObxbUTGqbavNGTD0RjvVa8eX1EaNTuU2eIWhJ9qZK3R8SSOCriLK7fEGQw80udP5lXbuSnRF4vm0gOFsqx7112hbvI4GGM6iI0VHDO3EHehytdzm2TCcQUO+rq9px+1EpzVPpwQMR1Pn7zTkP0aF7mURCcOR/vr0KVTnH7TNKvxyf4yG4ShaQaOdE4WHIsBwBG047ZRoZhcBhr1FO+c/RnOCWRNDDHvShmbnf0tFUO6rETDsKcKlXi09c1Dur94w7EULIbTh6avRt5Yx7EFLobTB6f90ehy5RoChNZ33PTy8sQqtFpb7sBcMreXQ/3SjTgUYWlrlel9Dr6erE7VlxKUhhpZWuKevna1C9bY+MeLuIYZWVpj4HZ1/tNlbEfSeEGJoxfvRX3b+wVMR9F4bwNCC96P/WucfPBVBz1EAQwuej/7HOv/gpQj0RHTZNisYtlLF0oZ4cGvnHzwUgd6/bJcVDFt5ve5/aucfPBSBHpwp22UBw1YeV/1qO188PLiih2XLdlnAsIV2Mm3ATKt3/qHHwhCGLbwN/7t0vvQ4DWDYwtP9/p06X3qsCWBYS0MUNXyG3TpfNLcq29oKw1peFn927PyD9TwAw1pasKBGj7Rz54v1ZwwxrDX7c327d75YrwpiWGvmBDBC54v1egCGtajBI0TpfLF+XAzDGrOuACJ1vmh7y+1ogWGNGVcA0Tr/UG5LCwxrjC6AqJ0v5fa0wLDGyAKI3PliuRaAYY1RBRC988VyLQDDGqMKoPY6WEeNiodeczWhC0B0JJfvfwuNHDsUQfgCkMhFUG5TCwxrjC4AiVoE5fa0wLDGjAKQiEVQbksLDGtRY0eIVATWzwRgWIsaPEqUInB7L0BmfxgkQhFYPxaGYS01jho90u5FcGf8WwQY1vLwRJDsXASWawCCYa1ZVwKktgg8bQMp29sKwxbU6Flqi0D/j15vth7fJYhhC2+fCt6pCHp8YwiGLTRJocbPtEsRWJ//BcMWXj8avnoRaHJats0Chq28fh3sykXQ66tiMGzl8TRwqCkCD5eHakPZLgsYtvL0GUHylCLw0Pk9PhN4wNCCh1XB77mlCLwsDNWeum6BoQXP3xN0+N6O1b956Hy1wfoDoZcwtLLCbwBSESijv52h5zeECYZWNITSRnlzWQSeOr/30S8YWvI+Fzio4z11vtwZ3/kjGFrSXMDDuXQ1PWf+lzC0pkqmjUzX9Vj2JRj2kD8WdbsRXxN/wLAHL9fU3mno7z3xu4RhL94mWR71WvK9BsOeVrkqmOHycnQUDHvL+cC3et3tewyGvekcl0XwlfWz/k+B4Qg5KfyPDoSRk74ShqNEL4LZnS8YjqQi0KUP7aCdeeh8wXC0aHMCTfg8dL5gOIN2yAq3j1v1vr37VBjOtOt9A811ev3uTwsMZ9ttXqDLvJ6//dcCQw90SvD662O30lE/4p5+Cww90Wjg7eNmt9BEz+tRfwlDj3T+XOG0oGIddS/fAoae6YaJxxFBVzArdfwBwxXo1KBhduZKokYkzVNWGOqvwXA1Oj2MKgZ1ut7L4yVdDQxXppFBM28NyRZzBq1QqsP1mnrt8v1Wh+FudG4WrcIdNHRrLiGXuehvd+xsgmGKA8MUB4YpDgxTHBimODBMcWCY4sAwxYFhigPDFAeGKQ4MUxwYpjgwTHFgmOLAMMWBYYoDwxTF6dk/P8ngRg7z9FEAAAAASUVORK5CYII=',
    pdf_prev: icons.pdf_prev || 'data:image/png;base64,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',
    pdf_close: icons.pdf_close || 'data:image/png;base64,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
Download .txt
gitextract_ce2vii70/

├── .gitignore
├── Canvas-Designer/
│   ├── .gitignore
│   ├── .npmignore
│   ├── .travis.yml
│   ├── Gruntfile.js
│   ├── Help/
│   │   └── index.html
│   ├── LICENSE
│   ├── README.md
│   ├── bower.json
│   ├── canvas-designer-widget.js
│   ├── dev/
│   │   ├── amd.js
│   │   ├── arc-handler.js
│   │   ├── arrow-handler.js
│   │   ├── bezier-handler.js
│   │   ├── common.js
│   │   ├── data-uris.js
│   │   ├── decorator.js
│   │   ├── drag-helper.js
│   │   ├── draw-helper.js
│   │   ├── eraser-handler.js
│   │   ├── events-handler.js
│   │   ├── file-selector.js
│   │   ├── head.js
│   │   ├── image-handler.js
│   │   ├── line-handler.js
│   │   ├── marker-handler.js
│   │   ├── pdf-handler.js
│   │   ├── pencil-handler.js
│   │   ├── quadratic-handler.js
│   │   ├── rect-handler.js
│   │   ├── share-drawings.js
│   │   ├── tail.js
│   │   ├── text-handler.js
│   │   ├── webrtc-handler.js
│   │   └── zoom-handler.js
│   ├── index.html
│   ├── multiple.html
│   ├── package.json
│   ├── server.js
│   ├── simple.html
│   ├── widget.html
│   └── widget.js
├── Chrome-Extensions/
│   ├── .gitignore
│   ├── LICENSE
│   ├── README.md
│   ├── Screen-Capturing.js/
│   │   ├── README.md
│   │   ├── Screen-Capturing.js
│   │   ├── index.html
│   │   └── server.js
│   ├── desktopCapture/
│   │   ├── README.md
│   │   ├── background-script.js
│   │   ├── content-script.js
│   │   ├── different-api/
│   │   │   ├── background-script.js
│   │   │   └── manifest.json
│   │   └── manifest.json
│   ├── desktopCapture-p2p/
│   │   ├── README.md
│   │   ├── background/
│   │   │   ├── captureCamera.js
│   │   │   ├── captureDesktop.js
│   │   │   ├── captureTabUsingTabCapture.js
│   │   │   ├── common.js
│   │   │   ├── globals.js
│   │   │   ├── gotStream.js
│   │   │   ├── gotTabCaptureStream.js
│   │   │   ├── helpers/
│   │   │   │   ├── AntMediaWrapper.js
│   │   │   │   ├── CodecsHandler.js
│   │   │   │   ├── IceServersHandler.js
│   │   │   │   ├── MultiStreamsMixer.js
│   │   │   │   ├── adapter.js
│   │   │   │   ├── getStats.js
│   │   │   │   └── socket.io.js
│   │   │   ├── onAccessApproved.js
│   │   │   ├── online-offline.js
│   │   │   ├── runtimePort.js
│   │   │   ├── setDefaults.js
│   │   │   ├── setupWebRTCConnection.js
│   │   │   ├── shareStreamUsingAntMediaServer.js
│   │   │   └── shareStreamUsingRTCMultiConnection.js
│   │   ├── extension-pages/
│   │   │   ├── camera-mic.html
│   │   │   ├── camera-mic.js
│   │   │   ├── chat.html
│   │   │   ├── chat.js
│   │   │   ├── dropdown.html
│   │   │   ├── dropdown.js
│   │   │   ├── options.html
│   │   │   ├── options.js
│   │   │   ├── video.html
│   │   │   └── video.js
│   │   ├── index.html
│   │   ├── manifest.json
│   │   ├── screen-receivers/
│   │   │   └── ant/
│   │   │       └── index.html
│   │   └── server.js
│   ├── file-sharing/
│   │   ├── README.md
│   │   ├── background.js
│   │   ├── fonts/
│   │   │   └── MyriadPro-Light.otf
│   │   ├── info.html
│   │   ├── manifest.json
│   │   ├── options.html
│   │   ├── options.js
│   │   ├── popup.html
│   │   ├── popup.js
│   │   └── rmc-files-handler.js
│   ├── get-any-webrtc-peer-stream/
│   │   ├── RTCPeerConnection-override.js
│   │   ├── content-script.js
│   │   └── manifest.json
│   ├── getUserMedia-on-http/
│   │   ├── README.md
│   │   ├── background-script.js
│   │   ├── camera-mic.html
│   │   ├── camera-mic.js
│   │   ├── content-script.js
│   │   ├── example/
│   │   │   ├── index.html
│   │   │   └── index.js
│   │   ├── manifest.json
│   │   └── webrtc-handler.js
│   ├── screen-recording/
│   │   ├── README.md
│   │   ├── RecordRTC/
│   │   │   ├── DiskStorage.js
│   │   │   ├── EBML.js
│   │   │   ├── MediaStreamRecorder.js
│   │   │   ├── MultiStreamRecorder.js
│   │   │   ├── MultiStreamsMixer.js
│   │   │   ├── StereoAudioRecorder.js
│   │   │   └── getAllAudioVideoDevices.js
│   │   ├── background/
│   │   │   ├── background.badgeText.js
│   │   │   ├── background.common.js
│   │   │   ├── background.contentScript.js
│   │   │   ├── background.desktopCapture.js
│   │   │   ├── background.getUserMedia.js
│   │   │   ├── background.js
│   │   │   ├── background.messaging.js
│   │   │   ├── background.players.js
│   │   │   └── background.tabCapture.js
│   │   ├── camera-mic.html
│   │   ├── camera-mic.js
│   │   ├── dropdown.html
│   │   ├── dropdown.js
│   │   ├── manifest.json
│   │   ├── options.html
│   │   ├── options.js
│   │   ├── preview/
│   │   │   ├── preview.js
│   │   │   ├── preview.php.upload.js
│   │   │   └── preview.youtube.upload.js
│   │   ├── preview.html
│   │   ├── video.html
│   │   └── video.js
│   └── tabCapture/
│       ├── CodecsHandler.js
│       ├── IceServersHandler.js
│       ├── README.md
│       ├── index.html
│       ├── manifest.json
│       ├── options.html
│       ├── options.js
│       ├── shareStreamUsingRTCMultiConnection.js
│       ├── socket.io.js
│       └── tab-capturing.js
├── ConcatenateBlobs/
│   ├── ConcatenateBlobs.js
│   ├── README.md
│   ├── index.html
│   └── package.json
├── Conversation.js/
│   ├── AndroidRTC/
│   │   ├── fonts/
│   │   │   ├── MyriadPro-Bold.otf
│   │   │   ├── MyriadPro-Light.otf
│   │   │   └── MyriadPro-Regular.otf
│   │   ├── index.html
│   │   ├── manifest.json
│   │   ├── scripts/
│   │   │   ├── FileBufferReader.js
│   │   │   ├── RTCMultiConnection.js
│   │   │   ├── common-signaling.js
│   │   │   ├── conversation.js
│   │   │   └── ui-handler.js
│   │   └── styles/
│   │       └── ui-styles.css
│   ├── README.md
│   ├── conversation.js
│   ├── demos/
│   │   ├── common-signaling.js
│   │   ├── common-styles.css
│   │   ├── cross-language-chat.html
│   │   └── search-user.html
│   ├── package.json
│   └── server.js
├── DataChannel/
│   ├── .gitignore
│   ├── .jshintrc
│   ├── .npmignore
│   ├── .travis.yml
│   ├── DataChannel.js
│   ├── Gruntfile.js
│   ├── README.md
│   ├── auto-session-establishment.html
│   ├── bower.json
│   ├── dev/
│   │   ├── DataChannel.js
│   │   ├── DataConnector.js
│   │   ├── FileConverter.js
│   │   ├── FileReceiver.js
│   │   ├── FileSaver.js
│   │   ├── FileSender.js
│   │   ├── IceServersHandler.js
│   │   ├── RTCPeerConnection.js
│   │   ├── SocketConnector.js
│   │   ├── TextReceiver.js
│   │   ├── TextSender.js
│   │   ├── externalIceServers.js
│   │   ├── globals.js
│   │   ├── head.js
│   │   └── tail.js
│   ├── index.html
│   ├── package.json
│   ├── server.js
│   └── simple.html
├── DetectRTC/
│   ├── .gitignore
│   ├── .jshintrc
│   ├── .npmignore
│   ├── .travis.yml
│   ├── DetectRTC.js
│   ├── Gruntfile.js
│   ├── LICENSE
│   ├── README.md
│   ├── bower.json
│   ├── dev/
│   │   ├── CheckDeviceSupport.js
│   │   ├── DetectLocalIPAddress.js
│   │   ├── DetectRTC.js
│   │   ├── Objects.js
│   │   ├── common.js
│   │   ├── detectCaptureStream.js
│   │   ├── detectDesktopOS.js
│   │   ├── detectOSName.js
│   │   ├── detectPrivateBrowsing.js
│   │   ├── getBrowserInfo.js
│   │   ├── head.js
│   │   ├── isMobile.js
│   │   └── tail.js
│   ├── index.html
│   ├── npm-test.js
│   ├── package.json
│   ├── server.js
│   ├── simple-demos/
│   │   ├── select-cameras.html
│   │   └── simple-demo.html
│   └── test/
│       ├── CheckDeviceSupport.js
│       ├── DetectRTC.js
│       ├── browserstack.config.js
│       ├── detectOSName.js
│       ├── getBrowserInfo.js
│       └── html-test-files/
│           ├── CheckDeviceSupport.html
│           ├── DetectRTC.html
│           ├── detectOSName.html
│           └── getBrowserInfo.html
├── FileBufferReader/
│   ├── .gitignore
│   ├── .npmignore
│   ├── .travis.yml
│   ├── FileBufferReader.js
│   ├── Gruntfile.js
│   ├── LICENSE
│   ├── README.md
│   ├── bower.json
│   ├── demo/
│   │   ├── IceServersHandler.js
│   │   ├── PeerConnection.js
│   │   ├── PeerUI.js
│   │   ├── adapter-latest.js
│   │   └── index.html
│   ├── dev/
│   │   ├── FileBufferReader.js
│   │   ├── FileBufferReaderHelper.js
│   │   ├── FileBufferReceiver.js
│   │   ├── FileConverter.js
│   │   ├── FileSelector.js
│   │   ├── binarize.js
│   │   ├── common.js
│   │   ├── head.js
│   │   └── tail.js
│   ├── fbr-client/
│   │   ├── .gitignore
│   │   ├── .npmignore
│   │   ├── README.md
│   │   ├── demo/
│   │   │   ├── circular-progress-bar.css
│   │   │   ├── style.css
│   │   │   └── ui.js
│   │   ├── index.html
│   │   ├── package.json
│   │   └── server.js
│   ├── index.html
│   ├── package.json
│   └── server.js
├── Firefox-Extensions/
│   ├── README.md
│   ├── enable-screen-capturing/
│   │   ├── README.md
│   │   ├── content-script.js
│   │   ├── index.js
│   │   ├── package.json
│   │   └── test/
│   │       └── test-index.js
│   ├── enable-screen-capturing-old/
│   │   ├── README.md
│   │   ├── bootstrap.js
│   │   ├── enable-screen-capturing.xpi
│   │   └── install.rdf
│   └── enable-screen-capturing-old2/
│       ├── FirefoxScreenAddon.js
│       ├── README.md
│       ├── content-script.js
│       ├── index.js
│       ├── package.json
│       └── test/
│           └── test-index.js
├── LICENSE
├── MediaStreamRecorder/
│   ├── .gitignore
│   ├── .npmignore
│   ├── .travis.yml
│   ├── AudioStreamRecorder/
│   │   ├── FlashAudioRecorder.js
│   │   ├── FlashAudioRecorder.md
│   │   ├── MediaRecorderWrapper.js
│   │   ├── README.md
│   │   ├── StereoAudioRecorder.js
│   │   ├── StereoAudioRecorderHelper.js
│   │   └── lib/
│   │       ├── recorder.js/
│   │       │   ├── recorder.js
│   │       │   └── recorder.swf
│   │       └── wavencoder/
│   │           └── wavencoder.js
│   ├── FileSystem/
│   │   ├── FileReader.js
│   │   ├── FileWriter.js
│   │   └── README.md
│   ├── Gruntfile.js
│   ├── LICENSE
│   ├── MediaStreamRecorder.js
│   ├── README.md
│   ├── VideoStreamRecorder/
│   │   ├── GifRecorder.js
│   │   ├── README.md
│   │   ├── WhammyRecorder.js
│   │   ├── WhammyRecorderHelper.js
│   │   └── lib/
│   │       ├── gif-encoder.js
│   │       └── whammy.js
│   ├── bower.json
│   ├── common/
│   │   ├── ConcatenateBlobs.js
│   │   ├── Cross-Browser-Declarations.js
│   │   ├── MediaStreamRecorder.js
│   │   ├── MultiStreamRecorder.js
│   │   ├── MultiStreamsMixer.js
│   │   ├── OpentTokStreamRecorder.js
│   │   └── amd.js
│   ├── demos/
│   │   ├── MultiStreamRecorder.html
│   │   ├── README.md
│   │   ├── audio-recorder.html
│   │   ├── flash-audio-recorder-upload.html
│   │   ├── flash-audio-recorder.html
│   │   ├── gif-recorder.html
│   │   ├── index.html
│   │   ├── opentok-stream-recorder.html
│   │   └── video-recorder.html
│   ├── fake-keys/
│   │   ├── certificate.pem
│   │   └── privatekey.pem
│   ├── lib/
│   │   └── AjaxRequest/
│   │       └── AjaxRequest.js
│   ├── npm-test.js
│   ├── package.json
│   ├── server.js
│   └── tests/
│       └── flash-audio-recorder-memory-usage.html
├── MultiRTC/
│   ├── .gitignore
│   ├── MultiRTC-firebase/
│   │   ├── FileBufferReader.js
│   │   ├── README.md
│   │   ├── RTCMultiConnection.js
│   │   ├── firebase.js
│   │   ├── index.html
│   │   ├── linkify.js
│   │   ├── package.json
│   │   ├── scrol-bars.css
│   │   ├── style.css
│   │   ├── ui.main.js
│   │   ├── ui.peer-connection.js
│   │   ├── ui.settings.js
│   │   ├── ui.share-files.js
│   │   └── ui.users-list.js
│   ├── MultiRTC-socketio/
│   │   ├── README.md
│   │   ├── certificate.pem
│   │   ├── package.json
│   │   ├── privatekey.pem
│   │   ├── public/
│   │   │   ├── FileBufferReader.js
│   │   │   ├── RTCMultiConnection.js
│   │   │   ├── index.html
│   │   │   ├── linkify.js
│   │   │   ├── scrol-bars.css
│   │   │   ├── style.css
│   │   │   ├── ui.main.js
│   │   │   ├── ui.peer-connection.js
│   │   │   ├── ui.settings.js
│   │   │   ├── ui.share-files.js
│   │   │   └── ui.users-list.js
│   │   └── signaler.js
│   ├── MultiRTC-websocket/
│   │   ├── FileBufferReader.js
│   │   ├── README.md
│   │   ├── RTCMultiConnection.js
│   │   ├── index.html
│   │   ├── linkify.js
│   │   ├── package.json
│   │   ├── scrol-bars.css
│   │   ├── style.css
│   │   ├── ui.main.js
│   │   ├── ui.peer-connection.js
│   │   ├── ui.settings.js
│   │   ├── ui.share-files.js
│   │   └── ui.users-list.js
│   └── README.md
├── MultiStreamsMixer/
│   ├── .gitignore
│   ├── .npmignore
│   ├── .travis.yml
│   ├── Gruntfile.js
│   ├── LICENSE
│   ├── MultiStreamsMixer.js
│   ├── MultiStreamsMixer.ts
│   ├── README.md
│   ├── bower.json
│   ├── dev/
│   │   ├── README.md
│   │   ├── amd.js
│   │   ├── append-streams.js
│   │   ├── cross-browser-declarations.js
│   │   ├── draw-videos-on-canvas.js
│   │   ├── get-mixed-audio-stream.js
│   │   ├── get-mixed-stream.js
│   │   ├── get-mixed-video-stream.js
│   │   ├── get-video-element.js
│   │   ├── head.js
│   │   ├── init.js
│   │   ├── module.exports.js
│   │   ├── release-streams.js
│   │   ├── replace-streams.js
│   │   ├── start-drawing-frames.js
│   │   └── tail.js
│   ├── index.html
│   ├── npm-test.js
│   ├── package.json
│   └── server.js
├── PluginRTC/
│   ├── Plugin.EveryWhere.js
│   ├── Plugin.Temasys.js
│   └── README.md
├── Pluginfree-Screen-Sharing/
│   ├── README.md
│   ├── conference.js
│   └── index.html
├── Pre-recorded-Media-Streaming/
│   ├── MediaStreamer.js
│   ├── README.md
│   ├── index-2.html
│   ├── index-old.html
│   ├── index.html
│   └── streamer.js
├── README.md
├── RTCMultiConnection/
│   ├── .gitignore
│   ├── .jshintrc
│   ├── .npmignore
│   ├── .travis.yml
│   ├── CONTRIBUTING.md
│   ├── Gruntfile.js
│   ├── LICENSE.md
│   ├── README.md
│   ├── admin/
│   │   ├── admin-ui.js
│   │   └── index.html
│   ├── bower.json
│   ├── config.json
│   ├── demos/
│   │   ├── Audio-Conferencing.html
│   │   ├── Call-By-UserName.html
│   │   ├── One-to-One.html
│   │   ├── README.md
│   │   ├── SSEConnection/
│   │   │   ├── README.md
│   │   │   ├── SSE.php
│   │   │   ├── checkPresence.php
│   │   │   ├── enableCORS.php
│   │   │   ├── get-param.php
│   │   │   ├── publish.php
│   │   │   ├── rooms/
│   │   │   │   └── README.md
│   │   │   └── write-json.php
│   │   ├── SSEConnection.html
│   │   ├── Scalable-Broadcast.html
│   │   ├── Video-Conferencing.html
│   │   ├── camera-zoom.html
│   │   ├── dashboard/
│   │   │   ├── canvas-designer-old.html
│   │   │   ├── canvas-designer.html
│   │   │   ├── index-old.html
│   │   │   └── index.html
│   │   ├── file-sharing.html
│   │   ├── getStats.html
│   │   ├── index.html
│   │   ├── menu.js
│   │   ├── screen-sharing.html
│   │   ├── stylesheet.css
│   │   ├── text-chat-file-sharing.html
│   │   ├── translate-text-chat.html
│   │   ├── video-and-screen-sharing.html
│   │   ├── video-broadcasting.html
│   │   ├── video-conference/
│   │   │   ├── index.html
│   │   │   └── video-conference.html
│   │   ├── video-conferencing-chat-filesharing.html
│   │   └── vuejs-video-conferencing.html
│   ├── dev/
│   │   ├── BandwidthHandler.js
│   │   ├── BluetoothConnection.js
│   │   ├── CodecsHandler.js
│   │   ├── FileProgressBarHandler.js
│   │   ├── FileSelector.js
│   │   ├── FirebaseConnection.js
│   │   ├── IceServersHandler.js
│   │   ├── MediaStreamRecorder.js
│   │   ├── MultiPeersHandler.js
│   │   ├── MultiStreamsMixer.js
│   │   ├── OnIceCandidateHandler.js
│   │   ├── Plugin.EveryWhere.js
│   │   ├── PubNubConnection.js
│   │   ├── README.md
│   │   ├── RTCMultiConnection.js
│   │   ├── RTCPeerConnection.js
│   │   ├── RecordingHandler.js
│   │   ├── SSEConnection.js
│   │   ├── SignalRConnection.js
│   │   ├── SipConnection.js
│   │   ├── SocketConnection.js
│   │   ├── StreamHasData.js
│   │   ├── StreamsHandler.js
│   │   ├── TextSenderReceiver.js
│   │   ├── TranslationHandler.js
│   │   ├── WebSocketConnection.js
│   │   ├── WebSyncConnection.js
│   │   ├── XHRConnection.js
│   │   ├── amd.js
│   │   ├── enableV2Api.js
│   │   ├── getHTMLMediaElement.css
│   │   ├── getHTMLMediaElement.js
│   │   ├── getUserMedia.js
│   │   ├── globals.js
│   │   ├── gumadapter.js
│   │   ├── head.js
│   │   ├── ios-hacks.js
│   │   └── tail.js
│   ├── dist/
│   │   ├── README.md
│   │   └── RTCMultiConnection.js
│   ├── docs/
│   │   ├── README.md
│   │   ├── api.md
│   │   ├── getting-started.md
│   │   ├── how-to-use.md
│   │   ├── installation-guide.md
│   │   ├── ios-android.md
│   │   ├── tips-tricks.md
│   │   └── upgrade.md
│   ├── fake-keys/
│   │   ├── certificate.pem
│   │   └── privatekey.pem
│   ├── logs.json
│   ├── npm-test.js
│   ├── package.json
│   └── server.js
├── RTCMultiConnection-Server/
│   ├── .gitignore
│   ├── .npmignore
│   ├── LICENSE
│   ├── README.md
│   ├── bower.json
│   ├── config.json
│   ├── fake-keys/
│   │   ├── certificate.pem
│   │   └── privatekey.pem
│   ├── logs.json
│   ├── package.json
│   └── server.js
├── RTCMultiConnection-SignalR/
│   ├── LICENSE
│   ├── README.md
│   ├── RTCMultiConnection/
│   │   ├── Properties/
│   │   │   └── AssemblyInfo.cs
│   │   ├── RTCMultiConnection.csproj
│   │   ├── RTCMultiConnectionHub.cs
│   │   ├── RTCMultiConnectionSignaling.cs
│   │   ├── Scripts/
│   │   │   ├── RTCMultiConnection.js
│   │   │   ├── jquery-1.10.2.intellisense.js
│   │   │   ├── jquery-1.10.2.js
│   │   │   └── jquery.signalR-2.1.2.js
│   │   ├── SignalRConnection.js
│   │   ├── Web.Debug.config
│   │   ├── Web.Release.config
│   │   ├── Web.config
│   │   ├── index.html
│   │   └── packages.config
│   ├── RTCMultiConnection.sln
│   └── packages/
│       └── README.md
├── RTCPeerConnection/
│   ├── README.md
│   ├── RTCPeerConnection-Helpers.js
│   ├── RTCPeerConnection-v1.1.js
│   ├── RTCPeerConnection-v1.2.js
│   ├── RTCPeerConnection-v1.3.js
│   ├── RTCPeerConnection-v1.4.js
│   ├── RTCPeerConnection-v1.5.js
│   ├── RTCPeerConnection-v1.6.js
│   └── RTCPeerConnection.js
├── RTCall/
│   ├── README.md
│   ├── RTCall.js
│   └── index.html
├── Record-Entire-Meeting/
│   ├── .gitignore
│   ├── .npmignore
│   ├── Browser-Recording-Helper.js
│   ├── Concatenate-Recordings.js
│   ├── MediaStreamRecorder.js
│   ├── Nodejs-Recording-Handler.js
│   ├── README.md
│   ├── Write-Recordings-To-Disk.js
│   ├── fake-keys/
│   │   ├── certificate.pem
│   │   └── privatekey.pem
│   ├── index.html
│   ├── package.json
│   └── server.js
├── RecordRTC/
│   ├── .gitignore
│   ├── .jshintrc
│   ├── .npmignore
│   ├── .travis.yml
│   ├── CONTRIBUTING.md
│   ├── Canvas-Recording/
│   │   ├── Canvas-Animation-Recording-Plus-Microphone-Plus-Mp3.html
│   │   ├── Canvas-Animation-Recording-Plus-Microphone.html
│   │   ├── Canvas-Animation-Recording-Plus-Mp3.html
│   │   ├── Canvas-Animation-Recording.html
│   │   ├── README.md
│   │   ├── canvas-designer.js
│   │   ├── index.html
│   │   ├── record-canvas-drawings.html
│   │   ├── video.webm
│   │   └── webpage-recording.html
│   ├── Gruntfile.js
│   ├── LICENSE
│   ├── MRecordRTC/
│   │   ├── README.md
│   │   └── index.html
│   ├── PHP-and-FFmpeg/
│   │   ├── .htaccess
│   │   ├── README.md
│   │   ├── index.html
│   │   ├── save.php
│   │   └── uploads/
│   │       └── README.md
│   ├── README.md
│   ├── RecordRTC-over-Socketio/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── ffmpeg-output/
│   │   │   └── README.md
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── server.js
│   │   └── uploads/
│   │       └── README.md
│   ├── RecordRTC-to-ASPNETMVC/
│   │   ├── README.md
│   │   ├── RecordRTC_to_ASPNETMVC/
│   │   │   ├── Controllers/
│   │   │   │   ├── README.md
│   │   │   │   └── RecordRTCController.cs
│   │   │   ├── Global.asax
│   │   │   ├── Global.asax.cs
│   │   │   ├── Properties/
│   │   │   │   └── AssemblyInfo.cs
│   │   │   ├── RecordRTC_to_ASPNETMVC.csproj
│   │   │   ├── RecordRTC_to_ASPNETMVC.csproj.user
│   │   │   ├── Views/
│   │   │   │   ├── RecordRTC/
│   │   │   │   │   └── Index.cshtml
│   │   │   │   ├── Web.config
│   │   │   │   └── _ViewStart.cshtml
│   │   │   ├── Web.Debug.config
│   │   │   ├── Web.Release.config
│   │   │   ├── Web.config
│   │   │   ├── bin/
│   │   │   │   └── RecordRTC_to_ASPNETMVC.pdb
│   │   │   └── uploads/
│   │   │       └── README.md
│   │   └── RecordRTC_to_ASPNETMVC.sln
│   ├── RecordRTC-to-Nodejs/
│   │   ├── .gitignore
│   │   ├── README.md
│   │   ├── index.html
│   │   ├── package.json
│   │   └── server.js
│   ├── RecordRTC-to-PHP/
│   │   ├── .htaccess
│   │   ├── README.md
│   │   ├── delete.php
│   │   ├── index.html
│   │   ├── save.php
│   │   └── uploads/
│   │       └── README.md
│   ├── RecordRTC.js
│   ├── WebGL-Recording/
│   │   ├── README.md
│   │   ├── assets/
│   │   │   ├── DST-Canopy.ogg
│   │   │   ├── blank.cur
│   │   │   ├── duck.dae
│   │   │   ├── pickup.ogg
│   │   │   ├── scene.xml
│   │   │   ├── seymourplane_triangulate.dae
│   │   │   └── target.dae
│   │   ├── index.html
│   │   ├── logic.js
│   │   ├── plotly.html
│   │   ├── style.css
│   │   ├── vendor/
│   │   │   ├── README.md
│   │   │   ├── backbone-min.js
│   │   │   ├── buzz.js
│   │   │   ├── glge-compiled-min.js
│   │   │   ├── glge-compiled.js
│   │   │   └── underscore-min.js
│   │   └── view.js
│   ├── bower.json
│   ├── dev/
│   │   ├── CanvasRecorder.js
│   │   ├── Cross-Browser-Declarations.js
│   │   ├── DiskStorage.js
│   │   ├── GetRecorderType.js
│   │   ├── GifRecorder.js
│   │   ├── MRecordRTC.js
│   │   ├── MediaStreamRecorder.js
│   │   ├── MultiStreamRecorder.js
│   │   ├── MultiStreamsMixer.js
│   │   ├── README.md
│   │   ├── RecordRTC-Configuration.js
│   │   ├── RecordRTC.IndexedDB.js
│   │   ├── RecordRTC.js
│   │   ├── RecordRTC.promises.js
│   │   ├── StereoAudioRecorder.js
│   │   ├── Storage.js
│   │   ├── WebAssemblyRecorder.js
│   │   ├── Whammy.js
│   │   ├── WhammyRecorder.js
│   │   ├── amd.js
│   │   └── isMediaRecorderCompatible.js
│   ├── index.html
│   ├── libs/
│   │   ├── EBML.js
│   │   ├── gif-recorder.js
│   │   ├── webm-wasm.js
│   │   ├── webm-wasm.wasm
│   │   └── webm-worker.js
│   ├── npm-test.js
│   ├── package.json
│   ├── server.js
│   ├── simple-demos/
│   │   ├── 16khz-audio-recording.html
│   │   ├── README.md
│   │   ├── Record-Mp3-or-Wav.html
│   │   ├── RecordRTCPromisesHandler.html
│   │   ├── RecordRTC_Extension.html
│   │   ├── WebAssemblyRecorder.html
│   │   ├── audio-recording.html
│   │   ├── auto-stop-on-silence.html
│   │   ├── bitsPerSecond.html
│   │   ├── calculate-recording-duration.html
│   │   ├── destroy.html
│   │   ├── edge-audio-recording.html
│   │   ├── embedded-iframes.html
│   │   ├── gif-recording.html
│   │   ├── index.html
│   │   ├── isTypeSupported.html
│   │   ├── multi-audios-recording.html
│   │   ├── multi-cameras-recording.html
│   │   ├── onStateChanged.html
│   │   ├── onTimeStamp.html
│   │   ├── ondataavailable-StereoAudioRecorder.html
│   │   ├── ondataavailable.html
│   │   ├── pass-getUserMedia-constraints.html
│   │   ├── php-upload-jquery.html
│   │   ├── php-upload-simple-javascript.html
│   │   ├── preview-blob-size-during-recording.html
│   │   ├── raw-pcm.html
│   │   ├── record-cropped-screen.html
│   │   ├── recording-html-element.html
│   │   ├── reuse-same-instance.html
│   │   ├── screen-recording.html
│   │   ├── seeking-workaround.html
│   │   ├── setRecordingDuration.html
│   │   ├── show-animated-bar-on-video.html
│   │   ├── show-logo-on-recorded-video.html
│   │   ├── video-mirror-recording.html
│   │   ├── video-plus-screen-recording.html
│   │   └── video-recording.html
│   └── test/
│       ├── README.md
│       ├── audio-recording-using-StereoAudioRecorder.js
│       ├── audio-recording.js
│       ├── browserstack.config.js
│       ├── canvas-recording.js
│       ├── html-test-files/
│       │   ├── README.md
│       │   ├── audio-recording-using-StereoAudioRecorder.html
│       │   ├── audio-recording.html
│       │   ├── canvas-recording.html
│       │   ├── video-recording-using-WhammyRecorder.html
│       │   └── video-recording.html
│       ├── video-recording-using-WhammyRecorder.js
│       └── video-recording.js
├── Reliable-Signaler/
│   ├── README.md
│   ├── datachannel-client/
│   │   ├── README.md
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── server.js
│   │   └── style.css
│   ├── index.js
│   ├── package.json
│   ├── reliable-signaler.js
│   ├── rtcmulticonnection-client/
│   │   ├── README.md
│   │   ├── index.html
│   │   ├── package.json
│   │   ├── server.js
│   │   └── style.css
│   ├── signaler.js
│   └── videoconferencing-client/
│       ├── README.md
│       ├── RTCPeerConnection-v1.5.js
│       ├── conference.js
│       ├── index.html
│       ├── package.json
│       ├── server.js
│       └── style.css
├── Signaling.md
├── Translator.js/
│   ├── README.md
│   ├── Robot-Speaker.js
│   ├── Translator.js
│   └── index.html
├── WebRTC-File-Sharing/
│   ├── File.js
│   ├── PeerConnection.js
│   ├── README.md
│   └── index.html
├── WebRTC-Scalable-Broadcast/
│   ├── .gitignore
│   ├── .npmignore
│   ├── README.md
│   ├── RTCMultiConnection.js
│   ├── WebRTC-Scalable-Broadcast.js
│   ├── index.html
│   ├── package.json
│   ├── server.js
│   └── share-files.html
├── audio-broadcast/
│   ├── README.md
│   ├── broadcast-ui.js
│   ├── broadcast.js
│   └── index.html
├── broadcast/
│   ├── README.md
│   ├── broadcast-ui.js
│   ├── broadcast.js
│   └── index.html
├── chat-hangout/
│   ├── README.md
│   ├── hangout-ui.js
│   ├── hangout.js
│   └── index.html
├── demos/
│   ├── MediaStreamTrack.getSources.html
│   ├── README.md
│   ├── audio-only-streaming.html
│   ├── client-side-datachannel.html
│   ├── client-side-socket-io.html
│   ├── client-side-websocket.html
│   ├── client-side.html
│   ├── remote-stream-recording.html
│   ├── screen-and-video-from-single-peer.html
│   └── switch-streams.html
├── desktop-sharing/
│   ├── README.md
│   ├── index.html
│   └── old.html
├── docs/
│   ├── How-to-Broadcast-Screen-using-WebRTC.html
│   ├── README.md
│   ├── RTP-usage.html
│   ├── STUN-or-TURN.html
│   ├── Share-Files-using-Filejs.html
│   ├── TURN-server-installation-guide.html
│   ├── WebRTC-PeerConnection.html
│   ├── WebRTC-Signaling-Concepts.html
│   ├── echo-cancellation.html
│   ├── how-file-broadcast-works.html
│   ├── how-to-WebRTC-video-conferencing.html
│   ├── how-to-broadcast-video-using-RTCWeb-APIs.html
│   ├── how-to-install-tabCapture-extension.html
│   ├── how-to-share-audio-only-streams.html
│   ├── how-to-switch-streams.html
│   ├── how-to-use-plugin-free-calls.html
│   ├── how-to-use-rtcdatachannel-and-rtcpeerconnectionjs.html
│   ├── how-to-use-rtcdatachannel.html
│   ├── how-to-use-rtcpeerconnection-js-v1.1.html
│   ├── rtc-datachannel-for-beginners.html
│   ├── webrtc-for-beginners.html
│   ├── webrtc-for-newbies.html
│   └── webrtcpedia/
│       └── index.html
├── experimental/
│   ├── README.md
│   ├── mozCaptureStreamUntilEnded/
│   │   ├── README.md
│   │   └── index.html
│   ├── remote-media-stream-attachment/
│   │   ├── README.md
│   │   └── index.html
│   └── remote-stream-recording.html
├── ffmpeg/
│   ├── LICENSE
│   ├── README.md
│   ├── audio-plus-canvas-recording.html
│   ├── audio-plus-screen-recording.html
│   ├── index.html
│   ├── merging-wav-and-webm-into-mp4.html
│   ├── server.js
│   ├── video-cropping.html
│   ├── wav-to-aac.html
│   ├── wav-to-ogg.html
│   ├── webm-to-mp4.html
│   └── worker-asm.js
├── file-hangout/
│   ├── README.md
│   ├── file-hangout.js
│   └── index.html
├── file-sharing/
│   ├── README.md
│   ├── data-connection.js
│   └── index.html
├── getDisplayMedia/
│   ├── README.md
│   └── index.html
├── getMediaElement/
│   ├── .npmignore
│   ├── README.md
│   ├── getAudioElement.html
│   ├── getMediaElement-v1.2/
│   │   ├── getMediaElement-v1.2.css
│   │   └── getMediaElement-v1.2.js
│   ├── getMediaElement.css
│   ├── getMediaElement.js
│   ├── getVideoElement.html
│   ├── index.html
│   └── package.json
├── getScreenId.js/
│   ├── .npmignore
│   ├── LICENSE
│   ├── README.md
│   ├── Screen-Capturing.js
│   ├── getScreenId.html
│   ├── getScreenId.js
│   ├── index.html
│   ├── package.json
│   └── server.js
├── getStats/
│   ├── .gitignore
│   ├── .npmignore
│   ├── .travis.yml
│   ├── Gruntfile.js
│   ├── LICENSE.md
│   ├── README.md
│   ├── bower.json
│   ├── dev/
│   │   ├── README.md
│   │   ├── bweforvideo.js
│   │   ├── candidate-pair.js
│   │   ├── dataSentReceived.js
│   │   ├── datachannel.js
│   │   ├── getStats.js
│   │   ├── globals.js
│   │   ├── googCertificate.js
│   │   ├── googCodecName.audio.js
│   │   ├── googCodecName.video.js
│   │   ├── head.js
│   │   ├── inbound-rtp.js
│   │   ├── local-candidate.js
│   │   ├── module.exports.js
│   │   ├── outbound-rtp.js
│   │   ├── parameters.js
│   │   ├── remote-candidate.js
│   │   ├── ssrc.js
│   │   ├── tail.js
│   │   ├── track.js
│   │   └── wrapper.js
│   ├── getStats.js
│   ├── index.html
│   ├── package.json
│   └── server.js
├── gumadapter/
│   ├── README.md
│   ├── gumadapter.js
│   └── package.json
├── hark/
│   ├── README.md
│   └── hark.js
├── meeting/
│   ├── README.md
│   ├── index.html
│   ├── meeting.js
│   └── simple.html
├── navigator.customGetUserMediaBar/
│   ├── README.md
│   ├── index.html
│   └── navigator.customGetUserMediaBar.js
├── one-to-many-audio-broadcasting/
│   ├── README.md
│   ├── index.html
│   └── meeting.js
├── one-to-many-video-broadcasting/
│   ├── README.md
│   ├── index.html
│   └── meeting.js
├── part-of-screen-sharing/
│   ├── README.md
│   ├── firebase/
│   │   └── index.html
│   ├── iframe/
│   │   ├── index.html
│   │   └── otherpage.html
│   ├── realtime-chat/
│   │   ├── No-WebRTC-Chat.html
│   │   ├── README.md
│   │   └── how-this-work.html
│   ├── screenshot-dev.js
│   ├── screenshot.js
│   └── webrtc-data-channel/
│       └── index.html
├── realtime-pluginfree-calls/
│   ├── README.md
│   ├── index.html
│   ├── js/
│   │   ├── PeerConnection.js
│   │   ├── linkify.js
│   │   └── script.js
│   ├── old/
│   │   ├── README.md
│   │   ├── call-initiator.js
│   │   ├── index.html
│   │   └── ui.js
│   ├── old2/
│   │   └── index.html
│   └── style.css
├── screen-broadcast/
│   ├── README.md
│   └── index.html
├── screen-sharing/
│   ├── README.md
│   ├── index.html
│   └── screen.js
├── server.js
├── socket.io/
│   ├── PeerConnection.js
│   ├── README.md
│   └── index.html
├── socketio-over-nodejs/
│   ├── README.md
│   ├── fake-keys/
│   │   ├── certificate.pem
│   │   └── privatekey.pem
│   ├── package.json
│   └── server.js
├── text-chat/
│   ├── README.md
│   ├── data-connection.js
│   └── index.html
├── video-conferencing/
│   ├── README.md
│   ├── conference.js
│   ├── index.html
│   └── server.js
├── webrtc-broadcasting/
│   ├── README.md
│   ├── broadcast.js
│   ├── index.html
│   └── server.js
├── websocket/
│   ├── PeerConnection.js
│   ├── README.md
│   └── index.html
└── websocket-over-nodejs/
    ├── README.md
    ├── fake-keys/
    │   ├── certificate.pem
    │   └── privatekey.pem
    ├── package.json
    └── server.js
Download .txt
Showing preview only (262K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (2982 symbols across 326 files)

FILE: Canvas-Designer/canvas-designer-widget.js
  function CanvasDesigner (line 11) | function CanvasDesigner() {

FILE: Canvas-Designer/dev/common.js
  function addEvent (line 25) | function addEvent(element, eventType, callback) {
  function find (line 45) | function find(selector) {
  function getContext (line 60) | function getContext(id) {
  function drawArrow (line 499) | function drawArrow(mx, my, lx, ly, options) {
  function endLastPath (line 555) | function endLastPath() {
  function copy (line 574) | function copy() {
  function paste (line 588) | function paste() {
  function hexToR (line 613) | function hexToR(h) {
  function hexToG (line 617) | function hexToG(h) {
  function hexToB (line 621) | function hexToB(h) {
  function cutHex (line 625) | function cutHex(h) {
  function clone (line 629) | function clone(obj) {
  function hexToRGB (line 649) | function hexToRGB(h) {

FILE: Canvas-Designer/dev/decorator.js
  function setSelection (line 35) | function setSelection(element, prop) {
  function setDefaultSelectedIcon (line 54) | function setDefaultSelectedIcon() {
  function getContext (line 83) | function getContext(id) {
  function bindEvent (line 90) | function bindEvent(context, shape) {
  function decorateDragLastPath (line 196) | function decorateDragLastPath() {
  function decorateDragAllPaths (line 213) | function decorateDragAllPaths() {
  function decorateLine (line 230) | function decorateLine() {
  function decorateUndo (line 246) | function decorateUndo() {
  function decorateArrow (line 271) | function decorateArrow() {
  function decoreZoomUp (line 287) | function decoreZoomUp() {
  function decoreZoomDown (line 301) | function decoreZoomDown() {
  function decoratePencil (line 323) | function decoratePencil() {
  function decorateMarker (line 426) | function decorateMarker() {
  function decorateEraser (line 528) | function decorateEraser() {
  function decorateText (line 544) | function decorateText() {
  function decorateImage (line 560) | function decorateImage() {
  function decoratePDF (line 577) | function decoratePDF() {
  function decorateArc (line 593) | function decorateArc() {
  function decorateRect (line 609) | function decorateRect() {
  function decorateQuadratic (line 625) | function decorateQuadratic() {
  function decorateBezier (line 641) | function decorateBezier() {
  function tempStrokeTheLine (line 657) | function tempStrokeTheLine(context, width, mx, my, lx, ly) {
  function decorateLineWidth (line 665) | function decorateLineWidth() {
  function decorateColors (line 701) | function decorateColors() {
  function decorateAdditionalOptions (line 739) | function decorateAdditionalOptions() {
  function btnDesignerPreviewClicked (line 805) | function btnDesignerPreviewClicked() {
  function btnCodePreviewClicked (line 818) | function btnCodePreviewClicked() {
  function setHeightForCodeAndOptionsContainer (line 834) | function setHeightForCodeAndOptionsContainer() {
  function hideContainers (line 849) | function hideContainers() {
  function setTemporaryLine (line 867) | function setTemporaryLine() {

FILE: Canvas-Designer/dev/events-handler.js
  function preventStopEvent (line 31) | function preventStopEvent(e) {
  function onkeydown (line 109) | function onkeydown(e) {
  function isBackKey (line 129) | function isBackKey(e, keyCode) {
  function onkeyup (line 156) | function onkeyup(e) {
  function onkeypress (line 225) | function onkeypress(e) {
  function onTextFromClipboard (line 240) | function onTextFromClipboard(e) {

FILE: Canvas-Designer/dev/file-selector.js
  function selectFile (line 9) | function selectFile(callback, multiple, accept) {
  function fireClickEvent (line 43) | function fireClickEvent(element) {

FILE: Canvas-Designer/dev/share-drawings.js
  function syncPoints (line 153) | function syncPoints(isSyncAll) {
  function syncData (line 177) | function syncData(data) {

FILE: Canvas-Designer/server.js
  function responseError (line 7) | function responseError(response, code, msg) {
  function serverHandler (line 15) | function serverHandler(request, response) {

FILE: Canvas-Designer/widget.js
  function addEvent (line 36) | function addEvent(element, eventType, callback) {
  function find (line 56) | function find(selector) {
  function getContext (line 71) | function getContext(id) {
  function drawArrow (line 510) | function drawArrow(mx, my, lx, ly, options) {
  function endLastPath (line 566) | function endLastPath() {
  function copy (line 585) | function copy() {
  function paste (line 599) | function paste() {
  function hexToR (line 624) | function hexToR(h) {
  function hexToG (line 628) | function hexToG(h) {
  function hexToB (line 632) | function hexToB(h) {
  function cutHex (line 636) | function cutHex(h) {
  function clone (line 640) | function clone(obj) {
  function hexToRGB (line 660) | function hexToRGB(h) {
  function selectFile (line 2534) | function selectFile(callback, multiple, accept) {
  function fireClickEvent (line 2568) | function fireClickEvent(element) {
  function setSelection (line 2884) | function setSelection(element, prop) {
  function setDefaultSelectedIcon (line 2903) | function setDefaultSelectedIcon() {
  function getContext (line 2932) | function getContext(id) {
  function bindEvent (line 2939) | function bindEvent(context, shape) {
  function decorateDragLastPath (line 3045) | function decorateDragLastPath() {
  function decorateDragAllPaths (line 3062) | function decorateDragAllPaths() {
  function decorateLine (line 3079) | function decorateLine() {
  function decorateUndo (line 3095) | function decorateUndo() {
  function decorateArrow (line 3120) | function decorateArrow() {
  function decoreZoomUp (line 3136) | function decoreZoomUp() {
  function decoreZoomDown (line 3150) | function decoreZoomDown() {
  function decoratePencil (line 3172) | function decoratePencil() {
  function decorateMarker (line 3275) | function decorateMarker() {
  function decorateEraser (line 3377) | function decorateEraser() {
  function decorateText (line 3393) | function decorateText() {
  function decorateImage (line 3409) | function decorateImage() {
  function decoratePDF (line 3426) | function decoratePDF() {
  function decorateArc (line 3442) | function decorateArc() {
  function decorateRect (line 3458) | function decorateRect() {
  function decorateQuadratic (line 3474) | function decorateQuadratic() {
  function decorateBezier (line 3490) | function decorateBezier() {
  function tempStrokeTheLine (line 3506) | function tempStrokeTheLine(context, width, mx, my, lx, ly) {
  function decorateLineWidth (line 3514) | function decorateLineWidth() {
  function decorateColors (line 3550) | function decorateColors() {
  function decorateAdditionalOptions (line 3588) | function decorateAdditionalOptions() {
  function btnDesignerPreviewClicked (line 3654) | function btnDesignerPreviewClicked() {
  function btnCodePreviewClicked (line 3667) | function btnCodePreviewClicked() {
  function setHeightForCodeAndOptionsContainer (line 3683) | function setHeightForCodeAndOptionsContainer() {
  function hideContainers (line 3698) | function hideContainers() {
  function setTemporaryLine (line 3716) | function setTemporaryLine() {
  function preventStopEvent (line 3760) | function preventStopEvent(e) {
  function onkeydown (line 3838) | function onkeydown(e) {
  function isBackKey (line 3858) | function isBackKey(e, keyCode) {
  function onkeyup (line 3885) | function onkeyup(e) {
  function onkeypress (line 3954) | function onkeypress(e) {
  function onTextFromClipboard (line 3969) | function onTextFromClipboard(e) {
  function syncPoints (line 4134) | function syncPoints(isSyncAll) {
  function syncData (line 4158) | function syncData(data) {

FILE: Chrome-Extensions/Screen-Capturing.js/Screen-Capturing.js
  function onMessageCallback (line 40) | function onMessageCallback(data) {
  function isChromeExtensionAvailable (line 65) | function isChromeExtensionAvailable(callback) {
  function getSourceId (line 81) | function getSourceId(callback) {
  function getCustomSourceId (line 90) | function getCustomSourceId(arr, callback) {
  function getSourceIdWithAudio (line 103) | function getSourceIdWithAudio(callback) {
  function getChromeExtensionStatus (line 115) | function getChromeExtensionStatus(extensionid, callback) {
  function getScreenConstraintsWithAudio (line 139) | function getScreenConstraintsWithAudio(callback) {
  function getScreenConstraints (line 144) | function getScreenConstraints(callback, captureSourceIdWithAudio) {

FILE: Chrome-Extensions/Screen-Capturing.js/server.js
  function serverHandler (line 12) | function serverHandler(request, response) {
  function runServer (line 73) | function runServer() {

FILE: Chrome-Extensions/desktopCapture-p2p/background/captureCamera.js
  function captureCamera (line 1) | function captureCamera(callback) {

FILE: Chrome-Extensions/desktopCapture-p2p/background/captureDesktop.js
  function captureDesktop (line 1) | function captureDesktop() {

FILE: Chrome-Extensions/desktopCapture-p2p/background/captureTabUsingTabCapture.js
  function captureTabUsingTabCapture (line 1) | function captureTabUsingTabCapture(resolutions) {

FILE: Chrome-Extensions/desktopCapture-p2p/background/common.js
  function getAspectRatio (line 1) | function getAspectRatio(w, h) {
  function openVideoPreview (line 9) | function openVideoPreview(stream) {
  function initVideoPlayer (line 23) | function initVideoPlayer(stream) {
  function addStreamStopListener (line 32) | function addStreamStopListener(stream, callback) {
  function getUserMediaError (line 55) | function getUserMediaError(e) {
  function setBadgeText (line 66) | function setBadgeText(text) {

FILE: Chrome-Extensions/desktopCapture-p2p/background/gotStream.js
  function gotStream (line 1) | function gotStream(stream) {

FILE: Chrome-Extensions/desktopCapture-p2p/background/gotTabCaptureStream.js
  function gotTabCaptureStream (line 1) | function gotTabCaptureStream(stream, constraints) {

FILE: Chrome-Extensions/desktopCapture-p2p/background/helpers/AntMediaWrapper.js
  function AntMediaWrapper (line 1) | function AntMediaWrapper() {
  function webrtcHandler (line 234) | function webrtcHandler() {
  function getIceServers (line 368) | function getIceServers(connection) {

FILE: Chrome-Extensions/desktopCapture-p2p/background/helpers/CodecsHandler.js
  function preferCodec (line 4) | function preferCodec(sdp, codecName) {
  function preferCodecHelper (line 28) | function preferCodecHelper(sdp, codec, info, ignore) {
  function splitLines (line 72) | function splitLines(sdp) {
  function removeVPX (line 101) | function removeVPX(sdp) {
  function disableNACK (line 111) | function disableNACK(sdp) {
  function prioritize (line 124) | function prioritize(codecMimeType, peer) {
  function removeNonG722 (line 145) | function removeNonG722(sdp) {
  function setBAS (line 149) | function setBAS(sdp, bandwidth, isScreen) {
  function findLine (line 192) | function findLine(sdpLines, prefix, substr) {
  function findLineInRange (line 198) | function findLineInRange(sdpLines, startLine, endLine, prefix, substr) {
  function getCodecPayloadType (line 212) | function getCodecPayloadType(sdpLine) {
  function setVideoBitrates (line 218) | function setVideoBitrates(sdp, params) {
  function setOpusAttributes (line 257) | function setOpusAttributes(sdp, params) {
  function forceStereoAudio (line 314) | function forceStereoAudio(sdp) {

FILE: Chrome-Extensions/desktopCapture-p2p/background/helpers/IceServersHandler.js
  function getIceServers (line 4) | function getIceServers(connection) {

FILE: Chrome-Extensions/desktopCapture-p2p/background/helpers/MultiStreamsMixer.js
  function MultiStreamsMixer (line 13) | function MultiStreamsMixer(arrayOfMediaStreams) {

FILE: Chrome-Extensions/desktopCapture-p2p/background/helpers/adapter.js
  function s (line 22) | function s(o, u) {
  function writeMediaSection (line 58) | function writeMediaSection(transceiver, caps, type, stream, dtlsRole) {
  function filterIceServers (line 119) | function filterIceServers(iceServers, edgeVersion) {
  function getCommonCapabilities (line 154) | function getCommonCapabilities(localCapabilities, remoteCapabilities) {
  function isActionAllowedInSignalingState (line 231) | function isActionAllowedInSignalingState(action, type, signalingState) {
  function maybeAddCandidate (line 244) | function maybeAddCandidate(iceTransport, candidate) {
  function makeError (line 263) | function makeError(name, description) {
  function addTrackToStreamAndFireEvent (line 281) | function addTrackToStreamAndFireEvent(track, stream) {
  function removeTrackFromStreamAndFireEvent (line 288) | function removeTrackFromStreamAndFireEvent(track, stream) {
  function fireAddTrack (line 295) | function fireAddTrack(pc, track, receiver, streams) {
  method dtmf (line 2816) | get dtmf() {
  function replaceInternalStreamId (line 3146) | function replaceInternalStreamId(pc, description) {
  function replaceExternalStreamId (line 3160) | function replaceExternalStreamId(pc, description) {
  function extractVersion (line 4950) | function extractVersion(uastring, expr, pos) {
  function wrapPeerConnectionEvent (line 4957) | function wrapPeerConnectionEvent(window, eventNameToWrap, wrapper) {

FILE: Chrome-Extensions/desktopCapture-p2p/background/helpers/getStats.js
  function getStatsLooper (line 140) | function getStatsLooper() {
  function getStatsWrapper (line 190) | function getStatsWrapper(cb) {

FILE: Chrome-Extensions/desktopCapture-p2p/background/helpers/socket.io.js
  function e (line 6) | function e(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,lo...
  function r (line 6) | function r(t,e){"object"===("undefined"==typeof t?"undefined":o(t))&&(e=...
  function r (line 6) | function r(t,n){var r=t;n=n||e.location,null==t&&(t=n.protocol+"//"+n.ho...
  function o (line 6) | function o(){return!("undefined"==typeof window||!window.process||"rende...
  function i (line 6) | function i(t){var n=this.useColors;if(t[0]=(n?"%c":"")+this.namespace+(n...
  function s (line 6) | function s(){return"object"==typeof console&&console.log&&Function.proto...
  function a (line 6) | function a(t){try{null==t?e.storage.removeItem("debug"):e.storage.debug=...
  function c (line 6) | function c(){var t;try{t=e.storage.debug}catch(n){}return!t&&"undefined"...
  function u (line 6) | function u(){try{return window.localStorage}catch(t){}}
  function n (line 6) | function n(){throw new Error("setTimeout has not been defined")}
  function r (line 6) | function r(){throw new Error("clearTimeout has not been defined")}
  function o (line 6) | function o(t){if(p===setTimeout)return setTimeout(t,0);if((p===n||!p)&&s...
  function i (line 6) | function i(t){if(h===clearTimeout)return clearTimeout(t);if((h===r||!h)&...
  function s (line 6) | function s(){y&&l&&(y=!1,l.length?d=l.concat(d):m=-1,d.length&&a())}
  function a (line 6) | function a(){if(!y){var t=o(s);y=!0;for(var e=d.length;e;){for(l=d,d=[];...
  function c (line 6) | function c(t,e){this.fun=t,this.array=e}
  function u (line 6) | function u(){}
  function r (line 6) | function r(t){var n,r=0;for(n in t)r=(r<<5)-r+t.charCodeAt(n),r|=0;retur...
  function o (line 6) | function o(t){function n(){if(n.enabled){var t=n,r=+new Date,i=r-(o||r);...
  function i (line 6) | function i(){var t=e.instances.indexOf(this);return t!==-1&&(e.instances...
  function s (line 6) | function s(t){e.save(t),e.names=[],e.skips=[];var n,r=("string"==typeof ...
  function a (line 6) | function a(){e.enable("")}
  function c (line 6) | function c(t){if("*"===t[t.length-1])return!0;var n,r;for(n=0,r=e.skips....
  function u (line 6) | function u(t){return t instanceof Error?t.stack||t.message:t}
  function n (line 6) | function n(t){if(t=String(t),!(t.length>100)){var e=/^((?:\d+)?\.?\d+) *...
  function r (line 6) | function r(t){return t>=u?Math.round(t/u)+"d":t>=c?Math.round(t/c)+"h":t...
  function o (line 6) | function o(t){return i(t,u,"day")||i(t,c,"hour")||i(t,a,"minute")||i(t,s...
  function i (line 6) | function i(t,e,n){if(!(t<e))return t<1.5*e?Math.floor(t/e)+" "+n:Math.ce...
  function r (line 6) | function r(){}
  function o (line 6) | function o(t){var n=""+t.type;if(e.BINARY_EVENT!==t.type&&e.BINARY_ACK!=...
  function i (line 6) | function i(t){try{return JSON.stringify(t)}catch(e){return!1}}
  function s (line 6) | function s(t,e){function n(t){var n=d.deconstructPacket(t),r=o(n.packet)...
  function a (line 6) | function a(){this.reconstructor=null}
  function c (line 6) | function c(t){var n=0,r={type:Number(t.charAt(0))};if(null==e.types[r.ty...
  function u (line 6) | function u(t){try{return JSON.parse(t)}catch(e){return!1}}
  function p (line 6) | function p(t){this.reconPack=t,this.buffers=[]}
  function h (line 6) | function h(t){return{type:e.ERROR,data:"parser error: "+t}}
  function r (line 6) | function r(t){if(t)return o(t)}
  function o (line 6) | function o(t){for(var e in r.prototype)t[e]=r.prototype[e];return t}
  function n (line 6) | function n(){this.off(t,n),e.apply(this,arguments)}
  function r (line 6) | function r(t,e){if(!t)return t;if(s(t)){var n={_placeholder:!0,num:e.len...
  function o (line 6) | function o(t,e){if(!t)return t;if(t&&t._placeholder)return e[t.num];if(i...
  function n (line 6) | function n(t,a,p){if(!t)return t;if(c&&t instanceof Blob||u&&t instanceo...
  function n (line 6) | function n(t){return r&&e.Buffer.isBuffer(t)||o&&(t instanceof e.ArrayBu...
  function r (line 6) | function r(t,e){if(!(this instanceof r))return new r(t,e);t&&"object"===...
  function n (line 6) | function n(){~f(o.connecting,r)||o.connecting.push(r)}
  function r (line 6) | function r(t,n){if(!(this instanceof r))return new r(t,n);n=n||{},t&&"ob...
  function o (line 6) | function o(t){var e={};for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);r...
  function e (line 6) | function e(){if(f.onlyBinaryUpgrades){var e=!this.supportsBinary&&f.tran...
  function n (line 6) | function n(){h||(h=!0,u(),p.close(),p=null)}
  function o (line 6) | function o(e){var r=new Error("probe error: "+e);r.transport=p.name,n(),...
  function i (line 6) | function i(){o("transport closed")}
  function s (line 6) | function s(){o("socket closed")}
  function c (line 6) | function c(t){p&&t.name!==p.name&&(a('"%s" works - aborting "%s"',t.name...
  function u (line 6) | function u(){p.removeListener("open",e),p.removeListener("error",o),p.re...
  function t (line 6) | function t(){r.onClose("forced close"),a("socket closing - telling trans...
  function e (line 6) | function e(){r.removeListener("upgrade",e),r.removeListener("upgradeErro...
  function n (line 6) | function n(){r.once("upgrade",e),r.once("upgradeError",e)}
  function r (line 6) | function r(e){var n,r=!1,a=!1,c=!1!==e.jsonp;if(t.location){var u="https...
  function r (line 7) | function r(){}
  function o (line 7) | function o(t){if(c.call(this,t),this.requestTimeout=t.requestTimeout,thi...
  function i (line 7) | function i(t){this.method=t.method||"GET",this.uri=t.uri,this.xd=!!t.xd,...
  function s (line 7) | function s(){for(var t in i.requests)i.requests.hasOwnProperty(t)&&i.req...
  function r (line 7) | function r(t){var e=t&&t.forceBase64;p&&!e||(this.supportsBinary=!1),o.c...
  function e (line 7) | function e(){u("paused"),n.readyState="paused",t()}
  function t (line 7) | function t(){u("writing close packet"),e.write([{type:"close"}])}
  function r (line 7) | function r(t){this.path=t.path,this.hostname=t.hostname,this.port=t.port...
  function r (line 7) | function r(t,n){var r="b"+e.packets[t.type]+t.data.data;return n(r)}
  function o (line 7) | function o(t,n,r){if(!n)return e.encodeBase64Packet(t,r);var o=t.data,i=...
  function i (line 7) | function i(t,n,r){if(!n)return e.encodeBase64Packet(t,r);var o=new FileR...
  function s (line 7) | function s(t,n,r){if(!n)return e.encodeBase64Packet(t,r);if(g)return i(t...
  function a (line 7) | function a(t){try{t=d.decode(t,{strict:!1})}catch(e){return!1}return t}
  function c (line 7) | function c(t,e,n){for(var r=new Array(t.length),o=l(t.length,n),i=functi...
  function o (line 7) | function o(t){return t.length+":"+t}
  function i (line 7) | function i(t,r){e.encodePacket(t,!!s&&n,!1,function(t){r(null,o(t))})}
  function r (line 7) | function r(t,n){e.encodePacket(t,!0,!0,function(t){return n(null,t)})}
  function r (line 7) | function r(t,n){e.encodePacket(t,!0,!0,function(t){var e=new Uint8Array(...
  function r (line 7) | function r(t){if(!t||"object"!=typeof t)return!1;if(o(t)){for(var n=0,i=...
  function n (line 7) | function n(t,e,n){function o(t,r){if(o.count<=0)throw new Error("after c...
  function r (line 7) | function r(){}
  function s (line 7) | function s(t){for(var e,n,r=[],o=0,i=t.length;o<i;)e=t.charCodeAt(o++),e...
  function a (line 7) | function a(t){for(var e,n=t.length,r=-1,o="";++r<n;)e=t[r],e>65535&&(e-=...
  function c (line 7) | function c(t,e){if(t>=55296&&t<=57343){if(e)throw Error("Lone surrogate ...
  function u (line 7) | function u(t,e){return w(t>>e&63|128)}
  function p (line 7) | function p(t,e){if(0==(4294967168&t))return w(t);var n="";return 0==(429...
  function h (line 7) | function h(t,e){e=e||{};for(var n,r=!1!==e.strict,o=s(t),i=o.length,a=-1...
  function f (line 7) | function f(){if(b>=v)throw Error("Invalid byte index");var t=255&g[b];if...
  function l (line 7) | function l(t){var e,n,r,o,i;if(b>v)throw Error("Invalid byte index");if(...
  function d (line 7) | function d(t,e){e=e||{};var n=!1!==e.strict;g=s(t),v=g.length,b=0;for(va...
  function n (line 7) | function n(t){for(var e=0;e<t.length;e++){var n=t[e];if(n.buffer instanc...
  function r (line 7) | function r(t,e){e=e||{};var r=new i;n(t);for(var o=0;o<t.length;o++)r.ap...
  function o (line 7) | function o(t,e){return n(t),new Blob(t,e||{})}
  function n (line 7) | function n(t){var e="";do e=s[t%a]+e,t=Math.floor(t/a);while(t>0);return e}
  function r (line 7) | function r(t){var e=0;for(p=0;p<t.length;p++)e=e*a+c[t.charAt(p)];return e}
  function o (line 7) | function o(){var t=n(+new Date);return t!==i?(u=0,i=t):t+"."+n(u++)}
  function r (line 7) | function r(){}
  function o (line 7) | function o(t){i.call(this,t),this.query=this.query||{},a||(e.___eio||(e....
  function n (line 7) | function n(){r(),e()}
  function r (line 7) | function r(){if(o.iframe)try{o.form.removeChild(o.iframe)}catch(t){o.onE...
  function r (line 7) | function r(t){var e=t&&t.forceBase64;e&&(this.supportsBinary=!1),this.pe...
  function n (line 7) | function n(){r.emit("flush"),setTimeout(function(){r.writable=!0,r.emit(...
  function r (line 7) | function r(t,e,n){this.io=t,this.nsp=e,this.json=this,this.ids=0,this.ac...
  function n (line 7) | function n(t,e){var n=[];e=e||0;for(var r=e||0;r<t.length;r++)n[r-e]=t[r...
  function n (line 7) | function n(t,e,n){return t.on(e,n),{destroy:function(){t.removeListener(...
  function n (line 7) | function n(t){t=t||{},this.ms=t.min||100,this.max=t.max||1e4,this.factor...

FILE: Chrome-Extensions/desktopCapture-p2p/background/onAccessApproved.js
  function onAccessApproved (line 1) | function onAccessApproved(chromeMediaSourceId, opts) {

FILE: Chrome-Extensions/desktopCapture-p2p/background/setDefaults.js
  function setDefaults (line 1) | function setDefaults() {

FILE: Chrome-Extensions/desktopCapture-p2p/background/setupWebRTCConnection.js
  function setupWebRTCConnection (line 1) | function setupWebRTCConnection(stream) {

FILE: Chrome-Extensions/desktopCapture-p2p/background/shareStreamUsingAntMediaServer.js
  function shareStreamUsingAntMediaServer (line 1) | function shareStreamUsingAntMediaServer(stream) {

FILE: Chrome-Extensions/desktopCapture-p2p/background/shareStreamUsingRTCMultiConnection.js
  function shareStreamUsingRTCMultiConnection (line 1) | function shareStreamUsingRTCMultiConnection(stream) {

FILE: Chrome-Extensions/desktopCapture-p2p/extension-pages/chat.js
  function appendChatMessage (line 19) | function appendChatMessage(name, message, checkmark_id) {

FILE: Chrome-Extensions/desktopCapture-p2p/extension-pages/dropdown.js
  function querySelectorAll (line 152) | function querySelectorAll(selector, element) {

FILE: Chrome-Extensions/desktopCapture-p2p/extension-pages/options.js
  function querySelectorAll (line 1) | function querySelectorAll(selector, element) {
  function setCustomSelectElements (line 107) | function setCustomSelectElements() {

FILE: Chrome-Extensions/desktopCapture-p2p/server.js
  function serverHandler (line 9) | function serverHandler(request, response) {

FILE: Chrome-Extensions/desktopCapture/background-script.js
  function portOnMessageHanlder (line 10) | function portOnMessageHanlder(message) {
  function onAccessApproved (line 31) | function onAccessApproved(sourceId, opts) {

FILE: Chrome-Extensions/desktopCapture/different-api/background-script.js
  function onAccessApproved (line 30) | function onAccessApproved(sourceId) {

FILE: Chrome-Extensions/file-sharing/background.js
  function portOnMessageHanlder (line 8) | function portOnMessageHanlder(message) {
  function setBadgeText (line 37) | function setBadgeText(percentage, color) {

FILE: Chrome-Extensions/file-sharing/popup.js
  function s (line 4) | function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"funct...
  function fa (line 4) | function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.node...
  function ga (line 4) | function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLengt...
  function ha (line 4) | function ha(a){return a[u]=!0,a}
  function ia (line 4) | function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){re...
  function ja (line 4) | function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[...
  function ka (line 4) | function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sou...
  function la (line 4) | function la(a){return function(b){var c=b.nodeName.toLowerCase();return"...
  function ma (line 4) | function ma(a){return function(b){var c=b.nodeName.toLowerCase();return(...
  function na (line 4) | function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,...
  function oa (line 4) | function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}
  function pa (line 4) | function pa(){}
  function qa (line 4) | function qa(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}
  function ra (line 4) | function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.firs...
  function sa (line 4) | function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e-...
  function ta (line 4) | function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}
  function ua (line 4) | function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(...
  function va (line 4) | function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)...
  function wa (line 4) | function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.r...
  function xa (line 4) | function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var...
  function z (line 4) | function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){retur...
  function F (line 4) | function F(a,b){while((a=a[b])&&1!==a.nodeType);return a}
  function H (line 4) | function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!...
  function J (line 4) | function J(){d.removeEventListener("DOMContentLoaded",J),a.removeEventLi...
  function M (line 4) | function M(){this.expando=n.expando+M.uid++}
  function R (line 4) | function R(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.rep...
  function W (line 5) | function W(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:functi...
  function _ (line 5) | function _(a,b){var c="undefined"!=typeof a.getElementsByTagName?a.getEl...
  function aa (line 5) | function aa(a,b){for(var c=0,d=a.length;d>c;c++)N.set(a[c],"globalEval",...
  function ca (line 5) | function ca(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),...
  function ga (line 5) | function ga(){return!0}
  function ha (line 5) | function ha(){return!1}
  function ia (line 5) | function ia(){try{return d.activeElement}catch(a){}}
  function ja (line 5) | function ja(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof...
  function pa (line 5) | function pa(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeTyp...
  function qa (line 5) | function qa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}
  function ra (line 5) | function ra(a){var b=na.exec(a.type);return b?a.type=b[1]:a.removeAttrib...
  function sa (line 5) | function sa(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(N.hasData(a)&...
  function ta (line 5) | function ta(a,b){var c=b.nodeName.toLowerCase();"input"===c&&X.test(a.ty...
  function ua (line 5) | function ua(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-...
  function va (line 5) | function va(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)...
  function ya (line 5) | function ya(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[...
  function za (line 5) | function za(a){var b=d,c=xa[a];return c||(c=ya(a,b),"none"!==c&&c||(wa=(...
  function i (line 5) | function i(){h.style.cssText="-webkit-box-sizing:border-box;-moz-box-siz...
  function Fa (line 5) | function Fa(a,b,c){var d,e,f,g,h=a.style;return c=c||Ca(a),g=c?c.getProp...
  function Ga (line 5) | function Ga(a,b){return{get:function(){return a()?void delete this.get:(...
  function Ma (line 5) | function Ma(a){if(a in La)return a;var b=a[0].toUpperCase()+a.slice(1),c...
  function Na (line 5) | function Na(a,b,c){var d=T.exec(b);return d?Math.max(0,d[2]-(c||0))+(d[3...
  function Oa (line 5) | function Oa(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===...
  function Pa (line 5) | function Pa(b,c,e){var f=!0,g="width"===c?b.offsetWidth:b.offsetHeight,h...
  function Qa (line 5) | function Qa(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.styl...
  function Ra (line 5) | function Ra(a,b,c,d,e){return new Ra.prototype.init(a,b,c,d,e)}
  function Wa (line 5) | function Wa(){return a.setTimeout(function(){Sa=void 0}),Sa=n.now()}
  function Xa (line 5) | function Xa(a,b){var c,d=0,e={height:a};for(b=b?1:0;4>d;d+=2-b)c=U[d],e[...
  function Ya (line 5) | function Ya(a,b,c){for(var d,e=(_a.tweeners[b]||[]).concat(_a.tweeners["...
  function Za (line 5) | function Za(a,b,c){var d,e,f,g,h,i,j,k,l=this,m={},o=a.style,p=a.nodeTyp...
  function $a (line 5) | function $a(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a...
  function _a (line 5) | function _a(a,b,c){var d,e,f=0,g=_a.prefilters.length,h=n.Deferred().alw...
  function fb (line 6) | function fb(a){return a.getAttribute&&a.getAttribute("class")||""}
  function wb (line 6) | function wb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var ...
  function xb (line 6) | function xb(a,b,c,d){var e={},f=a===tb;function g(h){var i;return e[h]=!...
  function yb (line 6) | function yb(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(c in b)voi...
  function zb (line 6) | function zb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[...
  function Ab (line 6) | function Ab(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])fo...
  function z (line 6) | function z(b,c,d,h){var j,l,t,u,w,y=c;2!==v&&(v=2,i&&a.clearTimeout(i),e...
  function Gb (line 6) | function Gb(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||Cb....
  function Mb (line 6) | function Mb(a){return n.isWindow(a)?a:9===a.nodeType&&a.defaultView}
  function injectContentScript (line 9) | function injectContentScript(tabId) {
  function msgCallback (line 18) | function msgCallback(messages) {
  function handleMessage (line 26) | function handleMessage(message) {

FILE: Chrome-Extensions/file-sharing/rmc-files-handler.js
  function FileBufferReader (line 18) | function FileBufferReader(){function fbrClone(from,to){if(null==from||"o...
  function FileBufferReaderHelper (line 18) | function FileBufferReaderHelper(){function fileReaderWrapper(options,cal...
  function FileSelector (line 18) | function FileSelector(){function selectFile(callback,multiple){var file=...
  function FileBufferReceiver (line 18) | function FileBufferReceiver(fbr){function receive(chunk,callback){if(!ch...
  function merge (line 18) | function merge(mergein,mergeto){if(mergein||(mergein={}),!mergeto)return...
  function SocketConnection (line 23) | function SocketConnection(connection,connectCallback){function updateExt...
  function MultiPeers (line 23) | function MultiPeers(connection){function initFileBufferReader(){connecti...
  function fireEvent (line 23) | function fireEvent(obj,eventName,args){if("undefined"!=typeof CustomEven...
  function setHarkEvents (line 23) | function setHarkEvents(connection,streamEvent){if(streamEvent.stream&&st...
  function setMuteHandlers (line 23) | function setMuteHandlers(connection,streamEvent){streamEvent.stream&&str...
  function getRandomString (line 23) | function getRandomString(){if(window.crypto&&window.crypto.getRandomValu...
  function getRMCMediaElement (line 23) | function getRMCMediaElement(stream,callback,connection){if(!connection.a...
  function listenEventHandler (line 23) | function listenEventHandler(eventName,eventHandler){window.removeEventLi...
  function removeNullEntries (line 23) | function removeNullEntries(array){var newArray=[];return array.forEach(f...
  function isData (line 23) | function isData(session){return!session.audio&&!session.video&&!session....
  function isNull (line 23) | function isNull(obj){return"undefined"==typeof obj}
  function isString (line 23) | function isString(obj){return"string"==typeof obj}
  function isAudioPlusTab (line 23) | function isAudioPlusTab(connection,audioPlusTab){return(!connection.sess...
  function getAudioScreenConstraints (line 23) | function getAudioScreenConstraints(screen_constraints){return"Firefox"==...
  function setCordovaAPIs (line 23) | function setCordovaAPIs(){if("undefined"!=typeof cordova&&"undefined"!=t...
  function setSdpConstraints (line 23) | function setSdpConstraints(config){var sdpConstraints={OfferToReceiveAud...
  function PeerInitiator (line 23) | function PeerInitiator(config){function oldAddRemoteSdp(remoteSdp,cb){cb...
  function setStreamType (line 24) | function setStreamType(constraints,stream){constraints.mandatory&&constr...
  function getUserMediaHandler (line 24) | function getUserMediaHandler(options){function streaming(stream,returnBa...
  function onMessageCallback (line 24) | function onMessageCallback(data){if("PermissionDeniedError"==data){if(ch...
  function isChromeExtensionAvailable (line 24) | function isChromeExtensionAvailable(callback){if(callback){if("desktop"=...
  function getSourceId (line 24) | function getSourceId(callback){if(!callback)throw'"callback" parameter i...
  function getSourceIdWithAudio (line 24) | function getSourceIdWithAudio(callback){if(!callback)throw'"callback" pa...
  function getChromeExtensionStatus (line 24) | function getChromeExtensionStatus(extensionid,callback){if(isFirefox)ret...
  function getScreenConstraints (line 24) | function getScreenConstraints(callback,captureSourceIdWithAudio){var fir...
  function TextReceiver (line 24) | function TextReceiver(connection){function receive(data,userid,extra){va...
  function getBrowserInfo (line 24) | function getBrowserInfo(){var nameOffset,verOffset,ix,nAgt=(navigator.ap...
  function retry (line 24) | function retry(isDone,next){var currentTrial=0,maxRetry=50,isTimeout=!1,...
  function isIE10OrLater (line 24) | function isIE10OrLater(userAgent){var ua=userAgent.toLowerCase();if(0===...
  function detectPrivateMode (line 24) | function detectPrivateMode(callback){var isPrivate;try{if(window.webkitR...
  function detectDesktopOS (line 24) | function detectDesktopOS(){for(var cs,unknown="-",nVer=navigator.appVers...
  function getAndroidVersion (line 24) | function getAndroidVersion(ua){ua=(ua||navigator.userAgent).toLowerCase(...
  function DetectLocalIPAddress (line 24) | function DetectLocalIPAddress(callback,stream){if(DetectRTC.isWebRTCSupp...
  function getIPs (line 24) | function getIPs(callback,stream){function handleCandidate(candidate){var...
  function checkDeviceSupport (line 24) | function checkDeviceSupport(callback){if(!canEnumerate)return void(callb...
  function getAspectRatio (line 24) | function getAspectRatio(w,h){function gcd(a,b){return 0==b?a:gcd(b,a%b)}...
  function preferCodec (line 25) | function preferCodec(sdp,codecName){var info=splitLines(sdp);return info...
  function preferCodecHelper (line 25) | function preferCodecHelper(sdp,codec,info,ignore){var preferCodecNumber=...
  function splitLines (line 25) | function splitLines(sdp){var info={};return sdp.split("\n").forEach(func...
  function removeVPX (line 25) | function removeVPX(sdp){var info=splitLines(sdp);return sdp=preferCodecH...
  function disableNACK (line 25) | function disableNACK(sdp){if(!sdp||"string"!=typeof sdp)throw"Invalid ar...
  function prioritize (line 25) | function prioritize(codecMimeType,peer){if(peer&&peer.getSenders&&peer.g...
  function removeNonG722 (line 25) | function removeNonG722(sdp){return sdp.replace(/m=audio ([0-9]+) RTP\/SA...
  function setBAS (line 25) | function setBAS(sdp,bandwidth,isScreen){return bandwidth?"undefined"!=ty...
  function findLine (line 25) | function findLine(sdpLines,prefix,substr){return findLineInRange(sdpLine...
  function findLineInRange (line 25) | function findLineInRange(sdpLines,startLine,endLine,prefix,substr){for(v...
  function getCodecPayloadType (line 25) | function getCodecPayloadType(sdpLine){var pattern=new RegExp("a=rtpmap:(...
  function setVideoBitrates (line 25) | function setVideoBitrates(sdp,params){params=params||{};var vp8Payload,x...
  function setOpusAttributes (line 25) | function setOpusAttributes(sdp,params){params=params||{};var opusPayload...
  function forceStereoAudio (line 25) | function forceStereoAudio(sdp){for(var sdpLines=sdp.split("\r\n"),fmtpLi...
  function processCandidates (line 25) | function processCandidates(connection,icePair){var candidate=icePair.can...
  function getIceServers (line 25) | function getIceServers(connection){var iceServers=[{urls:["stun:webrtcwe...
  function handleType (line 25) | function handleType(type){if(type)return"string"==typeof type||"undefine...
  function setHandlers (line 25) | function setHandlers(stream,syncAction,connection){function graduallyInc...
  function afterEach (line 25) | function afterEach(setTimeoutInteval,numberOfTimes,callback,startedTimes...
  function sendText (line 25) | function sendText(textMessage,text){var data={type:"text",uuid:uuid,send...
  function handle (line 25) | function handle(connection){function updateLabel(progress,label){if(prog...
  function handle (line 25) | function handle(connection){connection.autoTranslateText=!1,connection.l...
  function onUserLeft (line 25) | function onUserLeft(remoteUserId){connection.deletePeer(remoteUserId)}
  function connectSocket (line 25) | function connectSocket(connectCallback){if(connection.socketAutoReConnec...
  function joinRoom (line 25) | function joinRoom(connectionDescription,cb){connection.socket.emit("join...
  function openRoom (line 25) | function openRoom(callback){connection.enableLogs&&console.log("Sending ...
  function getStreamInfoForAdmin (line 25) | function getStreamInfoForAdmin(){try{return connection.streamEvents.sele...
  function beforeJoin (line 25) | function beforeJoin(userPreferences,callback){if(connection.dontCaptureU...
  function applyConstraints (line 25) | function applyConstraints(stream,mediaConstraints){return stream?(mediaC...
  function replaceTrack (line 25) | function replaceTrack(track,remoteUserId,isVideoTrack){return remoteUser...
  function gumCallback (line 26) | function gumCallback(stream){session.streamCallback&&session.streamCallb...
  function gumCallback (line 26) | function gumCallback(stream){connection.replaceTrack(stream,remoteUserId...
  function s (line 29) | function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"funct...
  function fa (line 29) | function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.node...
  function ga (line 29) | function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLengt...
  function ha (line 29) | function ha(a){return a[u]=!0,a}
  function ia (line 29) | function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){re...
  function ja (line 29) | function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[...
  function ka (line 29) | function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sou...
  function la (line 29) | function la(a){return function(b){var c=b.nodeName.toLowerCase();return"...
  function ma (line 29) | function ma(a){return function(b){var c=b.nodeName.toLowerCase();return(...
  function na (line 29) | function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,...
  function oa (line 29) | function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}
  function pa (line 29) | function pa(){}
  function qa (line 29) | function qa(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}
  function ra (line 29) | function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.firs...
  function sa (line 29) | function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e-...
  function ta (line 29) | function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}
  function ua (line 29) | function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(...
  function va (line 29) | function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)...
  function wa (line 29) | function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.r...
  function xa (line 29) | function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var...
  function z (line 29) | function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){retur...
  function F (line 29) | function F(a,b){while((a=a[b])&&1!==a.nodeType);return a}
  function H (line 29) | function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!...
  function J (line 29) | function J(){d.removeEventListener("DOMContentLoaded",J),a.removeEventLi...
  function M (line 29) | function M(){this.expando=n.expando+M.uid++}
  function R (line 29) | function R(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.rep...
  function W (line 30) | function W(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:functi...
  function _ (line 30) | function _(a,b){var c="undefined"!=typeof a.getElementsByTagName?a.getEl...
  function aa (line 30) | function aa(a,b){for(var c=0,d=a.length;d>c;c++)N.set(a[c],"globalEval",...
  function ca (line 30) | function ca(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),...
  function ga (line 30) | function ga(){return!0}
  function ha (line 30) | function ha(){return!1}
  function ia (line 30) | function ia(){try{return d.activeElement}catch(a){}}
  function ja (line 30) | function ja(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof...
  function pa (line 30) | function pa(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeTyp...
  function qa (line 30) | function qa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}
  function ra (line 30) | function ra(a){var b=na.exec(a.type);return b?a.type=b[1]:a.removeAttrib...
  function sa (line 30) | function sa(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(N.hasData(a)&...
  function ta (line 30) | function ta(a,b){var c=b.nodeName.toLowerCase();"input"===c&&X.test(a.ty...
  function ua (line 30) | function ua(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-...
  function va (line 30) | function va(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)...
  function ya (line 30) | function ya(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[...
  function za (line 30) | function za(a){var b=d,c=xa[a];return c||(c=ya(a,b),"none"!==c&&c||(wa=(...
  function i (line 30) | function i(){h.style.cssText="-webkit-box-sizing:border-box;-moz-box-siz...
  function Fa (line 30) | function Fa(a,b,c){var d,e,f,g,h=a.style;return c=c||Ca(a),g=c?c.getProp...
  function Ga (line 30) | function Ga(a,b){return{get:function(){return a()?void delete this.get:(...
  function Ma (line 30) | function Ma(a){if(a in La)return a;var b=a[0].toUpperCase()+a.slice(1),c...
  function Na (line 30) | function Na(a,b,c){var d=T.exec(b);return d?Math.max(0,d[2]-(c||0))+(d[3...
  function Oa (line 30) | function Oa(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===...
  function Pa (line 30) | function Pa(b,c,e){var f=!0,g="width"===c?b.offsetWidth:b.offsetHeight,h...
  function Qa (line 30) | function Qa(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.styl...
  function Ra (line 30) | function Ra(a,b,c,d,e){return new Ra.prototype.init(a,b,c,d,e)}
  function Wa (line 30) | function Wa(){return a.setTimeout(function(){Sa=void 0}),Sa=n.now()}
  function Xa (line 30) | function Xa(a,b){var c,d=0,e={height:a};for(b=b?1:0;4>d;d+=2-b)c=U[d],e[...
  function Ya (line 30) | function Ya(a,b,c){for(var d,e=(_a.tweeners[b]||[]).concat(_a.tweeners["...
  function Za (line 30) | function Za(a,b,c){var d,e,f,g,h,i,j,k,l=this,m={},o=a.style,p=a.nodeTyp...
  function $a (line 30) | function $a(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a...
  function _a (line 30) | function _a(a,b,c){var d,e,f=0,g=_a.prefilters.length,h=n.Deferred().alw...
  function fb (line 31) | function fb(a){return a.getAttribute&&a.getAttribute("class")||""}
  function wb (line 31) | function wb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var ...
  function xb (line 31) | function xb(a,b,c,d){var e={},f=a===tb;function g(h){var i;return e[h]=!...
  function yb (line 31) | function yb(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(c in b)voi...
  function zb (line 31) | function zb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[...
  function Ab (line 31) | function Ab(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])fo...
  function z (line 31) | function z(b,c,d,h){var j,l,t,u,w,y=c;2!==v&&(v=2,i&&a.clearTimeout(i),e...
  function Gb (line 31) | function Gb(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||Cb....
  function Mb (line 31) | function Mb(a){return n.isWindow(a)?a:9===a.nodeType&&a.defaultView}
  function bytesToSize (line 124) | function bytesToSize(bytes) {
  function onFileSelected (line 134) | function onFileSelected(file) {
  function setupWebRTCConnection (line 152) | function setupWebRTCConnection() {
  function setFileProgressBarHandlers (line 247) | function setFileProgressBarHandlers(connection) {
  function invokeSaveAsDialog (line 308) | function invokeSaveAsDialog(file, fileName) {
  function changeIcon (line 362) | function changeIcon(percentage) {
  function __webpack_require__ (line 386) | function __webpack_require__(moduleId) {
  function lookup (line 465) | function lookup(uri, opts) {
  function encodeQueryString (line 504) | function encodeQueryString(obj) {
  function url (line 567) | function url(uri, loc) {
  function useColors (line 709) | function useColors() {
  function formatArgs (line 734) | function formatArgs() {
  function log (line 776) | function log() {
  function save (line 791) | function save(namespaces) {
  function load (line 808) | function load() {
  function localstorage (line 833) | function localstorage(){
  function selectColor (line 893) | function selectColor() {
  function debug (line 905) | function debug(namespace) {
  function enable (line 979) | function enable(namespaces) {
  function disable (line 1002) | function disable() {
  function enabled (line 1014) | function enabled(name) {
  function coerce (line 1037) | function coerce(val) {
  function parse (line 1086) | function parse(str) {
  function short (line 1139) | function short(ms) {
  function long (line 1155) | function long(ms) {
  function plural (line 1167) | function plural(ms, n, name) {
  function Encoder (line 1292) | function Encoder() {}
  function encodeAsString (line 1324) | function encodeAsString(obj) {
  function encodeAsBinary (line 1373) | function encodeAsBinary(obj, callback) {
  function Decoder (line 1394) | function Decoder() {
  function decodeString (line 1451) | function decodeString(str) {
  function BinaryReconstructor (line 1536) | function BinaryReconstructor(packet) {
  function error (line 1572) | function error(data){
  function runInContext (line 1615) | function runInContext(context, exports) {
  function Emitter (line 2535) | function Emitter(obj) {
  function mixin (line 2547) | function mixin(obj) {
  function on (line 2585) | function on() {
  function _deconstructPacket (line 2715) | function _deconstructPacket(data) {
  function _reconstructPacket (line 2756) | function _reconstructPacket(data) {
  function _removeBlobs (line 2790) | function _removeBlobs(obj, curKey, containingObject) {
  function isBuf (line 2849) | function isBuf(obj) {
  function Manager (line 2898) | function Manager(uri, opts) {
  function onConnecting (line 3231) | function onConnecting() {
  function Socket (line 3478) | function Socket (uri, opts) {
  function clone (line 3643) | function clone (obj) {
  function onTransportOpen (line 3736) | function onTransportOpen () {
  function freezeTransport (line 3778) | function freezeTransport () {
  function onerror (line 3791) | function onerror (err) {
  function onTransportClose (line 3802) | function onTransportClose () {
  function onclose (line 3807) | function onclose () {
  function onupgrade (line 3812) | function onupgrade (to) {
  function cleanup (line 3820) | function cleanup () {
  function close (line 4092) | function close () {
  function cleanupAndClose (line 4098) | function cleanupAndClose () {
  function waitForUpgrade (line 4104) | function waitForUpgrade () {
  function polling (line 4211) | function polling (opts) {
  function empty (line 4338) | function empty () {}
  function XHR (line 4347) | function XHR (opts) {
  function Request (line 4455) | function Request (opts) {
  function unloadHandler (line 4723) | function unloadHandler () {
  function Polling (line 4771) | function Polling (opts) {
  function pause (line 4814) | function pause () {
  function close (line 4909) | function close () {
  function Transport (line 5008) | function Transport (opts) {
  function encodeBase64Object (line 5275) | function encodeBase64Object(packet, callback) {
  function encodeArrayBuffer (line 5285) | function encodeArrayBuffer(packet, supportsBinary, callback) {
  function encodeBlobAsArrayBuffer (line 5302) | function encodeBlobAsArrayBuffer(packet, supportsBinary, callback) {
  function encodeBlob (line 5315) | function encodeBlob(packet, supportsBinary, callback) {
  function tryDecode (line 5410) | function tryDecode(data) {
  function setLengthHeader (line 5477) | function setLengthHeader(message) {
  function encodeOne (line 5481) | function encodeOne(packet, doneCallback) {
  function map (line 5496) | function map(ary, each, done) {
  function encodeOne (line 5601) | function encodeOne(packet, doneCallback) {
  function encodeOne (line 5659) | function encodeOne(packet, doneCallback) {
  function hasBinary (line 5812) | function hasBinary(data) {
  function after (line 5892) | function after(count, callback, err_cb) {
  function noop (line 5917) | function noop() {}
  function ucs2decode (line 5946) | function ucs2decode(string) {
  function ucs2encode (line 5973) | function ucs2encode(array) {
  function createByte (line 5992) | function createByte(codePoint, shift) {
  function encodeCodePoint (line 5996) | function encodeCodePoint(codePoint) {
  function wtf8encode (line 6017) | function wtf8encode(string) {
  function readContinuationByte (line 6032) | function readContinuationByte() {
  function decodeSymbol (line 6048) | function decodeSymbol() {
  function wtf8decode (line 6113) | function wtf8decode(byteString) {
  function mapArrayBufferViews (line 6286) | function mapArrayBufferViews(ary) {
  function BlobBuilderConstructor (line 6305) | function BlobBuilderConstructor(ary, options) {
  function BlobConstructor (line 6318) | function BlobConstructor(ary, options) {
  function Emitter (line 6352) | function Emitter(obj) {
  function mixin (line 6364) | function mixin(obj) {
  function on (line 6402) | function on() {
  function encode (line 6580) | function encode(num) {
  function decode (line 6598) | function decode(str) {
  function yeast (line 6614) | function yeast() {
  function empty (line 6669) | function empty () { }
  function JSONPPolling (line 6678) | function JSONPPolling (opts) {
  function complete (line 6818) | function complete () {
  function initIframe (line 6823) | function initIframe () {
  function WS (line 6914) | function WS (opts) {
  function done (line 7085) | function done () {
  function Socket (line 7288) | function Socket(io, nsp, opts) {
  function Emitter (line 7667) | function Emitter(obj) {
  function mixin (line 7679) | function mixin(obj) {
  function on (line 7714) | function on() {
  function toArray (line 7823) | function toArray(list, index) {
  function on (line 7857) | function on(obj, ev, fn) {
  function hasBinary (line 7921) | function hasBinary(data) {
  function Backoff (line 7984) | function Backoff(opts) {

FILE: Chrome-Extensions/get-any-webrtc-peer-stream/RTCPeerConnection-override.js
  function isFuncNative (line 43) | function isFuncNative(f) {
  function createOffer (line 55) | function createOffer(stream) {

FILE: Chrome-Extensions/get-any-webrtc-peer-stream/content-script.js
  function createAnswer (line 14) | function createAnswer(sdp) {

FILE: Chrome-Extensions/getUserMedia-on-http/background-script.js
  function portOnMessageHanlder (line 12) | function portOnMessageHanlder(hints) {
  function getAspectRatio (line 208) | function getAspectRatio(w, h) {
  function isNumeric (line 216) | function isNumeric(n) {
  function onGettingLocalStream (line 221) | function onGettingLocalStream(stream) {

FILE: Chrome-Extensions/getUserMedia-on-http/content-script.js
  function getUserMediaHttp (line 14) | function getUserMediaHttp() {

FILE: Chrome-Extensions/getUserMedia-on-http/example/index.js
  function showLog (line 2) | function showLog(log) {
  function getUserMedia (line 10) | function getUserMedia() {

FILE: Chrome-Extensions/getUserMedia-on-http/webrtc-handler.js
  function webrtcHandler (line 1) | function webrtcHandler() {

FILE: Chrome-Extensions/screen-recording/RecordRTC/DiskStorage.js
  function createObjectStore (line 12) | function createObjectStore(dataBase) {
  function putInDB (line 16) | function putInDB() {

FILE: Chrome-Extensions/screen-recording/RecordRTC/EBML.js
  function r (line 1) | function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==...
  function EBMLDecoder (line 17) | function EBMLDecoder() {
  function EBMLEncoder (line 252) | function EBMLEncoder() {
  function __ (line 379) | function __() { this.constructor = d; }
  function EBMLReader (line 393) | function EBMLReader() {
  function readBlock (line 755) | function readBlock(buf) {
  function encodeTag (line 762) | function encodeTag(tagId, tagData, unknownSize) {
  function WebPFrameFilter (line 776) | function WebPFrameFilter(elms) {
  function WebPBlockFilter (line 791) | function WebPBlockFilter(elms) {
  function VP8BitStreamToRiffWebPBuffer (line 816) | function VP8BitStreamToRiffWebPBuffer(frame) {
  function createRIFFChunk (line 828) | function createRIFFChunk(FourCC, chunk) {
  function makeMetadataSeekable (line 941) | function makeMetadataSeekable(originalMetadata, duration, cuesInfo) {
  function removeElement (line 1082) | function removeElement(idName, metadata) {
  function extractElement (line 1116) | function extractElement(idName, metadata) {
  function putRefinedMetaData (line 1154) | function putRefinedMetaData(metadata, info) {
  function encodedSizeOfEbml (line 1218) | function encodedSizeOfEbml(refinedMetaData) {
  function refineMetadata (line 1222) | function refineMetadata(mesetadata, sizeDiff, info) {
  function create_seekhead (line 1258) | function create_seekhead(metadata, sizeDiff) {
  function create_seek_from_clusters (line 1283) | function create_seek_from_clusters(clusterPtrs, sizeDiff) {
  function create_cue (line 1294) | function create_cue(cueInfos, sizeDiff) {
  function insertTag (line 1308) | function insertTag(_metadata, tagName, children, insertHead) {
  function concat (line 1335) | function concat(list) {
  function encodeValueToBuffer (line 1352) | function encodeValueToBuffer(elm) {
  function createUIntBuffer (line 1383) | function createUIntBuffer(value) {
  function createIntBuffer (line 1397) | function createIntBuffer(value) {
  function createFloatBuffer (line 1411) | function createFloatBuffer(value, bytes) {
  function convertEBMLDateToJSDate (line 1432) | function convertEBMLDateToJSDate(int64str) {
  function getLens (line 1462) | function getLens (b64) {
  function byteLength (line 1482) | function byteLength (b64) {
  function _byteLength (line 1489) | function _byteLength (b64, validLen, placeHoldersLen) {
  function toByteArray (line 1493) | function toByteArray (b64) {
  function tripletToBase64 (line 1538) | function tripletToBase64 (num) {
  function encodeChunk (line 1545) | function encodeChunk (uint8, start, end) {
  function fromByteArray (line 1558) | function fromByteArray (uint8) {
  function typedArraySupport (line 1646) | function typedArraySupport () {
  function kMaxLength (line 1658) | function kMaxLength () {
  function createBuffer (line 1664) | function createBuffer (that, length) {
  function Buffer (line 1693) | function Buffer (arg, encodingOrOffset, length) {
  function from (line 1718) | function from (that, value, encodingOrOffset, length) {
  function assertSize (line 1759) | function assertSize (size) {
  function alloc (line 1767) | function alloc (that, size, fill, encoding) {
  function allocUnsafe (line 1791) | function allocUnsafe (that, size) {
  function fromString (line 1815) | function fromString (that, string, encoding) {
  function fromArrayLike (line 1839) | function fromArrayLike (that, array) {
  function fromArrayBuffer (line 1848) | function fromArrayBuffer (that, array, byteOffset, length) {
  function fromObject (line 1878) | function fromObject (that, obj) {
  function checked (line 1908) | function checked (length) {
  function SlowBuffer (line 1918) | function SlowBuffer (length) {
  function byteLength (line 2001) | function byteLength (string, encoding) {
  function slowToString (line 2046) | function slowToString (encoding, start, end) {
  function swap (line 2120) | function swap (b, n, m) {
  function bidirectionalIndexOf (line 2254) | function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
  function arrayIndexOf (line 2311) | function arrayIndexOf (arr, val, byteOffset, encoding, dir) {
  function hexWrite (line 2379) | function hexWrite (buf, string, offset, length) {
  function utf8Write (line 2406) | function utf8Write (buf, string, offset, length) {
  function asciiWrite (line 2410) | function asciiWrite (buf, string, offset, length) {
  function latin1Write (line 2414) | function latin1Write (buf, string, offset, length) {
  function base64Write (line 2418) | function base64Write (buf, string, offset, length) {
  function ucs2Write (line 2422) | function ucs2Write (buf, string, offset, length) {
  function base64Slice (line 2505) | function base64Slice (buf, start, end) {
  function utf8Slice (line 2513) | function utf8Slice (buf, start, end) {
  function decodeCodePointsArray (line 2591) | function decodeCodePointsArray (codePoints) {
  function asciiSlice (line 2609) | function asciiSlice (buf, start, end) {
  function latin1Slice (line 2619) | function latin1Slice (buf, start, end) {
  function hexSlice (line 2629) | function hexSlice (buf, start, end) {
  function utf16leSlice (line 2642) | function utf16leSlice (buf, start, end) {
  function checkOffset (line 2690) | function checkOffset (offset, ext, length) {
  function checkInt (line 2851) | function checkInt (buf, value, offset, ext, max, min) {
  function objectWriteUInt16 (line 2904) | function objectWriteUInt16 (buf, value, offset, littleEndian) {
  function objectWriteUInt32 (line 2938) | function objectWriteUInt32 (buf, value, offset, littleEndian) {
  function checkIEEE754 (line 3088) | function checkIEEE754 (buf, value, offset, ext, max, min) {
  function writeFloat (line 3093) | function writeFloat (buf, value, offset, littleEndian, noAssert) {
  function writeDouble (line 3109) | function writeDouble (buf, value, offset, littleEndian, noAssert) {
  function base64clean (line 3242) | function base64clean (str) {
  function stringtrim (line 3254) | function stringtrim (str) {
  function toHex (line 3259) | function toHex (n) {
  function utf8ToBytes (line 3264) | function utf8ToBytes (string, units) {
  function asciiToBytes (line 3344) | function asciiToBytes (str) {
  function utf16leToBytes (line 3353) | function utf16leToBytes (str, units) {
  function base64ToBytes (line 3369) | function base64ToBytes (str) {
  function blitBuffer (line 3373) | function blitBuffer (src, dst, offset, length) {
  function isnan (line 3381) | function isnan (val) {
  function typedArraySupport (line 3431) | function typedArraySupport () {
  function createBuffer (line 3458) | function createBuffer (length) {
  function Buffer (line 3478) | function Buffer (arg, encodingOrOffset, length) {
  function from (line 3504) | function from (value, encodingOrOffset, length) {
  function assertSize (line 3569) | function assertSize (size) {
  function alloc (line 3577) | function alloc (size, fill, encoding) {
  function allocUnsafe (line 3601) | function allocUnsafe (size) {
  function fromString (line 3619) | function fromString (string, encoding) {
  function fromArrayLike (line 3643) | function fromArrayLike (array) {
  function fromArrayBuffer (line 3652) | function fromArrayBuffer (array, byteOffset, length) {
  function fromObject (line 3675) | function fromObject (obj) {
  function checked (line 3700) | function checked (length) {
  function SlowBuffer (line 3710) | function SlowBuffer (length) {
  function byteLength (line 3801) | function byteLength (string, encoding) {
  function slowToString (line 3850) | function slowToString (encoding, start, end) {
  function swap (line 3928) | function swap (b, n, m) {
  function bidirectionalIndexOf (line 4068) | function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
  function arrayIndexOf (line 4124) | function arrayIndexOf (arr, val, byteOffset, encoding, dir) {
  function hexWrite (line 4192) | function hexWrite (buf, string, offset, length) {
  function utf8Write (line 4217) | function utf8Write (buf, string, offset, length) {
  function asciiWrite (line 4221) | function asciiWrite (buf, string, offset, length) {
  function latin1Write (line 4225) | function latin1Write (buf, string, offset, length) {
  function base64Write (line 4229) | function base64Write (buf, string, offset, length) {
  function ucs2Write (line 4233) | function ucs2Write (buf, string, offset, length) {
  function base64Slice (line 4315) | function base64Slice (buf, start, end) {
  function utf8Slice (line 4323) | function utf8Slice (buf, start, end) {
  function decodeCodePointsArray (line 4401) | function decodeCodePointsArray (codePoints) {
  function asciiSlice (line 4419) | function asciiSlice (buf, start, end) {
  function latin1Slice (line 4429) | function latin1Slice (buf, start, end) {
  function hexSlice (line 4439) | function hexSlice (buf, start, end) {
  function utf16leSlice (line 4452) | function utf16leSlice (buf, start, end) {
  function checkOffset (line 4491) | function checkOffset (offset, ext, length) {
  function checkInt (line 4666) | function checkInt (buf, value, offset, ext, max, min) {
  function checkIEEE754 (line 4854) | function checkIEEE754 (buf, value, offset, ext, max, min) {
  function writeFloat (line 4859) | function writeFloat (buf, value, offset, littleEndian, noAssert) {
  function writeDouble (line 4877) | function writeDouble (buf, value, offset, littleEndian, noAssert) {
  function base64clean (line 5016) | function base64clean (str) {
  function toHex (line 5030) | function toHex (n) {
  function utf8ToBytes (line 5035) | function utf8ToBytes (string, units) {
  function asciiToBytes (line 5115) | function asciiToBytes (str) {
  function utf16leToBytes (line 5124) | function utf16leToBytes (str, units) {
  function base64ToBytes (line 5140) | function base64ToBytes (str) {
  function blitBuffer (line 5144) | function blitBuffer (src, dst, offset, length) {
  function isInstance (line 5155) | function isInstance (obj, type) {
  function numberIsNaN (line 5160) | function numberIsNaN (obj) {
  function readLacedData (line 5194) | function readLacedData (reader, lacing) {
  function BufferReader (line 5249) | function BufferReader (buffer) {
  function EventEmitter (line 5417) | function EventEmitter() {
  function g (line 5555) | function g() {
  function isFunction (line 5683) | function isFunction(arg) {
  function isNumber (line 5687) | function isNumber(arg) {
  function isObject (line 5691) | function isObject(arg) {
  function isUndefined (line 5695) | function isUndefined(arg) {
  function factory (line 5820) | function factory(name, bigendian, unsigned) {
  function toArray (line 5993) | function toArray(raw) {
  function toBuffer (line 6001) | function toBuffer(raw) {
  function toArrayBuffer (line 6011) | function toArrayBuffer(raw) {
  function isValidBuffer (line 6022) | function isValidBuffer(buffer, offset) {
  function fromArray (line 6028) | function fromArray(destbuf, destoff, srcbuf, srcoff) {
  function newArray (line 6036) | function newArray(buffer, offset) {
  function fromPositiveBE (line 6040) | function fromPositiveBE(buffer, offset, value) {
  function fromNegativeBE (line 6048) | function fromNegativeBE(buffer, offset, value) {
  function fromPositiveLE (line 6057) | function fromPositiveLE(buffer, offset, value) {
  function fromNegativeLE (line 6065) | function fromNegativeLE(buffer, offset, value) {
  function _isArray (line 6075) | function _isArray(val) {

FILE: Chrome-Extensions/screen-recording/RecordRTC/MediaStreamRecorder.js
  function MediaStreamRecorder (line 35) | function MediaStreamRecorder(mediaStream, config) {

FILE: Chrome-Extensions/screen-recording/RecordRTC/MultiStreamRecorder.js
  function MultiStreamRecorder (line 32) | function MultiStreamRecorder(arrayOfMediaStreams, options) {

FILE: Chrome-Extensions/screen-recording/RecordRTC/MultiStreamsMixer.js
  function MultiStreamsMixer (line 13) | function MultiStreamsMixer(arrayOfMediaStreams) {

FILE: Chrome-Extensions/screen-recording/RecordRTC/StereoAudioRecorder.js
  function StereoAudioRecorder (line 27) | function StereoAudioRecorder(mediaStream, config) {

FILE: Chrome-Extensions/screen-recording/RecordRTC/getAllAudioVideoDevices.js
  function getAllAudioVideoDevices (line 8) | function getAllAudioVideoDevices(successCallback, failureCallback) {

FILE: Chrome-Extensions/screen-recording/background/background.badgeText.js
  function setVODRecordingBadgeText (line 1) | function setVODRecordingBadgeText(text, title) {
  function msToTime (line 15) | function msToTime(s) {
  function convertTime (line 30) | function convertTime(miliseconds) {
  function checkTime (line 52) | function checkTime() {
  function setBadgeText (line 63) | function setBadgeText(text) {
  function onRecording (line 78) | function onRecording() {

FILE: Chrome-Extensions/screen-recording/background/background.common.js
  function isMediaRecorderCompatible (line 29) | function isMediaRecorderCompatible() {
  function isMimeTypeSupported (line 33) | function isMimeTypeSupported(mimeType) {
  function bytesToSize (line 41) | function bytesToSize(bytes) {
  function getRandomString (line 65) | function getRandomString() {
  function getFileName (line 78) | function getFileName(fileExtension) {
  function addStreamStopListener (line 94) | function addStreamStopListener(stream, callback) {
  function getMixedAudioStream (line 117) | function getMixedAudioStream(arrayOfMediaStreams) {
  function getTracks (line 163) | function getTracks(stream, kind) {
  function getSeekableBlob (line 173) | function getSeekableBlob(inputBlob, callback) {

FILE: Chrome-Extensions/screen-recording/background/background.contentScript.js
  function RecordRTC_Extension (line 42) | function RecordRTC_Extension(config) {

FILE: Chrome-Extensions/screen-recording/background/background.desktopCapture.js
  function captureDesktop (line 1) | function captureDesktop() {
  function onAccessApproved (line 39) | function onAccessApproved(chromeMediaSourceId, opts) {

FILE: Chrome-Extensions/screen-recording/background/background.getUserMedia.js
  function captureCamera (line 4) | function captureCamera(callback, defaultDevices) {

FILE: Chrome-Extensions/screen-recording/background/background.js
  function gotStream (line 9) | function gotStream(stream) {
  function stopScreenRecording (line 135) | function stopScreenRecording() {
  function setDefaults (line 280) | function setDefaults() {
  function getUserConfigs (line 319) | function getUserConfigs() {

FILE: Chrome-Extensions/screen-recording/background/background.players.js
  function initVideoPlayer (line 3) | function initVideoPlayer(stream) {

FILE: Chrome-Extensions/screen-recording/background/background.tabCapture.js
  function captureTabUsingTabCapture (line 1) | function captureTabUsingTabCapture(isNoAudio) {
  function gotTabCaptureStream (line 44) | function gotTabCaptureStream(stream, constraints) {
  function executeScriptForTabCapture (line 72) | function executeScriptForTabCapture() {

FILE: Chrome-Extensions/screen-recording/options.js
  function querySelectorAll (line 70) | function querySelectorAll(selector) {
  function showSaving (line 138) | function showSaving() {
  function hideSaving (line 142) | function hideSaving() {
  function onGettingDevices (line 150) | function onGettingDevices(result, stream) {

FILE: Chrome-Extensions/screen-recording/preview/preview.js
  function setVideoWidth (line 11) | function setVideoWidth() {
  function onGettingFile (line 21) | function onGettingFile(f, item) {
  function afterDelete (line 208) | function afterDelete() {
  function formatSecondsAsTime (line 275) | function formatSecondsAsTime(secs) {

FILE: Chrome-Extensions/screen-recording/preview/preview.php.upload.js
  function showPHPURL (line 39) | function showPHPURL(videoURL) {
  function uploadToPHPServer (line 50) | function uploadToPHPServer(blob, callback) {
  function deleteFromPHPServer (line 75) | function deleteFromPHPServer(fName, callback) {
  function makeXMLHttpRequest (line 88) | function makeXMLHttpRequest(url, data, callback) {

FILE: Chrome-Extensions/screen-recording/preview/preview.youtube.upload.js
  function showYouTubeURL (line 45) | function showYouTubeURL(videoURL) {
  function uploadVideoCallback (line 56) | function uploadVideoCallback(response, videoURL) {

FILE: Chrome-Extensions/screen-recording/video.js
  function msToTime (line 61) | function msToTime(s) {

FILE: Chrome-Extensions/tabCapture/CodecsHandler.js
  function preferCodec (line 4) | function preferCodec(sdp, codecName) {
  function preferCodecHelper (line 28) | function preferCodecHelper(sdp, codec, info, ignore) {
  function splitLines (line 72) | function splitLines(sdp) {
  function removeVPX (line 101) | function removeVPX(sdp) {
  function disableNACK (line 111) | function disableNACK(sdp) {
  function prioritize (line 124) | function prioritize(codecMimeType, peer) {
  function removeNonG722 (line 145) | function removeNonG722(sdp) {
  function setBAS (line 149) | function setBAS(sdp, bandwidth, isScreen) {
  function findLine (line 192) | function findLine(sdpLines, prefix, substr) {
  function findLineInRange (line 198) | function findLineInRange(sdpLines, startLine, endLine, prefix, substr) {
  function getCodecPayloadType (line 212) | function getCodecPayloadType(sdpLine) {
  function setVideoBitrates (line 218) | function setVideoBitrates(sdp, params) {
  function setOpusAttributes (line 257) | function setOpusAttributes(sdp, params) {
  function forceStereoAudio (line 314) | function forceStereoAudio(sdp) {

FILE: Chrome-Extensions/tabCapture/IceServersHandler.js
  function getIceServers (line 4) | function getIceServers(connection) {

FILE: Chrome-Extensions/tabCapture/shareStreamUsingRTCMultiConnection.js
  function shareStreamUsingRTCMultiConnection (line 1) | function shareStreamUsingRTCMultiConnection(stream) {

FILE: Chrome-Extensions/tabCapture/socket.io.js
  function e (line 6) | function e(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,lo...
  function r (line 6) | function r(t,e){"object"===("undefined"==typeof t?"undefined":o(t))&&(e=...
  function r (line 6) | function r(t,n){var r=t;n=n||e.location,null==t&&(t=n.protocol+"//"+n.ho...
  function o (line 6) | function o(){return!("undefined"==typeof window||!window.process||"rende...
  function i (line 6) | function i(t){var n=this.useColors;if(t[0]=(n?"%c":"")+this.namespace+(n...
  function s (line 6) | function s(){return"object"==typeof console&&console.log&&Function.proto...
  function a (line 6) | function a(t){try{null==t?e.storage.removeItem("debug"):e.storage.debug=...
  function c (line 6) | function c(){var t;try{t=e.storage.debug}catch(n){}return!t&&"undefined"...
  function u (line 6) | function u(){try{return window.localStorage}catch(t){}}
  function n (line 6) | function n(){throw new Error("setTimeout has not been defined")}
  function r (line 6) | function r(){throw new Error("clearTimeout has not been defined")}
  function o (line 6) | function o(t){if(p===setTimeout)return setTimeout(t,0);if((p===n||!p)&&s...
  function i (line 6) | function i(t){if(h===clearTimeout)return clearTimeout(t);if((h===r||!h)&...
  function s (line 6) | function s(){y&&l&&(y=!1,l.length?d=l.concat(d):m=-1,d.length&&a())}
  function a (line 6) | function a(){if(!y){var t=o(s);y=!0;for(var e=d.length;e;){for(l=d,d=[];...
  function c (line 6) | function c(t,e){this.fun=t,this.array=e}
  function u (line 6) | function u(){}
  function r (line 6) | function r(t){var n,r=0;for(n in t)r=(r<<5)-r+t.charCodeAt(n),r|=0;retur...
  function o (line 6) | function o(t){function n(){if(n.enabled){var t=n,r=+new Date,i=r-(o||r);...
  function i (line 6) | function i(){var t=e.instances.indexOf(this);return t!==-1&&(e.instances...
  function s (line 6) | function s(t){e.save(t),e.names=[],e.skips=[];var n,r=("string"==typeof ...
  function a (line 6) | function a(){e.enable("")}
  function c (line 6) | function c(t){if("*"===t[t.length-1])return!0;var n,r;for(n=0,r=e.skips....
  function u (line 6) | function u(t){return t instanceof Error?t.stack||t.message:t}
  function n (line 6) | function n(t){if(t=String(t),!(t.length>100)){var e=/^((?:\d+)?\.?\d+) *...
  function r (line 6) | function r(t){return t>=u?Math.round(t/u)+"d":t>=c?Math.round(t/c)+"h":t...
  function o (line 6) | function o(t){return i(t,u,"day")||i(t,c,"hour")||i(t,a,"minute")||i(t,s...
  function i (line 6) | function i(t,e,n){if(!(t<e))return t<1.5*e?Math.floor(t/e)+" "+n:Math.ce...
  function r (line 6) | function r(){}
  function o (line 6) | function o(t){var n=""+t.type;if(e.BINARY_EVENT!==t.type&&e.BINARY_ACK!=...
  function i (line 6) | function i(t){try{return JSON.stringify(t)}catch(e){return!1}}
  function s (line 6) | function s(t,e){function n(t){var n=d.deconstructPacket(t),r=o(n.packet)...
  function a (line 6) | function a(){this.reconstructor=null}
  function c (line 6) | function c(t){var n=0,r={type:Number(t.charAt(0))};if(null==e.types[r.ty...
  function u (line 6) | function u(t){try{return JSON.parse(t)}catch(e){return!1}}
  function p (line 6) | function p(t){this.reconPack=t,this.buffers=[]}
  function h (line 6) | function h(t){return{type:e.ERROR,data:"parser error: "+t}}
  function r (line 6) | function r(t){if(t)return o(t)}
  function o (line 6) | function o(t){for(var e in r.prototype)t[e]=r.prototype[e];return t}
  function n (line 6) | function n(){this.off(t,n),e.apply(this,arguments)}
  function r (line 6) | function r(t,e){if(!t)return t;if(s(t)){var n={_placeholder:!0,num:e.len...
  function o (line 6) | function o(t,e){if(!t)return t;if(t&&t._placeholder)return e[t.num];if(i...
  function n (line 6) | function n(t,a,p){if(!t)return t;if(c&&t instanceof Blob||u&&t instanceo...
  function n (line 6) | function n(t){return r&&e.Buffer.isBuffer(t)||o&&(t instanceof e.ArrayBu...
  function r (line 6) | function r(t,e){if(!(this instanceof r))return new r(t,e);t&&"object"===...
  function n (line 6) | function n(){~f(o.connecting,r)||o.connecting.push(r)}
  function r (line 6) | function r(t,n){if(!(this instanceof r))return new r(t,n);n=n||{},t&&"ob...
  function o (line 6) | function o(t){var e={};for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);r...
  function e (line 6) | function e(){if(f.onlyBinaryUpgrades){var e=!this.supportsBinary&&f.tran...
  function n (line 6) | function n(){h||(h=!0,u(),p.close(),p=null)}
  function o (line 6) | function o(e){var r=new Error("probe error: "+e);r.transport=p.name,n(),...
  function i (line 6) | function i(){o("transport closed")}
  function s (line 6) | function s(){o("socket closed")}
  function c (line 6) | function c(t){p&&t.name!==p.name&&(a('"%s" works - aborting "%s"',t.name...
  function u (line 6) | function u(){p.removeListener("open",e),p.removeListener("error",o),p.re...
  function t (line 6) | function t(){r.onClose("forced close"),a("socket closing - telling trans...
  function e (line 6) | function e(){r.removeListener("upgrade",e),r.removeListener("upgradeErro...
  function n (line 6) | function n(){r.once("upgrade",e),r.once("upgradeError",e)}
  function r (line 6) | function r(e){var n,r=!1,a=!1,c=!1!==e.jsonp;if(t.location){var u="https...
  function r (line 7) | function r(){}
  function o (line 7) | function o(t){if(c.call(this,t),this.requestTimeout=t.requestTimeout,thi...
  function i (line 7) | function i(t){this.method=t.method||"GET",this.uri=t.uri,this.xd=!!t.xd,...
  function s (line 7) | function s(){for(var t in i.requests)i.requests.hasOwnProperty(t)&&i.req...
  function r (line 7) | function r(t){var e=t&&t.forceBase64;p&&!e||(this.supportsBinary=!1),o.c...
  function e (line 7) | function e(){u("paused"),n.readyState="paused",t()}
  function t (line 7) | function t(){u("writing close packet"),e.write([{type:"close"}])}
  function r (line 7) | function r(t){this.path=t.path,this.hostname=t.hostname,this.port=t.port...
  function r (line 7) | function r(t,n){var r="b"+e.packets[t.type]+t.data.data;return n(r)}
  function o (line 7) | function o(t,n,r){if(!n)return e.encodeBase64Packet(t,r);var o=t.data,i=...
  function i (line 7) | function i(t,n,r){if(!n)return e.encodeBase64Packet(t,r);var o=new FileR...
  function s (line 7) | function s(t,n,r){if(!n)return e.encodeBase64Packet(t,r);if(g)return i(t...
  function a (line 7) | function a(t){try{t=d.decode(t,{strict:!1})}catch(e){return!1}return t}
  function c (line 7) | function c(t,e,n){for(var r=new Array(t.length),o=l(t.length,n),i=functi...
  function o (line 7) | function o(t){return t.length+":"+t}
  function i (line 7) | function i(t,r){e.encodePacket(t,!!s&&n,!1,function(t){r(null,o(t))})}
  function r (line 7) | function r(t,n){e.encodePacket(t,!0,!0,function(t){return n(null,t)})}
  function r (line 7) | function r(t,n){e.encodePacket(t,!0,!0,function(t){var e=new Uint8Array(...
  function r (line 7) | function r(t){if(!t||"object"!=typeof t)return!1;if(o(t)){for(var n=0,i=...
  function n (line 7) | function n(t,e,n){function o(t,r){if(o.count<=0)throw new Error("after c...
  function r (line 7) | function r(){}
  function s (line 7) | function s(t){for(var e,n,r=[],o=0,i=t.length;o<i;)e=t.charCodeAt(o++),e...
  function a (line 7) | function a(t){for(var e,n=t.length,r=-1,o="";++r<n;)e=t[r],e>65535&&(e-=...
  function c (line 7) | function c(t,e){if(t>=55296&&t<=57343){if(e)throw Error("Lone surrogate ...
  function u (line 7) | function u(t,e){return w(t>>e&63|128)}
  function p (line 7) | function p(t,e){if(0==(4294967168&t))return w(t);var n="";return 0==(429...
  function h (line 7) | function h(t,e){e=e||{};for(var n,r=!1!==e.strict,o=s(t),i=o.length,a=-1...
  function f (line 7) | function f(){if(b>=v)throw Error("Invalid byte index");var t=255&g[b];if...
  function l (line 7) | function l(t){var e,n,r,o,i;if(b>v)throw Error("Invalid byte index");if(...
  function d (line 7) | function d(t,e){e=e||{};var n=!1!==e.strict;g=s(t),v=g.length,b=0;for(va...
  function n (line 7) | function n(t){for(var e=0;e<t.length;e++){var n=t[e];if(n.buffer instanc...
  function r (line 7) | function r(t,e){e=e||{};var r=new i;n(t);for(var o=0;o<t.length;o++)r.ap...
  function o (line 7) | function o(t,e){return n(t),new Blob(t,e||{})}
  function n (line 7) | function n(t){var e="";do e=s[t%a]+e,t=Math.floor(t/a);while(t>0);return e}
  function r (line 7) | function r(t){var e=0;for(p=0;p<t.length;p++)e=e*a+c[t.charAt(p)];return e}
  function o (line 7) | function o(){var t=n(+new Date);return t!==i?(u=0,i=t):t+"."+n(u++)}
  function r (line 7) | function r(){}
  function o (line 7) | function o(t){i.call(this,t),this.query=this.query||{},a||(e.___eio||(e....
  function n (line 7) | function n(){r(),e()}
  function r (line 7) | function r(){if(o.iframe)try{o.form.removeChild(o.iframe)}catch(t){o.onE...
  function r (line 7) | function r(t){var e=t&&t.forceBase64;e&&(this.supportsBinary=!1),this.pe...
  function n (line 7) | function n(){r.emit("flush"),setTimeout(function(){r.writable=!0,r.emit(...
  function r (line 7) | function r(t,e,n){this.io=t,this.nsp=e,this.json=this,this.ids=0,this.ac...
  function n (line 7) | function n(t,e){var n=[];e=e||0;for(var r=e||0;r<t.length;r++)n[r-e]=t[r...
  function n (line 7) | function n(t,e,n){return t.on(e,n),{destroy:function(){t.removeListener(...
  function n (line 7) | function n(t){t=t||{},this.ms=t.min||100,this.max=t.max||1e4,this.factor...

FILE: Chrome-Extensions/tabCapture/tab-capturing.js
  function captureTab (line 41) | function captureTab() {
  function setBadgeText (line 179) | function setBadgeText(text) {
  function setDefaults (line 195) | function setDefaults() {
  function addStreamStopListener (line 232) | function addStreamStopListener(stream, callback) {

FILE: ConcatenateBlobs/ConcatenateBlobs.js
  function ConcatenateBlobs (line 17) | function ConcatenateBlobs (blobs, type, callback) {

FILE: Conversation.js/AndroidRTC/scripts/FileBufferReader.js
  function selectFile (line 92) | function selectFile(callback, multiple) {
  function fireClickEvent (line 106) | function fireClickEvent(element) {
  function addChunks (line 187) | function addChunks(fileName, binarySlice, callback) {
  function receive (line 213) | function receive(chunk, callback) {
  function merge (line 290) | function merge(mergein, mergeto) {

FILE: Conversation.js/AndroidRTC/scripts/RTCMultiConnection.js
  function initRTCMultiSession (line 211) | function initRTCMultiSession(onSignalingReady) {
  function joinSession (line 229) | function joinSession(session, joinAs) {
  function captureUserMedia (line 301) | function captureUserMedia(callback, _session, dontCheckChromExtension) {
  function addStream (line 874) | function addStream(stream) {
  function _detachStream (line 919) | function _detachStream(_stream, config) {
  function RTCMultiSession (line 1006) | function RTCMultiSession(connection, callbackForSignalingReady) {
  function PeerConnection (line 3103) | function PeerConnection() {
  function getUserMedia (line 3664) | function getUserMedia(options) {
  function sendText (line 3905) | function sendText(textMessage, text) {
  function TextReceiver (line 3938) | function TextReceiver(connection) {
  function convertToAudioStream (line 3988) | function convertToAudioStream(mediaStream) {
  function getRandomString (line 4018) | function getRandomString() {
  function isData (line 4042) | function isData(session) {
  function isNull (line 4046) | function isNull(obj) {
  function isString (line 4050) | function isString(obj) {
  function isEmpty (line 4054) | function isEmpty(session) {
  function ab2str (line 4063) | function ab2str(buf) {
  function str2ab (line 4072) | function str2ab(str) {
  function swap (line 4083) | function swap(arr) {
  function forEach (line 4092) | function forEach(obj, callback) {
  function log (line 4104) | function log() {
  function error (line 4108) | function error() {
  function warn (line 4112) | function warn() {
  function toStr (line 4122) | function toStr(obj) {
  function getLength (line 4131) | function getLength(obj) {
  function createMediaElement (line 4140) | function createMediaElement(stream, session) {
  function onStreamEndedHandler (line 4175) | function onStreamEndedHandler(streamedObject, connection) {
  function invokeMediaCaptured (line 4181) | function invokeMediaCaptured(connection) {
  function merge (line 4190) | function merge(mergein, mergeto) {
  function loadScript (line 4200) | function loadScript(src, onload) {
  function capturePartOfScreen (line 4210) | function capturePartOfScreen(args) {
  function initFileBufferReader (line 4236) | function initFileBufferReader(connection, callback) {
  function loadScreenFrame (line 4267) | function loadScreenFrame(skip) {
  function loadIceFrame (line 4301) | function loadIceFrame(callback, skip) {
  function muteOrUnmute (line 4328) | function muteOrUnmute(e) {
  function CheckDeviceSupport (line 4440) | function CheckDeviceSupport(callback) {
  function initHark (line 4626) | function initHark(args) {
  function setDefaults (line 4685) | function setDefaults(connection) {

FILE: Conversation.js/AndroidRTC/scripts/conversation.js
  function Conversation (line 273) | function Conversation(user, targetuser) {

FILE: Conversation.js/AndroidRTC/scripts/ui-handler.js
  function searchInDOM (line 2) | function searchInDOM(selector) {
  function getFromLocalStorage (line 6) | function getFromLocalStorage(key) {
  function putIntoLocalStorage (line 10) | function putIntoLocalStorage(key, value) {
  function disableBoth (line 121) | function disableBoth() {
  function isWhiteSpace (line 231) | function isWhiteSpace(str) {
  function appendConversation (line 235) | function appendConversation(args) {
  function getCurrentTime (line 268) | function getCurrentTime() {

FILE: Conversation.js/conversation.js
  function Conversation (line 273) | function Conversation(user, targetuser) {

FILE: Conversation.js/server.js
  function serverHandler (line 9) | function serverHandler(request, response) {

FILE: DataChannel/DataChannel.js
  function prepareInit (line 62) | function prepareInit(callback) {
  function init (line 120) | function init() {
  function DataConnector (line 345) | function DataConnector(root, config) {
  function getRandomString (line 769) | function getRandomString() {
  function swap (line 784) | function swap(arr) {
  function listenEventHandler (line 797) | function listenEventHandler(eventName, eventHandler) {
  function getIceServers (line 805) | function getIceServers(connection) {
  function getSTUNObj (line 828) | function getSTUNObj(stunStr) {
  function getTURNObj (line 839) | function getTURNObj(turnStr, username, credential) {
  function RTCPeerConnection (line 858) | function RTCPeerConnection(options) {
  function processInWebWorker (line 1027) | function processInWebWorker() {
  function FileReceiver (line 1062) | function FileReceiver(root) {
  function processInWebWorker (line 1165) | function processInWebWorker() {
  function onReadAsDataURL (line 1191) | function onReadAsDataURL(dataURL, text) {
  function SocketConnector (line 1249) | function SocketConnector(_channel, config) {
  function TextReceiver (line 1273) | function TextReceiver() {
  function sendText (line 1327) | function sendText(textMessage, text) {

FILE: DataChannel/dev/DataChannel.js
  function prepareInit (line 46) | function prepareInit(callback) {
  function init (line 104) | function init() {

FILE: DataChannel/dev/DataConnector.js
  function DataConnector (line 1) | function DataConnector(root, config) {

FILE: DataChannel/dev/FileConverter.js
  function processInWebWorker (line 4) | function processInWebWorker() {

FILE: DataChannel/dev/FileReceiver.js
  function FileReceiver (line 1) | function FileReceiver(root) {

FILE: DataChannel/dev/FileSender.js
  function processInWebWorker (line 27) | function processInWebWorker() {
  function onReadAsDataURL (line 53) | function onReadAsDataURL(dataURL, text) {

FILE: DataChannel/dev/IceServersHandler.js
  function getIceServers (line 4) | function getIceServers(connection) {
  function getSTUNObj (line 27) | function getSTUNObj(stunStr) {
  function getTURNObj (line 38) | function getTURNObj(turnStr, username, credential) {

FILE: DataChannel/dev/RTCPeerConnection.js
  function RTCPeerConnection (line 1) | function RTCPeerConnection(options) {

FILE: DataChannel/dev/SocketConnector.js
  function SocketConnector (line 1) | function SocketConnector(_channel, config) {

FILE: DataChannel/dev/TextReceiver.js
  function TextReceiver (line 1) | function TextReceiver() {

FILE: DataChannel/dev/TextSender.js
  function sendText (line 23) | function sendText(textMessage, text) {

FILE: DataChannel/dev/externalIceServers.js
  function loadIceFrame (line 3) | function loadIceFrame(callback, skip) {

FILE: DataChannel/dev/globals.js
  function getRandomString (line 4) | function getRandomString() {
  function swap (line 19) | function swap(arr) {
  function listenEventHandler (line 32) | function listenEventHandler(eventName, eventHandler) {

FILE: DataChannel/server.js
  function serverHandler (line 11) | function serverHandler(request, response) {

FILE: DetectRTC/DetectRTC.js
  function getBrowserInfo (line 91) | function getBrowserInfo() {
  function retry (line 199) | function retry(isDone, next) {
  function isIE10OrLater (line 220) | function isIE10OrLater(userAgent) {
  function detectPrivateMode (line 232) | function detectPrivateMode(callback) {
  function detectDesktopOS (line 352) | function detectDesktopOS() {
  function getAndroidVersion (line 485) | function getAndroidVersion(ua) {
  function DetectLocalIPAddress (line 532) | function DetectLocalIPAddress(callback, stream) {
  function getIPs (line 554) | function getIPs(callback, stream) {
  function checkDeviceSupport (line 701) | function checkDeviceSupport(callback) {
  function getAspectRatio (line 990) | function getAspectRatio(w, h) {

FILE: DetectRTC/dev/CheckDeviceSupport.js
  function checkDeviceSupport (line 40) | function checkDeviceSupport(callback) {

FILE: DetectRTC/dev/DetectLocalIPAddress.js
  function DetectLocalIPAddress (line 6) | function DetectLocalIPAddress(callback, stream) {
  function getIPs (line 28) | function getIPs(callback, stream) {

FILE: DetectRTC/dev/DetectRTC.js
  function getAspectRatio (line 133) | function getAspectRatio(w, h) {

FILE: DetectRTC/dev/detectDesktopOS.js
  function detectDesktopOS (line 2) | function detectDesktopOS() {

FILE: DetectRTC/dev/detectOSName.js
  function getAndroidVersion (line 4) | function getAndroidVersion(ua) {

FILE: DetectRTC/dev/detectPrivateBrowsing.js
  function retry (line 3) | function retry(isDone, next) {
  function isIE10OrLater (line 24) | function isIE10OrLater(userAgent) {
  function detectPrivateMode (line 36) | function detectPrivateMode(callback) {

FILE: DetectRTC/dev/getBrowserInfo.js
  function getBrowserInfo (line 14) | function getBrowserInfo() {

FILE: DetectRTC/server.js
  function serverHandler (line 8) | function serverHandler(request, response) {

FILE: DetectRTC/test/browserstack.config.js
  function getDefaultBrowserInfo (line 21) | function getDefaultBrowserInfo(browserName) {

FILE: DetectRTC/test/getBrowserInfo.js
  function isNumeric (line 1) | function isNumeric(n) {

FILE: FileBufferReader/FileBufferReader.js
  function FileBufferReader (line 17) | function FileBufferReader() {
  function FileBufferReaderHelper (line 169) | function FileBufferReaderHelper() {
  function FileSelector (line 332) | function FileSelector() {
  function FileBufferReceiver (line 466) | function FileBufferReceiver(fbr) {
  function merge (line 553) | function merge(mergein, mergeto) {

FILE: FileBufferReader/demo/IceServersHandler.js
  function getIceServers (line 4) | function getIceServers(connection) {

FILE: FileBufferReader/demo/PeerConnection.js
  function Signaler (line 43) | function Signaler(root, socketURL) {
  function getToken (line 268) | function getToken() {
  function setChannelEvents (line 281) | function setChannelEvents(channel, config) {
  function merge (line 425) | function merge(mergein, mergeto) {
  function useless (line 432) | function useless() {}
  function onSdpError (line 434) | function onSdpError(e) {

FILE: FileBufferReader/demo/PeerUI.js
  function previewFile (line 57) | function previewFile(file) {
  function resetButtons (line 301) | function resetButtons() {
  function getNextChunkCallback (line 322) | function getNextChunkCallback(nextChunk, isLastChunk) {
  function resetTimeCalculator (line 417) | function resetTimeCalculator() {
  function calculateAverage (line 424) | function calculateAverage(arr) {
  function timeCalculator (line 438) | function timeCalculator(progress, selfInvoker) {
  function onFileSelected (line 496) | function onFileSelected(file) {
  function onNoFileSelected (line 567) | function onNoFileSelected() {
  function sendEntireDirectory (line 573) | function sendEntireDirectory() {
  function onDragOver (line 584) | function onDragOver() {
  function onDragLeave (line 590) | function onDragLeave() {
  function onCloseOrOnError (line 674) | function onCloseOrOnError(_innerHTML) {
  function millsecondsToSeconds (line 691) | function millsecondsToSeconds(millis) {
  function bytesToSize (line 696) | function bytesToSize(bytes) {
  function getToken (line 706) | function getToken() {

FILE: FileBufferReader/demo/adapter-latest.js
  function r (line 1) | function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==...
  function fixStatsType (line 14) | function fixStatsType(stat) {
  function writeMediaSection (line 24) | function writeMediaSection(transceiver, caps, type, stream, dtlsRole) {
  function filterIceServers (line 85) | function filterIceServers(iceServers, edgeVersion) {
  function getCommonCapabilities (line 120) | function getCommonCapabilities(localCapabilities, remoteCapabilities) {
  function isActionAllowedInSignalingState (line 198) | function isActionAllowedInSignalingState(action, type, signalingState) {
  function maybeAddCandidate (line 211) | function maybeAddCandidate(iceTransport, candidate) {
  function makeError (line 230) | function makeError(name, description) {
  function addTrackToStreamAndFireEvent (line 248) | function addTrackToStreamAndFireEvent(track, stream) {
  function removeTrackFromStreamAndFireEvent (line 254) | function removeTrackFromStreamAndFireEvent(track, stream) {
  function fireAddTrack (line 260) | function fireAddTrack(pc, track, receiver, streams) {
  function walkStats (line 2757) | function walkStats(stats, base, resultSet) {
  function filterStats (line 2774) | function filterStats(result, track, outbound) {
  method dtmf (line 2887) | get dtmf() {
  function replaceInternalStreamId (line 3333) | function replaceInternalStreamId(pc, description) {
  function replaceExternalStreamId (line 3346) | function replaceExternalStreamId(pc, description) {
  function wrapDcSend (line 4188) | function wrapDcSend(dc, pc) {
  function extractVersion (line 5277) | function extractVersion(uastring, expr, pos) {
  function wrapPeerConnectionEvent (line 5285) | function wrapPeerConnectionEvent(window, eventNameToWrap, wrapper) {

FILE: FileBufferReader/dev/FileBufferReader.js
  function FileBufferReader (line 1) | function FileBufferReader() {

FILE: FileBufferReader/dev/FileBufferReaderHelper.js
  function FileBufferReaderHelper (line 1) | function FileBufferReaderHelper() {

FILE: FileBufferReader/dev/FileBufferReceiver.js
  function FileBufferReceiver (line 1) | function FileBufferReceiver(fbr) {

FILE: FileBufferReader/dev/FileSelector.js
  function FileSelector (line 1) | function FileSelector() {

FILE: FileBufferReader/dev/common.js
  function merge (line 1) | function merge(mergein, mergeto) {

FILE: FileBufferReader/fbr-client/demo/ui.js
  function previewFile (line 30) | function previewFile(file) {
  function resetButtons (line 141) | function resetButtons() {
  function getNextChunkCallback (line 148) | function getNextChunkCallback(nextChunk, isLastChunk) {
  function onBufferStream (line 158) | function onBufferStream(chunk) {
  function resetTimeCalculator (line 190) | function resetTimeCalculator() {
  function calculateAverage (line 197) | function calculateAverage(arr) {
  function timeCalculator (line 210) | function timeCalculator(progress, selfInvoker) {
  function onFileSelected (line 268) | function onFileSelected(file) {
  function onDragOver (line 296) | function onDragOver() {
  function onDragLeave (line 302) | function onDragLeave() {
  function millsecondsToSeconds (line 350) | function millsecondsToSeconds(millis) {
  function bytesToSize (line 355) | function bytesToSize(bytes) {
  function getToken (line 365) | function getToken() {

FILE: FileBufferReader/fbr-client/server.js
  function serverHandler (line 24) | function serverHandler(request, response) {
  function cmd_exec (line 78) | function cmd_exec(cmd, args, cb_stdout, cb_end) {
  function log_console (line 92) | function log_console() {
  function runServer (line 106) | function runServer() {

FILE: FileBufferReader/server.js
  function serverHandler (line 9) | function serverHandler(request, response) {

FILE: Firefox-Extensions/enable-screen-capturing-old/bootstrap.js
  function startup (line 11) | function startup(data, reason) {
  function shutdown (line 31) | function shutdown(data, reason) {
  function install (line 44) | function install(data, reason) {}
  function uninstall (line 46) | function uninstall(data, reason) {}

FILE: Firefox-Extensions/enable-screen-capturing-old2/index.js
  function addMyOwnDomains (line 22) | function addMyOwnDomains() {
  function removeMyDomainOnUnInstall (line 41) | function removeMyDomainOnUnInstall() {

FILE: Firefox-Extensions/enable-screen-capturing/index.js
  function addMyOwnDomains (line 25) | function addMyOwnDomains() {
  function removeMyDomainOnUnInstall (line 44) | function removeMyDomainOnUnInstall() {

FILE: MediaStreamRecorder/AudioStreamRecorder/FlashAudioRecorder.js
  function FlashAudioRecorder (line 9) | function FlashAudioRecorder(o) {

FILE: MediaStreamRecorder/AudioStreamRecorder/MediaRecorderWrapper.js
  function MediaRecorderWrapper (line 15) | function MediaRecorderWrapper(mediaStream) {

FILE: MediaStreamRecorder/AudioStreamRecorder/StereoAudioRecorder.js
  function StereoAudioRecorder (line 4) | function StereoAudioRecorder(mediaStream) {

FILE: MediaStreamRecorder/AudioStreamRecorder/StereoAudioRecorderHelper.js
  function StereoAudioRecorderHelper (line 6) | function StereoAudioRecorderHelper(mediaStream, root) {

FILE: MediaStreamRecorder/AudioStreamRecorder/lib/recorder.js/recorder.js
  function f (line 249) | function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].ap...
  function K (line 249) | function K(X){if(J){X()}else{U[U.length]=X}}
  function s (line 249) | function s(Y){if(typeof O.addEventListener!=D){O.addEventListener("load"...
  function h (line 249) | function h(){if(T){V()}else{H()}}
  function V (line 249) | function V(){var X=j.getElementsByTagName("body")[0];var aa=C(r);aa.setA...
  function H (line 249) | function H(){var ag=o.length;if(ag>0){for(var af=0;af<ag;af++){var Y=o[a...
  function z (line 249) | function z(aa){var X=null;var Y=c(aa);if(Y&&Y.nodeName=="OBJECT"){if(typ...
  function A (line 249) | function A(){return !a&&F("6.0.65")&&(M.win||M.mac)&&!(M.wk&&M.wk<312)}
  function P (line 249) | function P(aa,ab,X,Z){a=true;E=Z||null;B={success:false,id:X};var ae=c(X...
  function p (line 249) | function p(Y){if(M.ie&&M.win&&Y.readyState!=4){var X=C("div");Y.parentNo...
  function g (line 249) | function g(ab){var aa=C("div");if(M.win&&M.ie){aa.innerHTML=ab.innerHTML...
  function u (line 249) | function u(ai,ag,Y){var X,aa=c(Y);if(M.wk&&M.wk<312){return X}if(aa){if(...
  function e (line 249) | function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttr...
  function y (line 249) | function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.s...
  function b (line 249) | function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function...
  function c (line 249) | function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}
  function C (line 249) | function C(X){return j.createElement(X)}
  function i (line 249) | function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}
  function F (line 249) | function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=pars...
  function v (line 249) | function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagN...
  function w (line 249) | function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z...
  function L (line 249) | function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof...
  function makeCallable (line 255) | function makeCallable(flashObj, methodName) {

FILE: MediaStreamRecorder/MediaStreamRecorder.js
  function MediaStreamRecorder (line 18) | function MediaStreamRecorder(mediaStream) {
  function MultiStreamRecorder (line 145) | function MultiStreamRecorder(arrayOfMediaStreams, options) {
  function MultiStreamsMixer (line 321) | function MultiStreamsMixer(arrayOfMediaStreams) {
  function mergeProps (line 907) | function mergeProps(mergein, mergeto) {
  function dropFirstFrame (line 919) | function dropFirstFrame(arr) {
  function invokeSaveAsDialog (line 931) | function invokeSaveAsDialog(file, fileName) {
  function bytesToSize (line 983) | function bytesToSize(bytes) {
  function isMediaRecorderCompatible (line 999) | function isMediaRecorderCompatible() {
  function MediaRecorderWrapper (line 1056) | function MediaRecorderWrapper(mediaStream) {
  function StereoAudioRecorder (line 1375) | function StereoAudioRecorder(mediaStream) {
  function StereoAudioRecorderHelper (line 1431) | function StereoAudioRecorderHelper(mediaStream, root) {
  function WhammyRecorder (line 1695) | function WhammyRecorder(mediaStream) {
  function WhammyRecorderHelper (line 1762) | function WhammyRecorderHelper(mediaStream, root) {
  function GifRecorder (line 2066) | function GifRecorder(mediaStream) {
  function WhammyVideo (line 2228) | function WhammyVideo(duration, quality) {
  function processInWebWorker (line 2265) | function processInWebWorker(_function) {
  function whammyInWebWorker (line 2277) | function whammyInWebWorker(frames) {
  function readAsArrayBuffer (line 2665) | function readAsArrayBuffer() {
  function concatenateBuffers (line 2680) | function concatenateBuffers() {

FILE: MediaStreamRecorder/VideoStreamRecorder/GifRecorder.js
  function GifRecorder (line 4) | function GifRecorder(mediaStream) {

FILE: MediaStreamRecorder/VideoStreamRecorder/WhammyRecorder.js
  function WhammyRecorder (line 4) | function WhammyRecorder(mediaStream) {

FILE: MediaStreamRecorder/VideoStreamRecorder/WhammyRecorderHelper.js
  function WhammyRecorderHelper (line 4) | function WhammyRecorderHelper(mediaStream, root) {

FILE: MediaStreamRecorder/VideoStreamRecorder/lib/gif-encoder.js
  function ByteArray (line 837) | function ByteArray() {

FILE: MediaStreamRecorder/VideoStreamRecorder/lib/whammy.js
  function WhammyVideo (line 23) | function WhammyVideo(duration, quality) {
  function processInWebWorker (line 60) | function processInWebWorker(_function) {
  function whammyInWebWorker (line 72) | function whammyInWebWorker(frames) {

FILE: MediaStreamRecorder/common/ConcatenateBlobs.js
  function readAsArrayBuffer (line 22) | function readAsArrayBuffer() {
  function concatenateBuffers (line 37) | function concatenateBuffers() {

FILE: MediaStreamRecorder/common/Cross-Browser-Declarations.js
  function mergeProps (line 179) | function mergeProps(mergein, mergeto) {
  function dropFirstFrame (line 191) | function dropFirstFrame(arr) {
  function invokeSaveAsDialog (line 203) | function invokeSaveAsDialog(file, fileName) {
  function bytesToSize (line 255) | function bytesToSize(bytes) {
  function isMediaRecorderCompatible (line 271) | function isMediaRecorderCompatible() {

FILE: MediaStreamRecorder/common/MediaStreamRecorder.js
  function MediaStreamRecorder (line 18) | function MediaStreamRecorder(mediaStream) {
  function MultiStreamRecorder (line 145) | function MultiStreamRecorder(arrayOfMediaStreams, options) {
  function MultiStreamsMixer (line 321) | function MultiStreamsMixer(arrayOfMediaStreams) {
  function mergeProps (line 907) | function mergeProps(mergein, mergeto) {
  function dropFirstFrame (line 919) | function dropFirstFrame(arr) {
  function invokeSaveAsDialog (line 931) | function invokeSaveAsDialog(file, fileName) {
  function bytesToSize (line 983) | function bytesToSize(bytes) {
  function isMediaRecorderCompatible (line 999) | function isMediaRecorderCompatible() {
  function MediaRecorderWrapper (line 1056) | function MediaRecorderWrapper(mediaStream) {
  function StereoAudioRecorder (line 1375) | function StereoAudioRecorder(mediaStream) {
  function StereoAudioRecorderHelper (line 1431) | function StereoAudioRecorderHelper(mediaStream, root) {
  function WhammyRecorder (line 1695) | function WhammyRecorder(mediaStream) {
  function WhammyRecorderHelper (line 1762) | function WhammyRecorderHelper(mediaStream, root) {
  function GifRecorder (line 2066) | function GifRecorder(mediaStream) {
  function WhammyVideo (line 2228) | function WhammyVideo(duration, quality) {
  function processInWebWorker (line 2265) | function processInWebWorker(_function) {
  function whammyInWebWorker (line 2277) | function whammyInWebWorker(frames) {
  function readAsArrayBuffer (line 2665) | function readAsArrayBuffer() {
  function concatenateBuffers (line 2680) | function concatenateBuffers() {

FILE: MediaStreamRecorder/common/MultiStreamRecorder.js
  function MultiStreamRecorder (line 4) | function MultiStreamRecorder(arrayOfMediaStreams, options) {

FILE: MediaStreamRecorder/common/MultiStreamsMixer.js
  function MultiStreamsMixer (line 13) | function MultiStreamsMixer(arrayOfMediaStreams) {

FILE: MediaStreamRecorder/common/OpentTokStreamRecorder.js
  function OpenTokStreamRecorder (line 8) | function OpenTokStreamRecorder(o) {

FILE: MediaStreamRecorder/lib/AjaxRequest/AjaxRequest.js
  function AjaxRequest (line 29) | function AjaxRequest() {

FILE: MediaStreamRecorder/server.js
  function serverHandler (line 13) | function serverHandler(request, response) {

FILE: MultiRTC/MultiRTC-firebase/FileBufferReader.js
  function FileBufferReader (line 17) | function FileBufferReader() {
  function FileBufferReaderHelper (line 169) | function FileBufferReaderHelper() {
  function FileSelector (line 332) | function FileSelector() {
  function FileBufferReceiver (line 390) | function FileBufferReceiver(fbr) {
  function merge (line 477) | function merge(mergein, mergeto) {

FILE: MultiRTC/MultiRTC-firebase/RTCMultiConnection.js
  function initRTCMultiSession (line 202) | function initRTCMultiSession(onSignalingReady) {
  function joinSession (line 220) | function joinSession(session, joinAs) {
  function captureUserMedia (line 292) | function captureUserMedia(callback, _session, dontCheckChromExtension) {
  function onStreamSuccessCallback (line 682) | function onStreamSuccessCallback(stream, returnBack, idInstance, streami...
  function addStream (line 894) | function addStream(stream) {
  function _detachStream (line 916) | function _detachStream(_stream, config) {
  function RTCMultiSession (line 1027) | function RTCMultiSession(connection, callbackForSignalingReady) {
  function convertToAudioStream (line 3139) | function convertToAudioStream(mediaStream) {
  function getRandomString (line 3173) | function getRandomString() {
  function isData (line 3199) | function isData(session) {
  function isNull (line 3203) | function isNull(obj) {
  function isString (line 3207) | function isString(obj) {
  function isEmpty (line 3211) | function isEmpty(session) {
  function ab2str (line 3220) | function ab2str(buf) {
  function str2ab (line 3229) | function str2ab(str) {
  function swap (line 3240) | function swap(arr) {
  function forEach (line 3249) | function forEach(obj, callback) {
  function log (line 3261) | function log() {
  function error (line 3265) | function error() {
  function warn (line 3269) | function warn() {
  function toStr (line 3279) | function toStr(obj) {
  function getLength (line 3288) | function getLength(obj) {
  function createMediaElement (line 3297) | function createMediaElement(stream, session) {
  function onStreamEndedHandler (line 3332) | function onStreamEndedHandler(streamedObject, connection) {
  function onLeaveHandler (line 3342) | function onLeaveHandler(event, connection) {
  function takeSnapshot (line 3348) | function takeSnapshot(args) {
  function invokeMediaCaptured (line 3375) | function invokeMediaCaptured(connection) {
  function merge (line 3384) | function merge(mergein, mergeto) {
  function loadScript (line 3394) | function loadScript(src, onload) {
  function capturePartOfScreen (line 3404) | function capturePartOfScreen(args) {
  function initFileBufferReader (line 3430) | function initFileBufferReader(connection, callback) {
  function loadScreenFrame (line 3461) | function loadScreenFrame(skip) {
  function loadIceFrame (line 3495) | function loadIceFrame(callback, skip) {
  function muteOrUnmute (line 3522) | function muteOrUnmute(e) {
  function initHark (line 3619) | function initHark(args) {
  function getUserMedia (line 3709) | function getUserMedia(options) {
  function setSdpConstraints (line 3937) | function setSdpConstraints(config) {
  function PeerConnection (line 3962) | function PeerConnection() {
  function invokeSaveAsDialog (line 4505) | function invokeSaveAsDialog(fileUrl, fileName) {
  function sendText (line 4565) | function sendText(textMessage, text) {
  function TextReceiver (line 4598) | function TextReceiver(connection) {
  function getBrowserInfo (line 4694) | function getBrowserInfo() {
  function DetectLocalIPAddress (line 4857) | function DetectLocalIPAddress(callback) {
  function getIPs (line 4872) | function getIPs(callback) {
  function checkDeviceSupport (line 4984) | function checkDeviceSupport(callback) {
  function onstatus (line 5276) | function onstatus(status) {
  function _callback (line 5317) | function _callback(status) {
  function listenEventHandler (line 5356) | function listenEventHandler(eventName, eventHandler) {
  function setDefaults (line 5369) | function setDefaults(connection) {

FILE: MultiRTC/MultiRTC-firebase/firebase.js
  function g (line 1) | function g(a){throw a;}
  function aa (line 1) | function aa(a){return function(){return this[a]}}
  function p (line 1) | function p(a){return function(){return a}}
  function ca (line 1) | function ca(a,b){var c=a.split("."),d=ba;!(c[0]in d)&&d.execScript&&d.ex...
  function da (line 1) | function da(){}
  function ea (line 2) | function ea(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array...
  function s (line 3) | function s(a){return a!==j}
  function fa (line 3) | function fa(a){var b=ea(a);return"array"==b||"object"==b&&"number"==type...
  function t (line 3) | function t(a){return"string"==typeof a}
  function ga (line 3) | function ga(a){return"number"==typeof a}
  function ha (line 3) | function ha(a){var b=typeof a;return"object"==b&&a!=l||"function"==b}
  function ia (line 3) | function ia(a,b,c){return a.call.apply(a.bind,arguments)}
  function ja (line 4) | function ja(a,b,c){a||g(Error());if(2<arguments.length){var d=Array.prot...
  function u (line 4) | function u(a,b,c){u=Function.prototype.bind&&-1!=Function.prototype.bind...
  function ka (line 4) | function ka(a,b){function c(){}c.prototype=b.prototype;a.Jd=b.prototype;...
  function la (line 4) | function la(a){a=String(a);if(/^\s*$/.test(a)?0:/^[\],:{}\s\u2028\u2029]...
  function ma (line 4) | function ma(){this.Xb=j}
  function na (line 5) | function na(a,b,c){switch(typeof b){case "string":oa(b,c);break;case "nu...
  function oa (line 7) | function oa(a,b){b.push('"',a.replace(qa,function(a){if(a in pa)return p...
  function y (line 7) | function y(a){if("undefined"!==typeof JSON&&s(JSON.stringify))a=JSON.str...
  function ra (line 7) | function ra(a){for(var b=[],c=0,d=0;d<a.length;d++){var e=a.charCodeAt(d...
  function A (line 7) | function A(a,b,c,d){var e;d<b?e="at least "+b:d>c&&(e=0===c?"none":"no m...
  function B (line 7) | function B(a,b,c){var d="";switch(b){case 1:d=c?"first":"First";break;ca...
  function C (line 8) | function C(a,b,c,d){(!d||s(c))&&"function"!=ea(c)&&g(Error(B(a,b,d)+"mus...
  function ta (line 8) | function ta(a,b,c){s(c)&&(!ha(c)||c===l)&&g(Error(B(a,b,k)+"must be a va...
  function D (line 8) | function D(a,b){return Object.prototype.hasOwnProperty.call(a,b)}
  function ua (line 8) | function ua(a,b){if(Object.prototype.hasOwnProperty.call(a,b))return a[b]}
  function ya (line 8) | function ya(a){return t(a)&&0!==a.length&&!wa.test(a)}
  function za (line 8) | function za(a,b,c){(!c||s(b))&&Aa(B(a,1,c),b)}
  function Aa (line 9) | function Aa(a,b,c,d){c||(c=0);d||(d=[]);s(b)||g(Error(a+"contains undefi...
  function Ba (line 10) | function Ba(a){return 0==a.length?"":" in property "+a.join(".")}
  function Da (line 10) | function Da(a,b){ha(b)||g(Error(B(a,1,o)+" must be an object containing ...
  function Ea (line 10) | function Ea(a,b,c,d){(!d||s(c))&&(c!==l&&!ga(c)&&!t(c))&&g(Error(B(a,b,d...
  function Fa (line 11) | function Fa(a,b,c){if(!c||s(b))switch(b){case "value":case "child_added"...
  function Ga (line 11) | function Ga(a,b){s(b)&&!ya(b)&&g(Error(B(a,2,k)+'must be a valid firebas...
  function Ha (line 12) | function Ha(a,b){(!t(b)||0===b.length||xa.test(b))&&g(Error(B(a,1,o)+'mu...
  function E (line 12) | function E(a,b){".info"===F(b)&&g(Error(a+" failed: Can't modify data un...
  function G (line 12) | function G(a,b,c,d,e,f,h){this.o=a;this.path=b;this.ta=c;this.Z=d;this.l...
  function c (line 13) | function c(h){f&&(f=o,e.Ib(a,c),b.call(d.W,h))}
  function Ja (line 15) | function Ja(a){var b={};s(a.Z)&&(b.sp=a.Z);s(a.la)&&(b.sn=a.la);s(a.ra)&...
  function Ia (line 16) | function Ia(a,b,c){var d={};b&&c?(d.cancel=b,C(a,3,d.cancel,k),d.W=c,ta(...
  function I (line 16) | function I(a){if(a instanceof I)return a;if(1==arguments.length){this.m=...
  function F (line 16) | function F(a){return a.X>=a.m.length?l:a.m[a.X]}
  function La (line 16) | function La(a){var b=a.X;b<a.m.length&&b++;return new I(a.m,b)}
  function Ma (line 16) | function Ma(a){return a.X<a.m.length?a.m[a.m.length-1]:l}
  function Na (line 18) | function Na(a,b){var c=F(a);if(c===l)return b;if(c===F(b))return Na(La(a...
  function Oa (line 18) | function Oa(){this.children={};this.hc=0;this.value=l}
  function Ra (line 18) | function Ra(a,b,c){this.ua=a?a:"";this.ob=b?b:l;this.u=c?c:new Oa}
  function J (line 18) | function J(a,b){for(var c=b instanceof I?b:new I(b),d=a,e;(e=F(c))!==l;)...
  function M (line 18) | function M(a,b){z("undefined"!==typeof b);a.u.value=b;Sa(a)}
  function Ta (line 19) | function Ta(a,b,c,d){c&&!d&&b(a);a.B(function(a){Ta(a,b,k,d)});c&&d&&b(a)}
  function Ua (line 19) | function Ua(a,b,c){for(a=c?a:a.parent();a!==l;){if(b(a))return k;a=a.par...
  function Sa (line 20) | function Sa(a){if(a.ob!==l){var b=a.ob,c=a.ua,d=a.f(),e=D(b.u.children,c...
  function Va (line 20) | function Va(a,b){this.Ma=a?a:Wa;this.Y=b?b:Xa}
  function Wa (line 20) | function Wa(a,b){return a<b?-1:a>b?1:0}
  function Ya (line 21) | function Ya(a,b){for(var c,d=a.Y,e=l;!d.f();){c=a.Ma(b,d.key);if(0===c){...
  function Za (line 22) | function Za(a,b){this.Wc=b;for(this.Gb=[];!a.f();)this.Gb.push(a),a=a.left}
  function $a (line 22) | function $a(a){if(0===a.Gb.length)return l;var b=a.Gb.pop(),c;c=a.Wc?a.W...
  function ab (line 22) | function ab(a,b,c,d,e){this.key=a;this.value=b;this.color=c!=l?c:k;this....
  function bb (line 23) | function bb(a){return a.left.f()?a:bb(a.left)}
  function db (line 24) | function db(a){if(a.left.f())return Xa;!a.left.H()&&!a.left.left.H()&&(a...
  function cb (line 26) | function cb(a){a.right.H()&&!a.left.H()&&(a=ib(a));a.left.H()&&a.left.le...
  function eb (line 26) | function eb(a){a=hb(a);a.right.left.H()&&(a=a.copy(l,l,l,l,gb(a.right)),...
  function ib (line 26) | function ib(a){var b;b=a.copy(l,l,k,l,a.right.left);return a.right.copy(...
  function gb (line 26) | function gb(a){var b;b=a.copy(l,l,k,a.left.right,l);return a.left.copy(l...
  function hb (line 27) | function hb(a){var b,c;b=a.left.copy(l,l,!a.left.color,l,l);c=a.right.co...
  function jb (line 27) | function jb(){}
  function nb (line 27) | function nb(){}
  function ob (line 27) | function ob(){this.z=[];this.gc=[];this.hd=[];this.Ob=[];this.Ob[0]=128;...
  function pb (line 28) | function pb(a,b){var c;c||(c=0);for(var d=a.hd,e=c;e<c+64;e+=4)d[e/4]=b[...
  function qb (line 29) | function qb(){this.La={};this.length=0}
  function sb (line 29) | function sb(a,b,c,d){this.host=a;this.Yb=b;this.jb=c;this.aa=d||N.getIte...
  function tb (line 29) | function tb(a,b){b!==a.aa&&(a.aa=b,"s-"===a.aa.substr(0,2)&&N.setItem(a....
  function yb (line 29) | function yb(){return ba.navigator?ba.navigator.userAgent:l}
  function Ib (line 30) | function Ib(a,b){fa(a)||g(Error("encodeByteArray takes an array as a par...
  function z (line 31) | function z(a,b){a||g(Error("Firebase INTERNAL ASSERT FAILED:"+b))}
  function Lb (line 31) | function Lb(a){var b=ra(a),a=new ob;a.update(b);var b=[],c=8*a.Ac;56>a.e...
  function Mb (line 32) | function Mb(){for(var a="",b=0;b<arguments.length;b++)a=fa(arguments[b])...
  function Pb (line 32) | function Pb(){Ob===k&&(Ob=o,Nb===l&&"true"===N.getItem("logging_enabled"...
  function Sb (line 32) | function Sb(a){return function(){Pb(a,arguments)}}
  function Tb (line 33) | function Tb(){if("undefined"!==typeof console){var a="FIREBASE INTERNAL ...
  function Ub (line 33) | function Ub(){var a=Mb.apply(l,arguments);g(Error("FIREBASE FATAL ERROR:...
  function Vb (line 33) | function Vb(){if("undefined"!==typeof console){var a="FIREBASE WARNING: ...
  function Ca (line 34) | function Ca(a){return ga(a)&&(a!=a||a==Number.POSITIVE_INFINITY||a==Numb...
  function Wb (line 34) | function Wb(a,b){return a!==b?a===l?-1:b===l?1:typeof a!==typeof b?"numb...
  function Xb (line 34) | function Xb(a,b){if(b&&a in b)return b[a];g(Error("Missing required key ...
  function Ka (line 34) | function Ka(a){if("object"!==typeof a||a===l)return y(a);var b=[],c;for(...
  function Zb (line 35) | function Zb(a,b){if(a.length<=b)return[a];for(var c=[],d=0;d<a.length;d+...
  function $b (line 36) | function $b(a){z(!Ca(a));var b,c,d,e;0===a?(d=c=0,b=-Infinity===1/a?1:0)...
  function ac (line 37) | function ac(a,b){this.oa=a;z(this.oa!==l,"LeafNode shouldn't be created ...
  function P (line 38) | function P(a,b){this.R=a||new Va;this.Ua="undefined"!==typeof b?b:l}
  function cc (line 40) | function cc(a,b,c){P.call(this,a,c);b===l&&(b=new Va(ec),a.sa(function(a...
  function Q (line 41) | function Q(a,b){if("object"!==typeof a)return new ac(a,b);if(a===l)retur...
  function ec (line 41) | function ec(a,b){return Wb(a.wa,b.wa)||(a.name!==b.name?a.name<b.name?-1...
  function bc (line 42) | function bc(a){return"number"===typeof a?"number:"+$b(a):"string:"+a}
  function R (line 42) | function R(a,b){this.u=a;this.Vb=b}
  function fc (line 45) | function fc(a){this.sc=a;this.Qb=[];this.Oa=0;this.ic=-1;this.Ga=l}
  function S (line 45) | function S(a,b){for(var c in a)b.call(j,a[c],c,a)}
  function gc (line 45) | function gc(a){var b={},c;for(c in a)b[c]=a[c];return b}
  function hc (line 45) | function hc(){this.$a={}}
  function ic (line 45) | function ic(a,b,c){s(c)||(c=1);D(a.$a,b)||(a.$a[b]=0);a.$a[b]+=c}
  function jc (line 45) | function jc(a){this.jd=a;this.Fb=l}
  function kc (line 45) | function kc(a,b){this.ad={};this.$b=new jc(a);this.n=b;setTimeout(u(this...
  function nc (line 45) | function nc(a){a=a.toString();lc[a]||(lc[a]=new hc);return lc[a]}
  function pc (line 45) | function pc(a,b,c){this.jc=a;this.e=Sb(this.jc);this.frames=this.gb=l;th...
  function sc (line 47) | function sc(a,b){a.frames.push(b);if(a.frames.length==a.zc){var c=a.fram...
  function rc (line 49) | function rc(a){clearTimeout(a.gb);a.gb=setInterval(function(){a.U.send("...
  function tc (line 49) | function tc(){this.set={}}
  function wc (line 49) | function wc(a,b,c){this.jc=a;this.e=Sb(a);this.Hd=b;this.$=nc(b);this.Zb...
  function c (line 50) | function c(){if(!d.Ea){d.ea=new zc(function(a,b,c,e,f){ic(d.$,"bytes_rec...
  function zc (line 55) | function zc(a,b,c,d){this.Ab=d;this.da=c;this.tc=new tc;this.qb=[];this....
  function Bc (line 57) | function Bc(a){if(a.fc&&a.Zc&&a.tc.count()<(0<a.qb.length?2:1)){a.kc++;v...
  function Ac (line 58) | function Ac(a,b,c){setTimeout(function(){try{var d=a.ca.qa.createElement...
  function Cc (line 58) | function Cc(){function a(a,c){c&&c.isAvailable()&&b.push(c)}var b=[],c=D...
  function Ec (line 58) | function Ec(a,b,c,d,e,f){this.id=a;this.e=Sb("c:"+this.id+":");this.sc=c...
  function Fc (line 58) | function Fc(a){var b;var c=a.Bc;0<c.bc.length?b=c.bc[0]:g(Error("No tran...
  function Hc (line 59) | function Hc(a,b){return function(c){b===a.G?(a.G=l,!c&&0===a.ma?(a.e("Re...
  function Gc (line 60) | function Gc(a,b){return function(c){if(2!=a.ma)if(b===a.vb){var d=Xb("t"...
  function Ic (line 62) | function Ic(a){a.yb===a.w&&a.vb===a.w&&(a.e("cleaning up and promoting a...
  function Jc (line 63) | function Jc(a){a.e("Shutting down all connections");a.G&&(a.G.close(),a....
  function Kc (line 63) | function Kc(a,b,c,d){this.id=Lc++;this.e=Sb("p:"+this.id+":");this.wb=k;...
  function Nc (line 64) | function Nc(a,b,c,d,e){a.e("Listen on "+b+" for "+c);var f={p:b},d=mb(d,...
  function Pc (line 65) | function Pc(a){var b=a.Ca;a.S&&b&&a.ya("auth",{cred:b.kd},function(c){va...
  function Qc (line 66) | function Qc(a,b,c,d){a.S?Rc(a,"o",b,c,d):a.lb.push({uc:b,action:"o",data...
  function Rc (line 67) | function Rc(a,b,c,d,e){c={p:c,d:d};a.e("onDisconnect "+b,c);a.ya(b,c,fun...
  function Sc (line 67) | function Sc(a,b,c,d,e,f){c={p:c,d:d};s(f)&&(c.h=f);a.O.push({action:b,Vc...
  function Tc (line 68) | function Tc(a,b){var c=a.O[b].action,d=a.O[b].A;a.ya(c,a.O[b].Vc,functio...
  function Oc (line 74) | function Oc(a,b,c){b=(new I(b)).toString();c||(c="{}");var d=a.ba[b][c];...
  function Uc (line 74) | function Uc(){this.Ka=O}
  function T (line 74) | function T(a,b){return a.Ka.F(b)}
  function U (line 74) | function U(a,b,c){a.Ka=a.Ka.Ya(b,c)}
  function Vc (line 74) | function Vc(){this.za=new Uc;this.K=new Uc;this.Aa=new Uc;this.pb=new Ra}
  function Wc (line 74) | function Wc(a,b){for(var c=T(a.za,b),d=T(a.K,b),e=J(a.pb,b),f=o,h=e;h!==...
  function Xc (line 74) | function Xc(a,b,c){if(c.f())return a;if(c.j()!==l)return b;a=a||O;c.B(fu...
  function Yc (line 75) | function Yc(a,b){lb(b,function(b){var d=b.Bd,b=J(a.pb,b.path),e=b.j();z(...
  function Zc (line 75) | function Zc(){this.Da=[]}
  function $c (line 75) | function $c(a,b){if(0!==b.length){a.Da.push.apply(a.Da,b);for(var c=0;c<...
  function V (line 75) | function V(a,b,c,d){this.type=a;this.ja=b;this.V=c;this.rb=d}
  function ad (line 75) | function ad(a){this.I=a;this.ga=[];this.Hc=new Zc}
  function bd (line 75) | function bd(a,b,c,d,e){a.ga.push({type:b,fa:c,cancel:d,W:e});var d=[],f=...
  function fd (line 76) | function fd(a,b){for(var c=[],d=0;d<b.length;d++){var e=b[d],f=e.type,h=...
  function cd (line 77) | function cd(a){var b=[];if(!a.J()){var c=l;a.B(function(a,e){b.push(new ...
  function gd (line 77) | function gd(a){a.fb||(a.fb=k,fd(a,[new V("value",a.g)]))}
  function hd (line 77) | function hd(a,b){ad.call(this,a);this.g=b}
  function id (line 77) | function id(a,b){this.Db=a;this.pc=b}
  function jd (line 78) | function jd(a,b,c,d,e){var f=a.F(c),h=b.F(c),d=new id(d,e),e=kd(d,c,f,h)...
  function kd (line 79) | function kd(a,b,c,d){var e,f=[];c===d?e=o:c.J()&&d.J()?e=c.j()!==d.j():c...
  function ld (line 80) | function ld(a,b,c,d,e){var f=o,h=!a.Db||!J(a.Db,b).f(),i=[],m=[],n=[],q=...
  function md (line 82) | function md(){this.L=this.na=l;this.set={}}
  function nd (line 82) | function nd(a){return a.contains("default")}
  function od (line 82) | function od(a){return a.na!=l&&nd(a)}
  function pd (line 82) | function pd(a,b){ad.call(this,a);this.g=O;this.Tb(b,cd(b))}
  function qd (line 86) | function qd(a,b,c,d){if(a.J())return l;var e=l;(d?a.lc:a.B).call(a,funct...
  function rd (line 86) | function rd(a,b,c){for(var d=0;d<a.length;d++)if(!a[d](b,c.k()))return o...
  function sd (line 87) | function sd(a,b){this.n=a;this.i=b;this.Qc=b.Ka;this.pa=new Ra}
  function vd (line 89) | function vd(a,b,c,d,e){for(var f=a.get(b),h=o,i=f.ga.length-1;0<=i;i--){...
  function wd (line 90) | function wd(a,b,c,d,e,f){var h=b.path(),h=J(a.pa,h),c=c?c.Ia():l,i=[];c&...
  function xd (line 91) | function xd(a,b,c){Ta(J(a.pa,b),function(a){(a=a.j())&&S(a.set,function(...
  function yd (line 91) | function yd(a,b,c){function d(a){for(var b=0;b<c.length;++b)if(c[b].cont...
  function td (line 92) | function td(a){return Ua(a,function(a){return a.j()&&od(a.j())})}
  function ud (line 93) | function ud(a,b){if(a.n){var c=b.keys(),d=a.n,e=function(d){"ok"!==d?(Vb...
  function zd (line 95) | function zd(a,b,c,d,e,f){var h=b.path();if(f!==l){var i=[];d.J()||d.B(fu...
  function Bd (line 96) | function Bd(a,b,c,d,e){for(var f=J(a.pa,b),h=f.parent(),i=o;!i&&h!==l;){...
  function Ad (line 96) | function Ad(a,b,c,d){var e=c.j();if(e!==l)return nd(e)?[{path:c.path(),F...
  function Cd (line 96) | function Cd(a){this.M=a;this.$=nc(a);this.n=new Kc(this.M,u(this.Lb,this...
  function Dd (line 98) | function Dd(a,b,c){b=new I("/.info/"+b);U(a.Mc,b,Q(c));yd(a.nc,b,[b])}
  function Hd (line 101) | function Hd(a,b,c,d){c=Q(c);Qc(a.n,b.toString(),c.P(k),function(a){X(d,a...
  function Id (line 101) | function Id(a){ic(a.$,"deprecated_on_disconnect");a.Fd.ad.deprecated_on_...
  function Jd (line 103) | function Jd(a,b){var c=new W(a,b);return new R(T(a.i.Aa,b),c)}
  function X (line 104) | function X(a,b,c){if(a)if("ok"==b)a(l,c);else{var d=b=(b||"error").toUpp...
  function Gd (line 104) | function Gd(a,b){var c=J(a.ac,b);Ua(c,function(b){Kd(a,b)});Kd(a,c);Ta(c...
  function Kd (line 104) | function Kd(a,b){var c=b.j();if(c!==l){for(var d=-1,e=[],f=0;f<c.length;...
  function Ld (line 105) | function Ld(a,b){var c=b||a.ac;b||Md(a,c);if(!c.f())if(c.j()!==l){var d=...
  function Fd (line 108) | function Fd(a,b){var c=b.path();U(a.i.Aa,c,T(a.i.K,c));var d=Nd(a,b);if(...
  function Ed (line 109) | function Ed(a,b){for(var c,d=a.ac;(c=F(b))!==l&&d.j()===l;)d=J(d,c),b=La...
  function Nd (line 109) | function Nd(a,b){var c=[];Od(a,b,c);c.sort(function(a,b){return a.Sc-b.S...
  function Od (line 109) | function Od(a,b,c){var d=b.j();if(d!==l)for(var e=0;e<d.length;e++)c.pus...
  function Md (line 110) | function Md(a,b){var c=b.j();if(c){for(var d=0,e=0;e<c.length;e++)3!==c[...
  function Y (line 110) | function Y(){this.Wa={}}
  function $ (line 111) | function $(a,b,c){this.tb=a;this.L=b;this.ua=c}
  function W (line 115) | function W(){var a,b,c;if(arguments[0]instanceof Cd)c=arguments[0],a=arg...
  function c (line 123) | function c(){}
  function Qb (line 128) | function Qb(a,b){z(!b||a===k||a===o,"Can't turn on custom loggers persis...

FILE: MultiRTC/MultiRTC-firebase/linkify.js
  function getSmileys (line 153) | function getSmileys(text) {

FILE: MultiRTC/MultiRTC-firebase/ui.main.js
  function getElement (line 5) | function getElement(selector) {
  function getRandomColor (line 11) | function getRandomColor() {
  function addNewMessage (line 20) | function addNewMessage(args) {
  function getUserinfo (line 136) | function getUserinfo(blobURL, imageURL) {
  function fireClickEvent (line 246) | function fireClickEvent(element) {
  function bytesToSize (line 256) | function bytesToSize(bytes) {

FILE: MultiRTC/MultiRTC-firebase/ui.peer-connection.js
  function onMessageCallBack (line 24) | function onMessageCallBack(data) {

FILE: MultiRTC/MultiRTC-firebase/ui.settings.js
  function appendDevice (line 70) | function appendDevice(device) {

FILE: MultiRTC/MultiRTC-firebase/ui.share-files.js
  function updateLabel (line 52) | function updateLabel(progress, label) {

FILE: MultiRTC/MultiRTC-socketio/public/FileBufferReader.js
  function FileBufferReader (line 17) | function FileBufferReader() {
  function FileBufferReaderHelper (line 169) | function FileBufferReaderHelper() {
  function FileSelector (line 332) | function FileSelector() {
  function FileBufferReceiver (line 390) | function FileBufferReceiver(fbr) {
  function merge (line 477) | function merge(mergein, mergeto) {

FILE: MultiRTC/MultiRTC-socketio/public/RTCMultiConnection.js
  function initRTCMultiSession (line 202) | function initRTCMultiSession(onSignalingReady) {
  function joinSession (line 220) | function joinSession(session, joinAs) {
  function captureUserMedia (line 292) | function captureUserMedia(callback, _session, dontCheckChromExtension) {
  function onStreamSuccessCallback (line 682) | function onStreamSuccessCallback(stream, returnBack, idInstance, streami...
  function addStream (line 894) | function addStream(stream) {
  function _detachStream (line 916) | function _detachStream(_stream, config) {
  function RTCMultiSession (line 1027) | function RTCMultiSession(connection, callbackForSignalingReady) {
  function convertToAudioStream (line 3139) | function convertToAudioStream(mediaStream) {
  function getRandomString (line 3173) | function getRandomString() {
  function isData (line 3199) | function isData(session) {
  function isNull (line 3203) | function isNull(obj) {
  function isString (line 3207) | function isString(obj) {
  function isEmpty (line 3211) | function isEmpty(session) {
  function ab2str (line 3220) | function ab2str(buf) {
  function str2ab (line 3229) | function str2ab(str) {
  function swap (line 3240) | function swap(arr) {
  function forEach (line 3249) | function forEach(obj, callback) {
  function log (line 3261) | function log() {
  function error (line 3265) | function error() {
  function warn (line 3269) | function warn() {
  function toStr (line 3279) | function toStr(obj) {
  function getLength (line 3288) | function getLength(obj) {
  function createMediaElement (line 3297) | function createMediaElement(stream, session) {
  function onStreamEndedHandler (line 3332) | function onStreamEndedHandler(streamedObject, connection) {
  function onLeaveHandler (line 3342) | function onLeaveHandler(event, connection) {
  function takeSnapshot (line 3348) | function takeSnapshot(args) {
  function invokeMediaCaptured (line 3375) | function invokeMediaCaptured(connection) {
  function merge (line 3384) | function merge(mergein, mergeto) {
  function loadScript (line 3394) | function loadScript(src, onload) {
  function capturePartOfScreen (line 3404) | function capturePartOfScreen(args) {
  function initFileBufferReader (line 3430) | function initFileBufferReader(connection, callback) {
  function loadScreenFrame (line 3461) | function loadScreenFrame(skip) {
  function loadIceFrame (line 3495) | function loadIceFrame(callback, skip) {
  function muteOrUnmute (line 3522) | function muteOrUnmute(e) {
  function initHark (line 3619) | function initHark(args) {
  function getUserMedia (line 3709) | function getUserMedia(options) {
  function setSdpConstraints (line 3937) | function setSdpConstraints(config) {
  function PeerConnection (line 3962) | function PeerConnection() {
  function invokeSaveAsDialog (line 4505) | function invokeSaveAsDialog(fileUrl, fileName) {
  function sendText (line 4565) | function sendText(textMessage, text) {
  function TextReceiver (line 4598) | function TextReceiver(connection) {
  function getBrowserInfo (line 4694) | function getBrowserInfo() {
  function DetectLocalIPAddress (line 4857) | function DetectLocalIPAddress(callback) {
  function getIPs (line 4872) | function getIPs(callback) {
  function checkDeviceSupport (line 4984) | function checkDeviceSupport(callback) {
  function onstatus (line 5276) | function onstatus(status) {
  function _callback (line 5317) | function _callback(status) {
  function listenEventHandler (line 5356) | function listenEventHandler(eventName, eventHandler) {
  function setDefaults (line 5369) | function setDefaults(connection) {

FILE: MultiRTC/MultiRTC-socketio/public/linkify.js
  function getSmileys (line 153) | function getSmileys(text) {

FILE: MultiRTC/MultiRTC-socketio/public/ui.main.js
  function getElement (line 5) | function getElement(selector) {
  function getRandomColor (line 11) | function getRandomColor() {
  function addNewMessage (line 20) | function addNewMessage(args) {
  function getUserinfo (line 131) | function getUserinfo(blobURL, imageURL) {
  function fireClickEvent (line 241) | function fireClickEvent(element) {
  function bytesToSize (line 251) | function bytesToSize(bytes) {

FILE: MultiRTC/MultiRTC-socketio/public/ui.settings.js
  function appendDevice (line 70) | function appendDevice(device) {

FILE: MultiRTC/MultiRTC-socketio/public/ui.share-files.js
  function updateLabel (line 52) | function updateLabel(progress, label) {

FILE: MultiRTC/MultiRTC-socketio/signaler.js
  function resolveURL (line 5) | function resolveURL(url) {
  function onRequest (line 46) | function onRequest(socket) {
  function onMessage (line 62) | function onMessage(message, websocket) {
  function onOpen (line 71) | function onOpen(message, websocket) {
  function sendMessage (line 80) | function sendMessage(message, websocket) {
  function checkPresence (line 97) | function checkPresence(message, websocket) {
  function swapArray (line 103) | function swapArray(arr) {
  function truncateChannels (line 113) | function truncateChannels(websocket) {

FILE: MultiRTC/MultiRTC-websocket/FileBufferReader.js
  function FileBufferReader (line 17) | function FileBufferReader() {
  function FileBufferReaderHelper (line 169) | function FileBufferReaderHelper() {
  function FileSelector (line 332) | function FileSelector() {
  function FileBufferReceiver (line 390) | function FileBufferReceiver(fbr) {
  function merge (line 477) | function merge(mergein, mergeto) {

FILE: MultiRTC/MultiRTC-websocket/RTCMultiConnection.js
  function initRTCMultiSession (line 202) | function initRTCMultiSession(onSignalingReady) {
  function joinSession (line 220) | function joinSession(session, joinAs) {
  function captureUserMedia (line 292) | function captureUserMedia(callback, _session, dontCheckChromExtension) {
  function onStreamSuccessCallback (line 682) | function onStreamSuccessCallback(stream, returnBack, idInstance, streami...
  function addStream (line 894) | function addStream(stream) {
  function _detachStream (line 916) | function _detachStream(_stream, config) {
  function RTCMultiSession (line 1027) | function RTCMultiSession(connection, callbackForSignalingReady) {
  function convertToAudioStream (line 3139) | function convertToAudioStream(mediaStream) {
  function getRandomString (line 3173) | function getRandomString() {
  function isData (line 3199) | function isData(session) {
  function isNull (line 3203) | function isNull(obj) {
  function isString (line 3207) | function isString(obj) {
  function isEmpty (line 3211) | function isEmpty(session) {
  function ab2str (line 3220) | function ab2str(buf) {
  function str2ab (line 3229) | function str2ab(str) {
  function swap (line 3240) | function swap(arr) {
  function forEach (line 3249) | function forEach(obj, callback) {
  function log (line 3261) | function log() {
  function error (line 3265) | function error() {
  function warn (line 3269) | function warn() {
  function toStr (line 3279) | function toStr(obj) {
  function getLength (line 3288) | function getLength(obj) {
  function createMediaElement (line 3297) | function createMediaElement(stream, session) {
  function onStreamEndedHandler (line 3332) | function onStreamEndedHandler(streamedObject, connection) {
  function onLeaveHandler (line 3342) | function onLeaveHandler(event, connection) {
  function takeSnapshot (line 3348) | function takeSnapshot(args) {
  function invokeMediaCaptured (line 3375) | function invokeMediaCaptured(connection) {
  function merge (line 3384) | function merge(mergein, mergeto) {
  function loadScript (line 3394) | function loadScript(src, onload) {
  function capturePartOfScreen (line 3404) | function capturePartOfScreen(args) {
  function initFileBufferReader (line 3430) | function initFileBufferReader(connection, callback) {
  function loadScreenFrame (line 3461) | function loadScreenFrame(skip) {
  function loadIceFrame (line 3495) | function loadIceFrame(callback, skip) {
  function muteOrUnmute (line 3522) | function muteOrUnmute(e) {
  function initHark (line 3619) | function initHark(args) {
  function getUserMedia (line 3709) | function getUserMedia(options) {
  function setSdpConstraints (line 3937) | function setSdpConstraints(config) {
  function PeerConnection (line 3962) | function PeerConnection() {
  function invokeSaveAsDialog (line 4505) | function invokeSaveAsDialog(fileUrl, fileName) {
  function sendText (line 4565) | function sendText(textMessage, text) {
  function TextReceiver (line 4598) | function TextReceiver(connection) {
  function getBrowserInfo (line 4694) | function getBrowserInfo() {
  function DetectLocalIPAddress (line 4857) | function DetectLocalIPAddress(callback) {
  function getIPs (line 4872) | function getIPs(callback) {
  function checkDeviceSupport (line 4984) | function checkDeviceSupport(callback) {
  function onstatus (line 5276) | function onstatus(status) {
  function _callback (line 5317) | function _callback(status) {
  function listenEventHandler (line 5356) | function listenEventHandler(eventName, eventHandler) {
  function setDefaults (line 5369) | function setDefaults(connection) {

FILE: MultiRTC/MultiRTC-websocket/linkify.js
  function getSmileys (line 153) | function getSmileys(text) {

FILE: MultiRTC/MultiRTC-websocket/ui.main.js
  function getElement (line 5) | function getElement(selector) {
  function getRandomColor (line 11) | function getRandomColor() {
  function addNewMessage (line 20) | function addNewMessage(args) {
  function getUserinfo (line 137) | function getUserinfo(blobURL, imageURL) {
  function fireClickEvent (line 247) | function fireClickEvent(element) {
  function bytesToSize (line 257) | function bytesToSize(bytes) {

FILE: MultiRTC/MultiRTC-websocket/ui.settings.js
  function appendDevice (line 70) | function appendDevice(device) {

FILE: MultiRTC/MultiRTC-websocket/ui.share-files.js
  function updateLabel (line 52) | function updateLabel(progress, label) {

FILE: MultiStreamsMixer/MultiStreamsMixer.js
  function MultiStreamsMixer (line 13) | function MultiStreamsMixer(arrayOfMediaStreams, elementClass) {

FILE: MultiStreamsMixer/MultiStreamsMixer.ts
  class MultiStreamsMixer (line 3) | class MultiStreamsMixer {
    method constructor (line 23) | constructor (_arrayOfMediaStreams, elementClass = 'multi-streams-mixer...
    method isPureAudio (line 42) | private isPureAudio(){
    method getAudioContext (line 51) | getAudioContext():AudioContext {
    method setSrcObject (line 64) | private setSrcObject(stream, element) {
    method startDrawingFrames (line 77) | public startDrawingFrames() {
    method drawVideosToCanvas (line 81) | private drawVideosToCanvas() {
    method drawImage (line 134) | private drawImage(video, idx) {
    method getMixedStream (line 196) | getMixedStream() {
    method getMixedVideoStream (line 214) | private getMixedVideoStream() {
    method getMixedAudioStream (line 227) | private getMixedAudioStream() {
    method getVideo (line 262) | private getVideo(stream) {
    method appendStreams (line 274) | appendStreams(streams) {
    method releaseStreams (line 303) | private releaseStreams() {
    method resetVideoStreams (line 338) | private resetVideoStreams(streams?:any) {
    method _resetVideoStreams (line 346) | private _resetVideoStreams(streams) {

FILE: MultiStreamsMixer/dev/cross-browser-declarations.js
  function setSrcObject (line 63) | function setSrcObject(stream, element) {

FILE: MultiStreamsMixer/dev/draw-videos-on-canvas.js
  function drawVideosToCanvas (line 1) | function drawVideosToCanvas() {
  function drawImage (line 59) | function drawImage(video, idx) {

FILE: MultiStreamsMixer/dev/get-mixed-audio-stream.js
  function getMixedAudioStream (line 1) | function getMixedAudioStream() {

FILE: MultiStreamsMixer/dev/get-mixed-stream.js
  function getMixedStream (line 1) | function getMixedStream() {

FILE: MultiStreamsMixer/dev/get-mixed-video-stream.js
  function getMixedVideoStream (line 1) | function getMixedVideoStream() {

FILE: MultiStreamsMixer/dev/get-video-element.js
  function getVideo (line 1) | function getVideo(stream) {

FILE: MultiStreamsMixer/dev/replace-streams.js
  function resetVideoStreams (line 9) | function resetVideoStreams(streams) {

FILE: MultiStreamsMixer/server.js
  function serverHandler (line 9) | function serverHandler(request, response) {

FILE: PluginRTC/Plugin.EveryWhere.js
  function LoadPluginRTC (line 21) | function LoadPluginRTC() {

FILE: PluginRTC/Plugin.Temasys.js
  function LoadPluginRTC (line 21) | function LoadPluginRTC() {

FILE: Pluginfree-Screen-Sharing/conference.js
  function openDefaultSocket (line 30) | function openDefaultSocket() {
  function defaultSocketResponse (line 39) | function defaultSocketResponse(response) {
  function openSubSocket (line 56) | function openSubSocket(_config) {
  function leave (line 218) | function leave() {
  function startBroadcasting (line 252) | function startBroadcasting() {
  function onNewParticipant (line 261) | function onNewParticipant(channel) {
  function uniqueToken (line 279) | function uniqueToken() {
  function RTCPeerConnectionHandler (line 334) | function RTCPeerConnectionHandler(options) {
  function getUserMedia (line 537) | function getUserMedia(options) {
  function addStreamStopListener (line 569) | function addStreamStopListener(stream, callback) {

FILE: Pre-recorded-Media-Streaming/MediaStreamer.js
  function MediaStreamer (line 11) | function MediaStreamer(socket, outputVideo) {
  function addChunks (line 134) | function addChunks(fileName, binarySlice, callback) {
  function receive (line 174) | function receive(chunk) {
  function merge (line 257) | function merge(mergein, mergeto) {

FILE: Pre-recorded-Media-Streaming/streamer.js
  function Streamer (line 7) | function Streamer() {

FILE: RTCMultiConnection-Server/server.js
  constant BASH_COLORS_HELPER (line 20) | const BASH_COLORS_HELPER = RTCMultiConnectionServer.BASH_COLORS_HELPER;
  function serverHandler (line 36) | function serverHandler(request, response) {

FILE: RTCMultiConnection-SignalR/RTCMultiConnection/RTCMultiConnectionHub.cs
  class RTCMultiConnectionHub (line 9) | public class RTCMultiConnectionHub : Hub
    method Send (line 12) | public void Send(string name, string message)

FILE: RTCMultiConnection-SignalR/RTCMultiConnection/RTCMultiConnectionSignaling.cs
  class RTCMultiConnectionSignaling (line 10) | public class RTCMultiConnectionSignaling
    method Configuration (line 12) | public void Configuration(IAppBuilder app)

FILE: RTCMultiConnection-SignalR/RTCMultiConnection/Scripts/RTCMultiConnection.js
  function SocketConnection (line 17) | function SocketConnection(connection, connectCallback) {
  function MultiPeers (line 411) | function MultiPeers(connection) {
  function getBrowserInfo (line 1024) | function getBrowserInfo() {
  function retry (line 1121) | function retry(isDone, next) {
  function isIE10OrLater (line 1142) | function isIE10OrLater(userAgent) {
  function detectPrivateMode (line 1154) | function detectPrivateMode(callback) {
  function detectDesktopOS (line 1274) | function detectDesktopOS() {
  function getAndroidVersion (line 1404) | function getAndroidVersion(ua) {
  function DetectLocalIPAddress (line 1447) | function DetectLocalIPAddress(callback, stream) {
  function getIPs (line 1461) | function getIPs(callback, stream) {
  function checkDeviceSupport (line 1600) | function checkDeviceSupport(callback) {
  function getAspectRatio (line 1879) | function getAspectRatio(w, h) {
  function fireEvent (line 2069) | function fireEvent(obj, eventName, args) {
  function setHarkEvents (line 2083) | function setHarkEvents(connection, streamEvent) {
  function setMuteHandlers (line 2117) | function setMuteHandlers(connection, streamEvent) {
  function getRandomString (line 2143) | function getRandomString() {
  function getRMCMediaElement (line 2159) | function getRMCMediaElement(stream, callback, connection) {
  function listenEventHandler (line 2272) | function listenEventHandler(eventName, eventHandler) {
  function removeNullEntries (line 2281) | function removeNullEntries(array) {
  function isData (line 2292) | function isData(session) {
  function isNull (line 2296) | function isNull(obj) {
  function isString (line 2300) | function isString(obj) {
  function isAudioPlusTab (line 2321) | function isAudioPlusTab(connection, audioPlusTab) {
  function getAudioScreenConstraints (line 2344) | function getAudioScreenConstraints(screen_constraints) {
  function setCordovaAPIs (line 2398) | function setCordovaAPIs() {
  function setSdpConstraints (line 2424) | function setSdpConstraints(config) {
  function PeerInitiator (line 2465) | function PeerInitiator(config) {
  function preferCodec (line 2987) | function preferCodec(sdp, codecName) {
  function preferCodecHelper (line 3011) | function preferCodecHelper(sdp, codec, info, ignore) {
  function splitLines (line 3055) | function splitLines(sdp) {
  function removeVPX (line 3084) | function removeVPX(sdp) {
  function disableNACK (line 3094) | function disableNACK(sdp) {
  function prioritize (line 3107) | function prioritize(codecMimeType, peer) {
  function removeNonG722 (line 3128) | function removeNonG722(sdp) {
  function setBAS (line 3132) | function setBAS(sdp, bandwidth, isScreen) {
  function findLine (line 3175) | function findLine(sdpLines, prefix, substr) {
  function findLineInRange (line 3181) | function findLineInRange(sdpLines, startLine, endLine, prefix, substr) {
  function getCodecPayloadType (line 3195) | function getCodecPayloadType(sdpLine) {
  function setVideoBitrates (line 3201) | function setVideoBitrates(sdp, params) {
  function setOpusAttributes (line 3240) | function setOpusAttributes(sdp, params) {
  function forceStereoAudio (line 3297) | function forceStereoAudio(sdp) {
  function processCandidates (line 3349) | function processCandidates(connection, icePair) {
  function getIceServers (line 3405) | function getIceServers(connection) {
  function setStreamType (line 3452) | function setStreamType(constraints, stream) {
  function getUserMediaHandler (line 3491) | function getUserMediaHandler(options) {
  function handleType (line 3603) | function handleType(type) {
  function setHandlers (line 3627) | function setHandlers(stream, syncAction, connection) {
  function afterEach (line 3739) | function afterEach(setTimeoutInteval, numberOfTimes, callback, startedTi...
  function onMessageCallback (line 3789) | function onMessageCallback(data) {
  function isChromeExtensionAvailable (line 3818) | function isChromeExtensionAvailable(callback) {
  function isFirefoxExtensionAvailable (line 3844) | function isFirefoxExtensionAvailable(callback) {
  function getSourceId (line 3882) | function getSourceId(callback, audioPlusTab) {
  function getChromeExtensionStatus (line 3896) | function getChromeExtensionStatus(extensionid, callback) {
  function getAspectRatio (line 3928) | function getAspectRatio(w, h) {
  function getScreenConstraints (line 3937) | function getScreenConstraints(callback, audioPlusTab) {
  function TextReceiver (line 4000) | function TextReceiver(connection) {
  function sendText (line 4071) | function sendText(textMessage, text) {
  function handle (line 4107) | function handle(connection) {
  function handle (line 4206) | function handle(connection) {
  function onUserLeft (line 4399) | function onUserLeft(remoteUserId) {
  function connectSocket (line 4420) | function connectSocket(connectCallback) {
  function beforeJoin (line 4726) | function beforeJoin(userPreferences, callback) {
  function beforeUnload (line 4869) | function beforeUnload(shiftModerationControlOnLeave, dontCloseSocket) {
  function gumCallback (line 5325) | function gumCallback(stream) {
  function applyConstraints (line 5375) | function applyConstraints(stream, mediaConstraints) {
  function replaceTrack (line 5416) | function replaceTrack(track, remoteUserId, isVideoTrack) {
  function gumCallback (line 5492) | function gumCallback(stream) {
  function keepNextBroadcasterOnServer (line 5627) | function keepNextBroadcasterOnServer() {

FILE: RTCMultiConnection-SignalR/RTCMultiConnection/Scripts/jquery-1.10.2.js
  function isArraylike (line 997) | function isArraylike( obj ) {
  function Sizzle (line 1197) | function Sizzle( selector, context, results, seed ) {
  function createCache (line 1312) | function createCache() {
  function markFunction (line 1330) | function markFunction( fn ) {
  function assert (line 1339) | function assert( fn ) {
  function addHandle (line 1361) | function addHandle( attrs, handler ) {
  function siblingCheck (line 1376) | function siblingCheck( a, b ) {
  function createInputPseudo (line 1403) | function createInputPseudo( type ) {
  function createButtonPseudo (line 1414) | function createButtonPseudo( type ) {
  function createPositionalPseudo (line 1425) | function createPositionalPseudo( fn ) {
  function setFilters (line 2408) | function setFilters() {}
  function tokenize (line 2412) | function tokenize( selector, parseOnly ) {
  function toSelector (line 2479) | function toSelector( tokens ) {
  function addCombinator (line 2489) | function addCombinator( matcher, combinator, base ) {
  function elementMatcher (line 2539) | function elementMatcher( matchers ) {
  function condense (line 2553) | function condense( unmatched, map, filter, context, xml ) {
  function setMatcher (line 2574) | function setMatcher( preFilter, selector, matcher, postFilter, postFinde...
  function matcherFromTokens (line 2667) | function matcherFromTokens( tokens ) {
  function matcherFromGroupMatchers (line 2722) | function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
  function multipleContexts (line 2850) | function multipleContexts( selector, contexts, results ) {
  function select (line 2859) | function select( selector, context, results, seed ) {
  function createOptions (line 2999) | function createOptions( options ) {
  function internalData (line 3582) | function internalData( elem, name, data, pvt /* Internal Use Only */ ){
  function internalRemoveData (line 3671) | function internalRemoveData( elem, name, pvt ) {
  function dataAttr (line 3868) | function dataAttr( elem, key, data ) {
  function isEmptyDataObject (line 3900) | function isEmptyDataObject( obj ) {
  function returnTrue (line 4726) | function returnTrue() {
  function returnFalse (line 4730) | function returnFalse() {
  function safeActiveElement (line 4734) | function safeActiveElement() {
  function sibling (line 5852) | function sibling( cur, dir ) {
  function winnow (line 5970) | function winnow( elements, qualifier, not ) {
  function createSafeFragment (line 5998) | function createSafeFragment( document ) {
  function manipulationTarget (line 6312) | function manipulationTarget( elem, content ) {
  function disableScript (line 6322) | function disableScript( elem ) {
  function restoreScript (line 6326) | function restoreScript( elem ) {
  function setGlobalEval (line 6337) | function setGlobalEval( elems, refElements ) {
  function cloneCopyEvent (line 6345) | function cloneCopyEvent( src, dest ) {
  function fixCloneNodeIssues (line 6373) | function fixCloneNodeIssues( src, dest ) {
  function getAll (line 6466) | function getAll( context, tag ) {
  function fixDefaultChecked (line 6489) | function fixDefaultChecked( elem ) {
  function vendorPropName (line 6831) | function vendorPropName( style, name ) {
  function isHidden (line 6853) | function isHidden( elem, el ) {
  function showHide (line 6860) | function showHide( elements, show ) {
  function setPositiveNumber (line 7189) | function setPositiveNumber( elem, value, subtract ) {
  function augmentWidthOrHeight (line 7197) | function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
  function getWidthOrHeight (line 7236) | function getWidthOrHeight( elem, name, extra ) {
  function css_defaultDisplay (line 7280) | function css_defaultDisplay( nodeName ) {
  function actualDisplay (line 7312) | function actualDisplay( name, doc ) {
  function buildParams (line 7541) | function buildParams( prefix, obj, traditional, add ) {
  function addToPrefiltersOrTransports (line 7656) | function addToPrefiltersOrTransports( structure ) {
  function inspectPrefiltersOrTransports (line 7688) | function inspectPrefiltersOrTransports( structure, options, originalOpti...
  function ajaxExtend (line 7715) | function ajaxExtend( target, src ) {
  function done (line 8163) | function done( status, nativeStatusText, responses, headers ) {
  function ajaxHandleResponses (line 8310) | function ajaxHandleResponses( s, jqXHR, responses ) {
  function ajaxConvert (line 8365) | function ajaxConvert( s, response, jqXHR, isSuccess ) {
  function createStandardXHR (line 8633) | function createStandardXHR() {
  function createActiveXHR (line 8639) | function createActiveXHR() {
  function createFxNow (line 8885) | function createFxNow() {
  function createTween (line 8892) | function createTween( value, prop, animation ) {
  function Animation (line 8906) | function Animation( elem, properties, options ) {
  function propFilter (line 9010) | function propFilter( props, specialEasing ) {
  function defaultPrefilter (line 9077) | function defaultPrefilter( elem, props, opts ) {
  function Tween (line 9202) | function Tween( elem, options, prop, end, easing ) {
  function genFx (line 9426) | function genFx( type, includeWidth ) {
  function getWindow (line 9722) | function getWindow( elem ) {

FILE: RTCMultiConnection-SignalR/RTCMultiConnection/Scripts/jquery.signalR-2.1.2.js
  function validateTransport (line 268) | function validateTransport(requestedTransport, connection) {
  function getDefaultPort (line 301) | function getDefaultPort(protocol) {
  function addDefaultPort (line 309) | function addDefaultPort(protocol, url) {
  function ConnectingMessageBuffer (line 319) | function ConnectingMessageBuffer(connection, drainCallback) {
  function beat (line 1027) | function beat(connection) {
  function checkIfAlive (line 1040) | function checkIfAlive(connection) {
  function getAjaxUrl (line 1067) | function getAjaxUrl(connection, path) {
  function makeEventName (line 2419) | function makeEventName(event) {
  function map (line 2424) | function map(arr, fun, thisp) {
  function getArgValue (line 2436) | function getArgValue(a) {
  function hasMembers (line 2440) | function hasMembers(obj) {
  function clearInvocationCallbacks (line 2451) | function clearInvocationCallbacks(connection, error) {
  function hubProxy (line 2476) | function hubProxy(hubConnection, hubName) {
  function hubConnection (line 2640) | function hubConnection(url, options) {

FILE: RTCMultiConnection-SignalR/RTCMultiConnection/SignalRConnection.js
  function SignalRConnection (line 1) | function SignalRConnection(connection, connectCallback) {

FILE: RTCMultiConnection/admin/admin-ui.js
  function connectSocket (line 32) | function connectSocket(username, password) {
  function updateListOfUsers (line 89) | function updateListOfUsers(listOfUsers) {
  function updateListOfRooms (line 167) | function updateListOfRooms(rooms) {
  function updateViewLogsButton (line 233) | function updateViewLogsButton() {
  function getUserInfo (line 319) | function getUserInfo(userid, callback) {
  function alertBox (line 399) | function alertBox(message, title, specialMessage, callback) {
  function confirmBox (line 421) | function confirmBox(message, callback) {

FILE: RTCMultiConnection/demos/SSEConnection/enableCORS.php
  function enableCORS (line 6) | function enableCORS()

FILE: RTCMultiConnection/demos/SSEConnection/get-param.php
  function getParam (line 6) | function getParam($id)

FILE: RTCMultiConnection/demos/SSEConnection/write-json.php
  function writeJSON (line 8) | function writeJSON($json, $receiver, $sender)
  function removeJSON (line 55) | function removeJSON($receiver, $sender)

FILE: RTCMultiConnection/dev/BandwidthHandler.js
  function setBAS (line 13) | function setBAS(sdp, bandwidth, isScreen) {
  function findLine (line 58) | function findLine(sdpLines, prefix, substr) {
  function findLineInRange (line 64) | function findLineInRange(sdpLines, startLine, endLine, prefix, substr) {
  function getCodecPayloadType (line 78) | function getCodecPayloadType(sdpLine) {
  function setVideoBitrates (line 84) | function setVideoBitrates(sdp, params) {
  function setOpusAttributes (line 127) | function setOpusAttributes(sdp, params) {

FILE: RTCMultiConnection/dev/BluetoothConnection.js
  function BluetoothConnection (line 1) | function BluetoothConnection(connection, connectCallback) {

FILE: RTCMultiConnection/dev/CodecsHandler.js
  function preferCodec (line 5) | function preferCodec(sdp, codecName) {
  function preferCodecHelper (line 29) | function preferCodecHelper(sdp, codec, info, ignore) {
  function splitLines (line 73) | function splitLines(sdp) {
  function removeVPX (line 102) | function removeVPX(sdp) {
  function disableNACK (line 112) | function disableNACK(sdp) {
  function prioritize (line 125) | function prioritize(codecMimeType, peer) {
  function removeNonG722 (line 146) | function removeNonG722(sdp) {
  function setBAS (line 150) | function setBAS(sdp, bandwidth, isScreen) {
  function findLine (line 193) | function findLine(sdpLines, prefix, substr) {
  function findLineInRange (line 199) | function findLineInRange(sdpLines, startLine, endLine, prefix, substr) {
  function getCodecPayloadType (line 213) | function getCodecPayloadType(sdpLine) {
  function setVideoBitrates (line 219) | function setVideoBitrates(sdp, params) {
  function setOpusAttributes (line 258) | function setOpusAttributes(sdp, params) {
  function forceStereoAudio (line 315) | function forceStereoAudio(sdp) {

FILE: RTCMultiConnection/dev/FileProgressBarHandler.js
  function handle (line 4) | function handle(connection) {

FILE: RTCMultiConnection/dev/FileSelector.js
  function FileSelector (line 1) | function FileSelector() {

FILE: RTCMultiConnection/dev/FirebaseConnection.js
  function FirebaseConnection (line 1) | function FirebaseConnection(connection, connectCallback) {

FILE: RTCMultiConnection/dev/IceServersHandler.js
  function getIceServers (line 4) | function getIceServers(connection) {

FILE: RTCMultiConnection/dev/MediaStreamRecorder.js
  function MediaStreamRecorder (line 18) | function MediaStreamRecorder(mediaStream) {
  function MultiStreamRecorder (line 145) | function MultiStreamRecorder(arrayOfMediaStreams, options) {
  function MultiStreamsMixer (line 321) | function MultiStreamsMixer(arrayOfMediaStreams) {
  function mergeProps (line 907) | function mergeProps(mergein, mergeto) {
  function dropFirstFrame (line 919) | function dropFirstFrame(arr) {
  function invokeSaveAsDialog (line 931) | function invokeSaveAsDialog(file, fileName) {
  function bytesToSize (line 983) | function bytesToSize(bytes) {
  function isMediaRecorderCompatible (line 999) | function isMediaRecorderCompatible() {
  function MediaRecorderWrapper (line 1056) | function MediaRecorderWrapper(mediaStream) {
  function StereoAudioRecorder (line 1375) | function StereoAudioRecorder(mediaStream) {
  function StereoAudioRecorderHelper (line 1431) | function StereoAudioRecorderHelper(mediaStream, root) {
  function WhammyRecorder (line 1695) | function WhammyRecorder(mediaStream) {
  function WhammyRecorderHelper (line 1762) | function WhammyRecorderHelper(mediaStream, root) {
  function GifRecorder (line 2066) | function GifRecorder(mediaStream) {
  function WhammyVideo (line 2228) | function WhammyVideo(duration, quality) {
  function processInWebWorker (line 2265) | function processInWebWorker(_function) {
  function whammyInWebWorker (line 2277) | function whammyInWebWorker(frames) {
  function readAsArrayBuffer (line 2665) | function readAsArrayBuffer() {
  function concatenateBuffers (line 2680) | function concatenateBuffers() {

FILE: RTCMultiConnection/dev/MultiPeersHandler.js
  function MultiPeers (line 1) | function MultiPeers(connection) {

FILE: RTCMultiConnection/dev/MultiStreamsMixer.js
  function MultiStreamsMixer (line 13) | function MultiStreamsMixer(arrayOfMediaStreams) {

FILE: RTCMultiConnection/dev/OnIceCandidateHandler.js
  function processCandidates (line 4) | function processCandidates(connection, icePair) {

FILE: RTCMultiConnection/dev/Plugin.EveryWhere.js
  function LoadPluginRTC (line 31) | function LoadPluginRTC() {

FILE: RTCMultiConnection/dev/PubNubConnection.js
  function PubNubConnection (line 1) | function PubNubConnection(connection, connectCallback) {

FILE: RTCMultiConnection/dev/RTCMultiConnection.js
  function onUserLeft (line 139) | function onUserLeft(remoteUserId) {
  function connectSocket (line 158) | function connectSocket(connectCallback) {
  function joinRoom (line 397) | function joinRoom(connectionDescription, cb) {
  function openRoom (line 437) | function openRoom(callback) {
  function getStreamInfoForAdmin (line 470) | function getStreamInfoForAdmin() {
  function beforeJoin (line 483) | function beforeJoin(userPreferences, callback) {
  function gumCallback (line 1052) | function gumCallback(stream) {
  function applyConstraints (line 1102) | function applyConstraints(stream, mediaConstraints) {
  function replaceTrack (line 1143) | function replaceTrack(track, remoteUserId, isVideoTrack) {
  function gumCallback (line 1213) | function gumCallback(stream) {

FILE: RTCMultiConnection/dev/RTCPeerConnection.js
  function setSdpConstraints (line 5) | function setSdpConstraints(config) {
  function PeerInitiator (line 27) | function PeerInitiator(config) {

FILE: RTCMultiConnection/dev/RecordingHandler.js
  function record (line 6) | function record(stream) {
  function stop (line 12) | function stop(stream, callback) {

FILE: RTCMultiConnection/dev/SSEConnection.js
  function SSEConnection (line 4) | function SSEConnection(connection, connectCallback) {

FILE: RTCMultiConnection/dev/SignalRConnection.js
  function SignalRConnection (line 1) | function SignalRConnection(connection, connectCallback) {

FILE: RTCMultiConnection/dev/SipConnection.js
  function SipConnection (line 3) | function SipConnection(connection, connectCallback) {

FILE: RTCMultiConnection/dev/SocketConnection.js
  function SocketConnection (line 1) | function SocketConnection(connection, connectCallback) {

FILE: RTCMultiConnection/dev/StreamHasData.js
  function checkIfStreamHasData (line 4) | function checkIfStreamHasData(mediaElement, successCallback) {

FILE: RTCMultiConnection/dev/StreamsHandler.js
  function handleType (line 4) | function handleType(type) {
  function setHandlers (line 28) | function setHandlers(stream, syncAction, connection) {
  function afterEach (line 140) | function afterEach(setTimeoutInteval, numberOfTimes, callback, startedTi...

FILE: RTCMultiConnection/dev/TextSenderReceiver.js
  function TextReceiver (line 3) | function TextReceiver(connection) {
  function sendText (line 74) | function sendText(textMessage, text) {

FILE: RTCMultiConnection/dev/TranslationHandler.js
  function handle (line 4) | function handle(connection) {

FILE: RTCMultiConnection/dev/WebSocketConnection.js
  function WebSocketConnection (line 1) | function WebSocketConnection(connection, connectCallback) {

FILE: RTCMultiConnection/dev/WebSyncConnection.js
  function WebSyncConnection (line 1) | function WebSyncConnection(connection, connectCallback) {

FILE: RTCMultiConnection/dev/XHRConnection.js
  function XHRConnection (line 1) | function XHRConnection(connection, connectCallback) {

FILE: RTCMultiConnection/dev/enableV2Api.js
  function enableV2Api (line 1) | function enableV2Api(connection) {
  function openSignalingChannel (line 94) | function openSignalingChannel(connection, connectCallback) {

FILE: RTCMultiConnection/dev/getHTMLMediaElement.js
  function getHTMLMediaElement (line 4) | function getHTMLMediaElement(mediaElement, config) {
  function getAudioElement (line 338) | function getAudioElement(mediaElement, config) {

FILE: RTCMultiConnection/dev/getUserMedia.js
  function setStreamType (line 3) | function setStreamType(constraints, stream) {
  function getUserMediaHandler (line 42) | function getUserMediaHandler(options) {

FILE: RTCMultiConnection/dev/globals.js
  function fireEvent (line 13) | function fireEvent(obj, eventName, args) {
  function setHarkEvents (line 27) | function setHarkEvents(connection, streamEvent) {
  function setMuteHandlers (line 61) | function setMuteHandlers(connection, streamEvent) {
  function getRandomString (line 87) | function getRandomString() {
  function getRMCMediaElement (line 103) | function getRMCMediaElement(stream, callback, connection) {
  function listenEventHandler (line 212) | function listenEventHandler(eventName, eventHandler) {
  function removeNullEntries (line 221) | function removeNullEntries(array) {
  function isData (line 232) | function isData(session) {
  function isNull (line 236) | function isNull(obj) {
  function isString (line 240) | function isString(obj) {
  function isAudioPlusTab (line 261) | function isAudioPlusTab(connection, audioPlusTab) {
  function getAudioScreenConstraints (line 284) | function getAudioScreenConstraints(screen_constraints) {
  function getTracks (line 301) | function getTracks(stream, kind) {
  function isUnifiedPlanSupportedDefault (line 311) | function isUnifiedPlanSupportedDefault() {
  function isUnifiedPlanSuppored (line 333) | function isUnifiedPlanSuppored() {

FILE: RTCMultiConnection/dev/gumadapter.js
  function requestUserMedia (line 320) | function requestUserMedia(constraints) {

FILE: RTCMultiConnection/dev/ios-hacks.js
  function setCordovaAPIs (line 3) | function setCordovaAPIs() {

FILE: RTCMultiConnection/dist/RTCMultiConnection.js
  function SocketConnection (line 125) | function SocketConnection(connection, connectCallback) {
  function MultiPeers (line 441) | function MultiPeers(connection) {
  function getBrowserInfo (line 996) | function getBrowserInfo() {
  function retry (line 1099) | function retry(isDone, next) {
  function isIE10OrLater (line 1120) | function isIE10OrLater(userAgent) {
  function detectPrivateMode (line 1132) | function detectPrivateMode(callback) {
  function detectDesktopOS (line 1252) | function detectDesktopOS() {
  function getAndroidVersion (line 1382) | function getAndroidVersion(ua) {
  function DetectLocalIPAddress (line 1429) | function DetectLocalIPAddress(callback, stream) {
  function getIPs (line 1451) | function getIPs(callback, stream) {
  function checkDeviceSupport (line 1598) | function checkDeviceSupport(callback) {
  function getAspectRatio (line 1877) | function getAspectRatio(w, h) {
  function fireEvent (line 2067) | function fireEvent(obj, eventName, args) {
  function setHarkEvents (line 2081) | function setHarkEvents(connection, streamEvent) {
  function setMuteHandlers (line 2115) | function setMuteHandlers(connection, streamEvent) {
  function getRandomString (line 2141) | function getRandomString() {
  function getRMCMediaElement (line 2157) | function getRMCMediaElement(stream, callback, connection) {
  function listenEventHandler (line 2266) | function listenEventHandler(eventName, eventHandler) {
  function removeNullEntries (line 2275) | function removeNullEntries(array) {
  function isData (line 2286) | function isData(session) {
  function isNull (line 2290) | function isNull(obj) {
  function isString (line 2294) | function isString(obj) {
  function isAudioPlusTab (line 2315) | function isAudioPlusTab(connection, audioPlusTab) {
  function getAudioScreenConstraints (line 2338) | function getAudioScreenConstraints(screen_constraints) {
  function getTracks (line 2355) | function getTracks(stream, kind) {
  function isUnifiedPlanSupportedDefault (line 2365) | function isUnifiedPlanSupportedDefault() {
  function isUnifiedPlanSuppored (line 2387) | function isUnifiedPlanSuppored() {
  function setCordovaAPIs (line 2415) | function setCordovaAPIs() {
  function setSdpConstraints (line 2441) | function setSdpConstraints(config) {
  function PeerInitiator (line 2463) | function PeerInitiator(config) {
  function preferCodec (line 2994) | function preferCodec(sdp, codecName) {
  function preferCodecHelper (line 3018) | function preferCodecHelper(sdp, codec, info, ignore) {
  function splitLines (line 3062) | function splitLines(sdp) {
  function removeVPX (line 3091) | function removeVPX(sdp) {
  function disableNACK (line 3101) | function disableNACK(sdp) {
  function prioritize (line 3114) | function prioritize(codecMimeType, peer) {
  function removeNonG722 (line 3135) | function removeNonG722(sdp) {
  function setBAS (line 3139) | function setBAS(sdp, bandwidth, isScreen) {
  function findLine (line 3182) | function findLine(sdpLines, prefix, substr) {
  function findLineInRange (line 3188) | function findLineInRange(sdpLines, startLine, endLine, prefix, substr) {
  function getCodecPayloadType (line 3202) | function getCodecPayloadType(sdpLine) {
  function setVideoBitrates (line 3208) | function setVideoBitrates(sdp, params) {
  function setOpusAttributes (line 3247) | function setOpusAttributes(sdp, params) {
  function forceStereoAudio (line 3304) | function forceStereoAudio(sdp) {
  function processCandidates (line 3356) | function processCandidates(connection, icePair) {
  function getIceServers (line 3412) | function getIceServers(connection) {
  function setStreamType (line 3434) | function setStreamType(constraints, stream) {
  function getUserMediaHandler (line 3473) | function getUserMediaHandler(options) {
  function handleType (line 3610) | function handleType(type) {
  function setHandlers (line 3634) | function setHandlers(stream, syncAction, connection) {
  function afterEach (line 3746) | function afterEach(setTimeoutInteval, numberOfTimes, callback, startedTi...
  function TextReceiver (line 3764) | function TextReceiver(connection) {
  function sendText (line 3835) | function sendText(textMessage, text) {
  function handle (line 3871) | function handle(connection) {
  function handle (line 3970) | function handle(connection) {
  function onUserLeft (line 4183) | function onUserLeft(remoteUserId) {
  function connectSocket (line 4202) | function connectSocket(connectCallback) {
  function joinRoom (line 4441) | function joinRoom(connectionDescription, cb) {
  function openRoom (line 4481) | function openRoom(callback) {
  function getStreamInfoForAdmin (line 4514) | function getStreamInfoForAdmin() {
  function beforeJoin (line 4527) | function beforeJoin(userPreferences, callback) {
  function gumCallback (line 5096) | function gumCallback(stream) {
  function applyConstraints (line 5146) | function applyConstraints(stream, mediaConstraints) {
  function replaceTrack (line 5187) | function replaceTrack(track, remoteUserId, isVideoTrack) {
  function gumCallback (line 5257) | function gumCallback(stream) {

FILE: RTCMultiConnection/server.js
  constant BASH_COLORS_HELPER (line 20) | const BASH_COLORS_HELPER = RTCMultiConnectionServer.BASH_COLORS_HELPER;
  function serverHandler (line 37) | function serverHandler(request, response) {

FILE: RTCPeerConnection/RTCPeerConnection-Helpers.js
  function preferOpus (line 14) | function preferOpus() {
  function extractSdp (line 44) | function extractSdp(sdpLine, pattern) {
  function setDefaultCodec (line 50) | function setDefaultCodec(mLine, payload) {
  function removeCN (line 64) | function removeCN(sdpLines, mLineIndex) {

FILE: RTCPeerConnection/RTCPeerConnection-v1.1.js
  function onicecandidate (line 23) | function onicecandidate(event) {
  function onaddstream (line 28) | function onaddstream(event) {
  function createOffer (line 32) | function createOffer() {
  function createAnswer (line 48) | function createAnswer() {
  function getUserMedia (line 84) | function getUserMedia(options) {

FILE: RTCPeerConnection/RTCPeerConnection-v1.2.js
  function onicecandidate (line 29) | function onicecandidate(event) {
  function onaddstream (line 34) | function onaddstream(event) {
  function createOffer (line 38) | function createOffer() {
  function createAnswer (line 54) | function createAnswer() {
  function openDataChannel (line 72) | function openDataChannel() {
  function getUserMedia (line 130) | function getUserMedia(options) {

FILE: RTCPeerConnection/RTCPeerConnection-v1.3.js
  function onicecandidate (line 27) | function onicecandidate(event) {
  function onaddstream (line 32) | function onaddstream(event) {
  function createOffer (line 36) | function createOffer() {
  function createAnswer (line 45) | function createAnswer() {
  function openOffererChannel (line 67) | function openOffererChannel() {
  function _openOffererChannel (line 81) | function _openOffererChannel() {
  function setChannelEvents (line 86) | function setChannelEvents() {
  function openAnswererChannel (line 105) | function openAnswererChannel() {
  function useless (line 120) | function useless() { }
  function getUserMedia (line 155) | function getUserMedia(options) {

FILE: RTCPeerConnection/RTCPeerConnection-v1.4.js
  function onicecandidate (line 62) | function onicecandidate(event) {
  function onaddstream (line 71) | function onaddstream(event) {
  function getChars (line 89) | function getChars() {
  function createOffer (line 98) | function createOffer() {
  function createAnswer (line 107) | function createAnswer() {
  function openOffererChannel (line 131) | function openOffererChannel() {
  function _openOffererChannel (line 148) | function _openOffererChannel() {
  function setChannelEvents (line 157) | function setChannelEvents() {
  function openAnswererChannel (line 176) | function openAnswererChannel() {
  function useless (line 194) | function useless() {
  function info (line 197) | function info(information) {
  function getPorts (line 201) | function getPorts(ports) {
  function getUserMedia (line 251) | function getUserMedia(options) {

FILE: RTCPeerConnection/RTCPeerConnection-v1.5.js
  function createOffer (line 112) | function createOffer() {
  function createAnswer (line 125) | function createAnswer() {
  function openOffererChannel (line 149) | function openOffererChannel() {
  function _openOffererChannel (line 156) | function _openOffererChannel() {
  function setChannelEvents (line 164) | function setChannelEvents() {
  function openAnswererChannel (line 188) | function openAnswererChannel() {
  function useless (line 197) | function useless() {
  function onSdpSuccess (line 201) | function onSdpSuccess() {
  function onSdpError (line 204) | function onSdpError(e) {
  function getUserMedia (line 242) | function getUserMedia(options) {
  function getIceServers (line 268) | function getIceServers(connection) {

FILE: RTCPeerConnection/RTCPeerConnection-v1.6.js
  function RTCPeerConnection (line 10) | function RTCPeerConnection(options) {
  function getUserMedia (line 289) | function getUserMedia(options) {

FILE: RTCPeerConnection/RTCPeerConnection.js
  function onicecandidate (line 23) | function onicecandidate(event) {
  function onaddstream (line 28) | function onaddstream(event) {
  function createOffer (line 32) | function createOffer() {
  function createAnswer (line 48) | function createAnswer() {
  function getUserMedia (line 84) | function getUserMedia(options) {

FILE: RTCall/RTCall.js
  function setupSignalingChannel (line 46) | function setupSignalingChannel() {
  function waitForResponse (line 144) | function waitForResponse(callerid) {
  function onRemoteStream (line 202) | function onRemoteStream(stream) {
  function onaddstream (line 272) | function onaddstream(event) {
  function createOffer (line 285) | function createOffer() {
  function createAnswer (line 294) | function createAnswer() {
  function onSdpError (line 307) | function onSdpError(e) {
  function onSdpSuccess (line 311) | function onSdpSuccess() {
  function streaming (line 336) | function streaming(stream) {
  function onerror (line 345) | function onerror(e) {

FILE: Record-Entire-Meeting/Browser-Recording-Helper.js
  function initRecorder (line 12) | function initRecorder(mediaStream, video) {
  function onDataAvailable (line 46) | function onDataAvailable(blob) {
  function postFiles (line 60) | function postFiles(data) {
  function generatefileNameString (line 124) | function generatefileNameString() {
  function getDataURL (line 135) | function getDataURL(blob, callback) {
  function processInWebWorker (line 157) | function processInWebWorker(_function) {

FILE: Record-Entire-Meeting/Concatenate-Recordings.js
  function concatenateInLinuxOrMac (line 18) | function concatenateInLinuxOrMac(files) {
  function unlink_merged_files (line 79) | function unlink_merged_files(fileName, lastIndex, index) {

FILE: Record-Entire-Meeting/MediaStreamRecorder.js
  function MediaStreamRecorder (line 16) | function MediaStreamRecorder(mediaStream) {
  function bytesToSize (line 156) | function bytesToSize(bytes) {

FILE: Record-Entire-Meeting/Nodejs-Recording-Handler.js
  function SocketExtender (line 16) | function SocketExtender(socket) {
  function createNewDir (line 91) | function createNewDir(path, data, onGettingRecordedMessages, callback) {

FILE: Record-Entire-Meeting/Write-Recordings-To-Disk.js
  function writeToDisk (line 13) | function writeToDisk(file) {
  function writeToDiskInternal (line 20) | function writeToDiskInternal(file, callback) {

FILE: Record-Entire-Meeting/server.js
  function serverHandler (line 12) | function serverHandler(request, response) {

FILE: RecordRTC/Canvas-Recording/canvas-designer.js
  function addEvent (line 35) | function addEvent(element, eventType, callback) {
  function find (line 55) | function find(selector) {
  function getContext (line 70) | function getContext(id) {
  function drawArrow (line 504) | function drawArrow(mx, my, lx, ly, options) {
  function endLastPath (line 560) | function endLastPath() {
  function copy (line 579) | function copy() {
  function paste (line 593) | function paste() {
  function hexToR (line 618) | function hexToR(h) {
  function hexToG (line 622) | function hexToG(h) {
  function hexToB (line 626) | function hexToB(h) {
  function cutHex (line 630) | function cutHex(h) {
  function clone (line 634) | function clone(obj) {
  function hexToRGB (line 654) | function hexToRGB(h) {
  function selectFile (line 2314) | function selectFile(callback, multiple) {
  function fireClickEvent (line 2348) | function fireClickEvent(element) {
  function setSelection (line 2430) | function setSelection(element, prop) {
  function getContext (line 2475) | function getContext(id) {
  function bindEvent (line 2482) | function bindEvent(context, shape) {
  function decorateDragLastPath (line 2565) | function decorateDragLastPath() {
  function decorateDragAllPaths (line 2605) | function decorateDragAllPaths() {
  function decorateLine (line 2645) | function decorateLine() {
  function decorateArrow (line 2663) | function decorateArrow() {
  function decoreZoomUp (line 2695) | function decoreZoomUp() {
  function decoreZoomDown (line 2703) | function decoreZoomDown() {
  function decoratePencil (line 2719) | function decoratePencil() {
  function decorateMarker (line 2827) | function decorateMarker() {
  function decorateEraser (line 2935) | function decorateEraser() {
  function decorateText (line 2955) | function decorateText() {
  function decorateImage (line 2968) | function decorateImage() {
  function decorateArc (line 2983) | function decorateArc() {
  function decorateRect (line 3000) | function decorateRect() {
  function decorateQuadratic (line 3016) | function decorateQuadratic() {
  function decorateBezier (line 3034) | function decorateBezier() {
  function tempStrokeTheLine (line 3056) | function tempStrokeTheLine(context, width, mx, my, lx, ly) {
  function decorateLineWidth (line 3064) | function decorateLineWidth() {
  function decorateColors (line 3100) | function decorateColors() {
  function decorateAdditionalOptions (line 3138) | function decorateAdditionalOptions() {
  function btnDesignerPreviewClicked (line 3203) | function btnDesignerPreviewClicked() {
  function btnCodePreviewClicked (line 3216) | function btnCodePreviewClicked() {
  function setHeightForCodeAndOptionsContainer (line 3232) | function setHeightForCodeAndOptionsContainer() {
  function hideContainers (line 3247) | function hideContainers() {
  function preventStopEvent (line 3294) | function preventStopEvent(e) {
  function onkeydown (line 3362) | function onkeydown(e) {
  function isBackKey (line 3382) | function isBackKey(e, keyCode) {
  function onkeyup (line 3409) | function onkeyup(e) {
  function onkeypress (line 3478) | function onkeypress(e) {
  function onTextFromClipboard (line 3493) | function onTextFromClipboard(e) {
  function syncPoints (line 3611) | function syncPoints(isSyncAll) {
  function syncData (line 3635) | function syncData(data) {

FILE: RecordRTC/RecordRTC-over-Socketio/server.js
  function writeToDisk (line 78) | function writeToDisk(dataURL, fileName) {
  function merge (line 98) | function merge(socket, fileName) {

FILE: RecordRTC/RecordRTC-to-ASPNETMVC/RecordRTC_to_ASPNETMVC/Controllers/RecordRTCController.cs
  class RecordRTCController (line 10) | public class RecordRTCController : Controller
    method Index (line 13) | public ActionResult Index()
    method PostRecordedAudioVideo (line 19) | [HttpPost]
    method DeleteFile (line 34) | [HttpPost]

FILE: RecordRTC/RecordRTC-to-ASPNETMVC/RecordRTC_to_ASPNETMVC/Global.asax.cs
  class MvcApplication (line 13) | public class MvcApplication : System.Web.HttpApplication
    method RegisterGlobalFilters (line 15) | public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    method RegisterRoutes (line 20) | public static void RegisterRoutes(RouteCollection routes)
    method Application_Start (line 32) | protected void Application_Start()

FILE: RecordRTC/RecordRTC-to-Nodejs/server.js
  function serverHandler (line 11) | function serverHandler(request, response) {
  function uploadFile (line 90) | function uploadFile(request, response) {
  function getHeaders (line 122) | function getHeaders(opt, val) {

FILE: RecordRTC/RecordRTC-to-PHP/delete.php
  function selfInvoker (line 8) | function selfInvoker()

FILE: RecordRTC/RecordRTC-to-PHP/save.php
  function someFunction (line 12) | function someFunction($errno, $errstr) {
  function selfInvoker (line 17) | function selfInvoker()

FILE: RecordRTC/RecordRTC.js
  function RecordRTC (line 37) | function RecordRTC(mediaStream, config) {
  function RecordRTCConfiguration (line 923) | function RecordRTCConfiguration(mediaStream, config) {
  function GetRecorderType (line 997) | function GetRecorderType(mediaStream, config) {
  function MRecordRTC (line 1098) | function MRecordRTC(mediaStream) {
  function bytesToSize (line 1789) | function bytesToSize(bytes) {
  function invokeSaveAsDialog (line 1806) | function invokeSaveAsDialog(file, fileName) {
  function isElectron (line 1857) | function isElectron() {
  function getTracks (line 1876) | function getTracks(stream, kind) {
  function setSrcObject (line 1886) | function setSrcObject(stream, element) {
  function getSeekableBlob (line 1903) | function getSeekableBlob(inputBlob, callback) {
  function isMediaRecorderCompatible (line 1964) | function isMediaRecorderCompatible() {
  function MediaStreamRecorder (line 2033) | function MediaStreamRecorder(mediaStream, config) {
  function StereoAudioRecorder (line 2525) | function StereoAudioRecorder(mediaStream, config) {
  function CanvasRecorder (line 3239) | function CanvasRecorder(htmlElement, config) {
  function WhammyRecorder (line 3577) | function WhammyRecorder(mediaStream, config) {
  function WhammyVideo (line 3959) | function WhammyVideo(duration) {
  function processInWebWorker (line 3993) | function processInWebWorker(_function) {
  function whammyInWebWorker (line 4005) | function whammyInWebWorker(frames) {
  function createObjectStore (line 4424) | function createObjectStore(dataBase) {
  function putInDB (line 4428) | function putInDB() {
  function GifRecorder (line 4568) | function GifRecorder(mediaStream, config) {
  function MultiStreamsMixer (line 4847) | function MultiStreamsMixer(arrayOfMediaStreams, elementClass) {
  function MultiStreamRecorder (line 5444) | function MultiStreamRecorder(arrayOfMediaStreams, options) {
  function RecordRTCPromisesHandler (line 5680) | function RecordRTCPromisesHandler(mediaStream, options) {
  function WebAssemblyRecorder (line 5954) | function WebAssemblyRecorder(stream, config) {

FILE: RecordRTC/WebGL-Recording/vendor/buzz.js
  function doFade (line 499) | function doFade() {
  function timerangeToArray (line 565) | function timerangeToArray( timeRange ) {
  function getExt (line 578) | function getExt( filename ) {
  function addSource (line 582) | function addSource( sound, src ) {
  function fn (line 783) | function fn() {
  function argsToArray (line 792) | function argsToArray( array, args ) {

FILE: RecordRTC/WebGL-Recording/vendor/glge-compiled-min.js
  function c (line 28) | function c(){var b=a.Vec([1,2,3,4]),c=a.Vec4(a.getVec4(b,3),a.get1basedV...
  function c (line 28) | function c(a,b){var d=null;if(a.getAttribute("id")==b)return a;for(var e...
  function L (line 28) | function L(a,b){return a>b?b:a}
  function j (line 28) | function j(a){var b="";for(var c=a.length-1;c>=0;--c)a[c]>="0"&&a[c]<="9...

FILE: RecordRTC/WebGL-Recording/vendor/glge-compiled.js
  function GLGE_mathUnitTest (line 1322) | function GLGE_mathUnitTest() {
  function min (line 17602) | function min(a,b){
  function getChildElementById (line 17785) | function getChildElementById( dNode, id ) {
  function getLastNumber (line 18122) | function getLastNumber(str){

FILE: RecordRTC/WebGL-Recording/vendor/underscore-min.js
  function r (line 8) | function r(a,c,d){if(a===c)return a!==0||1/a==1/c;if(a==null||c==null)re...

FILE: RecordRTC/WebGL-Recording/view.js
  function onComplete (line 68) | function onComplete() {
  function createDuckie (line 115) | function createDuckie(model, animation) {
  function init (line 138) | function init() {
  function recordCanvasUsingRecordRTC (line 325) | function recordCanvasUsingRecordRTC(canvas) {

FILE: RecordRTC/dev/CanvasRecorder.js
  function CanvasRecorder (line 22) | function CanvasRecorder(htmlElement, config) {

FILE: RecordRTC/dev/Cross-Browser-Declarations.js
  function bytesToSize (line 127) | function bytesToSize(bytes) {
  function invokeSaveAsDialog (line 144) | function invokeSaveAsDialog(file, fileName) {
  function isElectron (line 195) | function isElectron() {
  function getTracks (line 214) | function getTracks(stream, kind) {
  function setSrcObject (line 224) | function setSrcObject(stream, element) {
  function getSeekableBlob (line 241) | function getSeekableBlob(inputBlob, callback) {

FILE: RecordRTC/dev/DiskStorage.js
  function createObjectStore (line 53) | function createObjectStore(dataBase) {
  function putInDB (line 57) | function putInDB() {

FILE: RecordRTC/dev/GetRecorderType.js
  function GetRecorderType (line 19) | function GetRecorderType(mediaStream, config) {

FILE: RecordRTC/dev/GifRecorder.js
  function GifRecorder (line 21) | function GifRecorder(mediaStream, config) {

FILE: RecordRTC/dev/MRecordRTC.js
  function MRecordRTC (line 32) | function MRecordRTC(mediaStream) {

FILE: RecordRTC/dev/MediaStreamRecorder.js
  function MediaStreamRecorder (line 35) | function MediaStreamRecorder(mediaStream, config) {

FILE: RecordRTC/dev/MultiStreamRecorder.js
  function MultiStreamRecorder (line 32) | function MultiStreamRecorder(arrayOfMediaStreams, options) {

FILE: RecordRTC/dev/MultiStreamsMixer.js
  function MultiStreamsMixer (line 13) | function MultiStreamsMixer(arrayOfMediaStreams, elementClass) {

FILE: RecordRTC/dev/RecordRTC-Configuration.js
  function RecordRTCConfiguration (line 18) | function RecordRTCConfiguration(mediaStream, config) {

FILE: RecordRTC/dev/RecordRTC.js
  function RecordRTC (line 23) | function RecordRTC(mediaStream, config) {

FILE: RecordRTC/dev/RecordRTC.promises.js
  function RecordRTCPromisesHandler (line 26) | function RecordRTCPromisesHandler(mediaStream, options) {

FILE: RecordRTC/dev/StereoAudioRecorder.js
  function StereoAudioRecorder (line 27) | function StereoAudioRecorder(mediaStream, config) {

FILE: RecordRTC/dev/WebAssemblyRecorder.js
  function WebAssemblyRecorder (line 21) | function WebAssemblyRecorder(stream, config) {

FILE: RecordRTC/dev/Whammy.js
  function WhammyVideo (line 26) | function WhammyVideo(duration) {
  function processInWebWorker (line 60) | function processInWebWorker(_function) {
  function whammyInWebWorker (line 72) | function whammyInWebWorker(frames) {

FILE: RecordRTC/dev/WhammyRecorder.js
  function WhammyRecorder (line 22) | function WhammyRecorder(mediaStream, config) {

FILE: RecordRTC/dev/isMediaRecorderCompatible.js
  function isMediaRecorderCompatible (line 1) | function isMediaRecorderCompatible() {

FILE: RecordRTC/libs/EBML.js
  function r (line 1) | function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==...
  function EBMLDecoder (line 17) | function EBMLDecoder() {
  function EBMLEncoder (line 252) | function EBMLEncoder() {
  function __ (line 379) | function __() { this.constructor = d; }
  function EBMLReader (line 393) | function EBMLReader() {
  function readBlock (line 755) | function readBlock(buf) {
  function encodeTag (line 762) | function encodeTag(tagId, tagData, unknownSize) {
  function WebPFrameFilter (line 776) | function WebPFrameFilter(elms) {
  function WebPBlockFilter (line 791) | function WebPBlockFilter(elms) {
  function VP8BitStreamToRiffWebPBuffer (line 816) | function VP8BitStreamToRiffWebPBuffer(frame) {
  function createRIFFChunk (line 828) | function createRIFFChunk(FourCC, chunk) {
  function makeMetadataSeekable (line 941) | function makeMetadataSeekable(originalMetadata, duration, cuesInfo) {
  function removeElement (line 1082) | function removeElement(idName, metadata) {
  function extractElement (line 1116) | function extractElement(idName, metadata) {
  function putRefinedMetaData (line 1154) | function putRefinedMetaData(metadata, info) {
  function encodedSizeOfEbml (line 1218) | function encodedSizeOfEbml(refinedMetaData) {
  function refineMetadata (line 1222) | function refineMetadata(mesetadata, sizeDiff, info) {
  function create_seekhead (line 1258) | function create_seekhead(metadata, sizeDiff) {
  function create_seek_from_clusters (line 1283) | function create_seek_from_clusters(clusterPtrs, sizeDiff) {
  function create_cue (line 1294) | function create_cue(cueInfos, sizeDiff) {
  function insertTag (line 1308) | function insertTag(_metadata, tagName, children, insertHead) {
  function concat (line 1335) | function concat(list) {
  function encodeValueToBuffer (line 1352) | function encodeValueToBuffer(elm) {
  function createUIntBuffer (line 1383) | function createUIntBuffer(value) {
  function createIntBuffer (line 1397) | function createIntBuffer(value) {
  function createFloatBuffer (line 1411) | function createFloatBuffer(value, bytes) {
  function convertEBMLDateToJSDate (line 1432) | function convertEBMLDateToJSDate(int64str) {
  function getLens (line 1462) | function getLens (b64) {
  function byteLength (line 1482) | function byteLength (b64) {
  function _byteLength (line 1489) | function _byteLength (b64, validLen, placeHoldersLen) {
  function toByteArray (line 1493) | function toByteArray (b64) {
  function tripletToBase64 (line 1538) | function tripletToBase64 (num) {
  function encodeChunk (line 1545) | function encodeChunk (uint8, start, end) {
  function fromByteArray (line 1558) | function fromByteArray (uint8) {
  function typedArraySupport (line 1646) | function typedArraySupport () {
  function kMaxLength (line 1658) | function kMaxLength () {
  function createBuffer (line 1664) | function createBuffer (that, length) {
  function Buffer (line 1693) | function Buffer (arg, encodingOrOffset, length) {
  function from (line 1718) | function from (that, value, encodingOrOffset, length) {
  function assertSize (line 1759) | function assertSize (size) {
  function alloc (line 1767) | function alloc (that, size, fill, encoding) {
  function allocUnsafe (line 1791) | function allocUnsafe (that, size) {
  function fromString (line 1815) | function fromString (that, string, encoding) {
  function fromArrayLike (line 1839) | function fromArrayLike (that, array) {
  function fromArrayBuffer (line 1848) | function fromArrayBuffer (that, array, byteOffset, length) {
  function fromObject (line 1878) | function fromObject (that, obj) {
  function checked (line 1908) | function checked (length) {
  function SlowBuffer (line 1918) | function SlowBuffer (length) {
  function byteLength (line 2001) | function byteLength (string, encoding) {
  function slowToString (line 2046) | function slowToString (encoding, start, end) {
  function swap (line 2120) | function swap (b, n, m) {
  function bidirectionalIndexOf (line 2254) | function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
  function arrayIndexOf (line 2311) | function arrayIndexOf (arr, val, byteOffset, encoding, dir) {
  function hexWrite (line 2379) | function hexWrite (buf, string, offset, length) {
  function utf8Write (line 2406) | function utf8Write (buf, string, offset, length) {
  function asciiWrite (line 2410) | function asciiWrite (buf, string, offset, length) {
  function latin1Write (line 2414) | function latin1Write (buf, string, offset, length) {
  function base64Write (line 2418) | function base64Write (buf, string, offset, length) {
  function ucs2Write (line 2422) | function ucs2Write (buf, string, offset, length) {
  function base64Slice (line 2505) | function base64Slice (buf, start, end) {
  function utf8Slice (line 2513) | function utf8Slice (buf, start, end) {
  function decodeCodePointsArray (line 2591) | function decodeCodePointsArray (codePoints) {
  function asciiSlice (line 2609) | function asciiSlice (buf, start, end) {
  function latin1Slice (line 2619) | function latin1Slice (buf, start, end) {
  function hexSlice (line 2629) | function hexSlice (buf, start, end) {
  function utf16leSlice (line 2642) | function utf16leSlice (buf, start, end) {
  function checkOffset (line 2690) | function checkOffset (offset, ext, length) {
  function checkInt (line 2851) | function checkInt (buf, value, offset, ext, max, min) {
  function objectWriteUInt16 (line 2904) | function objectWriteUInt16 (buf, value, offset, littleEndian) {
  function objectWriteUInt32 (line 2938) | function objectWriteUInt32 (buf, value, offset, littleEndian) {
  function checkIEEE754 (line 3088) | function checkIEEE754 (buf, value, offset, ext, max, min) {
  function writeFloat (line 3093) | function writeFloat (buf, value, offset, littleEndian, noAssert) {
  function writeDouble (line 3109) | function writeDouble (buf, value, offset, littleEndian, noAssert) {
  function base64clean (line 3242) | function base64clean (str) {
  function stringtrim (line 3254) | function stringtrim (str) {
  function toHex (line 3259) | function toHex (n) {
  function utf8ToBytes (line 3264) | function utf8ToBytes (string, units) {
  function asciiToBytes (line 3344) | function asciiToBytes (str) {
  function utf16leToBytes (line 3353) | function utf16leToBytes (str, units) {
  function base64ToBytes (line 3369) | function base64ToBytes (str) {
  function blitBuffer (line 3373) | function blitBuffer (src, dst, offset, length) {
  function isnan (line 3381) | function isnan (val) {
  function typedArraySupport (line 3431) | function typedArraySupport () {
  function createBuffer (line 3458) | function createBuffer (length) {
  function Buffer (line 3478) | function Buffer (arg, encodingOrOffset, length) {
  function from (line 3504) | function from (value, encodingOrOffset, length) {
  function assertSize (line 3569) | function assertSize (size) {
  function alloc (line 3577) | function alloc (size, fill, encoding) {
  function allocUnsafe (line 3601) | function allocUnsafe (size) {
  function fromString (line 3619) | function fromString (string, encoding) {
  function fromArrayLike (line 3643) | function fromArrayLike (array) {
  function fromArrayBuffer (line 3652) | function fromArrayBuffer (array, byteOffset, length) {
  function fromObject (line 3675) | function fromObject (obj) {
  function checked (line 3700) | function checked (length) {
  function SlowBuffer (line 3710) | function SlowBuffer (length) {
  function byteLength (line 3801) | function byteLength (string, encoding) {
  function slowToString (line 3850) | function slowToString (encoding, start, end) {
  function swap (line 3928) | function swap (b, n, m) {
  function bidirectionalIndexOf (line 4068) | function bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {
  function arrayIndexOf (line 4124) | function arrayIndexOf (arr, val, byteOffset, encoding, dir) {
  function hexWrite (line 4192) | function hexWrite (buf, string, offset, length) {
  function utf8Write (line 4217) | function utf8Write (buf, string, offset, length) {
  function asciiWrite (line 4221) | function asciiWrite (buf, string, offset, length) {
  function latin1Write (line 4225) | function latin1Write (buf, string, offset, length) {
  function base64Write (line 4229) | function base64Write (buf, string, offset, length) {
  function ucs2Write (line 4233) | function ucs2Write (buf, 
Copy disabled (too large) Download .json
Condensed preview — 981 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (16,678K chars).
[
  {
    "path": ".gitignore",
    "chars": 162,
    "preview": "RecordRTC/RecordRTC-to-Nodejs/uploads/\n*.DS_Store\nffmpeg/ffmpeg_asm.js\nnode_modules\nRecordRTC/node_modules\nDetectRTC/nod"
  },
  {
    "path": "Canvas-Designer/.gitignore",
    "chars": 164,
    "preview": "node_modules\r\nbower_components\r\n\r\n*.tar.gz\r\nlib-cov\r\n\r\n.*.swp\r\n._*\r\n.DS_Store\r\n.git\r\n.hg\r\n.npmrc\r\n.lock-wscript\r\n.svn\r\n."
  },
  {
    "path": "Canvas-Designer/.npmignore",
    "chars": 209,
    "preview": "# ignore everything\r\n*\r\n\r\n# but not these files...\r\n!canvas-designer-widget.js\r\n!widget.html\r\n!widget.js\r\n!widget.min.js"
  },
  {
    "path": "Canvas-Designer/.travis.yml",
    "chars": 223,
    "preview": "\nlanguage: node_js\nnode_js:\n  - \"0.11\"\ninstall: npm install\nbefore_script:\n  - npm install grunt-cli@0.1.13 -g\n  - npm i"
  },
  {
    "path": "Canvas-Designer/Gruntfile.js",
    "chars": 4475,
    "preview": "'use strict';\n\nmodule.exports = function(grunt) {\n    require('load-grunt-tasks')(grunt, {\n        pattern: 'grunt-*',\n "
  },
  {
    "path": "Canvas-Designer/Help/index.html",
    "chars": 15393,
    "preview": "<!DOCTYPE html>\n<html itemscope itemtype=\"http://schema.org/WebPage\">\n<head>\n\t<meta http-equiv=\"Content-Type\" content=\""
  },
  {
    "path": "Canvas-Designer/LICENSE",
    "chars": 1108,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2017 [Muaz Khan](https://github.com/muaz-khan)\n\nPermission is hereby granted, free "
  },
  {
    "path": "Canvas-Designer/README.md",
    "chars": 20278,
    "preview": "# [Canvas Designer](https://github.com/muaz-khan/Canvas-Designer) / [API Referencee](https://github.com/muaz-khan/Canvas"
  },
  {
    "path": "Canvas-Designer/bower.json",
    "chars": 1161,
    "preview": "{\n  \"name\": \"canvas-designer\",\n  \"preferGlobal\": false,\n  \"version\": \"1.3.1\",\n  \"author\": {\n    \"name\": \"Muaz Khan\",\n   "
  },
  {
    "path": "Canvas-Designer/canvas-designer-widget.js",
    "chars": 6143,
    "preview": "// _______________\n// Canvas-Designer\n\n// Open-Sourced: https://github.com/muaz-khan/Canvas-Designer\n\n// ---------------"
  },
  {
    "path": "Canvas-Designer/dev/amd.js",
    "chars": 1557,
    "preview": "var browserFakeUserAgent = 'Fake/5.0 (FakeOS) AppleWebKit/123 (KHTML, like Gecko) Fake/12.3.4567.89 Fake/123.45';\n\n(func"
  },
  {
    "path": "Canvas-Designer/dev/arc-handler.js",
    "chars": 5137,
    "preview": "var arcHandler = {\n    global: {\n        ismousedown: false,\n        prevX: 0,\n        prevY: 0,\n        prevRadius: 0,\n"
  },
  {
    "path": "Canvas-Designer/dev/arrow-handler.js",
    "chars": 959,
    "preview": "var arrowHandler = {\n    ismousedown: false,\n    prevX: 0,\n    prevY: 0,\n    arrowSize: 10,\n    mousedown: function(e) {"
  },
  {
    "path": "Canvas-Designer/dev/bezier-handler.js",
    "chars": 2630,
    "preview": "var bezierHandler = {\n    global: {\n        ismousedown: false,\n        prevX: 0,\n        prevY: 0,\n\n        firstContro"
  },
  {
    "path": "Canvas-Designer/dev/common.js",
    "chars": 23553,
    "preview": "var is = {\n    isLine: false,\n    isArrow: false,\n    isArc: false,\n    isDragLastPath: false,\n    isDragAllPaths: false"
  },
  {
    "path": "Canvas-Designer/dev/data-uris.js",
    "chars": 117891,
    "preview": "var icons = {};\nif (params.icons) {\n    try {\n        icons = JSON.parse(params.icons);\n    } catch (e) {\n        icons "
  },
  {
    "path": "Canvas-Designer/dev/decorator.js",
    "chars": 27581,
    "preview": "var tools = {\n    line: true,\n    arrow: true,\n    pencil: true,\n    marker: true,\n    dragSingle: true,\n    dragMultipl"
  },
  {
    "path": "Canvas-Designer/dev/drag-helper.js",
    "chars": 26454,
    "preview": "var dragHelper = {\n    global: {\n        prevX: 0,\n        prevY: 0,\n        ismousedown: false,\n        pointsToMove: '"
  },
  {
    "path": "Canvas-Designer/dev/draw-helper.js",
    "chars": 5764,
    "preview": "var drawHelper = {\n    redraw: function() {\n        tempContext.clearRect(0, 0, innerWidth, innerHeight);\n        contex"
  },
  {
    "path": "Canvas-Designer/dev/eraser-handler.js",
    "chars": 1055,
    "preview": "var eraserHandler = {\n    ismousedown: false,\n    prevX: 0,\n    prevY: 0,\n    mousedown: function(e) {\n        var x = e"
  },
  {
    "path": "Canvas-Designer/dev/events-handler.js",
    "chars": 7487,
    "preview": "var canvas = tempContext.canvas,\n    isTouch = 'createTouch' in document;\n\naddEvent(canvas, isTouch ? 'touchstart moused"
  },
  {
    "path": "Canvas-Designer/dev/file-selector.js",
    "chars": 1422,
    "preview": "var FileSelector = function() {\n    var selector = this;\n\n    selector.selectSingleFile = selectFile;\n    selector.selec"
  },
  {
    "path": "Canvas-Designer/dev/head.js",
    "chars": 117,
    "preview": "// _______________\n// Canvas-Designer\n\n// https://github.com/muaz-khan/Canvas-Designer\n\n'use strict';\n\n(function() {\n"
  },
  {
    "path": "Canvas-Designer/dev/image-handler.js",
    "chars": 1501,
    "preview": "var imageHandler = {\n    lastImageURL: null,\n    lastImageIndex: 0,\n    images: [],\n\n    ismousedown: false,\n    prevX: "
  },
  {
    "path": "Canvas-Designer/dev/line-handler.js",
    "chars": 937,
    "preview": "var lineHandler = {\n    ismousedown: false,\n    prevX: 0,\n    prevY: 0,\n    mousedown: function(e) {\n        var x = e.p"
  },
  {
    "path": "Canvas-Designer/dev/marker-handler.js",
    "chars": 1593,
    "preview": "var markerHandler = {\n    ismousedown: false,\n    prevX: 0,\n    prevY: 0,\n    mousedown: function(e) {\n        var x = e"
  },
  {
    "path": "Canvas-Designer/dev/pdf-handler.js",
    "chars": 6459,
    "preview": "var pdfHandler = {\n    lastPdfURL: null,\n    lastIndex: 0,\n    lastPointIndex: 0,\n    removeWhiteBackground: false,\n    "
  },
  {
    "path": "Canvas-Designer/dev/pencil-handler.js",
    "chars": 2011,
    "preview": "var pencilHandler = {\n    ismousedown: false,\n    prevX: 0,\n    prevY: 0,\n    mousedown: function(e) {\n        var x = e"
  },
  {
    "path": "Canvas-Designer/dev/quadratic-handler.js",
    "chars": 1838,
    "preview": "var quadraticHandler = {\n    global: {\n        ismousedown: false,\n        prevX: 0,\n        prevY: 0,\n        controlPo"
  },
  {
    "path": "Canvas-Designer/dev/rect-handler.js",
    "chars": 977,
    "preview": "var rectHandler = {\n    ismousedown: false,\n    prevX: 0,\n    prevY: 0,\n    mousedown: function(e) {\n        var x = e.p"
  },
  {
    "path": "Canvas-Designer/dev/share-drawings.js",
    "chars": 4578,
    "preview": "// scripts on this page directly touches DOM-elements\n// removing or altering anything may cause failures in the UI even"
  },
  {
    "path": "Canvas-Designer/dev/tail.js",
    "chars": 6,
    "preview": "})();\n"
  },
  {
    "path": "Canvas-Designer/dev/text-handler.js",
    "chars": 6741,
    "preview": "var textHandler = {\n    text: '',\n    selectedFontFamily: 'Arial',\n    selectedFontSize: '15',\n    lastFillStyle: '',\n  "
  },
  {
    "path": "Canvas-Designer/dev/webrtc-handler.js",
    "chars": 2299,
    "preview": "var webrtcHandler = {\n    createOffer: function(callback) {\n        var captureStream = document.getElementById('main-ca"
  },
  {
    "path": "Canvas-Designer/dev/zoom-handler.js",
    "chars": 846,
    "preview": "var zoomHandler = {\n    scale: 1.0,\n    lastZoomState: null,\n    up: function(e) {\n        this.scale = this.lastZoomSta"
  },
  {
    "path": "Canvas-Designer/index.html",
    "chars": 19862,
    "preview": "<!DOCTYPE html>\n<html itemscope itemtype=\"http://schema.org/WebPage\">\n<head>\n\t<meta http-equiv=\"Content-Type\" content=\""
  },
  {
    "path": "Canvas-Designer/multiple.html",
    "chars": 17564,
    "preview": "<!DOCTYPE html>\n<html itemscope itemtype=\"http://schema.org/WebPage\">\n<head>\n\t<meta http-equiv=\"Content-Type\" content=\""
  },
  {
    "path": "Canvas-Designer/package.json",
    "chars": 1194,
    "preview": "{\n  \"name\": \"canvas-designer\",\n  \"preferGlobal\": false,\n  \"version\": \"1.3.1\",\n  \"author\": {\n    \"name\": \"Muaz Khan\",\n   "
  },
  {
    "path": "Canvas-Designer/server.js",
    "chars": 1716,
    "preview": "var server = require('http'),\n    url = require('url'),\n    path = require('path'),\n    fs = require('fs'),\n    cwd = pr"
  },
  {
    "path": "Canvas-Designer/simple.html",
    "chars": 15344,
    "preview": "<!DOCTYPE html>\n<html itemscope itemtype=\"http://schema.org/WebPage\">\n<head>\n\t<meta http-equiv=\"Content-Type\" content=\""
  },
  {
    "path": "Canvas-Designer/widget.html",
    "chars": 27193,
    "preview": "<!DOCTYPE html>\n<html itemscope itemtype=\"http://schema.org/WebPage\">\n\n<head>\n    <meta http-equiv=\"Content-Type\" conte"
  },
  {
    "path": "Canvas-Designer/widget.js",
    "chars": 263147,
    "preview": "// Last time updated: 2019-03-08 2:53:41 PM UTC\n\n// _______________\n// Canvas-Designer\n\n// https://github.com/muaz-khan/"
  },
  {
    "path": "Chrome-Extensions/.gitignore",
    "chars": 76,
    "preview": "# Node\nnode_modules\n\n# bower\nbower_components\n\n.DS_Store\n\n.zip\n.tar\n*/*.zip\n"
  },
  {
    "path": "Chrome-Extensions/LICENSE",
    "chars": 1108,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2017 [Muaz Khan](https://github.com/muaz-khan)\n\nPermission is hereby granted, free "
  },
  {
    "path": "Chrome-Extensions/README.md",
    "chars": 978,
    "preview": "# WebRTC [Chrome Extensions](https://github.com/muaz-khan/Chrome-Extensions)\n\n| Description        | Download           "
  },
  {
    "path": "Chrome-Extensions/Screen-Capturing.js/README.md",
    "chars": 8028,
    "preview": "# Please use `getDisplayMedia` instead\n\n```javascript\ngetScreenStream(function(screenStream) {\n    video.srcObject = scr"
  },
  {
    "path": "Chrome-Extensions/Screen-Capturing.js/Screen-Capturing.js",
    "chars": 6810,
    "preview": "// Last time updated on: June 08, 2018\n\n// Latest file can be found here: https://cdn.webrtc-experiment.com/Screen-Captu"
  },
  {
    "path": "Chrome-Extensions/Screen-Capturing.js/index.html",
    "chars": 16889,
    "preview": "<!--\n> Muaz Khan       - wwww.MuazKhan.com\n> MIT License     - www.WebRTC-Experiment.com/licence\n> Documentation   - htt"
  },
  {
    "path": "Chrome-Extensions/Screen-Capturing.js/server.js",
    "chars": 2369,
    "preview": "// Muaz Khan      - www.MuazKhan.com\n// MIT License    - www.WebRTC-Experiment.com/licence\n// Documentation  - github.co"
  },
  {
    "path": "Chrome-Extensions/desktopCapture/README.md",
    "chars": 5241,
    "preview": "# Please use `getDisplayMedia` instead\n\n```javascript\ngetScreenStream(function(screenStream) {\n    video.srcObject = scr"
  },
  {
    "path": "Chrome-Extensions/desktopCapture/background-script.js",
    "chars": 1600,
    "preview": "// this background script is used to invoke desktopCapture API\n// to capture screen-MediaStream.\n\nvar screenOptions = ["
  },
  {
    "path": "Chrome-Extensions/desktopCapture/content-script.js",
    "chars": 1651,
    "preview": "// this content-script plays role of medium to publish/subscribe messages from webpage to the background script\n\n// thi"
  },
  {
    "path": "Chrome-Extensions/desktopCapture/different-api/background-script.js",
    "chars": 1408,
    "preview": "// this background script is used to invoke desktopCapture API\n// to capture screen-MediaStream.\n\nvar screenOptions = ["
  },
  {
    "path": "Chrome-Extensions/desktopCapture/different-api/manifest.json",
    "chars": 723,
    "preview": "{\n    \"name\" : \"Screen Capturing XYZ\",\n    \"author\": \"Muaz Khan\",\n    \"version\" : \"3.4\",\n    \"manifest_version\" : 2,\n   "
  },
  {
    "path": "Chrome-Extensions/desktopCapture/manifest.json",
    "chars": 796,
    "preview": "{\n    \"name\" : \"Screen Capturing\",\n    \"author\": \"Muaz Khan\",\n    \"version\" : \"3.7\",\n    \"manifest_version\" : 2,\n    \"mi"
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/README.md",
    "chars": 4013,
    "preview": "# Chrome extension for WebRTC Screen Sharing\n\n<a target=\"_blank\" href=\"https://chrome.google.com/webstore/detail/webrtc-"
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/background/captureCamera.js",
    "chars": 1779,
    "preview": "function captureCamera(callback) {\n    var supported = navigator.mediaDevices.getSupportedConstraints();\n    var constra"
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/background/captureDesktop.js",
    "chars": 4991,
    "preview": "function captureDesktop() {\n    false && chrome.storage.sync.set({\n        isSharingOn: 'false'\n    });\n\n    if (connect"
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/background/captureTabUsingTabCapture.js",
    "chars": 1575,
    "preview": "function captureTabUsingTabCapture(resolutions) {\n    chrome.tabs.query({\n        active: true,\n        currentWindow: t"
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/background/common.js",
    "chars": 2417,
    "preview": "function getAspectRatio(w, h) {\n    function gcd(a, b) {\n        return (b == 0) ? a : gcd(b, a % b);\n    }\n    var r = "
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/background/globals.js",
    "chars": 459,
    "preview": "var runtimePort;\n\nvar desktop_id;\nvar constraints;\nvar room_password = '';\nvar room_id = '';\nvar codecs = 'default';\nvar"
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/background/gotStream.js",
    "chars": 1363,
    "preview": "function gotStream(stream) {\n    if (!stream) {\n        setDefaults();\n\n        chrome.windows.create({\n            url:"
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/background/gotTabCaptureStream.js",
    "chars": 520,
    "preview": "function gotTabCaptureStream(stream, constraints) {\n    if (!stream) {\n        if (constraints.audio === true) {\n       "
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/background/helpers/AntMediaWrapper.js",
    "chars": 12137,
    "preview": "function AntMediaWrapper() {\n    var callbacks = {\n        onopen: function() {},\n        onclose: function() {},\n      "
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/background/helpers/CodecsHandler.js",
    "chars": 11943,
    "preview": "// CodecsHandler.js\n\nvar CodecsHandler = (function() {\n    function preferCodec(sdp, codecName) {\n        var info = spl"
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/background/helpers/IceServersHandler.js",
    "chars": 1104,
    "preview": "// IceServersHandler.js\n\nvar IceServersHandler = (function() {\n    function getIceServers(connection) {\n        // resip"
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/background/helpers/MultiStreamsMixer.js",
    "chars": 12242,
    "preview": "// Last time updated: 2018-12-22 9:13:29 AM UTC\n\n// ________________________\n// MultiStreamsMixer v1.0.7\n\n// Open-Source"
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/background/helpers/adapter.js",
    "chars": 257550,
    "preview": "(function(f) {\n    if (typeof exports === \"object\" && typeof module !== \"undefined\") {\n        module.exports = f()\n    "
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/background/helpers/getStats.js",
    "chars": 21121,
    "preview": "'use strict';\n\n// Last time updated: 2017-11-19 4:49:44 AM UTC\n\n// _______________\n// getStats v1.0.6\n\n// Open-Sourced: "
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/background/helpers/socket.io.js",
    "chars": 62395,
    "preview": "/*!\n * Socket.IO v2.1.0\n * (c) 2014-2018 Guillermo Rauch\n * Released under the MIT License.\n */\n!function(t,e){\"object\"="
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/background/onAccessApproved.js",
    "chars": 3880,
    "preview": "function onAccessApproved(chromeMediaSourceId, opts) {\n    if (!chromeMediaSourceId) {\n        setDefaults();\n        re"
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/background/online-offline.js",
    "chars": 321,
    "preview": "window.addEventListener('offline', function() {\n    if (!connection || !connection.attachStreams.length) return;\n\n    //"
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/background/runtimePort.js",
    "chars": 898,
    "preview": "chrome.runtime.onConnect.addListener(function(port) {\n    runtimePort = port;\n\n    runtimePort.onMessage.addListener(fun"
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/background/setDefaults.js",
    "chars": 1157,
    "preview": "function setDefaults() {\n    chrome.storage.sync.set({\n        enableTabCaptureAPI: 'false',\n        enableMicrophone: '"
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/background/setupWebRTCConnection.js",
    "chars": 437,
    "preview": "function setupWebRTCConnection(stream) {\n    // forcing RTCMultiConnection ONLY\n    // reason: webserver doesn't has eno"
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/background/shareStreamUsingAntMediaServer.js",
    "chars": 2092,
    "preview": "function shareStreamUsingAntMediaServer(stream) {\n    var wrapper = new AntMediaWrapper();\n    wrapper.callbacks('onopen"
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/background/shareStreamUsingRTCMultiConnection.js",
    "chars": 6518,
    "preview": "function shareStreamUsingRTCMultiConnection(stream) {\n    // www.RTCMultiConnection.org/docs/\n    connection = new RTCMu"
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/extension-pages/camera-mic.html",
    "chars": 142,
    "preview": "<link rel=\"shortcut icon\" href=\"../images/desktopCapture128.png\">\n<title>WebRTC Desktop Sharing</title>\n<script src=\"ca"
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/extension-pages/camera-mic.js",
    "chars": 1251,
    "preview": "document.write('<h1 style=\"font-family: Courier New; font-size: 30px; color:green;margin-top:200px;\">The purpose of this"
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/extension-pages/chat.html",
    "chars": 1964,
    "preview": "<!DOCTYPE html>\n<html>\n<link rel=\"shortcut icon\" href=\"../images/desktopCapture128.png\">\n<title>Chat</title>\n<head>\n<st"
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/extension-pages/chat.js",
    "chars": 1751,
    "preview": "var txtChatMessage = document.getElementById('txt-chat-message');\nvar chatMessages = document.getElementById('chat-messa"
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/extension-pages/dropdown.html",
    "chars": 3191,
    "preview": " <!DOCTYPE html>\n<html>\n<link rel=\"shortcut icon\" href=\"../images/desktopCapture128.png\">\n<head>\n<style>\n* {\n  -webkit-"
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/extension-pages/dropdown.js",
    "chars": 5822,
    "preview": "var runtimePort = chrome.runtime.connect({\n    name: location.href.replace(/\\/|:|#|\\?|\\$|\\^|%|\\.|`|~|!|\\+|@|\\[|\\||]|\\|*"
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/extension-pages/options.html",
    "chars": 4739,
    "preview": "<style>\n/* custom select start */\n.custom-select {\n  position: relative;\n  font-family: -apple-system, BlinkMacSystemFo"
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/extension-pages/options.js",
    "chars": 5727,
    "preview": "function querySelectorAll(selector, element) {\n    element = element || document;\n    return Array.prototype.slice.call"
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/extension-pages/video.html",
    "chars": 612,
    "preview": "<!DOCTYPE html>\n<html dir=\"ltr\" lang=\"en\" style=\"overflow: hidden;padding: 0;margin: 0;\">\n<link rel=\"shortcut icon\" hre"
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/extension-pages/video.js",
    "chars": 295,
    "preview": "// var src = location.href.split('?src=')[1];\n// document.querySelector('video').src = src;\n\nnavigator.mediaDevices.getU"
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/index.html",
    "chars": 13726,
    "preview": "<title>WebRTC Desktop Viewer</title>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<meta charset=\""
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/manifest.json",
    "chars": 2111,
    "preview": "{\n   \"name\":\"WebRTC Desktop Sharing\",\n   \"author\":\"Muaz Khan\",\n   \"version\":\"6.0\",\n   \"manifest_version\":2,\n   \"minimum_"
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/screen-receivers/ant/index.html",
    "chars": 2786,
    "preview": "<!--\n<style>\n* {margin:0;padding:0;}\niframe {\n    border: 0;\n    outline: none;\n    width: 100%;\n    height: 100%;\n}\n</s"
  },
  {
    "path": "Chrome-Extensions/desktopCapture-p2p/server.js",
    "chars": 2048,
    "preview": "// http://127.0.0.1:9001\n// http://localhost:9001\n\nvar server = require('http'),\n    url = require('url'),\n    path = re"
  },
  {
    "path": "Chrome-Extensions/file-sharing/README.md",
    "chars": 412,
    "preview": "# Chrome Extension to share files\n\n## Disclaimer\n\nNo more maintaining this extension; as of 2019. So please use at your "
  },
  {
    "path": "Chrome-Extensions/file-sharing/background.js",
    "chars": 1169,
    "preview": "// background.js\n\nchrome.runtime.onConnect.addListener(function(port) {\n    port.onMessage.addListener(portOnMessageHanl"
  },
  {
    "path": "Chrome-Extensions/file-sharing/info.html",
    "chars": 11325,
    "preview": " <!DOCTYPE html>\n<html lang=\"en\" itemscope itemtype=\"http://schema.org/WebPage\">\n<head>\n    <title>About | Help | How t"
  },
  {
    "path": "Chrome-Extensions/file-sharing/manifest.json",
    "chars": 974,
    "preview": "{\n\t\"name\" : \"WebRTC File Sharing\",\n\t\"short_name\" : \"FileSharing\",\n    \"author\": \"Muaz Khan\",\n\t\"version\" : \"2.6\",\n\t\"manif"
  },
  {
    "path": "Chrome-Extensions/file-sharing/options.html",
    "chars": 1199,
    "preview": "<style>\nbody: { \n    padding: 10px;\n}\n\nh2 {\n    font-size: 1.5em;\n    font-weight: bold;\n}\n\nselect {\n    font-size: 1.2"
  },
  {
    "path": "Chrome-Extensions/file-sharing/options.js",
    "chars": 752,
    "preview": "chrome.storage.sync.get(null, function(items) {\n    if (items['room_id']) {\n        document.getElementById('room_id')."
  },
  {
    "path": "Chrome-Extensions/file-sharing/popup.html",
    "chars": 7105,
    "preview": " <!DOCTYPE html>\n<html lang=\"en\" itemscope itemtype=\"http://schema.org/WebPage\">\n<head>\n    <style>\n        /* cyrillic"
  },
  {
    "path": "Chrome-Extensions/file-sharing/popup.js",
    "chars": 91676,
    "preview": "// popup.js\n\n/*! jQuery v2.2.2 | (c) jQuery Foundation | jquery.org/license */\n!function(a,b){\"object\"==typeof module&&\""
  },
  {
    "path": "Chrome-Extensions/file-sharing/rmc-files-handler.js",
    "chars": 434886,
    "preview": "// rmc-files-handler.js\n\n// Open-Sourced: https://github.com/muaz-khan/Chrome-Extensions/tree/master/file-sharing\n\n//--"
  },
  {
    "path": "Chrome-Extensions/get-any-webrtc-peer-stream/RTCPeerConnection-override.js",
    "chars": 2574,
    "preview": "var nativePeer;\n\n(function looper() {\n    var RTC = window.RTCPeerConnection || window.webkitRTCPeerConnection;\n\n    if "
  },
  {
    "path": "Chrome-Extensions/get-any-webrtc-peer-stream/content-script.js",
    "chars": 1187,
    "preview": "var s = document.createElement('script');\ns.src = chrome.extension.getURL('RTCPeerConnection-override.js');\ns.onload = "
  },
  {
    "path": "Chrome-Extensions/get-any-webrtc-peer-stream/manifest.json",
    "chars": 673,
    "preview": "{\n    \"name\" : \"Get Any WebRTC Peer Stream\",\n    \"author\": \"Muaz Khan\",\n    \"version\" : \"1.0\",\n    \"manifest_version\" : "
  },
  {
    "path": "Chrome-Extensions/getUserMedia-on-http/README.md",
    "chars": 3203,
    "preview": "# DO NOT USE THIS\n\n# PLEASE USE HTTPS\n\n# NOT RECOMMENDED\n\n# YOUR CHOICE; at YOUR own RISK\n\n----\n\n# Call getUserMedia on "
  },
  {
    "path": "Chrome-Extensions/getUserMedia-on-http/background-script.js",
    "chars": 7543,
    "preview": "var port, rtc;\n\nchrome.runtime.onConnect.addListener(function(p) {\n    if (p.sender.url.indexOf('http:') === 0) {\n     "
  },
  {
    "path": "Chrome-Extensions/getUserMedia-on-http/camera-mic.html",
    "chars": 66,
    "preview": "<title>getUserMedia</title>\n<script src=\"camera-mic.js\"></script>"
  },
  {
    "path": "Chrome-Extensions/getUserMedia-on-http/camera-mic.js",
    "chars": 1558,
    "preview": "document.write('<h1 style=\"font-family: Courier New; font-size: 30px; color:red;margin-top:200px;\">The purpose of this p"
  },
  {
    "path": "Chrome-Extensions/getUserMedia-on-http/content-script.js",
    "chars": 4037,
    "preview": "var port = chrome.runtime.connect();\nport.onMessage.addListener(function(message) {\n    window.postMessage({\n        'g"
  },
  {
    "path": "Chrome-Extensions/getUserMedia-on-http/example/index.html",
    "chars": 893,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<title>getUserMedia on HTTP</title>\n<style type=\"text/css\">\nvideo {\n    max-widt"
  },
  {
    "path": "Chrome-Extensions/getUserMedia-on-http/example/index.js",
    "chars": 2600,
    "preview": "var logs = document.querySelector('#logs');\nfunction showLog(log) {\n    var div = document.createElement('div');\n    di"
  },
  {
    "path": "Chrome-Extensions/getUserMedia-on-http/manifest.json",
    "chars": 968,
    "preview": "{\n    \"name\" : \"getUserMedia\",\n    \"author\": \"Muaz Khan\",\n    \"version\" : \"1.2\",\n    \"manifest_version\" : 2,\n    \"minimu"
  },
  {
    "path": "Chrome-Extensions/getUserMedia-on-http/webrtc-handler.js",
    "chars": 3254,
    "preview": "function webrtcHandler() {\n    return {\n        createOffer: function(stream, callback) {\n            var peer = this.ge"
  },
  {
    "path": "Chrome-Extensions/screen-recording/README.md",
    "chars": 3249,
    "preview": "# Record Screen Activity, Camera, Tab, Speakers and Microphone in 4K HD video (H264, VP8, VP9, MKV)\n\n<a target=\"_blank\" "
  },
  {
    "path": "Chrome-Extensions/screen-recording/RecordRTC/DiskStorage.js",
    "chars": 10243,
    "preview": "// via: https://github.com/muaz-khan/RecordRTC/blob/master/dev/DiskStorage.js\n\nvar DiskStorage = {\n    init: function() "
  },
  {
    "path": "Chrome-Extensions/screen-recording/RecordRTC/EBML.js",
    "chars": 242416,
    "preview": "(function(f){if(typeof exports===\"object\"&&typeof module!==\"undefined\"){module.exports=f()}else if(typeof define===\"func"
  },
  {
    "path": "Chrome-Extensions/screen-recording/RecordRTC/MediaStreamRecorder.js",
    "chars": 16726,
    "preview": "// ______________________\n// MediaStreamRecorder.js\n\n/**\n * MediaStreamRecorder is an abstraction layer for {@link https"
  },
  {
    "path": "Chrome-Extensions/screen-recording/RecordRTC/MultiStreamRecorder.js",
    "chars": 5730,
    "preview": "// ______________________\n// MultiStreamRecorder.js\n\n/*\n * Video conference recording, using captureStream API along wit"
  },
  {
    "path": "Chrome-Extensions/screen-recording/RecordRTC/MultiStreamsMixer.js",
    "chars": 12242,
    "preview": "// Last time updated: 2018-12-22 9:13:29 AM UTC\n\n// ________________________\n// MultiStreamsMixer v1.0.7\n\n// Open-Source"
  },
  {
    "path": "Chrome-Extensions/screen-recording/RecordRTC/StereoAudioRecorder.js",
    "chars": 23094,
    "preview": "// source code from: http://typedarray.org/wp-content/projects/WebAudioRecorder/script.js\n// https://github.com/mattdiam"
  },
  {
    "path": "Chrome-Extensions/screen-recording/RecordRTC/getAllAudioVideoDevices.js",
    "chars": 3339,
    "preview": "if (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) {\n    // Firefox 38+, Microsoft Edge, and Chrome "
  },
  {
    "path": "Chrome-Extensions/screen-recording/background/background.badgeText.js",
    "chars": 2391,
    "preview": "function setVODRecordingBadgeText(text, title) {\n    chrome.browserAction.setBadgeBackgroundColor({\n        color: [203,"
  },
  {
    "path": "Chrome-Extensions/screen-recording/background/background.common.js",
    "chars": 5495,
    "preview": "var recorder;\nvar isRecording = false;\nvar bitsPerSecond = 0;\nvar isChrome = true; // used by RecordRTC\n\nvar enableTabCa"
  },
  {
    "path": "Chrome-Extensions/screen-recording/background/background.contentScript.js",
    "chars": 5196,
    "preview": "var port = chrome.runtime.connect();\nport.onMessage.addListener(function(message) {\n    message.messageFromContentScrip"
  },
  {
    "path": "Chrome-Extensions/screen-recording/background/background.desktopCapture.js",
    "chars": 3308,
    "preview": "function captureDesktop() {\n    if (isRecording) {\n        stopScreenRecording();\n        return;\n    }\n\n    if (recorde"
  },
  {
    "path": "Chrome-Extensions/screen-recording/background/background.getUserMedia.js",
    "chars": 3080,
    "preview": "var microphoneDevice = false;\nvar cameraDevice = false;\n\nfunction captureCamera(callback, defaultDevices) {\n    var supp"
  },
  {
    "path": "Chrome-Extensions/screen-recording/background/background.js",
    "chars": 12705,
    "preview": "chrome.storage.sync.set({\n    isRecording: 'false' // FALSE\n});\n\nchrome.browserAction.setIcon({\n    path: 'images/main-i"
  },
  {
    "path": "Chrome-Extensions/screen-recording/background/background.messaging.js",
    "chars": 3165,
    "preview": "var runtimePort;\n\nchrome.runtime.onConnect.addListener(function(port) {\n    runtimePort = port;\n\n    runtimePort.onMessa"
  },
  {
    "path": "Chrome-Extensions/screen-recording/background/background.players.js",
    "chars": 283,
    "preview": "var videoPlayers = [];\n\nfunction initVideoPlayer(stream) {\n    var videoPlayer = document.createElement('video');\n    vi"
  },
  {
    "path": "Chrome-Extensions/screen-recording/background/background.tabCapture.js",
    "chars": 2296,
    "preview": "function captureTabUsingTabCapture(isNoAudio) {\n    chrome.tabs.query({\n        active: true,\n        currentWindow: tru"
  },
  {
    "path": "Chrome-Extensions/screen-recording/camera-mic.html",
    "chars": 63,
    "preview": "<title>RecordRTC</title>\n<script src=\"camera-mic.js\"></script>"
  },
  {
    "path": "Chrome-Extensions/screen-recording/camera-mic.js",
    "chars": 2232,
    "preview": "document.write('<h1 style=\"font-family: Courier New; font-size: 30px; color:red;margin-top:200px;\">The purpose of this p"
  },
  {
    "path": "Chrome-Extensions/screen-recording/dropdown.html",
    "chars": 3852,
    "preview": " <!DOCTYPE html>\n<html>\n<head>\n<style>\n* {\n  -webkit-user-select: none;\n  -user-select: none;\n  -webkit-user-drag: none"
  },
  {
    "path": "Chrome-Extensions/screen-recording/dropdown.js",
    "chars": 7858,
    "preview": "var runtimePort = chrome.runtime.connect({\n    name: location.href.replace(/\\/|:|#|\\?|\\$|\\^|%|\\.|`|~|!|\\+|@|\\[|\\||]|\\|*"
  },
  {
    "path": "Chrome-Extensions/screen-recording/manifest.json",
    "chars": 2403,
    "preview": "{  \n   \"name\":\"RecordRTC\",\n   \"short_name\":\"RecordRTC\",\n   \"author\":\"Muaz Khan\",\n   \"version\":\"8.6\",\n   \"manifest_versio"
  },
  {
    "path": "Chrome-Extensions/screen-recording/options.html",
    "chars": 5219,
    "preview": "<style>\n* {\n  -webkit-user-select: none;\n  -user-select: none;\n  -webkit-user-drag: none;\n  -user-drag: none;\n}\n\n@font-"
  },
  {
    "path": "Chrome-Extensions/screen-recording/options.js",
    "chars": 7233,
    "preview": "chrome.storage.sync.get(null, function(items) {\n    if (items['videoCodec']) {\n        querySelectorAll('#videoCodec in"
  },
  {
    "path": "Chrome-Extensions/screen-recording/preview/preview.js",
    "chars": 9746,
    "preview": "var video = document.querySelector('video');\nvar fname = document.querySelector('#file-name');\nvar fsize = document.quer"
  },
  {
    "path": "Chrome-Extensions/screen-recording/preview/preview.php.upload.js",
    "chars": 4081,
    "preview": "var server_url = 'https://your-domain.com/f/';\n\ndocument.querySelector('#btn-php-upload').onclick = function() {\n    if "
  },
  {
    "path": "Chrome-Extensions/screen-recording/preview/preview.youtube.upload.js",
    "chars": 11794,
    "preview": "var youtube_privacy = 'public';\n\nchrome.storage.sync.get(null, function(items) {\n    if (items['youtube_privacy'] && ite"
  },
  {
    "path": "Chrome-Extensions/screen-recording/preview.html",
    "chars": 3659,
    "preview": "<style>\n* {\n  -webkit-user-select: none;\n  -user-select: none;\n  -webkit-user-drag: none;\n  -user-drag: none;\n}\n\n@font-"
  },
  {
    "path": "Chrome-Extensions/screen-recording/video.html",
    "chars": 600,
    "preview": "<!DOCTYPE html>\n<html dir=\"ltr\" lang=\"en\" style=\"overflow: hidden;padding: 0;margin: 0;\">\n<head>\n<title>RecordRTC Exten"
  },
  {
    "path": "Chrome-Extensions/screen-recording/video.js",
    "chars": 2179,
    "preview": "// var src = location.href.split('?src=')[1];\n// document.querySelector('video').src = src;\n\nvar video = document.queryS"
  },
  {
    "path": "Chrome-Extensions/tabCapture/CodecsHandler.js",
    "chars": 11943,
    "preview": "// CodecsHandler.js\n\nvar CodecsHandler = (function() {\n    function preferCodec(sdp, codecName) {\n        var info = spl"
  },
  {
    "path": "Chrome-Extensions/tabCapture/IceServersHandler.js",
    "chars": 1104,
    "preview": "// IceServersHandler.js\n\nvar IceServersHandler = (function() {\n    function getIceServers(connection) {\n        // resip"
  },
  {
    "path": "Chrome-Extensions/tabCapture/README.md",
    "chars": 1595,
    "preview": "# Disclaimer\n\nNo more maintaining this extension; as of 2019. So please use at your own risk.\n\n* https://www.webrtc-expe"
  },
  {
    "path": "Chrome-Extensions/tabCapture/index.html",
    "chars": 9951,
    "preview": "<title>WebRTC Desktop Viewer</title>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n<meta charset=\""
  },
  {
    "path": "Chrome-Extensions/tabCapture/manifest.json",
    "chars": 1040,
    "preview": "{\n    \"name\" : \"Tab Capturing & Sharing\",\n    \"author\": \"Muaz Khan\",\n    \"version\" : \"2.3\",\n    \"manifest_version\" : 2,\n"
  },
  {
    "path": "Chrome-Extensions/tabCapture/options.html",
    "chars": 1539,
    "preview": "<style>\nbody: { \n    padding: 10px;\n}\n\nh2 {\n    font-size: 1.5em;\n    font-weight: bold;\n}\n\nselect {\n    font-size: 1.2"
  },
  {
    "path": "Chrome-Extensions/tabCapture/options.js",
    "chars": 3113,
    "preview": "chrome.storage.sync.get(null, function(items) {\n    if (items['resolutions']) {\n        document.getElementById('resolu"
  },
  {
    "path": "Chrome-Extensions/tabCapture/shareStreamUsingRTCMultiConnection.js",
    "chars": 5260,
    "preview": "function shareStreamUsingRTCMultiConnection(stream) {\n    // www.RTCMultiConnection.org/docs/\n    connection = new RTCMu"
  },
  {
    "path": "Chrome-Extensions/tabCapture/socket.io.js",
    "chars": 62395,
    "preview": "/*!\n * Socket.IO v2.1.0\n * (c) 2014-2018 Guillermo Rauch\n * Released under the MIT License.\n */\n!function(t,e){\"object\"="
  },
  {
    "path": "Chrome-Extensions/tabCapture/tab-capturing.js",
    "chars": 6536,
    "preview": "// Muaz Khan     - https://github.com/muaz-khan\n// MIT License   - https://www.WebRTC-Experiment.com/licence/\n// Source"
  },
  {
    "path": "ConcatenateBlobs/ConcatenateBlobs.js",
    "chars": 2123,
    "preview": "// Last time updated at May 23, 2015, 08:32:23\n\n// Latest file can be found here: https://cdn.webrtc-experiment.com/Conc"
  },
  {
    "path": "ConcatenateBlobs/README.md",
    "chars": 1626,
    "preview": "## [ConcatenateBlobs.js](https://github.com/muaz-khan/ConcatenateBlobs)  [![npm](https://img.shields.io/npm/v/concatenat"
  },
  {
    "path": "ConcatenateBlobs/index.html",
    "chars": 5983,
    "preview": "<title>ConcatenateBlobs | JavaScript</title>\n\n<h1>ConcatenateBlobs | JavaScript - <a href=\"https://github.com/muaz-khan"
  },
  {
    "path": "ConcatenateBlobs/package.json",
    "chars": 1149,
    "preview": "{\n  \"name\": \"concatenateblobs\",\n  \"preferGlobal\": true,\n  \"version\": \"1.0.3\",\n  \"author\": {\n    \"name\": \"Muaz Khan\",\n   "
  },
  {
    "path": "Conversation.js/AndroidRTC/index.html",
    "chars": 17069,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n\n<head>\n    <title>AndroidRTC: Runs top over Conversation.js!</title>\n    <meta http-e"
  },
  {
    "path": "Conversation.js/AndroidRTC/manifest.json",
    "chars": 1006,
    "preview": "{\n  \"name\": \"AndroidRTC\",\n  \"description\": \"AndroidRTC is using WebRTC standards to bring realtime [secure] p2p connecti"
  },
  {
    "path": "Conversation.js/AndroidRTC/scripts/FileBufferReader.js",
    "chars": 35961,
    "preview": "// Last time updated at Sep 16, 2014, 08:32:23\n\n// Latest file can be found here: https://cdn.webrtc-experiment.com/File"
  },
  {
    "path": "Conversation.js/AndroidRTC/scripts/RTCMultiConnection.js",
    "chars": 237958,
    "preview": "// Last time updated at Sep 16, 2014, 08:32:23\n\n// Quick-Demo for newbies: http://jsfiddle.net/c46de0L8/\n// Another simp"
  },
  {
    "path": "Conversation.js/AndroidRTC/scripts/common-signaling.js",
    "chars": 666,
    "preview": "var SIGNALING_SERVER = 'wss://webrtcweb.com:9449/';\nvar channel = window.RMCDefaultChannel;\n\nvar websocket = new WebSock"
  },
  {
    "path": "Conversation.js/AndroidRTC/scripts/conversation.js",
    "chars": 26323,
    "preview": "// Last time updated at Sep 15, 2014, 08:32:23\n\n// Latest file can be found here: https://cdn.webrtc-experiment.com/conv"
  },
  {
    "path": "Conversation.js/AndroidRTC/scripts/ui-handler.js",
    "chars": 10039,
    "preview": "// ui-handler for AndroidRTC app\nfunction searchInDOM(selector) {\n    return document.querySelector(selector);\n}\n\nfuncti"
  },
  {
    "path": "Conversation.js/AndroidRTC/styles/ui-styles.css",
    "chars": 5638,
    "preview": "@font-face {\n    font-family: 'Myriad';\n    src: url('../fonts/MyriadPro-Light.otf') format(\"opentype\");\n    font-weight"
  },
  {
    "path": "Conversation.js/README.md",
    "chars": 8806,
    "preview": "## [Conversation.js](https://github.com/muaz-khan/Conversation.js) runs top over [RTCMultiConnection.js](http://www.RTCM"
  },
  {
    "path": "Conversation.js/conversation.js",
    "chars": 26323,
    "preview": "// Last time updated at Sep 15, 2014, 08:32:23\n\n// Latest file can be found here: https://cdn.webrtc-experiment.com/conv"
  },
  {
    "path": "Conversation.js/demos/common-signaling.js",
    "chars": 666,
    "preview": "var SIGNALING_SERVER = 'wss://webrtcweb.com:9449/';\nvar channel = window.RMCDefaultChannel;\n\nvar websocket = new WebSock"
  },
  {
    "path": "Conversation.js/demos/common-styles.css",
    "chars": 1638,
    "preview": "* {\n    -webkit-user-select: none;\n    -o-user-select: none;\n    -ms-user-select: none;\n    -moz-user-select: none;\n    "
  },
  {
    "path": "Conversation.js/demos/cross-language-chat.html",
    "chars": 21997,
    "preview": "<title>Text-Translation (Multi-Lingual) using Conversation.js ® Muaz Khan</title>\n\n<h1 style=\"text-align: center;displa"
  },
  {
    "path": "Conversation.js/demos/search-user.html",
    "chars": 21858,
    "preview": "<title>Search Users using Conversation.js ® Muaz Khan</title>\n\n<h1 style=\"text-align: center;display: block;border-bott"
  },
  {
    "path": "Conversation.js/package.json",
    "chars": 1314,
    "preview": "{\n  \"name\": \"conversationjs\",\n  \"preferGlobal\": true,\n  \"version\": \"1.0.0\",\n  \"author\": {\n    \"name\": \"Muaz Khan\",\n    \""
  },
  {
    "path": "Conversation.js/server.js",
    "chars": 2048,
    "preview": "// http://127.0.0.1:9001\n// http://localhost:9001\n\nvar server = require('http'),\n    url = require('url'),\n    path = re"
  },
  {
    "path": "DataChannel/.gitignore",
    "chars": 46,
    "preview": "# Node\nnode_modules\n\n# bower\nbower_components\n"
  },
  {
    "path": "DataChannel/.jshintrc",
    "chars": 238,
    "preview": "{\n  \"browser\": true,\n  \"camelcase\": true,\n  \"curly\": true,\n  \"devel\": true,\n  \"eqeqeq\": true,\n  \"forin\": false,\n  \"globa"
  },
  {
    "path": "DataChannel/.npmignore",
    "chars": 34,
    "preview": "node_modules\nlib-cov\nnpm-debug.log"
  },
  {
    "path": "DataChannel/.travis.yml",
    "chars": 160,
    "preview": "language: node_js\nnode_js:\n  - \"0.11\"\ninstall: npm install\nbefore_script:\n  - npm install grunt-cli\n  - npm install grun"
  },
  {
    "path": "DataChannel/DataChannel.js",
    "chars": 43896,
    "preview": "'use strict';\n\n// Last time updated: 2017-07-29 4:31:53 PM UTC\n\n// __________________\n// DataChannel v1.0.0\n\n// Open-Sou"
  },
  {
    "path": "DataChannel/Gruntfile.js",
    "chars": 4888,
    "preview": "'use strict';\n\nmodule.exports = function(grunt) {\n    require('load-grunt-tasks')(grunt, {\n        pattern: 'grunt-*',\n "
  },
  {
    "path": "DataChannel/README.md",
    "chars": 12136,
    "preview": "# [DataChannel.js](https://github.com/muaz-khan/DataChannel) : A JavaScript wrapper library for RTCDataChannel APIs / [D"
  },
  {
    "path": "DataChannel/auto-session-establishment.html",
    "chars": 15697,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n\n    <head>\n        <title>Auto Session Establishment using DataChannel.js</title>\n   "
  },
  {
    "path": "DataChannel/bower.json",
    "chars": 985,
    "preview": "{\n  \"name\": \"datachannel\",\n  \"version\": \"1.0.0\",\n  \"authors\": [\n        {\n            \"name\": \"Muaz Khan\",\n            \""
  },
  {
    "path": "DataChannel/dev/DataChannel.js",
    "chars": 9420,
    "preview": "window.DataChannel = function(channel, extras) {\n    if (channel) {\n        this.automatic = true;\n    }\n\n    this.chann"
  },
  {
    "path": "DataChannel/dev/DataConnector.js",
    "chars": 12634,
    "preview": "function DataConnector(root, config) {\n    var self = {};\n    var that = this;\n\n    self.userToken = (root.userid = root"
  },
  {
    "path": "DataChannel/dev/FileConverter.js",
    "chars": 1369,
    "preview": "var FileConverter = {\n    DataURLToBlob: function(dataURL, fileType, callback) {\n\n        function processInWebWorker() "
  },
  {
    "path": "DataChannel/dev/FileReceiver.js",
    "chars": 1587,
    "preview": "function FileReceiver(root) {\n    var content = {};\n    var packets = {};\n    var numberOfPackets = {};\n\n    function re"
  },
  {
    "path": "DataChannel/dev/FileSaver.js",
    "chars": 513,
    "preview": "var FileSaver = {\n    SaveToDisk: function(fileUrl, fileName) {\n        var hyperlink = document.createElement('a');\n   "
  },
  {
    "path": "DataChannel/dev/FileSender.js",
    "chars": 3426,
    "preview": "var FileSender = {\n    send: function(config) {\n        var root = config.root;\n        var channel = config.channel;\n  "
  },
  {
    "path": "DataChannel/dev/IceServersHandler.js",
    "chars": 1934,
    "preview": "// IceServersHandler.js\n\nvar IceServersHandler = (function() {\n    function getIceServers(connection) {\n        var iceS"
  },
  {
    "path": "DataChannel/dev/RTCPeerConnection.js",
    "chars": 4416,
    "preview": "function RTCPeerConnection(options) {\n    var w = window;\n    var PeerConnection = w.mozRTCPeerConnection || w.webkitRTC"
  },
  {
    "path": "DataChannel/dev/SocketConnector.js",
    "chars": 513,
    "preview": "function SocketConnector(_channel, config) {\n    var socket = config.openSignalingChannel({\n        channel: _channel,\n "
  },
  {
    "path": "DataChannel/dev/TextReceiver.js",
    "chars": 770,
    "preview": "function TextReceiver() {\n    var content = {};\n\n    function receive(data, onmessage, userid) {\n        // uuid is used"
  },
  {
    "path": "DataChannel/dev/TextSender.js",
    "chars": 1540,
    "preview": "var TextSender = {\n    send: function(config) {\n        var root = config.root;\n\n        var channel = config.channel;\n "
  },
  {
    "path": "DataChannel/dev/externalIceServers.js",
    "chars": 1036,
    "preview": "var loadedIceFrame;\n\nfunction loadIceFrame(callback, skip) {\n    if (loadedIceFrame) {\n        return;\n    }\n\n    if (!s"
  },
  {
    "path": "DataChannel/dev/globals.js",
    "chars": 1039,
    "preview": "var moz = !!navigator.mozGetUserMedia;\nvar IsDataChannelSupported = !((moz && !navigator.mozGetUserMedia) || (!moz && !n"
  },
  {
    "path": "DataChannel/dev/head.js",
    "chars": 14,
    "preview": "(function() {\n"
  },
  {
    "path": "DataChannel/dev/tail.js",
    "chars": 6,
    "preview": "})();\n"
  },
  {
    "path": "DataChannel/index.html",
    "chars": 14618,
    "preview": "<!--\n> Muaz Khan     - https://github.com/muaz-khan \n> MIT License   - https://www.webrtc-experiment.com/licence/\n> Doc"
  },
  {
    "path": "DataChannel/package.json",
    "chars": 1490,
    "preview": "{\n  \"name\": \"datachannel\",\n  \"preferGlobal\": false,\n  \"version\": \"1.0.0\",\n  \"author\": {\n    \"name\": \"Muaz Khan\",\n    \"em"
  },
  {
    "path": "DataChannel/server.js",
    "chars": 2066,
    "preview": "// http://127.0.0.1:9001\n// http://localhost:9001\n\nvar port = 9001;\n\nvar server = require('http'),\n    url = require('ur"
  },
  {
    "path": "DataChannel/simple.html",
    "chars": 14615,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n\n    <head>\n        <title>File Sharing + Text Chat using WebRTC DataChannel</title>\n "
  }
]

// ... and 781 more files (download for full content)

About this extraction

This page contains the full source code of the muaz-khan/WebRTC-Experiment GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 981 files (15.3 MB), approximately 4.1M tokens, and a symbol index with 2982 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!