From e5e330034ff92a98a1f9bc6bbf60590101350d9a Mon Sep 17 00:00:00 2001 From: Hadi Nategh Date: Tue, 9 Jun 2015 07:43:19 +0000 Subject: [PATCH] Remove the Messenger app from trunk --- messenger/inc/class.messenger_hooks.inc.php | 76 - messenger/inc/class.messenger_ui.inc.php | 187 - messenger/js/app.js | 126 - messenger/js/easyrtc/README.md | 32 - messenger/js/easyrtc/easyrtc.js | 5468 - .../easyrtc/node_modules/easyrtc/.npmignore | 182 - .../js/easyrtc/node_modules/easyrtc/LICENSE | 23 - .../js/easyrtc/node_modules/easyrtc/README.md | 147 - .../node_modules/easyrtc/api/adapter.js | 184 - .../easyrtc/api/buildEnglishVersions.bat | 1 - .../easyrtc/api/buildEnglishVersions.sh | 2 - .../node_modules/easyrtc/api/easyrtc.css | 74 - .../node_modules/easyrtc/api/easyrtc.js | 5468 - .../node_modules/easyrtc/api/easyrtc_ft.js | 748 - .../node_modules/easyrtc/api/easyrtc_int.js | 5270 - .../easyrtc/api/easyrtc_lang_en.js | 15 - .../node_modules/easyrtc/api/img/LICENSE | 6 - .../node_modules/easyrtc/api/img/easyrtc.png | Bin 3483 -> 0 bytes .../easyrtc/api/img/powered_by_easyrtc.png | Bin 4178 -> 0 bytes .../easyrtc/api/img/priologic_logo_white.png | Bin 2810 -> 0 bytes .../node_modules/easyrtc/api/img/x.svg | 27 - .../node_modules/easyrtc/api/labs/README.md | 3 - .../easyrtc/api/labs/desktopCapture.zip | Bin 4718 -> 0 bytes .../labs/desktop_capture_iframe_version.js | 122 - .../labs/desktop_capture_no_iframe_version.js | 166 - .../easyrtc/api/labs/easyrtc_rates.js | 245 - .../easyrtc/api/labs/inline-installcode.html | 36 - .../node_modules/easyrtc/demos/css/demo4.css | 47 - .../demos/css/demo_audio_video_simple.css | 27 - .../demos/css/demo_audio_video_simple_hd.css | 51 - .../easyrtc/demos/css/demo_lowbandwidth.css | 27 - .../easyrtc/demos/css/demo_room.css | 74 - .../easyrtc/demos/css/landing.css | 125 - .../node_modules/easyrtc/demos/demo4.html | 118 - .../easyrtc/demos/demo_audio_only.html | 128 - .../easyrtc/demos/demo_audio_video.html | 146 - .../demos/demo_audio_video_simple.html | 98 - .../demos/demo_audio_video_simple_hd.html | 95 - .../demos/demo_data_channel_filesharing.html | 141 - .../demos/demo_data_channel_messaging.html | 105 - .../easyrtc/demos/demo_ice_filter.html | 95 - .../easyrtc/demos/demo_instant_messaging.html | 104 - .../demos/demo_instant_messaging_rooms.html | 194 - .../demo_instant_messaging_selfconnect.html | 106 - .../easyrtc/demos/demo_lowbandwidth.html | 100 - .../easyrtc/demos/demo_multiparty.html | 32 - .../easyrtc/demos/demo_multistream.html | 147 - .../demos/demo_multistream_iframe.html | 148 - .../demos/demo_multistream_no_iframe.html | 153 - .../easyrtc/demos/demo_reconnect.html | 20 - .../node_modules/easyrtc/demos/demo_room.html | 32 - .../easyrtc/demos/demo_screen_receive.html | 168 - .../easyrtc/demos/demo_screen_send.html | 121 - .../easyrtc/demos/demo_video_only.html | 135 - .../node_modules/easyrtc/demos/images/LICENSE | 8 - .../easyrtc/demos/images/bg_dark.png | Bin 9165 -> 0 bytes .../easyrtc/demos/images/bg_light.png | Bin 8552 -> 0 bytes .../easyrtc/demos/images/blank.gif | Bin 43 -> 0 bytes .../easyrtc/demos/images/br_chrome.png | Bin 1891 -> 0 bytes .../easyrtc/demos/images/br_chrome_canary.png | Bin 1566 -> 0 bytes .../easyrtc/demos/images/br_ff.png | Bin 2818 -> 0 bytes .../easyrtc/demos/images/br_ff_aurora.png | Bin 2621 -> 0 bytes .../easyrtc/demos/images/br_ff_nightly.png | Bin 2631 -> 0 bytes .../easyrtc/demos/images/br_ie.png | Bin 2344 -> 0 bytes .../easyrtc/demos/images/br_opera.png | Bin 1921 -> 0 bytes .../easyrtc/demos/images/br_safari.png | Bin 2460 -> 0 bytes .../easyrtc/demos/images/br_status_fail.png | Bin 507 -> 0 bytes .../easyrtc/demos/images/br_status_pass.png | Bin 390 -> 0 bytes .../easyrtc/demos/images/br_status_warn.png | Bin 819 -> 0 bytes .../easyrtc/demos/images/button_close.png | Bin 4303 -> 0 bytes .../easyrtc/demos/images/button_mute.png | Bin 6011 -> 0 bytes .../easyrtc/demos/images/button_refresh.png | Bin 1619 -> 0 bytes .../easyrtc/demos/images/button_unmute.png | Bin 7915 -> 0 bytes .../demos/images/by_priologic_logo.png | Bin 2492 -> 0 bytes .../easyrtc/demos/images/cloud.png | Bin 9714 -> 0 bytes .../easyrtc/demos/images/easyrtc_logo.png | Bin 3483 -> 0 bytes .../easyrtc/demos/images/irongrip.png | Bin 56156 -> 0 bytes .../demos/images/powered_by_easyrtc.png | Bin 4178 -> 0 bytes .../demos/images/priologic_logo_white.png | Bin 2810 -> 0 bytes .../easyrtc/demos/images/textEntry.png | Bin 3232 -> 0 bytes .../node_modules/easyrtc/demos/index.html | 265 - .../node_modules/easyrtc/demos/js/demo4.js | 89 - .../easyrtc/demos/js/demo_audio_only.js | 169 - .../easyrtc/demos/js/demo_audio_video.js | 193 - .../demos/js/demo_audio_video_simple.js | 54 - .../demos/js/demo_audio_video_simple_hd.js | 91 - .../demos/js/demo_data_channel_filesharing.js | 292 - .../demos/js/demo_data_channel_messaging.js | 172 - .../easyrtc/demos/js/demo_ice_filter.js | 84 - .../demos/js/demo_instant_messaging.js | 87 - .../demos/js/demo_instant_messaging_rooms.js | 418 - .../js/demo_instant_messaging_selfconnect.js | 111 - .../easyrtc/demos/js/demo_lowbandwidth.js | 61 - .../easyrtc/demos/js/demo_multiparty.js | 727 - .../easyrtc/demos/js/demo_multistream.js | 255 - .../demos/js/demo_multistream_iframe.js | 249 - .../demos/js/demo_multistream_no_iframe.js | 265 - .../easyrtc/demos/js/demo_reconnect.js | 73 - .../easyrtc/demos/js/demo_room.js | 726 - .../easyrtc/demos/js/demo_screen_receive.js | 209 - .../easyrtc/demos/js/demo_screen_send.js | 156 - .../easyrtc/demos/js/demo_video_only.js | 176 - .../easyrtc/demos/js/prettify/README | 214 - .../demos/js/prettify/jquery-1.9.1.min.js | 5 - .../easyrtc/demos/js/prettify/jquery.js | 8829 -- .../easyrtc/demos/js/prettify/jquery.min.js | 4 - .../easyrtc/demos/js/prettify/lang-css.js | 2 - .../easyrtc/demos/js/prettify/lang-sql.js | 2 - .../easyrtc/demos/js/prettify/lang-vhdl.js | 3 - .../easyrtc/demos/js/prettify/lang-yaml.js | 2 - .../demos/js/prettify/loadAndFilter.js | 124 - .../easyrtc/demos/js/prettify/prettify.css | 1 - .../easyrtc/demos/js/prettify/prettify.js | 28 - .../node_modules/easyrtc/dev/readme.md | 6 - .../scripts/client_jsdoc_templates/README.md | 1 - .../scripts/client_jsdoc_templates/publish.js | 513 - .../scripts/prettify/Apache-License-2.0.txt | 202 - .../static/scripts/prettify/lang-css.js | 2 - .../static/scripts/prettify/prettify.js | 28 - .../static/styles/jsdoc-default.css | 240 - .../static/styles/prettify-jsdoc.css | 111 - .../static/styles/prettify-tomorrow.css | 132 - .../tmpl/container.tmpl | 123 - .../client_jsdoc_templates/tmpl/details.tmpl | 93 - .../client_jsdoc_templates/tmpl/example.tmpl | 2 - .../client_jsdoc_templates/tmpl/examples.tmpl | 11 - .../tmpl/exceptions.tmpl | 19 - .../client_jsdoc_templates/tmpl/fires.tmpl | 4 - .../client_jsdoc_templates/tmpl/layout.tmpl | 26 - .../client_jsdoc_templates/tmpl/mainpage.tmpl | 14 - .../client_jsdoc_templates/tmpl/members.tmpl | 22 - .../client_jsdoc_templates/tmpl/method.tmpl | 76 - .../client_jsdoc_templates/tmpl/params.tmpl | 108 - .../tmpl/properties.tmpl | 107 - .../client_jsdoc_templates/tmpl/returns.tmpl | 19 - .../client_jsdoc_templates/tmpl/source.tmpl | 8 - .../client_jsdoc_templates/tmpl/tutorial.tmpl | 19 - .../client_jsdoc_templates/tmpl/type.tmpl | 7 - .../scripts/client_jsdoc_templates2/README.md | 1 - .../client_jsdoc_templates2/publish.js | 513 - .../scripts/prettify/Apache-License-2.0.txt | 202 - .../static/scripts/prettify/lang-css.js | 2 - .../static/scripts/prettify/prettify.js | 28 - .../static/styles/jsdoc-default.css | 239 - .../static/styles/prettify-jsdoc.css | 111 - .../static/styles/prettify-tomorrow.css | 132 - .../tmpl/container.tmpl | 123 - .../client_jsdoc_templates2/tmpl/details.tmpl | 93 - .../client_jsdoc_templates2/tmpl/example.tmpl | 2 - .../tmpl/examples.tmpl | 11 - .../tmpl/exceptions.tmpl | 19 - .../client_jsdoc_templates2/tmpl/fires.tmpl | 4 - .../client_jsdoc_templates2/tmpl/layout.tmpl | 26 - .../tmpl/mainpage.tmpl | 14 - .../client_jsdoc_templates2/tmpl/members.tmpl | 22 - .../client_jsdoc_templates2/tmpl/method.tmpl | 76 - .../client_jsdoc_templates2/tmpl/params.tmpl | 108 - .../tmpl/properties.tmpl | 107 - .../client_jsdoc_templates2/tmpl/returns.tmpl | 19 - .../client_jsdoc_templates2/tmpl/source.tmpl | 8 - .../tmpl/tutorial.tmpl | 19 - .../client_jsdoc_templates2/tmpl/type.tmpl | 7 - .../easyrtc/dev/scripts/readme.md | 6 - .../dev/scripts/updateEasyrtcJsDocs.bat | 5 - .../dev/scripts/updateEasyrtc_ftJsDocs.bat | 4 - .../dev/scripts/update_server_docs.bat | 1 - .../docs/client_html_docs/easyrtc.html | 12917 -- .../docs/client_html_docs/easyrtc_ft.html | 582 - .../jsdoc/styles/jsdoc-client.css | 239 - .../client_html_docs/scripts/linenumber.js | 17 - .../scripts/prettify/Apache-License-2.0.txt | 202 - .../scripts/prettify/lang-css.js | 2 - .../scripts/prettify/prettify.js | 28 - .../client_html_docs/styles/jsdoc-default.css | 240 - .../styles/prettify-jsdoc.css | 111 - .../styles/prettify-tomorrow.css | 132 - .../easyrtc/docs/easyrtc_authentication.md | 105 - .../easyrtc/docs/easyrtc_changelog.md | 507 - .../easyrtc/docs/easyrtc_client_tutorial.md | 627 - .../node_modules/easyrtc/docs/easyrtc_faq.md | 137 - .../easyrtc/docs/easyrtc_rooms.md | 117 - .../docs/easyrtc_server_configuration.md | 239 - .../easyrtc/docs/easyrtc_server_events.md | 72 - .../easyrtc/docs/easyrtc_server_ice.md | 101 - .../easyrtc/docs/easyrtc_server_install.md | 210 - .../easyrtc/docs/easyrtc_server_msgtypes.md | 474 - .../easyrtc/docs/easyrtc_server_ssl.md | 68 - .../easyrtc/docs/easyrtc_upcoming_features.md | 49 - .../easyrtc/docs/easyrtc_webrtc_problems.md | 98 - .../docs/easyrtc_with_other_servers.md | 49 - .../easyrtc_default_event_listeners.js.html | 1647 - .../easyrtc_public_obj.js.html | 3332 - .../easyrtc/docs/server_html_docs/global.html | 755 - .../easyrtc/docs/server_html_docs/index.html | 62 - ...default_event_listeners-eventListener.html | 4782 - ...odule-easyrtc_default_event_listeners.html | 141 - .../module-easyrtc_public_obj-pub.events.html | 832 - .../module-easyrtc_public_obj-pub.html | 1399 - .../module-easyrtc_public_obj-pub.util.html | 2779 - .../module-easyrtc_public_obj.html | 141 - ...ppObj.connectionObj.connectionRoomObj.html | 1225 - .../pub.appObj.connectionObj.html | 3609 - .../docs/server_html_docs/pub.appObj.html | 3684 - .../server_html_docs/pub.appObj.roomObj.html | 1929 - .../pub.appObj.sessionObj.html | 1274 - .../server_html_docs/scripts/linenumber.js | 17 - .../scripts/prettify/Apache-License-2.0.txt | 202 - .../scripts/prettify/lang-css.js | 2 - .../scripts/prettify/prettify.js | 28 - .../server_html_docs/styles/jsdoc-default.css | 283 - .../styles/prettify-jsdoc.css | 111 - .../styles/prettify-tomorrow.css | 132 - .../js/easyrtc/node_modules/easyrtc/index.js | 2 - .../lib/easyrtc_default_event_listeners.js | 1616 - .../easyrtc/lib/easyrtc_default_options.js | 80 - .../easyrtc/lib/easyrtc_private_obj.js | 20 - .../easyrtc/lib/easyrtc_public_obj.js | 3389 - .../easyrtc/lib/easyrtc_server.js | 127 - .../node_modules/easyrtc/lib/easyrtc_util.js | 155 - .../node_modules/easyrtc/lib/general_util.js | 133 - .../easyrtc/node_modules/async/LICENSE | 19 - .../easyrtc/node_modules/async/README.md | 1425 - .../easyrtc/node_modules/async/component.json | 11 - .../easyrtc/node_modules/async/lib/async.js | 958 - .../easyrtc/node_modules/async/package.json | 60 - .../easyrtc/node_modules/colors/LICENSE | 23 - .../easyrtc/node_modules/colors/ReadMe.md | 177 - .../colors/examples/normal-usage.js | 74 - .../colors/examples/safe-string.js | 76 - .../easyrtc/node_modules/colors/lib/colors.js | 187 - .../node_modules/colors/lib/custom/trap.js | 45 - .../node_modules/colors/lib/custom/zalgo.js | 104 - .../colors/lib/extendStringPrototype.js | 113 - .../easyrtc/node_modules/colors/lib/index.js | 12 - .../node_modules/colors/lib/maps/america.js | 12 - .../node_modules/colors/lib/maps/rainbow.js | 13 - .../node_modules/colors/lib/maps/random.js | 8 - .../node_modules/colors/lib/maps/zebra.js | 5 - .../easyrtc/node_modules/colors/lib/styles.js | 77 - .../colors/lib/system/supports-colors.js | 61 - .../easyrtc/node_modules/colors/package.json | 59 - .../easyrtc/node_modules/colors/safe.js | 9 - .../colors/themes/generic-logging.js | 12 - .../easyrtc/node_modules/underscore/LICENSE | 23 - .../easyrtc/node_modules/underscore/README.md | 22 - .../node_modules/underscore/package.json | 63 - .../node_modules/underscore/underscore-min.js | 6 - .../node_modules/underscore/underscore.js | 1276 - .../easyrtc/node_modules/easyrtc/package.json | 56 - .../easyrtc/server_example/README.md | 32 - .../easyrtc/server_example/package.json | 24 - .../easyrtc/server_example/server.js | 18 - .../easyrtc/server_example/static/index.html | 20 - .../easyrtc/node_modules/express/History.md | 2829 - .../js/easyrtc/node_modules/express/LICENSE | 24 - .../js/easyrtc/node_modules/express/Readme.md | 138 - .../js/easyrtc/node_modules/express/index.js | 2 - .../node_modules/express/lib/application.js | 607 - .../node_modules/express/lib/express.js | 93 - .../express/lib/middleware/init.js | 26 - .../express/lib/middleware/query.js | 30 - .../node_modules/express/lib/request.js | 467 - .../node_modules/express/lib/response.js | 1030 - .../node_modules/express/lib/router/index.js | 630 - .../node_modules/express/lib/router/layer.js | 166 - .../node_modules/express/lib/router/route.js | 183 - .../easyrtc/node_modules/express/lib/utils.js | 293 - .../easyrtc/node_modules/express/lib/view.js | 142 - .../express/node_modules/accepts/HISTORY.md | 130 - .../express/node_modules/accepts/LICENSE | 22 - .../express/node_modules/accepts/README.md | 135 - .../express/node_modules/accepts/index.js | 160 - .../node_modules/mime-types/HISTORY.md | 109 - .../accepts/node_modules/mime-types/LICENSE | 22 - .../accepts/node_modules/mime-types/README.md | 102 - .../accepts/node_modules/mime-types/index.js | 63 - .../node_modules/mime-db/HISTORY.md | 204 - .../mime-types/node_modules/mime-db/LICENSE | 22 - .../mime-types/node_modules/mime-db/README.md | 76 - .../mime-types/node_modules/mime-db/db.json | 6345 - .../mime-types/node_modules/mime-db/index.js | 11 - .../node_modules/mime-db/package.json | 93 - .../node_modules/mime-types/package.json | 83 - .../node_modules/negotiator/HISTORY.md | 76 - .../accepts/node_modules/negotiator/LICENSE | 24 - .../accepts/node_modules/negotiator/README.md | 203 - .../accepts/node_modules/negotiator/index.js | 62 - .../node_modules/negotiator/lib/charset.js | 102 - .../node_modules/negotiator/lib/encoding.js | 118 - .../node_modules/negotiator/lib/language.js | 112 - .../node_modules/negotiator/lib/mediaType.js | 179 - .../node_modules/negotiator/package.json | 85 - .../express/node_modules/accepts/package.json | 97 - .../content-disposition/HISTORY.md | 40 - .../node_modules/content-disposition/LICENSE | 22 - .../content-disposition/README.md | 141 - .../node_modules/content-disposition/index.js | 443 - .../content-disposition/package.json | 66 - .../node_modules/content-type/HISTORY.md | 9 - .../express/node_modules/content-type/LICENSE | 22 - .../node_modules/content-type/README.md | 92 - .../node_modules/content-type/index.js | 214 - .../node_modules/content-type/package.json | 65 - .../node_modules/cookie-signature/.npmignore | 4 - .../node_modules/cookie-signature/History.md | 38 - .../node_modules/cookie-signature/Readme.md | 42 - .../node_modules/cookie-signature/index.js | 51 - .../cookie-signature/package.json | 58 - .../express/node_modules/cookie/.npmignore | 2 - .../express/node_modules/cookie/LICENSE | 9 - .../express/node_modules/cookie/README.md | 44 - .../express/node_modules/cookie/index.js | 75 - .../express/node_modules/cookie/package.json | 53 - .../express/node_modules/debug/.jshintrc | 3 - .../express/node_modules/debug/.npmignore | 6 - .../express/node_modules/debug/History.md | 195 - .../express/node_modules/debug/Makefile | 36 - .../express/node_modules/debug/Readme.md | 188 - .../express/node_modules/debug/bower.json | 28 - .../express/node_modules/debug/browser.js | 168 - .../express/node_modules/debug/component.json | 19 - .../express/node_modules/debug/debug.js | 197 - .../express/node_modules/debug/node.js | 209 - .../debug/node_modules/ms/.npmignore | 5 - .../debug/node_modules/ms/History.md | 66 - .../debug/node_modules/ms/LICENSE | 20 - .../debug/node_modules/ms/README.md | 35 - .../debug/node_modules/ms/index.js | 125 - .../debug/node_modules/ms/package.json | 47 - .../express/node_modules/debug/package.json | 72 - .../express/node_modules/depd/History.md | 75 - .../express/node_modules/depd/LICENSE | 22 - .../express/node_modules/depd/Readme.md | 274 - .../express/node_modules/depd/index.js | 529 - .../depd/lib/compat/buffer-concat.js | 33 - .../depd/lib/compat/callsite-tostring.js | 101 - .../node_modules/depd/lib/compat/index.js | 69 - .../express/node_modules/depd/package.json | 66 - .../node_modules/escape-html/.npmignore | 2 - .../express/node_modules/escape-html/Makefile | 11 - .../node_modules/escape-html/Readme.md | 15 - .../node_modules/escape-html/component.json | 10 - .../express/node_modules/escape-html/index.js | 16 - .../node_modules/escape-html/package.json | 46 - .../express/node_modules/etag/HISTORY.md | 62 - .../express/node_modules/etag/LICENSE | 22 - .../express/node_modules/etag/README.md | 150 - .../express/node_modules/etag/index.js | 166 - .../etag/node_modules/crc/.npmignore | 5 - .../etag/node_modules/crc/LICENSE | 22 - .../etag/node_modules/crc/README.md | 98 - .../etag/node_modules/crc/lib/crc.js | 71 - .../etag/node_modules/crc/lib/crc1.js | 21 - .../etag/node_modules/crc/lib/crc16.js | 25 - .../etag/node_modules/crc/lib/crc16_ccitt.js | 25 - .../etag/node_modules/crc/lib/crc16_modbus.js | 25 - .../etag/node_modules/crc/lib/crc24.js | 25 - .../etag/node_modules/crc/lib/crc32.js | 25 - .../etag/node_modules/crc/lib/crc8.js | 25 - .../etag/node_modules/crc/lib/crc8_1wire.js | 25 - .../etag/node_modules/crc/lib/create.js | 11 - .../etag/node_modules/crc/lib/hex.js | 9 - .../etag/node_modules/crc/lib/index.js | 11 - .../etag/node_modules/crc/package.json | 57 - .../express/node_modules/etag/package.json | 75 - .../node_modules/finalhandler/HISTORY.md | 76 - .../express/node_modules/finalhandler/LICENSE | 22 - .../node_modules/finalhandler/README.md | 133 - .../node_modules/finalhandler/index.js | 171 - .../node_modules/finalhandler/package.json | 79 - .../express/node_modules/fresh/HISTORY.md | 24 - .../express/node_modules/fresh/LICENSE | 22 - .../express/node_modules/fresh/README.md | 58 - .../express/node_modules/fresh/index.js | 53 - .../express/node_modules/fresh/package.json | 76 - .../node_modules/merge-descriptors/LICENSE | 22 - .../node_modules/merge-descriptors/README.md | 34 - .../node_modules/merge-descriptors/index.js | 57 - .../merge-descriptors/package.json | 124 - .../express/node_modules/methods/HISTORY.md | 24 - .../express/node_modules/methods/LICENSE | 23 - .../express/node_modules/methods/README.md | 41 - .../express/node_modules/methods/index.js | 42 - .../express/node_modules/methods/package.json | 88 - .../node_modules/on-finished/HISTORY.md | 81 - .../express/node_modules/on-finished/LICENSE | 23 - .../node_modules/on-finished/README.md | 109 - .../express/node_modules/on-finished/index.js | 191 - .../on-finished/node_modules/ee-first/LICENSE | 22 - .../node_modules/ee-first/README.md | 80 - .../node_modules/ee-first/index.js | 68 - .../node_modules/ee-first/package.json | 63 - .../node_modules/on-finished/package.json | 71 - .../express/node_modules/parseurl/.npmignore | 4 - .../express/node_modules/parseurl/HISTORY.md | 42 - .../express/node_modules/parseurl/LICENSE | 24 - .../express/node_modules/parseurl/README.md | 107 - .../express/node_modules/parseurl/index.js | 136 - .../node_modules/parseurl/package.json | 80 - .../node_modules/path-to-regexp/.npmignore | 2 - .../node_modules/path-to-regexp/History.md | 16 - .../node_modules/path-to-regexp/Readme.md | 33 - .../path-to-regexp/component.json | 15 - .../node_modules/path-to-regexp/index.js | 70 - .../node_modules/path-to-regexp/package.json | 161 - .../node_modules/path-to-regexp/test.js | 616 - .../node_modules/proxy-addr/HISTORY.md | 66 - .../express/node_modules/proxy-addr/LICENSE | 22 - .../express/node_modules/proxy-addr/README.md | 137 - .../express/node_modules/proxy-addr/index.js | 345 - .../node_modules/forwarded/HISTORY.md | 4 - .../proxy-addr/node_modules/forwarded/LICENSE | 22 - .../node_modules/forwarded/README.md | 53 - .../node_modules/forwarded/index.js | 35 - .../node_modules/forwarded/package.json | 65 - .../node_modules/ipaddr.js/.npmignore | 2 - .../node_modules/ipaddr.js/Cakefile | 18 - .../proxy-addr/node_modules/ipaddr.js/LICENSE | 19 - .../node_modules/ipaddr.js/README.md | 161 - .../node_modules/ipaddr.js/ipaddr.min.js | 1 - .../node_modules/ipaddr.js/lib/ipaddr.js | 439 - .../node_modules/ipaddr.js/package.json | 58 - .../node_modules/ipaddr.js/src/ipaddr.coffee | 374 - .../ipaddr.js/test/ipaddr.test.coffee | 262 - .../node_modules/proxy-addr/package.json | 89 - .../express/node_modules/qs/.jshintignore | 1 - .../express/node_modules/qs/.jshintrc | 10 - .../express/node_modules/qs/.npmignore | 18 - .../express/node_modules/qs/.travis.yml | 6 - .../express/node_modules/qs/CHANGELOG.md | 73 - .../express/node_modules/qs/CONTRIBUTING.md | 1 - .../express/node_modules/qs/LICENSE | 28 - .../express/node_modules/qs/Makefile | 8 - .../express/node_modules/qs/README.md | 233 - .../express/node_modules/qs/index.js | 1 - .../express/node_modules/qs/lib/index.js | 15 - .../express/node_modules/qs/lib/parse.js | 157 - .../express/node_modules/qs/lib/stringify.js | 97 - .../express/node_modules/qs/lib/utils.js | 132 - .../express/node_modules/qs/package.json | 58 - .../express/node_modules/qs/test/parse.js | 414 - .../express/node_modules/qs/test/stringify.js | 209 - .../node_modules/range-parser/HISTORY.md | 35 - .../express/node_modules/range-parser/LICENSE | 22 - .../node_modules/range-parser/README.md | 48 - .../node_modules/range-parser/index.js | 49 - .../node_modules/range-parser/package.json | 76 - .../express/node_modules/send/HISTORY.md | 274 - .../express/node_modules/send/LICENSE | 23 - .../express/node_modules/send/README.md | 195 - .../express/node_modules/send/index.js | 797 - .../node_modules/send/node_modules/.bin/mime | 1 - .../send/node_modules/destroy/README.md | 38 - .../send/node_modules/destroy/index.js | 36 - .../send/node_modules/destroy/package.json | 67 - .../send/node_modules/mime/.npmignore | 0 .../send/node_modules/mime/LICENSE | 19 - .../send/node_modules/mime/README.md | 90 - .../send/node_modules/mime/build/build.js | 11 - .../send/node_modules/mime/build/test.js | 57 - .../send/node_modules/mime/cli.js | 8 - .../send/node_modules/mime/mime.js | 108 - .../send/node_modules/mime/package.json | 73 - .../send/node_modules/mime/types.json | 1 - .../send/node_modules/ms/.npmignore | 5 - .../send/node_modules/ms/History.md | 66 - .../node_modules/send/node_modules/ms/LICENSE | 20 - .../send/node_modules/ms/README.md | 35 - .../send/node_modules/ms/index.js | 125 - .../send/node_modules/ms/package.json | 47 - .../express/node_modules/send/package.json | 86 - .../node_modules/serve-static/HISTORY.md | 259 - .../express/node_modules/serve-static/LICENSE | 25 - .../node_modules/serve-static/README.md | 216 - .../node_modules/serve-static/index.js | 138 - .../node_modules/serve-static/package.json | 83 - .../express/node_modules/type-is/HISTORY.md | 133 - .../express/node_modules/type-is/LICENSE | 21 - .../express/node_modules/type-is/README.md | 117 - .../express/node_modules/type-is/index.js | 224 - .../node_modules/media-typer/HISTORY.md | 22 - .../type-is/node_modules/media-typer/LICENSE | 22 - .../node_modules/media-typer/README.md | 81 - .../type-is/node_modules/media-typer/index.js | 270 - .../node_modules/media-typer/package.json | 58 - .../node_modules/mime-types/HISTORY.md | 109 - .../type-is/node_modules/mime-types/LICENSE | 22 - .../type-is/node_modules/mime-types/README.md | 102 - .../type-is/node_modules/mime-types/index.js | 63 - .../node_modules/mime-db/HISTORY.md | 204 - .../mime-types/node_modules/mime-db/LICENSE | 22 - .../mime-types/node_modules/mime-db/README.md | 76 - .../mime-types/node_modules/mime-db/db.json | 6345 - .../mime-types/node_modules/mime-db/index.js | 11 - .../node_modules/mime-db/package.json | 93 - .../node_modules/mime-types/package.json | 83 - .../express/node_modules/type-is/package.json | 92 - .../node_modules/utils-merge/.travis.yml | 6 - .../express/node_modules/utils-merge/LICENSE | 20 - .../node_modules/utils-merge/README.md | 34 - .../express/node_modules/utils-merge/index.js | 23 - .../node_modules/utils-merge/package.json | 60 - .../express/node_modules/vary/.npmignore | 3 - .../express/node_modules/vary/History.md | 16 - .../express/node_modules/vary/LICENSE | 22 - .../express/node_modules/vary/README.md | 59 - .../express/node_modules/vary/index.js | 112 - .../express/node_modules/vary/package.json | 71 - .../easyrtc/node_modules/express/package.json | 165 - .../easyrtc/node_modules/socket.io/.npmignore | 3 - .../node_modules/socket.io/.travis.yml | 6 - .../easyrtc/node_modules/socket.io/History.md | 332 - .../js/easyrtc/node_modules/socket.io/LICENSE | 22 - .../easyrtc/node_modules/socket.io/Makefile | 31 - .../easyrtc/node_modules/socket.io/Readme.md | 364 - .../socket.io/benchmarks/decode.bench.js | 64 - .../socket.io/benchmarks/encode.bench.js | 90 - .../socket.io/benchmarks/runner.js | 55 - .../easyrtc/node_modules/socket.io/index.js | 8 - .../js/easyrtc/node_modules/socket.io/latest | 2 - .../node_modules/socket.io/lib/logger.js | 97 - .../node_modules/socket.io/lib/manager.js | 1042 - .../node_modules/socket.io/lib/namespace.js | 355 - .../node_modules/socket.io/lib/parser.js | 249 - .../node_modules/socket.io/lib/socket.io.js | 143 - .../node_modules/socket.io/lib/socket.js | 369 - .../node_modules/socket.io/lib/static.js | 395 - .../node_modules/socket.io/lib/store.js | 98 - .../socket.io/lib/stores/memory.js | 143 - .../socket.io/lib/stores/redis.js | 269 - .../node_modules/socket.io/lib/transport.js | 516 - .../socket.io/lib/transports/flashsocket.js | 129 - .../socket.io/lib/transports/htmlfile.js | 83 - .../socket.io/lib/transports/http-polling.js | 147 - .../socket.io/lib/transports/http.js | 122 - .../socket.io/lib/transports/index.js | 12 - .../socket.io/lib/transports/jsonp-polling.js | 97 - .../socket.io/lib/transports/websocket.js | 36 - .../lib/transports/websocket/default.js | 376 - .../lib/transports/websocket/hybi-07-12.js | 642 - .../lib/transports/websocket/hybi-16.js | 642 - .../lib/transports/websocket/index.js | 11 - .../socket.io/lib/transports/xhr-polling.js | 69 - .../node_modules/socket.io/lib/util.js | 50 - .../node_modules/base64id/.npmignore | 3 - .../socket.io/node_modules/base64id/README.md | 18 - .../node_modules/base64id/lib/base64id.js | 103 - .../node_modules/base64id/package.json | 43 - .../node_modules/policyfile/.gitignore | 1 - .../socket.io/node_modules/policyfile/LICENSE | 19 - .../node_modules/policyfile/Makefile | 7 - .../node_modules/policyfile/README.md | 98 - .../node_modules/policyfile/doc/index.html | 375 - .../policyfile/examples/basic.fallback.js | 8 - .../node_modules/policyfile/examples/basic.js | 5 - .../node_modules/policyfile/index.js | 1 - .../node_modules/policyfile/lib/server.js | 289 - .../node_modules/policyfile/package.json | 67 - .../node_modules/policyfile/tests/ssl/ssl.crt | 21 - .../policyfile/tests/ssl/ssl.private.key | 27 - .../policyfile/tests/unit.test.js | 231 - .../socket.io/node_modules/redis/.npmignore | 1 - .../socket.io/node_modules/redis/README.md | 691 - .../redis/benches/buffer_bench.js | 89 - .../redis/benches/hiredis_parser.js | 38 - .../node_modules/redis/benches/re_sub_test.js | 14 - .../redis/benches/reconnect_test.js | 29 - .../redis/benches/stress/codec.js | 16 - .../redis/benches/stress/pubsub/pub.js | 38 - .../redis/benches/stress/pubsub/run | 10 - .../redis/benches/stress/pubsub/server.js | 23 - .../redis/benches/stress/rpushblpop/pub.js | 49 - .../redis/benches/stress/rpushblpop/run | 6 - .../redis/benches/stress/rpushblpop/server.js | 30 - .../redis/benches/stress/speed/00 | 13 - .../redis/benches/stress/speed/plot | 13 - .../redis/benches/stress/speed/size-rate.png | Bin 6672 -> 0 bytes .../redis/benches/stress/speed/speed.js | 84 - .../redis/benches/sub_quit_test.js | 18 - .../socket.io/node_modules/redis/changelog.md | 219 - .../redis/diff_multi_bench_output.js | 87 - .../node_modules/redis/examples/auth.js | 5 - .../redis/examples/backpressure_drain.js | 33 - .../node_modules/redis/examples/eval.js | 9 - .../node_modules/redis/examples/extend.js | 24 - .../node_modules/redis/examples/file.js | 32 - .../node_modules/redis/examples/mget.js | 5 - .../node_modules/redis/examples/monitor.js | 10 - .../node_modules/redis/examples/multi.js | 46 - .../node_modules/redis/examples/multi2.js | 29 - .../node_modules/redis/examples/psubscribe.js | 33 - .../node_modules/redis/examples/pub_sub.js | 41 - .../node_modules/redis/examples/simple.js | 24 - .../node_modules/redis/examples/sort.js | 17 - .../node_modules/redis/examples/subqueries.js | 15 - .../node_modules/redis/examples/subquery.js | 19 - .../redis/examples/unix_socket.js | 29 - .../node_modules/redis/examples/web_server.js | 31 - .../node_modules/redis/generate_commands.js | 39 - .../socket.io/node_modules/redis/index.js | 1113 - .../node_modules/redis/lib/commands.js | 147 - .../node_modules/redis/lib/parser/hiredis.js | 46 - .../redis/lib/parser/javascript.js | 317 - .../socket.io/node_modules/redis/lib/queue.js | 61 - .../node_modules/redis/lib/to_array.js | 12 - .../socket.io/node_modules/redis/lib/util.js | 11 - .../socket.io/node_modules/redis/mem.js | 11 - .../node_modules/redis/multi_bench.js | 225 - .../socket.io/node_modules/redis/package.json | 48 - .../socket.io/node_modules/redis/test.js | 1618 - .../node_modules/socket.io-client/.npmignore | 2 - .../node_modules/socket.io-client/History.md | 237 - .../node_modules/socket.io-client/Makefile | 20 - .../node_modules/socket.io-client/README.md | 246 - .../socket.io-client/bin/builder.js | 303 - .../components/component-bind/component.json | 14 - .../components/component-bind/index.js | 24 - .../component-emitter/component.json | 13 - .../components/component-emitter/index.js | 147 - .../component-json-fallback/component.json | 15 - .../component-json-fallback/index.js | 486 - .../components/component-json/component.json | 17 - .../components/component-json/index.js | 4 - .../component.json | 24 - .../lib/emitter.js | 52 - .../learnboost-engine.io-client/lib/index.js | 2 - .../learnboost-engine.io-client/lib/parser.js | 163 - .../learnboost-engine.io-client/lib/socket.js | 492 - .../lib/transport.js | 141 - .../lib/transports/flashsocket.js | 254 - .../lib/transports/index.js | 62 - .../lib/transports/polling-jsonp.js | 221 - .../lib/transports/polling-xhr.js | 288 - .../lib/transports/polling.js | 210 - .../lib/transports/websocket.js | 158 - .../learnboost-engine.io-client/lib/util.js | 265 - .../component.json | 12 - .../learnboost-socket.io-protocol/index.js | 177 - .../timoxley-to-array/component.json | 16 - .../components/timoxley-to-array/index.js | 27 - .../visionmedia-debug/component.json | 16 - .../components/visionmedia-debug/debug.js | 122 - .../components/visionmedia-debug/index.js | 5 - .../socket.io-client/dist/WebSocketMain.swf | Bin 175830 -> 0 bytes .../dist/WebSocketMainInsecure.swf | Bin 175953 -> 0 bytes .../socket.io-client/dist/socket.io.js | 3873 - .../socket.io-client/dist/socket.io.min.js | 2 - .../socket.io-client/lib/events.js | 182 - .../node_modules/socket.io-client/lib/io.js | 206 - .../node_modules/socket.io-client/lib/json.js | 322 - .../socket.io-client/lib/namespace.js | 242 - .../socket.io-client/lib/parser.js | 262 - .../socket.io-client/lib/socket.js | 579 - .../socket.io-client/lib/transport.js | 256 - .../lib/transports/flashsocket.js | 191 - .../lib/transports/htmlfile.js | 173 - .../lib/transports/jsonp-polling.js | 256 - .../lib/transports/websocket.js | 197 - .../lib/transports/xhr-polling.js | 177 - .../socket.io-client/lib/transports/xhr.js | 217 - .../node_modules/socket.io-client/lib/util.js | 365 - .../lib/vendor/web-socket-js/.npmignore | 1 - .../lib/vendor/web-socket-js/README.md | 157 - .../vendor/web-socket-js/WebSocketMain.swf | Bin 175830 -> 0 bytes .../web-socket-js/WebSocketMainInsecure.zip | Bin 166610 -> 0 bytes .../flash-src/IWebSocketLogger.as | 8 - .../web-socket-js/flash-src/WebSocket.as | 464 - .../web-socket-js/flash-src/WebSocketEvent.as | 33 - .../web-socket-js/flash-src/WebSocketMain.as | 150 - .../flash-src/WebSocketMainInsecure.as | 19 - .../vendor/web-socket-js/flash-src/build.sh | 10 - .../com/adobe/net/proxies/RFC2817Socket.as | 204 - .../flash-src/com/gsolo/encryption/MD5.as | 375 - .../flash-src/com/hurlant/crypto/Crypto.as | 287 - .../crypto/cert/MozillaRootCertificates.as | 3235 - .../hurlant/crypto/cert/X509Certificate.as | 218 - .../crypto/cert/X509CertificateCollection.as | 57 - .../flash-src/com/hurlant/crypto/hash/HMAC.as | 82 - .../com/hurlant/crypto/hash/IHMAC.as | 27 - .../com/hurlant/crypto/hash/IHash.as | 21 - .../flash-src/com/hurlant/crypto/hash/MAC.as | 137 - .../flash-src/com/hurlant/crypto/hash/MD2.as | 124 - .../flash-src/com/hurlant/crypto/hash/MD5.as | 204 - .../flash-src/com/hurlant/crypto/hash/SHA1.as | 106 - .../com/hurlant/crypto/hash/SHA224.as | 28 - .../com/hurlant/crypto/hash/SHA256.as | 115 - .../com/hurlant/crypto/hash/SHABase.as | 71 - .../flash-src/com/hurlant/crypto/prng/ARC4.as | 90 - .../com/hurlant/crypto/prng/IPRNG.as | 20 - .../com/hurlant/crypto/prng/Random.as | 119 - .../com/hurlant/crypto/prng/TLSPRF.as | 142 - .../com/hurlant/crypto/rsa/RSAKey.as | 339 - .../com/hurlant/crypto/symmetric/AESKey.as | 2797 - .../hurlant/crypto/symmetric/BlowFishKey.as | 375 - .../com/hurlant/crypto/symmetric/CBCMode.as | 55 - .../com/hurlant/crypto/symmetric/CFB8Mode.as | 61 - .../com/hurlant/crypto/symmetric/CFBMode.as | 64 - .../com/hurlant/crypto/symmetric/CTRMode.as | 58 - .../com/hurlant/crypto/symmetric/DESKey.as | 365 - .../com/hurlant/crypto/symmetric/ECBMode.as | 86 - .../com/hurlant/crypto/symmetric/ICipher.as | 21 - .../com/hurlant/crypto/symmetric/IMode.as | 15 - .../com/hurlant/crypto/symmetric/IPad.as | 32 - .../hurlant/crypto/symmetric/IStreamCipher.as | 21 - .../hurlant/crypto/symmetric/ISymmetricKey.as | 35 - .../com/hurlant/crypto/symmetric/IVMode.as | 110 - .../com/hurlant/crypto/symmetric/NullPad.as | 34 - .../com/hurlant/crypto/symmetric/OFBMode.as | 52 - .../com/hurlant/crypto/symmetric/PKCS5.as | 44 - .../com/hurlant/crypto/symmetric/SSLPad.as | 44 - .../hurlant/crypto/symmetric/SimpleIVMode.as | 60 - .../com/hurlant/crypto/symmetric/TLSPad.as | 42 - .../hurlant/crypto/symmetric/TripleDESKey.as | 88 - .../com/hurlant/crypto/symmetric/XTeaKey.as | 94 - .../com/hurlant/crypto/symmetric/aeskey.pl | 29 - .../com/hurlant/crypto/symmetric/dump.txt | 2304 - .../com/hurlant/crypto/tests/AESKeyTest.as | 1220 - .../com/hurlant/crypto/tests/ARC4Test.as | 58 - .../hurlant/crypto/tests/BigIntegerTest.as | 39 - .../hurlant/crypto/tests/BlowFishKeyTest.as | 148 - .../com/hurlant/crypto/tests/CBCModeTest.as | 160 - .../com/hurlant/crypto/tests/CFB8ModeTest.as | 71 - .../com/hurlant/crypto/tests/CFBModeTest.as | 98 - .../com/hurlant/crypto/tests/CTRModeTest.as | 109 - .../com/hurlant/crypto/tests/DESKeyTest.as | 112 - .../com/hurlant/crypto/tests/ECBModeTest.as | 151 - .../com/hurlant/crypto/tests/HMACTest.as | 184 - .../com/hurlant/crypto/tests/ITestHarness.as | 20 - .../com/hurlant/crypto/tests/MD2Test.as | 56 - .../com/hurlant/crypto/tests/MD5Test.as | 58 - .../com/hurlant/crypto/tests/OFBModeTest.as | 101 - .../com/hurlant/crypto/tests/RSAKeyTest.as | 92 - .../com/hurlant/crypto/tests/SHA1Test.as | 198 - .../com/hurlant/crypto/tests/SHA224Test.as | 58 - .../com/hurlant/crypto/tests/SHA256Test.as | 60 - .../com/hurlant/crypto/tests/TLSPRFTest.as | 51 - .../com/hurlant/crypto/tests/TestCase.as | 42 - .../hurlant/crypto/tests/TripleDESKeyTest.as | 59 - .../com/hurlant/crypto/tests/XTeaKeyTest.as | 66 - .../com/hurlant/crypto/tls/BulkCiphers.as | 102 - .../com/hurlant/crypto/tls/CipherSuites.as | 117 - .../hurlant/crypto/tls/IConnectionState.as | 14 - .../hurlant/crypto/tls/ISecurityParameters.as | 29 - .../com/hurlant/crypto/tls/KeyExchanges.as | 24 - .../flash-src/com/hurlant/crypto/tls/MACs.as | 38 - .../hurlant/crypto/tls/SSLConnectionState.as | 171 - .../com/hurlant/crypto/tls/SSLEvent.as | 26 - .../crypto/tls/SSLSecurityParameters.as | 340 - .../com/hurlant/crypto/tls/TLSConfig.as | 70 - .../hurlant/crypto/tls/TLSConnectionState.as | 151 - .../com/hurlant/crypto/tls/TLSEngine.as | 895 - .../com/hurlant/crypto/tls/TLSError.as | 39 - .../com/hurlant/crypto/tls/TLSEvent.as | 27 - .../crypto/tls/TLSSecurityParameters.as | 197 - .../com/hurlant/crypto/tls/TLSSocket.as | 370 - .../com/hurlant/crypto/tls/TLSSocketEvent.as | 26 - .../com/hurlant/crypto/tls/TLSTest.as | 180 - .../com/hurlant/math/BarrettReduction.as | 90 - .../flash-src/com/hurlant/math/BigInteger.as | 1543 - .../com/hurlant/math/ClassicReduction.as | 35 - .../flash-src/com/hurlant/math/IReduction.as | 11 - .../com/hurlant/math/MontgomeryReduction.as | 85 - .../com/hurlant/math/NullReduction.as | 34 - .../flash-src/com/hurlant/math/bi_internal.as | 11 - .../flash-src/com/hurlant/util/ArrayUtil.as | 25 - .../flash-src/com/hurlant/util/Base64.as | 189 - .../flash-src/com/hurlant/util/Hex.as | 66 - .../flash-src/com/hurlant/util/Memory.as | 28 - .../com/hurlant/util/der/ByteString.as | 43 - .../flash-src/com/hurlant/util/der/DER.as | 210 - .../com/hurlant/util/der/IAsn1Type.as | 21 - .../flash-src/com/hurlant/util/der/Integer.as | 44 - .../flash-src/com/hurlant/util/der/OID.as | 35 - .../com/hurlant/util/der/ObjectIdentifier.as | 112 - .../flash-src/com/hurlant/util/der/PEM.as | 118 - .../com/hurlant/util/der/PrintableString.as | 49 - .../com/hurlant/util/der/Sequence.as | 90 - .../flash-src/com/hurlant/util/der/Set.as | 27 - .../flash-src/com/hurlant/util/der/Type.as | 94 - .../flash-src/com/hurlant/util/der/UTCTime.as | 60 - .../lib/vendor/web-socket-js/sample.html | 75 - .../lib/vendor/web-socket-js/swfobject.js | 6 - .../lib/vendor/web-socket-js/web_socket.js | 349 - .../node_modules/.bin/uglifyjs | 1 - .../socket.io-client/node_modules/.bin/wscat | 1 - .../active-x-obfuscator/.npmignore | 2 - .../active-x-obfuscator/Readme.md | 33 - .../node_modules/active-x-obfuscator/index.js | 83 - .../node_modules/zeparser/.gitignore | 1 - .../node_modules/zeparser/LICENSE | 19 - .../node_modules/zeparser/README | 37 - .../node_modules/zeparser/Tokenizer.js | 646 - .../node_modules/zeparser/ZeParser.js | 2180 - .../node_modules/zeparser/benchmark.html | 111608 --------------- .../node_modules/zeparser/index.js | 1 - .../node_modules/zeparser/package.json | 51 - .../node_modules/zeparser/test-parser.html | 26 - .../node_modules/zeparser/test-tokenizer.html | 23 - .../node_modules/zeparser/tests.js | 478 - .../zeparser/unicodecategories.js | 49 - .../active-x-obfuscator/package.json | 54 - .../node_modules/active-x-obfuscator/test.js | 53 - .../node_modules/uglify-js/.npmignore | 4 - .../node_modules/uglify-js/README.html | 981 - .../node_modules/uglify-js/README.org | 574 - .../node_modules/uglify-js/bin/uglifyjs | 323 - .../node_modules/uglify-js/docstyle.css | 75 - .../node_modules/uglify-js/lib/object-ast.js | 75 - .../node_modules/uglify-js/lib/parse-js.js | 1342 - .../node_modules/uglify-js/lib/process.js | 2011 - .../uglify-js/lib/squeeze-more.js | 69 - .../node_modules/uglify-js/package.json | 54 - .../node_modules/uglify-js/test/beautify.js | 28 - .../node_modules/uglify-js/test/testparser.js | 403 - .../test/unit/compress/expected/array1.js | 1 - .../test/unit/compress/expected/array2.js | 1 - .../test/unit/compress/expected/array3.js | 1 - .../test/unit/compress/expected/array4.js | 1 - .../test/unit/compress/expected/assignment.js | 1 - .../unit/compress/expected/concatstring.js | 1 - .../test/unit/compress/expected/const.js | 1 - .../unit/compress/expected/empty-blocks.js | 1 - .../unit/compress/expected/forstatement.js | 1 - .../test/unit/compress/expected/if.js | 1 - .../test/unit/compress/expected/ifreturn.js | 1 - .../test/unit/compress/expected/ifreturn2.js | 1 - .../test/unit/compress/expected/issue10.js | 1 - .../test/unit/compress/expected/issue11.js | 1 - .../test/unit/compress/expected/issue13.js | 1 - .../test/unit/compress/expected/issue14.js | 1 - .../test/unit/compress/expected/issue16.js | 1 - .../test/unit/compress/expected/issue17.js | 1 - .../test/unit/compress/expected/issue20.js | 1 - .../test/unit/compress/expected/issue21.js | 1 - .../test/unit/compress/expected/issue25.js | 1 - .../test/unit/compress/expected/issue27.js | 1 - .../test/unit/compress/expected/issue278.js | 1 - .../test/unit/compress/expected/issue28.js | 1 - .../test/unit/compress/expected/issue29.js | 1 - .../test/unit/compress/expected/issue30.js | 1 - .../test/unit/compress/expected/issue34.js | 1 - .../test/unit/compress/expected/issue4.js | 1 - .../test/unit/compress/expected/issue48.js | 1 - .../test/unit/compress/expected/issue50.js | 1 - .../test/unit/compress/expected/issue53.js | 1 - .../test/unit/compress/expected/issue54.1.js | 1 - .../test/unit/compress/expected/issue68.js | 1 - .../test/unit/compress/expected/issue69.js | 1 - .../test/unit/compress/expected/issue9.js | 1 - .../test/unit/compress/expected/mangle.js | 1 - .../unit/compress/expected/null_string.js | 1 - .../unit/compress/expected/strict-equals.js | 1 - .../test/unit/compress/expected/var.js | 1 - .../test/unit/compress/expected/whitespace.js | 1 - .../test/unit/compress/expected/with.js | 1 - .../test/unit/compress/test/array1.js | 3 - .../test/unit/compress/test/array2.js | 4 - .../test/unit/compress/test/array3.js | 4 - .../test/unit/compress/test/array4.js | 6 - .../test/unit/compress/test/assignment.js | 20 - .../test/unit/compress/test/concatstring.js | 3 - .../test/unit/compress/test/const.js | 5 - .../test/unit/compress/test/empty-blocks.js | 4 - .../test/unit/compress/test/forstatement.js | 10 - .../uglify-js/test/unit/compress/test/if.js | 6 - .../test/unit/compress/test/ifreturn.js | 9 - .../test/unit/compress/test/ifreturn2.js | 16 - .../test/unit/compress/test/issue10.js | 1 - .../test/unit/compress/test/issue11.js | 3 - .../test/unit/compress/test/issue13.js | 1 - .../test/unit/compress/test/issue14.js | 1 - .../test/unit/compress/test/issue16.js | 1 - .../test/unit/compress/test/issue17.js | 4 - .../test/unit/compress/test/issue20.js | 1 - .../test/unit/compress/test/issue21.js | 6 - .../test/unit/compress/test/issue25.js | 7 - .../test/unit/compress/test/issue27.js | 1 - .../test/unit/compress/test/issue278.js | 1 - .../test/unit/compress/test/issue28.js | 3 - .../test/unit/compress/test/issue29.js | 1 - .../test/unit/compress/test/issue30.js | 3 - .../test/unit/compress/test/issue34.js | 3 - .../test/unit/compress/test/issue4.js | 3 - .../test/unit/compress/test/issue48.js | 1 - .../test/unit/compress/test/issue50.js | 9 - .../test/unit/compress/test/issue53.js | 1 - .../test/unit/compress/test/issue54.1.js | 3 - .../test/unit/compress/test/issue68.js | 5 - .../test/unit/compress/test/issue69.js | 1 - .../test/unit/compress/test/issue9.js | 4 - .../test/unit/compress/test/mangle.js | 5 - .../test/unit/compress/test/null_string.js | 1 - .../test/unit/compress/test/strict-equals.js | 3 - .../uglify-js/test/unit/compress/test/var.js | 3 - .../test/unit/compress/test/whitespace.js | 21 - .../uglify-js/test/unit/compress/test/with.js | 2 - .../uglify-js/test/unit/scripts.js | 55 - .../node_modules/uglify-js/tmp/269.js | 13 - .../node_modules/uglify-js/tmp/app.js | 22315 --- .../uglify-js/tmp/embed-tokens.js | 15 - .../node_modules/uglify-js/tmp/goto.js | 26 - .../node_modules/uglify-js/tmp/goto2.js | 8 - .../node_modules/uglify-js/tmp/hoist.js | 33 - .../node_modules/uglify-js/tmp/instrument.js | 97 - .../node_modules/uglify-js/tmp/instrument2.js | 138 - .../node_modules/uglify-js/tmp/liftvars.js | 8 - .../node_modules/uglify-js/tmp/test.js | 30 - .../uglify-js/tmp/uglify-hangs.js | 3930 - .../uglify-js/tmp/uglify-hangs2.js | 166 - .../node_modules/uglify-js/uglify-js.js | 17 - .../node_modules/ws/.npmignore | 11 - .../node_modules/ws/.travis.yml | 5 - .../node_modules/ws/History.md | 312 - .../socket.io-client/node_modules/ws/Makefile | 40 - .../node_modules/ws/README.md | 171 - .../node_modules/ws/bin/wscat | 222 - .../node_modules/ws/binding.gyp | 16 - .../node_modules/ws/build/Makefile | 337 - .../Release/.deps/Release/bufferutil.node.d | 1 - .../Release/obj.target/bufferutil.node.d | 1 - .../obj.target/bufferutil/src/bufferutil.o.d | 29 - .../Release/obj.target/validation.node.d | 1 - .../obj.target/validation/src/validation.o.d | 29 - .../Release/.deps/Release/validation.node.d | 1 - .../ws/build/Release/bufferutil.node | Bin 24664 -> 0 bytes .../node_modules/ws/build/Release/linker.lock | 0 .../build/Release/obj.target/bufferutil.node | Bin 24664 -> 0 bytes .../build/Release/obj.target/validation.node | Bin 2117680 -> 0 bytes .../ws/build/Release/validation.node | Bin 2117680 -> 0 bytes .../node_modules/ws/build/binding.Makefile | 6 - .../ws/build/bufferutil.target.mk | 133 - .../node_modules/ws/build/config.gypi | 119 - .../ws/build/validation.target.mk | 133 - .../node_modules/ws/builderror.log | 0 .../socket.io-client/node_modules/ws/index.js | 26 - .../node_modules/ws/lib/BufferPool.js | 59 - .../ws/lib/BufferUtil.fallback.js | 47 - .../node_modules/ws/lib/BufferUtil.js | 16 - .../node_modules/ws/lib/ErrorCodes.js | 24 - .../node_modules/ws/lib/Receiver.hixie.js | 180 - .../node_modules/ws/lib/Receiver.js | 585 - .../node_modules/ws/lib/Sender.hixie.js | 118 - .../node_modules/ws/lib/Sender.js | 227 - .../ws/lib/Validation.fallback.js | 12 - .../node_modules/ws/lib/Validation.js | 16 - .../node_modules/ws/lib/WebSocket.js | 794 - .../node_modules/ws/lib/WebSocketServer.js | 465 - .../node_modules/ws/lib/browser.js | 43 - .../ws/node_modules/commander/Readme.md | 195 - .../ws/node_modules/commander/index.js | 851 - .../ws/node_modules/commander/package.json | 58 - .../node_modules/ws/node_modules/nan/.dntrc | 36 - .../node_modules/ws/node_modules/nan/LICENSE | 46 - .../ws/node_modules/nan/README.md | 947 - .../ws/node_modules/nan/build/config.gypi | 38 - .../ws/node_modules/nan/include_dirs.js | 1 - .../node_modules/ws/node_modules/nan/nan.h | 1910 - .../ws/node_modules/nan/package.json | 68 - .../ws/node_modules/options/.npmignore | 7 - .../ws/node_modules/options/Makefile | 12 - .../ws/node_modules/options/README.md | 69 - .../ws/node_modules/options/lib/options.js | 86 - .../ws/node_modules/options/package.json | 51 - .../ws/node_modules/tinycolor/.gitignore | 5 - .../ws/node_modules/tinycolor/README.md | 3 - .../ws/node_modules/tinycolor/example.js | 3 - .../ws/node_modules/tinycolor/package.json | 49 - .../ws/node_modules/tinycolor/tinycolor.js | 31 - .../node_modules/ws/package.json | 82 - .../node_modules/ws/src/bufferutil.cc | 117 - .../node_modules/ws/src/validation.cc | 145 - .../node_modules/xmlhttprequest/README.md | 53 - .../xmlhttprequest/autotest.watchr | 8 - .../xmlhttprequest/example/demo.js | 16 - .../xmlhttprequest/lib/XMLHttpRequest.js | 548 - .../node_modules/xmlhttprequest/package.json | 59 - .../xmlhttprequest/tests/test-constants.js | 13 - .../xmlhttprequest/tests/test-events.js | 50 - .../xmlhttprequest/tests/test-exceptions.js | 62 - .../xmlhttprequest/tests/test-headers.js | 61 - .../tests/test-request-methods.js | 62 - .../tests/test-request-protocols.js | 34 - .../xmlhttprequest/tests/testdata.txt | 1 - .../socket.io-client/package.json | 84 - .../socket.io-client/test/events.test.js | 120 - .../socket.io-client/test/io.test.js | 31 - .../test/node/builder.common.js | 102 - .../test/node/builder.test.js | 131 - .../socket.io-client/test/parser.test.js | 360 - .../socket.io-client/test/socket.test.js | 422 - .../socket.io-client/test/util.test.js | 156 - .../socket.io-client/test/worker.js | 20 - .../node_modules/socket.io/package.json | 87 - messenger/js/easyrtc/package.json | 24 - messenger/js/easyrtc/server.js | 18 - messenger/js/easyrtc/static/index.html | 20 - messenger/setup/setup.inc.php | 47 - messenger/templates/default/app.css | 41 - messenger/templates/default/dialog.xet | 38 - messenger/templates/default/index.xet | 51 - 1000 files changed, 343631 deletions(-) delete mode 100644 messenger/inc/class.messenger_hooks.inc.php delete mode 100644 messenger/inc/class.messenger_ui.inc.php delete mode 100644 messenger/js/app.js delete mode 100755 messenger/js/easyrtc/README.md delete mode 100644 messenger/js/easyrtc/easyrtc.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/.npmignore delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/README.md delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/api/adapter.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/api/buildEnglishVersions.bat delete mode 100755 messenger/js/easyrtc/node_modules/easyrtc/api/buildEnglishVersions.sh delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/api/easyrtc.css delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/api/easyrtc.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/api/easyrtc_ft.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/api/easyrtc_int.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/api/easyrtc_lang_en.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/api/img/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/api/img/easyrtc.png delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/api/img/powered_by_easyrtc.png delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/api/img/priologic_logo_white.png delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/api/img/x.svg delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/api/labs/README.md delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/api/labs/desktopCapture.zip delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/api/labs/desktop_capture_iframe_version.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/api/labs/desktop_capture_no_iframe_version.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/api/labs/easyrtc_rates.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/api/labs/inline-installcode.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/css/demo4.css delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/css/demo_audio_video_simple.css delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/css/demo_audio_video_simple_hd.css delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/css/demo_lowbandwidth.css delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/css/demo_room.css delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/css/landing.css delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/demo4.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/demo_audio_only.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/demo_audio_video.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/demo_audio_video_simple.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/demo_audio_video_simple_hd.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/demo_data_channel_filesharing.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/demo_data_channel_messaging.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/demo_ice_filter.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/demo_instant_messaging.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/demo_instant_messaging_rooms.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/demo_instant_messaging_selfconnect.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/demo_lowbandwidth.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/demo_multiparty.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/demo_multistream.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/demo_multistream_iframe.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/demo_multistream_no_iframe.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/demo_reconnect.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/demo_room.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/demo_screen_receive.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/demo_screen_send.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/demo_video_only.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/images/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/images/bg_dark.png delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/images/bg_light.png delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/images/blank.gif delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/images/br_chrome.png delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/images/br_chrome_canary.png delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/images/br_ff.png delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/images/br_ff_aurora.png delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/images/br_ff_nightly.png delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/images/br_ie.png delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/images/br_opera.png delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/images/br_safari.png delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/images/br_status_fail.png delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/images/br_status_pass.png delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/images/br_status_warn.png delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/images/button_close.png delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/images/button_mute.png delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/images/button_refresh.png delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/images/button_unmute.png delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/images/by_priologic_logo.png delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/images/cloud.png delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/images/easyrtc_logo.png delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/images/irongrip.png delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/images/powered_by_easyrtc.png delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/images/priologic_logo_white.png delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/images/textEntry.png delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/index.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo4.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_audio_only.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_audio_video.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_audio_video_simple.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_audio_video_simple_hd.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_data_channel_filesharing.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_data_channel_messaging.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_ice_filter.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_instant_messaging.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_instant_messaging_rooms.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_instant_messaging_selfconnect.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_lowbandwidth.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_multiparty.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_multistream.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_multistream_iframe.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_multistream_no_iframe.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_reconnect.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_room.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_screen_receive.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_screen_send.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_video_only.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/prettify/README delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/prettify/jquery-1.9.1.min.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/prettify/jquery.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/prettify/jquery.min.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/prettify/lang-css.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/prettify/lang-sql.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/prettify/lang-vhdl.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/prettify/lang-yaml.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/prettify/loadAndFilter.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/prettify/prettify.css delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/demos/js/prettify/prettify.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/readme.md delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates/README.md delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates/publish.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates/static/scripts/prettify/Apache-License-2.0.txt delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates/static/scripts/prettify/lang-css.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates/static/scripts/prettify/prettify.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates/static/styles/jsdoc-default.css delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates/static/styles/prettify-jsdoc.css delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates/static/styles/prettify-tomorrow.css delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates/tmpl/container.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates/tmpl/details.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates/tmpl/example.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates/tmpl/examples.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates/tmpl/exceptions.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates/tmpl/fires.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates/tmpl/layout.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates/tmpl/mainpage.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates/tmpl/members.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates/tmpl/method.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates/tmpl/params.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates/tmpl/properties.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates/tmpl/returns.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates/tmpl/source.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates/tmpl/tutorial.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates/tmpl/type.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates2/README.md delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates2/publish.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates2/static/scripts/prettify/Apache-License-2.0.txt delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates2/static/scripts/prettify/lang-css.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates2/static/scripts/prettify/prettify.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates2/static/styles/jsdoc-default.css delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates2/static/styles/prettify-jsdoc.css delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates2/static/styles/prettify-tomorrow.css delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates2/tmpl/container.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates2/tmpl/details.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates2/tmpl/example.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates2/tmpl/examples.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates2/tmpl/exceptions.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates2/tmpl/fires.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates2/tmpl/layout.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates2/tmpl/mainpage.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates2/tmpl/members.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates2/tmpl/method.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates2/tmpl/params.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates2/tmpl/properties.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates2/tmpl/returns.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates2/tmpl/source.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates2/tmpl/tutorial.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/client_jsdoc_templates2/tmpl/type.tmpl delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/readme.md delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/updateEasyrtcJsDocs.bat delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/updateEasyrtc_ftJsDocs.bat delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/dev/scripts/update_server_docs.bat delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/client_html_docs/easyrtc.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/client_html_docs/easyrtc_ft.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/client_html_docs/jsdoc/styles/jsdoc-client.css delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/client_html_docs/scripts/linenumber.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/client_html_docs/scripts/prettify/Apache-License-2.0.txt delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/client_html_docs/scripts/prettify/lang-css.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/client_html_docs/scripts/prettify/prettify.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/client_html_docs/styles/jsdoc-default.css delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/client_html_docs/styles/prettify-jsdoc.css delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/client_html_docs/styles/prettify-tomorrow.css delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/easyrtc_authentication.md delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/easyrtc_changelog.md delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/easyrtc_client_tutorial.md delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/easyrtc_faq.md delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/easyrtc_rooms.md delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/easyrtc_server_configuration.md delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/easyrtc_server_events.md delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/easyrtc_server_ice.md delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/easyrtc_server_install.md delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/easyrtc_server_msgtypes.md delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/easyrtc_server_ssl.md delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/easyrtc_upcoming_features.md delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/easyrtc_webrtc_problems.md delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/easyrtc_with_other_servers.md delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/server_html_docs/easyrtc_default_event_listeners.js.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/server_html_docs/easyrtc_public_obj.js.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/server_html_docs/global.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/server_html_docs/index.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/server_html_docs/module-easyrtc_default_event_listeners-eventListener.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/server_html_docs/module-easyrtc_default_event_listeners.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/server_html_docs/module-easyrtc_public_obj-pub.events.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/server_html_docs/module-easyrtc_public_obj-pub.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/server_html_docs/module-easyrtc_public_obj-pub.util.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/server_html_docs/module-easyrtc_public_obj.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/server_html_docs/pub.appObj.connectionObj.connectionRoomObj.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/server_html_docs/pub.appObj.connectionObj.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/server_html_docs/pub.appObj.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/server_html_docs/pub.appObj.roomObj.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/server_html_docs/pub.appObj.sessionObj.html delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/server_html_docs/scripts/linenumber.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/server_html_docs/scripts/prettify/Apache-License-2.0.txt delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/server_html_docs/scripts/prettify/lang-css.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/server_html_docs/scripts/prettify/prettify.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/server_html_docs/styles/jsdoc-default.css delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/server_html_docs/styles/prettify-jsdoc.css delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/docs/server_html_docs/styles/prettify-tomorrow.css delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/index.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/lib/easyrtc_default_event_listeners.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/lib/easyrtc_default_options.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/lib/easyrtc_private_obj.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/lib/easyrtc_public_obj.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/lib/easyrtc_server.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/lib/easyrtc_util.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/lib/general_util.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/node_modules/async/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/node_modules/async/README.md delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/node_modules/async/component.json delete mode 100755 messenger/js/easyrtc/node_modules/easyrtc/node_modules/async/lib/async.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/node_modules/async/package.json delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/node_modules/colors/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/node_modules/colors/ReadMe.md delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/node_modules/colors/examples/normal-usage.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/node_modules/colors/examples/safe-string.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/node_modules/colors/lib/colors.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/node_modules/colors/lib/custom/trap.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/node_modules/colors/lib/custom/zalgo.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/node_modules/colors/lib/extendStringPrototype.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/node_modules/colors/lib/index.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/node_modules/colors/lib/maps/america.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/node_modules/colors/lib/maps/rainbow.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/node_modules/colors/lib/maps/random.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/node_modules/colors/lib/maps/zebra.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/node_modules/colors/lib/styles.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/node_modules/colors/lib/system/supports-colors.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/node_modules/colors/package.json delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/node_modules/colors/safe.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/node_modules/colors/themes/generic-logging.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/node_modules/underscore/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/node_modules/underscore/README.md delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/node_modules/underscore/package.json delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/node_modules/underscore/underscore-min.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/node_modules/underscore/underscore.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/package.json delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/server_example/README.md delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/server_example/package.json delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/server_example/server.js delete mode 100644 messenger/js/easyrtc/node_modules/easyrtc/server_example/static/index.html delete mode 100644 messenger/js/easyrtc/node_modules/express/History.md delete mode 100644 messenger/js/easyrtc/node_modules/express/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/Readme.md delete mode 100644 messenger/js/easyrtc/node_modules/express/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/lib/application.js delete mode 100644 messenger/js/easyrtc/node_modules/express/lib/express.js delete mode 100644 messenger/js/easyrtc/node_modules/express/lib/middleware/init.js delete mode 100644 messenger/js/easyrtc/node_modules/express/lib/middleware/query.js delete mode 100644 messenger/js/easyrtc/node_modules/express/lib/request.js delete mode 100644 messenger/js/easyrtc/node_modules/express/lib/response.js delete mode 100644 messenger/js/easyrtc/node_modules/express/lib/router/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/lib/router/layer.js delete mode 100644 messenger/js/easyrtc/node_modules/express/lib/router/route.js delete mode 100644 messenger/js/easyrtc/node_modules/express/lib/utils.js delete mode 100644 messenger/js/easyrtc/node_modules/express/lib/view.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/accepts/HISTORY.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/accepts/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/accepts/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/accepts/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/accepts/node_modules/mime-types/HISTORY.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/accepts/node_modules/mime-types/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/accepts/node_modules/mime-types/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/accepts/node_modules/mime-types/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/accepts/node_modules/mime-types/node_modules/mime-db/HISTORY.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/accepts/node_modules/mime-types/node_modules/mime-db/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/accepts/node_modules/mime-types/node_modules/mime-db/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/accepts/node_modules/mime-types/node_modules/mime-db/db.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/accepts/node_modules/mime-types/node_modules/mime-db/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/accepts/node_modules/mime-types/node_modules/mime-db/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/accepts/node_modules/mime-types/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/accepts/node_modules/negotiator/HISTORY.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/accepts/node_modules/negotiator/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/accepts/node_modules/negotiator/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/accepts/node_modules/negotiator/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/accepts/node_modules/negotiator/lib/charset.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/accepts/node_modules/negotiator/lib/encoding.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/accepts/node_modules/negotiator/lib/language.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/accepts/node_modules/negotiator/lib/mediaType.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/accepts/node_modules/negotiator/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/accepts/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/content-disposition/HISTORY.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/content-disposition/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/content-disposition/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/content-disposition/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/content-disposition/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/content-type/HISTORY.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/content-type/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/content-type/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/content-type/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/content-type/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/cookie-signature/.npmignore delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/cookie-signature/History.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/cookie-signature/Readme.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/cookie-signature/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/cookie-signature/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/cookie/.npmignore delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/cookie/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/cookie/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/cookie/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/cookie/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/debug/.jshintrc delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/debug/.npmignore delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/debug/History.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/debug/Makefile delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/debug/Readme.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/debug/bower.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/debug/browser.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/debug/component.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/debug/debug.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/debug/node.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/debug/node_modules/ms/.npmignore delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/debug/node_modules/ms/History.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/debug/node_modules/ms/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/debug/node_modules/ms/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/debug/node_modules/ms/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/debug/node_modules/ms/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/debug/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/depd/History.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/depd/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/depd/Readme.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/depd/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/depd/lib/compat/buffer-concat.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/depd/lib/compat/callsite-tostring.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/depd/lib/compat/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/depd/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/escape-html/.npmignore delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/escape-html/Makefile delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/escape-html/Readme.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/escape-html/component.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/escape-html/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/escape-html/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/etag/HISTORY.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/etag/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/etag/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/etag/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/etag/node_modules/crc/.npmignore delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/etag/node_modules/crc/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/etag/node_modules/crc/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/etag/node_modules/crc/lib/crc.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/etag/node_modules/crc/lib/crc1.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/etag/node_modules/crc/lib/crc16.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/etag/node_modules/crc/lib/crc16_ccitt.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/etag/node_modules/crc/lib/crc16_modbus.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/etag/node_modules/crc/lib/crc24.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/etag/node_modules/crc/lib/crc32.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/etag/node_modules/crc/lib/crc8.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/etag/node_modules/crc/lib/crc8_1wire.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/etag/node_modules/crc/lib/create.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/etag/node_modules/crc/lib/hex.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/etag/node_modules/crc/lib/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/etag/node_modules/crc/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/etag/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/finalhandler/HISTORY.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/finalhandler/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/finalhandler/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/finalhandler/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/finalhandler/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/fresh/HISTORY.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/fresh/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/fresh/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/fresh/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/fresh/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/merge-descriptors/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/merge-descriptors/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/merge-descriptors/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/merge-descriptors/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/methods/HISTORY.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/methods/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/methods/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/methods/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/methods/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/on-finished/HISTORY.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/on-finished/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/on-finished/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/on-finished/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/on-finished/node_modules/ee-first/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/on-finished/node_modules/ee-first/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/on-finished/node_modules/ee-first/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/on-finished/node_modules/ee-first/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/on-finished/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/parseurl/.npmignore delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/parseurl/HISTORY.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/parseurl/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/parseurl/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/parseurl/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/parseurl/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/path-to-regexp/.npmignore delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/path-to-regexp/History.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/path-to-regexp/Readme.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/path-to-regexp/component.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/path-to-regexp/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/path-to-regexp/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/path-to-regexp/test.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/proxy-addr/HISTORY.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/proxy-addr/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/proxy-addr/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/proxy-addr/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/proxy-addr/node_modules/forwarded/HISTORY.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/proxy-addr/node_modules/forwarded/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/proxy-addr/node_modules/forwarded/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/proxy-addr/node_modules/forwarded/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/proxy-addr/node_modules/forwarded/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/.npmignore delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/Cakefile delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/ipaddr.min.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/lib/ipaddr.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/src/ipaddr.coffee delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/proxy-addr/node_modules/ipaddr.js/test/ipaddr.test.coffee delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/proxy-addr/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/qs/.jshintignore delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/qs/.jshintrc delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/qs/.npmignore delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/qs/.travis.yml delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/qs/CHANGELOG.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/qs/CONTRIBUTING.md delete mode 100755 messenger/js/easyrtc/node_modules/express/node_modules/qs/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/qs/Makefile delete mode 100755 messenger/js/easyrtc/node_modules/express/node_modules/qs/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/qs/index.js delete mode 100755 messenger/js/easyrtc/node_modules/express/node_modules/qs/lib/index.js delete mode 100755 messenger/js/easyrtc/node_modules/express/node_modules/qs/lib/parse.js delete mode 100755 messenger/js/easyrtc/node_modules/express/node_modules/qs/lib/stringify.js delete mode 100755 messenger/js/easyrtc/node_modules/express/node_modules/qs/lib/utils.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/qs/package.json delete mode 100755 messenger/js/easyrtc/node_modules/express/node_modules/qs/test/parse.js delete mode 100755 messenger/js/easyrtc/node_modules/express/node_modules/qs/test/stringify.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/range-parser/HISTORY.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/range-parser/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/range-parser/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/range-parser/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/range-parser/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/send/HISTORY.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/send/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/send/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/send/index.js delete mode 120000 messenger/js/easyrtc/node_modules/express/node_modules/send/node_modules/.bin/mime delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/send/node_modules/destroy/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/send/node_modules/destroy/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/send/node_modules/destroy/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/send/node_modules/mime/.npmignore delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/send/node_modules/mime/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/send/node_modules/mime/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/send/node_modules/mime/build/build.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/send/node_modules/mime/build/test.js delete mode 100755 messenger/js/easyrtc/node_modules/express/node_modules/send/node_modules/mime/cli.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/send/node_modules/mime/mime.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/send/node_modules/mime/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/send/node_modules/mime/types.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/send/node_modules/ms/.npmignore delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/send/node_modules/ms/History.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/send/node_modules/ms/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/send/node_modules/ms/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/send/node_modules/ms/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/send/node_modules/ms/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/send/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/serve-static/HISTORY.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/serve-static/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/serve-static/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/serve-static/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/serve-static/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/type-is/HISTORY.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/type-is/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/type-is/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/type-is/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/type-is/node_modules/media-typer/HISTORY.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/type-is/node_modules/media-typer/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/type-is/node_modules/media-typer/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/type-is/node_modules/media-typer/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/type-is/node_modules/media-typer/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/type-is/node_modules/mime-types/HISTORY.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/type-is/node_modules/mime-types/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/type-is/node_modules/mime-types/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/type-is/node_modules/mime-types/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/type-is/node_modules/mime-types/node_modules/mime-db/HISTORY.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/type-is/node_modules/mime-types/node_modules/mime-db/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/type-is/node_modules/mime-types/node_modules/mime-db/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/type-is/node_modules/mime-types/node_modules/mime-db/db.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/type-is/node_modules/mime-types/node_modules/mime-db/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/type-is/node_modules/mime-types/node_modules/mime-db/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/type-is/node_modules/mime-types/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/type-is/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/utils-merge/.travis.yml delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/utils-merge/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/utils-merge/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/utils-merge/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/utils-merge/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/vary/.npmignore delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/vary/History.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/vary/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/vary/README.md delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/vary/index.js delete mode 100644 messenger/js/easyrtc/node_modules/express/node_modules/vary/package.json delete mode 100644 messenger/js/easyrtc/node_modules/express/package.json delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/.npmignore delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/.travis.yml delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/History.md delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/Makefile delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/Readme.md delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/benchmarks/decode.bench.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/benchmarks/encode.bench.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/benchmarks/runner.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/index.js delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/latest delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/lib/logger.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/lib/manager.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/lib/namespace.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/lib/parser.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/lib/socket.io.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/lib/socket.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/lib/static.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/lib/store.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/lib/stores/memory.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/lib/stores/redis.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/lib/transport.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/lib/transports/flashsocket.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/lib/transports/htmlfile.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/lib/transports/http-polling.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/lib/transports/http.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/lib/transports/index.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/lib/transports/jsonp-polling.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/lib/transports/websocket.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/lib/transports/websocket/default.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/lib/transports/websocket/hybi-07-12.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/lib/transports/websocket/hybi-16.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/lib/transports/websocket/index.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/lib/transports/xhr-polling.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/lib/util.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/base64id/.npmignore delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/base64id/README.md delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/base64id/lib/base64id.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/base64id/package.json delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/policyfile/.gitignore delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/policyfile/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/policyfile/Makefile delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/policyfile/README.md delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/policyfile/doc/index.html delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/policyfile/examples/basic.fallback.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/policyfile/examples/basic.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/policyfile/index.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/policyfile/lib/server.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/policyfile/package.json delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/policyfile/tests/ssl/ssl.crt delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/policyfile/tests/ssl/ssl.private.key delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/policyfile/tests/unit.test.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/.npmignore delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/README.md delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/benches/buffer_bench.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/benches/hiredis_parser.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/benches/re_sub_test.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/benches/reconnect_test.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/benches/stress/codec.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/benches/stress/pubsub/pub.js delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/benches/stress/pubsub/run delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/benches/stress/pubsub/server.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/benches/stress/rpushblpop/pub.js delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/benches/stress/rpushblpop/run delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/benches/stress/rpushblpop/server.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/benches/stress/speed/00 delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/benches/stress/speed/plot delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/benches/stress/speed/size-rate.png delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/benches/stress/speed/speed.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/benches/sub_quit_test.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/changelog.md delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/diff_multi_bench_output.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/examples/auth.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/examples/backpressure_drain.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/examples/eval.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/examples/extend.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/examples/file.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/examples/mget.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/examples/monitor.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/examples/multi.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/examples/multi2.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/examples/psubscribe.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/examples/pub_sub.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/examples/simple.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/examples/sort.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/examples/subqueries.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/examples/subquery.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/examples/unix_socket.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/examples/web_server.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/generate_commands.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/index.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/lib/commands.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/lib/parser/hiredis.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/lib/parser/javascript.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/lib/queue.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/lib/to_array.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/lib/util.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/mem.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/multi_bench.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/package.json delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/redis/test.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/.npmignore delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/History.md delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/Makefile delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/README.md delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/bin/builder.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/components/component-bind/component.json delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/components/component-bind/index.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/components/component-emitter/component.json delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/components/component-emitter/index.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/components/component-json-fallback/component.json delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/components/component-json-fallback/index.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/components/component-json/component.json delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/components/component-json/index.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/components/learnboost-engine.io-client/component.json delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/components/learnboost-engine.io-client/lib/emitter.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/components/learnboost-engine.io-client/lib/index.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/components/learnboost-engine.io-client/lib/parser.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/components/learnboost-engine.io-client/lib/socket.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/components/learnboost-engine.io-client/lib/transport.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/components/learnboost-engine.io-client/lib/transports/flashsocket.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/components/learnboost-engine.io-client/lib/transports/index.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/components/learnboost-engine.io-client/lib/transports/polling-jsonp.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/components/learnboost-engine.io-client/lib/transports/polling-xhr.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/components/learnboost-engine.io-client/lib/transports/polling.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/components/learnboost-engine.io-client/lib/transports/websocket.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/components/learnboost-engine.io-client/lib/util.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/components/learnboost-socket.io-protocol/component.json delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/components/learnboost-socket.io-protocol/index.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/components/timoxley-to-array/component.json delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/components/timoxley-to-array/index.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/components/visionmedia-debug/component.json delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/components/visionmedia-debug/debug.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/components/visionmedia-debug/index.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/dist/WebSocketMain.swf delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/dist/WebSocketMainInsecure.swf delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/dist/socket.io.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/dist/socket.io.min.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/events.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/io.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/json.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/namespace.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/parser.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/socket.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/transport.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/transports/flashsocket.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/transports/htmlfile.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/transports/jsonp-polling.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/transports/websocket.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/transports/xhr-polling.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/transports/xhr.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/util.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/.npmignore delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/README.md delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/WebSocketMain.swf delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/WebSocketMainInsecure.zip delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/IWebSocketLogger.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/WebSocket.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/WebSocketEvent.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/WebSocketMain.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/WebSocketMainInsecure.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/build.sh delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/adobe/net/proxies/RFC2817Socket.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/gsolo/encryption/MD5.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/Crypto.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/cert/MozillaRootCertificates.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/cert/X509Certificate.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/cert/X509CertificateCollection.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/HMAC.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/IHMAC.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/IHash.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/MAC.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/MD2.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/MD5.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/SHA1.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/SHA224.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/SHA256.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/hash/SHABase.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/prng/ARC4.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/prng/IPRNG.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/prng/Random.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/prng/TLSPRF.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/rsa/RSAKey.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/AESKey.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/BlowFishKey.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/CBCMode.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/CFB8Mode.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/CFBMode.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/CTRMode.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/DESKey.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/ECBMode.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/ICipher.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/IMode.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/IPad.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/IStreamCipher.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/ISymmetricKey.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/IVMode.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/NullPad.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/OFBMode.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/PKCS5.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/SSLPad.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/SimpleIVMode.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/TLSPad.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/TripleDESKey.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/XTeaKey.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/aeskey.pl delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/symmetric/dump.txt delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/AESKeyTest.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/ARC4Test.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/BigIntegerTest.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/BlowFishKeyTest.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/CBCModeTest.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/CFB8ModeTest.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/CFBModeTest.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/CTRModeTest.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/DESKeyTest.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/ECBModeTest.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/HMACTest.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/ITestHarness.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/MD2Test.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/MD5Test.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/OFBModeTest.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/RSAKeyTest.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/SHA1Test.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/SHA224Test.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/SHA256Test.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/TLSPRFTest.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/TestCase.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/TripleDESKeyTest.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tests/XTeaKeyTest.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/BulkCiphers.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/CipherSuites.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/IConnectionState.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/ISecurityParameters.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/KeyExchanges.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/MACs.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/SSLConnectionState.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/SSLEvent.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/SSLSecurityParameters.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSConfig.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSConnectionState.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSEngine.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSError.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSEvent.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSSecurityParameters.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSSocket.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSSocketEvent.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/crypto/tls/TLSTest.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/math/BarrettReduction.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/math/BigInteger.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/math/ClassicReduction.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/math/IReduction.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/math/MontgomeryReduction.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/math/NullReduction.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/math/bi_internal.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/util/ArrayUtil.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/util/Base64.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/util/Hex.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/util/Memory.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/util/der/ByteString.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/util/der/DER.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/util/der/IAsn1Type.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/util/der/Integer.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/util/der/OID.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/util/der/ObjectIdentifier.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/util/der/PEM.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/util/der/PrintableString.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/util/der/Sequence.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/util/der/Set.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/util/der/Type.as delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/flash-src/com/hurlant/util/der/UTCTime.as delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/sample.html delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/swfobject.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/lib/vendor/web-socket-js/web_socket.js delete mode 120000 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/.bin/uglifyjs delete mode 120000 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/.bin/wscat delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/.npmignore delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/Readme.md delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/index.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/node_modules/zeparser/.gitignore delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/node_modules/zeparser/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/node_modules/zeparser/README delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/node_modules/zeparser/Tokenizer.js delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/node_modules/zeparser/ZeParser.js delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/node_modules/zeparser/benchmark.html delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/node_modules/zeparser/index.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/node_modules/zeparser/package.json delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/node_modules/zeparser/test-parser.html delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/node_modules/zeparser/test-tokenizer.html delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/node_modules/zeparser/tests.js delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/node_modules/zeparser/unicodecategories.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/package.json delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/test.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/.npmignore delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/README.html delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/README.org delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/bin/uglifyjs delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/docstyle.css delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/lib/object-ast.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/lib/parse-js.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/lib/process.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/lib/squeeze-more.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/package.json delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/beautify.js delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/testparser.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/array1.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/array2.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/array3.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/array4.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/assignment.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/concatstring.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/const.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/empty-blocks.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/forstatement.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/if.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/ifreturn.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/ifreturn2.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/issue10.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/issue11.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/issue13.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/issue14.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/issue16.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/issue17.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/issue20.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/issue21.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/issue25.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/issue27.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/issue278.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/issue28.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/issue29.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/issue30.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/issue34.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/issue4.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/issue48.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/issue50.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/issue53.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/issue54.1.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/issue68.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/issue69.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/issue9.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/mangle.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/null_string.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/strict-equals.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/var.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/whitespace.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/expected/with.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/array1.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/array2.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/array3.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/array4.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/assignment.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/concatstring.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/const.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/empty-blocks.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/forstatement.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/if.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/ifreturn.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/ifreturn2.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/issue10.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/issue11.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/issue13.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/issue14.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/issue16.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/issue17.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/issue20.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/issue21.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/issue25.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/issue27.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/issue278.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/issue28.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/issue29.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/issue30.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/issue34.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/issue4.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/issue48.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/issue50.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/issue53.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/issue54.1.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/issue68.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/issue69.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/issue9.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/mangle.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/null_string.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/strict-equals.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/var.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/whitespace.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/compress/test/with.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/test/unit/scripts.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/269.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/app.js delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/embed-tokens.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/goto.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/goto2.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/hoist.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/instrument.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/instrument2.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/liftvars.js delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/test.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/uglify-hangs.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/uglify-hangs2.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/uglify-js.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/.npmignore delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/.travis.yml delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/History.md delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/Makefile delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/README.md delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/bin/wscat delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/binding.gyp delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Makefile delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/.deps/Release/bufferutil.node.d delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/.deps/Release/obj.target/bufferutil.node.d delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/.deps/Release/obj.target/bufferutil/src/bufferutil.o.d delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/.deps/Release/obj.target/validation.node.d delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/.deps/Release/obj.target/validation/src/validation.o.d delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/.deps/Release/validation.node.d delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/bufferutil.node delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/linker.lock delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/obj.target/bufferutil.node delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/obj.target/validation.node delete mode 100755 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/validation.node delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/binding.Makefile delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/bufferutil.target.mk delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/config.gypi delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/validation.target.mk delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/builderror.log delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/index.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/BufferPool.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/BufferUtil.fallback.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/BufferUtil.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/ErrorCodes.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/Receiver.hixie.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/Receiver.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/Sender.hixie.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/Sender.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/Validation.fallback.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/Validation.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/WebSocket.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/WebSocketServer.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/browser.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/commander/Readme.md delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/commander/index.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/commander/package.json delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/nan/.dntrc delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/nan/LICENSE delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/nan/README.md delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/nan/build/config.gypi delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/nan/include_dirs.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/nan/nan.h delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/nan/package.json delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/options/.npmignore delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/options/Makefile delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/options/README.md delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/options/lib/options.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/options/package.json delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/tinycolor/.gitignore delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/tinycolor/README.md delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/tinycolor/example.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/tinycolor/package.json delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/tinycolor/tinycolor.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/package.json delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/src/bufferutil.cc delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/src/validation.cc delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/README.md delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/autotest.watchr delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/example/demo.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/lib/XMLHttpRequest.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/package.json delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/tests/test-constants.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/tests/test-events.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/tests/test-exceptions.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/tests/test-headers.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/tests/test-request-methods.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/tests/test-request-protocols.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/tests/testdata.txt delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/package.json delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/events.test.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/io.test.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/node/builder.common.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/node/builder.test.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/parser.test.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/socket.test.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/util.test.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/worker.js delete mode 100644 messenger/js/easyrtc/node_modules/socket.io/package.json delete mode 100755 messenger/js/easyrtc/package.json delete mode 100755 messenger/js/easyrtc/server.js delete mode 100644 messenger/js/easyrtc/static/index.html delete mode 100644 messenger/setup/setup.inc.php delete mode 100644 messenger/templates/default/app.css delete mode 100644 messenger/templates/default/dialog.xet delete mode 100644 messenger/templates/default/index.xet diff --git a/messenger/inc/class.messenger_hooks.inc.php b/messenger/inc/class.messenger_hooks.inc.php deleted file mode 100644 index 5ae73b5502..0000000000 --- a/messenger/inc/class.messenger_hooks.inc.php +++ /dev/null @@ -1,76 +0,0 @@ - - * @package messenger - * @subpackage setup - * @copyright (c) 2014 by Stylite AG - * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License - * @version $Id: $ - */ - -/** - * Class containing admin, preferences and sidebox-menus and other hooks - */ -class messenger_hooks -{ - /* - * Messsenger App Name - */ - static $APPNAME = 'messenger'; - - /** - * Hook called by link-class to include Messenger in the appregistry of the linkage - * - * @return array with method-names - */ - static function search_link() - { - return array( - 'dialog'=> array( - 'menuaction' => 'messenger.messenger_ui.dialog', - ), - 'dialog_id'=> 'id', - 'dialog_popup' => '480x420', - ); - } - - /** - * Sidebox menu hook - * - * @param array|string $hook_data - */ - static function sidebox_menu($hook_data) - { - $menu_title = $GLOBALS['egw_info']['apps'][self::$APPNAME]['title']; - $file = Array( - 'Add' => "javascript:egw_openWindowCentered2('". - egw::link('/index.php',array('menuaction' => 'addressbook.addressbook_ui.edit'),false). - "','_blank',870,480,'yes')", - array( - 'text' => '
', - 'no_lang' => true, - 'link' => false, - 'icon' => false, - ), - 'menuOpened' => true - ); - - // Display Contacts - display_sidebox(self::$APPNAME,lang('Contacts'),$file); - - if ($GLOBALS['egw_info']['user']['apps']['admin']) - { - $file = Array( - 'Site configuration' => egw::link('/index.php',array( - 'menuaction' => 'admin.uiconfig.index', - 'appname' => self::$APPNAME, - ))); - } - // Display Admin menu - display_sidebox(self::$APPNAME,lang('Admin'),$file); - } - -} \ No newline at end of file diff --git a/messenger/inc/class.messenger_ui.inc.php b/messenger/inc/class.messenger_ui.inc.php deleted file mode 100644 index c66adea206..0000000000 --- a/messenger/inc/class.messenger_ui.inc.php +++ /dev/null @@ -1,187 +0,0 @@ - - * @package messenger - * @subpackage setup - * @copyright (c) 2014 by Stylite AG - * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License - * @version $Id: $ - */ - -class messenger_ui extends admin_accesslog -{ - /** - * Public functions - * - * @var type - */ - var $public_functions = array( - 'dialog' => true, - 'index' => true, - ); - - /** - * Constructor - */ - function __construct() - { - parent::__construct(); - } - - /** - * Open a conversation dialog with Video,Audio and Message exchange availability - * - * @param type $content - */ - function dialog($content=null) - { - - egw_framework::csp_connect_src_attrs(array("http://".$_SERVER['HTTP_HOST'],"ws://".$_SERVER['HTTP_HOST'])); - - $tmpl = new etemplate_new('messenger.dialog'); - $content['account_id'] = $_GET['id']; - $content['type'] = $_GET['type']; - - - $tmpl->exec('messenger.messenger_ui.dialog', $content,array(),array(),array(),array(),2); - } - - /** - * List of available users - * - * @param type $content - */ - function index($content=null) - { - egw_framework::csp_connect_src_attrs(array("http://".$_SERVER['HTTP_HOST'],"ws://".$_SERVER['HTTP_HOST'])); - - if (!isset($content)) - { - $content['nm'] = array ( - 'get_rows' => 'messenger.messenger_ui.get_rows', - 'no_filter' => True, // I disable the 1. filter - 'no_filter2' => True, // I disable the 2. filter (params are the same as for filter) - 'no_cat' => True, // I disable the cat-selectbox - 'sort' => 'DESC', - 'session_list' => 'active', // Choose active users from session - 'row_id' => 'account_id', - 'actions' => $this->get_actions(), - ); - } - else { - - } - - $tmpl = new etemplate_new('messenger.index'); - - // Initialise the toolbar actions - $tmpl->setElementAttribute('dialog[indexToolbar]', 'actions', self::get_toolbarActions()); - - return $tmpl->exec('messenger.messenger_ui.index', $content, array(),array()); - } - - /** - * Sends notification from calller to callee, and opens a conversation dialog for callee - * - * @param array $_param - */ - function ajax_makeChat (array $_param) - { - if (is_array($_param)) - { - $account_id = (int)$_param[0]; - $chatType = $_param[1]; - } - if ($account_id && is_int($account_id)) - { - $egwPush_Obj = new egw_json_push($account_id); - $egwPush_Obj->call("egw.open_link",'messenger.messenger_ui.dialog&id='.$GLOBALS['egw_info']['user']['account_id'].'&type='.$chatType,'_blank','600x750','messenger',true); - } - } - - /** - * Create actions for nm action - * - * @return array an array of actions - */ - public static function get_actions () - { - $actions = array( - 'chat' => array ( - 'caption' => 'Send MSG', - 'default' => true, - 'url' => 'menuaction=messenger.messenger_ui.dialog&id=$id', - 'popup' => egw_link::get_registry('messenger', 'dialog_popup'), - ), - 'call' => array ( - 'caption' => 'Call', - 'onExecute' => 'javaScript:app.messenger.makeCall', - 'popup' => egw_link::get_registry('messenger', 'dialog_popup') - ) - ); - return $actions; - } - - /** - * query rows for the nextmatch widget - * - * @param array $query with keys 'start', 'search', 'order', 'sort', 'col_filter' - * @param array &$rows returned rows/competitions - * @param array &$readonlys eg. to disable buttons based on acl, not use here, maybe in a derived class - * @return int total number of rows - */ - function get_rows($query,&$rows,&$readonlys) - { - // Avoid to show own user name on the list - $query['col_filter'][4] = "(account_id !=". $GLOBALS['egw_info']['user']['account_id']. ")"; - - $total = parent::get_rows($query, $rows, $readonlys); - return $total || array(); - } - - /** - * This function generates toolbar actions - * - * @return array an array of actions - */ - public static function get_toolbarActions () - { - $actions = array ( - 'call' => array( - 'caption' => 'Call', - 'icon' => 'call', - 'onExecute' => 'javaScript:app.messenger.toolbarActions', - 'popup' => egw_link::get_registry('messenger', 'dialog_popup'), - ), - 'vcall' => array( - 'caption' => 'Video call', - 'icon' => 'video_call', - 'onExecute' => 'javaScript:app.messenger.toolbarActions', - 'popup' => egw_link::get_registry('messenger', 'dialog_popup'), - ), - 'hangup' => array ( - 'caption' => 'Hangup', - 'icon' => 'hangup', - 'onExecute' => 'javaScript:app.messenger.toolbarActions', - ), - 'video' => array( - 'caption' => 'Video', - 'icon' => 'camera', - 'checkbox' => true, - 'onExecute' => 'javaScript:app.messenger.toolbarActions', - ), - 'micro' => array( - 'caption' => 'Microphone', - 'icon' => 'microphone', - 'checkbox' => true, - 'onExecute' => 'javaScript:app.messenger.toolbarActions', - ), - - ); - return $actions; - } - -} \ No newline at end of file diff --git a/messenger/js/app.js b/messenger/js/app.js deleted file mode 100644 index b63707e525..0000000000 --- a/messenger/js/app.js +++ /dev/null @@ -1,126 +0,0 @@ -/** - * EGroupware - messenger - Javascript UI - * - * @link http://www.egroupware.org - * @author Hadi Nategh - * @package messenger - * @subpackage setup - * @copyright (c) 2014 by Stylite AG - * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License - * @version $Id: $ - */ - -app.classes.messenger = AppJS.extend( -{ - appname:'messenger', - - connection:{}, - /** - * Constructor - * - * @memberOf app.messenger - */ - init: function () - { - var self = this; - var scripts = ['/socket.io/socket.io/socket.io.js','messenger/js/easyrtc/easyrtc.js']; - egw_LAB.script(scripts).wait(function(){ - // Ready to make connection - }); - - }, - - /** - * Destructor - */ - destroy: function() - { - this._super.apply(this, arguments); - }, - - /** - * This function is called when the etemplate2 object is loaded - * and ready. If you must store a reference to the et2 object, - * make sure to clean it up in destroy(). - * - * @param {etemplate2} et2 newly ready object - * @param {string} name - */ - et2_ready: function (et2,name) - { - // call parent - this._super.apply(this, arguments); - switch (name) - { - case 'messenger.dialog': - - break; - case 'messenger.index': - - } - }, - - /** - * Initialize webrtc connection - */ - _init_webrtc: function () - { - - }, - - makeCall: function () - { - - }, - - /** - * Get account label of a specific account_id - * @param {type} _account_id - * @returns {account.label} account label - */ - getAccountName: function (_account_id) - { - var accounts = egw.accounts('accounts'); - for (var account in accounts) - { - if (account.value == _account_id) return account.label; - } - }, - - userOnSelect: function (_rowId) - { - var id = _rowId[0].split('::')[1]; - }, - - /** - * Index toolbar actions, handles selected toolbar actions and redirect them to - * its related functionallity. - * - * @param {action object} _action selected toolbar action - */ - toolbarActions: function (_action) - { - var nm = this.et2.getWidgetById('nm'); - if (nm && _action) - { - var uid = nm.getSelection()['ids'][0]; - if (!uid) return; - - switch (_action.id) - { - case 'call': - // make call to selected uid - this.makeCall(_action, {0:{id:uid}}); - break; - case 'micro': - //TODO - case 'video': - //TODO - case 'video_call': - //TODO - case 'hangup': - } - } - } - -}); \ No newline at end of file diff --git a/messenger/js/easyrtc/README.md b/messenger/js/easyrtc/README.md deleted file mode 100755 index ef48b77a52..0000000000 --- a/messenger/js/easyrtc/README.md +++ /dev/null @@ -1,32 +0,0 @@ -EasyRTC Server Example -====================== - -This folder contains all the files you'll need to create a simple server with EasyRTC, Express, and Socket.io. You can copy these files where you wish. - -Files and Folders: ------------------- - - - package.json - Provides project information allowing npm to find and install required modules. - - server.js - Server code. - - /static/ - Root folder for web server. Put html files here! - - -Installing Required Modules: ----------------------------- - - - Type `npm install` in console. - - This will read the package.json file to find and install the required modules including EasyRTC, Express, and Socket.io. - - Required modules will go into a new 'node_modules' subfolder - - -Running the Server: -------------------- - - - Type `node server` in console. - - -Viewing the examples: ---------------------- - - - In your WebRTC enabled browser, visit your server address including the port. By default port 8080 is used. - - http://localhost:8080/ \ No newline at end of file diff --git a/messenger/js/easyrtc/easyrtc.js b/messenger/js/easyrtc/easyrtc.js deleted file mode 100644 index 96621510c2..0000000000 --- a/messenger/js/easyrtc/easyrtc.js +++ /dev/null @@ -1,5468 +0,0 @@ -// -// the below code is a copy of the standard polyfill adapter.js -// -var getUserMedia = null; -var attachMediaStream = null; -var reattachMediaStream = null; -var webrtcDetectedBrowser = null; -var webrtcDetectedVersion = null; -if (navigator.mozGetUserMedia) { -// console.log("This appears to be Firefox"); - - webrtcDetectedBrowser = "firefox"; - - // - // better version detection for gecko based browsers provided by - // Kévin Poulet. - // - var matches = navigator.userAgent.match(/\srv:([0-9]+)\./); - if (matches !== null && matches.length > 1) { - webrtcDetectedVersion = parseInt(matches[1]); - } - - // The RTCPeerConnection object. - window.RTCPeerConnection = mozRTCPeerConnection; - // The RTCSessionDescription object. - window.RTCSessionDescription = mozRTCSessionDescription; - // The RTCIceCandidate object. - window.RTCIceCandidate = mozRTCIceCandidate; - // Get UserMedia (only difference is the prefix). - // Code from Adam Barth. - window.getUserMedia = navigator.mozGetUserMedia.bind(navigator); - // Creates iceServer from the url for FF. - window.createIceServer = function(url, username, password) { - var iceServer = null; - var url_parts = url.split(':'); - var turn_url_parts; - if (url_parts[0].indexOf('stun') === 0) { - // Create iceServer with stun url. - iceServer = {'url': url}; - } else if (url_parts[0].indexOf('turn') === 0 && - (url.indexOf('transport=udp') !== -1 || - url.indexOf('?transport') === -1)) { - // Create iceServer with turn url. - // Ignore the transport parameter from TURN url. - turn_url_parts = url.split("?"); - iceServer = {'url': turn_url_parts[0], - 'credential': password, - 'username': username}; - } - return iceServer; - }; - // Attach a media stream to an element. - attachMediaStream = function(element, stream) { -// console.log("Attaching media stream"); - element.mozSrcObject = stream; - element.play(); - }; - reattachMediaStream = function(to, from) { -// console.log("Reattaching media stream"); - to.mozSrcObject = from.mozSrcObject; - to.play(); - }; - if (webrtcDetectedVersion < 23) { -// Fake get{Video,Audio}Tracks - MediaStream.prototype.getVideoTracks = function() { - return []; - }; - MediaStream.prototype.getAudioTracks = function() { - return []; - }; - } -} else if (navigator.webkitGetUserMedia) { -// console.log("This appears to be Chrome"); - - webrtcDetectedBrowser = "chrome"; - webrtcDetectedVersion = - parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2]); - // Creates iceServer from the url for Chrome. - window.createIceServer = function(url, username, password) { - var iceServer = null; - var url_turn_parts; - var url_parts = url.split(':'); - if (url_parts[0].indexOf('stun') === 0) { -// Create iceServer with stun url. - iceServer = {'url': url}; - } else if (url_parts[0].indexOf('turn') === 0) { - if (webrtcDetectedVersion < 28) { -// For pre-M28 chrome versions use old TURN format. - url_turn_parts = url.split("turn:"); - iceServer = {'url': 'turn:' + username + '@' + url_turn_parts[1], - 'credential': password}; - } else { -// For Chrome M28 & above use new TURN format. - iceServer = {'url': url, - 'credential': password, - 'username': username}; - } - } - return iceServer; - }; - // The RTCPeerConnection object. - window.RTCPeerConnection = webkitRTCPeerConnection; - // Get UserMedia (only difference is the prefix). - // Code from Adam Barth. - window.getUserMedia = navigator.webkitGetUserMedia.bind(navigator); - // Attach a media stream to an element. - attachMediaStream = function(element, stream) { - if (typeof element.srcObject !== 'undefined') { - element.srcObject = stream; - } else if (typeof element.mozSrcObject !== 'undefined') { - element.mozSrcObject = stream; - } else if (typeof element.src !== 'undefined') { - element.src = URL.createObjectURL(stream); - } else { - console.log('Error attaching stream to element.'); - } - }; - reattachMediaStream = function(to, from) { - to.src = from.src; - }; - // The representation of tracks in a stream is changed in M26. - // Unify them for earlier Chrome versions in the coexisting period. - if (!webkitMediaStream.prototype.getVideoTracks) { - webkitMediaStream.prototype.getVideoTracks = function() { - return this.videoTracks; - }; - webkitMediaStream.prototype.getAudioTracks = function() { - return this.audioTracks; - }; - } - -// New syntax of getXXXStreams method in M26. - if (!webkitRTCPeerConnection.prototype.getLocalStreams) { - webkitRTCPeerConnection.prototype.getLocalStreams = function() { - return this.localStreams; - }; - webkitRTCPeerConnection.prototype.getRemoteStreams = function() { - return this.remoteStreams; - }; - } -//} else if( window.ActiveXObject ){ // appears to IE so check for the wrapper. -// var head = document.getElementsByTagName('head')[0]; -// var i; -// var adapterAddress; -// var wrapperPresent = false; -// -// // -// // we look for the adapter as well as the wrapper because if we don't find the -// // wrapper, we'll look for it in the same directory as the adapter was found. -// // -// for( i = 0; i < head.childNodes.length; i++) { -// var child = head.childNodes[i]; -// if( /\/adapter.js$/.test(child.src)) { -// adapterAddress = child.src; -// } -// else if( /\/rtcplugin.js$/.test(child.src)) { -// wrapperPresent = true; -// } -// } -// -// -// if( wrapperPresent) { -// addIEDeclarations(); -// } -// else if( adapterAddress) { -// var script = document.createElement('script'); -// script.type = 'text/javascript'; -// script.src = adapterAddress.replace(/\/adapter.js$/, "/rtcplugin.js"); -// src.onload = addIEDeclarations; -// src.onerror = function () { -// alert("Developer error: this page requires the Priologic IE Webrtc plugin wrapper (rtcplugin.js) to run when using Internet Explorer, which the developer has not supplied."); -// throw new Error("No rtcplugin.js found. It should be in the same folder as your adapter.js or you can include it yourself before the adapter.js"); -// } -// head.appendChild(script); -// } -} else { - console.log("Browser does not appear to be WebRTC-capable"); -} - -if (!window.createIceServer) { - window.createIceServer = function(url, username, credential) { - return {'url': url, 'credential': credential, 'username': username}; - }; -}/** @class - *@version 1.0.13 - *

- * Provides client side support for the EasyRTC framework. - * Please see the easyrtc_client_api.md and easyrtc_client_tutorial.md - * for more details.

- * - *

- *copyright Copyright (c) 2014, Priologic Software Inc. - *All rights reserved.

- * - *

- *Redistribution and use in source and binary forms, with or without - *modification, are permitted provided that the following conditions are met: - *

- *
    - *
  • Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer.
  • - *
  • Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution.
  • - *
- *

- *THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - *AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - *IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - *ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - *LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - *CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - *SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - *INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - *CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - *ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - *POSSIBILITY OF SUCH DAMAGE. - *

- */ - -var Easyrtc = function() { - var self = this; - var isFirefox = (webrtcDetectedBrowser === "firefox"); - var autoInitUserMedia = true; - var sdpLocalFilter = null, - sdpRemoteFilter = null; - var iceCandidateFilter = null; - - var connectionOptions = { - 'connect timeout': 10000, - 'force new connection': true - }; - - /** - * Sets functions which filter sdp records before calling setLocalDescription or setRemoteDescription. - * This is advanced functionality which can break things, easily. See the easyrtc_rates.js file for a - * filter builder. - * @param {Function} localFilter a function that takes an sdp string and returns an sdp string. - * @param {Function} remoteFilter a function that takes an sdp string and returns an sdp string. - */ - this.setSdpFilters = function(localFilter, remoteFilter) { - sdpLocalFilter = localFilter; - sdpRemoteFilter = remoteFilter; - }; - - /** - * Sets a function which filters IceCandidate records being sent or received. - * - * Candidate records can be received while they are being generated locally (before being - * sent to a peer), and after they are received by the peer. The filter receives two arguments, the candidate record and a boolean - * flag that is true for a candidate being received from another peer, - * and false for a candidate that was generated locally. The candidate record has the form: - * {type: 'candidate', label: sdpMLineIndex, id: sdpMid, candidate: candidateString} - * The function should return one of the following: the input candidate record, a modified candidate record, or null (indicating that the - * candidate should be discarded). - * @param {Function} filter - * @param {String} isIncoming - * @return an ice candidate record or null. - */ - this.setIceCandidateFilter = function(filter) { - iceCandidateFilter = filter; - } - - /** - * Controls whether a default local media stream should be acquired automatically during calls and accepts - * if a list of streamNames is not supplied. The default is true, which mimicks the behaviour of earlier releases - * that didn't support multiple streams. This function should be called before easyrtc.call or before entering an - * accept callback. - * @param {Boolean} flag true to allocate a default local media stream. - */ - this.setAutoInitUserMedia = function(flag) { - autoInitUserMedia = !!flag; - } - /** - * This function performs a printf like formatting. It actually takes an unlimited - * number of arguments, the declared arguments arg1, arg2, arg3 are present just for - * documentation purposes. - * @param {String} format A string like "abcd{1}efg{2}hij{1}." - * @param {String} arg1 The value that replaces {1} - * @param {String} arg2 The value that replaces {2} - * @param {String} arg3 The value that replaces {3} - * @returns {String} the formatted string. - */ - this.format = function(format, arg1, arg2, arg3) { - var formatted = arguments[0]; - for (var i = 1; i < arguments.length; i++) { - var regexp = new RegExp('\\{' + (i - 1) + '\\}', 'gi'); - formatted = formatted.replace(regexp, arguments[i]); - } - return formatted; - }; - /** @private */ - var haveAudioVideo = {audio: false, video: false}; -// -// Maps a key to a language specific string using the easyrtc_constantStrings map. -// Defaults to the key if the key can not be found, but outputs a warning in that case. -// This function is only used internally by easyrtc.js -// - /** - * @private - * @param {String} key - */ - this.getConstantString = function(key) { - if (easyrtc_constantStrings[key]) { - return easyrtc_constantStrings[key]; - } - else { - console.warn("Could not find key='" + key + "' in easyrtc_constantStrings"); - return key; - } - }; - // - // this is a list of the events supported by the generalized event listener. - // - var allowedEvents = { - roomOccupant: true, // this receives the list of everybody in any room you belong to - roomOccupants: true // this receives a {roomName:..., occupants:...} value for a specific room - }; - // - // A map of eventListeners. The key is the event type. - var eventListeners = {}; - /** This function checks if an attempt was made to add an event listener or - * or emit an unlisted event, since such is typically a typo. - * @private - * @param {String} eventName - * @param {String} callingFunction the name of the calling function. - */ - function event(eventName, callingFunction) { - if (typeof eventName !== 'string') { - self.showError(self.errCodes.DEVELOPER_ERR, src + " called without a string as the first argument"); - throw "developer error"; - } - if (!allowedEvents[eventName]) { - self.showError(self.errCodes.DEVELOPER_ERR, src + " called with a bad event name = " + eventName); - throw "developer error"; - } - } - - /** - * Adds an event listener for a particular type of event. - * Currently the only eventName supported is "roomOccupant". - * @param {String} eventName the type of the event - * @param {Function} eventListener the function that expects the event. - * The eventListener gets called with the eventName as it's first argument, and the event - * data as it's second argument. - * @returns {void} - */ - this.addEventListener = function(eventName, eventListener) { - event(eventName, "addEventListener"); - if (typeof eventListener !== 'function') { - self.showError(self.errCodes.DEVELOPER_ERR, "addEventListener called with a non-function for second argument"); - throw "developer error"; - } - // - // remove the event listener if it's already present so we don't end up with two copies - // - self.removeEventListener(eventName, eventListener); - if (!eventListeners[eventName]) { - eventListeners[eventName] = []; - } - eventListeners[eventName][eventListeners[eventName].length] = eventListener; - }; - /** - * Removes an event listener. - * @param {String} eventName - * @param {Function} eventListener - */ - this.removeEventListener = function(eventName, eventListener) { - event(eventName, "removeEventListener"); - var listeners = eventListeners[eventName]; - var i = 0; - if (listeners) { - for (i = 0; i < listeners.length; i++) { - if (listeners[i] === eventListener) { - if (i < listeners.length - 1) { - listeners[i] = listeners[listeners.length - 1]; - } - listeners.length = listeners.length - 1; - } - } - } - }; - /** - * Emits an event, or in otherwords, calls all the eventListeners for a - * particular event. - * @param {String} eventName - * @param {Object} eventData - */ - this.emitEvent = function(eventName, eventData) { - event(eventName, "emitEvent"); - var listeners = eventListeners[eventName]; - var i = 0; - if (listeners) { - for (i = 0; i < listeners.length; i++) { - listeners[i](eventName, eventData); - } - } - }; - /** Error codes that the EasyRTC will use in the errorCode field of error object passed - * to error handler set by easyrtc.setOnError. The error codes are short printable strings. - * @type Object - */ - this.errCodes = { - BAD_NAME: "BAD_NAME", // a user name wasn't of the desired form - CALL_ERR: "CALL_ERR", // something went wrong creating the peer connection - DEVELOPER_ERR: "DEVELOPER_ERR", // the developer using the EasyRTC library made a mistake - SYSTEM_ERR: "SYSTEM_ERR", // probably an error related to the network - CONNECT_ERR: "CONNECT_ERR", // error occurred when trying to create a connection - MEDIA_ERR: "MEDIA_ERR", // unable to get the local media - MEDIA_WARNING: "MEDIA_WARNING", // didn't get the desired resolution - INTERNAL_ERR: "INTERNAL_ERR", - PEER_GONE: "PEER_GONE", // peer doesn't exist - ALREADY_CONNECTED: "ALREADY_CONNECTED", - BAD_CREDENTIAL: "BAD_CREDENTIAL", - ICECANDIDATE_ERR: "ICECANDIDATE_ERROR" - }; - this.apiVersion = "1.0.13"; - /** Most basic message acknowledgment object */ - this.ackMessage = {msgType: "ack"}; - /** Regular expression pattern for user ids. This will need modification to support non US character sets */ - this.usernameRegExp = /^(.){1,64}$/; - /** @private */ - var cookieId = "easyrtcsid"; - /** @private */ - var username = null; - /** @private */ - var loggingOut = false; - /** @private */ - var disconnecting = false; - // - // A map of ids to local media streams. - // - var namedLocalMediaStreams = {}; - var sessionFields = []; - var receivedMediaContraints = { - 'mandatory': { - 'OfferToReceiveAudio': true, - 'OfferToReceiveVideo': true - } - }; - /** - * Control whether the client requests audio from a peer during a call. - * Must be called before the call to have an effect. - * @param value - true to receive audio, false otherwise. The default is true. - */ - this.enableAudioReceive = function(value) { - receivedMediaContraints.mandatory.OfferToReceiveAudio = value; - }; - /** - * Control whether the client requests video from a peer during a call. - * Must be called before the call to have an effect. - * @param value - true to receive video, false otherwise. The default is true. - */ - this.enableVideoReceive = function(value) { - receivedMediaContraints.mandatory.OfferToReceiveVideo = value; - }; - - function getSourceList(callback, sourceType) { - if (MediaStreamTrack.getSources) { - MediaStreamTrack.getSources(function(sources) { - var results = []; - for (var i = 0; i < sources.length; i++) { - var source = sources[i]; - if (source.kind == sourceType) { - results.push(source); - } - } - callback(results); - }); - } - else { - callback([]); - } - } - - /** - * Gets a list of the available audio sources (ie, cameras) - * @param {Function} callback receives list of {label:String, id:String, kind:"audio"} - * Note: the label string always seems to be the empty string if you aren't using https. - * Note: not supported by Firefox. - * @example easyrtc.getAudioSourceList( function(list) { - * var i; - * for( i = 0; i < list.length; i++ ) { - * console.log("label=" + list[i].label + ", id= " + list[i].id); - * } - * }); - */ - this.getAudioSourceList = function(callback){ - getSourceList(callback, "audio"); - } - - /** - * Gets a list of the available video sources (ie, cameras) - * @param {Function} callback receives list of {facing:String, label:String, id:String, kind:"video"} - * Note: the label string always seems to be the empty string if you aren't using https. - * Note: not supported by Firefox. - * @example easyrtc.getVideoSourceList( function(list) { - * var i; - * for( i = 0; i < list.length; i++ ) { - * console.log("label=" + list[i].label + ", id= " + list[i].id); - * } - * }); - */ - this.getVideoSourceList = function(callback) { - getSourceList(callback, "video"); - } - - /** @private */ - var audioEnabled = true; - /** @private */ - var videoEnabled = true; - /** @private */ - var dataChannelName = "dc"; - /** @private */ - this.debugPrinter = null; - /** Your easyrtcid */ - this.myEasyrtcid = ""; - /** @private */ - var oldConfig = {}; - /** @private */ - var offersPending = {}; - /** @private */ - var selfRoomJoinTime = 0; - /** The height of the local media stream video in pixels. This field is set an indeterminate period - * of time after easyrtc.initMediaSource succeeds. Note: in actuality, the dimensions of a video stream - * change dynamically in response to external factors, you should check the videoWidth and videoHeight attributes - * of your video objects before you use them for pixel specific operations. - */ - this.nativeVideoHeight = 0; - /** The width of the local media stream video in pixels. This field is set an indeterminate period - * of time after easyrtc.initMediaSource succeeds. Note: in actuality, the dimensions of a video stream - * change dynamically in response to external factors, you should check the videoWidth and videoHeight attributes - * of your video objects before you use them for pixel specific operations. - */ - this.nativeVideoWidth = 0; - /** @private */ - var credential = null; - /** The rooms the user is in. This only applies to room oriented applications and is set at the same - * time a token is received. - */ - this.roomJoin = {}; - /** Checks if the supplied string is a valid user name (standard identifier rules) - * @param {String} name - * @return {Boolean} true for a valid user name - * @example - * var name = document.getElementById('nameField').value; - * if( !easyrtc.isNameValid(name)){ - * console.error("Bad user name"); - * } - */ - this.isNameValid = function(name) { - return self.usernameRegExp.test(name); - }; - /** - * This function sets the name of the cookie that client side library will look for - * and transmit back to the server as it's easyrtcsid in the first message. - * @param {String} cookieId - */ - this.setCookieId = function(cookieId) { - self.cookieId = cookieId; - }; - /** - * This method allows you to join a single room. It may be called multiple times to be in - * multiple rooms simultaneously. It may be called before or after connecting to the server. - * Note: the successCB and failureDB will only be called if you are already connected to the server. - * @param {String} roomName the room to be joined. - * @param {String} roomParameters application specific parameters, can be null. - * @param {Function} successCB called once, with a roomName as it's argument, once the room is joined. - * @param {Function} failureCB called if the room can not be joined. The arguments of failureCB are errorCode, errorText, roomName. - */ - this.joinRoom = function(roomName, roomParameters, successCB, failureCB) { - if (self.roomJoin[roomName]) { - console.error("Developer error: attempt to join room " + roomName + " which you are already in."); - return; - } - - var newRoomData = {roomName: roomName}; - if (roomParameters) { - try { - JSON.stringify(roomParameters); - } catch (error) { - self.showError(self.errCodes.DEVELOPER_ERR, "non-jsonable parameter to easyrtc.joinRoom"); - throw "Developer error, see application error messages"; - } - var parameters = {}; - for (var key in roomParameters) { - if (roomParameters.hasOwnProperty(key)) { - parameters[key] = roomParameters[key]; - } - } - newRoomData.roomParameter = parameters; - } - var msgData = { - roomJoin: {} - }; - var roomData; - var signallingSuccess, signallingFailure; - if (self.webSocket) { - - msgData.roomJoin[roomName] = newRoomData; - signallingSuccess = function(msgType, msgData) { - - roomData = msgData.roomData; - self.roomJoin[roomName] = newRoomData; - if (successCB) { - successCB(roomName); - } - - processRoomData(roomData); - }; - signallingFailure = function(errorCode, errorText) { - if (failureCB) { - failureCB(errorCode, errorText, roomName); - } - else { - self.showError(errorCode, self.format(self.getConstantString("unableToEnterRoom"), roomName, errorText)); - } - }; - sendSignalling(null, "roomJoin", msgData, signallingSuccess, signallingFailure); - } - else { - self.roomJoin[roomName] = newRoomData; - } - - }; - /** - * This function allows you to leave a single room. Note: the successCB and failureDB - * arguments are optional and will only be called if you are already connected to the server. - * @param {String} roomName - * @param {Function} successCallback - A function which expects a roomName. - * @param {Function} failureCallback - A function which expects the following arguments: errorCode, errorText, roomName. - * @example - * easyrtc.leaveRoom("freds_room"); - * easyrtc.leaveRoom("freds_room", function(roomName){ console.log("left the room")}, - * function(errorCode, errorText, roomName){ console.log("left the room")}); - */ - this.leaveRoom = function(roomName, successCallback, failureCallback) { - var roomItem; - if (self.roomJoin[roomName]) { - if (!self.webSocket) { - delete self.roomJoin[roomName]; - } - else { - roomItem = {}; - roomItem[roomName] = {roomName: roomName}; - sendSignalling(null, "roomLeave", {roomLeave: roomItem}, - function(msgType, msgData) { - var roomData = msgData.roomData; - processRoomData(roomData); - if (successCallback) { - successCallback(roomName); - } - }, - function(errorCode, errorText) { - if (failureCallback) { - failureCallback(errorCode, errorText, roomName); - } - }); - } - } - }; - /** @private */ - this._desiredVideoProperties = {}; // default camera - - - /** - * Specify particular video source. Call this before you call easyrtc.initMediaSource(). - * Note: this function isn't supported by Firefox. - * @param {String} videoSrcId is a id value from one of the entries fetched by getVideoSourceList. null for default. - * @example easyrtc.setVideoSrc( videoSrcId); - */ - this.setVideoSource = function(videoSrcId) { - self._desiredVideoProperties.videoSrcId = videoSrcId; - delete self._desiredVideoProperties.screenCapture; - }; - /** - * Temporary alias for easyrtc.setVideoSource - */ - this.setVideoSrc = this.setVideoSource; - delete this._desiredVideoProperties.screenCapture; - /** This function is used to set the dimensions of the local camera, usually to get HD. - * If called, it must be called before calling easyrtc.initMediaSource (explicitly or implicitly). - * assuming it is supported. If you don't pass any parameters, it will default to 720p dimensions. - * @param {Number} width in pixels - * @param {Number} height in pixels - * @param {number} frameRate is optional - * @example - * easyrtc.setVideoDims(1280,720); - * @example - * easyrtc.setVideoDims(); - */ - this.setVideoDims = function(width, height, frameRate) { - if (!width) { - width = 1280; - height = 720; - } - self._desiredVideoProperties.width = width; - self._desiredVideoProperties.height = height; - if (frameRate !== undefined) { - self._desiredVideoProperties.frameRate = frameRate; - } - }; - /** This function requests that screen capturing be used to provide the local media source - * rather than a webcam. If you have multiple screens, they are composited side by side. - * Note: this functionality is not supported by Firefox, has to be called before calling initMediaSource (or easyApp), we don't currently supply a way to - * turn it off (once it's on), only works if the website is hosted SSL (https), and the image quality is rather - * poor going across a network because it tries to transmit so much data. In short, screen sharing - * through WebRTC isn't worth using at this point, but it is provided here so people can try it out. - * @example - * easyrtc.setScreenCapture(); - * @deprecated: use easyrtc.initScreenCapture (same parameters as easyrtc.initMediaSource. - */ - this.setScreenCapture = function(enableScreenCapture) { - self._desiredVideoProperties.screenCapture = (enableScreenCapture !== false); - }; - /** - * Builds the constraint object passed to getUserMedia. - * @returns {Object} mediaConstraints - */ - self.getUserMediaConstraints = function() { - var constraints = {}; - // - // _presetMediaConstraints allow you to provide your own contraints to be used - // with initMediaSource. - // - if (self._presetMediaConstraints) { - constraints = self._presetMediaConstraints; - delete self._presetMediaConstraints; - return constraints; - } - else if (self._desiredVideoProperties.screenCapture) { - return { - video: { - mandatory: { - chromeMediaSource: 'screen', - maxWidth: screen.width, - maxHeight: screen.height, - minWidth: screen.width, - minHeight: screen.height, - minFrameRate: 1, - maxFrameRate: 5}, - optional: [] - }, - audio: false - }; - } - else if (!videoEnabled) { - constraints.video = false; - } - else { - constraints.video = {mandatory: {}, optional: []}; - if (self._desiredVideoProperties.width) { - constraints.video.mandatory.maxWidth = self._desiredVideoProperties.width; - constraints.video.mandatory.minWidth = self._desiredVideoProperties.width; - } - if (self._desiredVideoProperties.width) { - constraints.video.mandatory.maxHeight = self._desiredVideoProperties.height; - constraints.video.mandatory.minHeight = self._desiredVideoProperties.height; - } - if (self._desiredVideoProperties.frameRate) { - constraints.video.mandatory.maxFrameRate = self._desiredVideoProperties.frameRate; - } - if (self._desiredVideoProperties.videoSrcId) { - constraints.video.optional.push({sourceId: self._desiredVideoProperties.videoSrcId}); - } - // hack for opera - if (constraints.video.mandatory.length === 0 && constraints.video.optional.length === 0) { - constraints.video = true; - } - } - constraints.audio = audioEnabled; - return constraints; - }; - /** Set the application name. Applications can only communicate with other applications - * that share the same API Key and application name. There is no predefined set of application - * names. Maximum length is - * @param {String} name - * @example - * easyrtc.setApplicationName('simpleAudioVideo'); - */ - this.setApplicationName = function(name) { - self.applicationName = name; - }; - /** Enable or disable logging to the console. - * Note: if you want to control the printing of debug messages, override the - * easyrtc.debugPrinter variable with a function that takes a message string as it's argument. - * This is exactly what easyrtc.enableDebug does when it's enable argument is true. - * @param {Boolean} enable - true to turn on debugging, false to turn off debugging. Default is false. - * @example - * easyrtc.enableDebug(true); - */ - this.enableDebug = function(enable) { - if (enable) { - self.debugPrinter = function(message) { - var stackString = new Error().stack; - var srcLine = "location unknown"; - if (stackString) { - var stackFrameStrings = stackString.split('\n'); - srcLine = ""; - if (stackFrameStrings.length >= 3) { - srcLine = stackFrameStrings[2]; - } - } - console.log("debug " + (new Date()).toISOString() + " : " + message + " [" + srcLine + "]"); - }; - } - else { - self.debugPrinter = null; - } - }; -// -// this is a temporary version used until we connect to the server. -// - this.updatePresence = function(state, statusText) { - self.presenceShow = state; - self.presenceStatus = statusText; - }; - /** - * Determines if the local browser supports WebRTC GetUserMedia (access to camera and microphone). - * @returns {Boolean} True getUserMedia is supported. - */ - this.supportsGetUserMedia = function() { - return !!getUserMedia; - }; - /** - * Determines if the local browser supports WebRTC Peer connections to the extent of being able to do video chats. - * @returns {Boolean} True if Peer connections are supported. - */ - this.supportsPeerConnections = function() { - if (!self.supportsGetUserMedia()) { - return false; - } - if (!window.RTCPeerConnection) { - return false; - } - try { - self.createRTCPeerConnection({"iceServers": []}, null); - } catch (oops) { - return false; - } - return true; - }; - /** @private - * @param pc_config ice configuration array - * @param optionalStuff peer constraints. - */ - /** @private - * @param pc_config ice configuration array - * @param optionalStuff peer constraints. - */ - this.createRTCPeerConnection = function(pc_config, optionalStuff) { - if (RTCPeerConnection) { - return new RTCPeerConnection(pc_config, optionalStuff); - } - else { - throw "Your browser doesn't support webRTC (RTCPeerConnection)"; - } - }; -// -// this should really be part of adapter.js -// Versions of chrome < 31 don't support reliable data channels transport. -// Firefox does. -// - this.getDatachannelConstraints = function() { - if (webrtcDetectedBrowser === "chrome" && webrtcDetectedVersion < 31) { - return {reliable: false}; - } - else { - return {reliable: true}; - } - }; - /** @private */ - haveAudioVideo = { - audio: false, - video: false - }; - /** @private */ - var dataEnabled = false; - /** @private */ - var serverPath = null; - /** @private */ - var roomOccupantListener = null; - /** @private */ - var onDataChannelOpen = null; - /** @private */ - var onDataChannelClose = null; - /** @private */ - var lastLoggedInList = {}; - /** @private */ - var receivePeer = {msgTypes: {}}; - /** @private */ - var receiveServerCB = null; - /** @private */ - var updateConfigurationInfo = function() { - - }; // dummy placeholder for when we aren't connected -// -// -// peerConns is a map from caller names to the below object structure -// { startedAV: boolean, -- true if we have traded audio/video streams -// dataChannelS: RTPDataChannel for outgoing messages if present -// dataChannelR: RTPDataChannel for incoming messages if present -// dataChannelReady: true if the data channel can be used for sending yet -// connectTime: timestamp when the connection was started -// sharingAudio: true if audio is being shared -// sharingVideo: true if video is being shared -// cancelled: temporarily true if a connection was cancelled by the peer asking to initiate it -// candidatesToSend: SDP candidates temporarily queued -// streamsAddedAcks: ack callbacks waiting for stream received messages -// pc: RTCPeerConnection -// mediaStream: mediaStream -// function callSuccessCB(string) - see the easyrtc.call documentation. -// function callFailureCB(errorCode, string) - see the easyrtc.call documentation. -// function wasAcceptedCB(boolean,string) - see the easyrtc.call documentation. -// } -// - /** @private */ - var peerConns = {}; -// -// a map keeping track of whom we've requested a call with so we don't try to -// call them a second time before they've responded. -// - /** @private */ - var acceptancePending = {}; - /** - * Disconnect from the EasyRTC server. - * @example - * easyrtc.disconnect(); - */ - this.disconnect = function() { - }; - /** @private - * @param caller - * @param helper - */ - this.acceptCheck = function(caller, helper) { - helper(true); - }; - /** @private - * @param easyrtcid - * @param stream - */ - this.streamAcceptor = function(easyrtcid, stream) { - }; - /** @private - * @param easyrtcid - */ - this.onStreamClosed = function(easyrtcid) { - }; - /** @private - * @param easyrtcid - */ - this.callCancelled = function(easyrtcid) { - }; - /** - * This function gets the statistics for a particular peer connection. - * @param {String} peerId - * @param {Function} callback gets the peerid and a map of {userDefinedKey: value}. If there is no peer connection to peerId, then the map will - * have a value of {connected:false}. - * @param {Object} filter depends on whether Chrome or Firefox is used. See the default filters for guidance. - * It is still experimental. - */ - this.getPeerStatistics = function(peerId, callback, filter) { - if (isFirefox) { - self.getFirefoxPeerStatistics(peerId, callback, filter); - } - else { - self.getChromePeerStatistics(peerId, callback, filter); - } - }; - this.getFirefoxPeerStatistics = function(peerId, callback, filter) { - - - if (!peerConns[peerId]) { - callback(peerId, {"connected": false}); - } - else if (peerConns[peerId].pc.getStats) { - peerConns[peerId].pc.getStats(null, function(stats) { - var items = {}; - var candidates = {}; - var activeId = null; - var srcKey; - // - // the stats objects has a group of entries. Each entry is either an rtcp, rtp entry - // or a candidate entry. - // - stats.forEach(function(entry) { - var majorKey; - var subKey; - if (entry.type.match(/boundrtp/)) { - if (entry.id.match(/audio/)) { - majorKey = entry.type + "_audio"; - } - else if (entry.id.match(/video/)) { - majorKey = entry.type + "_video"; - } - else { - return; - } - for (subKey in entry) { - if (entry.hasOwnProperty(subKey)) { - items[majorKey + "." + subKey] = entry[subKey]; - } - } - } - else { - if( entry.hasOwnProperty("ipAddress") && entry.hasOwnProperty("id")) { - candidates[entry.id] = entry.ipAddress + ":" + - entry.portNumber; - } - else if( entry.hasOwnProperty("selected") && - entry.hasOwnProperty("remoteCandidateId") && - entry.selected ) { - activeId = entry.remoteCandidateId; - } - } - }); - - if( activeId ) { - items["firefoxRemoteAddress"] = candidates[activeId]; - } - if (!filter) { - callback(peerId, items); - } - else { - var filteredItems = {}; - for (srcKey in filter) { - if (filter.hasOwnProperty(srcKey) && items.hasOwnProperty(srcKey)) { - filteredItems[ filter[srcKey]] = items[srcKey]; - } - } - callback(peerId, filteredItems); - } - }, - function(error) { - console.log("unable to get statistics"); - }); - } - else { - callback(peerId, {"statistics": self.getConstantString("statsNotSupported")}); - } - }; - this.getChromePeerStatistics = function(peerId, callback, filter) { - - if (!peerConns[peerId]) { - callback(peerId, {"connected": false}); - } - else if (peerConns[peerId].pc.getStats) { - - peerConns[peerId].pc.getStats(function(stats) { - - var localStats = {}; - var part, parts = stats.result(); - var i, j; - var itemKeys; - var itemKey; - var names; - var userKey; - var partNames = []; - var partList; - var bestBytes = 0; - var bestI; - var turnAddress = null; - var hasActive, curReceived; - var localAddress, remoteAddress; - if (!filter) { - for (i = 0; i < parts.length; i++) { - names = parts[i].names(); - for (j = 0; j < names.length; j++) { - itemKey = names[j]; - localStats[parts[i].id + "." + itemKey] = parts[i].local.stat(itemKey); - } - } - } - else { - for (i = 0; i < parts.length; i++) { - partNames[i] = {}; - // - // convert the names into a dictionary - // - names = parts[i].names(); - for (j = 0; j < names.length; j++) { - partNames[i][names[j]] = true; - } - - // - // a chrome-firefox connection results in several activeConnections. - // we only want one, so we look for the one with the most data being received on it. - // - if (partNames[i].googRemoteAddress && partNames[i].googActiveConnection) { - hasActive = parts[i].local.stat("googActiveConnection"); - if (hasActive === true || hasActive === "true") { - curReceived = parseInt(parts[i].local.stat("bytesReceived")) + - parseInt(parts[i].local.stat("bytesSent")); - if (curReceived > bestBytes) { - bestI = i; - bestBytes = curReceived; - } - } - } - } - - for (i = 0; i < parts.length; i++) { - // - // discard info from any inactive connection. - // - if (partNames[i].googActiveConnection) { - if (i !== bestI) { - partNames[i] = {}; - } - else { - localAddress = parts[i].local.stat("googLocalAddress").split(":")[0]; - remoteAddress = parts[i].local.stat("googRemoteAddress").split(":")[0]; - if (self.isTurnServer(localAddress)) { - turnAddress = localAddress; - } - else if (self.isTurnServer(remoteAddress)) { - turnAddress = remoteAddress; - } - } - } - } - - for (i = 0; i < filter.length; i++) { - itemKeys = filter[i]; - partList = []; - part = null; - for (j = 0; j < parts.length; j++) { - var fullMatch = true; - for (itemKey in itemKeys) { - if (itemKeys.hasOwnProperty(itemKey) && !partNames[j][itemKey]) { - fullMatch = false; - break; - } - } - if (fullMatch && parts[j]) { - partList.push(parts[j]); - } - } - if (partList.length === 1) { - for (j = 0; j < partList.length; j++) { - part = partList[j]; - if (part.local) { - for (itemKey in itemKeys) { - if (itemKeys.hasOwnProperty(itemKey)) { - userKey = itemKeys[itemKey]; - localStats[userKey] = part.local.stat(itemKey); - } - } - } - } - } - else if (partList.length > 1) { - for (itemKey in itemKeys) { - if (itemKeys.hasOwnProperty(itemKey)) { - localStats[itemKeys[itemKey]] = []; - } - } - for (j = 0; j < partList.length; j++) { - part = partList[j]; - if (part.local) { - for (itemKey in itemKeys) { - if (itemKeys.hasOwnProperty(itemKey)) { - userKey = itemKeys[itemKey]; - localStats[userKey].push(part.local.stat(itemKey)); - } - } - } - } - } - } - } - - if (localStats.remoteAddress && turnAddress) { - localStats.remoteAddress = turnAddress; - } - callback(peerId, localStats); - }); - } - else { - callback(peerId, {"statistics": self.getConstantString("statsNotSupported")}); - } - }; - this.chromeStatsFilter = [ - { - "googTransmitBitrate": "transmitBitRate", - "googActualEncBitrate": "encodeRate", - "googAvailableSendBandwidth": "availableSendRate" - }, - { - "googCodecName": "audioCodec", - "googTypingNoiseState": "typingNoise", - "packetsSent": "audioPacketsSent", - "bytesSent": "audioBytesSent" - }, - { - "googCodecName": "videoCodec", - "googFrameRateSent": "outFrameRate", - "packetsSent": "videoPacketsSent", - "bytesSent": "videoBytesSent" - }, - { - "packetsLost": "videoPacketsLost", - "packetsReceived": "videoPacketsReceived", - "bytesReceived": "videoBytesReceived", - "googFrameRateOutput": "frameRateOut" - }, - { - "packetsLost": "audioPacketsLost", - "packetsReceived": "audioPacketsReceived", - "bytesReceived": "audioBytesReceived", - "audioOutputLevel": "audioOutputLevel" - }, - { - "googRemoteAddress": "remoteAddress", - "googActiveConnection": "activeConnection" - }, - { - "audioInputLevel": "audioInputLevel" - } - ]; - this.firefoxStatsFilter = { - "outboundrtp_audio.bytesSent": "audioBytesSent", - "outboundrtp_video.bytesSent": "videoBytesSent", - "inboundrtp_video.bytesReceived": "videoBytesReceived", - "inboundrtp_audio.bytesReceived": "audioBytesReceived", - "outboundrtp_audio.packetsSent": "audioPacketsSent", - "outboundrtp_video.packetsSent": "videoPacketsSent", - "inboundrtp_video.packetsReceived": "videoPacketsReceived", - "inboundrtp_audio.packetsReceived": "audioPacketsReceived", - "inboundrtp_video.packetsLost": "videoPacketsLost", - "inboundrtp_audio.packetsLost": "audioPacketsLost", - "firefoxRemoteAddress": "remoteAddress" - }; - this.standardStatsFilter = isFirefox ? self.firefoxStatsFilter : self.chromeStatsFilter; - /** Provide a set of application defined fields that will be part of this instances - * configuration information. This data will get sent to other peers via the websocket - * path. - * @param {String} roomName - the room the field is attached to. - * @param {String} fieldName - the name of the field. - * @param {Object} fieldValue - the value of the field. - * @example - * easyrtc.setRoomApiField("trekkieRoom", "favorite_alien", "Mr Spock"); - * easyrtc.setRoomOccupantListener( function(roomName, list){ - * for( var i in list ){ - * console.log("easyrtcid=" + i + " favorite alien is " + list[i].apiFields.favorite_alien); - * } - * }); - */ - this.setRoomApiField = function(roomName, fieldName, fieldValue) { - // - // if we're not connected yet, we'll just cache the fields until we are. - // - if (!self._roomApiFields) { - self._roomApiFields = {}; - } - if (!fieldName && !fieldValue) { - delete self._roomApiFields[roomName]; - return; - } - - if (!self._roomApiFields[roomName]) { - self._roomApiFields[roomName] = {}; - } - if (fieldValue !== undefined && fieldValue !== null) { - if (typeof fieldValue === "object") { - try { - JSON.stringify(fieldValue); - } - catch (jsonError) { - self.showError(self.errCodes.DEVELOPER_ERR, "easyrtc.setRoomApiField passed bad object "); - return; - } - } - self._roomApiFields[roomName][fieldName] = {fieldName: fieldName, fieldValue: fieldValue}; - } - else { - delete self._roomApiFields[roomName][fieldName]; - } - if (self.webSocketConnected) { - _enqueueSendRoomApi(roomName); - } - }; - var roomApiFieldTimer = null; - /** @private - * @param {String} roomName - */ - function _enqueueSendRoomApi(roomName) { -// -// Rather than issue the send request immediately, we set a timer so we can accumulate other -// calls -// - if (roomApiFieldTimer) { - clearTimeout(roomApiFieldTimer); - } - roomApiFieldTimer = setTimeout(function() { - _sendRoomApiFields(roomName, self._roomApiFields[roomName]); - roomApiFieldTimer = null; - }, 10); - } - ; - /** - * @private - * @param roomName - * @param fields - */ - function _sendRoomApiFields(roomName, fields) { - var fieldAsString = JSON.stringify(fields); - JSON.parse(fieldAsString); - var dataToShip = { - msgType: "setRoomApiField", - msgData: { - setRoomApiField: { - roomName: roomName, - field: fields - } - } - }; - self.webSocket.json.emit("easyrtcCmd", dataToShip, - function(ackMsg) { - if (ackMsg.msgType === "error") { - self.showError(ackMsg.msgData.errorCode, ackMsg.msgData.errorText); - } - } - ); - } - ; - /** Default error reporting function. The default implementation displays error messages - * in a programmatically created div with the id easyrtcErrorDialog. The div has title - * component with a class name of easyrtcErrorDialog_title. The error messages get added to a - * container with the id easyrtcErrorDialog_body. Each error message is a text node inside a div - * with a class of easyrtcErrorDialog_element. There is an "okay" button with the className of easyrtcErrorDialog_okayButton. - * @param {String} messageCode An error message code - * @param {String} message the error message text without any markup. - * @example - * easyrtc.showError("BAD_NAME", "Invalid username"); - */ - this.showError = function(messageCode, message) { - self.onError({errorCode: messageCode, errorText: message}); - }; - /** @private - * @param errorObject - */ - this.onError = function(errorObject) { - if (self.debugPrinter) { - self.debugPrinter("saw error " + errorObject.errorText); - } - var errorDiv = document.getElementById('easyrtcErrorDialog'); - var errorBody; - if (!errorDiv) { - errorDiv = document.createElement("div"); - errorDiv.id = 'easyrtcErrorDialog'; - var title = document.createElement("div"); - title.innerHTML = "Error messages"; - title.className = "easyrtcErrorDialog_title"; - errorDiv.appendChild(title); - errorBody = document.createElement("div"); - errorBody.id = "easyrtcErrorDialog_body"; - errorDiv.appendChild(errorBody); - var clearButton = document.createElement("button"); - clearButton.appendChild(document.createTextNode("Okay")); - clearButton.className = "easyrtcErrorDialog_okayButton"; - clearButton.onclick = function() { - errorBody.innerHTML = ""; // remove all inner nodes - errorDiv.style.display = "none"; - }; - errorDiv.appendChild(clearButton); - document.body.appendChild(errorDiv); - } - - errorBody = document.getElementById("easyrtcErrorDialog_body"); - var messageNode = document.createElement("div"); - messageNode.className = 'easyrtcErrorDialog_element'; - messageNode.appendChild(document.createTextNode(errorObject.errorText)); - errorBody.appendChild(messageNode); - errorDiv.style.display = "block"; - }; -// -// easyrtc.createObjectURL builds a URL from a media stream. -// Arguments: -// mediaStream - a media stream object. -// The video object in Chrome expects a URL. -// - /** @private - * @param mediaStream */ - this.createObjectURL = function(mediaStream) { - var errMessage; - if (window.URL && window.URL.createObjectURL) { - return window.URL.createObjectURL(mediaStream); - } - else if (window.webkitURL && window.webkitURL.createObjectURL) { - return window.webkit.createObjectURL(mediaStream); - } - else { - errMessage = "Your browsers does not support URL.createObjectURL."; - if (self.debugPrinter) { - self.debugPrinter("saw exception " + errMessage); - } - throw errMessage; - } - }; - /** - * A convenience function to ensure that a string doesn't have symbols that will be interpreted by HTML. - * @param {String} idString - * @return {String} The cleaned string. - * @example - * console.log( easyrtc.cleanId('&hello')); - */ - this.cleanId = function(idString) { - var MAP = { - '&': '&', - '<': '<', - '>': '>' - }; - return idString.replace(/[&<>]/g, function(c) { - return MAP[c]; - }); - }; - /** Set a callback that will be invoked when the application enters or leaves a room. - * - * @param {Function} handler - the first parameter is true for entering a room, false for leaving a room. The second parameter is the room name. - * @example - * easyrtc.setRoomEntryListener(function(entry, roomName){ - * if( entry ){ - * console.log("entering room " + roomName); - * } - * else{ - * console.log("leaving room " + roomName); - * } - * }); - */ - self.setRoomEntryListener = function(handler) { - self.roomEntryListener = handler; - }; - /** Set the callback that will be invoked when the list of people logged in changes. - * The callback expects to receive a room name argument, and - * a map whose ideas are easyrtcids and whose values are in turn maps - * supplying user specific information. The inner maps have the following keys: - * username, applicationName, browserFamily, browserMajor, osFamily, osMajor, deviceFamily. - * The third argument is the listener is the innerMap for the connections own data (not needed by most applications). - * @param {Function} listener - * @example - * easyrtc.setRoomOccupantListener( function(roomName, list, selfInfo){ - * for( var i in list ){ - * ("easyrtcid=" + i + " belongs to user " + list[i].username); - * } - * }); - */ - self.setRoomOccupantListener = function(listener) { - roomOccupantListener = listener; - }; - /** - * Sets a callback that is called when a data channel is open and ready to send data. - * The callback will be called with an easyrtcid as it's sole argument. - * @param {Function} listener - * @example - * easyrtc.setDataChannelOpenListener( function(easyrtcid){ - * easyrtc.sendDataP2P(easyrtcid, "greeting", "hello"); - * }); - */ - this.setDataChannelOpenListener = function(listener) { - onDataChannelOpen = listener; - }; - /** Sets a callback that is called when a previously open data channel closes. - * The callback will be called with an easyrtcid as it's sole argument. - * @param {Function} listener - * @example - * easyrtc.setDataChannelCloseListener( function(easyrtcid){ - * ("No longer connected to " + easyrtc.idToName(easyrtcid)); - * }); - */ - this.setDataChannelCloseListener = function(listener) { - onDataChannelClose = listener; - }; - /** Returns the number of live peer connections the client has. - * @return {Number} - * @example - * ("You have " + easyrtc.getConnectionCount() + " peer connections"); - */ - this.getConnectionCount = function() { - var count = 0; - var i; - for (i in peerConns) { - if (peerConns.hasOwnProperty(i)) { - if (self.getConnectStatus(i) === self.IS_CONNECTED) { - count++; - } - } - } - return count; - }; - /** Sets whether audio is transmitted by the local user in any subsequent calls. - * @param {Boolean} enabled true to include audio, false to exclude audio. The default is true. - * @example - * easyrtc.enableAudio(false); - */ - this.enableAudio = function(enabled) { - audioEnabled = enabled; - }; - /** - *Sets whether video is transmitted by the local user in any subsequent calls. - * @param {Boolean} enabled - true to include video, false to exclude video. The default is true. - * @example - * easyrtc.enableVideo(false); - */ - this.enableVideo = function(enabled) { - videoEnabled = enabled; - }; - /** - * Sets whether WebRTC data channels are used to send inter-client messages. - * This is only the messages that applications explicitly send to other applications, not the WebRTC signaling messages. - * @param {Boolean} enabled true to use data channels, false otherwise. The default is false. - * @example - * easyrtc.enableDataChannels(true); - */ - this.enableDataChannels = function(enabled) { - dataEnabled = enabled; - }; - /** - * @private - * @param {Boolean} enable - * @param {Array} tracks - an array of MediaStreamTrack - */ - function enableMediaTracks(enable, tracks) { - var i; - if (tracks) { - for (i = 0; i < tracks.length; i++) { - var track = tracks[i]; - track.enabled = enable; - } - } - } - - - // - // fetches a stream by name. Treat a null/undefined streamName as "default". - // - function getLocalMediaStreamByName(streamName) { - if (!streamName) { - streamName = "default"; - } - if (namedLocalMediaStreams.hasOwnProperty(streamName)) { - return namedLocalMediaStreams[streamName]; - } - else { - return null; - } - } - - /** - * Returns the user assigned id's of currently active local media streams. - * @return {Array} - */ - this.getLocalMediaIds = function() { - return Object.keys(namedLocalMediaStreams); - } - - function buildMediaIds() { - var mediaMap = {}; - var streamName; - for (streamName in namedLocalMediaStreams) { - mediaMap[streamName] = namedLocalMediaStreams[streamName].id || "default"; - } - return mediaMap; - } - - - function registerLocalMediaStreamByName(stream, streamName) { - var roomName; - if (!streamName) { - streamName = "default"; - } - stream.streamName = streamName; - namedLocalMediaStreams[streamName] = stream; - if (streamName !== "default") { - var mediaIds = buildMediaIds(); - for (roomName in self.roomData) { - self.setRoomApiField(roomName, "mediaIds", mediaIds); - } - } - } - - /** - * Allow an externally created mediastream (ie, created by another - * library) to be used within easyrtc. Tracking when it closes - * must be done by the supplying party. - */ - this.register3rdPartyLocalMediaStream = function(stream, streamName) { - return registerLocalMediaStreamByName(stream, streamName); - }; - // - // look up a stream's name from the stream.id - // - function getNameOfRemoteStream(easyrtcId, webrtcstreamId) { - var roomName; - var mediaIds; - var streamName; - if (!webrtcstreamId) { - webrtcstreamId = "default"; - } - if (peerConns[easyrtcId]) { - streamName = peerConns[easyrtcId].remoteStreamIdToName[webrtcstreamId]; - if (streamName) { - return streamName; - } - } - - for (roomName in self.roomData) { - mediaIds = self.getRoomApiField(roomName, easyrtcId, "mediaIds"); - if (!mediaIds) { - continue; - } - for (streamName in mediaIds) { - if (mediaIds.hasOwnProperty(streamName) && - mediaIds[streamName] === webrtcstreamId) { - return streamName; - } - } - // - // a stream from chrome to firefox will be missing it's id/label. - // there is no correct solution. - // - if( isFirefox ) { - // if there is a stream called default, return it in preference - if( mediaIds["default"] ) { - return "default"; - } - // - // otherwise return the first name we find. If there is more than - // one, complain to Mozilla. - // - for( var anyName in mediaIds ) { - return anyName; - } - } - } - return undefined; - } - - this.getNameOfRemoteStream = function(easyrtcId, webrtcStream){ - if(typeof webrtcStream == "string") { - return getNameOfRemoteStream(easyrtcId, webrtcStream); - } - else if( webrtcStream.id) { - return getNameOfRemoteStream(easyrtcId, webrtcStream.id); - } - } - - function closeLocalMediaStreamByName(streamName) { - if (!streamName) { - streamName = "default"; - } - var stream = self.getLocalStream(streamName); - if (!stream) { - return; - } - var streamId = stream.id || "default"; - if (namedLocalMediaStreams[streamName]) { - - - for (id in peerConns) { - if (peerConns.hasOwnProperty(id)) { - try { - peerConns[id].pc.removeStream(stream); - } catch (err) { - } - self.sendPeerMessage(id, "__closingMediaStream", {streamId: streamId, streamName: streamName}); - } - } - try { - namedLocalMediaStreams[streamName].stop(); - } catch (err) { - // not worth reporting an error at this location - // since we didn't want the media stream anyhow. - } - delete namedLocalMediaStreams[streamName]; - if (streamName !== "default") { - var mediaIds = buildMediaIds(); - for (roomName in self.roomData) { - self.setRoomApiField(roomName, "mediaIds", mediaIds); - } - } - } - } - /** - * Close the local media stream. You usually need to close the existing media stream - * of a camera before reacquring it at a different resolution. - * @param {String} streamName - an option stream name. - */ - this.closeLocalMediaStream = function(streamName) { - return closeLocalMediaStreamByName(streamName); - } - - /** - * Alias for closeLocalMediaStream - */ - this.closeLocalStream = this.closeLocalMediaStream; - /** - * This function is used to enable and disable the local camera. If you disable the - * camera, video objects display it will "freeze" until the camera is re-enabled. * - * By default, a camera is enabled. - * @param {Boolean} enable - true to enable the camera, false to disable it. - * @param {String} streamName - the name of the stream, optional. - */ - this.enableCamera = function(enable, streamName) { - var stream = getLocalMediaStreamByName(streamName); - if (stream && stream.getVideoTracks) { - enableMediaTracks(enable, stream.getVideoTracks()); - } - }; - /** - * This function is used to enable and disable the local microphone. If you disable - * the microphone, sounds stops being transmitted to your peers. By default, the microphone - * is enabled. - * @param {Boolean} enable - true to enable the microphone, false to disable it. - * @param {String} streamName - an optional streamName - */ - this.enableMicrophone = function(enable, streamName) { - var stream = getLocalMediaStreamByName(streamName); - if (stream && stream.getAudioTracks) { - enableMediaTracks(enable, stream.getAudioTracks()); - } - }; - /** - * Mute a video object. - * @param {String} videoObjectName - A DOMObject or the id of the DOMObject. - * @param {Boolean} mute - true to mute the video object, false to unmute it. - */ - self.muteVideoObject = function(videoObjectName, mute) { - var videoObject; - if (typeof (videoObjectName) === 'string') { - videoObject = document.getElementById(videoObjectName); - if (!videoObject) { - throw "Unknown video object " + videoObjectName; - } - } - else if (!videoObjectName) { - throw "muteVideoObject passed a null"; - } - else { - videoObject = videoObjectName; - } - videoObject.muted = !!mute; - }; - /** - * Returns a URL for your local camera and microphone. - * It can be called only after easyrtc.initMediaSource has succeeded. - * It returns a url that can be used as a source by the Chrome video element or the <canvas> element. - * @param {String} streamName - an option stream name. - * @return {URL} - * @example - * document.getElementById("myVideo").src = easyrtc.getLocalStreamAsUrl(); - */ - self.getLocalStreamAsUrl = function(streamName) { - var stream = getLocalMediaStreamByName(streamName); - if (stream === null) { - throw "Developer error: attempt to get a MediaStream without invoking easyrtc.initMediaSource successfully"; - } - return self.createObjectURL(stream); - }; - /** - * Returns a media stream for your local camera and microphone. - * It can be called only after easyrtc.initMediaSource has succeeded. - * It returns a stream that can be used as an argument to easyrtc.setVideoObjectSrc. - * Returns null if there is no local media stream acquired yet. - * @return {MediaStream} - * @example - * easyrtc.setVideoObjectSrc( document.getElementById("myVideo"), easyrtc.getLocalStream()); - */ - this.getLocalStream = function(streamName) { - return getLocalMediaStreamByName(streamName) || null; - }; - /** Clears the media stream on a video object. - * - * @param {Object} element the video object. - * @example - * easyrtc.clearMediaStream( document.getElementById('selfVideo')); - * - */ - this.clearMediaStream = function(element) { - if (typeof element.srcObject !== 'undefined') { - element.srcObject = null; - } else if (typeof element.mozSrcObject !== 'undefined') { - element.mozSrcObject = null; - } else if (typeof element.src !== 'undefined') { - //noinspection JSUndefinedPropertyAssignment - element.src = ""; - } - }; - /** - * Sets a video or audio object from a media stream. - * Chrome uses the src attribute and expects a URL, while firefox - * uses the mozSrcObject and expects a stream. This procedure hides - * that from you. - * If the media stream is from a local webcam, you may want to add the - * easyrtcMirror class to the video object so it looks like a proper mirror. - * The easyrtcMirror class is defined in this.css. - * Which is could be added using the same path of easyrtc.js file to an HTML file - * @param {Object} videoObject an HTML5 video object - * @param {MediaStream|String} stream a media stream as returned by easyrtc.getLocalStream or your stream acceptor. - * @example - * easyrtc.setVideoObjectSrc( document.getElementById("myVideo"), easyrtc.getLocalStream()); - * - */ - this.setVideoObjectSrc = function(videoObject, stream) { - if (stream && stream !== "") { - videoObject.autoplay = true; - attachMediaStream(videoObject, stream); - videoObject.play(); - } - else { - self.clearMediaStream(videoObject); - } - }; - - - /** - * This function builds a new named local media stream from a set of existing audio and video tracks from other media streams. - * @param {String} streamName is the name of the new media stream. - * @param {Array} audioTracks is an array of MediaStreamTracks - * @param {Array} videoTracks is an array of MediaStreamTracks - * @returns {MediaStream} the track created. - * @example - * easyrtc.buildLocalMediaStream("myComposedStream", - * easyrtc.getLocalStream("camera1").getVideoTracks(), - * easyrtc.getLocalStream("camera2").getAudioTracks()); - */ - this.buildLocalMediaStream = function(streamName, audioTracks, videoTracks) { - var i; - if (typeof streamName !== 'string') { - easyrtc.showError(this.errCodes.DEVELOPER_ERR, - "easyrtc.buildLocalMediaStream not supplied a stream name"); - return null; - } - - var streamToClone = null; - for(var key in namedLocalMediaStreams ) { - if( namedLocalMediaStreams.hasOwnProperty(key)) { - streamToClone = namedLocalMediaStreams[key]; - if(streamToClone) break; - } - } - if( !streamToClone ) { - for(key in peerConns) { - var remoteStreams = peerConns[key].pc.getRemoteStreams(); - if( remoteStreams && remoteStreams.length > 1 ) { - streamToClone = remoteStreams[0]; - } - } - } - if( !streamToClone ){ - self.showError(self.errCodes.DEVELOPER_ERR, - "Attempt to create a mediastream without one to clone from"); - return null; - } - - // - // clone whatever mediastream we found, and remove any of it's - // tracks. - // - var mediaClone = streamToClone.clone(); - var i; - var oldTracks = mediaClone.getTracks(); - - if (audioTracks) { - for (i = 0; i < audioTracks.length; i++) { - mediaClone.addTrack(audioTracks[i].clone()); - } - } - - if (videoTracks) { - for (i = 0; i < videoTracks.length; i++) { - mediaClone.addTrack(videoTracks[i].clone()); - } - } - - for( i = 0; i < oldTracks.length; i++ ) { - mediaClone.removeTrack(oldTracks[i]); - } - - registerLocalMediaStreamByName(mediaClone, streamName); - return mediaClone; - }; - - /* @private*/ - /** Load Easyrtc Stylesheet. - * Easyrtc Stylesheet define easyrtcMirror class and some basic css class for using easyrtc.js. - * That way, developers can override it or use it's own css file minified css or package. - * @example - * easyrtc.loadStylesheet(); - * - */ - this.loadStylesheet = function() { - - // - // check to see if we already have an easyrtc.css file loaded - // if we do, we can exit immediately. - // - var links = document.getElementsByTagName("link"); - var cssIndex, css; - for (cssIndex in links) { - if (links.hasOwnProperty(cssIndex)) { - css = links[cssIndex]; - if (css.href && (css.href.match(/\/easyrtc.css/))) { - return; - } - } - } - // - // add the easyrtc.css file since it isn't present - // - var easySheet = document.createElement("link"); - easySheet.setAttribute("rel", "stylesheet"); - easySheet.setAttribute("type", "text/css"); - easySheet.setAttribute("href", "/easyrtc/easyrtc.css"); - var headSection = document.getElementsByTagName("head")[0]; - var firstHead = headSection.childNodes[0]; - headSection.insertBefore(easySheet, firstHead); - }; - /** @private - * @param {String} x */ - this.formatError = function(x) { - var name, result; - if (x === null || typeof x === 'undefined') { - return "null"; - } - if (typeof x === 'string') { - return x; - } - else if (x.type && x.description) { - return x.type + " : " + x.description; - } - else if (typeof x === 'object') { - try { - return JSON.stringify(x); - } - catch (oops) { - result = "{"; - for (name in x) { - if (x.hasOwnProperty(name)) { - if (typeof x[name] === 'string') { - result = result + name + "='" + x[name] + "' "; - } - } - } - result = result + "}"; - return result; - } - } - else { - return "Strange case"; - } - }; - /** Initializes your access to a local camera and microphone. - * Failure could be caused a browser that didn't support WebRTC, or by the user - * not granting permission. - * If you are going to call easyrtc.enableAudio or easyrtc.enableVideo, you need to do it before - * calling easyrtc.initMediaSource. - * @param {function(Object)} successCallback - will be called with localmedia stream on success. - * @param {function(String,String)} errorCallback - is called with an error code and error description. - * @param {String} streamName - an optional name for the media source so you can use multiple cameras and screen share simultaneously. - * @example - * easyrtc.initMediaSource( - * function(mediastream){ - * easyrtc.setVideoObjectSrc( document.getElementById("mirrorVideo"), mediastream); - * }, - * function(errorCode, errorText){ - * easyrtc.showError(errorCode, errorText); - * }); - * - */ - this.initMediaSource = function(successCallback, errorCallback, streamName) { - - if (self.debugPrinter) { - self.debugPrinter("about to request local media"); - } - - if (!streamName) { - streamName = "default"; - } - - haveAudioVideo = { - audio: audioEnabled, - video: videoEnabled - }; - if (!errorCallback) { - errorCallback = function(errorCode, errorText) { - var message = "easyrtc.initMediaSource: " + self.formatError(errorText); - if (self.debugPrinter) { - self.debugPrinter(message); - } - self.showError(self.errCodes.MEDIA_ERR, message); - }; - } - - if (!self.supportsGetUserMedia()) { - errorCallback(self.errCodes.MEDIA_ERR, self.getConstantString("noWebrtcSupport")); - return; - } - - - if (!successCallback) { - self.showError(self.errCodes.DEVELOPER_ERR, - "easyrtc.initMediaSource not supplied a successCallback"); - return; - } - - - var mode = self.getUserMediaConstraints(); - /** @private - * @param {Object} stream - A mediaStream object. - * */ - var onUserMediaSuccess = function(stream) { - if (self.debugPrinter) { - self.debugPrinter("getUserMedia success callback entered"); - } - - if (self.debugPrinter) { - self.debugPrinter("successfully got local media"); - } - - stream.streamName = streamName; - registerLocalMediaStreamByName(stream, streamName); - var videoObj, triesLeft, tryToGetSize, ele; - if (haveAudioVideo.video) { - videoObj = document.createElement('video'); - videoObj.muted = true; - triesLeft = 30; - tryToGetSize = function() { - if (videoObj.videoWidth > 0 || triesLeft < 0) { - self.nativeVideoWidth = videoObj.videoWidth; - self.nativeVideoHeight = videoObj.videoHeight; - if (self._desiredVideoProperties.height && - (self.nativeVideoHeight !== self._desiredVideoProperties.height || - self.nativeVideoWidth !== self._desiredVideoProperties.width)) { - self.showError(self.errCodes.MEDIA_WARNING, - self.format(self.getConstantString("resolutionWarning"), - self._desiredVideoProperties.width, self._desiredVideoProperties.height, - self.nativeVideoWidth, self.nativeVideoHeight)); - } - self.setVideoObjectSrc(videoObj, ""); - if (videoObj.removeNode) { - videoObj.removeNode(true); - } - else { - ele = document.createElement('div'); - ele.appendChild(videoObj); - ele.removeChild(videoObj); - } - - updateConfigurationInfo(); - if (successCallback) { - successCallback(stream); - } - } - else { - triesLeft -= 1; - setTimeout(tryToGetSize, 300); - } - }; - self.setVideoObjectSrc(videoObj, stream); - tryToGetSize(); - } - else { - updateConfigurationInfo(); - if (successCallback) { - successCallback(stream); - } - } - }; - /** @private - * @param {String} error - */ - var onUserMediaError = function(error) { - console.log("getusermedia failed"); - if (self.debugPrinter) { - self.debugPrinter("failed to get local media"); - } - var errText; - if (typeof error === 'string') { - errText = error; - } - else if (error.name) { - errText = error.name; - } - else { - errText = "Unknown"; - } - if (errorCallback) { - console.log("invoking error callback", errText); - errorCallback(self.errCodes.MEDIA_ERR, self.format(self.getConstantString("gumFailed"), errText)); - } - closeLocalMediaStreamByName(streamName); - haveAudioVideo = { - audio: false, - video: false - }; - updateConfigurationInfo(); - }; - if (!audioEnabled && !videoEnabled) { - onUserMediaError(self.getConstantString("requireAudioOrVideo")); - return; - } - - function getCurrentTime() { - return (new Date()).getTime(); - } - - var firstCallTime; - function tryAgain(error) { - var currentTime = getCurrentTime(); - if (currentTime < firstCallTime + 1000) { - console.log("Trying getUserMedia a second time"); - setTimeout(function() { - getUserMedia(mode, onUserMediaSuccess, onUserMediaError); - }, 3000); - } - else { - onUserMediaError(error); - } - } - - if (videoEnabled || audioEnabled) { - // - // getUserMedia sometimes fails the first time I call it. I suspect it's a page loading - // issue. So I'm going to try adding a 3 second delay to allow things to settle down first. - // In addition, I'm going to try again after 3 seconds. - // - - - setTimeout(function() { - try { - firstCallTime = getCurrentTime(); - getUserMedia(mode, onUserMediaSuccess, tryAgain); - } catch (e) { - tryAgain(e); - } - }, 1000); - } - else { - onUserMediaSuccess(null); - } - }; - /** - * Sets the callback used to decide whether to accept or reject an incoming call. - * @param {Function} acceptCheck takes the arguments (callerEasyrtcid, acceptor). - * The acceptCheck callback is passed an easyrtcid and an aceptor function. The acceptor function should be called with either - * a true value (accept the call) or false value( reject the call) as it's first argument, and optionally, - * an array of local media streamNames as a second argument. - * @example - * easyrtc.setAcceptChecker( function(easyrtcid, acceptor){ - * if( easyrtc.idToName(easyrtcid) === 'Fred' ){ - * acceptor(true); - * } - * else if( easyrtc.idToName(easyrtcid) === 'Barney' ){ - * setTimeout( function(){ - acceptor(true, ['myOtherCam']); // myOtherCam presumed to a streamName - }, 10000); - * } - * else{ - * acceptor(false); - * } - * }); - */ - this.setAcceptChecker = function(acceptCheck) { - self.acceptCheck = acceptCheck; - }; - /** - * easyrtc.setStreamAcceptor sets a callback to receive media streams from other peers, independent - * of where the call was initiated (caller or callee). - * @param {Function} acceptor takes arguments (caller, mediaStream, mediaStreamName) - * @example - * easyrtc.setStreamAcceptor(function(easyrtcid, stream, streamName){ - * document.getElementById('callerName').innerHTML = easyrtc.idToName(easyrtcid); - * easyrtc.setVideoObjectSrc( document.getElementById("callerVideo"), stream); - * }); - */ - this.setStreamAcceptor = function(acceptor) { - self.streamAcceptor = acceptor; - }; - /** Sets the easyrtc.onError field to a user specified function. - * @param {Function} errListener takes an object of the form {errorCode: String, errorText: String} - * @example - * easyrtc.setOnError( function(errorObject){ - * document.getElementById("errMessageDiv").innerHTML += errorObject.errorText; - * }); - */ - self.setOnError = function(errListener) { - self.onError = errListener; - }; - /** - * Sets the callCancelled callback. This will be called when a remote user - * initiates a call to you, but does a "hangup" before you have a chance to get his video stream. - * @param {Function} callCancelled takes an easyrtcid as an argument and a boolean that indicates whether - * the call was explicitly cancelled remotely (true), or actually accepted by the user attempting a call to - * the same party. - * @example - * easyrtc.setCallCancelled( function(easyrtcid, explicitlyCancelled){ - * if( explicitlyCancelled ){ - * console.log(easyrtc.idToName(easyrtcid) + " stopped trying to reach you"); - * } - * else{ - * console.log("Implicitly called " + easyrtc.idToName(easyrtcid)); - * } - * }); - */ - this.setCallCancelled = function(callCancelled) { - self.callCancelled = callCancelled; - }; - /** Sets a callback to receive notification of a media stream closing. The usual - * use of this is to clear the source of your video object so you aren't left with - * the last frame of the video displayed on it. - * @param {Function} onStreamClosed takes an easyrtcid as it's first parameter, the stream as it's second argument, and name of the video stream as it's third. - * @example - * easyrtc.setOnStreamClosed( function(easyrtcid, stream, streamName){ - * easyrtc.setVideoObjectSrc( document.getElementById("callerVideo"), ""); - * ( easyrtc.idToName(easyrtcid) + " closed stream " + stream.id + " " + streamName); - * }); - */ - this.setOnStreamClosed = function(onStreamClosed) { - self.onStreamClosed = onStreamClosed; - }; - /** @deprecated No longer supported by Google. - * Sets the bandwidth for sending video data. - * Setting the rate too low will cause connection attempts to fail. 40 is probably good lower limit. - * The default is 50. A value of zero will remove bandwidth limits. - * @param {Number} kbitsPerSecond is rate in kilobits per second. - * @example - * easyrtc.setVideoBandwidth( 40); - */ - this.setVideoBandwidth = function(kbitsPerSecond) { - self.showError("easyrtc.setVideoBandwidth is deprecated, it no longer has an effect."); - }; - /** Determines whether the current browser supports the new data channels. - * EasyRTC will not open up connections with the old data channels. - * @returns {Boolean} - */ - this.supportsDataChannels = function() { - if (navigator.userAgent.match(/android/i)) { - return webrtcDetectedVersion >= 34; - } - else { - return (webrtcDetectedBrowser === "firefox" || webrtcDetectedVersion >= 32); - } - }; - /** - * Sets a listener for data sent from another client (either peer to peer or via websockets). - * If no msgType or source is provided, the listener applies to all events that aren't otherwise handled. - * If a msgType but no source is provided, the listener applies to all messages of that msgType that aren't otherwise handled. - * If a msgType and a source is provided, the listener applies to only message of the specified type coming from the specified peer. - * The most specific case takes priority over the more general. - * @param {Function} listener has the signature (easyrtcid, msgType, msgData, targeting). - * msgType is a string. targeting is null if the message was received using WebRTC data channels, otherwise it - * is an object that contains one or more of the following string valued elements {targetEasyrtcid, targetGroup, targetRoom}. - * @param {String} msgType - a string, optional. - * @param {String} source - the sender's easyrtcid, optional. - * @example - * easyrtc.setPeerListener( function(easyrtcid, msgType, msgData, targeting){ - * console.log("From " + easyrtc.idToName(easyrtcid) + - * " sent the following data " + JSON.stringify(msgData)); - * }); - * easyrtc.setPeerListener( function(easyrtcid, msgType, msgData, targeting){ - * console.log("From " + easyrtc.idToName(easyrtcid) + - * " sent the following data " + JSON.stringify(msgData)); - * }, 'food', 'dkdjdekj44--'); - * easyrtc.setPeerListener( function(easyrtcid, msgType, msgData, targeting){ - * console.log("From " + easyrtcid + - * " sent the following data " + JSON.stringify(msgData)); - * }, 'drink'); - * - * - */ - this.setPeerListener = function(listener, msgType, source) { - if (!msgType) { - receivePeer.cb = listener; - } - else { - if (!receivePeer.msgTypes[msgType]) { - receivePeer.msgTypes[msgType] = {sources: {}}; - } - if (!source) { - receivePeer.msgTypes[msgType].cb = listener; - } - else { - receivePeer.msgTypes[msgType].sources[source] = {cb: listener}; - } - } - }; - /* This function serves to distribute peer messages to the various peer listeners */ - /** @private - * @param {String} easyrtcid - * @param {Object} msg - needs to contain a msgType and a msgData field. - * @param {Object} targeting - */ - this.receivePeerDistribute = function(easyrtcid, msg, targeting) { - var msgType = msg.msgType; - var msgData = msg.msgData; - if (!msgType) { - console.log("received peer message without msgType", msg); - return; - } - - if (receivePeer.msgTypes[msgType]) { - if (receivePeer.msgTypes[msgType].sources[easyrtcid] && - receivePeer.msgTypes[msgType].sources[easyrtcid].cb) { - receivePeer.msgTypes[msgType].sources[easyrtcid].cb(easyrtcid, msgType, msgData, targeting); - return; - } - if (receivePeer.msgTypes[msgType].cb) { - receivePeer.msgTypes[msgType].cb(easyrtcid, msgType, msgData, targeting); - return; - } - } - if (receivePeer.cb) { - receivePeer.cb(easyrtcid, msgType, msgData, targeting); - } - }; - /** - * Sets a listener for messages from the server. - * @param {Function} listener has the signature (msgType, msgData, targeting) - * @example - * easyrtc.setServerListener( function(msgType, msgData, targeting){ - * ("The Server sent the following message " + JSON.stringify(msgData)); - * }); - */ - this.setServerListener = function(listener) { - receiveServerCB = listener; - }; - /** - * Sets the url of the Socket server. - * The node.js server is great as a socket server, but it doesn't have - * all the hooks you'd like in a general web server, like PHP or Python - * plug-ins. By setting the serverPath your application can get it's regular - * pages from a regular web server, but the EasyRTC library can still reach the - * socket server. - * @param {String} socketUrl - * @param {Object} options an optional dictionary of options for socket.io's connect method. - * The default is {'connect timeout': 10000,'force new connection': true } - * @example - * easyrtc.setSocketUrl(":8080", options); - */ - this.setSocketUrl = function(socketUrl, options) { - if (self.debugPrinter) { - self.debugPrinter("WebRTC signaling server URL set to " + socketUrl); - } - serverPath = socketUrl; - if( options ) { - connectionOptions = options; - } - }; - /** - * Sets the user name associated with the connection. - * @param {String} username must obey standard identifier conventions. - * @returns {Boolean} true if the call succeeded, false if the username was invalid. - * @example - * if( !easyrtc.setUsername("JohnSmith") ){ - * console.error("bad user name); - * - */ - this.setUsername = function(username) { - if( self.myEasyrtcid ) { - easyrtc.showError(easyrtc.errCodes.DEVELOPER_ERR, "easyrtc.setUsername called after authentication"); - return false; - } - else if (self.isNameValid(username)) { - self.username = username; - return true; - } - else { - self.showError(self.errCodes.BAD_NAME, self.format(self.getConstantString("badUserName"), username)); - return false; - } - }; - /** - * Get an array of easyrtcids that are using a particular username - * @param {String} username - the username of interest. - * @param {String} room - an optional room name argument limiting results to a particular room. - * @returns {Array} an array of {easyrtcid:id, roomName: roomName}. - */ - this.usernameToIds = function(username, room) { - var results = []; - var id, roomName; - for (roomName in lastLoggedInList) { - if (!lastLoggedInList.hasOwnProperty(roomName)) { - continue; - } - if (room && roomName !== room) { - continue; - } - for (id in lastLoggedInList[roomName]) { - if (!lastLoggedInList[roomName].hasOwnProperty(id)) { - continue; - } - if (lastLoggedInList[roomName][id].username === username) { - results.push({ - easyrtcid: id, - roomName: roomName - }); - } - } - } - return results; - }; - /** - * Returns another peers API field, if it exists. - * @param {type} roomName - * @param {type} easyrtcid - * @param {type} fieldName - * @returns {Object} Undefined if the attribute does not exist, its value otherwise. - */ - this.getRoomApiField = function(roomName, easyrtcid, fieldName) { - if (lastLoggedInList[roomName] && - lastLoggedInList[roomName][easyrtcid] && - lastLoggedInList[roomName][easyrtcid].apiField && - lastLoggedInList[roomName][easyrtcid].apiField[fieldName]) { - return lastLoggedInList[roomName][easyrtcid].apiField[fieldName].fieldValue; - } - else { - return undefined; - } - }; - /** - * Set the authentication credential if needed. - * @param {Object} credentialParm - a JSONable object. - */ - this.setCredential = function(credentialParm) { - try { - JSON.stringify(credentialParm); - credential = credentialParm; - return true; - } - catch (oops) { - self.showError(self.errCodes.BAD_CREDENTIAL, "easyrtc.setCredential passed a non-JSON-able object"); - throw "easyrtc.setCredential passed a non-JSON-able object"; - } - }; - /** - * Sets the listener for socket disconnection by external (to the API) reasons. - * @param {Function} disconnectListener takes no arguments and is not called as a result of calling easyrtc.disconnect. - * @example - * easyrtc.setDisconnectListener(function(){ - * easyrtc.showError("SYSTEM-ERROR", "Lost our connection to the socket server"); - * }); - */ - this.setDisconnectListener = function(disconnectListener) { - self.disconnectListener = disconnectListener; - }; - /** - * Convert an easyrtcid to a user name. This is useful for labeling buttons and messages - * regarding peers. - * @param {String} easyrtcid - * @return {String} the username associated with the easyrtcid, or the easyrtcid if there is - * no associated username. - * @example - * console.log(easyrtcid + " is actually " + easyrtc.idToName(easyrtcid)); - */ - this.idToName = function(easyrtcid) { - var roomName; - for (roomName in lastLoggedInList) { - if (!lastLoggedInList.hasOwnProperty(roomName)) { - continue; - } - if (lastLoggedInList[roomName][easyrtcid]) { - if (lastLoggedInList[roomName][easyrtcid].username) { - return lastLoggedInList[roomName][easyrtcid].username; - } - } - } - return easyrtcid; - }; - /* used in easyrtc.connect */ - /** @private */ - this.webSocket = null; - var pc_config = {}; - var pc_config_to_use = null; - var use_fresh_ice_each_peer = false; - /** - * Determines whether fresh ice server configuration should be requested from the server for each peer connection. - * @param {Boolean} value the default is false. - */ - this.setUseFreshIceEachPeerConnection = function(value) { - use_fresh_ice_each_peer = value; - }; - /** - * Returns the last ice config supplied by the EasyRTC server. This function is not normally used, it is provided - * for people who want to try filtering ice server configuration on the client. - * @return {Object} which has the form {iceServers:[ice_server_entry, ice_server_entry, ...]} - */ - this.getServerIce = function() { - return pc_config; - }; - /** - * Sets the ice server configuration that will be used in subsequent calls. You only need this function if you are filtering - * the ice server configuration on the client or if you are using TURN certificates that have a very short lifespan. - * @param {Object} ice An object with iceServers element containing an array of ice server entries. - * @example - * easyrtc.setIceUsedInCalls( {"iceServers": [ - * { - * "url": "stun:stun.sipgate.net" - * }, - * { - * "url": "stun:217.10.68.152" - * }, - * { - * "url": "stun:stun.sipgate.net:10000" - * } - * ]}); - * easyrtc.call(...); - */ - this.setIceUsedInCalls = function(ice) { - if (!ice.iceServers) { - easyrtc.showError(easyrtc.errCodes.DEVELOPER_ERR, "Bad ice configuration passed to easyrtc.setIceUsedInCalls"); - } - else { - pc_config_to_use = ice; - } - }; - var closedChannel = null; - /** @private - * @param easyrtcid - * @param checkAudio - */ - function _haveTracks(easyrtcid, checkAudio, streamName) { - var stream, peerConnObj; - if (!easyrtcid) { - stream = getLocalMediaStreamByName(streamName); - } - else { - peerConnObj = peerConns[easyrtcid]; - if (!peerConnObj) { - console.error("Developer error: haveTracks called about a peer you don't have a connection to"); - return false; - } - stream = peerConnObj.getRemoteStreamByName(streamName); - } - if (!stream) { - return false; - } - - var tracks; - try { - if (checkAudio) { - tracks = stream.getAudioTracks(); - } - else { - tracks = stream.getVideoTracks(); - } - } catch (oops) { - return true; - } - if (!tracks) - return false; - return tracks.length > 0; - } - ; - /** Determines if a particular peer2peer connection has an audio track. - * @param {String} easyrtcid - the id of the other caller in the connection. If easyrtcid is not supplied, checks the local media. - * @param {String} streamName - an optional stream id. - * @return {Boolean} true if there is an audio track or the browser can't tell us. - */ - this.haveAudioTrack = function(easyrtcid, streamName) { - return _haveTracks(easyrtcid, true, streamName); - }; - /** Determines if a particular peer2peer connection has a video track. - * @param {String} easyrtcid - the id of the other caller in the connection. If easyrtcid is not supplied, checks the local media. - * @param {String} streamName - an optional stream id. * - * @return {Boolean} true if there is an video track or the browser can't tell us. - */ - this.haveVideoTrack = function(easyrtcid, streamName) { - return _haveTracks(easyrtcid, false, streamName); - }; - /** - * Gets a data field associated with a room. - * @param {String} roomName - the name of the room. - * @param {String} fieldName - the name of the field. - * @return {Object} dataValue - the value of the field if present, undefined if not present. - */ - this.getRoomField = function(roomName, fieldName) { - var fields = self.getRoomFields(roomName); - if (!fields || !fields[fieldName]) - return undefined; - return fields[fieldName].fieldValue; - }; -// -// Experimental function to determine if statistics gathering is supported. -// - this.supportsStatistics = function() { - var peer; - try { - peer = new RTCPeerConnection({iceServers: []}, {}); - return !!peer.getStats; - } - catch (err) { - return false; - } - }; - /** - * Connects to the EasyRTC signaling server. You must connect before trying to - * call other users. - * @param {String} applicationName is a string that identifies the application so that different applications can have different - * lists of users. Note that the server configuration specifies a regular expression that is used to check application names - * for validity. The default pattern is that of an identifier, spaces are not allowed. - * @param {Function} successCallback (easyrtcId, roomOwner) - is called on successful connect. easyrtcId is the - * unique name that the client is known to the server by. A client usually only needs it's own easyrtcId for debugging purposes. - * roomOwner is true if the user is the owner of a room. It's value is random if the user is in multiple rooms. - * @param {Function} errorCallback (errorCode, errorText) - is called on unsuccessful connect. if null, an alert is called instead. - * The errorCode takes it's value from easyrtc.errCodes. - * @example - * easyrtc.connect("mychat_app", - * function(easyrtcid, roomOwner){ - * if( roomOwner){ console.log("I'm the room owner"); } - * console.log("my id is " + easyrtcid); - * }, - * function(errorText){ - * console.log("failed to connect ", erFrText); - * }); - */ - - var fields = null; - function isEmptyObj(obj) { - if (obj === null || obj === undefined) { - return true; - } - var key; - for (key in obj) { - if (obj.hasOwnProperty(key)) { - return false; - } - } - return true; - } - - // -// easyrtc.disconnect performs a clean disconnection of the client from the server. -// - function disconnectBody() { - var key; - self.loggingOut = true; - offersPending = {}; - acceptancePending = {}; - self.disconnecting = true; - closedChannel = self.webSocket; - if (self.webSocketConnected) { - if (!preallocatedSocketIo) { - self.webSocket.close(); - } - self.webSocketConnected = false; - } - self.hangupAll(); - if (roomOccupantListener) { - for (key in lastLoggedInList) { - if (lastLoggedInList.hasOwnProperty(key)) { - roomOccupantListener(key, {}, false); - } - } - } - lastLoggedInList = {}; - self.emitEvent("roomOccupant", {}); - self.roomData = {}; - self.roomJoin = {}; - self.loggingOut = false; - self.myEasyrtcid = null; - self.disconnecting = false; - oldConfig = {}; - } - ; - this.disconnect = function() { - - if (self.debugPrinter) { - self.debugPrinter("attempt to disconnect from WebRTC signalling server"); - } - - self.disconnecting = true; - self.hangupAll(); - self.loggingOut = true; - // - // The hangupAll may try to send configuration information back to the server. - // Collecting that information is asynchronous, we don't actually close the - // connection until it's had a chance to be sent. We allocate 100ms for collecting - // the info, so 250ms should be sufficient for the disconnecting. - // - setTimeout(function() { - if (self.webSocket) { - try { - self.webSocket.disconnect(); - } catch (e) { - // we don't really care if this fails. - } - - closedChannel = self.webSocket; - self.webSocket = 0; - } - self.loggingOut = false; - self.disconnecting = false; - if (roomOccupantListener) { - roomOccupantListener(null, {}, false); - } - self.emitEvent("roomOccupant", {}); - oldConfig = {}; - }, 250); - }; - // - // This function is used to send WebRTC signaling messages to another client. These messages all the form: - // destUser: some id or null - // msgType: one of ["offer"/"answer"/"candidate","reject","hangup", "getRoomList"] - // msgData: either null or an SDP record - // successCallback: a function with the signature function(msgType, wholeMsg); - // errorCallback: a function with signature function(errorCode, errorText) - // - function sendSignalling(destUser, msgType, msgData, successCallback, errorCallback) { - if (!self.webSocket) { - throw "Attempt to send message without a valid connection to the server."; - } - else { - var dataToShip = { - msgType: msgType - }; - if (destUser) { - dataToShip.targetEasyrtcid = destUser; - } - if (msgData) { - dataToShip.msgData = msgData; - } - - if (self.debugPrinter) { - self.debugPrinter("sending socket message " + JSON.stringify(dataToShip)); - } - self.webSocket.json.emit("easyrtcCmd", dataToShip, - function(ackMsg) { - if (ackMsg.msgType !== "error") { - if (!ackMsg.hasOwnProperty("msgData")) { - ackMsg.msgData = null; - } - if (successCallback) { - successCallback(ackMsg.msgType, ackMsg.msgData); - } - } - else { - if (errorCallback) { - errorCallback(ackMsg.msgData.errorCode, ackMsg.msgData.errorText); - } - else { - self.showError(ackMsg.msgData.errorCode, ackMsg.msgData.errorText); - } - } - } - ); - } - } - - - /** - *Sends data to another user using previously established data channel. This method will - * fail if no data channel has been established yet. Unlike the easyrtc.sendWS method, - * you can't send a dictionary, convert dictionaries to strings using JSON.stringify first. - * What data types you can send, and how large a data type depends on your browser. - * @param {String} destUser (an easyrtcid) - * @param {String} msgType - the type of message being sent (application specific). - * @param {Object} msgData - a JSONable object. - * @example - * easyrtc.sendDataP2P(someEasyrtcid, "roomData", {room:499, bldgNum:'asd'}); - */ - this.sendDataP2P = function(destUser, msgType, msgData) { - - var flattenedData = JSON.stringify({msgType: msgType, msgData: msgData}); - if (self.debugPrinter) { - self.debugPrinter("sending p2p message to " + destUser + " with data=" + JSON.stringify(flattenedData)); - } - - if (!peerConns[destUser]) { - self.showError(self.errCodes.DEVELOPER_ERR, "Attempt to send data peer to peer without a connection to " + destUser + ' first.'); - } - else if (!peerConns[destUser].dataChannelS) { - self.showError(self.errCodes.DEVELOPER_ERR, "Attempt to send data peer to peer without establishing a data channel to " + destUser + ' first.'); - } - else if (!peerConns[destUser].dataChannelReady) { - self.showError(self.errCodes.DEVELOPER_ERR, "Attempt to use data channel to " + destUser + " before it's ready to send."); - } - else { - try { - peerConns[destUser].dataChannelS.send(flattenedData); - } catch (oops) { - console.log("error=", oops); - throw oops; - } - } - }; - /** Sends data to another user using websockets. The easyrtc.sendServerMessage or easyrtc.sendPeerMessage methods - * are wrappers for this method; application code should use them instead. - * @param {String} destination - either a string containing the easyrtcId of the other user, or an object containing some subset of the following fields: targetEasyrtcid, targetGroup, targetRoom. - * Specifying multiple fields restricts the scope of the destination (operates as a logical AND, not a logical OR). - * @param {String} msgType -the type of message being sent (application specific). - * @param {Object} msgData - a JSONable object. - * @param {Function} ackhandler - by default, the ackhandler handles acknowledgments from the server that your message was delivered to it's destination. - * However, application logic in the server can over-ride this. If you leave this null, a stub ackHandler will be used. The ackHandler - * gets passed a message with the same msgType as your outgoing message, or a message type of "error" in which case - * msgData will contain a errorCode and errorText fields. - * @example - * easyrtc.sendDataWS(someEasyrtcid, "setPostalAddress", {room:499, bldgNum:'asd'}, - * function(ackMsg){ - * console.log("saw the following acknowledgment " + JSON.stringify(ackMsg)); - * } - * ); - */ - this.sendDataWS = function(destination, msgType, msgData, ackhandler) { - if (self.debugPrinter) { - self.debugPrinter("sending client message via websockets to " + destination + " with data=" + JSON.stringify(msgData)); - } - if (!ackhandler) { - ackhandler = function(msg) { - if (msg.msgType === "error") { - self.showError(msg.msgData.errorCode, msg.msgData.errorText); - } - }; - } - - var outgoingMessage = { - msgType: msgType, - msgData: msgData - }; - if (destination) { - if (typeof destination === 'string') { - outgoingMessage.targetEasyrtcid = destination; - } - else if (typeof destination === 'object') { - if (destination.targetEasyrtcid) { - outgoingMessage.targetEasyrtcid = destination.targetEasyrtcid; - } - if (destination.targetRoom) { - outgoingMessage.targetRoom = destination.targetRoom; - } - if (destination.targetGroup) { - outgoingMessage.targetGroup = destination.targetGroup; - } - } - } - - - if (self.webSocket) { - self.webSocket.json.emit("easyrtcMsg", outgoingMessage, ackhandler); - } - else { - if (self.debugPrinter) { - self.debugPrinter("websocket failed because no connection to server"); - } - throw "Attempt to send message without a valid connection to the server."; - } - }; - /** Sends data to another user. This method uses data channels if one has been set up, or websockets otherwise. - * @param {String} destUser - a string containing the easyrtcId of the other user. - * Specifying multiple fields restricts the scope of the destination (operates as a logical AND, not a logical OR). - * @param {String} msgType -the type of message being sent (application specific). - * @param {Object} msgData - a JSONable object. - * @param {Function} ackHandler - a function which receives acknowledgments. May only be invoked in - * the websocket case. - * @example - * easyrtc.sendData(someEasyrtcid, "roomData", {room:499, bldgNum:'asd'}, - * function ackHandler(msgType, msgData); - * ); - */ - this.sendData = function(destUser, msgType, msgData, ackHandler) { - if (peerConns[destUser] && peerConns[destUser].dataChannelReady) { - self.sendDataP2P(destUser, msgType, msgData); - } - else { - self.sendDataWS(destUser, msgType, msgData, ackHandler); - } - }; - /** - * Sends a message to another peer on the easyrtcMsg channel. - * @param {String} destination - either a string containing the easyrtcId of the other user, or an object containing some subset of the following fields: targetEasyrtcid, targetGroup, targetRoom. - * Specifying multiple fields restricts the scope of the destination (operates as a logical AND, not a logical OR). - * @param {String} msgType - the type of message being sent (application specific). - * @param {Object} msgData - a JSONable object with the message contents. - * @param {function(String, Object)} successCB - a callback function with results from the server. - * @param {function(String, String)} failureCB - a callback function to handle errors. - * @example - * easyrtc.sendPeerMessage(otherUser, 'offer_candy', {candy_name:'mars'}, - * function(msgType, msgBody ){ - * console.log("message was sent"); - * }, - * function(errorCode, errorText){ - * console.log("error was " + errorText); - * }); - */ - this.sendPeerMessage = function(destination, msgType, msgData, successCB, failureCB) { - if (!destination) { - console.error("Developer error, destination was null in sendPeerMessage"); - } - - if (self.debugPrinter) { - self.debugPrinter("sending peer message " + JSON.stringify(msgData)); - } - function ackHandler(response) { - if (response.msgType === "error") { - if (failureCB) { - failureCB(response.msgData.errorCode, response.msgData.errorText); - } - } - else { - if (successCB) { - // firefox complains if you pass an undefined as an parameter. - successCB(response.msgType, response.msgData ? response.msgData : null); - } - } - } - - self.sendDataWS(destination, msgType, msgData, ackHandler); - }; - /** - * Sends a message to the application code in the server (ie, on the easyrtcMsg channel). - * @param {String} msgType - the type of message being sent (application specific). - * @param {Object} msgData - a JSONable object with the message contents. - * @param {function(String, Object)} successCB - a callback function with results from the server. - * @param {function(String, String)} failureCB - a callback function to handle errors. - * @example - * easyrtc.sendServerMessage('get_candy', {candy_name:'mars'}, - * function(msgType, msgData ){ - * console.log("got candy count of " + msgData.barCount); - * }, - * function(errorCode, errorText){ - * console.log("error was " + errorText); - * }); - */ - this.sendServerMessage = function(msgType, msgData, successCB, failureCB) { - if (self.debugPrinter) { - var dataToShip = {msgType: msgType, msgData: msgData}; - self.debugPrinter("sending server message " + JSON.stringify(dataToShip)); - } - function ackhandler(response) { - if (response.msgType === "error") { - if (failureCB) { - failureCB(response.msgData.errorCode, response.msgData.errorText); - } - } - else { - if (successCB) { - successCB(response.msgType, response.msgData ? response.msgData : null); - } - } - } - - self.sendDataWS(null, msgType, msgData, ackhandler); - }; - /** Sends the server a request for the list of rooms the user can see. - * You must have already be connected to use this function. - * @param {function(Object)} callback - on success, this function is called with a map of the form { roomName:{"roomName":String, "numberClients": Number}}. - * The roomName appears as both the key to the map, and as the value of the "roomName" field. - * @param {function(String, String)} errorCallback is called on failure. It gets an errorCode and errorText as it's too arguments. - * @example - * easyrtc.getRoomList( - * function(roomList){ - * for(roomName in roomList){ - * console.log("saw room " + roomName); - * } - * }, - * function(errorCode, errorText){ - * easyrtc.showError(errorCode, errorText); - * } - * ); - */ - this.getRoomList = function(callback, errorCallback) { - sendSignalling(null, "getRoomList", null, - function(msgType, msgData) { - callback(msgData.roomList); - }, - function(errorCode, errorText) { - if (errorCallback) { - errorCallback(errorCode, errorText); - } - else { - self.showError(errorCode, errorText); - } - } - ); - }; - /** Value returned by easyrtc.getConnectStatus if the other user isn't connected to us. */ - this.NOT_CONNECTED = "not connected"; - /** Value returned by easyrtc.getConnectStatus if the other user is in the process of getting connected */ - this.BECOMING_CONNECTED = "connection in progress to us."; - /** Value returned by easyrtc.getConnectStatus if the other user is connected to us. */ - this.IS_CONNECTED = "is connected"; - /** - * Check if the client has a peer-2-peer connection to another user. - * The return values are text strings so you can use them in debugging output. - * @param {String} otherUser - the easyrtcid of the other user. - * @return {String} one of the following values: easyrtc.NOT_CONNECTED, easyrtc.BECOMING_CONNECTED, easyrtc.IS_CONNECTED - * @example - * if( easyrtc.getConnectStatus(otherEasyrtcid) == easyrtc.NOT_CONNECTED ){ - * easyrtc.call(otherEasyrtcid, - * function(){ console.log("success"); }, - * function(){ console.log("failure"); }); - * } - */ - this.getConnectStatus = function(otherUser) { - if (!peerConns.hasOwnProperty(otherUser)) { - return self.NOT_CONNECTED; - } - var peer = peerConns[otherUser]; - if ((peer.sharingAudio || peer.sharingVideo) && !peer.startedAV) { - return self.BECOMING_CONNECTED; - } - else if (peer.sharingData && !peer.dataChannelReady) { - return self.BECOMING_CONNECTED; - } - else { - return self.IS_CONNECTED; - } - }; - /** - * @private - */ - function buildPeerConstraints() { - var options = []; - options.push({'DtlsSrtpKeyAgreement': 'true'}); // for interoperability - return {optional: options}; - } - - - /** - * Initiates a call to another user. If it succeeds, the streamAcceptor callback will be called. - * @param {String} otherUser - the easyrtcid of the peer being called. - * @param {Function} callSuccessCB (otherCaller, mediaType) - is called when the datachannel is established or the MediaStream is established. mediaType will have a value of "audiovideo" or "datachannel" - * @param {Function} callFailureCB (errorCode, errMessage) - is called if there was a system error interfering with the call. - * @param {Function} wasAcceptedCB (wasAccepted:boolean,otherUser:string) - is called when a call is accepted or rejected by another party. It can be left null. - * @param {Array} streamNames - optional array of streamNames. - * @example - * easyrtc.call( otherEasyrtcid, - * function(easyrtcid, mediaType){ - * console.log("Got mediaType " + mediaType + " from " + easyrtc.idToName(easyrtcid)); - * }, - * function(errorCode, errMessage){ - * console.log("call to " + easyrtc.idToName(otherEasyrtcid) + " failed:" + errMessage); - * }, - * function(wasAccepted, easyrtcid){ - * if( wasAccepted ){ - * console.log("call accepted by " + easyrtc.idToName(easyrtcid)); - * } - * else{ - * console.log("call rejected" + easyrtc.idToName(easyrtcid)); - * } - * }); - */ - this.call = function(otherUser, callSuccessCB, callFailureCB, wasAcceptedCB, streamNames) { - - if (streamNames) { - if (typeof streamNames === "string") { // accept a string argument if passed. - streamNames = [streamNames]; - } - else if (streamNames.length === undefined) { - easyrtc.showError(self.errCodes.DEVELOPER_ERR, "easyrtc.call passed bad streamNames"); - return; - } - } - - if (self.debugPrinter) { - self.debugPrinter("initiating peer to peer call to " + otherUser + - " audio=" + audioEnabled + - " video=" + videoEnabled + - " data=" + dataEnabled); - } - - if (!self.supportsPeerConnections()) { - callFailureCB(self.errCodes.CALL_ERR, self.getConstantString("noWebrtcSupport")); - return; - } - - var message; - // - // If we are sharing audio/video and we haven't allocated the local media stream yet, - // we'll do so, recalling ourself on success. - // - if (!streamNames && autoInitUserMedia) { - var stream = self.getLocalStream(); - if (!stream && (audioEnabled || videoEnabled)) { - self.initMediaSource(function() { - self.call(otherUser, callSuccessCB, callFailureCB, wasAcceptedCB); - }, callFailureCB); - return; - } - } - - if (!self.webSocket) { - message = "Attempt to make a call prior to connecting to service"; - if (self.debugPrinter) { - self.debugPrinter(message); - } - throw message; - } - - // - // If B calls A, and then A calls B before accepting, then A should treat the attempt to - // call B as a positive offer to B's offer. - // - if (offersPending[otherUser]) { - wasAcceptedCB(true); - doAnswer(otherUser, offersPending[otherUser], streamNames); - delete offersPending[otherUser]; - self.callCancelled(otherUser, false); - return; - } - - // do we already have a pending call? - if (typeof acceptancePending[otherUser] !== 'undefined') { - message = "Call already pending acceptance"; - if (self.debugPrinter) { - self.debugPrinter(message); - } - callFailureCB(self.errCodes.ALREADY_CONNECTED, message); - return; - } - - if (use_fresh_ice_each_peer) { - self.getFreshIceConfig(function(succeeded) { - if (succeeded) { - callBody(otherUser, callSuccessCB, callFailureCB, wasAcceptedCB, streamNames); - } - else { - callFailureCB(self.errCodes.CALL_ERR, "Attempt to get fresh ice configuration failed"); - } - }); - } - else { - callBody(otherUser, callSuccessCB, callFailureCB, wasAcceptedCB, streamNames); - } - }; - function callBody(otherUser, callSuccessCB, callFailureCB, wasAcceptedCB, streamNames) { - acceptancePending[otherUser] = true; - var pc = buildPeerConnection(otherUser, true, callFailureCB, streamNames); - if (!pc) { - message = "buildPeerConnection failed, call not completed"; - if (self.debugPrinter) { - self.debugPrinter(message); - } - throw message; - } - - peerConns[otherUser].callSuccessCB = callSuccessCB; - peerConns[otherUser].callFailureCB = callFailureCB; - peerConns[otherUser].wasAcceptedCB = wasAcceptedCB; - var peerConnObj = peerConns[otherUser]; - var setLocalAndSendMessage0 = function(sessionDescription) { - if (peerConnObj.cancelled) { - return; - } - var sendOffer = function() { - - sendSignalling(otherUser, "offer", sessionDescription, null, callFailureCB); - }; - if (sdpLocalFilter) { - sessionDescription.sdp = sdpLocalFilter(sessionDescription.sdp); - } - pc.setLocalDescription(sessionDescription, sendOffer, - function(errorText) { - callFailureCB(self.errCodes.CALL_ERR, errorText); - }); - }; - setTimeout(function() { - // - // if the call was cancelled, we don't want to continue getting the offer. - // we can tell the call was cancelled because there won't be a peerConn object - // for it. - // - if( !peerConns[otherUser]) { - return; - } - pc.createOffer(setLocalAndSendMessage0, function(errorObj) { - callFailureCB(self.errCodes.CALL_ERR, JSON.stringify(errorObj)); - }, - receivedMediaContraints); - }, 100); - } - ; - function hangupBody(otherUser) { - var i; - if (self.debugPrinter) { - self.debugPrinter("Hanging up on " + otherUser); - } - clearQueuedMessages(otherUser); - if (peerConns[otherUser]) { - if (peerConns[otherUser].pc) { - var remoteStreams = peerConns[otherUser].pc.getRemoteStreams(); - for (i = 0; i < remoteStreams.length; i++) { - if( !remoteStreams[i].ended ) { - emitOnStreamClosed(otherUser, remoteStreams[i]); - try { - remoteStreams[i].close(); - } catch (err) { - } - } - } - // - // todo: may need to add a few lines here for closing the data channels - // - try { - peerConns[otherUser].pc.close(); - } catch (err) { - } - } - - peerConns[otherUser].cancelled = true; - delete peerConns[otherUser]; - if (self.webSocket) { - sendSignalling(otherUser, "hangup", null, function() { - }, function(errorCode, errorText) { - if (self.debugPrinter) { - self.debugPrinter("hangup failed:" + errorText); - } - }); - } - if (acceptancePending[otherUser]) { - delete acceptancePending[otherUser]; - } - } - } - - /** - * Hang up on a particular user or all users. - * @param {String} otherUser - the easyrtcid of the person to hang up on. - * @example - * easyrtc.hangup(someEasyrtcid); - */ - this.hangup = function(otherUser) { - hangupBody(otherUser); - updateConfigurationInfo(); - }; - /** - * Hangs up on all current connections. - * @example - * easyrtc.hangupAll(); - */ - this.hangupAll = function() { - - var sawAConnection = false, - onHangupSuccess = function() { - }, - onHangupFailure = function(errorCode, errorText) { - if (self.debugPrinter) { - self.debugPrinter("hangup failed:" + errorText); - } - }; - for (var otherUser in peerConns) { - if (!peerConns.hasOwnProperty(otherUser)) { - continue; - } - sawAConnection = true; - hangupBody(otherUser); - } - - if (sawAConnection) { - updateConfigurationInfo(); - } - }; - /** Checks to see if data channels work between two peers. - * @param {String} otherUser - the other peer. - * @returns {Boolean} true if data channels work and are ready to be used - * between the two peers. - */ - this.doesDataChannelWork = function(otherUser) { - if (!peerConns[otherUser]) { - return false; - } - return !!peerConns[otherUser].dataChannelReady; - }; - /** - * Return the media stream shared by a particular peer. This is needed when you - * add a stream in the middle of a call. - * @param {String} easyrtcid the peer. - * @param {String} remotestreamName an optional argument supplying the streamName. - * @returns {Object} A mediaStream. - */ - this.getRemoteStream = function(easyrtcid, remotestreamName) { - if (!peerConns[easyrtcid]) { - self.showError(self.errCodes.DEVELOPER_ERR, "attempt to get stream of uncalled party"); - throw "Developer err: no such stream"; - } - else { - return peerConns[easyrtcid].getRemoteStreamByName(remotestreamName); - } - } - /** - * Assign a local streamName to a remote stream so that it can be forwarded to other callers. - * @param {String} easyrtcid the peer supplying the remote stream - * @param {String} remotestreamName the streamName supplied by the peer. - * @param {String} localstreamName streamName used when passing the stream to other peers. - * @example - * easyrtc.makeLocalStreamFromRemoteStream(sourcePeer, "default", "forwardedStream"); - * easyrtc.call(nextPeer, callSuccessCB, callFailureCB, wasAcceptedCB, ["forwardedStream"]); - */ - this.makeLocalStreamFromRemoteStream = function(easyrtcid, remotestreamName, localstreamName) { - if (!streamName) { - streamName = "default"; - } - var remoteStream; - if (peerConns[easyrtcid].pc) { - remoteStream = peerConns[easyrtcid].getRemoteStreamByName(remotestreamName); - if (remoteStream) { - registerLocalMediaStreamByName(remoteStream, localstreamName); - } - else { - throw "Developer err: no such stream"; - } - } - else { - throw "Developer err: no such peer "; - } - } - - /** - * Add a named local stream to a call. - * @param {String} easyrtcId The id of client receiving the stream. - * @param {String} streamName The name of the stream. - * @param {Function} receiptHandler is a function that gets called when the other side sends a message - * that the stream has been received. The receiptHandler gets called with an easyrtcid and a stream name. This - * argument is optional. - */ - this.addStreamToCall = function(easyrtcId, streamName, receiptHandler) { - if( !streamName) { - streamName = "default"; - } - var stream = getLocalMediaStreamByName(streamName); - if (!stream) { - console.log("attempt to add nonexistent stream " + streamName); - } - else if (!peerConns[easyrtcId] || !peerConns[easyrtcId].pc) { - console.log("Can't add stream before a call has started."); - } - else { - var pc = peerConns[easyrtcId].pc; - peerConns[easyrtcId].enableNegotiateListener = true; - pc.addStream(stream); - if( receiptHandler ) { - peerConns[easyrtcId].streamsAddedAcks[streamName] = receiptHandler; - } - } - } - - // - // these three listeners support the ability to add/remove additional mediastreams on the fly. - // - this.setPeerListener(function(easyrtcid, msgType, msgData) { - if (!peerConns[easyrtcid] || !peerConns[easyrtcid].pc) { - easyrtc.showError(self.errCodes.DEVELOPER_ERR, - "Attempt to add additional stream before establishing the base call."); - } - else { - var sdp = msgData.sdp; - var pc = peerConns[easyrtcid].pc; - - var setLocalAndSendMessage1 = function(sessionDescription) { - var sendAnswer = function() { - if (self.debugPrinter) { - self.debugPrinter("sending answer"); - } - function onSignalSuccess() { - } - - function onSignalFailure(errorCode, errorText) { - delete peerConns[easyrtcid]; - self.showError(errorCode, errorText); - } - - sendSignalling(easyrtcid, "answer", sessionDescription, - onSignalSuccess, onSignalFailure); - peerConns[easyrtcid].connectionAccepted = true; - sendQueuedCandidates(easyrtcid, onSignalSuccess, onSignalFailure); - }; - - if (sdpLocalFilter) { - sessionDescription.sdp = sdpLocalFilter(sessionDescription.sdp); - } - pc.setLocalDescription(sessionDescription, sendAnswer, function(message) { - self.showError(self.errCodes.INTERNAL_ERR, "setLocalDescription: " + msgData); - }); - }; - - var invokeCreateAnswer = function() { - pc.createAnswer(setLocalAndSendMessage1, - function(message) { - self.showError(self.errCodes.INTERNAL_ERR, "create-answer: " + message); - }, - receivedMediaContraints); - self.sendPeerMessage(easyrtcid, "__gotAddedMediaStream", {sdp: sdp}); - }; - - if (self.debugPrinter) { - self.debugPrinter("about to call setRemoteDescription in doAnswer"); - } - try { - - if (sdpRemoteFilter) { - sdp.sdp = sdpRemoteFilter(sdp.sdp); - } - pc.setRemoteDescription(new RTCSessionDescription(sdp), - invokeCreateAnswer, function(message) { - self.showError(self.errCodes.INTERNAL_ERR, "set-remote-description: " + message); - }); - } catch (srdError) { - console.log("set remote description failed"); - if (self.debugPrinter) { - self.debugPrinter("saw exception in setRemoteDescription"); - } - self.showError(self.errCodes.INTERNAL_ERR, "setRemoteDescription failed: " + srdError.message); - } - } - }, "__addedMediaStream"); - this.setPeerListener(function(easyrtcid, msgType, msgData) { - if (!peerConns[easyrtcid] || !peerConns[easyrtcid].pc) { - } - else { - var sdp = msgData.sdp; - if (sdpRemoteFilter) { - sdp.sdp = sdpRemoteFilter(sdp.sdp); - } - var pc = peerConns[easyrtcid].pc; - pc.setRemoteDescription(new RTCSessionDescription(sdp), function(){}, - function(message) { - self.showError(self.errCodes.INTERNAL_ERR, "set-remote-description: " + message); - }); - } - - }, "__gotAddedMediaStream"); - this.setPeerListener(function(easyrtcid, msgType, msgData) { - if (!peerConns[easyrtcid] || !peerConns[easyrtcid].pc) { - } - else { - var stream = peerConns[easyrtcid].getRemoteStreamByName(msgData.streamName); - if (stream) { - onRemoveStreamHelper(easyrtcid, stream, msgData.streamName); - stream.ended = true; - } - } - - }, "__closingMediaStream"); - function onRemoveStreamHelper(easyrtcid, stream) { - if (peerConns[easyrtcid]) { - emitOnStreamClosed(easyrtcid, stream); - updateConfigurationInfo(); - if( peerConns[easyrtcid].pc ) { - try { - peerConns[easyrtcid].pc.removeStream(stream); - } catch( err) {} - } - - } - } - - - this.dumpPeerConnectionInfo = function() { - for (var peer in peerConns) { - console.log("For peer " + peer); - var pc = peerConns[peer].pc; - var remotes = pc.getRemoteStreams(); - var remoteIds = []; - for (var i = 0; i < remotes.length; i++) { - remoteIds.push(remotes[i].id); - } - var locals = pc.getLocalStreams(); - var localIds = []; - for (var i = 0; i < locals.length; i++) { - localIds.push(locals[i].id); - } - console.log(" " + JSON.stringify({local: localIds, remote: remoteIds})); - } - } - - - var buildPeerConnection = function(otherUser, isInitiator, failureCB, streamNames) { - var pc; - var message; - var newPeerConn; - var iceConfig = pc_config_to_use ? pc_config_to_use : pc_config; - if (self.debugPrinter) { - self.debugPrinter("building peer connection to " + otherUser); - } - - // - // we don't support data channels on chrome versions < 31 - // - try { - pc = self.createRTCPeerConnection(iceConfig, buildPeerConstraints()); - if (!pc) { - message = "Unable to create PeerConnection object, check your ice configuration(" + - JSON.stringify(ice_config) + ")"; - if (self.debugPrinter) { - self.debugPrinter(message); - } - throw(message); - } - - // - // turn off data channel support if the browser doesn't support it. - // - if (dataEnabled && typeof pc.createDataChannel === 'undefined') { - dataEnabled = false; - } - pc.onnegotiationneeded = function(event) { - if( peerConns[otherUser].enableNegotiateListener ) { - pc.createOffer(function(sdp) { - if (sdpLocalFilter) { - sdp.sdp = sdpLocalFilter(sdp.sdp); - } - pc.setLocalDescription(sdp, function() { - self.sendPeerMessage(otherUser, "__addedMediaStream", {sdp: sdp}); - }, function() { - }); - }, function(errorObj) { - console.log("unexpected error in creating offer"); - }); - } - } - - pc.onconnection = function() { - if (self.debugPrinter) { - self.debugPrinter("onconnection called prematurely"); - } - }; - newPeerConn = { - pc: pc, - candidatesToSend: [], - startedAV: false, - connectionAccepted: false, - isInitiator: isInitiator, - remoteStreamIdToName: {}, - streamsAddedAcks: {}, - liveRemoteStreams: {}, - getRemoteStreamByName: function(streamName) { - var remoteStreams = pc.getRemoteStreams(); - var i = 0; - var keyToMatch = null; - var roomName; - if (!streamName) { - streamName = "default"; - } - - if (streamName === "default") { - if (remoteStreams.length > 0) { - return remoteStreams[0]; - } - else { - return null; - } - } - for (roomName in self.roomData) { - var mediaIds = self.getRoomApiField(roomName, otherUser, "mediaIds"); - keyToMatch = mediaIds ? mediaIds[streamName] : null; - if (keyToMatch) { - break; - } - } - if (!keyToMatch) { - self.showError(self.errCodes.DEVELOPER_ERR, "remote peer does not have media stream called " + streamName); - } - - for (i = 0; i < remoteStreams.length; i++) { - var remoteId; - if (remoteStreams[i].hasOwnProperty("id")) { - remoteId = remoteStreams[i].id; - } - else { - remoteId = "default"; - } - - if (!keyToMatch || remoteId === keyToMatch) { - return remoteStreams[i]; - } - - } - return null; - } - // var remoteStreams = peerConns[i].pc.getRemoteStreams(); - }; - pc.onicecandidate = function(event) { - if (newPeerConn.cancelled) { - return; - } - var candidateData; - if (event.candidate && peerConns[otherUser]) { - candidateData = { - type: 'candidate', - label: event.candidate.sdpMLineIndex, - id: event.candidate.sdpMid, - candidate: event.candidate.candidate - }; - - if( iceCandidateFilter ) { - candidateData = iceCandidateFilter(candidateData, false); - if( !candidateData ) { - return; - } - } - // - // some candidates include ip addresses of turn servers. we'll want those - // later so we can see if our actual connection uses a turn server. - // The keyword "relay" in the candidate identifies it as referencing a - // turn server. The \d symbol in the regular expression matches a number. - // - if (event.candidate.candidate.indexOf("typ relay") > 0) { - var ipAddress = event.candidate.candidate.match(/(udp|tcp) \d+ (\d+\.\d+\.\d+\.\d+)/i)[2]; - self._turnServers[ipAddress] = true; - } - - if (peerConns[otherUser].connectionAccepted) { - sendSignalling(otherUser, "candidate", candidateData, null, function() { - failureCB(self.errCodes.PEER_GONE, "Candidate disappeared"); - }); - } - else { - peerConns[otherUser].candidatesToSend.push(candidateData); - } - } - }; - pc.onaddstream = function(event) { - if (self.debugPrinter) { - self.debugPrinter("saw incoming media stream"); - } - if (newPeerConn.cancelled) - return; - if (!peerConns[otherUser].startedAV) { - peerConns[otherUser].startedAV = true; - peerConns[otherUser].sharingAudio = haveAudioVideo.audio; - peerConns[otherUser].sharingVideo = haveAudioVideo.video; - peerConns[otherUser].connectTime = new Date().getTime(); - if (peerConns[otherUser].callSuccessCB) { - if (peerConns[otherUser].sharingAudio || peerConns[otherUser].sharingVideo) { - peerConns[otherUser].callSuccessCB(otherUser, "audiovideo"); - } - } - if (audioEnabled || videoEnabled) { - updateConfiguration(); - } - } - var remoteName = getNameOfRemoteStream(otherUser, event.stream.id || "default"); - if (!remoteName) { - remoteName = "default"; - } - peerConns[otherUser].remoteStreamIdToName[event.stream.id || "default"] = remoteName; - peerConns[otherUser].liveRemoteStreams[remoteName] = true; - event.stream.streamName = remoteName; - if (self.streamAcceptor) { - self.streamAcceptor(otherUser, event.stream, remoteName); - // - // Inform the other user that the stream they provided has been received. - // This should be moved into signalling at some point - // - self.sendDataWS(otherUser, "easyrtc_streamReceived", {streamName:remoteName},function(){}); - } - }; - pc.onremovestream = function(event) { - if (self.debugPrinter) { - self.debugPrinter("saw remove on remote media stream"); - } - onRemoveStreamHelper(otherUser, event.stream, event.stream.id || "default"); - }; - peerConns[otherUser] = newPeerConn; - } catch (e) { - if (self.debugPrinter) { - self.debugPrinter(JSON.stringify(e)); - } - failureCB(self.errCodes.SYSTEM_ERR, e.message); - return null; - } - - var i, stream; - if (streamNames) { - for (i = 0; i < streamNames.length; i++) { - stream = getLocalMediaStreamByName(streamNames[i]); - if (stream) { - pc.addStream(stream); - } - else { - console.log("Developer error, attempt to access unknown local media stream " + streamNames[i]); - } - } - } - else if (autoInitUserMedia && (videoEnabled || audioEnabled)) { - stream = self.getLocalStream(); - pc.addStream(stream); - } - - // - // This function handles data channel message events. - // - function dataChannelMessageHandler(event) { - if (self.debugPrinter) { - self.debugPrinter("saw dataChannel.onmessage event: " + JSON.stringify(event.data)); - } - - if (event.data === "dataChannelPrimed") { - self.sendDataWS(otherUser, "dataChannelPrimed", ""); - } - else { - // - // Chrome and Firefox Interop is passing a event with a strange data="", perhaps - // as it's own form of priming message. Comparing the data against "" doesn't - // work, so I'm going with parsing and trapping the parse error. - // - try { - var msg = JSON.parse(event.data); - if (msg) { - self.receivePeerDistribute(otherUser, msg, null); - } - } - catch (err) { - } - } - } - - function initOutGoingChannel(otherUser) { - if (self.debugPrinter) { - self.debugPrinter("saw initOutgoingChannel call"); - } - var dataChannel = pc.createDataChannel(dataChannelName, self.getDatachannelConstraints()); - peerConns[otherUser].dataChannelS = dataChannel; - peerConns[otherUser].dataChannelR = dataChannel; - dataChannel.onmessage = dataChannelMessageHandler; - dataChannel.onopen = function(event) { - if (self.debugPrinter) { - self.debugPrinter("saw dataChannel.onopen event"); - } - if (peerConns[otherUser]) { - dataChannel.send("dataChannelPrimed"); - } - }; - dataChannel.onclose = function(event) { - if (self.debugPrinter) { - self.debugPrinter("saw dataChannelS.onclose event"); - } - if (peerConns[otherUser]) { - peerConns[otherUser].dataChannelReady = false; - delete peerConns[otherUser].dataChannelS; - } - if (onDataChannelClose) { - onDataChannelClose(otherUser); - } - - updateConfigurationInfo(); - }; - } - - function initIncomingChannel(otherUser) { - if (self.debugPrinter) { - self.debugPrinter("initializing incoming channel handler for " + otherUser); - } - - peerConns[otherUser].pc.ondatachannel = function(event) { - - if (self.debugPrinter) { - self.debugPrinter("saw incoming data channel"); - } - - var dataChannel = event.channel; - peerConns[otherUser].dataChannelR = dataChannel; - peerConns[otherUser].dataChannelS = dataChannel; - peerConns[otherUser].dataChannelReady = true; - dataChannel.onmessage = dataChannelMessageHandler; - dataChannel.onclose = function(event) { - if (self.debugPrinter) { - self.debugPrinter("saw dataChannelR.onclose event"); - } - if (peerConns[otherUser]) { - peerConns[otherUser].dataChannelReady = false; - delete peerConns[otherUser].dataChannelR; - } - if (onDataChannelClose) { - onDataChannelClose(otherUser); - } - - updateConfigurationInfo(); - }; - dataChannel.onopen = function(event) { - if (self.debugPrinter) { - self.debugPrinter("saw dataChannel.onopen event"); - } - if (peerConns[otherUser]) { - dataChannel.send("dataChannelPrimed"); - } - }; - }; - } - - // - // added for interoperability - // - var doDataChannels = dataEnabled; - if (doDataChannels) { - - // check if both sides have the same browser and versions - } - - if (doDataChannels) { - self.setPeerListener(function() { - peerConns[otherUser].dataChannelReady = true; - if (peerConns[otherUser].callSuccessCB) { - peerConns[otherUser].callSuccessCB(otherUser, "datachannel"); - } - if (onDataChannelOpen) { - onDataChannelOpen(otherUser, true); - } - updateConfigurationInfo(); - }, "dataChannelPrimed", otherUser); - if (isInitiator) { - try { - - initOutGoingChannel(otherUser); - } catch (channelErrorEvent) { - console.log("failed to init outgoing channel"); - failureCB(self.errCodes.SYSTEM_ERR, - self.formatError(channelErrorEvent)); - } - } - if (!isInitiator) { - initIncomingChannel(otherUser); - } - } - - pc.onconnection = function() { - if (self.debugPrinter) { - self.debugPrinter("setup pc.onconnection "); - } - }; - - // - // Temporary support for responding to acknowledgements of about streams being added. - // - self.setPeerListener(function(easyrtcid, msgType, msgData, targeting){ - if( newPeerConn.streamsAddedAcks[msgData.streamName]) { - (newPeerConn.streamsAddedAcks[msgData.streamName])(easyrtcid, msgData.streamName); - delete newPeerConn.streamsAddedAcks[msgData.streamName]; - } - }, "easyrtc_streamReceived", otherUser); - return pc; - }; - var doAnswer = function(caller, msgData, streamNames) { - if (!streamNames && autoInitUserMedia) { - var localStream = self.getLocalStream(); - if (!localStream && (videoEnabled || audioEnabled)) { - self.initMediaSource( - function() { - doAnswer(caller, msgData); - }, - function(errorCode, errorObj) { - self.showError(self.errCodes.MEDIA_ERR, self.format(self.getConstantString("localMediaError"))); - }); - return; - } - } - if (use_fresh_ice_each_peer) { - self.getFreshIceConfig(function(succeeded) { - if (succeeded) { - doAnswerBody(caller, msgData, streamNames); - } - else { - self.showError(self.errCodes.CALL_ERR, "Failed to get fresh ice config"); - } - }); - } - else { - doAnswerBody(caller, msgData, streamNames); - } - } - - - var doAnswerBody = function(caller, msgData, streamNames) { - var pc = buildPeerConnection(caller, false, function(message) { - self.showError(self.errCodes.SYSTEM_ERR, message); - }, streamNames); - var newPeerConn = peerConns[caller]; - if (!pc) { - if (self.debugPrinter) { - self.debugPrinter("buildPeerConnection failed. Call not answered"); - } - return; - } - var setLocalAndSendMessage1 = function(sessionDescription) { - if (newPeerConn.cancelled) - return; - var sendAnswer = function() { - if (self.debugPrinter) { - self.debugPrinter("sending answer"); - } - function onSignalSuccess() { - } - - function onSignalFailure(errorCode, errorText) { - delete peerConns[caller]; - self.showError(errorCode, errorText); - } - - sendSignalling(caller, "answer", sessionDescription, - onSignalSuccess, onSignalFailure); - peerConns[caller].connectionAccepted = true; - sendQueuedCandidates(caller, onSignalSuccess, onSignalFailure); - if (pc.connectDataConnection) { - if (self.debugPrinter) { - self.debugPrinter("calling connectDataConnection(5002,5001)"); - } - pc.connectDataConnection(5002, 5001); - } - }; - if (sdpLocalFilter) { - sessionDescription.sdp = sdpLocalFilter(sessionDescription.sdp); - } - pc.setLocalDescription(sessionDescription, sendAnswer, function(message) { - self.showError(self.errCodes.INTERNAL_ERR, "setLocalDescription: " + message); - }); - }; - var sd = null; - if (window.mozRTCSessionDescription) { - sd = new mozRTCSessionDescription(msgData); - } - else { - sd = new RTCSessionDescription(msgData); - } - if (self.debugPrinter) { - self.debugPrinter("sdp || " + JSON.stringify(sd)); - } - var invokeCreateAnswer = function() { - if (newPeerConn.cancelled) - return; - pc.createAnswer(setLocalAndSendMessage1, - function(message) { - self.showError(self.errCodes.INTERNAL_ERR, "create-answer: " + message); - }, - receivedMediaContraints); - }; - if (self.debugPrinter) { - self.debugPrinter("about to call setRemoteDescription in doAnswer"); - } - try { - - if (sdpRemoteFilter) { - sd.sdp = sdpRemoteFilter(sd.sdp); - } - pc.setRemoteDescription(sd, invokeCreateAnswer, function(message) { - self.showError(self.errCodes.INTERNAL_ERR, "set-remote-description: " + message); - }); - } catch (srdError) { - console.log("set remote description failed"); - if (self.debugPrinter) { - self.debugPrinter("saw exception in setRemoteDescription"); - } - self.showError(self.errCodes.INTERNAL_ERR, "setRemoteDescription failed: " + srdError.message); - } - }; - // - // This function calls the users onStreamClosed handler, passing it the easyrtcid of the peer, the stream itself, - // and the name of the stream. - // - function emitOnStreamClosed(easyrtcid, stream) { - if (!peerConns[easyrtcid]) { - return; - } - var streamName; - var id; - if (stream.hasOwnProperty("id")) { - id = stream.id; - } - else { - id = "default"; - } - streamName = peerConns[easyrtcid].remoteStreamIdToName[id] || "default"; - if (peerConns[easyrtcid].liveRemoteStreams[streamName] && - self.onStreamClosed) { - delete peerConns[easyrtcid].liveRemoteStreams[streamName]; - self.onStreamClosed(easyrtcid, stream, streamName); - } - delete peerConns[easyrtcid].remoteStreamIdToName[id]; - } - - var onRemoteHangup = function(caller) { - delete offersPending[caller]; - if (self.debugPrinter) { - self.debugPrinter("Saw onRemote hangup event"); - } - if (peerConns[caller]) { - peerConns[caller].cancelled = true; - if (peerConns[caller].pc) { - // - // close any remote streams. - // - var remoteStreams = peerConns[caller].pc.getRemoteStreams(); - if (remoteStreams) { - var i; - for (i = 0; i < remoteStreams.length; i++) { - emitOnStreamClosed(caller, remoteStreams[i]); - try { - remoteStreams[i].stop(); - } catch (err) { - } - ; - } - } - - try { - peerConns[caller].pc.close(); - } catch (anyErrors) { - } - } - else { - if (self.callCancelled) { - self.callCancelled(caller, true); - } - } - delete peerConns[caller]; - updateConfigurationInfo(); - } - else { - if (self.callCancelled) { - self.callCancelled(caller, true); - } - } - }; - var queuedMessages = {}; - var clearQueuedMessages = function(caller) { - queuedMessages[caller] = { - candidates: [] - }; - }; - // - // checks to see if a particular peer is in any room at all. - // - function isPeerInAnyRoom(id) { - var roomName; - for (roomName in lastLoggedInList) { - if (!lastLoggedInList.hasOwnProperty(roomName)) { - continue; - } - if (lastLoggedInList[roomName][id]) { - return true; - } - } - return false; - } - - /** - * Checks to see if a particular peer is present in any room. - * If it isn't, we assume it's logged out. - * @param easyrtcid the easyrtcId of the peer. - */ - this.isPeerInAnyRoom = function(easyrtcId) { - return isPeerInAnyRoom(easyrtcId); - } - - // - // - // - function processLostPeers(peersInRoom) { - var id; - // - // check to see the person is still in at least one room. If not, we'll hangup - // on them. This isn't the correct behavior, but it's the best we can do without - // changes to the server. - // - for (id in peerConns) { - if (peerConns.hasOwnProperty(id) && - typeof peersInRoom[id] === 'undefined') { - if (!isPeerInAnyRoom(id)) { - if (peerConns[id].pc || peerConns[id].isInitiator) { - onRemoteHangup(id); - } - delete offersPending[id]; - delete acceptancePending[id]; - clearQueuedMessages(id); - } - } - } - - for (id in offersPending) { - if (offersPending.hasOwnProperty(id) && !isPeerInAnyRoom(id)) { - onRemoteHangup(id); - clearQueuedMessages(id); - delete offersPending[id]; - delete acceptancePending[id]; - } - } - - for (id in acceptancePending) { - if (acceptancePending.hasOwnProperty(id) && !isPeerInAnyRoom(id)) { - onRemoteHangup(id); - clearQueuedMessages(id); - delete acceptancePending[id]; - } - } - - } - - /** - * The idea of aggregating timers is that there are events that convey state and these can fire more frequently - * than desired. Aggregating timers allow a bunch of events to be collapsed into one by only firing the last - * event. - * @private - */ - var aggregatingTimers = {}; - - /** - * This function sets a timeout for a function to be called with the feature that if another - * invocation comes along within a particular interval (with the same key), the second invocation - * replaces the first. To prevent a continuous stream of events from preventing a callback from ever - * firing, we'll collapse no more than 20 events. - * @param {String} key A key used to identify callbacks that should be aggregated. - * @param {Function} callback The callback to invoke. - * @param {Number} period The aggregating period in milliseconds. - * @private - */ - function addAggregatingTimer(key, callback, period) { - if( !period) { - period = 100; // 0.1 second - } - var counter = 0; - if( aggregatingTimers[key]) { - clearTimeout(aggregatingTimers[key].timer); - counter = aggregatingTimers[key].counter; - } - if( counter > 20) { - delete aggregatingTimers[key]; - callback(); - } - else { - aggregatingTimers[key] = {counter: counter +1}; - aggregatingTimers[key].timer = setTimeout(function () { - delete aggregatingTimers[key]; - callback(); - }, period); - } - } - - // - // this function gets called for each room when there is a room update. - // - function processOccupantList(roomName, occupantList) { - var myInfo = null; - self.reducedList = {}; - var id; - for (id in occupantList) { - if (occupantList.hasOwnProperty(id)) { - if (id === self.myEasyrtcid) { - myInfo = occupantList[id]; - } - else { - self.reducedList[id] = occupantList[id]; - } - } - } - // - // processLostPeers detects peers that have gone away and performs - // house keeping accordingly. - // - processLostPeers(self.reducedList); - // - // - // - addAggregatingTimer("roomOccupants&" + roomName, function(){ - if (roomOccupantListener) { - roomOccupantListener(roomName, self.reducedList, myInfo); - } - self.emitEvent("roomOccupants", {roomName:roomName, occupants:lastLoggedInList}); - }, 100); - - } - - function sendQueuedCandidates(peer, onSignalSuccess, onSignalFailure) { - var i; - for (i = 0; i < peerConns[peer].candidatesToSend.length; i++) { - sendSignalling( - peer, - "candidate", - peerConns[peer].candidatesToSend[i], - onSignalSuccess, - onSignalFailure - ); - } - } - - var onChannelMsg = function(msg, ackAcceptorFunc) { - - var targeting = {}; - if (ackAcceptorFunc) { - ackAcceptorFunc(self.ackMessage); - } - if (msg.targetEasyrtcid) { - targeting.targetEasyrtcid = msg.targetEasyrtcid; - } - if (msg.targetRoom) { - targeting.targetRoom = msg.targetRoom; - } - if (msg.targetGroup) { - targeting.targetGroup = msg.targetGroup; - } - if (msg.senderEasyrtcid) { - self.receivePeerDistribute(msg.senderEasyrtcid, msg, targeting); - } - else { - if (receiveServerCB) { - receiveServerCB(msg.msgType, msg.msgData, targeting); - } - else { - console.log("Unhandled server message " + JSON.stringify(msg)); - } - } - }; - var onChannelCmd = function(msg, ackAcceptorFn) { - - var caller = msg.senderEasyrtcid; - var msgType = msg.msgType; - var msgData = msg.msgData; - var pc; - if (self.debugPrinter) { - self.debugPrinter('received message of type ' + msgType); - } - - if (typeof queuedMessages[caller] === "undefined") { - clearQueuedMessages(caller); - } - - var processCandidateBody = function(caller, msgData) { - var candidate = null; - - if( iceCandidateFilter ) { - msgData = iceCandidateFilter(msgData, true); - if( !msgData ) { - return; - } - } - - if (window.mozRTCIceCandidate) { - candidate = new mozRTCIceCandidate({ - sdpMLineIndex: msgData.label, - candidate: msgData.candidate - }); - } - else { - candidate = new RTCIceCandidate({ - sdpMLineIndex: msgData.label, - candidate: msgData.candidate - }); - } - pc = peerConns[caller].pc; - - function iceAddSuccess() {} - function iceAddFailure(domError) { - easyrtc.showError(self.errCodes.ICECANDIDATE_ERR, "bad ice candidate (" + domError.name + "): " + - JSON.stringify(candidate)); - } - pc.addIceCandidate(candidate, iceAddSuccess, iceAddFailure); - - if (msgData.candidate.indexOf("typ relay") > 0) { - var ipAddress = msgData.candidate.match(/(udp|tcp) \d+ (\d+\.\d+\.\d+\.\d+)/i)[1]; - self._turnServers[ipAddress] = true; - } - }; - var flushCachedCandidates = function(caller) { - var i; - if (queuedMessages[caller]) { - for (i = 0; i < queuedMessages[caller].candidates.length; i++) { - processCandidateBody(caller, queuedMessages[caller].candidates[i]); - } - delete queuedMessages[caller]; - } - }; - var processOffer = function(caller, msgData) { - - var helper = function(wasAccepted, streamNames) { - - if (streamNames) { - if (typeof streamNames === "string") { - streamNames = [streamNames]; - } - else if (streamNames.length === undefined) { - easyrtc.showError(self.errCodes.DEVELOPER_ERR, "accept callback passed invalid streamNames"); - return; - } - } - if (self.debugPrinter) { - self.debugPrinter("offer accept=" + wasAccepted); - } - delete offersPending[caller]; - if (!self.supportsPeerConnections()) { - callFailureCB(self.errCodes.CALL_ERR, self.getConstantString("noWebrtcSupport")); - return; - } - - if (wasAccepted) { - doAnswer(caller, msgData, streamNames); - flushCachedCandidates(caller); - } - else { - sendSignalling(caller, "reject", null, null, null); - clearQueuedMessages(caller); - } - }; - // - // There is a very rare case of two callers sending each other offers - // before receiving the others offer. In such a case, the caller with the - // greater valued easyrtcid will delete its pending call information and do a - // simple answer to the other caller's offer. - // - if (acceptancePending[caller] && caller < self.myEasyrtcid) { - delete acceptancePending[caller]; - if (queuedMessages[caller]) { - delete queuedMessages[caller]; - } - if (peerConns[caller].wasAcceptedCB) { - peerConns[caller].wasAcceptedCB(true, caller); - } - delete peerConns[caller]; - helper(true); - return; - } - - offersPending[caller] = msgData; - if (!self.acceptCheck) { - helper(true); - } - else { - self.acceptCheck(caller, helper); - } - }; - function processReject(caller) { - delete acceptancePending[caller]; - if (queuedMessages[caller]) { - delete queuedMessages[caller]; - } - if (peerConns[caller]) { - if (peerConns[caller].wasAcceptedCB) { - peerConns[caller].wasAcceptedCB(false, caller); - } - delete peerConns[caller]; - } - } - - function processAnswer(caller, msgData) { - - - - delete acceptancePending[caller]; - - // - // if we've discarded the peer connection, ignore the answer. - // - if (!peerConns[caller]) { - return; - } - peerConns[caller].connectionAccepted = true; - - - - if (peerConns[caller].wasAcceptedCB) { - peerConns[caller].wasAcceptedCB(true, caller); - } - - var onSignalSuccess = function() { - - }; - var onSignalFailure = function(errorCode, errorText) { - if (peerConns[caller]) { - delete peerConns[caller]; - } - self.showError(errorCode, errorText); - }; - var i; - // peerConns[caller].startedAV = true; - sendQueuedCandidates(caller, onSignalSuccess, onSignalFailure); - pc = peerConns[caller].pc; - var sd = null; - if (window.mozRTCSessionDescription) { - sd = new mozRTCSessionDescription(msgData); - } - else { - sd = new RTCSessionDescription(msgData); - } - if (!sd) { - throw "Could not create the RTCSessionDescription"; - } - - if (self.debugPrinter) { - self.debugPrinter("about to call initiating setRemoteDescription"); - } - try { - if (sdpRemoteFilter) { - sd.sdp = sdpRemoteFilter(sd.sdp); - } - pc.setRemoteDescription(sd, function() { - if (pc.connectDataConnection) { - if (self.debugPrinter) { - self.debugPrinter("calling connectDataConnection(5001,5002)"); - } - pc.connectDataConnection(5001, 5002); // these are like ids for data channels - } - }, function(message){ - console.log("setRemoteDescription failed ", message); - }); - } catch (smdException) { - console.log("setRemoteDescription failed ", smdException); - } - flushCachedCandidates(caller); - } - - function processCandidateQueue(caller, msgData) { - - if (peerConns[caller] && peerConns[caller].pc) { - processCandidateBody(caller, msgData); - } - else { - if (!peerConns[caller]) { - queuedMessages[caller] = { - candidates: [] - }; - } - queuedMessages[caller].candidates.push(msgData); - } - } - - switch (msgType) { - case "sessionData": - processSessionData(msgData.sessionData); - break; - case "roomData": - processRoomData(msgData.roomData); - break; - case "iceConfig": - processIceConfig(msgData.iceConfig); - break; - case "forwardToUrl": - if (msgData.newWindow) { - window.open(msgData.forwardToUrl.url); - } - else { - window.location.href = msgData.forwardToUrl.url; - } - break; - case "offer": - processOffer(caller, msgData); - break; - case "reject": - processReject(caller); - break; - case "answer": - processAnswer(caller, msgData); - break; - case "candidate": - processCandidateQueue(caller, msgData); - break; - case "hangup": - onRemoteHangup(caller); - clearQueuedMessages(caller); - break; - case "error": - self.showError(msg.errorCode, msg.errorText); - break; - default: - console.error("received unknown message type from server, msgType is " + msgType); - return; - } - - if (ackAcceptorFn) { - ackAcceptorFn(self.ackMessage); - } - }; - function connectToWSServer(successCallback, errorCallback) { - var i; - if (preallocatedSocketIo) { - self.webSocket = preallocatedSocketIo; - } - else if (!self.webSocket) { - try { - self.webSocket = io.connect(serverPath, connectionOptions); - } catch(socketErr) { - errorCallback( self.errCodes.SYSTEM_ERROR, - socketError.toString()); - return; - } - if (!self.webSocket) { - throw "io.connect failed"; - } - } - else { - for (i in self.websocketListeners) { - if (!self.websocketListeners.hasOwnProperty(i)) { - continue; - } - self.webSocket.removeEventListener(self.websocketListeners[i].event, - self.websocketListeners[i].handler); - } - } - self.websocketListeners = []; - function addSocketListener(event, handler) { - self.webSocket.on(event, handler); - self.websocketListeners.push({event: event, handler: handler}); - } - - addSocketListener("close", function(event) { - console.log("the web socket closed"); - }); - addSocketListener('error', function(event) { - function handleErrorEvent() { - if (self.myEasyrtcid) { - // - // socket.io version 1 got rid of the socket member, moving everything up one level. - // - if (self.webSocket.connected || (self.webSocket.socket && self.webSocket.socket.connected)) { - self.showError(self.errCodes.SIGNAL_ERROR, self.getConstantString("miscSignalError")); - } - else { - /* socket server went down. this will generate a 'disconnect' event as well, so skip this event */ - errorCallback(self.errCodes.CONNECT_ERR, self.getConstantString("noServer")); - } - } - else { - errorCallback(self.errCodes.CONNECT_ERR, self.getConstantString("noServer")); - } - } - handleErrorEvent(); - }); - function connectHandler(event) { - self.webSocketConnected = true; - if (!self.webSocket) { - self.showError(self.errCodes.CONNECT_ERR, self.getConstantString("badsocket")); - } - - if (self.debugPrinter) { - self.debugPrinter("saw socketserver onconnect event"); - } - if (self.webSocketConnected) { - sendAuthenticate(successCallback, errorCallback); - } - else { - errorCallback(self.errCodes.SIGNAL_ERROR, self.getConstantString("icf")); - } - } - if (preallocatedSocketIo && preallocatedSocketIo.socket.connected) { - connectHandler(null); - } - else { - addSocketListener("connect", connectHandler); - } - addSocketListener("easyrtcMsg", onChannelMsg); - addSocketListener("easyrtcCmd", onChannelCmd); - addSocketListener("disconnect", function(/* code, reason, wasClean */) { - self.webSocketConnected = false; - updateConfigurationInfo = function() { - }; // dummy update function - oldConfig = {}; - disconnectBody(); - if (self.disconnectListener) { - self.disconnectListener(); - } - }); - } - - - function buildDeltaRecord(added, deleted, modified) { - function objectNotEmpty(obj) { - var i; - for (i in obj) { - if (obj.hasOwnProperty(i)) { - return true; - } - } - return false; - } - - var result = {}; - if (objectNotEmpty(added)) { - result.added = added; - } - - if (objectNotEmpty(deleted)) { - result.deleted = deleted; - } - - if (objectNotEmpty(result)) { - return result; - } - else { - return null; - } - } - - function findDeltas(oldVersion, newVersion) { - var i; - var added = {}, deleted = {}; - var subPart; - for (i in newVersion) { - if (!newVersion.hasOwnProperty(i)) { - // do nothing - } - else if (oldVersion === null || typeof oldVersion[i] === 'undefined') { - added[i] = newVersion[i]; - } - else if (typeof newVersion[i] === 'object') { - subPart = findDeltas(oldVersion[i], newVersion[i]); - if (subPart !== null) { - added[i] = newVersion[i]; - } - } - else if (newVersion[i] !== oldVersion[i]) { - added[i] = newVersion[i]; - } - } - for (i in oldVersion) { - if (!newVersion.hasOwnProperty(i)) { - // do nothing - } - else if (typeof newVersion[i] === 'undefined') { - deleted = oldVersion[i]; - } - } - - return buildDeltaRecord(added, deleted); - } - -// -// this function collects configuration info that will be sent to the server. -// It returns that information, leaving it the responsibility of the caller to -// do the actual sending. -// - function collectConfigurationInfo(/* forAuthentication */) { - var p2pList = {}; - var i; - for (i in peerConns) { - if (!peerConns.hasOwnProperty(i)) { - continue; - } - p2pList[i] = { - connectTime: peerConns[i].connectTime, - isInitiator: !!peerConns[i].isInitiator - }; - } - - var newConfig = { - userSettings: { - sharingAudio: !!haveAudioVideo.audio, - sharingVideo: !!haveAudioVideo.video, - sharingData: !!dataEnabled, - nativeVideoWidth: self.nativeVideoWidth, - nativeVideoHeight: self.nativeVideoHeight, - windowWidth: window.innerWidth, - windowHeight: window.innerHeight, - screenWidth: window.screen.width, - screenHeight: window.screen.height, - cookieEnabled: navigator.cookieEnabled, - os: navigator.oscpu, - language: navigator.language - } - }; - if (!isEmptyObj(p2pList)) { - newConfig.p2pList = p2pList; - } - return newConfig; - } - ; - function updateConfiguration() { - - var newConfig = collectConfigurationInfo(false); - // - // we need to give the getStats calls a chance to fish out the data. - // The longest I've seen it take is 5 milliseconds so 100 should be overkill. - // - var sendDeltas = function() { - var alteredData = findDeltas(oldConfig, newConfig); - // - // send all the configuration information that changes during the session - // - if (alteredData) { - if (self.debugPrinter) { - self.debugPrinter("cfg=" + JSON.stringify(alteredData.added)); - } - if (self.webSocket) { - sendSignalling(null, "setUserCfg", {setUserCfg: alteredData.added}, null, null); - } - } - oldConfig = newConfig; - }; - if (oldConfig === {}) { - sendDeltas(); - } - else { - setTimeout(sendDeltas, 100); - } - } - - updateConfigurationInfo = function() { - updateConfiguration(); - }; - /** - * Sets the presence state on the server. - * @param {String} state - one of 'away','chat','dnd','xa' - * @param {String} statusText - User configurable status string. May be length limited. - * @example easyrtc.updatePresence('dnd', 'sleeping'); - */ - this.updatePresence = function(state, statusText) { - self.presenceShow = state; - self.presenceStatus = statusText; - if (self.webSocketConnected) { - sendSignalling(null, 'setPresence', {setPresence: {'show': state, 'status': statusText}}, null); - } - }; - /** - * Fetch the collection of session fields as a map. The map has the structure: - * {key1: {"fieldName": key1, "fieldValue": value1}, ..., - * key2: {"fieldName": key2, "fieldValue": value2} - * } - * @returns {Object} - */ - this.getSessionFields = function() { - return sessionFields; - }; - /** - * Fetch the value of a session field by name. - * @param {String} name - name of the session field to be fetched. - * @returns the field value (which can be anything). Returns undefined if the field does not exist. - */ - this.getSessionField = function(name) { - if (sessionFields[name]) { - return sessionFields[name].fieldValue; - } - else { - return undefined; - } - }; - function processSessionData(sessionData) { - if (sessionData) { - if (sessionData.easyrtcsid) { - self.easyrtcsid = sessionData.easyrtcsid; - } - if (sessionData.field) { - sessionFields = sessionData.field; - } - } - } - - - function processRoomData(roomData) { - self.roomData = roomData; - var roomName; - var stuffToRemove; - var stuffToAdd; - var id, removeId; - for (roomName in self.roomData) { - if (!self.roomData.hasOwnProperty(roomName)) { - continue; - } - if (roomData[roomName].roomStatus === "join") { - if (!(self.roomJoin[roomName])) { - self.roomJoin[roomName] = roomData[roomName]; - } - var mediaIds = buildMediaIds(); - if (mediaIds !== {}) { - self.setRoomApiField(roomName, "mediaIds", mediaIds); - } - } - else if (roomData[roomName].roomStatus === "leave") { - if (self.roomEntryListener) { - self.roomEntryListener(false, roomName); - } - delete self.roomJoin[roomName]; - delete lastLoggedInList[roomName]; - continue; - } - - if (roomData[roomName].clientList) { - lastLoggedInList[roomName] = roomData[roomName].clientList; - } - else if (roomData[roomName].clientListDelta) { - stuffToAdd = roomData[roomName].clientListDelta.updateClient; - if (stuffToAdd) { - for (id in stuffToAdd) { - if (!stuffToAdd.hasOwnProperty(id)) { - continue; - } - if (!lastLoggedInList[roomName]) { - lastLoggedInList[roomName] = []; - } - lastLoggedInList[roomName][id] = stuffToAdd[id]; - } - } - stuffToRemove = roomData[roomName].clientListDelta.removeClient; - if (stuffToRemove && lastLoggedInList[roomName]) { - for (removeId in stuffToRemove) { - if (stuffToRemove.hasOwnProperty(removeId)) { - delete lastLoggedInList[roomName][removeId]; - } - } - } - } - if (self.roomJoin[roomName] && roomData[roomName].field) { - fields.rooms[roomName] = roomData[roomName].field; - } - if (roomData[roomName].roomStatus === "join") { - if (self.roomEntryListener) { - self.roomEntryListener(true, roomName); - } - } - processOccupantList(roomName, lastLoggedInList[roomName]); - } - self.emitEvent("roomOccupant", lastLoggedInList); - } - - /** - * Returns an array of easyrtcid's of peers in a particular room. - * @param roomName - * @returns {Array} of easyrtcids or null if the client is not in the room. - * @example - * var occupants = easyrtc.getRoomOccupants("default"); - * var i; - * for( i = 0; i < occupants.length; i++ ) { - * console.log( occupants[i] + " is in the room"); - * } - */ - this.getRoomOccupantsAsArray = function(roomName) { - if (!lastLoggedInList[roomName]) { - return null; - } - else { - return Object.keys(lastLoggedInList[roomName]); - } - } - - /** - * Returns a map of easyrtcid's of peers in a particular room. You should only test elements in the map to see if they are - * null; their actual values are not guaranteed to be the same in different releases. - * @param roomName - * @returns {Object} of easyrtcids or null if the client is not in the room. - * @example - * if( easyrtc.getRoomOccupantsAsMap("default")[some_easyrtcid]) { - * console.log("yep, " + some_easyrtcid + " is in the room"); - * } - */ - this.getRoomOccupantsAsMap = function(roomName) { - return lastLoggedInList[roomName]; - } - - /** - * Returns true if the ipAddress parameter was the address of a turn server. This is done by checking against information - * collected during peer to peer calls. Don't expect it to work before the first call, or to identify turn servers that aren't - * in the ice config. - * @param ipAddress - * @returns {boolean} true if ip address is known to be that of a turn server, false otherwise. - */ - this.isTurnServer = function(ipAddress) { - return !!self._turnServers[ipAddress]; - }; - function processIceConfig(iceConfig) { - pc_config = {iceServers: []}; - self._turnServers = {}; - var i; - var item, fixedItem, username, ipAddress; - if (!window.createIceServer) { - return; - } - for (i = 0; i < iceConfig.iceServers.length; i++) { - item = iceConfig.iceServers[i]; - if (item.url.indexOf('turn:') === 0) { - if (item.username) { - fixedItem = createIceServer(item.url, item.username, item.credential); - } - else { - self.showError("Developer error", "Iceserver entry doesn't have a username: " + JSON.stringify(item)); - } - ipAddress = item.url.split(/[@:&]/g)[1]; - self._turnServers[ipAddress] = true; - } - else { // is stun server entry - fixedItem = item; - } - if (fixedItem) { - pc_config.iceServers.push(fixedItem); - } - } - } - - /** - * Request fresh ice config information from the server. - * This should be done periodically by long running applications. - * @param {Function} callback is called with a value of true on success, false on failure. - */ - this.getFreshIceConfig = function(callback) { - var dataToShip = { - msgType: "getIceConfig", - msgData: {} - }; - if (!callback) { - callback = function() { - }; - } - self.webSocket.json.emit("easyrtcCmd", dataToShip, - function(ackMsg) { - if (ackMsg.msgType === "iceConfig") { - processIceConfig(ackMsg.msgData.iceConfig); - callback(true); - } - else { - self.showError(ackMsg.msgData.errorCode, ackMsg.msgData.errorText); - callback(false); - } - } - ); - }; - function processToken(msg) { - if (self.debugPrinter) { - self.debugPrinter("entered process token"); - } - var msgData = msg.msgData; - if (msgData.easyrtcid) { - self.myEasyrtcid = msgData.easyrtcid; - } - if (msgData.field) { - fields.connection = msgData.field; - } - if (msgData.iceConfig) { - processIceConfig(msgData.iceConfig); - } - - if (msgData.sessionData) { - processSessionData(msgData.sessionData); - } - - if (msgData.roomData) { - processRoomData(msgData.roomData); - } - - if (msgData.application.field) { - fields.application = msgData.application.field; - } - - } - - function sendAuthenticate(successCallback, errorCallback) { - // - // find our easyrtcsid - // - var cookies, target, i; - var easyrtcsid = null; - if (self.cookieId && document.cookie) { - cookies = document.cookie.split(/[; ]/g); - target = self.cookieId + "="; - for (i = 0; i < cookies.length; i++) { - if (cookies[i].indexOf(target) === 0) { - easyrtcsid = cookies[i].substring(target.length); - } - } - } - - if (!self.roomJoin) { - self.roomJoin = {}; - } - - var msgData = { - apiVersion: self.apiVersion, - applicationName: self.applicationName, - setUserCfg: collectConfigurationInfo(true) - }; - if (self.presenceShow) { - msgData.setPresence = {show: self.presenceShow, status: self.presenceStatus}; - } - if (self.username) { - msgData.username = self.username; - } - if (self.roomJoin && !isEmptyObj(self.roomJoin)) { - msgData.roomJoin = self.roomJoin; - } - if (easyrtcsid) { - msgData.easyrtcsid = easyrtcsid; - } - if (credential) { - msgData.credential = credential; - } - - self.webSocket.json.emit("easyrtcAuth", - {msgType: "authenticate", - msgData: msgData - }, - function(msg) { - var room; - if (msg.msgType === "error") { - errorCallback(msg.msgData.errorCode, msg.msgData.errorText); - self.roomJoin = {}; - } - else { - processToken(msg); - if (self._roomApiFields) { - for (room in self._roomApiFields) { - if (self._roomApiFields.hasOwnProperty(room)) { - _enqueueSendRoomApi(room, self._roomApiFields[room]); - } - } - } - - if (successCallback) { - successCallback(self.myEasyrtcid); - } - } - } - ); - } - - /** Get a list of the rooms you are in. You must be connected to call this function. - * @returns {Object} A map whose keys are the room names - */ - this.getRoomsJoined = function() { - var roomsIn = {}; - var key; - for (key in self.roomJoin) { - if (self.roomJoin.hasOwnProperty(key)) { - roomsIn[key] = true; - } - } - return roomsIn; - }; - /** Get server defined fields associated with a particular room. Only valid - * after a connection has been made. - * @param {String} roomName - the name of the room you want the fields for. - * @returns {Object} A dictionary containing entries of the form {key:{'fieldName':key, 'fieldValue':value1}} or undefined - * if you are not connected to the room. - */ - this.getRoomFields = function(roomName) { - if (!fields || !fields.rooms || !fields.rooms[roomName]) - return undefined; - return fields.rooms[roomName]; - }; - /** Get server defined fields associated with the current application. Only valid - * after a connection has been made. - * @returns {Object} A dictionary containing entries of the form {key:{'fieldName':key, 'fieldValue':value1}} - */ - this.getApplicationFields = function() { - return fields.application; - }; - /** Get server defined fields associated with the connection. Only valid - * after a connection has been made. - * @returns {Object} A dictionary containing entries of the form {key:{'fieldName':key, 'fieldValue':value1}} - */ - this.getConnectionFields = function() { - return fields.connection; - }; -// this flag controls whether the easyApp routine adds close buttons to the caller -// video objects - - /** @private */ - var autoAddCloseButtons = true; - /** By default, the easyApp routine sticks a "close" button on top of each caller - * video object that it manages. Call this function(before calling easyApp) to disable that particular feature. - * @example - * easyrtc.dontAddCloseButtons(); - */ - this.dontAddCloseButtons = function() { - autoAddCloseButtons = false; - }; - /** - * Validates that the video ids correspond to dom objects. - * @param {String} monitorVideoId - * @param {Array} videoIds - * @returns {Boolean} - * @private - */ - function _validateVideoIds(monitorVideoId, videoIds) { - var i; - // verify that video ids were not typos. - if (monitorVideoId && !document.getElementById(monitorVideoId)) { - self.showError(self.errCodes.DEVELOPER_ERR, "The monitor video id passed to easyApp was bad, saw " + monitorVideoId); - return false; - } - - for (i in videoIds) { - if (!videoIds.hasOwnProperty(i)) { - continue; - } - var name = videoIds[i]; - if (!document.getElementById(name)) { - self.showError(self.errCodes.DEVELOPER_ERR, "The caller video id '" + name + "' passed to easyApp was bad."); - return false; - } - } - return true; - } - ; - /** - * This is a helper function for the easyApp method. It manages the assignment of video streams - * to video objects. It assumes - * @param {String} monitorVideoId is the id of the mirror video tag. - * @param {Array} videoIds is an array of ids of the caller video tags. - * @private - */ - function easyAppBody(monitorVideoId, videoIds) { - var numPEOPLE = videoIds.length; - var videoIdsP = videoIds; - var refreshPane = 0; - var onCall = null, onHangup = null; - - if (!videoIdsP) { - videoIdsP = []; - } - - easyrtc.addEventListener("roomOccupants", - function(eventName, eventData) { - for (i = 0; i < numPEOPLE; i++) { - var video = getIthVideo(i); - if (!videoIsFree(video)) { - if( !easyrtc.isPeerInAnyRoom(video.dataset.caller)){ - if( onHangup ) { - onHangup(i, easyrtc.dataset.caller); - } - easyrtc.dataset.caller = null; - } - } - } - } - ); - - function videoIsFree(obj) { - return (obj.dataset.caller === "" || obj.dataset.caller === null || obj.dataset.caller === undefined); - } - - if (!_validateVideoIds(monitorVideoId, videoIdsP)) { - throw "bad video element id"; - } - - if (monitorVideoId) { - document.getElementById(monitorVideoId).muted = "muted"; - } - - /** Sets an event handler that gets called when an incoming MediaStream is assigned - * to a video object. The name is poorly chosen and reflects a simpler era when you could - * only have one media stream per peer connection. - * @param {Function} cb has the signature function(easyrtcid, slot){} - * @example - * easyrtc.setOnCall( function(easyrtcid, slot){ - * console.log("call with " + easyrtcid + "established"); - * }); - */ - self.setOnCall = function(cb) { - onCall = cb; - }; - /** Sets an event handler that gets called when a call is ended. - * it's only purpose (so far) is to support transitions on video elements. - x * this function is only defined after easyrtc.easyApp is called. - * The slot is parameter is the index into the array of video ids. - * Note: if you call easyrtc.getConnectionCount() from inside your callback - * it's count will reflect the number of connections before the hangup started. - * @param {Function} cb has the signature function(easyrtcid, slot){} - * @example - * easyrtc.setOnHangup( function(easyrtcid, slot){ - * console.log("call with " + easyrtcid + "ended"); - * }); - */ - self.setOnHangup = function(cb) { - onHangup = cb; - }; - - function getIthVideo(i) { - if (videoIdsP[i]) { - return document.getElementById(videoIdsP[i]); - } - else { - return null; - } - } - - - self.getIthCaller = function(i) { - if (i < 0 || i > videoIdsP.length) { - return null; - } - var vid = getIthVideo(i); - return vid.dataset.caller; - }; - - self.getSlotOfCaller = function(easyrtcid) { - var i; - for (i = 0; i < numPEOPLE; i++) { - if (self.getIthCaller(i) === easyrtcid) { - return i; - } - } - return -1; // caller not connected - }; - function hideVideo(video) { - self.setVideoObjectSrc(video, ""); - video.style.visibility = "hidden"; - } - - self.setOnStreamClosed(function(caller) { - var i; - for (i = 0; i < numPEOPLE; i++) { - var video = getIthVideo(i); - if (video.dataset.caller === caller) { - hideVideo(video); - video.dataset.caller = ""; - if (onHangup) { - onHangup(caller, i); - } - } - } - }); - // - // Only accept incoming calls if we have a free video object to display - // them in. - // - self.setAcceptChecker(function(caller, helper) { - var i; - for (i = 0; i < numPEOPLE; i++) { - var video = getIthVideo(i); - if (videoIsFree(video)) { - helper(true); - return; - } - } - helper(false); - }); - self.setStreamAcceptor(function(caller, stream) { - var i; - if (self.debugPrinter) { - self.debugPrinter("stream acceptor called"); - } - function showVideo(video, stream) { - self.setVideoObjectSrc(video, stream); - if (video.style.visibility) { - video.style.visibility = 'visible'; - } - } - - var video; - if (refreshPane && videoIsFree(refreshPane)) { - showVideo(refreshPane, stream); - if (onCall) { - onCall(caller, refreshPane); - } - refreshPane = null; - return; - } - for (i = 0; i < numPEOPLE; i++) { - video = getIthVideo(i); - if (video.dataset.caller === caller) { - showVideo(video, stream); - if (onCall) { - onCall(caller, i); - } - return; - } - } - - for (i = 0; i < numPEOPLE; i++) { - video = getIthVideo(i); - if (!video.dataset.caller || videoIsFree(video)) { - video.dataset.caller = caller; - if (onCall) { - onCall(caller, i); - } - showVideo(video, stream); - return; - } - } -// -// no empty slots, so drop whatever caller we have in the first slot and use that one. -// - video = getIthVideo(0); - if (video) { - self.hangup(video.dataset.caller); - showVideo(video, stream); - if (onCall) { - onCall(caller, 0); - } - } - video.dataset.caller = caller; - }); - (function() { - var addControls, parentDiv, closeButton, i; - if (autoAddCloseButtons) { - - addControls = function(video) { - parentDiv = video.parentNode; - video.dataset.caller = ""; - closeButton = document.createElement("div"); - closeButton.className = "easyrtc_closeButton"; - closeButton.onclick = function() { - if (video.dataset.caller) { - self.hangup(video.dataset.caller); - hideVideo(video); - video.dataset.caller = ""; - } - }; - parentDiv.appendChild(closeButton); - }; - for (i = 0; i < numPEOPLE; i++) { - addControls(getIthVideo(i)); - } - } - })(); - var monitorVideo = null; - if (videoEnabled && monitorVideoId !== null) { - monitorVideo = document.getElementById(monitorVideoId); - if (!monitorVideo) { - console.error("Programmer error: no object called " + monitorVideoId); - return; - } - monitorVideo.muted = "muted"; - monitorVideo.defaultMuted = true; - } - - - } - ; - /** - * Provides a layer on top of the easyrtc.initMediaSource and easyrtc.connect, assign the local media stream to - * the video object identified by monitorVideoId, assign remote video streams to - * the video objects identified by videoIds, and then call onReady. One of it's - * side effects is to add hangup buttons to the remote video objects, buttons - * that only appear when you hover over them with the mouse cursor. This method will also add the - * easyrtcMirror class to the monitor video object so that it behaves like a mirror. - * @param {String} applicationName - name of the application. - * @param {String} monitorVideoId - the id of the video object used for monitoring the local stream. - * @param {Array} videoIds - an array of video object ids (strings) - * @param {Function} onReady - a callback function used on success. It is called with the easyrtcId this peer is known to the server as. - * @param {Function} onFailure - a callback function used on failure (failed to get local media or a connection of the signaling server). - * @example - * easyrtc.easyApp('multiChat', 'selfVideo', ['remote1', 'remote2', 'remote3'], - * function(easyrtcId){ - * console.log("successfully connected, I am " + easyrtcId); - * }, - * function(errorCode, errorText){ - * console.log(errorText); - * ); - */ - this.easyApp = function(applicationName, monitorVideoId, videoIds, onReady, onFailure) { - var gotMediaCallback = null, - gotConnectionCallback = null; - easyAppBody(monitorVideoId, videoIds); - self.setGotMedia = function(gotMediaCB) { - gotMediaCallback = gotMediaCB; - }; - /** Sets an event handler that gets called when a connection to the signaling - * server has or has not been made. Can only be called after calling easyrtc.easyApp. - * @param {Function} gotConnectionCB has the signature (gotConnection, errorText) - * @example - * easyrtc.setGotConnection( function(gotConnection, errorText){ - * if( gotConnection ){ - * console.log("Successfully connected to signaling server"); - * } - * else{ - * console.log("Failed to connect to signaling server because: " + errorText); - * } - * }); - */ - self.setGotConnection = function(gotConnectionCB) { - gotConnectionCallback = gotConnectionCB; - }; - var nextInitializationStep; - nextInitializationStep = function(/* token */) { - if (gotConnectionCallback) { - gotConnectionCallback(true, ""); - } - onReady(self.myEasyrtcid); - }; - function postGetUserMedia() { - if (gotMediaCallback) { - gotMediaCallback(true, null); - } - if (monitorVideoId !== null) { - self.setVideoObjectSrc(document.getElementById(monitorVideoId), self.getLocalStream()); - } - function connectError(errorCode, errorText) { - if (gotConnectionCallback) { - gotConnectionCallback(false, errorText); - } - else if (onFailure) { - onFailure(self.errCodes.CONNECT_ERR, errorText); - } - else { - self.showError(self.errCodes.CONNECT_ERR, errorText); - } - } - - self.connect(applicationName, nextInitializationStep, connectError); - } - - var stream = getLocalMediaStreamByName(null); - if (stream) { - postGetUserMedia(); - } - else { - self.initMediaSource( - postGetUserMedia, - function(errorCode, errorText) { - if (gotMediaCallback) { - gotMediaCallback(false, errorText); - } - else if (onFailure) { - onFailure(self.errCodes.MEDIA_ERR, errorText); - } - else { - self.showError(self.errCodes.MEDIA_ERR, errorText); - } - }, - null // default stream - ); - } - }; - /** - * - * @deprecated now called easyrtc.easyApp. - */ - this.initManaged = this.easyApp; - var preallocatedSocketIo = null; - /** - * Supply a socket.io connection that will be used instead of allocating a new socket. - * The expected usage is that you allocate a websocket, assign options to it, call - * easyrtc.useThisSocketConnection, followed by easyrtc.connect or easyrtc.easyApp. Easyrtc will not attempt to - * close sockets that were supplied with easyrtc.useThisSocketConnection. - * @param {Object} alreadyAllocatedSocketIo A value allocated with the connect method of socket.io. - */ - this.useThisSocketConnection = function(alreadyAllocatedSocketIo) { - preallocatedSocketIo = alreadyAllocatedSocketIo; - } - /** - * Connect to the easyrtc signaling server. - * @param applicationName - * @param successCallback - * @param errorCallback - */ - this.connect = function(applicationName, successCallback, errorCallback) { - - if (!window.io) { - self.showError("Developer error", "Your HTML has not included the socket.io.js library"); - } - - if (!preallocatedSocketIo && self.webSocket) { - console.error("Developer error: attempt to connect when already connected to socket server"); - return; - } - pc_config = {}; - closedChannel = null; - oldConfig = {}; // used internally by updateConfiguration - queuedMessages = {}; - self.applicationName = applicationName; - fields = { - rooms: {}, - application: {}, - connection: {} - }; - if (self.debugPrinter) { - self.debugPrinter("attempt to connect to WebRTC signalling server with application name=" + applicationName); - } - - if (errorCallback === null) { - errorCallback = function(errorCode, errorText) { - console.error("easyrtc.connect: " + errorText); - }; - } - - connectToWSServer(successCallback, errorCallback); - }; -}; -window.easyrtc = new Easyrtc(); - -var easyrtc_constantStrings = { - "unableToEnterRoom":"Unable to enter room {0} because {1}" , - "resolutionWarning": "Requested video size of {0}x{1} but got size of {2}x{3}", - "badUserName": "Illegal username {0}", - "localMediaError": "Error getting local media stream: {0}", - "miscSignalError": "Miscellaneous error from signalling server. It may be ignorable.", - "noServer": "Unable to reach the EasyRTC signalling server.", - "badsocket": "Socket.io connect event fired with bad websocket.", - "icf": "Internal communications failure", - "statsNotSupported":"call statistics not supported by this browser, try Chrome.", - "noWebrtcSupport":"Your browser doesn't appear to support WebRTC.", - "gumFailed":"Failed to get access to local media. Error code was {0}.", - "requireAudioOrVideo":"At least one of audio and video must be provided" -}; \ No newline at end of file diff --git a/messenger/js/easyrtc/node_modules/easyrtc/.npmignore b/messenger/js/easyrtc/node_modules/easyrtc/.npmignore deleted file mode 100644 index cd7d58500e..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/.npmignore +++ /dev/null @@ -1,182 +0,0 @@ -# This file is used to restrict unnecessary files from being committed to git. -# It the same as the recommended default, but with an addition of restricting -# node_modules from being committed and .log files. - -################# -## Eclipse -################# - -*.pydevproject -.project -.metadata -bin/ -tmp/ -*.tmp -*.bak -*.swp -*~.nib -local.properties -.classpath -.settings/ -.loadpath - -# External tool builders -.externalToolBuilders/ - -# Locally stored "Eclipse launch configurations" -*.launch - -# CDT-specific -.cproject - -# PDT-specific -.buildpath - - -################# -## Visual Studio -################# - -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. - -# User-specific files -*.suo -*.user -*.sln.docstates - -# Build results -[Dd]ebug/ -[Rr]elease/ -*_i.c -*_p.c -*.ilk -*.meta -*.obj -*.pch -*.pdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.vspscc -.builds -*.dotCover - -## TODO: If you have NuGet Package Restore enabled, uncomment this -#packages/ - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opensdf -*.sdf - -# Visual Studio profiler -*.psess -*.vsp - -# ReSharper is a .NET coding add-in -_ReSharper* - -# Installshield output folder -[Ee]xpress - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish - -# Others -[Bb]in -[Oo]bj -sql -TestResults -*.Cache -ClientBin -stylecop.* -~$* -*.dbmdl -Generated_Code #added for RIA/Silverlight projects - -# Backup & report files from converting an old project file to a newer -# Visual Studio version. Backup files are not needed, because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML - - - -############ -## Windows -############ - -# Windows image file caches -Thumbs.db - -# Folder config file -Desktop.ini - - -############# -## Python -############# - -*.py[co] - -# Packages -*.egg -*.egg-info -dist -build -eggs -parts -bin -var -sdist -develop-eggs -.installed.cfg - -# Installer logs -pip-log.txt - -# Unit test / coverage reports -.coverage -.tox - -#Translations -*.mo - -#Mr Developer -.mr.developer.cfg - -# Mac crap -.DS_Store - -######### -# Node.js -######### -node_modules - -######### -# EasyRTC -######### -*.log -config_override.js -nbproject -/.idea -desktopCapture -/api/labs/desktopCapture diff --git a/messenger/js/easyrtc/node_modules/easyrtc/LICENSE b/messenger/js/easyrtc/node_modules/easyrtc/LICENSE deleted file mode 100644 index ebf68d085d..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -Copyright (c) 2014, Priologic Software Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/messenger/js/easyrtc/node_modules/easyrtc/README.md b/messenger/js/easyrtc/node_modules/easyrtc/README.md deleted file mode 100644 index c84f78cede..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/README.md +++ /dev/null @@ -1,147 +0,0 @@ -![EasyRTC](./api/img/easyrtc.png "EasyRTC") - -EasyRTC -======= - -**A bundle of Open Source WebRTC joy!** - -Priologic's EasyRTC, a bundle of Open Source WebRTC joy, incorporates an EasyRTC server install and client API, and working, HTML5 and JavaScript, application source code under a BSD 2 license. - - -Features --------- - * Install EasyRTC's WebRTC Server on your own Linux, Windows, or Mac server in minutes not days. - * Use our EasyRTC API and sample application code to build and deploy your WebRTC app in hours not weeks. - * EasyRTC is completely free and open source under a BSD 2 license. No usage costs or other hidden fees. - - -Installation In A Nutshell --------------------------- - 1. Install [Node.js](http://nodejs.org) - 2. Download files from [server_example/](./server_example/) and place them in a local folder of your choice. - - [package.json](./server_example/package.json) - - [server.js](./server_example/server.js) - - OR [download and extract this .zip](http://easyrtc.com/files/easyrtc_server_example.zip) - 3. Run `npm install` from the installation folder to install dependent packages (including EasyRTC) - 4. Start EasyRTC by running `node server.js` - 5. Browse the examples using a WebRTC enabled browser. *(defaults to port `8080`)* - -Step by step instructions including additional setup options can be found in `/docs/easyrtc_server_install.md` - -Note: there is no corresponding need to install the client files specifically; they were installed as part of EasyRTC in step 3. - -Documentation -------------- -All documentation can be found within [the docs folder](./docs/). - -**EasyRTC Server** - - * [Install instructions for Ubuntu, Windows, and Mac](./docs/easyrtc_server_install.md) - * `/docs/easyrtc_server_install.md` - * [Configuration options](./docs/easyrtc_server_configuration.md) - * `/docs/easyrtc_server_configuration.md` - * [Using Server Events](./docs/easyrtc_server_events.md) - * `/docs/easyrtc_server_events.md` - * Server API - * `/docs/server_html_docs/index.html` - -**EasyRTC Client API** - * [Client API tutorial](./docs/easyrtc_client_tutorial.md) - * `/docs/easyrtc_client_tutorial.md` - * Client API - * `/docs/client_html_docs/easyrtc.html` - * Client File Transfer API - * `/docs/client_html_docs/easyrtc_ft.html` - -**General Development** - * [Frequently asked questions](./docs/easyrtc_faq.md) - * `/docs/easyrtc_faq.md` - * [Authentication](./docseasyrtc_authentication.md/) - * `/docs/easyrtc_authentication.md` - * [ICE, TURN, STUN Configuration](./docs/easyrtc_server_ice.md) - * `/docs/easyrtc_server_ice.md` - * [Using Rooms](./docs/easyrtc_rooms.md) - * `/docs/easyrtc_rooms.md` - * [Serving with SSL](./docs/easyrtc_server_ssl.md) - * `/docs/easyrtc_server_ssl.md` - * [Serving next to IIS or Apache](./docs/easyrtc_with_other_servers.md) - * `/docs/easyrtc_with_other_servers.md` - * [Upcoming features](./docs/easyrtc_upcoming_features.md) - * `/docs/easyrtc_upcoming_features.md` - * [Changelog](./docs/easyrtc_changelog.md) - * `/docs/easyrtc_changelog.md` - - -Folder Structure ----------------- - - * / (root) - * Licenses and package information - * /api/ - * Client API files including easyrtc.js - * /demos/ - * EasyRTC live demos and example code - * /docs/ - * Documentation for using the API and running the server - * /lib/ - * Required libraries - * /node_modules/ - * Required node.js modules - * This folder will be created during the install - * /server_example/ - * A simple server example - - -Included Demos --------------- - -EasyRTC comes with a number of demo's which work immediately after installation. - - * Video and/or Audio connections - * Multi-party video chat - * Text Messaging with or without Data Channels - * Screen and tab sharing - * File transfer - - -Links for help and information ------------------------------- - -* The EasyRTC website is at: - * [http://www.easyrtc.com/](http://www.easyrtc.com/) -* Use our support forum is at: - * [https://groups.google.com/forum/#!forum/easyrtc](https://groups.google.com/forum/#!forum/easyrtc) -* Live demo site: - * [http://demo.easyrtc.com/](http://demo.easyrtc.com/) -* Bugs and requests can be filed on our github page or on the forum: - * [https://github.com/priologic/easyrtc/issues](https://github.com/priologic/easyrtc/issues) -* Our YouTube channel has live demo's: - * [http://www.youtube.com/user/priologic](http://www.youtube.com/user/priologic) - - -License -------- - -Copyright (c) 2014, Priologic Software Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/messenger/js/easyrtc/node_modules/easyrtc/api/adapter.js b/messenger/js/easyrtc/node_modules/easyrtc/api/adapter.js deleted file mode 100644 index af7fb6710d..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/api/adapter.js +++ /dev/null @@ -1,184 +0,0 @@ -// -// the below code is a copy of the standard polyfill adapter.js -// -var getUserMedia = null; -var attachMediaStream = null; -var reattachMediaStream = null; -var webrtcDetectedBrowser = null; -var webrtcDetectedVersion = null; -if (navigator.mozGetUserMedia) { -// console.log("This appears to be Firefox"); - - webrtcDetectedBrowser = "firefox"; - - // - // better version detection for gecko based browsers provided by - // Kévin Poulet. - // - var matches = navigator.userAgent.match(/\srv:([0-9]+)\./); - if (matches !== null && matches.length > 1) { - webrtcDetectedVersion = parseInt(matches[1]); - } - - // The RTCPeerConnection object. - window.RTCPeerConnection = mozRTCPeerConnection; - // The RTCSessionDescription object. - window.RTCSessionDescription = mozRTCSessionDescription; - // The RTCIceCandidate object. - window.RTCIceCandidate = mozRTCIceCandidate; - // Get UserMedia (only difference is the prefix). - // Code from Adam Barth. - window.getUserMedia = navigator.mozGetUserMedia.bind(navigator); - // Creates iceServer from the url for FF. - window.createIceServer = function(url, username, password) { - var iceServer = null; - var url_parts = url.split(':'); - var turn_url_parts; - if (url_parts[0].indexOf('stun') === 0) { - // Create iceServer with stun url. - iceServer = {'url': url}; - } else if (url_parts[0].indexOf('turn') === 0 && - (url.indexOf('transport=udp') !== -1 || - url.indexOf('?transport') === -1)) { - // Create iceServer with turn url. - // Ignore the transport parameter from TURN url. - turn_url_parts = url.split("?"); - iceServer = {'url': turn_url_parts[0], - 'credential': password, - 'username': username}; - } - return iceServer; - }; - // Attach a media stream to an element. - attachMediaStream = function(element, stream) { -// console.log("Attaching media stream"); - element.mozSrcObject = stream; - element.play(); - }; - reattachMediaStream = function(to, from) { -// console.log("Reattaching media stream"); - to.mozSrcObject = from.mozSrcObject; - to.play(); - }; - if (webrtcDetectedVersion < 23) { -// Fake get{Video,Audio}Tracks - MediaStream.prototype.getVideoTracks = function() { - return []; - }; - MediaStream.prototype.getAudioTracks = function() { - return []; - }; - } -} else if (navigator.webkitGetUserMedia) { -// console.log("This appears to be Chrome"); - - webrtcDetectedBrowser = "chrome"; - webrtcDetectedVersion = - parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2]); - // Creates iceServer from the url for Chrome. - window.createIceServer = function(url, username, password) { - var iceServer = null; - var url_turn_parts; - var url_parts = url.split(':'); - if (url_parts[0].indexOf('stun') === 0) { -// Create iceServer with stun url. - iceServer = {'url': url}; - } else if (url_parts[0].indexOf('turn') === 0) { - if (webrtcDetectedVersion < 28) { -// For pre-M28 chrome versions use old TURN format. - url_turn_parts = url.split("turn:"); - iceServer = {'url': 'turn:' + username + '@' + url_turn_parts[1], - 'credential': password}; - } else { -// For Chrome M28 & above use new TURN format. - iceServer = {'url': url, - 'credential': password, - 'username': username}; - } - } - return iceServer; - }; - // The RTCPeerConnection object. - window.RTCPeerConnection = webkitRTCPeerConnection; - // Get UserMedia (only difference is the prefix). - // Code from Adam Barth. - window.getUserMedia = navigator.webkitGetUserMedia.bind(navigator); - // Attach a media stream to an element. - attachMediaStream = function(element, stream) { - if (typeof element.srcObject !== 'undefined') { - element.srcObject = stream; - } else if (typeof element.mozSrcObject !== 'undefined') { - element.mozSrcObject = stream; - } else if (typeof element.src !== 'undefined') { - element.src = URL.createObjectURL(stream); - } else { - console.log('Error attaching stream to element.'); - } - }; - reattachMediaStream = function(to, from) { - to.src = from.src; - }; - // The representation of tracks in a stream is changed in M26. - // Unify them for earlier Chrome versions in the coexisting period. - if (!webkitMediaStream.prototype.getVideoTracks) { - webkitMediaStream.prototype.getVideoTracks = function() { - return this.videoTracks; - }; - webkitMediaStream.prototype.getAudioTracks = function() { - return this.audioTracks; - }; - } - -// New syntax of getXXXStreams method in M26. - if (!webkitRTCPeerConnection.prototype.getLocalStreams) { - webkitRTCPeerConnection.prototype.getLocalStreams = function() { - return this.localStreams; - }; - webkitRTCPeerConnection.prototype.getRemoteStreams = function() { - return this.remoteStreams; - }; - } -//} else if( window.ActiveXObject ){ // appears to IE so check for the wrapper. -// var head = document.getElementsByTagName('head')[0]; -// var i; -// var adapterAddress; -// var wrapperPresent = false; -// -// // -// // we look for the adapter as well as the wrapper because if we don't find the -// // wrapper, we'll look for it in the same directory as the adapter was found. -// // -// for( i = 0; i < head.childNodes.length; i++) { -// var child = head.childNodes[i]; -// if( /\/adapter.js$/.test(child.src)) { -// adapterAddress = child.src; -// } -// else if( /\/rtcplugin.js$/.test(child.src)) { -// wrapperPresent = true; -// } -// } -// -// -// if( wrapperPresent) { -// addIEDeclarations(); -// } -// else if( adapterAddress) { -// var script = document.createElement('script'); -// script.type = 'text/javascript'; -// script.src = adapterAddress.replace(/\/adapter.js$/, "/rtcplugin.js"); -// src.onload = addIEDeclarations; -// src.onerror = function () { -// alert("Developer error: this page requires the Priologic IE Webrtc plugin wrapper (rtcplugin.js) to run when using Internet Explorer, which the developer has not supplied."); -// throw new Error("No rtcplugin.js found. It should be in the same folder as your adapter.js or you can include it yourself before the adapter.js"); -// } -// head.appendChild(script); -// } -} else { - console.log("Browser does not appear to be WebRTC-capable"); -} - -if (!window.createIceServer) { - window.createIceServer = function(url, username, credential) { - return {'url': url, 'credential': credential, 'username': username}; - }; -} \ No newline at end of file diff --git a/messenger/js/easyrtc/node_modules/easyrtc/api/buildEnglishVersions.bat b/messenger/js/easyrtc/node_modules/easyrtc/api/buildEnglishVersions.bat deleted file mode 100644 index a08163d843..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/api/buildEnglishVersions.bat +++ /dev/null @@ -1 +0,0 @@ - type adapter.js easyrtc_int.js easyrtc_lang_en.js > easyrtc.js \ No newline at end of file diff --git a/messenger/js/easyrtc/node_modules/easyrtc/api/buildEnglishVersions.sh b/messenger/js/easyrtc/node_modules/easyrtc/api/buildEnglishVersions.sh deleted file mode 100755 index 9f1fd1dffe..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/api/buildEnglishVersions.sh +++ /dev/null @@ -1,2 +0,0 @@ -#!/bin/sh -cat adapter.js easyrtc_int.js easyrtc_lang_en.js > easyrtc.js diff --git a/messenger/js/easyrtc/node_modules/easyrtc/api/easyrtc.css b/messenger/js/easyrtc/node_modules/easyrtc/api/easyrtc.css deleted file mode 100644 index 2ffe088003..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/api/easyrtc.css +++ /dev/null @@ -1,74 +0,0 @@ -/* - * These styles define the appearance of the default error dialog box. - */ -#easyrtcErrorDialog { - background-color: #ffe0e0; - - position:fixed; - right: 10px; - top:20px; - z-index: 30; - opacity: 0.95; - padding: 0.5em; - border-radius:10px; - border-color: red; - border-style: solid; - border-width: 1px; - -webkit-box-shadow: 2px 2px 8px 1px rgba(0,0,0,0.9); - box-shadow: 2px 2px 8px 1px rgba(0,0,0,0.9); -} - -.easyrtcErrorDialog_title { - position:static; - text-align:center; - font-size: 18px; - font-weight: bold; - margin-bottom: 0.5em; - clear:both; -} - -#easyrtcErrorDialog_body{ - position:static; - height:150px; - overflow-y:auto; -} - -.easyrtcErrorDialog_element { - position:static; - font-style: italic; - font-size: 12px; - width:300px; - margin-bottom: 0.5em; - clear: both; - float:left; -} - -.easyrtcErrorDialog_okayButton { - position:static; - clear:both; - float:right; -} - -.easyrtcMirror { - -webkit-transform: scaleX(-1); - -moz-transform: scaleX(-1); - -ms-transform: scaleX(-1); - -o-transform: scaleX(-1); - transform: scaleX(-1); -} - -.easyrtc_closeButton { - z-index: 2; - position: absolute; - width: 40px; - height:40px; - right: 0px; - top: 0px; - background-image: url('data:image/svg+xml;utf8, '); - opacity: 0.3; -} - -.easyrtc_closeButton:hover { - opacity: 1; -} - diff --git a/messenger/js/easyrtc/node_modules/easyrtc/api/easyrtc.js b/messenger/js/easyrtc/node_modules/easyrtc/api/easyrtc.js deleted file mode 100644 index 96621510c2..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/api/easyrtc.js +++ /dev/null @@ -1,5468 +0,0 @@ -// -// the below code is a copy of the standard polyfill adapter.js -// -var getUserMedia = null; -var attachMediaStream = null; -var reattachMediaStream = null; -var webrtcDetectedBrowser = null; -var webrtcDetectedVersion = null; -if (navigator.mozGetUserMedia) { -// console.log("This appears to be Firefox"); - - webrtcDetectedBrowser = "firefox"; - - // - // better version detection for gecko based browsers provided by - // Kévin Poulet. - // - var matches = navigator.userAgent.match(/\srv:([0-9]+)\./); - if (matches !== null && matches.length > 1) { - webrtcDetectedVersion = parseInt(matches[1]); - } - - // The RTCPeerConnection object. - window.RTCPeerConnection = mozRTCPeerConnection; - // The RTCSessionDescription object. - window.RTCSessionDescription = mozRTCSessionDescription; - // The RTCIceCandidate object. - window.RTCIceCandidate = mozRTCIceCandidate; - // Get UserMedia (only difference is the prefix). - // Code from Adam Barth. - window.getUserMedia = navigator.mozGetUserMedia.bind(navigator); - // Creates iceServer from the url for FF. - window.createIceServer = function(url, username, password) { - var iceServer = null; - var url_parts = url.split(':'); - var turn_url_parts; - if (url_parts[0].indexOf('stun') === 0) { - // Create iceServer with stun url. - iceServer = {'url': url}; - } else if (url_parts[0].indexOf('turn') === 0 && - (url.indexOf('transport=udp') !== -1 || - url.indexOf('?transport') === -1)) { - // Create iceServer with turn url. - // Ignore the transport parameter from TURN url. - turn_url_parts = url.split("?"); - iceServer = {'url': turn_url_parts[0], - 'credential': password, - 'username': username}; - } - return iceServer; - }; - // Attach a media stream to an element. - attachMediaStream = function(element, stream) { -// console.log("Attaching media stream"); - element.mozSrcObject = stream; - element.play(); - }; - reattachMediaStream = function(to, from) { -// console.log("Reattaching media stream"); - to.mozSrcObject = from.mozSrcObject; - to.play(); - }; - if (webrtcDetectedVersion < 23) { -// Fake get{Video,Audio}Tracks - MediaStream.prototype.getVideoTracks = function() { - return []; - }; - MediaStream.prototype.getAudioTracks = function() { - return []; - }; - } -} else if (navigator.webkitGetUserMedia) { -// console.log("This appears to be Chrome"); - - webrtcDetectedBrowser = "chrome"; - webrtcDetectedVersion = - parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2]); - // Creates iceServer from the url for Chrome. - window.createIceServer = function(url, username, password) { - var iceServer = null; - var url_turn_parts; - var url_parts = url.split(':'); - if (url_parts[0].indexOf('stun') === 0) { -// Create iceServer with stun url. - iceServer = {'url': url}; - } else if (url_parts[0].indexOf('turn') === 0) { - if (webrtcDetectedVersion < 28) { -// For pre-M28 chrome versions use old TURN format. - url_turn_parts = url.split("turn:"); - iceServer = {'url': 'turn:' + username + '@' + url_turn_parts[1], - 'credential': password}; - } else { -// For Chrome M28 & above use new TURN format. - iceServer = {'url': url, - 'credential': password, - 'username': username}; - } - } - return iceServer; - }; - // The RTCPeerConnection object. - window.RTCPeerConnection = webkitRTCPeerConnection; - // Get UserMedia (only difference is the prefix). - // Code from Adam Barth. - window.getUserMedia = navigator.webkitGetUserMedia.bind(navigator); - // Attach a media stream to an element. - attachMediaStream = function(element, stream) { - if (typeof element.srcObject !== 'undefined') { - element.srcObject = stream; - } else if (typeof element.mozSrcObject !== 'undefined') { - element.mozSrcObject = stream; - } else if (typeof element.src !== 'undefined') { - element.src = URL.createObjectURL(stream); - } else { - console.log('Error attaching stream to element.'); - } - }; - reattachMediaStream = function(to, from) { - to.src = from.src; - }; - // The representation of tracks in a stream is changed in M26. - // Unify them for earlier Chrome versions in the coexisting period. - if (!webkitMediaStream.prototype.getVideoTracks) { - webkitMediaStream.prototype.getVideoTracks = function() { - return this.videoTracks; - }; - webkitMediaStream.prototype.getAudioTracks = function() { - return this.audioTracks; - }; - } - -// New syntax of getXXXStreams method in M26. - if (!webkitRTCPeerConnection.prototype.getLocalStreams) { - webkitRTCPeerConnection.prototype.getLocalStreams = function() { - return this.localStreams; - }; - webkitRTCPeerConnection.prototype.getRemoteStreams = function() { - return this.remoteStreams; - }; - } -//} else if( window.ActiveXObject ){ // appears to IE so check for the wrapper. -// var head = document.getElementsByTagName('head')[0]; -// var i; -// var adapterAddress; -// var wrapperPresent = false; -// -// // -// // we look for the adapter as well as the wrapper because if we don't find the -// // wrapper, we'll look for it in the same directory as the adapter was found. -// // -// for( i = 0; i < head.childNodes.length; i++) { -// var child = head.childNodes[i]; -// if( /\/adapter.js$/.test(child.src)) { -// adapterAddress = child.src; -// } -// else if( /\/rtcplugin.js$/.test(child.src)) { -// wrapperPresent = true; -// } -// } -// -// -// if( wrapperPresent) { -// addIEDeclarations(); -// } -// else if( adapterAddress) { -// var script = document.createElement('script'); -// script.type = 'text/javascript'; -// script.src = adapterAddress.replace(/\/adapter.js$/, "/rtcplugin.js"); -// src.onload = addIEDeclarations; -// src.onerror = function () { -// alert("Developer error: this page requires the Priologic IE Webrtc plugin wrapper (rtcplugin.js) to run when using Internet Explorer, which the developer has not supplied."); -// throw new Error("No rtcplugin.js found. It should be in the same folder as your adapter.js or you can include it yourself before the adapter.js"); -// } -// head.appendChild(script); -// } -} else { - console.log("Browser does not appear to be WebRTC-capable"); -} - -if (!window.createIceServer) { - window.createIceServer = function(url, username, credential) { - return {'url': url, 'credential': credential, 'username': username}; - }; -}/** @class - *@version 1.0.13 - *

- * Provides client side support for the EasyRTC framework. - * Please see the easyrtc_client_api.md and easyrtc_client_tutorial.md - * for more details.

- * - *

- *copyright Copyright (c) 2014, Priologic Software Inc. - *All rights reserved.

- * - *

- *Redistribution and use in source and binary forms, with or without - *modification, are permitted provided that the following conditions are met: - *

- *
    - *
  • Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer.
  • - *
  • Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution.
  • - *
- *

- *THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - *AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - *IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - *ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - *LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - *CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - *SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - *INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - *CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - *ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - *POSSIBILITY OF SUCH DAMAGE. - *

- */ - -var Easyrtc = function() { - var self = this; - var isFirefox = (webrtcDetectedBrowser === "firefox"); - var autoInitUserMedia = true; - var sdpLocalFilter = null, - sdpRemoteFilter = null; - var iceCandidateFilter = null; - - var connectionOptions = { - 'connect timeout': 10000, - 'force new connection': true - }; - - /** - * Sets functions which filter sdp records before calling setLocalDescription or setRemoteDescription. - * This is advanced functionality which can break things, easily. See the easyrtc_rates.js file for a - * filter builder. - * @param {Function} localFilter a function that takes an sdp string and returns an sdp string. - * @param {Function} remoteFilter a function that takes an sdp string and returns an sdp string. - */ - this.setSdpFilters = function(localFilter, remoteFilter) { - sdpLocalFilter = localFilter; - sdpRemoteFilter = remoteFilter; - }; - - /** - * Sets a function which filters IceCandidate records being sent or received. - * - * Candidate records can be received while they are being generated locally (before being - * sent to a peer), and after they are received by the peer. The filter receives two arguments, the candidate record and a boolean - * flag that is true for a candidate being received from another peer, - * and false for a candidate that was generated locally. The candidate record has the form: - * {type: 'candidate', label: sdpMLineIndex, id: sdpMid, candidate: candidateString} - * The function should return one of the following: the input candidate record, a modified candidate record, or null (indicating that the - * candidate should be discarded). - * @param {Function} filter - * @param {String} isIncoming - * @return an ice candidate record or null. - */ - this.setIceCandidateFilter = function(filter) { - iceCandidateFilter = filter; - } - - /** - * Controls whether a default local media stream should be acquired automatically during calls and accepts - * if a list of streamNames is not supplied. The default is true, which mimicks the behaviour of earlier releases - * that didn't support multiple streams. This function should be called before easyrtc.call or before entering an - * accept callback. - * @param {Boolean} flag true to allocate a default local media stream. - */ - this.setAutoInitUserMedia = function(flag) { - autoInitUserMedia = !!flag; - } - /** - * This function performs a printf like formatting. It actually takes an unlimited - * number of arguments, the declared arguments arg1, arg2, arg3 are present just for - * documentation purposes. - * @param {String} format A string like "abcd{1}efg{2}hij{1}." - * @param {String} arg1 The value that replaces {1} - * @param {String} arg2 The value that replaces {2} - * @param {String} arg3 The value that replaces {3} - * @returns {String} the formatted string. - */ - this.format = function(format, arg1, arg2, arg3) { - var formatted = arguments[0]; - for (var i = 1; i < arguments.length; i++) { - var regexp = new RegExp('\\{' + (i - 1) + '\\}', 'gi'); - formatted = formatted.replace(regexp, arguments[i]); - } - return formatted; - }; - /** @private */ - var haveAudioVideo = {audio: false, video: false}; -// -// Maps a key to a language specific string using the easyrtc_constantStrings map. -// Defaults to the key if the key can not be found, but outputs a warning in that case. -// This function is only used internally by easyrtc.js -// - /** - * @private - * @param {String} key - */ - this.getConstantString = function(key) { - if (easyrtc_constantStrings[key]) { - return easyrtc_constantStrings[key]; - } - else { - console.warn("Could not find key='" + key + "' in easyrtc_constantStrings"); - return key; - } - }; - // - // this is a list of the events supported by the generalized event listener. - // - var allowedEvents = { - roomOccupant: true, // this receives the list of everybody in any room you belong to - roomOccupants: true // this receives a {roomName:..., occupants:...} value for a specific room - }; - // - // A map of eventListeners. The key is the event type. - var eventListeners = {}; - /** This function checks if an attempt was made to add an event listener or - * or emit an unlisted event, since such is typically a typo. - * @private - * @param {String} eventName - * @param {String} callingFunction the name of the calling function. - */ - function event(eventName, callingFunction) { - if (typeof eventName !== 'string') { - self.showError(self.errCodes.DEVELOPER_ERR, src + " called without a string as the first argument"); - throw "developer error"; - } - if (!allowedEvents[eventName]) { - self.showError(self.errCodes.DEVELOPER_ERR, src + " called with a bad event name = " + eventName); - throw "developer error"; - } - } - - /** - * Adds an event listener for a particular type of event. - * Currently the only eventName supported is "roomOccupant". - * @param {String} eventName the type of the event - * @param {Function} eventListener the function that expects the event. - * The eventListener gets called with the eventName as it's first argument, and the event - * data as it's second argument. - * @returns {void} - */ - this.addEventListener = function(eventName, eventListener) { - event(eventName, "addEventListener"); - if (typeof eventListener !== 'function') { - self.showError(self.errCodes.DEVELOPER_ERR, "addEventListener called with a non-function for second argument"); - throw "developer error"; - } - // - // remove the event listener if it's already present so we don't end up with two copies - // - self.removeEventListener(eventName, eventListener); - if (!eventListeners[eventName]) { - eventListeners[eventName] = []; - } - eventListeners[eventName][eventListeners[eventName].length] = eventListener; - }; - /** - * Removes an event listener. - * @param {String} eventName - * @param {Function} eventListener - */ - this.removeEventListener = function(eventName, eventListener) { - event(eventName, "removeEventListener"); - var listeners = eventListeners[eventName]; - var i = 0; - if (listeners) { - for (i = 0; i < listeners.length; i++) { - if (listeners[i] === eventListener) { - if (i < listeners.length - 1) { - listeners[i] = listeners[listeners.length - 1]; - } - listeners.length = listeners.length - 1; - } - } - } - }; - /** - * Emits an event, or in otherwords, calls all the eventListeners for a - * particular event. - * @param {String} eventName - * @param {Object} eventData - */ - this.emitEvent = function(eventName, eventData) { - event(eventName, "emitEvent"); - var listeners = eventListeners[eventName]; - var i = 0; - if (listeners) { - for (i = 0; i < listeners.length; i++) { - listeners[i](eventName, eventData); - } - } - }; - /** Error codes that the EasyRTC will use in the errorCode field of error object passed - * to error handler set by easyrtc.setOnError. The error codes are short printable strings. - * @type Object - */ - this.errCodes = { - BAD_NAME: "BAD_NAME", // a user name wasn't of the desired form - CALL_ERR: "CALL_ERR", // something went wrong creating the peer connection - DEVELOPER_ERR: "DEVELOPER_ERR", // the developer using the EasyRTC library made a mistake - SYSTEM_ERR: "SYSTEM_ERR", // probably an error related to the network - CONNECT_ERR: "CONNECT_ERR", // error occurred when trying to create a connection - MEDIA_ERR: "MEDIA_ERR", // unable to get the local media - MEDIA_WARNING: "MEDIA_WARNING", // didn't get the desired resolution - INTERNAL_ERR: "INTERNAL_ERR", - PEER_GONE: "PEER_GONE", // peer doesn't exist - ALREADY_CONNECTED: "ALREADY_CONNECTED", - BAD_CREDENTIAL: "BAD_CREDENTIAL", - ICECANDIDATE_ERR: "ICECANDIDATE_ERROR" - }; - this.apiVersion = "1.0.13"; - /** Most basic message acknowledgment object */ - this.ackMessage = {msgType: "ack"}; - /** Regular expression pattern for user ids. This will need modification to support non US character sets */ - this.usernameRegExp = /^(.){1,64}$/; - /** @private */ - var cookieId = "easyrtcsid"; - /** @private */ - var username = null; - /** @private */ - var loggingOut = false; - /** @private */ - var disconnecting = false; - // - // A map of ids to local media streams. - // - var namedLocalMediaStreams = {}; - var sessionFields = []; - var receivedMediaContraints = { - 'mandatory': { - 'OfferToReceiveAudio': true, - 'OfferToReceiveVideo': true - } - }; - /** - * Control whether the client requests audio from a peer during a call. - * Must be called before the call to have an effect. - * @param value - true to receive audio, false otherwise. The default is true. - */ - this.enableAudioReceive = function(value) { - receivedMediaContraints.mandatory.OfferToReceiveAudio = value; - }; - /** - * Control whether the client requests video from a peer during a call. - * Must be called before the call to have an effect. - * @param value - true to receive video, false otherwise. The default is true. - */ - this.enableVideoReceive = function(value) { - receivedMediaContraints.mandatory.OfferToReceiveVideo = value; - }; - - function getSourceList(callback, sourceType) { - if (MediaStreamTrack.getSources) { - MediaStreamTrack.getSources(function(sources) { - var results = []; - for (var i = 0; i < sources.length; i++) { - var source = sources[i]; - if (source.kind == sourceType) { - results.push(source); - } - } - callback(results); - }); - } - else { - callback([]); - } - } - - /** - * Gets a list of the available audio sources (ie, cameras) - * @param {Function} callback receives list of {label:String, id:String, kind:"audio"} - * Note: the label string always seems to be the empty string if you aren't using https. - * Note: not supported by Firefox. - * @example easyrtc.getAudioSourceList( function(list) { - * var i; - * for( i = 0; i < list.length; i++ ) { - * console.log("label=" + list[i].label + ", id= " + list[i].id); - * } - * }); - */ - this.getAudioSourceList = function(callback){ - getSourceList(callback, "audio"); - } - - /** - * Gets a list of the available video sources (ie, cameras) - * @param {Function} callback receives list of {facing:String, label:String, id:String, kind:"video"} - * Note: the label string always seems to be the empty string if you aren't using https. - * Note: not supported by Firefox. - * @example easyrtc.getVideoSourceList( function(list) { - * var i; - * for( i = 0; i < list.length; i++ ) { - * console.log("label=" + list[i].label + ", id= " + list[i].id); - * } - * }); - */ - this.getVideoSourceList = function(callback) { - getSourceList(callback, "video"); - } - - /** @private */ - var audioEnabled = true; - /** @private */ - var videoEnabled = true; - /** @private */ - var dataChannelName = "dc"; - /** @private */ - this.debugPrinter = null; - /** Your easyrtcid */ - this.myEasyrtcid = ""; - /** @private */ - var oldConfig = {}; - /** @private */ - var offersPending = {}; - /** @private */ - var selfRoomJoinTime = 0; - /** The height of the local media stream video in pixels. This field is set an indeterminate period - * of time after easyrtc.initMediaSource succeeds. Note: in actuality, the dimensions of a video stream - * change dynamically in response to external factors, you should check the videoWidth and videoHeight attributes - * of your video objects before you use them for pixel specific operations. - */ - this.nativeVideoHeight = 0; - /** The width of the local media stream video in pixels. This field is set an indeterminate period - * of time after easyrtc.initMediaSource succeeds. Note: in actuality, the dimensions of a video stream - * change dynamically in response to external factors, you should check the videoWidth and videoHeight attributes - * of your video objects before you use them for pixel specific operations. - */ - this.nativeVideoWidth = 0; - /** @private */ - var credential = null; - /** The rooms the user is in. This only applies to room oriented applications and is set at the same - * time a token is received. - */ - this.roomJoin = {}; - /** Checks if the supplied string is a valid user name (standard identifier rules) - * @param {String} name - * @return {Boolean} true for a valid user name - * @example - * var name = document.getElementById('nameField').value; - * if( !easyrtc.isNameValid(name)){ - * console.error("Bad user name"); - * } - */ - this.isNameValid = function(name) { - return self.usernameRegExp.test(name); - }; - /** - * This function sets the name of the cookie that client side library will look for - * and transmit back to the server as it's easyrtcsid in the first message. - * @param {String} cookieId - */ - this.setCookieId = function(cookieId) { - self.cookieId = cookieId; - }; - /** - * This method allows you to join a single room. It may be called multiple times to be in - * multiple rooms simultaneously. It may be called before or after connecting to the server. - * Note: the successCB and failureDB will only be called if you are already connected to the server. - * @param {String} roomName the room to be joined. - * @param {String} roomParameters application specific parameters, can be null. - * @param {Function} successCB called once, with a roomName as it's argument, once the room is joined. - * @param {Function} failureCB called if the room can not be joined. The arguments of failureCB are errorCode, errorText, roomName. - */ - this.joinRoom = function(roomName, roomParameters, successCB, failureCB) { - if (self.roomJoin[roomName]) { - console.error("Developer error: attempt to join room " + roomName + " which you are already in."); - return; - } - - var newRoomData = {roomName: roomName}; - if (roomParameters) { - try { - JSON.stringify(roomParameters); - } catch (error) { - self.showError(self.errCodes.DEVELOPER_ERR, "non-jsonable parameter to easyrtc.joinRoom"); - throw "Developer error, see application error messages"; - } - var parameters = {}; - for (var key in roomParameters) { - if (roomParameters.hasOwnProperty(key)) { - parameters[key] = roomParameters[key]; - } - } - newRoomData.roomParameter = parameters; - } - var msgData = { - roomJoin: {} - }; - var roomData; - var signallingSuccess, signallingFailure; - if (self.webSocket) { - - msgData.roomJoin[roomName] = newRoomData; - signallingSuccess = function(msgType, msgData) { - - roomData = msgData.roomData; - self.roomJoin[roomName] = newRoomData; - if (successCB) { - successCB(roomName); - } - - processRoomData(roomData); - }; - signallingFailure = function(errorCode, errorText) { - if (failureCB) { - failureCB(errorCode, errorText, roomName); - } - else { - self.showError(errorCode, self.format(self.getConstantString("unableToEnterRoom"), roomName, errorText)); - } - }; - sendSignalling(null, "roomJoin", msgData, signallingSuccess, signallingFailure); - } - else { - self.roomJoin[roomName] = newRoomData; - } - - }; - /** - * This function allows you to leave a single room. Note: the successCB and failureDB - * arguments are optional and will only be called if you are already connected to the server. - * @param {String} roomName - * @param {Function} successCallback - A function which expects a roomName. - * @param {Function} failureCallback - A function which expects the following arguments: errorCode, errorText, roomName. - * @example - * easyrtc.leaveRoom("freds_room"); - * easyrtc.leaveRoom("freds_room", function(roomName){ console.log("left the room")}, - * function(errorCode, errorText, roomName){ console.log("left the room")}); - */ - this.leaveRoom = function(roomName, successCallback, failureCallback) { - var roomItem; - if (self.roomJoin[roomName]) { - if (!self.webSocket) { - delete self.roomJoin[roomName]; - } - else { - roomItem = {}; - roomItem[roomName] = {roomName: roomName}; - sendSignalling(null, "roomLeave", {roomLeave: roomItem}, - function(msgType, msgData) { - var roomData = msgData.roomData; - processRoomData(roomData); - if (successCallback) { - successCallback(roomName); - } - }, - function(errorCode, errorText) { - if (failureCallback) { - failureCallback(errorCode, errorText, roomName); - } - }); - } - } - }; - /** @private */ - this._desiredVideoProperties = {}; // default camera - - - /** - * Specify particular video source. Call this before you call easyrtc.initMediaSource(). - * Note: this function isn't supported by Firefox. - * @param {String} videoSrcId is a id value from one of the entries fetched by getVideoSourceList. null for default. - * @example easyrtc.setVideoSrc( videoSrcId); - */ - this.setVideoSource = function(videoSrcId) { - self._desiredVideoProperties.videoSrcId = videoSrcId; - delete self._desiredVideoProperties.screenCapture; - }; - /** - * Temporary alias for easyrtc.setVideoSource - */ - this.setVideoSrc = this.setVideoSource; - delete this._desiredVideoProperties.screenCapture; - /** This function is used to set the dimensions of the local camera, usually to get HD. - * If called, it must be called before calling easyrtc.initMediaSource (explicitly or implicitly). - * assuming it is supported. If you don't pass any parameters, it will default to 720p dimensions. - * @param {Number} width in pixels - * @param {Number} height in pixels - * @param {number} frameRate is optional - * @example - * easyrtc.setVideoDims(1280,720); - * @example - * easyrtc.setVideoDims(); - */ - this.setVideoDims = function(width, height, frameRate) { - if (!width) { - width = 1280; - height = 720; - } - self._desiredVideoProperties.width = width; - self._desiredVideoProperties.height = height; - if (frameRate !== undefined) { - self._desiredVideoProperties.frameRate = frameRate; - } - }; - /** This function requests that screen capturing be used to provide the local media source - * rather than a webcam. If you have multiple screens, they are composited side by side. - * Note: this functionality is not supported by Firefox, has to be called before calling initMediaSource (or easyApp), we don't currently supply a way to - * turn it off (once it's on), only works if the website is hosted SSL (https), and the image quality is rather - * poor going across a network because it tries to transmit so much data. In short, screen sharing - * through WebRTC isn't worth using at this point, but it is provided here so people can try it out. - * @example - * easyrtc.setScreenCapture(); - * @deprecated: use easyrtc.initScreenCapture (same parameters as easyrtc.initMediaSource. - */ - this.setScreenCapture = function(enableScreenCapture) { - self._desiredVideoProperties.screenCapture = (enableScreenCapture !== false); - }; - /** - * Builds the constraint object passed to getUserMedia. - * @returns {Object} mediaConstraints - */ - self.getUserMediaConstraints = function() { - var constraints = {}; - // - // _presetMediaConstraints allow you to provide your own contraints to be used - // with initMediaSource. - // - if (self._presetMediaConstraints) { - constraints = self._presetMediaConstraints; - delete self._presetMediaConstraints; - return constraints; - } - else if (self._desiredVideoProperties.screenCapture) { - return { - video: { - mandatory: { - chromeMediaSource: 'screen', - maxWidth: screen.width, - maxHeight: screen.height, - minWidth: screen.width, - minHeight: screen.height, - minFrameRate: 1, - maxFrameRate: 5}, - optional: [] - }, - audio: false - }; - } - else if (!videoEnabled) { - constraints.video = false; - } - else { - constraints.video = {mandatory: {}, optional: []}; - if (self._desiredVideoProperties.width) { - constraints.video.mandatory.maxWidth = self._desiredVideoProperties.width; - constraints.video.mandatory.minWidth = self._desiredVideoProperties.width; - } - if (self._desiredVideoProperties.width) { - constraints.video.mandatory.maxHeight = self._desiredVideoProperties.height; - constraints.video.mandatory.minHeight = self._desiredVideoProperties.height; - } - if (self._desiredVideoProperties.frameRate) { - constraints.video.mandatory.maxFrameRate = self._desiredVideoProperties.frameRate; - } - if (self._desiredVideoProperties.videoSrcId) { - constraints.video.optional.push({sourceId: self._desiredVideoProperties.videoSrcId}); - } - // hack for opera - if (constraints.video.mandatory.length === 0 && constraints.video.optional.length === 0) { - constraints.video = true; - } - } - constraints.audio = audioEnabled; - return constraints; - }; - /** Set the application name. Applications can only communicate with other applications - * that share the same API Key and application name. There is no predefined set of application - * names. Maximum length is - * @param {String} name - * @example - * easyrtc.setApplicationName('simpleAudioVideo'); - */ - this.setApplicationName = function(name) { - self.applicationName = name; - }; - /** Enable or disable logging to the console. - * Note: if you want to control the printing of debug messages, override the - * easyrtc.debugPrinter variable with a function that takes a message string as it's argument. - * This is exactly what easyrtc.enableDebug does when it's enable argument is true. - * @param {Boolean} enable - true to turn on debugging, false to turn off debugging. Default is false. - * @example - * easyrtc.enableDebug(true); - */ - this.enableDebug = function(enable) { - if (enable) { - self.debugPrinter = function(message) { - var stackString = new Error().stack; - var srcLine = "location unknown"; - if (stackString) { - var stackFrameStrings = stackString.split('\n'); - srcLine = ""; - if (stackFrameStrings.length >= 3) { - srcLine = stackFrameStrings[2]; - } - } - console.log("debug " + (new Date()).toISOString() + " : " + message + " [" + srcLine + "]"); - }; - } - else { - self.debugPrinter = null; - } - }; -// -// this is a temporary version used until we connect to the server. -// - this.updatePresence = function(state, statusText) { - self.presenceShow = state; - self.presenceStatus = statusText; - }; - /** - * Determines if the local browser supports WebRTC GetUserMedia (access to camera and microphone). - * @returns {Boolean} True getUserMedia is supported. - */ - this.supportsGetUserMedia = function() { - return !!getUserMedia; - }; - /** - * Determines if the local browser supports WebRTC Peer connections to the extent of being able to do video chats. - * @returns {Boolean} True if Peer connections are supported. - */ - this.supportsPeerConnections = function() { - if (!self.supportsGetUserMedia()) { - return false; - } - if (!window.RTCPeerConnection) { - return false; - } - try { - self.createRTCPeerConnection({"iceServers": []}, null); - } catch (oops) { - return false; - } - return true; - }; - /** @private - * @param pc_config ice configuration array - * @param optionalStuff peer constraints. - */ - /** @private - * @param pc_config ice configuration array - * @param optionalStuff peer constraints. - */ - this.createRTCPeerConnection = function(pc_config, optionalStuff) { - if (RTCPeerConnection) { - return new RTCPeerConnection(pc_config, optionalStuff); - } - else { - throw "Your browser doesn't support webRTC (RTCPeerConnection)"; - } - }; -// -// this should really be part of adapter.js -// Versions of chrome < 31 don't support reliable data channels transport. -// Firefox does. -// - this.getDatachannelConstraints = function() { - if (webrtcDetectedBrowser === "chrome" && webrtcDetectedVersion < 31) { - return {reliable: false}; - } - else { - return {reliable: true}; - } - }; - /** @private */ - haveAudioVideo = { - audio: false, - video: false - }; - /** @private */ - var dataEnabled = false; - /** @private */ - var serverPath = null; - /** @private */ - var roomOccupantListener = null; - /** @private */ - var onDataChannelOpen = null; - /** @private */ - var onDataChannelClose = null; - /** @private */ - var lastLoggedInList = {}; - /** @private */ - var receivePeer = {msgTypes: {}}; - /** @private */ - var receiveServerCB = null; - /** @private */ - var updateConfigurationInfo = function() { - - }; // dummy placeholder for when we aren't connected -// -// -// peerConns is a map from caller names to the below object structure -// { startedAV: boolean, -- true if we have traded audio/video streams -// dataChannelS: RTPDataChannel for outgoing messages if present -// dataChannelR: RTPDataChannel for incoming messages if present -// dataChannelReady: true if the data channel can be used for sending yet -// connectTime: timestamp when the connection was started -// sharingAudio: true if audio is being shared -// sharingVideo: true if video is being shared -// cancelled: temporarily true if a connection was cancelled by the peer asking to initiate it -// candidatesToSend: SDP candidates temporarily queued -// streamsAddedAcks: ack callbacks waiting for stream received messages -// pc: RTCPeerConnection -// mediaStream: mediaStream -// function callSuccessCB(string) - see the easyrtc.call documentation. -// function callFailureCB(errorCode, string) - see the easyrtc.call documentation. -// function wasAcceptedCB(boolean,string) - see the easyrtc.call documentation. -// } -// - /** @private */ - var peerConns = {}; -// -// a map keeping track of whom we've requested a call with so we don't try to -// call them a second time before they've responded. -// - /** @private */ - var acceptancePending = {}; - /** - * Disconnect from the EasyRTC server. - * @example - * easyrtc.disconnect(); - */ - this.disconnect = function() { - }; - /** @private - * @param caller - * @param helper - */ - this.acceptCheck = function(caller, helper) { - helper(true); - }; - /** @private - * @param easyrtcid - * @param stream - */ - this.streamAcceptor = function(easyrtcid, stream) { - }; - /** @private - * @param easyrtcid - */ - this.onStreamClosed = function(easyrtcid) { - }; - /** @private - * @param easyrtcid - */ - this.callCancelled = function(easyrtcid) { - }; - /** - * This function gets the statistics for a particular peer connection. - * @param {String} peerId - * @param {Function} callback gets the peerid and a map of {userDefinedKey: value}. If there is no peer connection to peerId, then the map will - * have a value of {connected:false}. - * @param {Object} filter depends on whether Chrome or Firefox is used. See the default filters for guidance. - * It is still experimental. - */ - this.getPeerStatistics = function(peerId, callback, filter) { - if (isFirefox) { - self.getFirefoxPeerStatistics(peerId, callback, filter); - } - else { - self.getChromePeerStatistics(peerId, callback, filter); - } - }; - this.getFirefoxPeerStatistics = function(peerId, callback, filter) { - - - if (!peerConns[peerId]) { - callback(peerId, {"connected": false}); - } - else if (peerConns[peerId].pc.getStats) { - peerConns[peerId].pc.getStats(null, function(stats) { - var items = {}; - var candidates = {}; - var activeId = null; - var srcKey; - // - // the stats objects has a group of entries. Each entry is either an rtcp, rtp entry - // or a candidate entry. - // - stats.forEach(function(entry) { - var majorKey; - var subKey; - if (entry.type.match(/boundrtp/)) { - if (entry.id.match(/audio/)) { - majorKey = entry.type + "_audio"; - } - else if (entry.id.match(/video/)) { - majorKey = entry.type + "_video"; - } - else { - return; - } - for (subKey in entry) { - if (entry.hasOwnProperty(subKey)) { - items[majorKey + "." + subKey] = entry[subKey]; - } - } - } - else { - if( entry.hasOwnProperty("ipAddress") && entry.hasOwnProperty("id")) { - candidates[entry.id] = entry.ipAddress + ":" + - entry.portNumber; - } - else if( entry.hasOwnProperty("selected") && - entry.hasOwnProperty("remoteCandidateId") && - entry.selected ) { - activeId = entry.remoteCandidateId; - } - } - }); - - if( activeId ) { - items["firefoxRemoteAddress"] = candidates[activeId]; - } - if (!filter) { - callback(peerId, items); - } - else { - var filteredItems = {}; - for (srcKey in filter) { - if (filter.hasOwnProperty(srcKey) && items.hasOwnProperty(srcKey)) { - filteredItems[ filter[srcKey]] = items[srcKey]; - } - } - callback(peerId, filteredItems); - } - }, - function(error) { - console.log("unable to get statistics"); - }); - } - else { - callback(peerId, {"statistics": self.getConstantString("statsNotSupported")}); - } - }; - this.getChromePeerStatistics = function(peerId, callback, filter) { - - if (!peerConns[peerId]) { - callback(peerId, {"connected": false}); - } - else if (peerConns[peerId].pc.getStats) { - - peerConns[peerId].pc.getStats(function(stats) { - - var localStats = {}; - var part, parts = stats.result(); - var i, j; - var itemKeys; - var itemKey; - var names; - var userKey; - var partNames = []; - var partList; - var bestBytes = 0; - var bestI; - var turnAddress = null; - var hasActive, curReceived; - var localAddress, remoteAddress; - if (!filter) { - for (i = 0; i < parts.length; i++) { - names = parts[i].names(); - for (j = 0; j < names.length; j++) { - itemKey = names[j]; - localStats[parts[i].id + "." + itemKey] = parts[i].local.stat(itemKey); - } - } - } - else { - for (i = 0; i < parts.length; i++) { - partNames[i] = {}; - // - // convert the names into a dictionary - // - names = parts[i].names(); - for (j = 0; j < names.length; j++) { - partNames[i][names[j]] = true; - } - - // - // a chrome-firefox connection results in several activeConnections. - // we only want one, so we look for the one with the most data being received on it. - // - if (partNames[i].googRemoteAddress && partNames[i].googActiveConnection) { - hasActive = parts[i].local.stat("googActiveConnection"); - if (hasActive === true || hasActive === "true") { - curReceived = parseInt(parts[i].local.stat("bytesReceived")) + - parseInt(parts[i].local.stat("bytesSent")); - if (curReceived > bestBytes) { - bestI = i; - bestBytes = curReceived; - } - } - } - } - - for (i = 0; i < parts.length; i++) { - // - // discard info from any inactive connection. - // - if (partNames[i].googActiveConnection) { - if (i !== bestI) { - partNames[i] = {}; - } - else { - localAddress = parts[i].local.stat("googLocalAddress").split(":")[0]; - remoteAddress = parts[i].local.stat("googRemoteAddress").split(":")[0]; - if (self.isTurnServer(localAddress)) { - turnAddress = localAddress; - } - else if (self.isTurnServer(remoteAddress)) { - turnAddress = remoteAddress; - } - } - } - } - - for (i = 0; i < filter.length; i++) { - itemKeys = filter[i]; - partList = []; - part = null; - for (j = 0; j < parts.length; j++) { - var fullMatch = true; - for (itemKey in itemKeys) { - if (itemKeys.hasOwnProperty(itemKey) && !partNames[j][itemKey]) { - fullMatch = false; - break; - } - } - if (fullMatch && parts[j]) { - partList.push(parts[j]); - } - } - if (partList.length === 1) { - for (j = 0; j < partList.length; j++) { - part = partList[j]; - if (part.local) { - for (itemKey in itemKeys) { - if (itemKeys.hasOwnProperty(itemKey)) { - userKey = itemKeys[itemKey]; - localStats[userKey] = part.local.stat(itemKey); - } - } - } - } - } - else if (partList.length > 1) { - for (itemKey in itemKeys) { - if (itemKeys.hasOwnProperty(itemKey)) { - localStats[itemKeys[itemKey]] = []; - } - } - for (j = 0; j < partList.length; j++) { - part = partList[j]; - if (part.local) { - for (itemKey in itemKeys) { - if (itemKeys.hasOwnProperty(itemKey)) { - userKey = itemKeys[itemKey]; - localStats[userKey].push(part.local.stat(itemKey)); - } - } - } - } - } - } - } - - if (localStats.remoteAddress && turnAddress) { - localStats.remoteAddress = turnAddress; - } - callback(peerId, localStats); - }); - } - else { - callback(peerId, {"statistics": self.getConstantString("statsNotSupported")}); - } - }; - this.chromeStatsFilter = [ - { - "googTransmitBitrate": "transmitBitRate", - "googActualEncBitrate": "encodeRate", - "googAvailableSendBandwidth": "availableSendRate" - }, - { - "googCodecName": "audioCodec", - "googTypingNoiseState": "typingNoise", - "packetsSent": "audioPacketsSent", - "bytesSent": "audioBytesSent" - }, - { - "googCodecName": "videoCodec", - "googFrameRateSent": "outFrameRate", - "packetsSent": "videoPacketsSent", - "bytesSent": "videoBytesSent" - }, - { - "packetsLost": "videoPacketsLost", - "packetsReceived": "videoPacketsReceived", - "bytesReceived": "videoBytesReceived", - "googFrameRateOutput": "frameRateOut" - }, - { - "packetsLost": "audioPacketsLost", - "packetsReceived": "audioPacketsReceived", - "bytesReceived": "audioBytesReceived", - "audioOutputLevel": "audioOutputLevel" - }, - { - "googRemoteAddress": "remoteAddress", - "googActiveConnection": "activeConnection" - }, - { - "audioInputLevel": "audioInputLevel" - } - ]; - this.firefoxStatsFilter = { - "outboundrtp_audio.bytesSent": "audioBytesSent", - "outboundrtp_video.bytesSent": "videoBytesSent", - "inboundrtp_video.bytesReceived": "videoBytesReceived", - "inboundrtp_audio.bytesReceived": "audioBytesReceived", - "outboundrtp_audio.packetsSent": "audioPacketsSent", - "outboundrtp_video.packetsSent": "videoPacketsSent", - "inboundrtp_video.packetsReceived": "videoPacketsReceived", - "inboundrtp_audio.packetsReceived": "audioPacketsReceived", - "inboundrtp_video.packetsLost": "videoPacketsLost", - "inboundrtp_audio.packetsLost": "audioPacketsLost", - "firefoxRemoteAddress": "remoteAddress" - }; - this.standardStatsFilter = isFirefox ? self.firefoxStatsFilter : self.chromeStatsFilter; - /** Provide a set of application defined fields that will be part of this instances - * configuration information. This data will get sent to other peers via the websocket - * path. - * @param {String} roomName - the room the field is attached to. - * @param {String} fieldName - the name of the field. - * @param {Object} fieldValue - the value of the field. - * @example - * easyrtc.setRoomApiField("trekkieRoom", "favorite_alien", "Mr Spock"); - * easyrtc.setRoomOccupantListener( function(roomName, list){ - * for( var i in list ){ - * console.log("easyrtcid=" + i + " favorite alien is " + list[i].apiFields.favorite_alien); - * } - * }); - */ - this.setRoomApiField = function(roomName, fieldName, fieldValue) { - // - // if we're not connected yet, we'll just cache the fields until we are. - // - if (!self._roomApiFields) { - self._roomApiFields = {}; - } - if (!fieldName && !fieldValue) { - delete self._roomApiFields[roomName]; - return; - } - - if (!self._roomApiFields[roomName]) { - self._roomApiFields[roomName] = {}; - } - if (fieldValue !== undefined && fieldValue !== null) { - if (typeof fieldValue === "object") { - try { - JSON.stringify(fieldValue); - } - catch (jsonError) { - self.showError(self.errCodes.DEVELOPER_ERR, "easyrtc.setRoomApiField passed bad object "); - return; - } - } - self._roomApiFields[roomName][fieldName] = {fieldName: fieldName, fieldValue: fieldValue}; - } - else { - delete self._roomApiFields[roomName][fieldName]; - } - if (self.webSocketConnected) { - _enqueueSendRoomApi(roomName); - } - }; - var roomApiFieldTimer = null; - /** @private - * @param {String} roomName - */ - function _enqueueSendRoomApi(roomName) { -// -// Rather than issue the send request immediately, we set a timer so we can accumulate other -// calls -// - if (roomApiFieldTimer) { - clearTimeout(roomApiFieldTimer); - } - roomApiFieldTimer = setTimeout(function() { - _sendRoomApiFields(roomName, self._roomApiFields[roomName]); - roomApiFieldTimer = null; - }, 10); - } - ; - /** - * @private - * @param roomName - * @param fields - */ - function _sendRoomApiFields(roomName, fields) { - var fieldAsString = JSON.stringify(fields); - JSON.parse(fieldAsString); - var dataToShip = { - msgType: "setRoomApiField", - msgData: { - setRoomApiField: { - roomName: roomName, - field: fields - } - } - }; - self.webSocket.json.emit("easyrtcCmd", dataToShip, - function(ackMsg) { - if (ackMsg.msgType === "error") { - self.showError(ackMsg.msgData.errorCode, ackMsg.msgData.errorText); - } - } - ); - } - ; - /** Default error reporting function. The default implementation displays error messages - * in a programmatically created div with the id easyrtcErrorDialog. The div has title - * component with a class name of easyrtcErrorDialog_title. The error messages get added to a - * container with the id easyrtcErrorDialog_body. Each error message is a text node inside a div - * with a class of easyrtcErrorDialog_element. There is an "okay" button with the className of easyrtcErrorDialog_okayButton. - * @param {String} messageCode An error message code - * @param {String} message the error message text without any markup. - * @example - * easyrtc.showError("BAD_NAME", "Invalid username"); - */ - this.showError = function(messageCode, message) { - self.onError({errorCode: messageCode, errorText: message}); - }; - /** @private - * @param errorObject - */ - this.onError = function(errorObject) { - if (self.debugPrinter) { - self.debugPrinter("saw error " + errorObject.errorText); - } - var errorDiv = document.getElementById('easyrtcErrorDialog'); - var errorBody; - if (!errorDiv) { - errorDiv = document.createElement("div"); - errorDiv.id = 'easyrtcErrorDialog'; - var title = document.createElement("div"); - title.innerHTML = "Error messages"; - title.className = "easyrtcErrorDialog_title"; - errorDiv.appendChild(title); - errorBody = document.createElement("div"); - errorBody.id = "easyrtcErrorDialog_body"; - errorDiv.appendChild(errorBody); - var clearButton = document.createElement("button"); - clearButton.appendChild(document.createTextNode("Okay")); - clearButton.className = "easyrtcErrorDialog_okayButton"; - clearButton.onclick = function() { - errorBody.innerHTML = ""; // remove all inner nodes - errorDiv.style.display = "none"; - }; - errorDiv.appendChild(clearButton); - document.body.appendChild(errorDiv); - } - - errorBody = document.getElementById("easyrtcErrorDialog_body"); - var messageNode = document.createElement("div"); - messageNode.className = 'easyrtcErrorDialog_element'; - messageNode.appendChild(document.createTextNode(errorObject.errorText)); - errorBody.appendChild(messageNode); - errorDiv.style.display = "block"; - }; -// -// easyrtc.createObjectURL builds a URL from a media stream. -// Arguments: -// mediaStream - a media stream object. -// The video object in Chrome expects a URL. -// - /** @private - * @param mediaStream */ - this.createObjectURL = function(mediaStream) { - var errMessage; - if (window.URL && window.URL.createObjectURL) { - return window.URL.createObjectURL(mediaStream); - } - else if (window.webkitURL && window.webkitURL.createObjectURL) { - return window.webkit.createObjectURL(mediaStream); - } - else { - errMessage = "Your browsers does not support URL.createObjectURL."; - if (self.debugPrinter) { - self.debugPrinter("saw exception " + errMessage); - } - throw errMessage; - } - }; - /** - * A convenience function to ensure that a string doesn't have symbols that will be interpreted by HTML. - * @param {String} idString - * @return {String} The cleaned string. - * @example - * console.log( easyrtc.cleanId('&hello')); - */ - this.cleanId = function(idString) { - var MAP = { - '&': '&', - '<': '<', - '>': '>' - }; - return idString.replace(/[&<>]/g, function(c) { - return MAP[c]; - }); - }; - /** Set a callback that will be invoked when the application enters or leaves a room. - * - * @param {Function} handler - the first parameter is true for entering a room, false for leaving a room. The second parameter is the room name. - * @example - * easyrtc.setRoomEntryListener(function(entry, roomName){ - * if( entry ){ - * console.log("entering room " + roomName); - * } - * else{ - * console.log("leaving room " + roomName); - * } - * }); - */ - self.setRoomEntryListener = function(handler) { - self.roomEntryListener = handler; - }; - /** Set the callback that will be invoked when the list of people logged in changes. - * The callback expects to receive a room name argument, and - * a map whose ideas are easyrtcids and whose values are in turn maps - * supplying user specific information. The inner maps have the following keys: - * username, applicationName, browserFamily, browserMajor, osFamily, osMajor, deviceFamily. - * The third argument is the listener is the innerMap for the connections own data (not needed by most applications). - * @param {Function} listener - * @example - * easyrtc.setRoomOccupantListener( function(roomName, list, selfInfo){ - * for( var i in list ){ - * ("easyrtcid=" + i + " belongs to user " + list[i].username); - * } - * }); - */ - self.setRoomOccupantListener = function(listener) { - roomOccupantListener = listener; - }; - /** - * Sets a callback that is called when a data channel is open and ready to send data. - * The callback will be called with an easyrtcid as it's sole argument. - * @param {Function} listener - * @example - * easyrtc.setDataChannelOpenListener( function(easyrtcid){ - * easyrtc.sendDataP2P(easyrtcid, "greeting", "hello"); - * }); - */ - this.setDataChannelOpenListener = function(listener) { - onDataChannelOpen = listener; - }; - /** Sets a callback that is called when a previously open data channel closes. - * The callback will be called with an easyrtcid as it's sole argument. - * @param {Function} listener - * @example - * easyrtc.setDataChannelCloseListener( function(easyrtcid){ - * ("No longer connected to " + easyrtc.idToName(easyrtcid)); - * }); - */ - this.setDataChannelCloseListener = function(listener) { - onDataChannelClose = listener; - }; - /** Returns the number of live peer connections the client has. - * @return {Number} - * @example - * ("You have " + easyrtc.getConnectionCount() + " peer connections"); - */ - this.getConnectionCount = function() { - var count = 0; - var i; - for (i in peerConns) { - if (peerConns.hasOwnProperty(i)) { - if (self.getConnectStatus(i) === self.IS_CONNECTED) { - count++; - } - } - } - return count; - }; - /** Sets whether audio is transmitted by the local user in any subsequent calls. - * @param {Boolean} enabled true to include audio, false to exclude audio. The default is true. - * @example - * easyrtc.enableAudio(false); - */ - this.enableAudio = function(enabled) { - audioEnabled = enabled; - }; - /** - *Sets whether video is transmitted by the local user in any subsequent calls. - * @param {Boolean} enabled - true to include video, false to exclude video. The default is true. - * @example - * easyrtc.enableVideo(false); - */ - this.enableVideo = function(enabled) { - videoEnabled = enabled; - }; - /** - * Sets whether WebRTC data channels are used to send inter-client messages. - * This is only the messages that applications explicitly send to other applications, not the WebRTC signaling messages. - * @param {Boolean} enabled true to use data channels, false otherwise. The default is false. - * @example - * easyrtc.enableDataChannels(true); - */ - this.enableDataChannels = function(enabled) { - dataEnabled = enabled; - }; - /** - * @private - * @param {Boolean} enable - * @param {Array} tracks - an array of MediaStreamTrack - */ - function enableMediaTracks(enable, tracks) { - var i; - if (tracks) { - for (i = 0; i < tracks.length; i++) { - var track = tracks[i]; - track.enabled = enable; - } - } - } - - - // - // fetches a stream by name. Treat a null/undefined streamName as "default". - // - function getLocalMediaStreamByName(streamName) { - if (!streamName) { - streamName = "default"; - } - if (namedLocalMediaStreams.hasOwnProperty(streamName)) { - return namedLocalMediaStreams[streamName]; - } - else { - return null; - } - } - - /** - * Returns the user assigned id's of currently active local media streams. - * @return {Array} - */ - this.getLocalMediaIds = function() { - return Object.keys(namedLocalMediaStreams); - } - - function buildMediaIds() { - var mediaMap = {}; - var streamName; - for (streamName in namedLocalMediaStreams) { - mediaMap[streamName] = namedLocalMediaStreams[streamName].id || "default"; - } - return mediaMap; - } - - - function registerLocalMediaStreamByName(stream, streamName) { - var roomName; - if (!streamName) { - streamName = "default"; - } - stream.streamName = streamName; - namedLocalMediaStreams[streamName] = stream; - if (streamName !== "default") { - var mediaIds = buildMediaIds(); - for (roomName in self.roomData) { - self.setRoomApiField(roomName, "mediaIds", mediaIds); - } - } - } - - /** - * Allow an externally created mediastream (ie, created by another - * library) to be used within easyrtc. Tracking when it closes - * must be done by the supplying party. - */ - this.register3rdPartyLocalMediaStream = function(stream, streamName) { - return registerLocalMediaStreamByName(stream, streamName); - }; - // - // look up a stream's name from the stream.id - // - function getNameOfRemoteStream(easyrtcId, webrtcstreamId) { - var roomName; - var mediaIds; - var streamName; - if (!webrtcstreamId) { - webrtcstreamId = "default"; - } - if (peerConns[easyrtcId]) { - streamName = peerConns[easyrtcId].remoteStreamIdToName[webrtcstreamId]; - if (streamName) { - return streamName; - } - } - - for (roomName in self.roomData) { - mediaIds = self.getRoomApiField(roomName, easyrtcId, "mediaIds"); - if (!mediaIds) { - continue; - } - for (streamName in mediaIds) { - if (mediaIds.hasOwnProperty(streamName) && - mediaIds[streamName] === webrtcstreamId) { - return streamName; - } - } - // - // a stream from chrome to firefox will be missing it's id/label. - // there is no correct solution. - // - if( isFirefox ) { - // if there is a stream called default, return it in preference - if( mediaIds["default"] ) { - return "default"; - } - // - // otherwise return the first name we find. If there is more than - // one, complain to Mozilla. - // - for( var anyName in mediaIds ) { - return anyName; - } - } - } - return undefined; - } - - this.getNameOfRemoteStream = function(easyrtcId, webrtcStream){ - if(typeof webrtcStream == "string") { - return getNameOfRemoteStream(easyrtcId, webrtcStream); - } - else if( webrtcStream.id) { - return getNameOfRemoteStream(easyrtcId, webrtcStream.id); - } - } - - function closeLocalMediaStreamByName(streamName) { - if (!streamName) { - streamName = "default"; - } - var stream = self.getLocalStream(streamName); - if (!stream) { - return; - } - var streamId = stream.id || "default"; - if (namedLocalMediaStreams[streamName]) { - - - for (id in peerConns) { - if (peerConns.hasOwnProperty(id)) { - try { - peerConns[id].pc.removeStream(stream); - } catch (err) { - } - self.sendPeerMessage(id, "__closingMediaStream", {streamId: streamId, streamName: streamName}); - } - } - try { - namedLocalMediaStreams[streamName].stop(); - } catch (err) { - // not worth reporting an error at this location - // since we didn't want the media stream anyhow. - } - delete namedLocalMediaStreams[streamName]; - if (streamName !== "default") { - var mediaIds = buildMediaIds(); - for (roomName in self.roomData) { - self.setRoomApiField(roomName, "mediaIds", mediaIds); - } - } - } - } - /** - * Close the local media stream. You usually need to close the existing media stream - * of a camera before reacquring it at a different resolution. - * @param {String} streamName - an option stream name. - */ - this.closeLocalMediaStream = function(streamName) { - return closeLocalMediaStreamByName(streamName); - } - - /** - * Alias for closeLocalMediaStream - */ - this.closeLocalStream = this.closeLocalMediaStream; - /** - * This function is used to enable and disable the local camera. If you disable the - * camera, video objects display it will "freeze" until the camera is re-enabled. * - * By default, a camera is enabled. - * @param {Boolean} enable - true to enable the camera, false to disable it. - * @param {String} streamName - the name of the stream, optional. - */ - this.enableCamera = function(enable, streamName) { - var stream = getLocalMediaStreamByName(streamName); - if (stream && stream.getVideoTracks) { - enableMediaTracks(enable, stream.getVideoTracks()); - } - }; - /** - * This function is used to enable and disable the local microphone. If you disable - * the microphone, sounds stops being transmitted to your peers. By default, the microphone - * is enabled. - * @param {Boolean} enable - true to enable the microphone, false to disable it. - * @param {String} streamName - an optional streamName - */ - this.enableMicrophone = function(enable, streamName) { - var stream = getLocalMediaStreamByName(streamName); - if (stream && stream.getAudioTracks) { - enableMediaTracks(enable, stream.getAudioTracks()); - } - }; - /** - * Mute a video object. - * @param {String} videoObjectName - A DOMObject or the id of the DOMObject. - * @param {Boolean} mute - true to mute the video object, false to unmute it. - */ - self.muteVideoObject = function(videoObjectName, mute) { - var videoObject; - if (typeof (videoObjectName) === 'string') { - videoObject = document.getElementById(videoObjectName); - if (!videoObject) { - throw "Unknown video object " + videoObjectName; - } - } - else if (!videoObjectName) { - throw "muteVideoObject passed a null"; - } - else { - videoObject = videoObjectName; - } - videoObject.muted = !!mute; - }; - /** - * Returns a URL for your local camera and microphone. - * It can be called only after easyrtc.initMediaSource has succeeded. - * It returns a url that can be used as a source by the Chrome video element or the <canvas> element. - * @param {String} streamName - an option stream name. - * @return {URL} - * @example - * document.getElementById("myVideo").src = easyrtc.getLocalStreamAsUrl(); - */ - self.getLocalStreamAsUrl = function(streamName) { - var stream = getLocalMediaStreamByName(streamName); - if (stream === null) { - throw "Developer error: attempt to get a MediaStream without invoking easyrtc.initMediaSource successfully"; - } - return self.createObjectURL(stream); - }; - /** - * Returns a media stream for your local camera and microphone. - * It can be called only after easyrtc.initMediaSource has succeeded. - * It returns a stream that can be used as an argument to easyrtc.setVideoObjectSrc. - * Returns null if there is no local media stream acquired yet. - * @return {MediaStream} - * @example - * easyrtc.setVideoObjectSrc( document.getElementById("myVideo"), easyrtc.getLocalStream()); - */ - this.getLocalStream = function(streamName) { - return getLocalMediaStreamByName(streamName) || null; - }; - /** Clears the media stream on a video object. - * - * @param {Object} element the video object. - * @example - * easyrtc.clearMediaStream( document.getElementById('selfVideo')); - * - */ - this.clearMediaStream = function(element) { - if (typeof element.srcObject !== 'undefined') { - element.srcObject = null; - } else if (typeof element.mozSrcObject !== 'undefined') { - element.mozSrcObject = null; - } else if (typeof element.src !== 'undefined') { - //noinspection JSUndefinedPropertyAssignment - element.src = ""; - } - }; - /** - * Sets a video or audio object from a media stream. - * Chrome uses the src attribute and expects a URL, while firefox - * uses the mozSrcObject and expects a stream. This procedure hides - * that from you. - * If the media stream is from a local webcam, you may want to add the - * easyrtcMirror class to the video object so it looks like a proper mirror. - * The easyrtcMirror class is defined in this.css. - * Which is could be added using the same path of easyrtc.js file to an HTML file - * @param {Object} videoObject an HTML5 video object - * @param {MediaStream|String} stream a media stream as returned by easyrtc.getLocalStream or your stream acceptor. - * @example - * easyrtc.setVideoObjectSrc( document.getElementById("myVideo"), easyrtc.getLocalStream()); - * - */ - this.setVideoObjectSrc = function(videoObject, stream) { - if (stream && stream !== "") { - videoObject.autoplay = true; - attachMediaStream(videoObject, stream); - videoObject.play(); - } - else { - self.clearMediaStream(videoObject); - } - }; - - - /** - * This function builds a new named local media stream from a set of existing audio and video tracks from other media streams. - * @param {String} streamName is the name of the new media stream. - * @param {Array} audioTracks is an array of MediaStreamTracks - * @param {Array} videoTracks is an array of MediaStreamTracks - * @returns {MediaStream} the track created. - * @example - * easyrtc.buildLocalMediaStream("myComposedStream", - * easyrtc.getLocalStream("camera1").getVideoTracks(), - * easyrtc.getLocalStream("camera2").getAudioTracks()); - */ - this.buildLocalMediaStream = function(streamName, audioTracks, videoTracks) { - var i; - if (typeof streamName !== 'string') { - easyrtc.showError(this.errCodes.DEVELOPER_ERR, - "easyrtc.buildLocalMediaStream not supplied a stream name"); - return null; - } - - var streamToClone = null; - for(var key in namedLocalMediaStreams ) { - if( namedLocalMediaStreams.hasOwnProperty(key)) { - streamToClone = namedLocalMediaStreams[key]; - if(streamToClone) break; - } - } - if( !streamToClone ) { - for(key in peerConns) { - var remoteStreams = peerConns[key].pc.getRemoteStreams(); - if( remoteStreams && remoteStreams.length > 1 ) { - streamToClone = remoteStreams[0]; - } - } - } - if( !streamToClone ){ - self.showError(self.errCodes.DEVELOPER_ERR, - "Attempt to create a mediastream without one to clone from"); - return null; - } - - // - // clone whatever mediastream we found, and remove any of it's - // tracks. - // - var mediaClone = streamToClone.clone(); - var i; - var oldTracks = mediaClone.getTracks(); - - if (audioTracks) { - for (i = 0; i < audioTracks.length; i++) { - mediaClone.addTrack(audioTracks[i].clone()); - } - } - - if (videoTracks) { - for (i = 0; i < videoTracks.length; i++) { - mediaClone.addTrack(videoTracks[i].clone()); - } - } - - for( i = 0; i < oldTracks.length; i++ ) { - mediaClone.removeTrack(oldTracks[i]); - } - - registerLocalMediaStreamByName(mediaClone, streamName); - return mediaClone; - }; - - /* @private*/ - /** Load Easyrtc Stylesheet. - * Easyrtc Stylesheet define easyrtcMirror class and some basic css class for using easyrtc.js. - * That way, developers can override it or use it's own css file minified css or package. - * @example - * easyrtc.loadStylesheet(); - * - */ - this.loadStylesheet = function() { - - // - // check to see if we already have an easyrtc.css file loaded - // if we do, we can exit immediately. - // - var links = document.getElementsByTagName("link"); - var cssIndex, css; - for (cssIndex in links) { - if (links.hasOwnProperty(cssIndex)) { - css = links[cssIndex]; - if (css.href && (css.href.match(/\/easyrtc.css/))) { - return; - } - } - } - // - // add the easyrtc.css file since it isn't present - // - var easySheet = document.createElement("link"); - easySheet.setAttribute("rel", "stylesheet"); - easySheet.setAttribute("type", "text/css"); - easySheet.setAttribute("href", "/easyrtc/easyrtc.css"); - var headSection = document.getElementsByTagName("head")[0]; - var firstHead = headSection.childNodes[0]; - headSection.insertBefore(easySheet, firstHead); - }; - /** @private - * @param {String} x */ - this.formatError = function(x) { - var name, result; - if (x === null || typeof x === 'undefined') { - return "null"; - } - if (typeof x === 'string') { - return x; - } - else if (x.type && x.description) { - return x.type + " : " + x.description; - } - else if (typeof x === 'object') { - try { - return JSON.stringify(x); - } - catch (oops) { - result = "{"; - for (name in x) { - if (x.hasOwnProperty(name)) { - if (typeof x[name] === 'string') { - result = result + name + "='" + x[name] + "' "; - } - } - } - result = result + "}"; - return result; - } - } - else { - return "Strange case"; - } - }; - /** Initializes your access to a local camera and microphone. - * Failure could be caused a browser that didn't support WebRTC, or by the user - * not granting permission. - * If you are going to call easyrtc.enableAudio or easyrtc.enableVideo, you need to do it before - * calling easyrtc.initMediaSource. - * @param {function(Object)} successCallback - will be called with localmedia stream on success. - * @param {function(String,String)} errorCallback - is called with an error code and error description. - * @param {String} streamName - an optional name for the media source so you can use multiple cameras and screen share simultaneously. - * @example - * easyrtc.initMediaSource( - * function(mediastream){ - * easyrtc.setVideoObjectSrc( document.getElementById("mirrorVideo"), mediastream); - * }, - * function(errorCode, errorText){ - * easyrtc.showError(errorCode, errorText); - * }); - * - */ - this.initMediaSource = function(successCallback, errorCallback, streamName) { - - if (self.debugPrinter) { - self.debugPrinter("about to request local media"); - } - - if (!streamName) { - streamName = "default"; - } - - haveAudioVideo = { - audio: audioEnabled, - video: videoEnabled - }; - if (!errorCallback) { - errorCallback = function(errorCode, errorText) { - var message = "easyrtc.initMediaSource: " + self.formatError(errorText); - if (self.debugPrinter) { - self.debugPrinter(message); - } - self.showError(self.errCodes.MEDIA_ERR, message); - }; - } - - if (!self.supportsGetUserMedia()) { - errorCallback(self.errCodes.MEDIA_ERR, self.getConstantString("noWebrtcSupport")); - return; - } - - - if (!successCallback) { - self.showError(self.errCodes.DEVELOPER_ERR, - "easyrtc.initMediaSource not supplied a successCallback"); - return; - } - - - var mode = self.getUserMediaConstraints(); - /** @private - * @param {Object} stream - A mediaStream object. - * */ - var onUserMediaSuccess = function(stream) { - if (self.debugPrinter) { - self.debugPrinter("getUserMedia success callback entered"); - } - - if (self.debugPrinter) { - self.debugPrinter("successfully got local media"); - } - - stream.streamName = streamName; - registerLocalMediaStreamByName(stream, streamName); - var videoObj, triesLeft, tryToGetSize, ele; - if (haveAudioVideo.video) { - videoObj = document.createElement('video'); - videoObj.muted = true; - triesLeft = 30; - tryToGetSize = function() { - if (videoObj.videoWidth > 0 || triesLeft < 0) { - self.nativeVideoWidth = videoObj.videoWidth; - self.nativeVideoHeight = videoObj.videoHeight; - if (self._desiredVideoProperties.height && - (self.nativeVideoHeight !== self._desiredVideoProperties.height || - self.nativeVideoWidth !== self._desiredVideoProperties.width)) { - self.showError(self.errCodes.MEDIA_WARNING, - self.format(self.getConstantString("resolutionWarning"), - self._desiredVideoProperties.width, self._desiredVideoProperties.height, - self.nativeVideoWidth, self.nativeVideoHeight)); - } - self.setVideoObjectSrc(videoObj, ""); - if (videoObj.removeNode) { - videoObj.removeNode(true); - } - else { - ele = document.createElement('div'); - ele.appendChild(videoObj); - ele.removeChild(videoObj); - } - - updateConfigurationInfo(); - if (successCallback) { - successCallback(stream); - } - } - else { - triesLeft -= 1; - setTimeout(tryToGetSize, 300); - } - }; - self.setVideoObjectSrc(videoObj, stream); - tryToGetSize(); - } - else { - updateConfigurationInfo(); - if (successCallback) { - successCallback(stream); - } - } - }; - /** @private - * @param {String} error - */ - var onUserMediaError = function(error) { - console.log("getusermedia failed"); - if (self.debugPrinter) { - self.debugPrinter("failed to get local media"); - } - var errText; - if (typeof error === 'string') { - errText = error; - } - else if (error.name) { - errText = error.name; - } - else { - errText = "Unknown"; - } - if (errorCallback) { - console.log("invoking error callback", errText); - errorCallback(self.errCodes.MEDIA_ERR, self.format(self.getConstantString("gumFailed"), errText)); - } - closeLocalMediaStreamByName(streamName); - haveAudioVideo = { - audio: false, - video: false - }; - updateConfigurationInfo(); - }; - if (!audioEnabled && !videoEnabled) { - onUserMediaError(self.getConstantString("requireAudioOrVideo")); - return; - } - - function getCurrentTime() { - return (new Date()).getTime(); - } - - var firstCallTime; - function tryAgain(error) { - var currentTime = getCurrentTime(); - if (currentTime < firstCallTime + 1000) { - console.log("Trying getUserMedia a second time"); - setTimeout(function() { - getUserMedia(mode, onUserMediaSuccess, onUserMediaError); - }, 3000); - } - else { - onUserMediaError(error); - } - } - - if (videoEnabled || audioEnabled) { - // - // getUserMedia sometimes fails the first time I call it. I suspect it's a page loading - // issue. So I'm going to try adding a 3 second delay to allow things to settle down first. - // In addition, I'm going to try again after 3 seconds. - // - - - setTimeout(function() { - try { - firstCallTime = getCurrentTime(); - getUserMedia(mode, onUserMediaSuccess, tryAgain); - } catch (e) { - tryAgain(e); - } - }, 1000); - } - else { - onUserMediaSuccess(null); - } - }; - /** - * Sets the callback used to decide whether to accept or reject an incoming call. - * @param {Function} acceptCheck takes the arguments (callerEasyrtcid, acceptor). - * The acceptCheck callback is passed an easyrtcid and an aceptor function. The acceptor function should be called with either - * a true value (accept the call) or false value( reject the call) as it's first argument, and optionally, - * an array of local media streamNames as a second argument. - * @example - * easyrtc.setAcceptChecker( function(easyrtcid, acceptor){ - * if( easyrtc.idToName(easyrtcid) === 'Fred' ){ - * acceptor(true); - * } - * else if( easyrtc.idToName(easyrtcid) === 'Barney' ){ - * setTimeout( function(){ - acceptor(true, ['myOtherCam']); // myOtherCam presumed to a streamName - }, 10000); - * } - * else{ - * acceptor(false); - * } - * }); - */ - this.setAcceptChecker = function(acceptCheck) { - self.acceptCheck = acceptCheck; - }; - /** - * easyrtc.setStreamAcceptor sets a callback to receive media streams from other peers, independent - * of where the call was initiated (caller or callee). - * @param {Function} acceptor takes arguments (caller, mediaStream, mediaStreamName) - * @example - * easyrtc.setStreamAcceptor(function(easyrtcid, stream, streamName){ - * document.getElementById('callerName').innerHTML = easyrtc.idToName(easyrtcid); - * easyrtc.setVideoObjectSrc( document.getElementById("callerVideo"), stream); - * }); - */ - this.setStreamAcceptor = function(acceptor) { - self.streamAcceptor = acceptor; - }; - /** Sets the easyrtc.onError field to a user specified function. - * @param {Function} errListener takes an object of the form {errorCode: String, errorText: String} - * @example - * easyrtc.setOnError( function(errorObject){ - * document.getElementById("errMessageDiv").innerHTML += errorObject.errorText; - * }); - */ - self.setOnError = function(errListener) { - self.onError = errListener; - }; - /** - * Sets the callCancelled callback. This will be called when a remote user - * initiates a call to you, but does a "hangup" before you have a chance to get his video stream. - * @param {Function} callCancelled takes an easyrtcid as an argument and a boolean that indicates whether - * the call was explicitly cancelled remotely (true), or actually accepted by the user attempting a call to - * the same party. - * @example - * easyrtc.setCallCancelled( function(easyrtcid, explicitlyCancelled){ - * if( explicitlyCancelled ){ - * console.log(easyrtc.idToName(easyrtcid) + " stopped trying to reach you"); - * } - * else{ - * console.log("Implicitly called " + easyrtc.idToName(easyrtcid)); - * } - * }); - */ - this.setCallCancelled = function(callCancelled) { - self.callCancelled = callCancelled; - }; - /** Sets a callback to receive notification of a media stream closing. The usual - * use of this is to clear the source of your video object so you aren't left with - * the last frame of the video displayed on it. - * @param {Function} onStreamClosed takes an easyrtcid as it's first parameter, the stream as it's second argument, and name of the video stream as it's third. - * @example - * easyrtc.setOnStreamClosed( function(easyrtcid, stream, streamName){ - * easyrtc.setVideoObjectSrc( document.getElementById("callerVideo"), ""); - * ( easyrtc.idToName(easyrtcid) + " closed stream " + stream.id + " " + streamName); - * }); - */ - this.setOnStreamClosed = function(onStreamClosed) { - self.onStreamClosed = onStreamClosed; - }; - /** @deprecated No longer supported by Google. - * Sets the bandwidth for sending video data. - * Setting the rate too low will cause connection attempts to fail. 40 is probably good lower limit. - * The default is 50. A value of zero will remove bandwidth limits. - * @param {Number} kbitsPerSecond is rate in kilobits per second. - * @example - * easyrtc.setVideoBandwidth( 40); - */ - this.setVideoBandwidth = function(kbitsPerSecond) { - self.showError("easyrtc.setVideoBandwidth is deprecated, it no longer has an effect."); - }; - /** Determines whether the current browser supports the new data channels. - * EasyRTC will not open up connections with the old data channels. - * @returns {Boolean} - */ - this.supportsDataChannels = function() { - if (navigator.userAgent.match(/android/i)) { - return webrtcDetectedVersion >= 34; - } - else { - return (webrtcDetectedBrowser === "firefox" || webrtcDetectedVersion >= 32); - } - }; - /** - * Sets a listener for data sent from another client (either peer to peer or via websockets). - * If no msgType or source is provided, the listener applies to all events that aren't otherwise handled. - * If a msgType but no source is provided, the listener applies to all messages of that msgType that aren't otherwise handled. - * If a msgType and a source is provided, the listener applies to only message of the specified type coming from the specified peer. - * The most specific case takes priority over the more general. - * @param {Function} listener has the signature (easyrtcid, msgType, msgData, targeting). - * msgType is a string. targeting is null if the message was received using WebRTC data channels, otherwise it - * is an object that contains one or more of the following string valued elements {targetEasyrtcid, targetGroup, targetRoom}. - * @param {String} msgType - a string, optional. - * @param {String} source - the sender's easyrtcid, optional. - * @example - * easyrtc.setPeerListener( function(easyrtcid, msgType, msgData, targeting){ - * console.log("From " + easyrtc.idToName(easyrtcid) + - * " sent the following data " + JSON.stringify(msgData)); - * }); - * easyrtc.setPeerListener( function(easyrtcid, msgType, msgData, targeting){ - * console.log("From " + easyrtc.idToName(easyrtcid) + - * " sent the following data " + JSON.stringify(msgData)); - * }, 'food', 'dkdjdekj44--'); - * easyrtc.setPeerListener( function(easyrtcid, msgType, msgData, targeting){ - * console.log("From " + easyrtcid + - * " sent the following data " + JSON.stringify(msgData)); - * }, 'drink'); - * - * - */ - this.setPeerListener = function(listener, msgType, source) { - if (!msgType) { - receivePeer.cb = listener; - } - else { - if (!receivePeer.msgTypes[msgType]) { - receivePeer.msgTypes[msgType] = {sources: {}}; - } - if (!source) { - receivePeer.msgTypes[msgType].cb = listener; - } - else { - receivePeer.msgTypes[msgType].sources[source] = {cb: listener}; - } - } - }; - /* This function serves to distribute peer messages to the various peer listeners */ - /** @private - * @param {String} easyrtcid - * @param {Object} msg - needs to contain a msgType and a msgData field. - * @param {Object} targeting - */ - this.receivePeerDistribute = function(easyrtcid, msg, targeting) { - var msgType = msg.msgType; - var msgData = msg.msgData; - if (!msgType) { - console.log("received peer message without msgType", msg); - return; - } - - if (receivePeer.msgTypes[msgType]) { - if (receivePeer.msgTypes[msgType].sources[easyrtcid] && - receivePeer.msgTypes[msgType].sources[easyrtcid].cb) { - receivePeer.msgTypes[msgType].sources[easyrtcid].cb(easyrtcid, msgType, msgData, targeting); - return; - } - if (receivePeer.msgTypes[msgType].cb) { - receivePeer.msgTypes[msgType].cb(easyrtcid, msgType, msgData, targeting); - return; - } - } - if (receivePeer.cb) { - receivePeer.cb(easyrtcid, msgType, msgData, targeting); - } - }; - /** - * Sets a listener for messages from the server. - * @param {Function} listener has the signature (msgType, msgData, targeting) - * @example - * easyrtc.setServerListener( function(msgType, msgData, targeting){ - * ("The Server sent the following message " + JSON.stringify(msgData)); - * }); - */ - this.setServerListener = function(listener) { - receiveServerCB = listener; - }; - /** - * Sets the url of the Socket server. - * The node.js server is great as a socket server, but it doesn't have - * all the hooks you'd like in a general web server, like PHP or Python - * plug-ins. By setting the serverPath your application can get it's regular - * pages from a regular web server, but the EasyRTC library can still reach the - * socket server. - * @param {String} socketUrl - * @param {Object} options an optional dictionary of options for socket.io's connect method. - * The default is {'connect timeout': 10000,'force new connection': true } - * @example - * easyrtc.setSocketUrl(":8080", options); - */ - this.setSocketUrl = function(socketUrl, options) { - if (self.debugPrinter) { - self.debugPrinter("WebRTC signaling server URL set to " + socketUrl); - } - serverPath = socketUrl; - if( options ) { - connectionOptions = options; - } - }; - /** - * Sets the user name associated with the connection. - * @param {String} username must obey standard identifier conventions. - * @returns {Boolean} true if the call succeeded, false if the username was invalid. - * @example - * if( !easyrtc.setUsername("JohnSmith") ){ - * console.error("bad user name); - * - */ - this.setUsername = function(username) { - if( self.myEasyrtcid ) { - easyrtc.showError(easyrtc.errCodes.DEVELOPER_ERR, "easyrtc.setUsername called after authentication"); - return false; - } - else if (self.isNameValid(username)) { - self.username = username; - return true; - } - else { - self.showError(self.errCodes.BAD_NAME, self.format(self.getConstantString("badUserName"), username)); - return false; - } - }; - /** - * Get an array of easyrtcids that are using a particular username - * @param {String} username - the username of interest. - * @param {String} room - an optional room name argument limiting results to a particular room. - * @returns {Array} an array of {easyrtcid:id, roomName: roomName}. - */ - this.usernameToIds = function(username, room) { - var results = []; - var id, roomName; - for (roomName in lastLoggedInList) { - if (!lastLoggedInList.hasOwnProperty(roomName)) { - continue; - } - if (room && roomName !== room) { - continue; - } - for (id in lastLoggedInList[roomName]) { - if (!lastLoggedInList[roomName].hasOwnProperty(id)) { - continue; - } - if (lastLoggedInList[roomName][id].username === username) { - results.push({ - easyrtcid: id, - roomName: roomName - }); - } - } - } - return results; - }; - /** - * Returns another peers API field, if it exists. - * @param {type} roomName - * @param {type} easyrtcid - * @param {type} fieldName - * @returns {Object} Undefined if the attribute does not exist, its value otherwise. - */ - this.getRoomApiField = function(roomName, easyrtcid, fieldName) { - if (lastLoggedInList[roomName] && - lastLoggedInList[roomName][easyrtcid] && - lastLoggedInList[roomName][easyrtcid].apiField && - lastLoggedInList[roomName][easyrtcid].apiField[fieldName]) { - return lastLoggedInList[roomName][easyrtcid].apiField[fieldName].fieldValue; - } - else { - return undefined; - } - }; - /** - * Set the authentication credential if needed. - * @param {Object} credentialParm - a JSONable object. - */ - this.setCredential = function(credentialParm) { - try { - JSON.stringify(credentialParm); - credential = credentialParm; - return true; - } - catch (oops) { - self.showError(self.errCodes.BAD_CREDENTIAL, "easyrtc.setCredential passed a non-JSON-able object"); - throw "easyrtc.setCredential passed a non-JSON-able object"; - } - }; - /** - * Sets the listener for socket disconnection by external (to the API) reasons. - * @param {Function} disconnectListener takes no arguments and is not called as a result of calling easyrtc.disconnect. - * @example - * easyrtc.setDisconnectListener(function(){ - * easyrtc.showError("SYSTEM-ERROR", "Lost our connection to the socket server"); - * }); - */ - this.setDisconnectListener = function(disconnectListener) { - self.disconnectListener = disconnectListener; - }; - /** - * Convert an easyrtcid to a user name. This is useful for labeling buttons and messages - * regarding peers. - * @param {String} easyrtcid - * @return {String} the username associated with the easyrtcid, or the easyrtcid if there is - * no associated username. - * @example - * console.log(easyrtcid + " is actually " + easyrtc.idToName(easyrtcid)); - */ - this.idToName = function(easyrtcid) { - var roomName; - for (roomName in lastLoggedInList) { - if (!lastLoggedInList.hasOwnProperty(roomName)) { - continue; - } - if (lastLoggedInList[roomName][easyrtcid]) { - if (lastLoggedInList[roomName][easyrtcid].username) { - return lastLoggedInList[roomName][easyrtcid].username; - } - } - } - return easyrtcid; - }; - /* used in easyrtc.connect */ - /** @private */ - this.webSocket = null; - var pc_config = {}; - var pc_config_to_use = null; - var use_fresh_ice_each_peer = false; - /** - * Determines whether fresh ice server configuration should be requested from the server for each peer connection. - * @param {Boolean} value the default is false. - */ - this.setUseFreshIceEachPeerConnection = function(value) { - use_fresh_ice_each_peer = value; - }; - /** - * Returns the last ice config supplied by the EasyRTC server. This function is not normally used, it is provided - * for people who want to try filtering ice server configuration on the client. - * @return {Object} which has the form {iceServers:[ice_server_entry, ice_server_entry, ...]} - */ - this.getServerIce = function() { - return pc_config; - }; - /** - * Sets the ice server configuration that will be used in subsequent calls. You only need this function if you are filtering - * the ice server configuration on the client or if you are using TURN certificates that have a very short lifespan. - * @param {Object} ice An object with iceServers element containing an array of ice server entries. - * @example - * easyrtc.setIceUsedInCalls( {"iceServers": [ - * { - * "url": "stun:stun.sipgate.net" - * }, - * { - * "url": "stun:217.10.68.152" - * }, - * { - * "url": "stun:stun.sipgate.net:10000" - * } - * ]}); - * easyrtc.call(...); - */ - this.setIceUsedInCalls = function(ice) { - if (!ice.iceServers) { - easyrtc.showError(easyrtc.errCodes.DEVELOPER_ERR, "Bad ice configuration passed to easyrtc.setIceUsedInCalls"); - } - else { - pc_config_to_use = ice; - } - }; - var closedChannel = null; - /** @private - * @param easyrtcid - * @param checkAudio - */ - function _haveTracks(easyrtcid, checkAudio, streamName) { - var stream, peerConnObj; - if (!easyrtcid) { - stream = getLocalMediaStreamByName(streamName); - } - else { - peerConnObj = peerConns[easyrtcid]; - if (!peerConnObj) { - console.error("Developer error: haveTracks called about a peer you don't have a connection to"); - return false; - } - stream = peerConnObj.getRemoteStreamByName(streamName); - } - if (!stream) { - return false; - } - - var tracks; - try { - if (checkAudio) { - tracks = stream.getAudioTracks(); - } - else { - tracks = stream.getVideoTracks(); - } - } catch (oops) { - return true; - } - if (!tracks) - return false; - return tracks.length > 0; - } - ; - /** Determines if a particular peer2peer connection has an audio track. - * @param {String} easyrtcid - the id of the other caller in the connection. If easyrtcid is not supplied, checks the local media. - * @param {String} streamName - an optional stream id. - * @return {Boolean} true if there is an audio track or the browser can't tell us. - */ - this.haveAudioTrack = function(easyrtcid, streamName) { - return _haveTracks(easyrtcid, true, streamName); - }; - /** Determines if a particular peer2peer connection has a video track. - * @param {String} easyrtcid - the id of the other caller in the connection. If easyrtcid is not supplied, checks the local media. - * @param {String} streamName - an optional stream id. * - * @return {Boolean} true if there is an video track or the browser can't tell us. - */ - this.haveVideoTrack = function(easyrtcid, streamName) { - return _haveTracks(easyrtcid, false, streamName); - }; - /** - * Gets a data field associated with a room. - * @param {String} roomName - the name of the room. - * @param {String} fieldName - the name of the field. - * @return {Object} dataValue - the value of the field if present, undefined if not present. - */ - this.getRoomField = function(roomName, fieldName) { - var fields = self.getRoomFields(roomName); - if (!fields || !fields[fieldName]) - return undefined; - return fields[fieldName].fieldValue; - }; -// -// Experimental function to determine if statistics gathering is supported. -// - this.supportsStatistics = function() { - var peer; - try { - peer = new RTCPeerConnection({iceServers: []}, {}); - return !!peer.getStats; - } - catch (err) { - return false; - } - }; - /** - * Connects to the EasyRTC signaling server. You must connect before trying to - * call other users. - * @param {String} applicationName is a string that identifies the application so that different applications can have different - * lists of users. Note that the server configuration specifies a regular expression that is used to check application names - * for validity. The default pattern is that of an identifier, spaces are not allowed. - * @param {Function} successCallback (easyrtcId, roomOwner) - is called on successful connect. easyrtcId is the - * unique name that the client is known to the server by. A client usually only needs it's own easyrtcId for debugging purposes. - * roomOwner is true if the user is the owner of a room. It's value is random if the user is in multiple rooms. - * @param {Function} errorCallback (errorCode, errorText) - is called on unsuccessful connect. if null, an alert is called instead. - * The errorCode takes it's value from easyrtc.errCodes. - * @example - * easyrtc.connect("mychat_app", - * function(easyrtcid, roomOwner){ - * if( roomOwner){ console.log("I'm the room owner"); } - * console.log("my id is " + easyrtcid); - * }, - * function(errorText){ - * console.log("failed to connect ", erFrText); - * }); - */ - - var fields = null; - function isEmptyObj(obj) { - if (obj === null || obj === undefined) { - return true; - } - var key; - for (key in obj) { - if (obj.hasOwnProperty(key)) { - return false; - } - } - return true; - } - - // -// easyrtc.disconnect performs a clean disconnection of the client from the server. -// - function disconnectBody() { - var key; - self.loggingOut = true; - offersPending = {}; - acceptancePending = {}; - self.disconnecting = true; - closedChannel = self.webSocket; - if (self.webSocketConnected) { - if (!preallocatedSocketIo) { - self.webSocket.close(); - } - self.webSocketConnected = false; - } - self.hangupAll(); - if (roomOccupantListener) { - for (key in lastLoggedInList) { - if (lastLoggedInList.hasOwnProperty(key)) { - roomOccupantListener(key, {}, false); - } - } - } - lastLoggedInList = {}; - self.emitEvent("roomOccupant", {}); - self.roomData = {}; - self.roomJoin = {}; - self.loggingOut = false; - self.myEasyrtcid = null; - self.disconnecting = false; - oldConfig = {}; - } - ; - this.disconnect = function() { - - if (self.debugPrinter) { - self.debugPrinter("attempt to disconnect from WebRTC signalling server"); - } - - self.disconnecting = true; - self.hangupAll(); - self.loggingOut = true; - // - // The hangupAll may try to send configuration information back to the server. - // Collecting that information is asynchronous, we don't actually close the - // connection until it's had a chance to be sent. We allocate 100ms for collecting - // the info, so 250ms should be sufficient for the disconnecting. - // - setTimeout(function() { - if (self.webSocket) { - try { - self.webSocket.disconnect(); - } catch (e) { - // we don't really care if this fails. - } - - closedChannel = self.webSocket; - self.webSocket = 0; - } - self.loggingOut = false; - self.disconnecting = false; - if (roomOccupantListener) { - roomOccupantListener(null, {}, false); - } - self.emitEvent("roomOccupant", {}); - oldConfig = {}; - }, 250); - }; - // - // This function is used to send WebRTC signaling messages to another client. These messages all the form: - // destUser: some id or null - // msgType: one of ["offer"/"answer"/"candidate","reject","hangup", "getRoomList"] - // msgData: either null or an SDP record - // successCallback: a function with the signature function(msgType, wholeMsg); - // errorCallback: a function with signature function(errorCode, errorText) - // - function sendSignalling(destUser, msgType, msgData, successCallback, errorCallback) { - if (!self.webSocket) { - throw "Attempt to send message without a valid connection to the server."; - } - else { - var dataToShip = { - msgType: msgType - }; - if (destUser) { - dataToShip.targetEasyrtcid = destUser; - } - if (msgData) { - dataToShip.msgData = msgData; - } - - if (self.debugPrinter) { - self.debugPrinter("sending socket message " + JSON.stringify(dataToShip)); - } - self.webSocket.json.emit("easyrtcCmd", dataToShip, - function(ackMsg) { - if (ackMsg.msgType !== "error") { - if (!ackMsg.hasOwnProperty("msgData")) { - ackMsg.msgData = null; - } - if (successCallback) { - successCallback(ackMsg.msgType, ackMsg.msgData); - } - } - else { - if (errorCallback) { - errorCallback(ackMsg.msgData.errorCode, ackMsg.msgData.errorText); - } - else { - self.showError(ackMsg.msgData.errorCode, ackMsg.msgData.errorText); - } - } - } - ); - } - } - - - /** - *Sends data to another user using previously established data channel. This method will - * fail if no data channel has been established yet. Unlike the easyrtc.sendWS method, - * you can't send a dictionary, convert dictionaries to strings using JSON.stringify first. - * What data types you can send, and how large a data type depends on your browser. - * @param {String} destUser (an easyrtcid) - * @param {String} msgType - the type of message being sent (application specific). - * @param {Object} msgData - a JSONable object. - * @example - * easyrtc.sendDataP2P(someEasyrtcid, "roomData", {room:499, bldgNum:'asd'}); - */ - this.sendDataP2P = function(destUser, msgType, msgData) { - - var flattenedData = JSON.stringify({msgType: msgType, msgData: msgData}); - if (self.debugPrinter) { - self.debugPrinter("sending p2p message to " + destUser + " with data=" + JSON.stringify(flattenedData)); - } - - if (!peerConns[destUser]) { - self.showError(self.errCodes.DEVELOPER_ERR, "Attempt to send data peer to peer without a connection to " + destUser + ' first.'); - } - else if (!peerConns[destUser].dataChannelS) { - self.showError(self.errCodes.DEVELOPER_ERR, "Attempt to send data peer to peer without establishing a data channel to " + destUser + ' first.'); - } - else if (!peerConns[destUser].dataChannelReady) { - self.showError(self.errCodes.DEVELOPER_ERR, "Attempt to use data channel to " + destUser + " before it's ready to send."); - } - else { - try { - peerConns[destUser].dataChannelS.send(flattenedData); - } catch (oops) { - console.log("error=", oops); - throw oops; - } - } - }; - /** Sends data to another user using websockets. The easyrtc.sendServerMessage or easyrtc.sendPeerMessage methods - * are wrappers for this method; application code should use them instead. - * @param {String} destination - either a string containing the easyrtcId of the other user, or an object containing some subset of the following fields: targetEasyrtcid, targetGroup, targetRoom. - * Specifying multiple fields restricts the scope of the destination (operates as a logical AND, not a logical OR). - * @param {String} msgType -the type of message being sent (application specific). - * @param {Object} msgData - a JSONable object. - * @param {Function} ackhandler - by default, the ackhandler handles acknowledgments from the server that your message was delivered to it's destination. - * However, application logic in the server can over-ride this. If you leave this null, a stub ackHandler will be used. The ackHandler - * gets passed a message with the same msgType as your outgoing message, or a message type of "error" in which case - * msgData will contain a errorCode and errorText fields. - * @example - * easyrtc.sendDataWS(someEasyrtcid, "setPostalAddress", {room:499, bldgNum:'asd'}, - * function(ackMsg){ - * console.log("saw the following acknowledgment " + JSON.stringify(ackMsg)); - * } - * ); - */ - this.sendDataWS = function(destination, msgType, msgData, ackhandler) { - if (self.debugPrinter) { - self.debugPrinter("sending client message via websockets to " + destination + " with data=" + JSON.stringify(msgData)); - } - if (!ackhandler) { - ackhandler = function(msg) { - if (msg.msgType === "error") { - self.showError(msg.msgData.errorCode, msg.msgData.errorText); - } - }; - } - - var outgoingMessage = { - msgType: msgType, - msgData: msgData - }; - if (destination) { - if (typeof destination === 'string') { - outgoingMessage.targetEasyrtcid = destination; - } - else if (typeof destination === 'object') { - if (destination.targetEasyrtcid) { - outgoingMessage.targetEasyrtcid = destination.targetEasyrtcid; - } - if (destination.targetRoom) { - outgoingMessage.targetRoom = destination.targetRoom; - } - if (destination.targetGroup) { - outgoingMessage.targetGroup = destination.targetGroup; - } - } - } - - - if (self.webSocket) { - self.webSocket.json.emit("easyrtcMsg", outgoingMessage, ackhandler); - } - else { - if (self.debugPrinter) { - self.debugPrinter("websocket failed because no connection to server"); - } - throw "Attempt to send message without a valid connection to the server."; - } - }; - /** Sends data to another user. This method uses data channels if one has been set up, or websockets otherwise. - * @param {String} destUser - a string containing the easyrtcId of the other user. - * Specifying multiple fields restricts the scope of the destination (operates as a logical AND, not a logical OR). - * @param {String} msgType -the type of message being sent (application specific). - * @param {Object} msgData - a JSONable object. - * @param {Function} ackHandler - a function which receives acknowledgments. May only be invoked in - * the websocket case. - * @example - * easyrtc.sendData(someEasyrtcid, "roomData", {room:499, bldgNum:'asd'}, - * function ackHandler(msgType, msgData); - * ); - */ - this.sendData = function(destUser, msgType, msgData, ackHandler) { - if (peerConns[destUser] && peerConns[destUser].dataChannelReady) { - self.sendDataP2P(destUser, msgType, msgData); - } - else { - self.sendDataWS(destUser, msgType, msgData, ackHandler); - } - }; - /** - * Sends a message to another peer on the easyrtcMsg channel. - * @param {String} destination - either a string containing the easyrtcId of the other user, or an object containing some subset of the following fields: targetEasyrtcid, targetGroup, targetRoom. - * Specifying multiple fields restricts the scope of the destination (operates as a logical AND, not a logical OR). - * @param {String} msgType - the type of message being sent (application specific). - * @param {Object} msgData - a JSONable object with the message contents. - * @param {function(String, Object)} successCB - a callback function with results from the server. - * @param {function(String, String)} failureCB - a callback function to handle errors. - * @example - * easyrtc.sendPeerMessage(otherUser, 'offer_candy', {candy_name:'mars'}, - * function(msgType, msgBody ){ - * console.log("message was sent"); - * }, - * function(errorCode, errorText){ - * console.log("error was " + errorText); - * }); - */ - this.sendPeerMessage = function(destination, msgType, msgData, successCB, failureCB) { - if (!destination) { - console.error("Developer error, destination was null in sendPeerMessage"); - } - - if (self.debugPrinter) { - self.debugPrinter("sending peer message " + JSON.stringify(msgData)); - } - function ackHandler(response) { - if (response.msgType === "error") { - if (failureCB) { - failureCB(response.msgData.errorCode, response.msgData.errorText); - } - } - else { - if (successCB) { - // firefox complains if you pass an undefined as an parameter. - successCB(response.msgType, response.msgData ? response.msgData : null); - } - } - } - - self.sendDataWS(destination, msgType, msgData, ackHandler); - }; - /** - * Sends a message to the application code in the server (ie, on the easyrtcMsg channel). - * @param {String} msgType - the type of message being sent (application specific). - * @param {Object} msgData - a JSONable object with the message contents. - * @param {function(String, Object)} successCB - a callback function with results from the server. - * @param {function(String, String)} failureCB - a callback function to handle errors. - * @example - * easyrtc.sendServerMessage('get_candy', {candy_name:'mars'}, - * function(msgType, msgData ){ - * console.log("got candy count of " + msgData.barCount); - * }, - * function(errorCode, errorText){ - * console.log("error was " + errorText); - * }); - */ - this.sendServerMessage = function(msgType, msgData, successCB, failureCB) { - if (self.debugPrinter) { - var dataToShip = {msgType: msgType, msgData: msgData}; - self.debugPrinter("sending server message " + JSON.stringify(dataToShip)); - } - function ackhandler(response) { - if (response.msgType === "error") { - if (failureCB) { - failureCB(response.msgData.errorCode, response.msgData.errorText); - } - } - else { - if (successCB) { - successCB(response.msgType, response.msgData ? response.msgData : null); - } - } - } - - self.sendDataWS(null, msgType, msgData, ackhandler); - }; - /** Sends the server a request for the list of rooms the user can see. - * You must have already be connected to use this function. - * @param {function(Object)} callback - on success, this function is called with a map of the form { roomName:{"roomName":String, "numberClients": Number}}. - * The roomName appears as both the key to the map, and as the value of the "roomName" field. - * @param {function(String, String)} errorCallback is called on failure. It gets an errorCode and errorText as it's too arguments. - * @example - * easyrtc.getRoomList( - * function(roomList){ - * for(roomName in roomList){ - * console.log("saw room " + roomName); - * } - * }, - * function(errorCode, errorText){ - * easyrtc.showError(errorCode, errorText); - * } - * ); - */ - this.getRoomList = function(callback, errorCallback) { - sendSignalling(null, "getRoomList", null, - function(msgType, msgData) { - callback(msgData.roomList); - }, - function(errorCode, errorText) { - if (errorCallback) { - errorCallback(errorCode, errorText); - } - else { - self.showError(errorCode, errorText); - } - } - ); - }; - /** Value returned by easyrtc.getConnectStatus if the other user isn't connected to us. */ - this.NOT_CONNECTED = "not connected"; - /** Value returned by easyrtc.getConnectStatus if the other user is in the process of getting connected */ - this.BECOMING_CONNECTED = "connection in progress to us."; - /** Value returned by easyrtc.getConnectStatus if the other user is connected to us. */ - this.IS_CONNECTED = "is connected"; - /** - * Check if the client has a peer-2-peer connection to another user. - * The return values are text strings so you can use them in debugging output. - * @param {String} otherUser - the easyrtcid of the other user. - * @return {String} one of the following values: easyrtc.NOT_CONNECTED, easyrtc.BECOMING_CONNECTED, easyrtc.IS_CONNECTED - * @example - * if( easyrtc.getConnectStatus(otherEasyrtcid) == easyrtc.NOT_CONNECTED ){ - * easyrtc.call(otherEasyrtcid, - * function(){ console.log("success"); }, - * function(){ console.log("failure"); }); - * } - */ - this.getConnectStatus = function(otherUser) { - if (!peerConns.hasOwnProperty(otherUser)) { - return self.NOT_CONNECTED; - } - var peer = peerConns[otherUser]; - if ((peer.sharingAudio || peer.sharingVideo) && !peer.startedAV) { - return self.BECOMING_CONNECTED; - } - else if (peer.sharingData && !peer.dataChannelReady) { - return self.BECOMING_CONNECTED; - } - else { - return self.IS_CONNECTED; - } - }; - /** - * @private - */ - function buildPeerConstraints() { - var options = []; - options.push({'DtlsSrtpKeyAgreement': 'true'}); // for interoperability - return {optional: options}; - } - - - /** - * Initiates a call to another user. If it succeeds, the streamAcceptor callback will be called. - * @param {String} otherUser - the easyrtcid of the peer being called. - * @param {Function} callSuccessCB (otherCaller, mediaType) - is called when the datachannel is established or the MediaStream is established. mediaType will have a value of "audiovideo" or "datachannel" - * @param {Function} callFailureCB (errorCode, errMessage) - is called if there was a system error interfering with the call. - * @param {Function} wasAcceptedCB (wasAccepted:boolean,otherUser:string) - is called when a call is accepted or rejected by another party. It can be left null. - * @param {Array} streamNames - optional array of streamNames. - * @example - * easyrtc.call( otherEasyrtcid, - * function(easyrtcid, mediaType){ - * console.log("Got mediaType " + mediaType + " from " + easyrtc.idToName(easyrtcid)); - * }, - * function(errorCode, errMessage){ - * console.log("call to " + easyrtc.idToName(otherEasyrtcid) + " failed:" + errMessage); - * }, - * function(wasAccepted, easyrtcid){ - * if( wasAccepted ){ - * console.log("call accepted by " + easyrtc.idToName(easyrtcid)); - * } - * else{ - * console.log("call rejected" + easyrtc.idToName(easyrtcid)); - * } - * }); - */ - this.call = function(otherUser, callSuccessCB, callFailureCB, wasAcceptedCB, streamNames) { - - if (streamNames) { - if (typeof streamNames === "string") { // accept a string argument if passed. - streamNames = [streamNames]; - } - else if (streamNames.length === undefined) { - easyrtc.showError(self.errCodes.DEVELOPER_ERR, "easyrtc.call passed bad streamNames"); - return; - } - } - - if (self.debugPrinter) { - self.debugPrinter("initiating peer to peer call to " + otherUser + - " audio=" + audioEnabled + - " video=" + videoEnabled + - " data=" + dataEnabled); - } - - if (!self.supportsPeerConnections()) { - callFailureCB(self.errCodes.CALL_ERR, self.getConstantString("noWebrtcSupport")); - return; - } - - var message; - // - // If we are sharing audio/video and we haven't allocated the local media stream yet, - // we'll do so, recalling ourself on success. - // - if (!streamNames && autoInitUserMedia) { - var stream = self.getLocalStream(); - if (!stream && (audioEnabled || videoEnabled)) { - self.initMediaSource(function() { - self.call(otherUser, callSuccessCB, callFailureCB, wasAcceptedCB); - }, callFailureCB); - return; - } - } - - if (!self.webSocket) { - message = "Attempt to make a call prior to connecting to service"; - if (self.debugPrinter) { - self.debugPrinter(message); - } - throw message; - } - - // - // If B calls A, and then A calls B before accepting, then A should treat the attempt to - // call B as a positive offer to B's offer. - // - if (offersPending[otherUser]) { - wasAcceptedCB(true); - doAnswer(otherUser, offersPending[otherUser], streamNames); - delete offersPending[otherUser]; - self.callCancelled(otherUser, false); - return; - } - - // do we already have a pending call? - if (typeof acceptancePending[otherUser] !== 'undefined') { - message = "Call already pending acceptance"; - if (self.debugPrinter) { - self.debugPrinter(message); - } - callFailureCB(self.errCodes.ALREADY_CONNECTED, message); - return; - } - - if (use_fresh_ice_each_peer) { - self.getFreshIceConfig(function(succeeded) { - if (succeeded) { - callBody(otherUser, callSuccessCB, callFailureCB, wasAcceptedCB, streamNames); - } - else { - callFailureCB(self.errCodes.CALL_ERR, "Attempt to get fresh ice configuration failed"); - } - }); - } - else { - callBody(otherUser, callSuccessCB, callFailureCB, wasAcceptedCB, streamNames); - } - }; - function callBody(otherUser, callSuccessCB, callFailureCB, wasAcceptedCB, streamNames) { - acceptancePending[otherUser] = true; - var pc = buildPeerConnection(otherUser, true, callFailureCB, streamNames); - if (!pc) { - message = "buildPeerConnection failed, call not completed"; - if (self.debugPrinter) { - self.debugPrinter(message); - } - throw message; - } - - peerConns[otherUser].callSuccessCB = callSuccessCB; - peerConns[otherUser].callFailureCB = callFailureCB; - peerConns[otherUser].wasAcceptedCB = wasAcceptedCB; - var peerConnObj = peerConns[otherUser]; - var setLocalAndSendMessage0 = function(sessionDescription) { - if (peerConnObj.cancelled) { - return; - } - var sendOffer = function() { - - sendSignalling(otherUser, "offer", sessionDescription, null, callFailureCB); - }; - if (sdpLocalFilter) { - sessionDescription.sdp = sdpLocalFilter(sessionDescription.sdp); - } - pc.setLocalDescription(sessionDescription, sendOffer, - function(errorText) { - callFailureCB(self.errCodes.CALL_ERR, errorText); - }); - }; - setTimeout(function() { - // - // if the call was cancelled, we don't want to continue getting the offer. - // we can tell the call was cancelled because there won't be a peerConn object - // for it. - // - if( !peerConns[otherUser]) { - return; - } - pc.createOffer(setLocalAndSendMessage0, function(errorObj) { - callFailureCB(self.errCodes.CALL_ERR, JSON.stringify(errorObj)); - }, - receivedMediaContraints); - }, 100); - } - ; - function hangupBody(otherUser) { - var i; - if (self.debugPrinter) { - self.debugPrinter("Hanging up on " + otherUser); - } - clearQueuedMessages(otherUser); - if (peerConns[otherUser]) { - if (peerConns[otherUser].pc) { - var remoteStreams = peerConns[otherUser].pc.getRemoteStreams(); - for (i = 0; i < remoteStreams.length; i++) { - if( !remoteStreams[i].ended ) { - emitOnStreamClosed(otherUser, remoteStreams[i]); - try { - remoteStreams[i].close(); - } catch (err) { - } - } - } - // - // todo: may need to add a few lines here for closing the data channels - // - try { - peerConns[otherUser].pc.close(); - } catch (err) { - } - } - - peerConns[otherUser].cancelled = true; - delete peerConns[otherUser]; - if (self.webSocket) { - sendSignalling(otherUser, "hangup", null, function() { - }, function(errorCode, errorText) { - if (self.debugPrinter) { - self.debugPrinter("hangup failed:" + errorText); - } - }); - } - if (acceptancePending[otherUser]) { - delete acceptancePending[otherUser]; - } - } - } - - /** - * Hang up on a particular user or all users. - * @param {String} otherUser - the easyrtcid of the person to hang up on. - * @example - * easyrtc.hangup(someEasyrtcid); - */ - this.hangup = function(otherUser) { - hangupBody(otherUser); - updateConfigurationInfo(); - }; - /** - * Hangs up on all current connections. - * @example - * easyrtc.hangupAll(); - */ - this.hangupAll = function() { - - var sawAConnection = false, - onHangupSuccess = function() { - }, - onHangupFailure = function(errorCode, errorText) { - if (self.debugPrinter) { - self.debugPrinter("hangup failed:" + errorText); - } - }; - for (var otherUser in peerConns) { - if (!peerConns.hasOwnProperty(otherUser)) { - continue; - } - sawAConnection = true; - hangupBody(otherUser); - } - - if (sawAConnection) { - updateConfigurationInfo(); - } - }; - /** Checks to see if data channels work between two peers. - * @param {String} otherUser - the other peer. - * @returns {Boolean} true if data channels work and are ready to be used - * between the two peers. - */ - this.doesDataChannelWork = function(otherUser) { - if (!peerConns[otherUser]) { - return false; - } - return !!peerConns[otherUser].dataChannelReady; - }; - /** - * Return the media stream shared by a particular peer. This is needed when you - * add a stream in the middle of a call. - * @param {String} easyrtcid the peer. - * @param {String} remotestreamName an optional argument supplying the streamName. - * @returns {Object} A mediaStream. - */ - this.getRemoteStream = function(easyrtcid, remotestreamName) { - if (!peerConns[easyrtcid]) { - self.showError(self.errCodes.DEVELOPER_ERR, "attempt to get stream of uncalled party"); - throw "Developer err: no such stream"; - } - else { - return peerConns[easyrtcid].getRemoteStreamByName(remotestreamName); - } - } - /** - * Assign a local streamName to a remote stream so that it can be forwarded to other callers. - * @param {String} easyrtcid the peer supplying the remote stream - * @param {String} remotestreamName the streamName supplied by the peer. - * @param {String} localstreamName streamName used when passing the stream to other peers. - * @example - * easyrtc.makeLocalStreamFromRemoteStream(sourcePeer, "default", "forwardedStream"); - * easyrtc.call(nextPeer, callSuccessCB, callFailureCB, wasAcceptedCB, ["forwardedStream"]); - */ - this.makeLocalStreamFromRemoteStream = function(easyrtcid, remotestreamName, localstreamName) { - if (!streamName) { - streamName = "default"; - } - var remoteStream; - if (peerConns[easyrtcid].pc) { - remoteStream = peerConns[easyrtcid].getRemoteStreamByName(remotestreamName); - if (remoteStream) { - registerLocalMediaStreamByName(remoteStream, localstreamName); - } - else { - throw "Developer err: no such stream"; - } - } - else { - throw "Developer err: no such peer "; - } - } - - /** - * Add a named local stream to a call. - * @param {String} easyrtcId The id of client receiving the stream. - * @param {String} streamName The name of the stream. - * @param {Function} receiptHandler is a function that gets called when the other side sends a message - * that the stream has been received. The receiptHandler gets called with an easyrtcid and a stream name. This - * argument is optional. - */ - this.addStreamToCall = function(easyrtcId, streamName, receiptHandler) { - if( !streamName) { - streamName = "default"; - } - var stream = getLocalMediaStreamByName(streamName); - if (!stream) { - console.log("attempt to add nonexistent stream " + streamName); - } - else if (!peerConns[easyrtcId] || !peerConns[easyrtcId].pc) { - console.log("Can't add stream before a call has started."); - } - else { - var pc = peerConns[easyrtcId].pc; - peerConns[easyrtcId].enableNegotiateListener = true; - pc.addStream(stream); - if( receiptHandler ) { - peerConns[easyrtcId].streamsAddedAcks[streamName] = receiptHandler; - } - } - } - - // - // these three listeners support the ability to add/remove additional mediastreams on the fly. - // - this.setPeerListener(function(easyrtcid, msgType, msgData) { - if (!peerConns[easyrtcid] || !peerConns[easyrtcid].pc) { - easyrtc.showError(self.errCodes.DEVELOPER_ERR, - "Attempt to add additional stream before establishing the base call."); - } - else { - var sdp = msgData.sdp; - var pc = peerConns[easyrtcid].pc; - - var setLocalAndSendMessage1 = function(sessionDescription) { - var sendAnswer = function() { - if (self.debugPrinter) { - self.debugPrinter("sending answer"); - } - function onSignalSuccess() { - } - - function onSignalFailure(errorCode, errorText) { - delete peerConns[easyrtcid]; - self.showError(errorCode, errorText); - } - - sendSignalling(easyrtcid, "answer", sessionDescription, - onSignalSuccess, onSignalFailure); - peerConns[easyrtcid].connectionAccepted = true; - sendQueuedCandidates(easyrtcid, onSignalSuccess, onSignalFailure); - }; - - if (sdpLocalFilter) { - sessionDescription.sdp = sdpLocalFilter(sessionDescription.sdp); - } - pc.setLocalDescription(sessionDescription, sendAnswer, function(message) { - self.showError(self.errCodes.INTERNAL_ERR, "setLocalDescription: " + msgData); - }); - }; - - var invokeCreateAnswer = function() { - pc.createAnswer(setLocalAndSendMessage1, - function(message) { - self.showError(self.errCodes.INTERNAL_ERR, "create-answer: " + message); - }, - receivedMediaContraints); - self.sendPeerMessage(easyrtcid, "__gotAddedMediaStream", {sdp: sdp}); - }; - - if (self.debugPrinter) { - self.debugPrinter("about to call setRemoteDescription in doAnswer"); - } - try { - - if (sdpRemoteFilter) { - sdp.sdp = sdpRemoteFilter(sdp.sdp); - } - pc.setRemoteDescription(new RTCSessionDescription(sdp), - invokeCreateAnswer, function(message) { - self.showError(self.errCodes.INTERNAL_ERR, "set-remote-description: " + message); - }); - } catch (srdError) { - console.log("set remote description failed"); - if (self.debugPrinter) { - self.debugPrinter("saw exception in setRemoteDescription"); - } - self.showError(self.errCodes.INTERNAL_ERR, "setRemoteDescription failed: " + srdError.message); - } - } - }, "__addedMediaStream"); - this.setPeerListener(function(easyrtcid, msgType, msgData) { - if (!peerConns[easyrtcid] || !peerConns[easyrtcid].pc) { - } - else { - var sdp = msgData.sdp; - if (sdpRemoteFilter) { - sdp.sdp = sdpRemoteFilter(sdp.sdp); - } - var pc = peerConns[easyrtcid].pc; - pc.setRemoteDescription(new RTCSessionDescription(sdp), function(){}, - function(message) { - self.showError(self.errCodes.INTERNAL_ERR, "set-remote-description: " + message); - }); - } - - }, "__gotAddedMediaStream"); - this.setPeerListener(function(easyrtcid, msgType, msgData) { - if (!peerConns[easyrtcid] || !peerConns[easyrtcid].pc) { - } - else { - var stream = peerConns[easyrtcid].getRemoteStreamByName(msgData.streamName); - if (stream) { - onRemoveStreamHelper(easyrtcid, stream, msgData.streamName); - stream.ended = true; - } - } - - }, "__closingMediaStream"); - function onRemoveStreamHelper(easyrtcid, stream) { - if (peerConns[easyrtcid]) { - emitOnStreamClosed(easyrtcid, stream); - updateConfigurationInfo(); - if( peerConns[easyrtcid].pc ) { - try { - peerConns[easyrtcid].pc.removeStream(stream); - } catch( err) {} - } - - } - } - - - this.dumpPeerConnectionInfo = function() { - for (var peer in peerConns) { - console.log("For peer " + peer); - var pc = peerConns[peer].pc; - var remotes = pc.getRemoteStreams(); - var remoteIds = []; - for (var i = 0; i < remotes.length; i++) { - remoteIds.push(remotes[i].id); - } - var locals = pc.getLocalStreams(); - var localIds = []; - for (var i = 0; i < locals.length; i++) { - localIds.push(locals[i].id); - } - console.log(" " + JSON.stringify({local: localIds, remote: remoteIds})); - } - } - - - var buildPeerConnection = function(otherUser, isInitiator, failureCB, streamNames) { - var pc; - var message; - var newPeerConn; - var iceConfig = pc_config_to_use ? pc_config_to_use : pc_config; - if (self.debugPrinter) { - self.debugPrinter("building peer connection to " + otherUser); - } - - // - // we don't support data channels on chrome versions < 31 - // - try { - pc = self.createRTCPeerConnection(iceConfig, buildPeerConstraints()); - if (!pc) { - message = "Unable to create PeerConnection object, check your ice configuration(" + - JSON.stringify(ice_config) + ")"; - if (self.debugPrinter) { - self.debugPrinter(message); - } - throw(message); - } - - // - // turn off data channel support if the browser doesn't support it. - // - if (dataEnabled && typeof pc.createDataChannel === 'undefined') { - dataEnabled = false; - } - pc.onnegotiationneeded = function(event) { - if( peerConns[otherUser].enableNegotiateListener ) { - pc.createOffer(function(sdp) { - if (sdpLocalFilter) { - sdp.sdp = sdpLocalFilter(sdp.sdp); - } - pc.setLocalDescription(sdp, function() { - self.sendPeerMessage(otherUser, "__addedMediaStream", {sdp: sdp}); - }, function() { - }); - }, function(errorObj) { - console.log("unexpected error in creating offer"); - }); - } - } - - pc.onconnection = function() { - if (self.debugPrinter) { - self.debugPrinter("onconnection called prematurely"); - } - }; - newPeerConn = { - pc: pc, - candidatesToSend: [], - startedAV: false, - connectionAccepted: false, - isInitiator: isInitiator, - remoteStreamIdToName: {}, - streamsAddedAcks: {}, - liveRemoteStreams: {}, - getRemoteStreamByName: function(streamName) { - var remoteStreams = pc.getRemoteStreams(); - var i = 0; - var keyToMatch = null; - var roomName; - if (!streamName) { - streamName = "default"; - } - - if (streamName === "default") { - if (remoteStreams.length > 0) { - return remoteStreams[0]; - } - else { - return null; - } - } - for (roomName in self.roomData) { - var mediaIds = self.getRoomApiField(roomName, otherUser, "mediaIds"); - keyToMatch = mediaIds ? mediaIds[streamName] : null; - if (keyToMatch) { - break; - } - } - if (!keyToMatch) { - self.showError(self.errCodes.DEVELOPER_ERR, "remote peer does not have media stream called " + streamName); - } - - for (i = 0; i < remoteStreams.length; i++) { - var remoteId; - if (remoteStreams[i].hasOwnProperty("id")) { - remoteId = remoteStreams[i].id; - } - else { - remoteId = "default"; - } - - if (!keyToMatch || remoteId === keyToMatch) { - return remoteStreams[i]; - } - - } - return null; - } - // var remoteStreams = peerConns[i].pc.getRemoteStreams(); - }; - pc.onicecandidate = function(event) { - if (newPeerConn.cancelled) { - return; - } - var candidateData; - if (event.candidate && peerConns[otherUser]) { - candidateData = { - type: 'candidate', - label: event.candidate.sdpMLineIndex, - id: event.candidate.sdpMid, - candidate: event.candidate.candidate - }; - - if( iceCandidateFilter ) { - candidateData = iceCandidateFilter(candidateData, false); - if( !candidateData ) { - return; - } - } - // - // some candidates include ip addresses of turn servers. we'll want those - // later so we can see if our actual connection uses a turn server. - // The keyword "relay" in the candidate identifies it as referencing a - // turn server. The \d symbol in the regular expression matches a number. - // - if (event.candidate.candidate.indexOf("typ relay") > 0) { - var ipAddress = event.candidate.candidate.match(/(udp|tcp) \d+ (\d+\.\d+\.\d+\.\d+)/i)[2]; - self._turnServers[ipAddress] = true; - } - - if (peerConns[otherUser].connectionAccepted) { - sendSignalling(otherUser, "candidate", candidateData, null, function() { - failureCB(self.errCodes.PEER_GONE, "Candidate disappeared"); - }); - } - else { - peerConns[otherUser].candidatesToSend.push(candidateData); - } - } - }; - pc.onaddstream = function(event) { - if (self.debugPrinter) { - self.debugPrinter("saw incoming media stream"); - } - if (newPeerConn.cancelled) - return; - if (!peerConns[otherUser].startedAV) { - peerConns[otherUser].startedAV = true; - peerConns[otherUser].sharingAudio = haveAudioVideo.audio; - peerConns[otherUser].sharingVideo = haveAudioVideo.video; - peerConns[otherUser].connectTime = new Date().getTime(); - if (peerConns[otherUser].callSuccessCB) { - if (peerConns[otherUser].sharingAudio || peerConns[otherUser].sharingVideo) { - peerConns[otherUser].callSuccessCB(otherUser, "audiovideo"); - } - } - if (audioEnabled || videoEnabled) { - updateConfiguration(); - } - } - var remoteName = getNameOfRemoteStream(otherUser, event.stream.id || "default"); - if (!remoteName) { - remoteName = "default"; - } - peerConns[otherUser].remoteStreamIdToName[event.stream.id || "default"] = remoteName; - peerConns[otherUser].liveRemoteStreams[remoteName] = true; - event.stream.streamName = remoteName; - if (self.streamAcceptor) { - self.streamAcceptor(otherUser, event.stream, remoteName); - // - // Inform the other user that the stream they provided has been received. - // This should be moved into signalling at some point - // - self.sendDataWS(otherUser, "easyrtc_streamReceived", {streamName:remoteName},function(){}); - } - }; - pc.onremovestream = function(event) { - if (self.debugPrinter) { - self.debugPrinter("saw remove on remote media stream"); - } - onRemoveStreamHelper(otherUser, event.stream, event.stream.id || "default"); - }; - peerConns[otherUser] = newPeerConn; - } catch (e) { - if (self.debugPrinter) { - self.debugPrinter(JSON.stringify(e)); - } - failureCB(self.errCodes.SYSTEM_ERR, e.message); - return null; - } - - var i, stream; - if (streamNames) { - for (i = 0; i < streamNames.length; i++) { - stream = getLocalMediaStreamByName(streamNames[i]); - if (stream) { - pc.addStream(stream); - } - else { - console.log("Developer error, attempt to access unknown local media stream " + streamNames[i]); - } - } - } - else if (autoInitUserMedia && (videoEnabled || audioEnabled)) { - stream = self.getLocalStream(); - pc.addStream(stream); - } - - // - // This function handles data channel message events. - // - function dataChannelMessageHandler(event) { - if (self.debugPrinter) { - self.debugPrinter("saw dataChannel.onmessage event: " + JSON.stringify(event.data)); - } - - if (event.data === "dataChannelPrimed") { - self.sendDataWS(otherUser, "dataChannelPrimed", ""); - } - else { - // - // Chrome and Firefox Interop is passing a event with a strange data="", perhaps - // as it's own form of priming message. Comparing the data against "" doesn't - // work, so I'm going with parsing and trapping the parse error. - // - try { - var msg = JSON.parse(event.data); - if (msg) { - self.receivePeerDistribute(otherUser, msg, null); - } - } - catch (err) { - } - } - } - - function initOutGoingChannel(otherUser) { - if (self.debugPrinter) { - self.debugPrinter("saw initOutgoingChannel call"); - } - var dataChannel = pc.createDataChannel(dataChannelName, self.getDatachannelConstraints()); - peerConns[otherUser].dataChannelS = dataChannel; - peerConns[otherUser].dataChannelR = dataChannel; - dataChannel.onmessage = dataChannelMessageHandler; - dataChannel.onopen = function(event) { - if (self.debugPrinter) { - self.debugPrinter("saw dataChannel.onopen event"); - } - if (peerConns[otherUser]) { - dataChannel.send("dataChannelPrimed"); - } - }; - dataChannel.onclose = function(event) { - if (self.debugPrinter) { - self.debugPrinter("saw dataChannelS.onclose event"); - } - if (peerConns[otherUser]) { - peerConns[otherUser].dataChannelReady = false; - delete peerConns[otherUser].dataChannelS; - } - if (onDataChannelClose) { - onDataChannelClose(otherUser); - } - - updateConfigurationInfo(); - }; - } - - function initIncomingChannel(otherUser) { - if (self.debugPrinter) { - self.debugPrinter("initializing incoming channel handler for " + otherUser); - } - - peerConns[otherUser].pc.ondatachannel = function(event) { - - if (self.debugPrinter) { - self.debugPrinter("saw incoming data channel"); - } - - var dataChannel = event.channel; - peerConns[otherUser].dataChannelR = dataChannel; - peerConns[otherUser].dataChannelS = dataChannel; - peerConns[otherUser].dataChannelReady = true; - dataChannel.onmessage = dataChannelMessageHandler; - dataChannel.onclose = function(event) { - if (self.debugPrinter) { - self.debugPrinter("saw dataChannelR.onclose event"); - } - if (peerConns[otherUser]) { - peerConns[otherUser].dataChannelReady = false; - delete peerConns[otherUser].dataChannelR; - } - if (onDataChannelClose) { - onDataChannelClose(otherUser); - } - - updateConfigurationInfo(); - }; - dataChannel.onopen = function(event) { - if (self.debugPrinter) { - self.debugPrinter("saw dataChannel.onopen event"); - } - if (peerConns[otherUser]) { - dataChannel.send("dataChannelPrimed"); - } - }; - }; - } - - // - // added for interoperability - // - var doDataChannels = dataEnabled; - if (doDataChannels) { - - // check if both sides have the same browser and versions - } - - if (doDataChannels) { - self.setPeerListener(function() { - peerConns[otherUser].dataChannelReady = true; - if (peerConns[otherUser].callSuccessCB) { - peerConns[otherUser].callSuccessCB(otherUser, "datachannel"); - } - if (onDataChannelOpen) { - onDataChannelOpen(otherUser, true); - } - updateConfigurationInfo(); - }, "dataChannelPrimed", otherUser); - if (isInitiator) { - try { - - initOutGoingChannel(otherUser); - } catch (channelErrorEvent) { - console.log("failed to init outgoing channel"); - failureCB(self.errCodes.SYSTEM_ERR, - self.formatError(channelErrorEvent)); - } - } - if (!isInitiator) { - initIncomingChannel(otherUser); - } - } - - pc.onconnection = function() { - if (self.debugPrinter) { - self.debugPrinter("setup pc.onconnection "); - } - }; - - // - // Temporary support for responding to acknowledgements of about streams being added. - // - self.setPeerListener(function(easyrtcid, msgType, msgData, targeting){ - if( newPeerConn.streamsAddedAcks[msgData.streamName]) { - (newPeerConn.streamsAddedAcks[msgData.streamName])(easyrtcid, msgData.streamName); - delete newPeerConn.streamsAddedAcks[msgData.streamName]; - } - }, "easyrtc_streamReceived", otherUser); - return pc; - }; - var doAnswer = function(caller, msgData, streamNames) { - if (!streamNames && autoInitUserMedia) { - var localStream = self.getLocalStream(); - if (!localStream && (videoEnabled || audioEnabled)) { - self.initMediaSource( - function() { - doAnswer(caller, msgData); - }, - function(errorCode, errorObj) { - self.showError(self.errCodes.MEDIA_ERR, self.format(self.getConstantString("localMediaError"))); - }); - return; - } - } - if (use_fresh_ice_each_peer) { - self.getFreshIceConfig(function(succeeded) { - if (succeeded) { - doAnswerBody(caller, msgData, streamNames); - } - else { - self.showError(self.errCodes.CALL_ERR, "Failed to get fresh ice config"); - } - }); - } - else { - doAnswerBody(caller, msgData, streamNames); - } - } - - - var doAnswerBody = function(caller, msgData, streamNames) { - var pc = buildPeerConnection(caller, false, function(message) { - self.showError(self.errCodes.SYSTEM_ERR, message); - }, streamNames); - var newPeerConn = peerConns[caller]; - if (!pc) { - if (self.debugPrinter) { - self.debugPrinter("buildPeerConnection failed. Call not answered"); - } - return; - } - var setLocalAndSendMessage1 = function(sessionDescription) { - if (newPeerConn.cancelled) - return; - var sendAnswer = function() { - if (self.debugPrinter) { - self.debugPrinter("sending answer"); - } - function onSignalSuccess() { - } - - function onSignalFailure(errorCode, errorText) { - delete peerConns[caller]; - self.showError(errorCode, errorText); - } - - sendSignalling(caller, "answer", sessionDescription, - onSignalSuccess, onSignalFailure); - peerConns[caller].connectionAccepted = true; - sendQueuedCandidates(caller, onSignalSuccess, onSignalFailure); - if (pc.connectDataConnection) { - if (self.debugPrinter) { - self.debugPrinter("calling connectDataConnection(5002,5001)"); - } - pc.connectDataConnection(5002, 5001); - } - }; - if (sdpLocalFilter) { - sessionDescription.sdp = sdpLocalFilter(sessionDescription.sdp); - } - pc.setLocalDescription(sessionDescription, sendAnswer, function(message) { - self.showError(self.errCodes.INTERNAL_ERR, "setLocalDescription: " + message); - }); - }; - var sd = null; - if (window.mozRTCSessionDescription) { - sd = new mozRTCSessionDescription(msgData); - } - else { - sd = new RTCSessionDescription(msgData); - } - if (self.debugPrinter) { - self.debugPrinter("sdp || " + JSON.stringify(sd)); - } - var invokeCreateAnswer = function() { - if (newPeerConn.cancelled) - return; - pc.createAnswer(setLocalAndSendMessage1, - function(message) { - self.showError(self.errCodes.INTERNAL_ERR, "create-answer: " + message); - }, - receivedMediaContraints); - }; - if (self.debugPrinter) { - self.debugPrinter("about to call setRemoteDescription in doAnswer"); - } - try { - - if (sdpRemoteFilter) { - sd.sdp = sdpRemoteFilter(sd.sdp); - } - pc.setRemoteDescription(sd, invokeCreateAnswer, function(message) { - self.showError(self.errCodes.INTERNAL_ERR, "set-remote-description: " + message); - }); - } catch (srdError) { - console.log("set remote description failed"); - if (self.debugPrinter) { - self.debugPrinter("saw exception in setRemoteDescription"); - } - self.showError(self.errCodes.INTERNAL_ERR, "setRemoteDescription failed: " + srdError.message); - } - }; - // - // This function calls the users onStreamClosed handler, passing it the easyrtcid of the peer, the stream itself, - // and the name of the stream. - // - function emitOnStreamClosed(easyrtcid, stream) { - if (!peerConns[easyrtcid]) { - return; - } - var streamName; - var id; - if (stream.hasOwnProperty("id")) { - id = stream.id; - } - else { - id = "default"; - } - streamName = peerConns[easyrtcid].remoteStreamIdToName[id] || "default"; - if (peerConns[easyrtcid].liveRemoteStreams[streamName] && - self.onStreamClosed) { - delete peerConns[easyrtcid].liveRemoteStreams[streamName]; - self.onStreamClosed(easyrtcid, stream, streamName); - } - delete peerConns[easyrtcid].remoteStreamIdToName[id]; - } - - var onRemoteHangup = function(caller) { - delete offersPending[caller]; - if (self.debugPrinter) { - self.debugPrinter("Saw onRemote hangup event"); - } - if (peerConns[caller]) { - peerConns[caller].cancelled = true; - if (peerConns[caller].pc) { - // - // close any remote streams. - // - var remoteStreams = peerConns[caller].pc.getRemoteStreams(); - if (remoteStreams) { - var i; - for (i = 0; i < remoteStreams.length; i++) { - emitOnStreamClosed(caller, remoteStreams[i]); - try { - remoteStreams[i].stop(); - } catch (err) { - } - ; - } - } - - try { - peerConns[caller].pc.close(); - } catch (anyErrors) { - } - } - else { - if (self.callCancelled) { - self.callCancelled(caller, true); - } - } - delete peerConns[caller]; - updateConfigurationInfo(); - } - else { - if (self.callCancelled) { - self.callCancelled(caller, true); - } - } - }; - var queuedMessages = {}; - var clearQueuedMessages = function(caller) { - queuedMessages[caller] = { - candidates: [] - }; - }; - // - // checks to see if a particular peer is in any room at all. - // - function isPeerInAnyRoom(id) { - var roomName; - for (roomName in lastLoggedInList) { - if (!lastLoggedInList.hasOwnProperty(roomName)) { - continue; - } - if (lastLoggedInList[roomName][id]) { - return true; - } - } - return false; - } - - /** - * Checks to see if a particular peer is present in any room. - * If it isn't, we assume it's logged out. - * @param easyrtcid the easyrtcId of the peer. - */ - this.isPeerInAnyRoom = function(easyrtcId) { - return isPeerInAnyRoom(easyrtcId); - } - - // - // - // - function processLostPeers(peersInRoom) { - var id; - // - // check to see the person is still in at least one room. If not, we'll hangup - // on them. This isn't the correct behavior, but it's the best we can do without - // changes to the server. - // - for (id in peerConns) { - if (peerConns.hasOwnProperty(id) && - typeof peersInRoom[id] === 'undefined') { - if (!isPeerInAnyRoom(id)) { - if (peerConns[id].pc || peerConns[id].isInitiator) { - onRemoteHangup(id); - } - delete offersPending[id]; - delete acceptancePending[id]; - clearQueuedMessages(id); - } - } - } - - for (id in offersPending) { - if (offersPending.hasOwnProperty(id) && !isPeerInAnyRoom(id)) { - onRemoteHangup(id); - clearQueuedMessages(id); - delete offersPending[id]; - delete acceptancePending[id]; - } - } - - for (id in acceptancePending) { - if (acceptancePending.hasOwnProperty(id) && !isPeerInAnyRoom(id)) { - onRemoteHangup(id); - clearQueuedMessages(id); - delete acceptancePending[id]; - } - } - - } - - /** - * The idea of aggregating timers is that there are events that convey state and these can fire more frequently - * than desired. Aggregating timers allow a bunch of events to be collapsed into one by only firing the last - * event. - * @private - */ - var aggregatingTimers = {}; - - /** - * This function sets a timeout for a function to be called with the feature that if another - * invocation comes along within a particular interval (with the same key), the second invocation - * replaces the first. To prevent a continuous stream of events from preventing a callback from ever - * firing, we'll collapse no more than 20 events. - * @param {String} key A key used to identify callbacks that should be aggregated. - * @param {Function} callback The callback to invoke. - * @param {Number} period The aggregating period in milliseconds. - * @private - */ - function addAggregatingTimer(key, callback, period) { - if( !period) { - period = 100; // 0.1 second - } - var counter = 0; - if( aggregatingTimers[key]) { - clearTimeout(aggregatingTimers[key].timer); - counter = aggregatingTimers[key].counter; - } - if( counter > 20) { - delete aggregatingTimers[key]; - callback(); - } - else { - aggregatingTimers[key] = {counter: counter +1}; - aggregatingTimers[key].timer = setTimeout(function () { - delete aggregatingTimers[key]; - callback(); - }, period); - } - } - - // - // this function gets called for each room when there is a room update. - // - function processOccupantList(roomName, occupantList) { - var myInfo = null; - self.reducedList = {}; - var id; - for (id in occupantList) { - if (occupantList.hasOwnProperty(id)) { - if (id === self.myEasyrtcid) { - myInfo = occupantList[id]; - } - else { - self.reducedList[id] = occupantList[id]; - } - } - } - // - // processLostPeers detects peers that have gone away and performs - // house keeping accordingly. - // - processLostPeers(self.reducedList); - // - // - // - addAggregatingTimer("roomOccupants&" + roomName, function(){ - if (roomOccupantListener) { - roomOccupantListener(roomName, self.reducedList, myInfo); - } - self.emitEvent("roomOccupants", {roomName:roomName, occupants:lastLoggedInList}); - }, 100); - - } - - function sendQueuedCandidates(peer, onSignalSuccess, onSignalFailure) { - var i; - for (i = 0; i < peerConns[peer].candidatesToSend.length; i++) { - sendSignalling( - peer, - "candidate", - peerConns[peer].candidatesToSend[i], - onSignalSuccess, - onSignalFailure - ); - } - } - - var onChannelMsg = function(msg, ackAcceptorFunc) { - - var targeting = {}; - if (ackAcceptorFunc) { - ackAcceptorFunc(self.ackMessage); - } - if (msg.targetEasyrtcid) { - targeting.targetEasyrtcid = msg.targetEasyrtcid; - } - if (msg.targetRoom) { - targeting.targetRoom = msg.targetRoom; - } - if (msg.targetGroup) { - targeting.targetGroup = msg.targetGroup; - } - if (msg.senderEasyrtcid) { - self.receivePeerDistribute(msg.senderEasyrtcid, msg, targeting); - } - else { - if (receiveServerCB) { - receiveServerCB(msg.msgType, msg.msgData, targeting); - } - else { - console.log("Unhandled server message " + JSON.stringify(msg)); - } - } - }; - var onChannelCmd = function(msg, ackAcceptorFn) { - - var caller = msg.senderEasyrtcid; - var msgType = msg.msgType; - var msgData = msg.msgData; - var pc; - if (self.debugPrinter) { - self.debugPrinter('received message of type ' + msgType); - } - - if (typeof queuedMessages[caller] === "undefined") { - clearQueuedMessages(caller); - } - - var processCandidateBody = function(caller, msgData) { - var candidate = null; - - if( iceCandidateFilter ) { - msgData = iceCandidateFilter(msgData, true); - if( !msgData ) { - return; - } - } - - if (window.mozRTCIceCandidate) { - candidate = new mozRTCIceCandidate({ - sdpMLineIndex: msgData.label, - candidate: msgData.candidate - }); - } - else { - candidate = new RTCIceCandidate({ - sdpMLineIndex: msgData.label, - candidate: msgData.candidate - }); - } - pc = peerConns[caller].pc; - - function iceAddSuccess() {} - function iceAddFailure(domError) { - easyrtc.showError(self.errCodes.ICECANDIDATE_ERR, "bad ice candidate (" + domError.name + "): " + - JSON.stringify(candidate)); - } - pc.addIceCandidate(candidate, iceAddSuccess, iceAddFailure); - - if (msgData.candidate.indexOf("typ relay") > 0) { - var ipAddress = msgData.candidate.match(/(udp|tcp) \d+ (\d+\.\d+\.\d+\.\d+)/i)[1]; - self._turnServers[ipAddress] = true; - } - }; - var flushCachedCandidates = function(caller) { - var i; - if (queuedMessages[caller]) { - for (i = 0; i < queuedMessages[caller].candidates.length; i++) { - processCandidateBody(caller, queuedMessages[caller].candidates[i]); - } - delete queuedMessages[caller]; - } - }; - var processOffer = function(caller, msgData) { - - var helper = function(wasAccepted, streamNames) { - - if (streamNames) { - if (typeof streamNames === "string") { - streamNames = [streamNames]; - } - else if (streamNames.length === undefined) { - easyrtc.showError(self.errCodes.DEVELOPER_ERR, "accept callback passed invalid streamNames"); - return; - } - } - if (self.debugPrinter) { - self.debugPrinter("offer accept=" + wasAccepted); - } - delete offersPending[caller]; - if (!self.supportsPeerConnections()) { - callFailureCB(self.errCodes.CALL_ERR, self.getConstantString("noWebrtcSupport")); - return; - } - - if (wasAccepted) { - doAnswer(caller, msgData, streamNames); - flushCachedCandidates(caller); - } - else { - sendSignalling(caller, "reject", null, null, null); - clearQueuedMessages(caller); - } - }; - // - // There is a very rare case of two callers sending each other offers - // before receiving the others offer. In such a case, the caller with the - // greater valued easyrtcid will delete its pending call information and do a - // simple answer to the other caller's offer. - // - if (acceptancePending[caller] && caller < self.myEasyrtcid) { - delete acceptancePending[caller]; - if (queuedMessages[caller]) { - delete queuedMessages[caller]; - } - if (peerConns[caller].wasAcceptedCB) { - peerConns[caller].wasAcceptedCB(true, caller); - } - delete peerConns[caller]; - helper(true); - return; - } - - offersPending[caller] = msgData; - if (!self.acceptCheck) { - helper(true); - } - else { - self.acceptCheck(caller, helper); - } - }; - function processReject(caller) { - delete acceptancePending[caller]; - if (queuedMessages[caller]) { - delete queuedMessages[caller]; - } - if (peerConns[caller]) { - if (peerConns[caller].wasAcceptedCB) { - peerConns[caller].wasAcceptedCB(false, caller); - } - delete peerConns[caller]; - } - } - - function processAnswer(caller, msgData) { - - - - delete acceptancePending[caller]; - - // - // if we've discarded the peer connection, ignore the answer. - // - if (!peerConns[caller]) { - return; - } - peerConns[caller].connectionAccepted = true; - - - - if (peerConns[caller].wasAcceptedCB) { - peerConns[caller].wasAcceptedCB(true, caller); - } - - var onSignalSuccess = function() { - - }; - var onSignalFailure = function(errorCode, errorText) { - if (peerConns[caller]) { - delete peerConns[caller]; - } - self.showError(errorCode, errorText); - }; - var i; - // peerConns[caller].startedAV = true; - sendQueuedCandidates(caller, onSignalSuccess, onSignalFailure); - pc = peerConns[caller].pc; - var sd = null; - if (window.mozRTCSessionDescription) { - sd = new mozRTCSessionDescription(msgData); - } - else { - sd = new RTCSessionDescription(msgData); - } - if (!sd) { - throw "Could not create the RTCSessionDescription"; - } - - if (self.debugPrinter) { - self.debugPrinter("about to call initiating setRemoteDescription"); - } - try { - if (sdpRemoteFilter) { - sd.sdp = sdpRemoteFilter(sd.sdp); - } - pc.setRemoteDescription(sd, function() { - if (pc.connectDataConnection) { - if (self.debugPrinter) { - self.debugPrinter("calling connectDataConnection(5001,5002)"); - } - pc.connectDataConnection(5001, 5002); // these are like ids for data channels - } - }, function(message){ - console.log("setRemoteDescription failed ", message); - }); - } catch (smdException) { - console.log("setRemoteDescription failed ", smdException); - } - flushCachedCandidates(caller); - } - - function processCandidateQueue(caller, msgData) { - - if (peerConns[caller] && peerConns[caller].pc) { - processCandidateBody(caller, msgData); - } - else { - if (!peerConns[caller]) { - queuedMessages[caller] = { - candidates: [] - }; - } - queuedMessages[caller].candidates.push(msgData); - } - } - - switch (msgType) { - case "sessionData": - processSessionData(msgData.sessionData); - break; - case "roomData": - processRoomData(msgData.roomData); - break; - case "iceConfig": - processIceConfig(msgData.iceConfig); - break; - case "forwardToUrl": - if (msgData.newWindow) { - window.open(msgData.forwardToUrl.url); - } - else { - window.location.href = msgData.forwardToUrl.url; - } - break; - case "offer": - processOffer(caller, msgData); - break; - case "reject": - processReject(caller); - break; - case "answer": - processAnswer(caller, msgData); - break; - case "candidate": - processCandidateQueue(caller, msgData); - break; - case "hangup": - onRemoteHangup(caller); - clearQueuedMessages(caller); - break; - case "error": - self.showError(msg.errorCode, msg.errorText); - break; - default: - console.error("received unknown message type from server, msgType is " + msgType); - return; - } - - if (ackAcceptorFn) { - ackAcceptorFn(self.ackMessage); - } - }; - function connectToWSServer(successCallback, errorCallback) { - var i; - if (preallocatedSocketIo) { - self.webSocket = preallocatedSocketIo; - } - else if (!self.webSocket) { - try { - self.webSocket = io.connect(serverPath, connectionOptions); - } catch(socketErr) { - errorCallback( self.errCodes.SYSTEM_ERROR, - socketError.toString()); - return; - } - if (!self.webSocket) { - throw "io.connect failed"; - } - } - else { - for (i in self.websocketListeners) { - if (!self.websocketListeners.hasOwnProperty(i)) { - continue; - } - self.webSocket.removeEventListener(self.websocketListeners[i].event, - self.websocketListeners[i].handler); - } - } - self.websocketListeners = []; - function addSocketListener(event, handler) { - self.webSocket.on(event, handler); - self.websocketListeners.push({event: event, handler: handler}); - } - - addSocketListener("close", function(event) { - console.log("the web socket closed"); - }); - addSocketListener('error', function(event) { - function handleErrorEvent() { - if (self.myEasyrtcid) { - // - // socket.io version 1 got rid of the socket member, moving everything up one level. - // - if (self.webSocket.connected || (self.webSocket.socket && self.webSocket.socket.connected)) { - self.showError(self.errCodes.SIGNAL_ERROR, self.getConstantString("miscSignalError")); - } - else { - /* socket server went down. this will generate a 'disconnect' event as well, so skip this event */ - errorCallback(self.errCodes.CONNECT_ERR, self.getConstantString("noServer")); - } - } - else { - errorCallback(self.errCodes.CONNECT_ERR, self.getConstantString("noServer")); - } - } - handleErrorEvent(); - }); - function connectHandler(event) { - self.webSocketConnected = true; - if (!self.webSocket) { - self.showError(self.errCodes.CONNECT_ERR, self.getConstantString("badsocket")); - } - - if (self.debugPrinter) { - self.debugPrinter("saw socketserver onconnect event"); - } - if (self.webSocketConnected) { - sendAuthenticate(successCallback, errorCallback); - } - else { - errorCallback(self.errCodes.SIGNAL_ERROR, self.getConstantString("icf")); - } - } - if (preallocatedSocketIo && preallocatedSocketIo.socket.connected) { - connectHandler(null); - } - else { - addSocketListener("connect", connectHandler); - } - addSocketListener("easyrtcMsg", onChannelMsg); - addSocketListener("easyrtcCmd", onChannelCmd); - addSocketListener("disconnect", function(/* code, reason, wasClean */) { - self.webSocketConnected = false; - updateConfigurationInfo = function() { - }; // dummy update function - oldConfig = {}; - disconnectBody(); - if (self.disconnectListener) { - self.disconnectListener(); - } - }); - } - - - function buildDeltaRecord(added, deleted, modified) { - function objectNotEmpty(obj) { - var i; - for (i in obj) { - if (obj.hasOwnProperty(i)) { - return true; - } - } - return false; - } - - var result = {}; - if (objectNotEmpty(added)) { - result.added = added; - } - - if (objectNotEmpty(deleted)) { - result.deleted = deleted; - } - - if (objectNotEmpty(result)) { - return result; - } - else { - return null; - } - } - - function findDeltas(oldVersion, newVersion) { - var i; - var added = {}, deleted = {}; - var subPart; - for (i in newVersion) { - if (!newVersion.hasOwnProperty(i)) { - // do nothing - } - else if (oldVersion === null || typeof oldVersion[i] === 'undefined') { - added[i] = newVersion[i]; - } - else if (typeof newVersion[i] === 'object') { - subPart = findDeltas(oldVersion[i], newVersion[i]); - if (subPart !== null) { - added[i] = newVersion[i]; - } - } - else if (newVersion[i] !== oldVersion[i]) { - added[i] = newVersion[i]; - } - } - for (i in oldVersion) { - if (!newVersion.hasOwnProperty(i)) { - // do nothing - } - else if (typeof newVersion[i] === 'undefined') { - deleted = oldVersion[i]; - } - } - - return buildDeltaRecord(added, deleted); - } - -// -// this function collects configuration info that will be sent to the server. -// It returns that information, leaving it the responsibility of the caller to -// do the actual sending. -// - function collectConfigurationInfo(/* forAuthentication */) { - var p2pList = {}; - var i; - for (i in peerConns) { - if (!peerConns.hasOwnProperty(i)) { - continue; - } - p2pList[i] = { - connectTime: peerConns[i].connectTime, - isInitiator: !!peerConns[i].isInitiator - }; - } - - var newConfig = { - userSettings: { - sharingAudio: !!haveAudioVideo.audio, - sharingVideo: !!haveAudioVideo.video, - sharingData: !!dataEnabled, - nativeVideoWidth: self.nativeVideoWidth, - nativeVideoHeight: self.nativeVideoHeight, - windowWidth: window.innerWidth, - windowHeight: window.innerHeight, - screenWidth: window.screen.width, - screenHeight: window.screen.height, - cookieEnabled: navigator.cookieEnabled, - os: navigator.oscpu, - language: navigator.language - } - }; - if (!isEmptyObj(p2pList)) { - newConfig.p2pList = p2pList; - } - return newConfig; - } - ; - function updateConfiguration() { - - var newConfig = collectConfigurationInfo(false); - // - // we need to give the getStats calls a chance to fish out the data. - // The longest I've seen it take is 5 milliseconds so 100 should be overkill. - // - var sendDeltas = function() { - var alteredData = findDeltas(oldConfig, newConfig); - // - // send all the configuration information that changes during the session - // - if (alteredData) { - if (self.debugPrinter) { - self.debugPrinter("cfg=" + JSON.stringify(alteredData.added)); - } - if (self.webSocket) { - sendSignalling(null, "setUserCfg", {setUserCfg: alteredData.added}, null, null); - } - } - oldConfig = newConfig; - }; - if (oldConfig === {}) { - sendDeltas(); - } - else { - setTimeout(sendDeltas, 100); - } - } - - updateConfigurationInfo = function() { - updateConfiguration(); - }; - /** - * Sets the presence state on the server. - * @param {String} state - one of 'away','chat','dnd','xa' - * @param {String} statusText - User configurable status string. May be length limited. - * @example easyrtc.updatePresence('dnd', 'sleeping'); - */ - this.updatePresence = function(state, statusText) { - self.presenceShow = state; - self.presenceStatus = statusText; - if (self.webSocketConnected) { - sendSignalling(null, 'setPresence', {setPresence: {'show': state, 'status': statusText}}, null); - } - }; - /** - * Fetch the collection of session fields as a map. The map has the structure: - * {key1: {"fieldName": key1, "fieldValue": value1}, ..., - * key2: {"fieldName": key2, "fieldValue": value2} - * } - * @returns {Object} - */ - this.getSessionFields = function() { - return sessionFields; - }; - /** - * Fetch the value of a session field by name. - * @param {String} name - name of the session field to be fetched. - * @returns the field value (which can be anything). Returns undefined if the field does not exist. - */ - this.getSessionField = function(name) { - if (sessionFields[name]) { - return sessionFields[name].fieldValue; - } - else { - return undefined; - } - }; - function processSessionData(sessionData) { - if (sessionData) { - if (sessionData.easyrtcsid) { - self.easyrtcsid = sessionData.easyrtcsid; - } - if (sessionData.field) { - sessionFields = sessionData.field; - } - } - } - - - function processRoomData(roomData) { - self.roomData = roomData; - var roomName; - var stuffToRemove; - var stuffToAdd; - var id, removeId; - for (roomName in self.roomData) { - if (!self.roomData.hasOwnProperty(roomName)) { - continue; - } - if (roomData[roomName].roomStatus === "join") { - if (!(self.roomJoin[roomName])) { - self.roomJoin[roomName] = roomData[roomName]; - } - var mediaIds = buildMediaIds(); - if (mediaIds !== {}) { - self.setRoomApiField(roomName, "mediaIds", mediaIds); - } - } - else if (roomData[roomName].roomStatus === "leave") { - if (self.roomEntryListener) { - self.roomEntryListener(false, roomName); - } - delete self.roomJoin[roomName]; - delete lastLoggedInList[roomName]; - continue; - } - - if (roomData[roomName].clientList) { - lastLoggedInList[roomName] = roomData[roomName].clientList; - } - else if (roomData[roomName].clientListDelta) { - stuffToAdd = roomData[roomName].clientListDelta.updateClient; - if (stuffToAdd) { - for (id in stuffToAdd) { - if (!stuffToAdd.hasOwnProperty(id)) { - continue; - } - if (!lastLoggedInList[roomName]) { - lastLoggedInList[roomName] = []; - } - lastLoggedInList[roomName][id] = stuffToAdd[id]; - } - } - stuffToRemove = roomData[roomName].clientListDelta.removeClient; - if (stuffToRemove && lastLoggedInList[roomName]) { - for (removeId in stuffToRemove) { - if (stuffToRemove.hasOwnProperty(removeId)) { - delete lastLoggedInList[roomName][removeId]; - } - } - } - } - if (self.roomJoin[roomName] && roomData[roomName].field) { - fields.rooms[roomName] = roomData[roomName].field; - } - if (roomData[roomName].roomStatus === "join") { - if (self.roomEntryListener) { - self.roomEntryListener(true, roomName); - } - } - processOccupantList(roomName, lastLoggedInList[roomName]); - } - self.emitEvent("roomOccupant", lastLoggedInList); - } - - /** - * Returns an array of easyrtcid's of peers in a particular room. - * @param roomName - * @returns {Array} of easyrtcids or null if the client is not in the room. - * @example - * var occupants = easyrtc.getRoomOccupants("default"); - * var i; - * for( i = 0; i < occupants.length; i++ ) { - * console.log( occupants[i] + " is in the room"); - * } - */ - this.getRoomOccupantsAsArray = function(roomName) { - if (!lastLoggedInList[roomName]) { - return null; - } - else { - return Object.keys(lastLoggedInList[roomName]); - } - } - - /** - * Returns a map of easyrtcid's of peers in a particular room. You should only test elements in the map to see if they are - * null; their actual values are not guaranteed to be the same in different releases. - * @param roomName - * @returns {Object} of easyrtcids or null if the client is not in the room. - * @example - * if( easyrtc.getRoomOccupantsAsMap("default")[some_easyrtcid]) { - * console.log("yep, " + some_easyrtcid + " is in the room"); - * } - */ - this.getRoomOccupantsAsMap = function(roomName) { - return lastLoggedInList[roomName]; - } - - /** - * Returns true if the ipAddress parameter was the address of a turn server. This is done by checking against information - * collected during peer to peer calls. Don't expect it to work before the first call, or to identify turn servers that aren't - * in the ice config. - * @param ipAddress - * @returns {boolean} true if ip address is known to be that of a turn server, false otherwise. - */ - this.isTurnServer = function(ipAddress) { - return !!self._turnServers[ipAddress]; - }; - function processIceConfig(iceConfig) { - pc_config = {iceServers: []}; - self._turnServers = {}; - var i; - var item, fixedItem, username, ipAddress; - if (!window.createIceServer) { - return; - } - for (i = 0; i < iceConfig.iceServers.length; i++) { - item = iceConfig.iceServers[i]; - if (item.url.indexOf('turn:') === 0) { - if (item.username) { - fixedItem = createIceServer(item.url, item.username, item.credential); - } - else { - self.showError("Developer error", "Iceserver entry doesn't have a username: " + JSON.stringify(item)); - } - ipAddress = item.url.split(/[@:&]/g)[1]; - self._turnServers[ipAddress] = true; - } - else { // is stun server entry - fixedItem = item; - } - if (fixedItem) { - pc_config.iceServers.push(fixedItem); - } - } - } - - /** - * Request fresh ice config information from the server. - * This should be done periodically by long running applications. - * @param {Function} callback is called with a value of true on success, false on failure. - */ - this.getFreshIceConfig = function(callback) { - var dataToShip = { - msgType: "getIceConfig", - msgData: {} - }; - if (!callback) { - callback = function() { - }; - } - self.webSocket.json.emit("easyrtcCmd", dataToShip, - function(ackMsg) { - if (ackMsg.msgType === "iceConfig") { - processIceConfig(ackMsg.msgData.iceConfig); - callback(true); - } - else { - self.showError(ackMsg.msgData.errorCode, ackMsg.msgData.errorText); - callback(false); - } - } - ); - }; - function processToken(msg) { - if (self.debugPrinter) { - self.debugPrinter("entered process token"); - } - var msgData = msg.msgData; - if (msgData.easyrtcid) { - self.myEasyrtcid = msgData.easyrtcid; - } - if (msgData.field) { - fields.connection = msgData.field; - } - if (msgData.iceConfig) { - processIceConfig(msgData.iceConfig); - } - - if (msgData.sessionData) { - processSessionData(msgData.sessionData); - } - - if (msgData.roomData) { - processRoomData(msgData.roomData); - } - - if (msgData.application.field) { - fields.application = msgData.application.field; - } - - } - - function sendAuthenticate(successCallback, errorCallback) { - // - // find our easyrtcsid - // - var cookies, target, i; - var easyrtcsid = null; - if (self.cookieId && document.cookie) { - cookies = document.cookie.split(/[; ]/g); - target = self.cookieId + "="; - for (i = 0; i < cookies.length; i++) { - if (cookies[i].indexOf(target) === 0) { - easyrtcsid = cookies[i].substring(target.length); - } - } - } - - if (!self.roomJoin) { - self.roomJoin = {}; - } - - var msgData = { - apiVersion: self.apiVersion, - applicationName: self.applicationName, - setUserCfg: collectConfigurationInfo(true) - }; - if (self.presenceShow) { - msgData.setPresence = {show: self.presenceShow, status: self.presenceStatus}; - } - if (self.username) { - msgData.username = self.username; - } - if (self.roomJoin && !isEmptyObj(self.roomJoin)) { - msgData.roomJoin = self.roomJoin; - } - if (easyrtcsid) { - msgData.easyrtcsid = easyrtcsid; - } - if (credential) { - msgData.credential = credential; - } - - self.webSocket.json.emit("easyrtcAuth", - {msgType: "authenticate", - msgData: msgData - }, - function(msg) { - var room; - if (msg.msgType === "error") { - errorCallback(msg.msgData.errorCode, msg.msgData.errorText); - self.roomJoin = {}; - } - else { - processToken(msg); - if (self._roomApiFields) { - for (room in self._roomApiFields) { - if (self._roomApiFields.hasOwnProperty(room)) { - _enqueueSendRoomApi(room, self._roomApiFields[room]); - } - } - } - - if (successCallback) { - successCallback(self.myEasyrtcid); - } - } - } - ); - } - - /** Get a list of the rooms you are in. You must be connected to call this function. - * @returns {Object} A map whose keys are the room names - */ - this.getRoomsJoined = function() { - var roomsIn = {}; - var key; - for (key in self.roomJoin) { - if (self.roomJoin.hasOwnProperty(key)) { - roomsIn[key] = true; - } - } - return roomsIn; - }; - /** Get server defined fields associated with a particular room. Only valid - * after a connection has been made. - * @param {String} roomName - the name of the room you want the fields for. - * @returns {Object} A dictionary containing entries of the form {key:{'fieldName':key, 'fieldValue':value1}} or undefined - * if you are not connected to the room. - */ - this.getRoomFields = function(roomName) { - if (!fields || !fields.rooms || !fields.rooms[roomName]) - return undefined; - return fields.rooms[roomName]; - }; - /** Get server defined fields associated with the current application. Only valid - * after a connection has been made. - * @returns {Object} A dictionary containing entries of the form {key:{'fieldName':key, 'fieldValue':value1}} - */ - this.getApplicationFields = function() { - return fields.application; - }; - /** Get server defined fields associated with the connection. Only valid - * after a connection has been made. - * @returns {Object} A dictionary containing entries of the form {key:{'fieldName':key, 'fieldValue':value1}} - */ - this.getConnectionFields = function() { - return fields.connection; - }; -// this flag controls whether the easyApp routine adds close buttons to the caller -// video objects - - /** @private */ - var autoAddCloseButtons = true; - /** By default, the easyApp routine sticks a "close" button on top of each caller - * video object that it manages. Call this function(before calling easyApp) to disable that particular feature. - * @example - * easyrtc.dontAddCloseButtons(); - */ - this.dontAddCloseButtons = function() { - autoAddCloseButtons = false; - }; - /** - * Validates that the video ids correspond to dom objects. - * @param {String} monitorVideoId - * @param {Array} videoIds - * @returns {Boolean} - * @private - */ - function _validateVideoIds(monitorVideoId, videoIds) { - var i; - // verify that video ids were not typos. - if (monitorVideoId && !document.getElementById(monitorVideoId)) { - self.showError(self.errCodes.DEVELOPER_ERR, "The monitor video id passed to easyApp was bad, saw " + monitorVideoId); - return false; - } - - for (i in videoIds) { - if (!videoIds.hasOwnProperty(i)) { - continue; - } - var name = videoIds[i]; - if (!document.getElementById(name)) { - self.showError(self.errCodes.DEVELOPER_ERR, "The caller video id '" + name + "' passed to easyApp was bad."); - return false; - } - } - return true; - } - ; - /** - * This is a helper function for the easyApp method. It manages the assignment of video streams - * to video objects. It assumes - * @param {String} monitorVideoId is the id of the mirror video tag. - * @param {Array} videoIds is an array of ids of the caller video tags. - * @private - */ - function easyAppBody(monitorVideoId, videoIds) { - var numPEOPLE = videoIds.length; - var videoIdsP = videoIds; - var refreshPane = 0; - var onCall = null, onHangup = null; - - if (!videoIdsP) { - videoIdsP = []; - } - - easyrtc.addEventListener("roomOccupants", - function(eventName, eventData) { - for (i = 0; i < numPEOPLE; i++) { - var video = getIthVideo(i); - if (!videoIsFree(video)) { - if( !easyrtc.isPeerInAnyRoom(video.dataset.caller)){ - if( onHangup ) { - onHangup(i, easyrtc.dataset.caller); - } - easyrtc.dataset.caller = null; - } - } - } - } - ); - - function videoIsFree(obj) { - return (obj.dataset.caller === "" || obj.dataset.caller === null || obj.dataset.caller === undefined); - } - - if (!_validateVideoIds(monitorVideoId, videoIdsP)) { - throw "bad video element id"; - } - - if (monitorVideoId) { - document.getElementById(monitorVideoId).muted = "muted"; - } - - /** Sets an event handler that gets called when an incoming MediaStream is assigned - * to a video object. The name is poorly chosen and reflects a simpler era when you could - * only have one media stream per peer connection. - * @param {Function} cb has the signature function(easyrtcid, slot){} - * @example - * easyrtc.setOnCall( function(easyrtcid, slot){ - * console.log("call with " + easyrtcid + "established"); - * }); - */ - self.setOnCall = function(cb) { - onCall = cb; - }; - /** Sets an event handler that gets called when a call is ended. - * it's only purpose (so far) is to support transitions on video elements. - x * this function is only defined after easyrtc.easyApp is called. - * The slot is parameter is the index into the array of video ids. - * Note: if you call easyrtc.getConnectionCount() from inside your callback - * it's count will reflect the number of connections before the hangup started. - * @param {Function} cb has the signature function(easyrtcid, slot){} - * @example - * easyrtc.setOnHangup( function(easyrtcid, slot){ - * console.log("call with " + easyrtcid + "ended"); - * }); - */ - self.setOnHangup = function(cb) { - onHangup = cb; - }; - - function getIthVideo(i) { - if (videoIdsP[i]) { - return document.getElementById(videoIdsP[i]); - } - else { - return null; - } - } - - - self.getIthCaller = function(i) { - if (i < 0 || i > videoIdsP.length) { - return null; - } - var vid = getIthVideo(i); - return vid.dataset.caller; - }; - - self.getSlotOfCaller = function(easyrtcid) { - var i; - for (i = 0; i < numPEOPLE; i++) { - if (self.getIthCaller(i) === easyrtcid) { - return i; - } - } - return -1; // caller not connected - }; - function hideVideo(video) { - self.setVideoObjectSrc(video, ""); - video.style.visibility = "hidden"; - } - - self.setOnStreamClosed(function(caller) { - var i; - for (i = 0; i < numPEOPLE; i++) { - var video = getIthVideo(i); - if (video.dataset.caller === caller) { - hideVideo(video); - video.dataset.caller = ""; - if (onHangup) { - onHangup(caller, i); - } - } - } - }); - // - // Only accept incoming calls if we have a free video object to display - // them in. - // - self.setAcceptChecker(function(caller, helper) { - var i; - for (i = 0; i < numPEOPLE; i++) { - var video = getIthVideo(i); - if (videoIsFree(video)) { - helper(true); - return; - } - } - helper(false); - }); - self.setStreamAcceptor(function(caller, stream) { - var i; - if (self.debugPrinter) { - self.debugPrinter("stream acceptor called"); - } - function showVideo(video, stream) { - self.setVideoObjectSrc(video, stream); - if (video.style.visibility) { - video.style.visibility = 'visible'; - } - } - - var video; - if (refreshPane && videoIsFree(refreshPane)) { - showVideo(refreshPane, stream); - if (onCall) { - onCall(caller, refreshPane); - } - refreshPane = null; - return; - } - for (i = 0; i < numPEOPLE; i++) { - video = getIthVideo(i); - if (video.dataset.caller === caller) { - showVideo(video, stream); - if (onCall) { - onCall(caller, i); - } - return; - } - } - - for (i = 0; i < numPEOPLE; i++) { - video = getIthVideo(i); - if (!video.dataset.caller || videoIsFree(video)) { - video.dataset.caller = caller; - if (onCall) { - onCall(caller, i); - } - showVideo(video, stream); - return; - } - } -// -// no empty slots, so drop whatever caller we have in the first slot and use that one. -// - video = getIthVideo(0); - if (video) { - self.hangup(video.dataset.caller); - showVideo(video, stream); - if (onCall) { - onCall(caller, 0); - } - } - video.dataset.caller = caller; - }); - (function() { - var addControls, parentDiv, closeButton, i; - if (autoAddCloseButtons) { - - addControls = function(video) { - parentDiv = video.parentNode; - video.dataset.caller = ""; - closeButton = document.createElement("div"); - closeButton.className = "easyrtc_closeButton"; - closeButton.onclick = function() { - if (video.dataset.caller) { - self.hangup(video.dataset.caller); - hideVideo(video); - video.dataset.caller = ""; - } - }; - parentDiv.appendChild(closeButton); - }; - for (i = 0; i < numPEOPLE; i++) { - addControls(getIthVideo(i)); - } - } - })(); - var monitorVideo = null; - if (videoEnabled && monitorVideoId !== null) { - monitorVideo = document.getElementById(monitorVideoId); - if (!monitorVideo) { - console.error("Programmer error: no object called " + monitorVideoId); - return; - } - monitorVideo.muted = "muted"; - monitorVideo.defaultMuted = true; - } - - - } - ; - /** - * Provides a layer on top of the easyrtc.initMediaSource and easyrtc.connect, assign the local media stream to - * the video object identified by monitorVideoId, assign remote video streams to - * the video objects identified by videoIds, and then call onReady. One of it's - * side effects is to add hangup buttons to the remote video objects, buttons - * that only appear when you hover over them with the mouse cursor. This method will also add the - * easyrtcMirror class to the monitor video object so that it behaves like a mirror. - * @param {String} applicationName - name of the application. - * @param {String} monitorVideoId - the id of the video object used for monitoring the local stream. - * @param {Array} videoIds - an array of video object ids (strings) - * @param {Function} onReady - a callback function used on success. It is called with the easyrtcId this peer is known to the server as. - * @param {Function} onFailure - a callback function used on failure (failed to get local media or a connection of the signaling server). - * @example - * easyrtc.easyApp('multiChat', 'selfVideo', ['remote1', 'remote2', 'remote3'], - * function(easyrtcId){ - * console.log("successfully connected, I am " + easyrtcId); - * }, - * function(errorCode, errorText){ - * console.log(errorText); - * ); - */ - this.easyApp = function(applicationName, monitorVideoId, videoIds, onReady, onFailure) { - var gotMediaCallback = null, - gotConnectionCallback = null; - easyAppBody(monitorVideoId, videoIds); - self.setGotMedia = function(gotMediaCB) { - gotMediaCallback = gotMediaCB; - }; - /** Sets an event handler that gets called when a connection to the signaling - * server has or has not been made. Can only be called after calling easyrtc.easyApp. - * @param {Function} gotConnectionCB has the signature (gotConnection, errorText) - * @example - * easyrtc.setGotConnection( function(gotConnection, errorText){ - * if( gotConnection ){ - * console.log("Successfully connected to signaling server"); - * } - * else{ - * console.log("Failed to connect to signaling server because: " + errorText); - * } - * }); - */ - self.setGotConnection = function(gotConnectionCB) { - gotConnectionCallback = gotConnectionCB; - }; - var nextInitializationStep; - nextInitializationStep = function(/* token */) { - if (gotConnectionCallback) { - gotConnectionCallback(true, ""); - } - onReady(self.myEasyrtcid); - }; - function postGetUserMedia() { - if (gotMediaCallback) { - gotMediaCallback(true, null); - } - if (monitorVideoId !== null) { - self.setVideoObjectSrc(document.getElementById(monitorVideoId), self.getLocalStream()); - } - function connectError(errorCode, errorText) { - if (gotConnectionCallback) { - gotConnectionCallback(false, errorText); - } - else if (onFailure) { - onFailure(self.errCodes.CONNECT_ERR, errorText); - } - else { - self.showError(self.errCodes.CONNECT_ERR, errorText); - } - } - - self.connect(applicationName, nextInitializationStep, connectError); - } - - var stream = getLocalMediaStreamByName(null); - if (stream) { - postGetUserMedia(); - } - else { - self.initMediaSource( - postGetUserMedia, - function(errorCode, errorText) { - if (gotMediaCallback) { - gotMediaCallback(false, errorText); - } - else if (onFailure) { - onFailure(self.errCodes.MEDIA_ERR, errorText); - } - else { - self.showError(self.errCodes.MEDIA_ERR, errorText); - } - }, - null // default stream - ); - } - }; - /** - * - * @deprecated now called easyrtc.easyApp. - */ - this.initManaged = this.easyApp; - var preallocatedSocketIo = null; - /** - * Supply a socket.io connection that will be used instead of allocating a new socket. - * The expected usage is that you allocate a websocket, assign options to it, call - * easyrtc.useThisSocketConnection, followed by easyrtc.connect or easyrtc.easyApp. Easyrtc will not attempt to - * close sockets that were supplied with easyrtc.useThisSocketConnection. - * @param {Object} alreadyAllocatedSocketIo A value allocated with the connect method of socket.io. - */ - this.useThisSocketConnection = function(alreadyAllocatedSocketIo) { - preallocatedSocketIo = alreadyAllocatedSocketIo; - } - /** - * Connect to the easyrtc signaling server. - * @param applicationName - * @param successCallback - * @param errorCallback - */ - this.connect = function(applicationName, successCallback, errorCallback) { - - if (!window.io) { - self.showError("Developer error", "Your HTML has not included the socket.io.js library"); - } - - if (!preallocatedSocketIo && self.webSocket) { - console.error("Developer error: attempt to connect when already connected to socket server"); - return; - } - pc_config = {}; - closedChannel = null; - oldConfig = {}; // used internally by updateConfiguration - queuedMessages = {}; - self.applicationName = applicationName; - fields = { - rooms: {}, - application: {}, - connection: {} - }; - if (self.debugPrinter) { - self.debugPrinter("attempt to connect to WebRTC signalling server with application name=" + applicationName); - } - - if (errorCallback === null) { - errorCallback = function(errorCode, errorText) { - console.error("easyrtc.connect: " + errorText); - }; - } - - connectToWSServer(successCallback, errorCallback); - }; -}; -window.easyrtc = new Easyrtc(); - -var easyrtc_constantStrings = { - "unableToEnterRoom":"Unable to enter room {0} because {1}" , - "resolutionWarning": "Requested video size of {0}x{1} but got size of {2}x{3}", - "badUserName": "Illegal username {0}", - "localMediaError": "Error getting local media stream: {0}", - "miscSignalError": "Miscellaneous error from signalling server. It may be ignorable.", - "noServer": "Unable to reach the EasyRTC signalling server.", - "badsocket": "Socket.io connect event fired with bad websocket.", - "icf": "Internal communications failure", - "statsNotSupported":"call statistics not supported by this browser, try Chrome.", - "noWebrtcSupport":"Your browser doesn't appear to support WebRTC.", - "gumFailed":"Failed to get access to local media. Error code was {0}.", - "requireAudioOrVideo":"At least one of audio and video must be provided" -}; \ No newline at end of file diff --git a/messenger/js/easyrtc/node_modules/easyrtc/api/easyrtc_ft.js b/messenger/js/easyrtc/node_modules/easyrtc/api/easyrtc_ft.js deleted file mode 100644 index b5a820b68e..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/api/easyrtc_ft.js +++ /dev/null @@ -1,748 +0,0 @@ -/** @class - *@version 1.0.13 - *

- * Provides support file and data transfer support to easyrtc. - *

- *

- *copyright Copyright (c) 2014, Priologic Software Inc. - *All rights reserved.

- * - *

- *Redistribution and use in source and binary forms, with or without - *modification, are permitted provided that the following conditions are met: - *

- *
    - *
  • Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer.
  • - *
  • Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution.
  • - *
- *

- *THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - *AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - *IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - *ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - *LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - *CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - *SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - *INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - *CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - *ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - *POSSIBILITY OF SUCH DAMAGE. - *

- */ - - -var easyrtc_ft = {}; - -/** - * Establish an area as a drag-n-drop drop site for files. - * @param {DOMString} droptargetName - the id of the drag-and-drop site or the actual DOM object. - * @param {Function} filesHandler - function that accepts an array of File's. - */ -easyrtc_ft.buildDragNDropRegion = function(droptargetName, filesHandler) { - var droptarget; - if (typeof droptargetName === 'string') { - droptarget = document.getElementById(droptargetName); - if (!droptarget) { - alert("Developer error: attempt to call BuildFileSender on unknown object " + droptargetName); - throw("unknown object " + droptargetName); - } - } - else { - droptarget = droptargetName; - } - - - function ignore(e) { - e.stopPropagation(); - e.preventDefault(); - return false; - } - - function drageventcancel(e) { - if (e.preventDefault) - e.preventDefault(); // required by FF + Safari - e.dataTransfer.dropEffect = 'copy'; // tells the browser what drop effect is allowed here - return false; // required by IE - } - - function dropHandler(e) { - removeClass(droptarget, dropCueClass); - var dt = e.dataTransfer; - var files = dt.files; - if (dt.files.length > 0) { - try { - filesHandler(files); - } catch (errorEvent) { - console.log("dragndrop errorEvent", errorEvent); - } - } - return ignore(e); - } - - - var dropCueClass = "easyrtcfiledrop"; - - function dragEnterHandler(e) { - addClass(droptarget, dropCueClass); - return drageventcancel(e); - } - - - function dragLeaveHandler(e) { - removeClass(droptarget, dropCueClass); - return drageventcancel(e); - } - - var addEvent = (function() { - if (document.addEventListener) { - return function(el, type, fn) { - if (el && el.nodeName || el === window) { - el.addEventListener(type, fn, false); - } else if (el && el.length) { - for (var i = 0; i < el.length; i++) { - addEvent(el[i], type, fn); - } - } - }; - } else { - return function(el, type, fn) { - if (el && el.nodeName || el === window) { - el.attachEvent('on' + type, function() { - return fn.call(el, window.event); - }); - } else if (el && el.length) { - for (var i = 0; i < el.length; i++) { - addEvent(el[i], type, fn); - } - } - }; - } - })(); - - droptarget.ondrop = dropHandler; - droptarget.ondragenter = dragEnterHandler; - droptarget.ondragleave = dragLeaveHandler; - droptarget.ondragover = drageventcancel; - - function addClass(target, classname) { - if (target.className) { - if (target.className.indexOf(classname, 0) >= 0) { - return; - } - else { - target.className = target.className + " " + classname; - } - } - else { - target.className = classname; - } - target.className = target.className.replace(" ", " "); - } - - function removeClass(target, classname) { - if (!target.className) { - return; - } - target.className = target.className.replace(classname, "").replace(" ", " "); - } -}; - -/** - * Builds a function that can be used to send a group of files to a peer. - * @param {String} destUser easyrtcid of the person being sent to. - * @param {Function} progressListener - if provided, is called with the following objects: - * {status:"waiting"} // once a file offer has been sent but not accepted or rejected yet - * {status:"started_file", name: filename} - * {status:"working", name:filename, position:position_in_file, size:size_of_current_file, numFiles:number_of_files_left} - * {status:"cancelled"} // if the remote user cancels the sending - * {status:"done"} // when the file is done - * the progressListener should always return true for normal operation, false to cancel a filetransfer. - * @return {Function} an object that accepts an array of File (the Files to be sent), and a boolean - * argument that is true if the files are binary, false if they are text. - * It is safe to treat all files as binary, it will just require more bandwidth. - */ -easyrtc_ft.buildFileSender = function(destUser, progressListener) { - var droptarget; - var seq = 0; - var positionAcked = 0; - var filePosition = 0; - var filesOffered = []; - var filesBeingSent = []; - var sendStarted = false; - var curFile = null; - var curFileSize; - var filesAreBinary; - var maxChunkSize = 10 * 1024; - var waitingForAck = false; - var ackThreshold = 100 * 1024; // send is allowed to be 150KB ahead of receiver - var filesWaiting = []; - var haveFilesWaiting = false; - - if (!progressListener) { - progressListener = function() { - return true; - }; - } - - var roomOccupantListener = function(eventType, eventData) { - var roomName; - var foundUser = false; - for (roomName in eventData) { - if (eventData[roomName][destUser]) { - foundUser = true; - } - } - if (!foundUser) { - easyrtc.removeEventListener("roomOccupant", roomOccupantListener); - if (filesBeingSent.length > 0 || filesOffered.length > 0) { - progressListener({status: "cancelled"}); - } - } - }; - easyrtc.addEventListener("roomOccupant", roomOccupantListener); - // - // if a file offer is rejected, we delete references to it. - // - function fileOfferRejected(sender, msgType, msgData, targeting) { - if (!msgData.seq) - return; - delete filesOffered[msgData.seq]; - progressListener({status: "rejected"}); - filesOffered.length = 0; - sendFilesWaiting(); - } - // - // if a file offer is accepted, initiate sending of files. - // - function fileOfferAccepted(sender, msgType, msgData, targeting) { - if (!msgData.seq || !filesOffered[msgData.seq]) - return; - var alreadySending = filesBeingSent.length > 0; - for (var i = 0; i < filesOffered[msgData.seq].length; i++) { - filesBeingSent.push(filesOffered[msgData.seq][i]); - } - delete filesOffered[msgData.seq]; - if (!alreadySending) { - filePosition = 0; - sendChunk(); // this starts the file reading - } - } - - function fileCancelReceived(sender, msgType, msgData, targeting) { - filesBeingSent.empty(); - progressListener({status: "cancelled"}); - filesOffered.length = 0; - filesBeingSent.length = 0; - sendStarted = false; - sendFilesWaiting(); - } - - function packageAckReceived(sender, msgType, msgData) { - positionAcked = msgData.positionAck; - if (waitingForAck && filePosition < positionAcked + ackThreshold) { - waitingForAck = false; - sendChunk(); - } - } - - easyrtc.setPeerListener(fileOfferRejected, "filesReject", destUser); - easyrtc.setPeerListener(fileOfferAccepted, "filesAccept", destUser); - easyrtc.setPeerListener(fileCancelReceived, "filesCancel", destUser); - easyrtc.setPeerListener(packageAckReceived, "filesAck", destUser); - - - var outseq = 0; - - function sendChunk() { - if (!curFile) { - if (filesBeingSent.length === 0) { - outseq = 0; - easyrtc.sendData(destUser, "filesChunk", {done: "all"}); - filesOffered.length = 0; - progressListener({status: "done"}); - sendFilesWaiting(); - return; - } - else { - curFile = filesBeingSent.shift(); - progressListener({status: "started_file", name: curFile.name}); - curFileSize = curFile.size; - positionAcked = 0; - waitingForAck = false; - easyrtc.sendData(destUser, "filesChunk", {name: curFile.name, type: curFile.type, outseq: outseq, size: curFile.size}); - outseq++; - } - } - - var amountToRead = Math.min(maxChunkSize, curFileSize - filePosition); - if (!progressListener({status: "working", name: curFile.name, position: filePosition, size: curFileSize, numFiles: filesBeingSent.length + 1})) { - filesOffered.length = 0; - filePosition = 0; - easyrtc.sendData(destUser, "filesChunk", {done: "cancelled"}); - sendFilesWaiting(); - return; - } - - var nextLocation = filePosition + amountToRead; - var blobSlice = curFile.slice(filePosition, nextLocation); - var reader = new FileReader(); - reader.onloadend = function(evt) { - if (evt.target.readyState === FileReader.DONE) { // DONE == 2 - var binaryString = evt.target.result; - var maxchar = 32, minchar = 32; - for (var pp = 0; pp < binaryString.length; pp++) { - var oneChar = binaryString.charCodeAt(pp); - maxchar = Math.max(maxchar, oneChar); - minchar = Math.min(minchar, oneChar); - } - var maxPacketSize = 400; // size in bytes - for (var pos = 0; pos < binaryString.length; pos += maxPacketSize) { - var packetLen = Math.min(maxPacketSize, amountToRead - pos); - var packetData = binaryString.substring(pos, pos + packetLen); - var packetObject = {outseq: outseq}; - if (filesAreBinary) { - packetObject.data64 = btoa(packetData); - } - else { - packetObject.datatxt = packetData; - } - easyrtc.sendData(destUser, "filesChunk", packetObject); - outseq++; - } - if (nextLocation >= curFileSize) { - easyrtc.sendData(destUser, "filesChunk", {done: "file"}); - } - if (filePosition < positionAcked + ackThreshold) { - sendChunk(); - } - else { - waitingForAck = true; - } - } - }; - - reader.readAsBinaryString(blobSlice); - filePosition = nextLocation; - - // advance to the next file if we've read all of this file - if (nextLocation >= curFileSize) { - curFile = null; - filePosition = 0; - } - } - - function sendFilesWaiting() { - haveFilesWaiting = false; - if (filesWaiting.length > 0) { - setTimeout(function() { - var fileset = filesWaiting.shift(); - sendFilesOffer(fileset.files, fileset.areBinary); - }, 240); - } - } - - - function sendFilesOffer(files, areBinary) { - if (haveFilesWaiting) { - filesWaiting.push({files: files, areBinary: areBinary}); - } - else { - haveFilesWaiting = true; - filesAreBinary = areBinary; - progressListener({status: "waiting"}); - var fileNameList = []; - for (var i = 0; i < files.length; i++) { - fileNameList[i] = {name: files[i].name, size: files[i].size}; - } - seq++; - filesOffered[seq] = files; - easyrtc.sendDataWS(destUser, "filesOffer", {seq: seq, fileNameList: fileNameList}); - } - } - return sendFilesOffer; -}; - - -/** - * Enable datachannel based file receiving. The received blobs get passed to the statusCB in the 'eof' typed message. - * @param {Function(otherGuy,fileNameList, wasAccepted} acceptRejectCB - this function is called when another peer - * (otherGuy) offers to send you a list of files. this function should call it's wasAccepted function with true to - * allow those files to be sent, or false to disallow them. - * @param {Function} blobAcceptor - this function is called three arguments arguments: the suppliers easyrtcid, a blob and a filename. It is responsible for - * saving the blob to the file, usually using easyrtc_ft.saveAs. - * @param {type} statusCB - this function is called with the current state of file receiving. It is passed two arguments: - * otherGuy - the easyrtcid of the person sending the files. * - * msg - one of the following structures: - * {status:"done", reason:"accept_failed"} - * {status:"done", reason:"success"} - * {status:"done", reason:"cancelled"} - * {status:"eof"}, - * {status:"started_file, name:"filename"} - * {status:"progress", name:filename, - * received:received_size_in_bytes, - * size:file_size_in_bytes } - * @example - * - * easyrtc_ft( - * function(otherGuy, filenamelist, wasAccepted) { wasAccepted(true);}, - * function(otherGuy, blob, filename) { easyrtc_ft(blob, filename);}, - * function(otherGuy, status) { console.log("status:" + JSON.stringify(status))} - * ); - */ -easyrtc_ft.buildFileReceiver = function(acceptRejectCB, blobAcceptor, statusCB) { - var userStreams = {}; - var ackThreshold = 10000; // receiver is allowed to be 10KB behind of sender - var positionAcked = 0; - - var roomOccupantListener = function(eventType, eventData) { - var user; - var foundUser; - var roomName; - for (destUser in userStreams) { - foundUser = false; - for (roomName in eventData) { - if (eventData[roomName][destUser]) { - foundUser = true; - } - } - if (!foundUser) { - easyrtc.removeEventListener("roomOccupant", roomOccupantListener); - statusCB(destUser, {status: "done", reason: "cancelled"}); - delete userStreams[destUser]; - } - } - }; - easyrtc.addEventListener("roomOccupant", roomOccupantListener); - - function fileOfferHandler(otherGuy, msgType, msgData) { - if (!userStreams[otherGuy]) { - userStreams[otherGuy] = {}; - } - acceptRejectCB(otherGuy, msgData.fileNameList, function(wasAccepted) { - var ackHandler = function(ackMesg) { - - if (ackMesg.msgType === "error") { - statusCB(otherGuy, {status: "done", reason: "accept_failed"}); - delete userStreams[otherGuy]; - } - else { - statusCB(otherGuy, {status: "started"}); - } - }; - if (wasAccepted) { - userStreams[otherGuy] = { - groupSeq: msgData.seq, - nextPacketSeq: 0 - }; - easyrtc.sendDataWS(otherGuy, "filesAccept", {seq: msgData.seq}, ackHandler); - } - else { - easyrtc.sendDataWS(otherGuy, "filesReject", {seq: msgData.seq}); - delete userStreams[otherGuy]; - statusCB(otherGuy, {status: "rejected"}); - } - }); - } - - - function fileChunkHandler(otherGuy, msgType, msgData) { - var i; - var userStream = userStreams[otherGuy]; - if (!userStream) { - return; - } - if (msgData.done) { - switch (msgData.done) { - case "file": - var blob = new Blob(userStream.currentData, {type: userStream.currentFileType}); - blobAcceptor(otherGuy, blob, userStream.currentFileName); - statusCB(otherGuy, {status: "eof", name: userStream.currentFileName}); - blob = null; - positionAcked = 0; - userStream.currentData = []; - break; - case "all": - statusCB(otherGuy, {status: "done", reason: "success"}); - break; - case "cancelled": - delete userStreams[otherGuy]; - statusCB(otherGuy, {status: "done", reason: "cancelled"}); - break; - } - } - else if (msgData.name) { - statusCB(otherGuy, {status: "started_file", name: msgData.name}); - userStream.currentFileName = msgData.name; - userStream.currentFileType = msgData.type; - userStream.lengthReceived = 0; - userStream.lengthExpected = msgData.size; - userStream.currentData = []; - } - else if (msgData.data64 || msgData.datatxt) { - var binData; - if (msgData.data64) { - binData = atob(msgData.data64); - } - else { - binData = msgData.datatxt; - } - var n = binData.length; - var binheap = new Uint8Array(n); - for (i = 0; i < n; i += 1) { - binheap[i] = binData.charCodeAt(i); - } - userStream.lengthReceived += n; - if (!userStream.currentData) { - console.log("Lost my currentData!!!"); - } - userStream.currentData.push(binheap); - - statusCB(otherGuy, { - status: "progress", - name: userStream.currentFileName, - received: userStream.lengthReceived, - size: userStream.lengthExpected}); - if (userStream.lengthReceived > positionAcked + ackThreshold) { - positionAcked = userStream.lengthReceived; - easyrtc.sendData(otherGuy, "filesAck", {positionAck: positionAcked}); - } - } - else { - console.log("Unexpected data structure in filesChunk=", msgData); - } - } - - easyrtc.setPeerListener(fileOfferHandler, "filesOffer"); - easyrtc.setPeerListener(fileChunkHandler, "filesChunk"); -}; - -/** This is a wrapper around Eli Grey's saveAs function. This saves to the browser's downloads directory. - * @param {Blob} Blob - the data to be saved. - * @param {String} filename - the name of the file the blob should be written to. - */ -easyrtc_ft.saveAs = (function() { - /* FileSaver.js - * A saveAs() FileSaver implementation. - * 2013-01-23 - * - * By Eli Grey, http://eligrey.com - * License: X11/MIT - * See LICENSE.md - */ - - /*global self */ - /*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true, - plusplus: true */ - - /*! @source http://purl.eligrey.com/github/FileSaver.js/blob/master/FileSaver.js */ - - var saveAs = window.saveAs - || (navigator.msSaveOrOpenBlob && navigator.msSaveOrOpenBlob.bind(navigator)) - || (function(view) { - - var - doc = view.document - // only get URL when necessary in case BlobBuilder.js hasn't overridden it yet - , get_URL = function() { - return view.URL || view.webkitURL || view; - } - , URL = view.URL || view.webkitURL || view - , save_link = doc.createElementNS("http://www.w3.org/1999/xhtml", "a") - , can_use_save_link = !view.externalHost && "download" in save_link - , click = function(node) { - var event = doc.createEvent("MouseEvents"); - event.initMouseEvent( - "click", true, false, view, 0, 0, 0, 0, 0 - , false, false, false, false, 0, null - ); - node.dispatchEvent(event); - } - , webkit_req_fs = view.webkitRequestFileSystem - , req_fs = view.requestFileSystem || webkit_req_fs || view.mozRequestFileSystem - , throw_outside = function(ex) { - (view.setImmediate || view.setTimeout)(function() { - throw ex; - }, 0); - } - , force_saveable_type = "application/octet-stream" - , fs_min_size = 0 - , deletion_queue = [] - , process_deletion_queue = function() { - var i = deletion_queue.length; - while (i--) { - var file = deletion_queue[i]; - if (typeof file === "string") { // file is an object URL - URL.revokeObjectURL(file); - } else { // file is a File - file.remove(); - } - } - deletion_queue.length = 0; // clear queue - } - , dispatch = function(filesaver, event_types, event) { - event_types = [].concat(event_types); - var i = event_types.length; - while (i--) { - var listener = filesaver["on" + event_types[i]]; - if (typeof listener === "function") { - try { - listener.call(filesaver, event || filesaver); - } catch (ex) { - throw_outside(ex); - } - } - } - } - , FileSaver = function(blob, name) { - // First try a.download, then web filesystem, then object URLs - var - filesaver = this - , type = blob.type - , blob_changed = false - , object_url - , target_view - , get_object_url = function() { - var object_url = get_URL().createObjectURL(blob); - deletion_queue.push(object_url); - return object_url; - } - , dispatch_all = function() { - dispatch(filesaver, "writestart progress write writeend".split(" ")); - } - // on any filesys errors revert to saving with object URLs - , fs_error = function() { - // don't create more object URLs than needed - if (blob_changed || !object_url) { - object_url = get_object_url(blob); - } - if (target_view) { - target_view.location.href = object_url; - } else { - window.open(object_url, "_blank"); - } - filesaver.readyState = filesaver.DONE; - dispatch_all(); - } - , abortable = function(func) { - return function() { - if (filesaver.readyState !== filesaver.DONE) { - return func.apply(this, arguments); - } - else { - return null; - } - }; - } - , create_if_not_found = {create: true, exclusive: false} - , slice - ; - filesaver.readyState = filesaver.INIT; - if (!name) { - name = "download"; - } - if (can_use_save_link) { - object_url = get_object_url(blob); - save_link.href = object_url; - save_link.download = name; - click(save_link); - filesaver.readyState = filesaver.DONE; - dispatch_all(); - return; - } - // Object and web filesystem URLs have a problem saving in Google Chrome when - // viewed in a tab, so I force save with application/octet-stream - // http://code.google.com/p/chromium/issues/detail?id=91158 - if (view.chrome && type && type !== force_saveable_type) { - slice = blob.slice || blob.webkitSlice; - blob = slice.call(blob, 0, blob.size, force_saveable_type); - blob_changed = true; - } - // Since I can't be sure that the guessed media type will trigger a download - // in WebKit, I append .download to the filename. - // https://bugs.webkit.org/show_bug.cgi?id=65440 - if (webkit_req_fs && name !== "download") { - name += ".download"; - } - if (type === force_saveable_type || webkit_req_fs) { - target_view = view; - } - if (!req_fs) { - fs_error(); - return; - } - fs_min_size += blob.size; - req_fs(view.TEMPORARY, fs_min_size, abortable(function(fs) { - fs.root.getDirectory("saved", create_if_not_found, abortable(function(dir) { - var save = function() { - dir.getFile(name, create_if_not_found, abortable(function(file) { - file.createWriter(abortable(function(writer) { - writer.onwriteend = function(event) { - target_view.location.href = file.toURL(); - deletion_queue.push(file); - filesaver.readyState = filesaver.DONE; - dispatch(filesaver, "writeend", event); - }; - writer.onerror = function() { - var error = writer.error; - if (error.code !== error.ABORT_ERR) { - fs_error(); - } - }; - "writestart progress write abort".split(" ").forEach(function(event) { - writer["on" + event] = filesaver["on" + event]; - }); - writer.write(blob); - filesaver.abort = function() { - writer.abort(); - filesaver.readyState = filesaver.DONE; - }; - filesaver.readyState = filesaver.WRITING; - }), fs_error); - }), fs_error); - }; - dir.getFile(name, {create: false}, abortable(function(file) { - // delete file if it already exists - file.remove(); - save(); - }), abortable(function(ex) { - if (ex.code === ex.NOT_FOUND_ERR) { - save(); - } else { - fs_error(); - } - })); - }), fs_error); - }), fs_error); - } - , FS_proto = FileSaver.prototype - , saveAs = function(blob, name) { - return new FileSaver(blob, name); - } - ; - FS_proto.abort = function() { - var filesaver = this; - filesaver.readyState = filesaver.DONE; - dispatch(filesaver, "abort"); - }; - FS_proto.readyState = FS_proto.INIT = 0; - FS_proto.WRITING = 1; - FS_proto.DONE = 2; - - FS_proto.error = - FS_proto.onwritestart = - FS_proto.onprogress = - FS_proto.onwrite = - FS_proto.onabort = - FS_proto.onerror = - FS_proto.onwriteend = - null; - - view.addEventListener("unload", process_deletion_queue, false); - return saveAs; - }(self)); - - return saveAs; -})(); diff --git a/messenger/js/easyrtc/node_modules/easyrtc/api/easyrtc_int.js b/messenger/js/easyrtc/node_modules/easyrtc/api/easyrtc_int.js deleted file mode 100644 index 3180c757d0..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/api/easyrtc_int.js +++ /dev/null @@ -1,5270 +0,0 @@ -/** @class - *@version 1.0.13 - *

- * Provides client side support for the EasyRTC framework. - * Please see the easyrtc_client_api.md and easyrtc_client_tutorial.md - * for more details.

- * - *

- *copyright Copyright (c) 2014, Priologic Software Inc. - *All rights reserved.

- * - *

- *Redistribution and use in source and binary forms, with or without - *modification, are permitted provided that the following conditions are met: - *

- *
    - *
  • Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer.
  • - *
  • Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution.
  • - *
- *

- *THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - *AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - *IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - *ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - *LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - *CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - *SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - *INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - *CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - *ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - *POSSIBILITY OF SUCH DAMAGE. - *

- */ - -var Easyrtc = function() { - var self = this; - var isFirefox = (webrtcDetectedBrowser === "firefox"); - var autoInitUserMedia = true; - var sdpLocalFilter = null, - sdpRemoteFilter = null; - var iceCandidateFilter = null; - - var connectionOptions = { - 'connect timeout': 10000, - 'force new connection': true - }; - - /** - * Sets functions which filter sdp records before calling setLocalDescription or setRemoteDescription. - * This is advanced functionality which can break things, easily. See the easyrtc_rates.js file for a - * filter builder. - * @param {Function} localFilter a function that takes an sdp string and returns an sdp string. - * @param {Function} remoteFilter a function that takes an sdp string and returns an sdp string. - */ - this.setSdpFilters = function(localFilter, remoteFilter) { - sdpLocalFilter = localFilter; - sdpRemoteFilter = remoteFilter; - }; - - /** - * Sets a function which filters IceCandidate records being sent or received. - * - * Candidate records can be received while they are being generated locally (before being - * sent to a peer), and after they are received by the peer. The filter receives two arguments, the candidate record and a boolean - * flag that is true for a candidate being received from another peer, - * and false for a candidate that was generated locally. The candidate record has the form: - * {type: 'candidate', label: sdpMLineIndex, id: sdpMid, candidate: candidateString} - * The function should return one of the following: the input candidate record, a modified candidate record, or null (indicating that the - * candidate should be discarded). - * @param {Function} filter - * @param {String} isIncoming - * @return an ice candidate record or null. - */ - this.setIceCandidateFilter = function(filter) { - iceCandidateFilter = filter; - } - - /** - * Controls whether a default local media stream should be acquired automatically during calls and accepts - * if a list of streamNames is not supplied. The default is true, which mimicks the behaviour of earlier releases - * that didn't support multiple streams. This function should be called before easyrtc.call or before entering an - * accept callback. - * @param {Boolean} flag true to allocate a default local media stream. - */ - this.setAutoInitUserMedia = function(flag) { - autoInitUserMedia = !!flag; - } - /** - * This function performs a printf like formatting. It actually takes an unlimited - * number of arguments, the declared arguments arg1, arg2, arg3 are present just for - * documentation purposes. - * @param {String} format A string like "abcd{1}efg{2}hij{1}." - * @param {String} arg1 The value that replaces {1} - * @param {String} arg2 The value that replaces {2} - * @param {String} arg3 The value that replaces {3} - * @returns {String} the formatted string. - */ - this.format = function(format, arg1, arg2, arg3) { - var formatted = arguments[0]; - for (var i = 1; i < arguments.length; i++) { - var regexp = new RegExp('\\{' + (i - 1) + '\\}', 'gi'); - formatted = formatted.replace(regexp, arguments[i]); - } - return formatted; - }; - /** @private */ - var haveAudioVideo = {audio: false, video: false}; -// -// Maps a key to a language specific string using the easyrtc_constantStrings map. -// Defaults to the key if the key can not be found, but outputs a warning in that case. -// This function is only used internally by easyrtc.js -// - /** - * @private - * @param {String} key - */ - this.getConstantString = function(key) { - if (easyrtc_constantStrings[key]) { - return easyrtc_constantStrings[key]; - } - else { - console.warn("Could not find key='" + key + "' in easyrtc_constantStrings"); - return key; - } - }; - // - // this is a list of the events supported by the generalized event listener. - // - var allowedEvents = { - roomOccupant: true, // this receives the list of everybody in any room you belong to - roomOccupants: true // this receives a {roomName:..., occupants:...} value for a specific room - }; - // - // A map of eventListeners. The key is the event type. - var eventListeners = {}; - /** This function checks if an attempt was made to add an event listener or - * or emit an unlisted event, since such is typically a typo. - * @private - * @param {String} eventName - * @param {String} callingFunction the name of the calling function. - */ - function event(eventName, callingFunction) { - if (typeof eventName !== 'string') { - self.showError(self.errCodes.DEVELOPER_ERR, src + " called without a string as the first argument"); - throw "developer error"; - } - if (!allowedEvents[eventName]) { - self.showError(self.errCodes.DEVELOPER_ERR, src + " called with a bad event name = " + eventName); - throw "developer error"; - } - } - - /** - * Adds an event listener for a particular type of event. - * Currently the only eventName supported is "roomOccupant". - * @param {String} eventName the type of the event - * @param {Function} eventListener the function that expects the event. - * The eventListener gets called with the eventName as it's first argument, and the event - * data as it's second argument. - * @returns {void} - */ - this.addEventListener = function(eventName, eventListener) { - event(eventName, "addEventListener"); - if (typeof eventListener !== 'function') { - self.showError(self.errCodes.DEVELOPER_ERR, "addEventListener called with a non-function for second argument"); - throw "developer error"; - } - // - // remove the event listener if it's already present so we don't end up with two copies - // - self.removeEventListener(eventName, eventListener); - if (!eventListeners[eventName]) { - eventListeners[eventName] = []; - } - eventListeners[eventName][eventListeners[eventName].length] = eventListener; - }; - /** - * Removes an event listener. - * @param {String} eventName - * @param {Function} eventListener - */ - this.removeEventListener = function(eventName, eventListener) { - event(eventName, "removeEventListener"); - var listeners = eventListeners[eventName]; - var i = 0; - if (listeners) { - for (i = 0; i < listeners.length; i++) { - if (listeners[i] === eventListener) { - if (i < listeners.length - 1) { - listeners[i] = listeners[listeners.length - 1]; - } - listeners.length = listeners.length - 1; - } - } - } - }; - /** - * Emits an event, or in otherwords, calls all the eventListeners for a - * particular event. - * @param {String} eventName - * @param {Object} eventData - */ - this.emitEvent = function(eventName, eventData) { - event(eventName, "emitEvent"); - var listeners = eventListeners[eventName]; - var i = 0; - if (listeners) { - for (i = 0; i < listeners.length; i++) { - listeners[i](eventName, eventData); - } - } - }; - /** Error codes that the EasyRTC will use in the errorCode field of error object passed - * to error handler set by easyrtc.setOnError. The error codes are short printable strings. - * @type Object - */ - this.errCodes = { - BAD_NAME: "BAD_NAME", // a user name wasn't of the desired form - CALL_ERR: "CALL_ERR", // something went wrong creating the peer connection - DEVELOPER_ERR: "DEVELOPER_ERR", // the developer using the EasyRTC library made a mistake - SYSTEM_ERR: "SYSTEM_ERR", // probably an error related to the network - CONNECT_ERR: "CONNECT_ERR", // error occurred when trying to create a connection - MEDIA_ERR: "MEDIA_ERR", // unable to get the local media - MEDIA_WARNING: "MEDIA_WARNING", // didn't get the desired resolution - INTERNAL_ERR: "INTERNAL_ERR", - PEER_GONE: "PEER_GONE", // peer doesn't exist - ALREADY_CONNECTED: "ALREADY_CONNECTED", - BAD_CREDENTIAL: "BAD_CREDENTIAL", - ICECANDIDATE_ERR: "ICECANDIDATE_ERROR" - }; - this.apiVersion = "1.0.13"; - /** Most basic message acknowledgment object */ - this.ackMessage = {msgType: "ack"}; - /** Regular expression pattern for user ids. This will need modification to support non US character sets */ - this.usernameRegExp = /^(.){1,64}$/; - /** @private */ - var cookieId = "easyrtcsid"; - /** @private */ - var username = null; - /** @private */ - var loggingOut = false; - /** @private */ - var disconnecting = false; - // - // A map of ids to local media streams. - // - var namedLocalMediaStreams = {}; - var sessionFields = []; - var receivedMediaContraints = { - 'mandatory': { - 'OfferToReceiveAudio': true, - 'OfferToReceiveVideo': true - } - }; - /** - * Control whether the client requests audio from a peer during a call. - * Must be called before the call to have an effect. - * @param value - true to receive audio, false otherwise. The default is true. - */ - this.enableAudioReceive = function(value) { - receivedMediaContraints.mandatory.OfferToReceiveAudio = value; - }; - /** - * Control whether the client requests video from a peer during a call. - * Must be called before the call to have an effect. - * @param value - true to receive video, false otherwise. The default is true. - */ - this.enableVideoReceive = function(value) { - receivedMediaContraints.mandatory.OfferToReceiveVideo = value; - }; - - function getSourceList(callback, sourceType) { - if (MediaStreamTrack.getSources) { - MediaStreamTrack.getSources(function(sources) { - var results = []; - for (var i = 0; i < sources.length; i++) { - var source = sources[i]; - if (source.kind == sourceType) { - results.push(source); - } - } - callback(results); - }); - } - else { - callback([]); - } - } - - /** - * Gets a list of the available audio sources (ie, cameras) - * @param {Function} callback receives list of {label:String, id:String, kind:"audio"} - * Note: the label string always seems to be the empty string if you aren't using https. - * Note: not supported by Firefox. - * @example easyrtc.getAudioSourceList( function(list) { - * var i; - * for( i = 0; i < list.length; i++ ) { - * console.log("label=" + list[i].label + ", id= " + list[i].id); - * } - * }); - */ - this.getAudioSourceList = function(callback){ - getSourceList(callback, "audio"); - } - - /** - * Gets a list of the available video sources (ie, cameras) - * @param {Function} callback receives list of {facing:String, label:String, id:String, kind:"video"} - * Note: the label string always seems to be the empty string if you aren't using https. - * Note: not supported by Firefox. - * @example easyrtc.getVideoSourceList( function(list) { - * var i; - * for( i = 0; i < list.length; i++ ) { - * console.log("label=" + list[i].label + ", id= " + list[i].id); - * } - * }); - */ - this.getVideoSourceList = function(callback) { - getSourceList(callback, "video"); - } - - /** @private */ - var audioEnabled = true; - /** @private */ - var videoEnabled = true; - /** @private */ - var dataChannelName = "dc"; - /** @private */ - this.debugPrinter = null; - /** Your easyrtcid */ - this.myEasyrtcid = ""; - /** @private */ - var oldConfig = {}; - /** @private */ - var offersPending = {}; - /** @private */ - var selfRoomJoinTime = 0; - /** The height of the local media stream video in pixels. This field is set an indeterminate period - * of time after easyrtc.initMediaSource succeeds. Note: in actuality, the dimensions of a video stream - * change dynamically in response to external factors, you should check the videoWidth and videoHeight attributes - * of your video objects before you use them for pixel specific operations. - */ - this.nativeVideoHeight = 0; - /** The width of the local media stream video in pixels. This field is set an indeterminate period - * of time after easyrtc.initMediaSource succeeds. Note: in actuality, the dimensions of a video stream - * change dynamically in response to external factors, you should check the videoWidth and videoHeight attributes - * of your video objects before you use them for pixel specific operations. - */ - this.nativeVideoWidth = 0; - /** @private */ - var credential = null; - /** The rooms the user is in. This only applies to room oriented applications and is set at the same - * time a token is received. - */ - this.roomJoin = {}; - /** Checks if the supplied string is a valid user name (standard identifier rules) - * @param {String} name - * @return {Boolean} true for a valid user name - * @example - * var name = document.getElementById('nameField').value; - * if( !easyrtc.isNameValid(name)){ - * console.error("Bad user name"); - * } - */ - this.isNameValid = function(name) { - return self.usernameRegExp.test(name); - }; - /** - * This function sets the name of the cookie that client side library will look for - * and transmit back to the server as it's easyrtcsid in the first message. - * @param {String} cookieId - */ - this.setCookieId = function(cookieId) { - self.cookieId = cookieId; - }; - /** - * This method allows you to join a single room. It may be called multiple times to be in - * multiple rooms simultaneously. It may be called before or after connecting to the server. - * Note: the successCB and failureDB will only be called if you are already connected to the server. - * @param {String} roomName the room to be joined. - * @param {String} roomParameters application specific parameters, can be null. - * @param {Function} successCB called once, with a roomName as it's argument, once the room is joined. - * @param {Function} failureCB called if the room can not be joined. The arguments of failureCB are errorCode, errorText, roomName. - */ - this.joinRoom = function(roomName, roomParameters, successCB, failureCB) { - if (self.roomJoin[roomName]) { - console.error("Developer error: attempt to join room " + roomName + " which you are already in."); - return; - } - - var newRoomData = {roomName: roomName}; - if (roomParameters) { - try { - JSON.stringify(roomParameters); - } catch (error) { - self.showError(self.errCodes.DEVELOPER_ERR, "non-jsonable parameter to easyrtc.joinRoom"); - throw "Developer error, see application error messages"; - } - var parameters = {}; - for (var key in roomParameters) { - if (roomParameters.hasOwnProperty(key)) { - parameters[key] = roomParameters[key]; - } - } - newRoomData.roomParameter = parameters; - } - var msgData = { - roomJoin: {} - }; - var roomData; - var signallingSuccess, signallingFailure; - if (self.webSocket) { - - msgData.roomJoin[roomName] = newRoomData; - signallingSuccess = function(msgType, msgData) { - - roomData = msgData.roomData; - self.roomJoin[roomName] = newRoomData; - if (successCB) { - successCB(roomName); - } - - processRoomData(roomData); - }; - signallingFailure = function(errorCode, errorText) { - if (failureCB) { - failureCB(errorCode, errorText, roomName); - } - else { - self.showError(errorCode, self.format(self.getConstantString("unableToEnterRoom"), roomName, errorText)); - } - }; - sendSignalling(null, "roomJoin", msgData, signallingSuccess, signallingFailure); - } - else { - self.roomJoin[roomName] = newRoomData; - } - - }; - /** - * This function allows you to leave a single room. Note: the successCB and failureDB - * arguments are optional and will only be called if you are already connected to the server. - * @param {String} roomName - * @param {Function} successCallback - A function which expects a roomName. - * @param {Function} failureCallback - A function which expects the following arguments: errorCode, errorText, roomName. - * @example - * easyrtc.leaveRoom("freds_room"); - * easyrtc.leaveRoom("freds_room", function(roomName){ console.log("left the room")}, - * function(errorCode, errorText, roomName){ console.log("left the room")}); - */ - this.leaveRoom = function(roomName, successCallback, failureCallback) { - var roomItem; - if (self.roomJoin[roomName]) { - if (!self.webSocket) { - delete self.roomJoin[roomName]; - } - else { - roomItem = {}; - roomItem[roomName] = {roomName: roomName}; - sendSignalling(null, "roomLeave", {roomLeave: roomItem}, - function(msgType, msgData) { - var roomData = msgData.roomData; - processRoomData(roomData); - if (successCallback) { - successCallback(roomName); - } - }, - function(errorCode, errorText) { - if (failureCallback) { - failureCallback(errorCode, errorText, roomName); - } - }); - } - } - }; - /** @private */ - this._desiredVideoProperties = {}; // default camera - - - /** - * Specify particular video source. Call this before you call easyrtc.initMediaSource(). - * Note: this function isn't supported by Firefox. - * @param {String} videoSrcId is a id value from one of the entries fetched by getVideoSourceList. null for default. - * @example easyrtc.setVideoSrc( videoSrcId); - */ - this.setVideoSource = function(videoSrcId) { - self._desiredVideoProperties.videoSrcId = videoSrcId; - delete self._desiredVideoProperties.screenCapture; - }; - /** - * Temporary alias for easyrtc.setVideoSource - */ - this.setVideoSrc = this.setVideoSource; - delete this._desiredVideoProperties.screenCapture; - /** This function is used to set the dimensions of the local camera, usually to get HD. - * If called, it must be called before calling easyrtc.initMediaSource (explicitly or implicitly). - * assuming it is supported. If you don't pass any parameters, it will default to 720p dimensions. - * @param {Number} width in pixels - * @param {Number} height in pixels - * @param {number} frameRate is optional - * @example - * easyrtc.setVideoDims(1280,720); - * @example - * easyrtc.setVideoDims(); - */ - this.setVideoDims = function(width, height, frameRate) { - if (!width) { - width = 1280; - height = 720; - } - self._desiredVideoProperties.width = width; - self._desiredVideoProperties.height = height; - if (frameRate !== undefined) { - self._desiredVideoProperties.frameRate = frameRate; - } - }; - /** This function requests that screen capturing be used to provide the local media source - * rather than a webcam. If you have multiple screens, they are composited side by side. - * Note: this functionality is not supported by Firefox, has to be called before calling initMediaSource (or easyApp), we don't currently supply a way to - * turn it off (once it's on), only works if the website is hosted SSL (https), and the image quality is rather - * poor going across a network because it tries to transmit so much data. In short, screen sharing - * through WebRTC isn't worth using at this point, but it is provided here so people can try it out. - * @example - * easyrtc.setScreenCapture(); - * @deprecated: use easyrtc.initScreenCapture (same parameters as easyrtc.initMediaSource. - */ - this.setScreenCapture = function(enableScreenCapture) { - self._desiredVideoProperties.screenCapture = (enableScreenCapture !== false); - }; - /** - * Builds the constraint object passed to getUserMedia. - * @returns {Object} mediaConstraints - */ - self.getUserMediaConstraints = function() { - var constraints = {}; - // - // _presetMediaConstraints allow you to provide your own contraints to be used - // with initMediaSource. - // - if (self._presetMediaConstraints) { - constraints = self._presetMediaConstraints; - delete self._presetMediaConstraints; - return constraints; - } - else if (self._desiredVideoProperties.screenCapture) { - return { - video: { - mandatory: { - chromeMediaSource: 'screen', - maxWidth: screen.width, - maxHeight: screen.height, - minWidth: screen.width, - minHeight: screen.height, - minFrameRate: 1, - maxFrameRate: 5}, - optional: [] - }, - audio: false - }; - } - else if (!videoEnabled) { - constraints.video = false; - } - else { - constraints.video = {mandatory: {}, optional: []}; - if (self._desiredVideoProperties.width) { - constraints.video.mandatory.maxWidth = self._desiredVideoProperties.width; - constraints.video.mandatory.minWidth = self._desiredVideoProperties.width; - } - if (self._desiredVideoProperties.width) { - constraints.video.mandatory.maxHeight = self._desiredVideoProperties.height; - constraints.video.mandatory.minHeight = self._desiredVideoProperties.height; - } - if (self._desiredVideoProperties.frameRate) { - constraints.video.mandatory.maxFrameRate = self._desiredVideoProperties.frameRate; - } - if (self._desiredVideoProperties.videoSrcId) { - constraints.video.optional.push({sourceId: self._desiredVideoProperties.videoSrcId}); - } - // hack for opera - if (constraints.video.mandatory.length === 0 && constraints.video.optional.length === 0) { - constraints.video = true; - } - } - constraints.audio = audioEnabled; - return constraints; - }; - /** Set the application name. Applications can only communicate with other applications - * that share the same API Key and application name. There is no predefined set of application - * names. Maximum length is - * @param {String} name - * @example - * easyrtc.setApplicationName('simpleAudioVideo'); - */ - this.setApplicationName = function(name) { - self.applicationName = name; - }; - /** Enable or disable logging to the console. - * Note: if you want to control the printing of debug messages, override the - * easyrtc.debugPrinter variable with a function that takes a message string as it's argument. - * This is exactly what easyrtc.enableDebug does when it's enable argument is true. - * @param {Boolean} enable - true to turn on debugging, false to turn off debugging. Default is false. - * @example - * easyrtc.enableDebug(true); - */ - this.enableDebug = function(enable) { - if (enable) { - self.debugPrinter = function(message) { - var stackString = new Error().stack; - var srcLine = "location unknown"; - if (stackString) { - var stackFrameStrings = stackString.split('\n'); - srcLine = ""; - if (stackFrameStrings.length >= 3) { - srcLine = stackFrameStrings[2]; - } - } - console.log("debug " + (new Date()).toISOString() + " : " + message + " [" + srcLine + "]"); - }; - } - else { - self.debugPrinter = null; - } - }; -// -// this is a temporary version used until we connect to the server. -// - this.updatePresence = function(state, statusText) { - self.presenceShow = state; - self.presenceStatus = statusText; - }; - /** - * Determines if the local browser supports WebRTC GetUserMedia (access to camera and microphone). - * @returns {Boolean} True getUserMedia is supported. - */ - this.supportsGetUserMedia = function() { - return !!getUserMedia; - }; - /** - * Determines if the local browser supports WebRTC Peer connections to the extent of being able to do video chats. - * @returns {Boolean} True if Peer connections are supported. - */ - this.supportsPeerConnections = function() { - if (!self.supportsGetUserMedia()) { - return false; - } - if (!window.RTCPeerConnection) { - return false; - } - try { - self.createRTCPeerConnection({"iceServers": []}, null); - } catch (oops) { - return false; - } - return true; - }; - /** @private - * @param pc_config ice configuration array - * @param optionalStuff peer constraints. - */ - /** @private - * @param pc_config ice configuration array - * @param optionalStuff peer constraints. - */ - this.createRTCPeerConnection = function(pc_config, optionalStuff) { - if (RTCPeerConnection) { - return new RTCPeerConnection(pc_config, optionalStuff); - } - else { - throw "Your browser doesn't support webRTC (RTCPeerConnection)"; - } - }; -// -// this should really be part of adapter.js -// Versions of chrome < 31 don't support reliable data channels transport. -// Firefox does. -// - this.getDatachannelConstraints = function() { - if (webrtcDetectedBrowser === "chrome" && webrtcDetectedVersion < 31) { - return {reliable: false}; - } - else { - return {reliable: true}; - } - }; - /** @private */ - haveAudioVideo = { - audio: false, - video: false - }; - /** @private */ - var dataEnabled = false; - /** @private */ - var serverPath = null; - /** @private */ - var roomOccupantListener = null; - /** @private */ - var onDataChannelOpen = null; - /** @private */ - var onDataChannelClose = null; - /** @private */ - var lastLoggedInList = {}; - /** @private */ - var receivePeer = {msgTypes: {}}; - /** @private */ - var receiveServerCB = null; - /** @private */ - var updateConfigurationInfo = function() { - - }; // dummy placeholder for when we aren't connected -// -// -// peerConns is a map from caller names to the below object structure -// { startedAV: boolean, -- true if we have traded audio/video streams -// dataChannelS: RTPDataChannel for outgoing messages if present -// dataChannelR: RTPDataChannel for incoming messages if present -// dataChannelReady: true if the data channel can be used for sending yet -// connectTime: timestamp when the connection was started -// sharingAudio: true if audio is being shared -// sharingVideo: true if video is being shared -// cancelled: temporarily true if a connection was cancelled by the peer asking to initiate it -// candidatesToSend: SDP candidates temporarily queued -// streamsAddedAcks: ack callbacks waiting for stream received messages -// pc: RTCPeerConnection -// mediaStream: mediaStream -// function callSuccessCB(string) - see the easyrtc.call documentation. -// function callFailureCB(errorCode, string) - see the easyrtc.call documentation. -// function wasAcceptedCB(boolean,string) - see the easyrtc.call documentation. -// } -// - /** @private */ - var peerConns = {}; -// -// a map keeping track of whom we've requested a call with so we don't try to -// call them a second time before they've responded. -// - /** @private */ - var acceptancePending = {}; - /** - * Disconnect from the EasyRTC server. - * @example - * easyrtc.disconnect(); - */ - this.disconnect = function() { - }; - /** @private - * @param caller - * @param helper - */ - this.acceptCheck = function(caller, helper) { - helper(true); - }; - /** @private - * @param easyrtcid - * @param stream - */ - this.streamAcceptor = function(easyrtcid, stream) { - }; - /** @private - * @param easyrtcid - */ - this.onStreamClosed = function(easyrtcid) { - }; - /** @private - * @param easyrtcid - */ - this.callCancelled = function(easyrtcid) { - }; - /** - * This function gets the statistics for a particular peer connection. - * @param {String} peerId - * @param {Function} callback gets the peerid and a map of {userDefinedKey: value}. If there is no peer connection to peerId, then the map will - * have a value of {connected:false}. - * @param {Object} filter depends on whether Chrome or Firefox is used. See the default filters for guidance. - * It is still experimental. - */ - this.getPeerStatistics = function(peerId, callback, filter) { - if (isFirefox) { - self.getFirefoxPeerStatistics(peerId, callback, filter); - } - else { - self.getChromePeerStatistics(peerId, callback, filter); - } - }; - this.getFirefoxPeerStatistics = function(peerId, callback, filter) { - - - if (!peerConns[peerId]) { - callback(peerId, {"connected": false}); - } - else if (peerConns[peerId].pc.getStats) { - peerConns[peerId].pc.getStats(null, function(stats) { - var items = {}; - var candidates = {}; - var activeId = null; - var srcKey; - // - // the stats objects has a group of entries. Each entry is either an rtcp, rtp entry - // or a candidate entry. - // - stats.forEach(function(entry) { - var majorKey; - var subKey; - if (entry.type.match(/boundrtp/)) { - if (entry.id.match(/audio/)) { - majorKey = entry.type + "_audio"; - } - else if (entry.id.match(/video/)) { - majorKey = entry.type + "_video"; - } - else { - return; - } - for (subKey in entry) { - if (entry.hasOwnProperty(subKey)) { - items[majorKey + "." + subKey] = entry[subKey]; - } - } - } - else { - if( entry.hasOwnProperty("ipAddress") && entry.hasOwnProperty("id")) { - candidates[entry.id] = entry.ipAddress + ":" + - entry.portNumber; - } - else if( entry.hasOwnProperty("selected") && - entry.hasOwnProperty("remoteCandidateId") && - entry.selected ) { - activeId = entry.remoteCandidateId; - } - } - }); - - if( activeId ) { - items["firefoxRemoteAddress"] = candidates[activeId]; - } - if (!filter) { - callback(peerId, items); - } - else { - var filteredItems = {}; - for (srcKey in filter) { - if (filter.hasOwnProperty(srcKey) && items.hasOwnProperty(srcKey)) { - filteredItems[ filter[srcKey]] = items[srcKey]; - } - } - callback(peerId, filteredItems); - } - }, - function(error) { - console.log("unable to get statistics"); - }); - } - else { - callback(peerId, {"statistics": self.getConstantString("statsNotSupported")}); - } - }; - this.getChromePeerStatistics = function(peerId, callback, filter) { - - if (!peerConns[peerId]) { - callback(peerId, {"connected": false}); - } - else if (peerConns[peerId].pc.getStats) { - - peerConns[peerId].pc.getStats(function(stats) { - - var localStats = {}; - var part, parts = stats.result(); - var i, j; - var itemKeys; - var itemKey; - var names; - var userKey; - var partNames = []; - var partList; - var bestBytes = 0; - var bestI; - var turnAddress = null; - var hasActive, curReceived; - var localAddress, remoteAddress; - if (!filter) { - for (i = 0; i < parts.length; i++) { - names = parts[i].names(); - for (j = 0; j < names.length; j++) { - itemKey = names[j]; - localStats[parts[i].id + "." + itemKey] = parts[i].local.stat(itemKey); - } - } - } - else { - for (i = 0; i < parts.length; i++) { - partNames[i] = {}; - // - // convert the names into a dictionary - // - names = parts[i].names(); - for (j = 0; j < names.length; j++) { - partNames[i][names[j]] = true; - } - - // - // a chrome-firefox connection results in several activeConnections. - // we only want one, so we look for the one with the most data being received on it. - // - if (partNames[i].googRemoteAddress && partNames[i].googActiveConnection) { - hasActive = parts[i].local.stat("googActiveConnection"); - if (hasActive === true || hasActive === "true") { - curReceived = parseInt(parts[i].local.stat("bytesReceived")) + - parseInt(parts[i].local.stat("bytesSent")); - if (curReceived > bestBytes) { - bestI = i; - bestBytes = curReceived; - } - } - } - } - - for (i = 0; i < parts.length; i++) { - // - // discard info from any inactive connection. - // - if (partNames[i].googActiveConnection) { - if (i !== bestI) { - partNames[i] = {}; - } - else { - localAddress = parts[i].local.stat("googLocalAddress").split(":")[0]; - remoteAddress = parts[i].local.stat("googRemoteAddress").split(":")[0]; - if (self.isTurnServer(localAddress)) { - turnAddress = localAddress; - } - else if (self.isTurnServer(remoteAddress)) { - turnAddress = remoteAddress; - } - } - } - } - - for (i = 0; i < filter.length; i++) { - itemKeys = filter[i]; - partList = []; - part = null; - for (j = 0; j < parts.length; j++) { - var fullMatch = true; - for (itemKey in itemKeys) { - if (itemKeys.hasOwnProperty(itemKey) && !partNames[j][itemKey]) { - fullMatch = false; - break; - } - } - if (fullMatch && parts[j]) { - partList.push(parts[j]); - } - } - if (partList.length === 1) { - for (j = 0; j < partList.length; j++) { - part = partList[j]; - if (part.local) { - for (itemKey in itemKeys) { - if (itemKeys.hasOwnProperty(itemKey)) { - userKey = itemKeys[itemKey]; - localStats[userKey] = part.local.stat(itemKey); - } - } - } - } - } - else if (partList.length > 1) { - for (itemKey in itemKeys) { - if (itemKeys.hasOwnProperty(itemKey)) { - localStats[itemKeys[itemKey]] = []; - } - } - for (j = 0; j < partList.length; j++) { - part = partList[j]; - if (part.local) { - for (itemKey in itemKeys) { - if (itemKeys.hasOwnProperty(itemKey)) { - userKey = itemKeys[itemKey]; - localStats[userKey].push(part.local.stat(itemKey)); - } - } - } - } - } - } - } - - if (localStats.remoteAddress && turnAddress) { - localStats.remoteAddress = turnAddress; - } - callback(peerId, localStats); - }); - } - else { - callback(peerId, {"statistics": self.getConstantString("statsNotSupported")}); - } - }; - this.chromeStatsFilter = [ - { - "googTransmitBitrate": "transmitBitRate", - "googActualEncBitrate": "encodeRate", - "googAvailableSendBandwidth": "availableSendRate" - }, - { - "googCodecName": "audioCodec", - "googTypingNoiseState": "typingNoise", - "packetsSent": "audioPacketsSent", - "bytesSent": "audioBytesSent" - }, - { - "googCodecName": "videoCodec", - "googFrameRateSent": "outFrameRate", - "packetsSent": "videoPacketsSent", - "bytesSent": "videoBytesSent" - }, - { - "packetsLost": "videoPacketsLost", - "packetsReceived": "videoPacketsReceived", - "bytesReceived": "videoBytesReceived", - "googFrameRateOutput": "frameRateOut" - }, - { - "packetsLost": "audioPacketsLost", - "packetsReceived": "audioPacketsReceived", - "bytesReceived": "audioBytesReceived", - "audioOutputLevel": "audioOutputLevel" - }, - { - "googRemoteAddress": "remoteAddress", - "googActiveConnection": "activeConnection" - }, - { - "audioInputLevel": "audioInputLevel" - } - ]; - this.firefoxStatsFilter = { - "outboundrtp_audio.bytesSent": "audioBytesSent", - "outboundrtp_video.bytesSent": "videoBytesSent", - "inboundrtp_video.bytesReceived": "videoBytesReceived", - "inboundrtp_audio.bytesReceived": "audioBytesReceived", - "outboundrtp_audio.packetsSent": "audioPacketsSent", - "outboundrtp_video.packetsSent": "videoPacketsSent", - "inboundrtp_video.packetsReceived": "videoPacketsReceived", - "inboundrtp_audio.packetsReceived": "audioPacketsReceived", - "inboundrtp_video.packetsLost": "videoPacketsLost", - "inboundrtp_audio.packetsLost": "audioPacketsLost", - "firefoxRemoteAddress": "remoteAddress" - }; - this.standardStatsFilter = isFirefox ? self.firefoxStatsFilter : self.chromeStatsFilter; - /** Provide a set of application defined fields that will be part of this instances - * configuration information. This data will get sent to other peers via the websocket - * path. - * @param {String} roomName - the room the field is attached to. - * @param {String} fieldName - the name of the field. - * @param {Object} fieldValue - the value of the field. - * @example - * easyrtc.setRoomApiField("trekkieRoom", "favorite_alien", "Mr Spock"); - * easyrtc.setRoomOccupantListener( function(roomName, list){ - * for( var i in list ){ - * console.log("easyrtcid=" + i + " favorite alien is " + list[i].apiFields.favorite_alien); - * } - * }); - */ - this.setRoomApiField = function(roomName, fieldName, fieldValue) { - // - // if we're not connected yet, we'll just cache the fields until we are. - // - if (!self._roomApiFields) { - self._roomApiFields = {}; - } - if (!fieldName && !fieldValue) { - delete self._roomApiFields[roomName]; - return; - } - - if (!self._roomApiFields[roomName]) { - self._roomApiFields[roomName] = {}; - } - if (fieldValue !== undefined && fieldValue !== null) { - if (typeof fieldValue === "object") { - try { - JSON.stringify(fieldValue); - } - catch (jsonError) { - self.showError(self.errCodes.DEVELOPER_ERR, "easyrtc.setRoomApiField passed bad object "); - return; - } - } - self._roomApiFields[roomName][fieldName] = {fieldName: fieldName, fieldValue: fieldValue}; - } - else { - delete self._roomApiFields[roomName][fieldName]; - } - if (self.webSocketConnected) { - _enqueueSendRoomApi(roomName); - } - }; - var roomApiFieldTimer = null; - /** @private - * @param {String} roomName - */ - function _enqueueSendRoomApi(roomName) { -// -// Rather than issue the send request immediately, we set a timer so we can accumulate other -// calls -// - if (roomApiFieldTimer) { - clearTimeout(roomApiFieldTimer); - } - roomApiFieldTimer = setTimeout(function() { - _sendRoomApiFields(roomName, self._roomApiFields[roomName]); - roomApiFieldTimer = null; - }, 10); - } - ; - /** - * @private - * @param roomName - * @param fields - */ - function _sendRoomApiFields(roomName, fields) { - var fieldAsString = JSON.stringify(fields); - JSON.parse(fieldAsString); - var dataToShip = { - msgType: "setRoomApiField", - msgData: { - setRoomApiField: { - roomName: roomName, - field: fields - } - } - }; - self.webSocket.json.emit("easyrtcCmd", dataToShip, - function(ackMsg) { - if (ackMsg.msgType === "error") { - self.showError(ackMsg.msgData.errorCode, ackMsg.msgData.errorText); - } - } - ); - } - ; - /** Default error reporting function. The default implementation displays error messages - * in a programmatically created div with the id easyrtcErrorDialog. The div has title - * component with a class name of easyrtcErrorDialog_title. The error messages get added to a - * container with the id easyrtcErrorDialog_body. Each error message is a text node inside a div - * with a class of easyrtcErrorDialog_element. There is an "okay" button with the className of easyrtcErrorDialog_okayButton. - * @param {String} messageCode An error message code - * @param {String} message the error message text without any markup. - * @example - * easyrtc.showError("BAD_NAME", "Invalid username"); - */ - this.showError = function(messageCode, message) { - self.onError({errorCode: messageCode, errorText: message}); - }; - /** @private - * @param errorObject - */ - this.onError = function(errorObject) { - if (self.debugPrinter) { - self.debugPrinter("saw error " + errorObject.errorText); - } - var errorDiv = document.getElementById('easyrtcErrorDialog'); - var errorBody; - if (!errorDiv) { - errorDiv = document.createElement("div"); - errorDiv.id = 'easyrtcErrorDialog'; - var title = document.createElement("div"); - title.innerHTML = "Error messages"; - title.className = "easyrtcErrorDialog_title"; - errorDiv.appendChild(title); - errorBody = document.createElement("div"); - errorBody.id = "easyrtcErrorDialog_body"; - errorDiv.appendChild(errorBody); - var clearButton = document.createElement("button"); - clearButton.appendChild(document.createTextNode("Okay")); - clearButton.className = "easyrtcErrorDialog_okayButton"; - clearButton.onclick = function() { - errorBody.innerHTML = ""; // remove all inner nodes - errorDiv.style.display = "none"; - }; - errorDiv.appendChild(clearButton); - document.body.appendChild(errorDiv); - } - - errorBody = document.getElementById("easyrtcErrorDialog_body"); - var messageNode = document.createElement("div"); - messageNode.className = 'easyrtcErrorDialog_element'; - messageNode.appendChild(document.createTextNode(errorObject.errorText)); - errorBody.appendChild(messageNode); - errorDiv.style.display = "block"; - }; -// -// easyrtc.createObjectURL builds a URL from a media stream. -// Arguments: -// mediaStream - a media stream object. -// The video object in Chrome expects a URL. -// - /** @private - * @param mediaStream */ - this.createObjectURL = function(mediaStream) { - var errMessage; - if (window.URL && window.URL.createObjectURL) { - return window.URL.createObjectURL(mediaStream); - } - else if (window.webkitURL && window.webkitURL.createObjectURL) { - return window.webkit.createObjectURL(mediaStream); - } - else { - errMessage = "Your browsers does not support URL.createObjectURL."; - if (self.debugPrinter) { - self.debugPrinter("saw exception " + errMessage); - } - throw errMessage; - } - }; - /** - * A convenience function to ensure that a string doesn't have symbols that will be interpreted by HTML. - * @param {String} idString - * @return {String} The cleaned string. - * @example - * console.log( easyrtc.cleanId('&hello')); - */ - this.cleanId = function(idString) { - var MAP = { - '&': '&', - '<': '<', - '>': '>' - }; - return idString.replace(/[&<>]/g, function(c) { - return MAP[c]; - }); - }; - /** Set a callback that will be invoked when the application enters or leaves a room. - * - * @param {Function} handler - the first parameter is true for entering a room, false for leaving a room. The second parameter is the room name. - * @example - * easyrtc.setRoomEntryListener(function(entry, roomName){ - * if( entry ){ - * console.log("entering room " + roomName); - * } - * else{ - * console.log("leaving room " + roomName); - * } - * }); - */ - self.setRoomEntryListener = function(handler) { - self.roomEntryListener = handler; - }; - /** Set the callback that will be invoked when the list of people logged in changes. - * The callback expects to receive a room name argument, and - * a map whose ideas are easyrtcids and whose values are in turn maps - * supplying user specific information. The inner maps have the following keys: - * username, applicationName, browserFamily, browserMajor, osFamily, osMajor, deviceFamily. - * The third argument is the listener is the innerMap for the connections own data (not needed by most applications). - * @param {Function} listener - * @example - * easyrtc.setRoomOccupantListener( function(roomName, list, selfInfo){ - * for( var i in list ){ - * ("easyrtcid=" + i + " belongs to user " + list[i].username); - * } - * }); - */ - self.setRoomOccupantListener = function(listener) { - roomOccupantListener = listener; - }; - /** - * Sets a callback that is called when a data channel is open and ready to send data. - * The callback will be called with an easyrtcid as it's sole argument. - * @param {Function} listener - * @example - * easyrtc.setDataChannelOpenListener( function(easyrtcid){ - * easyrtc.sendDataP2P(easyrtcid, "greeting", "hello"); - * }); - */ - this.setDataChannelOpenListener = function(listener) { - onDataChannelOpen = listener; - }; - /** Sets a callback that is called when a previously open data channel closes. - * The callback will be called with an easyrtcid as it's sole argument. - * @param {Function} listener - * @example - * easyrtc.setDataChannelCloseListener( function(easyrtcid){ - * ("No longer connected to " + easyrtc.idToName(easyrtcid)); - * }); - */ - this.setDataChannelCloseListener = function(listener) { - onDataChannelClose = listener; - }; - /** Returns the number of live peer connections the client has. - * @return {Number} - * @example - * ("You have " + easyrtc.getConnectionCount() + " peer connections"); - */ - this.getConnectionCount = function() { - var count = 0; - var i; - for (i in peerConns) { - if (peerConns.hasOwnProperty(i)) { - if (self.getConnectStatus(i) === self.IS_CONNECTED) { - count++; - } - } - } - return count; - }; - /** Sets whether audio is transmitted by the local user in any subsequent calls. - * @param {Boolean} enabled true to include audio, false to exclude audio. The default is true. - * @example - * easyrtc.enableAudio(false); - */ - this.enableAudio = function(enabled) { - audioEnabled = enabled; - }; - /** - *Sets whether video is transmitted by the local user in any subsequent calls. - * @param {Boolean} enabled - true to include video, false to exclude video. The default is true. - * @example - * easyrtc.enableVideo(false); - */ - this.enableVideo = function(enabled) { - videoEnabled = enabled; - }; - /** - * Sets whether WebRTC data channels are used to send inter-client messages. - * This is only the messages that applications explicitly send to other applications, not the WebRTC signaling messages. - * @param {Boolean} enabled true to use data channels, false otherwise. The default is false. - * @example - * easyrtc.enableDataChannels(true); - */ - this.enableDataChannels = function(enabled) { - dataEnabled = enabled; - }; - /** - * @private - * @param {Boolean} enable - * @param {Array} tracks - an array of MediaStreamTrack - */ - function enableMediaTracks(enable, tracks) { - var i; - if (tracks) { - for (i = 0; i < tracks.length; i++) { - var track = tracks[i]; - track.enabled = enable; - } - } - } - - - // - // fetches a stream by name. Treat a null/undefined streamName as "default". - // - function getLocalMediaStreamByName(streamName) { - if (!streamName) { - streamName = "default"; - } - if (namedLocalMediaStreams.hasOwnProperty(streamName)) { - return namedLocalMediaStreams[streamName]; - } - else { - return null; - } - } - - /** - * Returns the user assigned id's of currently active local media streams. - * @return {Array} - */ - this.getLocalMediaIds = function() { - return Object.keys(namedLocalMediaStreams); - } - - function buildMediaIds() { - var mediaMap = {}; - var streamName; - for (streamName in namedLocalMediaStreams) { - mediaMap[streamName] = namedLocalMediaStreams[streamName].id || "default"; - } - return mediaMap; - } - - - function registerLocalMediaStreamByName(stream, streamName) { - var roomName; - if (!streamName) { - streamName = "default"; - } - stream.streamName = streamName; - namedLocalMediaStreams[streamName] = stream; - if (streamName !== "default") { - var mediaIds = buildMediaIds(); - for (roomName in self.roomData) { - self.setRoomApiField(roomName, "mediaIds", mediaIds); - } - } - } - - /** - * Allow an externally created mediastream (ie, created by another - * library) to be used within easyrtc. Tracking when it closes - * must be done by the supplying party. - */ - this.register3rdPartyLocalMediaStream = function(stream, streamName) { - return registerLocalMediaStreamByName(stream, streamName); - }; - // - // look up a stream's name from the stream.id - // - function getNameOfRemoteStream(easyrtcId, webrtcstreamId) { - var roomName; - var mediaIds; - var streamName; - if (!webrtcstreamId) { - webrtcstreamId = "default"; - } - if (peerConns[easyrtcId]) { - streamName = peerConns[easyrtcId].remoteStreamIdToName[webrtcstreamId]; - if (streamName) { - return streamName; - } - } - - for (roomName in self.roomData) { - mediaIds = self.getRoomApiField(roomName, easyrtcId, "mediaIds"); - if (!mediaIds) { - continue; - } - for (streamName in mediaIds) { - if (mediaIds.hasOwnProperty(streamName) && - mediaIds[streamName] === webrtcstreamId) { - return streamName; - } - } - // - // a stream from chrome to firefox will be missing it's id/label. - // there is no correct solution. - // - if( isFirefox ) { - // if there is a stream called default, return it in preference - if( mediaIds["default"] ) { - return "default"; - } - // - // otherwise return the first name we find. If there is more than - // one, complain to Mozilla. - // - for( var anyName in mediaIds ) { - return anyName; - } - } - } - return undefined; - } - - this.getNameOfRemoteStream = function(easyrtcId, webrtcStream){ - if(typeof webrtcStream == "string") { - return getNameOfRemoteStream(easyrtcId, webrtcStream); - } - else if( webrtcStream.id) { - return getNameOfRemoteStream(easyrtcId, webrtcStream.id); - } - } - - function closeLocalMediaStreamByName(streamName) { - if (!streamName) { - streamName = "default"; - } - var stream = self.getLocalStream(streamName); - if (!stream) { - return; - } - var streamId = stream.id || "default"; - if (namedLocalMediaStreams[streamName]) { - - - for (id in peerConns) { - if (peerConns.hasOwnProperty(id)) { - try { - peerConns[id].pc.removeStream(stream); - } catch (err) { - } - self.sendPeerMessage(id, "__closingMediaStream", {streamId: streamId, streamName: streamName}); - } - } - try { - namedLocalMediaStreams[streamName].stop(); - } catch (err) { - // not worth reporting an error at this location - // since we didn't want the media stream anyhow. - } - delete namedLocalMediaStreams[streamName]; - if (streamName !== "default") { - var mediaIds = buildMediaIds(); - for (roomName in self.roomData) { - self.setRoomApiField(roomName, "mediaIds", mediaIds); - } - } - } - } - /** - * Close the local media stream. You usually need to close the existing media stream - * of a camera before reacquring it at a different resolution. - * @param {String} streamName - an option stream name. - */ - this.closeLocalMediaStream = function(streamName) { - return closeLocalMediaStreamByName(streamName); - } - - /** - * Alias for closeLocalMediaStream - */ - this.closeLocalStream = this.closeLocalMediaStream; - /** - * This function is used to enable and disable the local camera. If you disable the - * camera, video objects display it will "freeze" until the camera is re-enabled. * - * By default, a camera is enabled. - * @param {Boolean} enable - true to enable the camera, false to disable it. - * @param {String} streamName - the name of the stream, optional. - */ - this.enableCamera = function(enable, streamName) { - var stream = getLocalMediaStreamByName(streamName); - if (stream && stream.getVideoTracks) { - enableMediaTracks(enable, stream.getVideoTracks()); - } - }; - /** - * This function is used to enable and disable the local microphone. If you disable - * the microphone, sounds stops being transmitted to your peers. By default, the microphone - * is enabled. - * @param {Boolean} enable - true to enable the microphone, false to disable it. - * @param {String} streamName - an optional streamName - */ - this.enableMicrophone = function(enable, streamName) { - var stream = getLocalMediaStreamByName(streamName); - if (stream && stream.getAudioTracks) { - enableMediaTracks(enable, stream.getAudioTracks()); - } - }; - /** - * Mute a video object. - * @param {String} videoObjectName - A DOMObject or the id of the DOMObject. - * @param {Boolean} mute - true to mute the video object, false to unmute it. - */ - self.muteVideoObject = function(videoObjectName, mute) { - var videoObject; - if (typeof (videoObjectName) === 'string') { - videoObject = document.getElementById(videoObjectName); - if (!videoObject) { - throw "Unknown video object " + videoObjectName; - } - } - else if (!videoObjectName) { - throw "muteVideoObject passed a null"; - } - else { - videoObject = videoObjectName; - } - videoObject.muted = !!mute; - }; - /** - * Returns a URL for your local camera and microphone. - * It can be called only after easyrtc.initMediaSource has succeeded. - * It returns a url that can be used as a source by the Chrome video element or the <canvas> element. - * @param {String} streamName - an option stream name. - * @return {URL} - * @example - * document.getElementById("myVideo").src = easyrtc.getLocalStreamAsUrl(); - */ - self.getLocalStreamAsUrl = function(streamName) { - var stream = getLocalMediaStreamByName(streamName); - if (stream === null) { - throw "Developer error: attempt to get a MediaStream without invoking easyrtc.initMediaSource successfully"; - } - return self.createObjectURL(stream); - }; - /** - * Returns a media stream for your local camera and microphone. - * It can be called only after easyrtc.initMediaSource has succeeded. - * It returns a stream that can be used as an argument to easyrtc.setVideoObjectSrc. - * Returns null if there is no local media stream acquired yet. - * @return {MediaStream} - * @example - * easyrtc.setVideoObjectSrc( document.getElementById("myVideo"), easyrtc.getLocalStream()); - */ - this.getLocalStream = function(streamName) { - return getLocalMediaStreamByName(streamName) || null; - }; - /** Clears the media stream on a video object. - * - * @param {Object} element the video object. - * @example - * easyrtc.clearMediaStream( document.getElementById('selfVideo')); - * - */ - this.clearMediaStream = function(element) { - if (typeof element.srcObject !== 'undefined') { - element.srcObject = null; - } else if (typeof element.mozSrcObject !== 'undefined') { - element.mozSrcObject = null; - } else if (typeof element.src !== 'undefined') { - //noinspection JSUndefinedPropertyAssignment - element.src = ""; - } - }; - /** - * Sets a video or audio object from a media stream. - * Chrome uses the src attribute and expects a URL, while firefox - * uses the mozSrcObject and expects a stream. This procedure hides - * that from you. - * If the media stream is from a local webcam, you may want to add the - * easyrtcMirror class to the video object so it looks like a proper mirror. - * The easyrtcMirror class is defined in this.css. - * Which is could be added using the same path of easyrtc.js file to an HTML file - * @param {Object} videoObject an HTML5 video object - * @param {MediaStream|String} stream a media stream as returned by easyrtc.getLocalStream or your stream acceptor. - * @example - * easyrtc.setVideoObjectSrc( document.getElementById("myVideo"), easyrtc.getLocalStream()); - * - */ - this.setVideoObjectSrc = function(videoObject, stream) { - if (stream && stream !== "") { - videoObject.autoplay = true; - attachMediaStream(videoObject, stream); - videoObject.play(); - } - else { - self.clearMediaStream(videoObject); - } - }; - - - /** - * This function builds a new named local media stream from a set of existing audio and video tracks from other media streams. - * @param {String} streamName is the name of the new media stream. - * @param {Array} audioTracks is an array of MediaStreamTracks - * @param {Array} videoTracks is an array of MediaStreamTracks - * @returns {MediaStream} the track created. - * @example - * easyrtc.buildLocalMediaStream("myComposedStream", - * easyrtc.getLocalStream("camera1").getVideoTracks(), - * easyrtc.getLocalStream("camera2").getAudioTracks()); - */ - this.buildLocalMediaStream = function(streamName, audioTracks, videoTracks) { - var i; - if (typeof streamName !== 'string') { - easyrtc.showError(this.errCodes.DEVELOPER_ERR, - "easyrtc.buildLocalMediaStream not supplied a stream name"); - return null; - } - - var streamToClone = null; - for(var key in namedLocalMediaStreams ) { - if( namedLocalMediaStreams.hasOwnProperty(key)) { - streamToClone = namedLocalMediaStreams[key]; - if(streamToClone) break; - } - } - if( !streamToClone ) { - for(key in peerConns) { - var remoteStreams = peerConns[key].pc.getRemoteStreams(); - if( remoteStreams && remoteStreams.length > 1 ) { - streamToClone = remoteStreams[0]; - } - } - } - if( !streamToClone ){ - self.showError(self.errCodes.DEVELOPER_ERR, - "Attempt to create a mediastream without one to clone from"); - return null; - } - - // - // clone whatever mediastream we found, and remove any of it's - // tracks. - // - var mediaClone = streamToClone.clone(); - var i; - var oldTracks = mediaClone.getTracks(); - - if (audioTracks) { - for (i = 0; i < audioTracks.length; i++) { - mediaClone.addTrack(audioTracks[i].clone()); - } - } - - if (videoTracks) { - for (i = 0; i < videoTracks.length; i++) { - mediaClone.addTrack(videoTracks[i].clone()); - } - } - - for( i = 0; i < oldTracks.length; i++ ) { - mediaClone.removeTrack(oldTracks[i]); - } - - registerLocalMediaStreamByName(mediaClone, streamName); - return mediaClone; - }; - - /* @private*/ - /** Load Easyrtc Stylesheet. - * Easyrtc Stylesheet define easyrtcMirror class and some basic css class for using easyrtc.js. - * That way, developers can override it or use it's own css file minified css or package. - * @example - * easyrtc.loadStylesheet(); - * - */ - this.loadStylesheet = function() { - - // - // check to see if we already have an easyrtc.css file loaded - // if we do, we can exit immediately. - // - var links = document.getElementsByTagName("link"); - var cssIndex, css; - for (cssIndex in links) { - if (links.hasOwnProperty(cssIndex)) { - css = links[cssIndex]; - if (css.href && (css.href.match(/\/easyrtc.css/))) { - return; - } - } - } - // - // add the easyrtc.css file since it isn't present - // - var easySheet = document.createElement("link"); - easySheet.setAttribute("rel", "stylesheet"); - easySheet.setAttribute("type", "text/css"); - easySheet.setAttribute("href", "/easyrtc/easyrtc.css"); - var headSection = document.getElementsByTagName("head")[0]; - var firstHead = headSection.childNodes[0]; - headSection.insertBefore(easySheet, firstHead); - }; - /** @private - * @param {String} x */ - this.formatError = function(x) { - var name, result; - if (x === null || typeof x === 'undefined') { - return "null"; - } - if (typeof x === 'string') { - return x; - } - else if (x.type && x.description) { - return x.type + " : " + x.description; - } - else if (typeof x === 'object') { - try { - return JSON.stringify(x); - } - catch (oops) { - result = "{"; - for (name in x) { - if (x.hasOwnProperty(name)) { - if (typeof x[name] === 'string') { - result = result + name + "='" + x[name] + "' "; - } - } - } - result = result + "}"; - return result; - } - } - else { - return "Strange case"; - } - }; - /** Initializes your access to a local camera and microphone. - * Failure could be caused a browser that didn't support WebRTC, or by the user - * not granting permission. - * If you are going to call easyrtc.enableAudio or easyrtc.enableVideo, you need to do it before - * calling easyrtc.initMediaSource. - * @param {function(Object)} successCallback - will be called with localmedia stream on success. - * @param {function(String,String)} errorCallback - is called with an error code and error description. - * @param {String} streamName - an optional name for the media source so you can use multiple cameras and screen share simultaneously. - * @example - * easyrtc.initMediaSource( - * function(mediastream){ - * easyrtc.setVideoObjectSrc( document.getElementById("mirrorVideo"), mediastream); - * }, - * function(errorCode, errorText){ - * easyrtc.showError(errorCode, errorText); - * }); - * - */ - this.initMediaSource = function(successCallback, errorCallback, streamName) { - - if (self.debugPrinter) { - self.debugPrinter("about to request local media"); - } - - if (!streamName) { - streamName = "default"; - } - - haveAudioVideo = { - audio: audioEnabled, - video: videoEnabled - }; - if (!errorCallback) { - errorCallback = function(errorCode, errorText) { - var message = "easyrtc.initMediaSource: " + self.formatError(errorText); - if (self.debugPrinter) { - self.debugPrinter(message); - } - self.showError(self.errCodes.MEDIA_ERR, message); - }; - } - - if (!self.supportsGetUserMedia()) { - errorCallback(self.errCodes.MEDIA_ERR, self.getConstantString("noWebrtcSupport")); - return; - } - - - if (!successCallback) { - self.showError(self.errCodes.DEVELOPER_ERR, - "easyrtc.initMediaSource not supplied a successCallback"); - return; - } - - - var mode = self.getUserMediaConstraints(); - /** @private - * @param {Object} stream - A mediaStream object. - * */ - var onUserMediaSuccess = function(stream) { - if (self.debugPrinter) { - self.debugPrinter("getUserMedia success callback entered"); - } - - if (self.debugPrinter) { - self.debugPrinter("successfully got local media"); - } - - stream.streamName = streamName; - registerLocalMediaStreamByName(stream, streamName); - var videoObj, triesLeft, tryToGetSize, ele; - if (haveAudioVideo.video) { - videoObj = document.createElement('video'); - videoObj.muted = true; - triesLeft = 30; - tryToGetSize = function() { - if (videoObj.videoWidth > 0 || triesLeft < 0) { - self.nativeVideoWidth = videoObj.videoWidth; - self.nativeVideoHeight = videoObj.videoHeight; - if (self._desiredVideoProperties.height && - (self.nativeVideoHeight !== self._desiredVideoProperties.height || - self.nativeVideoWidth !== self._desiredVideoProperties.width)) { - self.showError(self.errCodes.MEDIA_WARNING, - self.format(self.getConstantString("resolutionWarning"), - self._desiredVideoProperties.width, self._desiredVideoProperties.height, - self.nativeVideoWidth, self.nativeVideoHeight)); - } - self.setVideoObjectSrc(videoObj, ""); - if (videoObj.removeNode) { - videoObj.removeNode(true); - } - else { - ele = document.createElement('div'); - ele.appendChild(videoObj); - ele.removeChild(videoObj); - } - - updateConfigurationInfo(); - if (successCallback) { - successCallback(stream); - } - } - else { - triesLeft -= 1; - setTimeout(tryToGetSize, 300); - } - }; - self.setVideoObjectSrc(videoObj, stream); - tryToGetSize(); - } - else { - updateConfigurationInfo(); - if (successCallback) { - successCallback(stream); - } - } - }; - /** @private - * @param {String} error - */ - var onUserMediaError = function(error) { - console.log("getusermedia failed"); - if (self.debugPrinter) { - self.debugPrinter("failed to get local media"); - } - var errText; - if (typeof error === 'string') { - errText = error; - } - else if (error.name) { - errText = error.name; - } - else { - errText = "Unknown"; - } - if (errorCallback) { - console.log("invoking error callback", errText); - errorCallback(self.errCodes.MEDIA_ERR, self.format(self.getConstantString("gumFailed"), errText)); - } - closeLocalMediaStreamByName(streamName); - haveAudioVideo = { - audio: false, - video: false - }; - updateConfigurationInfo(); - }; - if (!audioEnabled && !videoEnabled) { - onUserMediaError(self.getConstantString("requireAudioOrVideo")); - return; - } - - function getCurrentTime() { - return (new Date()).getTime(); - } - - var firstCallTime; - function tryAgain(error) { - var currentTime = getCurrentTime(); - if (currentTime < firstCallTime + 1000) { - console.log("Trying getUserMedia a second time"); - setTimeout(function() { - getUserMedia(mode, onUserMediaSuccess, onUserMediaError); - }, 3000); - } - else { - onUserMediaError(error); - } - } - - if (videoEnabled || audioEnabled) { - // - // getUserMedia sometimes fails the first time I call it. I suspect it's a page loading - // issue. So I'm going to try adding a 3 second delay to allow things to settle down first. - // In addition, I'm going to try again after 3 seconds. - // - - - setTimeout(function() { - try { - firstCallTime = getCurrentTime(); - getUserMedia(mode, onUserMediaSuccess, tryAgain); - } catch (e) { - tryAgain(e); - } - }, 1000); - } - else { - onUserMediaSuccess(null); - } - }; - /** - * Sets the callback used to decide whether to accept or reject an incoming call. - * @param {Function} acceptCheck takes the arguments (callerEasyrtcid, acceptor). - * The acceptCheck callback is passed an easyrtcid and an aceptor function. The acceptor function should be called with either - * a true value (accept the call) or false value( reject the call) as it's first argument, and optionally, - * an array of local media streamNames as a second argument. - * @example - * easyrtc.setAcceptChecker( function(easyrtcid, acceptor){ - * if( easyrtc.idToName(easyrtcid) === 'Fred' ){ - * acceptor(true); - * } - * else if( easyrtc.idToName(easyrtcid) === 'Barney' ){ - * setTimeout( function(){ - acceptor(true, ['myOtherCam']); // myOtherCam presumed to a streamName - }, 10000); - * } - * else{ - * acceptor(false); - * } - * }); - */ - this.setAcceptChecker = function(acceptCheck) { - self.acceptCheck = acceptCheck; - }; - /** - * easyrtc.setStreamAcceptor sets a callback to receive media streams from other peers, independent - * of where the call was initiated (caller or callee). - * @param {Function} acceptor takes arguments (caller, mediaStream, mediaStreamName) - * @example - * easyrtc.setStreamAcceptor(function(easyrtcid, stream, streamName){ - * document.getElementById('callerName').innerHTML = easyrtc.idToName(easyrtcid); - * easyrtc.setVideoObjectSrc( document.getElementById("callerVideo"), stream); - * }); - */ - this.setStreamAcceptor = function(acceptor) { - self.streamAcceptor = acceptor; - }; - /** Sets the easyrtc.onError field to a user specified function. - * @param {Function} errListener takes an object of the form {errorCode: String, errorText: String} - * @example - * easyrtc.setOnError( function(errorObject){ - * document.getElementById("errMessageDiv").innerHTML += errorObject.errorText; - * }); - */ - self.setOnError = function(errListener) { - self.onError = errListener; - }; - /** - * Sets the callCancelled callback. This will be called when a remote user - * initiates a call to you, but does a "hangup" before you have a chance to get his video stream. - * @param {Function} callCancelled takes an easyrtcid as an argument and a boolean that indicates whether - * the call was explicitly cancelled remotely (true), or actually accepted by the user attempting a call to - * the same party. - * @example - * easyrtc.setCallCancelled( function(easyrtcid, explicitlyCancelled){ - * if( explicitlyCancelled ){ - * console.log(easyrtc.idToName(easyrtcid) + " stopped trying to reach you"); - * } - * else{ - * console.log("Implicitly called " + easyrtc.idToName(easyrtcid)); - * } - * }); - */ - this.setCallCancelled = function(callCancelled) { - self.callCancelled = callCancelled; - }; - /** Sets a callback to receive notification of a media stream closing. The usual - * use of this is to clear the source of your video object so you aren't left with - * the last frame of the video displayed on it. - * @param {Function} onStreamClosed takes an easyrtcid as it's first parameter, the stream as it's second argument, and name of the video stream as it's third. - * @example - * easyrtc.setOnStreamClosed( function(easyrtcid, stream, streamName){ - * easyrtc.setVideoObjectSrc( document.getElementById("callerVideo"), ""); - * ( easyrtc.idToName(easyrtcid) + " closed stream " + stream.id + " " + streamName); - * }); - */ - this.setOnStreamClosed = function(onStreamClosed) { - self.onStreamClosed = onStreamClosed; - }; - /** @deprecated No longer supported by Google. - * Sets the bandwidth for sending video data. - * Setting the rate too low will cause connection attempts to fail. 40 is probably good lower limit. - * The default is 50. A value of zero will remove bandwidth limits. - * @param {Number} kbitsPerSecond is rate in kilobits per second. - * @example - * easyrtc.setVideoBandwidth( 40); - */ - this.setVideoBandwidth = function(kbitsPerSecond) { - self.showError("easyrtc.setVideoBandwidth is deprecated, it no longer has an effect."); - }; - /** Determines whether the current browser supports the new data channels. - * EasyRTC will not open up connections with the old data channels. - * @returns {Boolean} - */ - this.supportsDataChannels = function() { - if (navigator.userAgent.match(/android/i)) { - return webrtcDetectedVersion >= 34; - } - else { - return (webrtcDetectedBrowser === "firefox" || webrtcDetectedVersion >= 32); - } - }; - /** - * Sets a listener for data sent from another client (either peer to peer or via websockets). - * If no msgType or source is provided, the listener applies to all events that aren't otherwise handled. - * If a msgType but no source is provided, the listener applies to all messages of that msgType that aren't otherwise handled. - * If a msgType and a source is provided, the listener applies to only message of the specified type coming from the specified peer. - * The most specific case takes priority over the more general. - * @param {Function} listener has the signature (easyrtcid, msgType, msgData, targeting). - * msgType is a string. targeting is null if the message was received using WebRTC data channels, otherwise it - * is an object that contains one or more of the following string valued elements {targetEasyrtcid, targetGroup, targetRoom}. - * @param {String} msgType - a string, optional. - * @param {String} source - the sender's easyrtcid, optional. - * @example - * easyrtc.setPeerListener( function(easyrtcid, msgType, msgData, targeting){ - * console.log("From " + easyrtc.idToName(easyrtcid) + - * " sent the following data " + JSON.stringify(msgData)); - * }); - * easyrtc.setPeerListener( function(easyrtcid, msgType, msgData, targeting){ - * console.log("From " + easyrtc.idToName(easyrtcid) + - * " sent the following data " + JSON.stringify(msgData)); - * }, 'food', 'dkdjdekj44--'); - * easyrtc.setPeerListener( function(easyrtcid, msgType, msgData, targeting){ - * console.log("From " + easyrtcid + - * " sent the following data " + JSON.stringify(msgData)); - * }, 'drink'); - * - * - */ - this.setPeerListener = function(listener, msgType, source) { - if (!msgType) { - receivePeer.cb = listener; - } - else { - if (!receivePeer.msgTypes[msgType]) { - receivePeer.msgTypes[msgType] = {sources: {}}; - } - if (!source) { - receivePeer.msgTypes[msgType].cb = listener; - } - else { - receivePeer.msgTypes[msgType].sources[source] = {cb: listener}; - } - } - }; - /* This function serves to distribute peer messages to the various peer listeners */ - /** @private - * @param {String} easyrtcid - * @param {Object} msg - needs to contain a msgType and a msgData field. - * @param {Object} targeting - */ - this.receivePeerDistribute = function(easyrtcid, msg, targeting) { - var msgType = msg.msgType; - var msgData = msg.msgData; - if (!msgType) { - console.log("received peer message without msgType", msg); - return; - } - - if (receivePeer.msgTypes[msgType]) { - if (receivePeer.msgTypes[msgType].sources[easyrtcid] && - receivePeer.msgTypes[msgType].sources[easyrtcid].cb) { - receivePeer.msgTypes[msgType].sources[easyrtcid].cb(easyrtcid, msgType, msgData, targeting); - return; - } - if (receivePeer.msgTypes[msgType].cb) { - receivePeer.msgTypes[msgType].cb(easyrtcid, msgType, msgData, targeting); - return; - } - } - if (receivePeer.cb) { - receivePeer.cb(easyrtcid, msgType, msgData, targeting); - } - }; - /** - * Sets a listener for messages from the server. - * @param {Function} listener has the signature (msgType, msgData, targeting) - * @example - * easyrtc.setServerListener( function(msgType, msgData, targeting){ - * ("The Server sent the following message " + JSON.stringify(msgData)); - * }); - */ - this.setServerListener = function(listener) { - receiveServerCB = listener; - }; - /** - * Sets the url of the Socket server. - * The node.js server is great as a socket server, but it doesn't have - * all the hooks you'd like in a general web server, like PHP or Python - * plug-ins. By setting the serverPath your application can get it's regular - * pages from a regular web server, but the EasyRTC library can still reach the - * socket server. - * @param {String} socketUrl - * @param {Object} options an optional dictionary of options for socket.io's connect method. - * The default is {'connect timeout': 10000,'force new connection': true } - * @example - * easyrtc.setSocketUrl(":8080", options); - */ - this.setSocketUrl = function(socketUrl, options) { - if (self.debugPrinter) { - self.debugPrinter("WebRTC signaling server URL set to " + socketUrl); - } - serverPath = socketUrl; - if( options ) { - connectionOptions = options; - } - }; - /** - * Sets the user name associated with the connection. - * @param {String} username must obey standard identifier conventions. - * @returns {Boolean} true if the call succeeded, false if the username was invalid. - * @example - * if( !easyrtc.setUsername("JohnSmith") ){ - * console.error("bad user name); - * - */ - this.setUsername = function(username) { - if( self.myEasyrtcid ) { - easyrtc.showError(easyrtc.errCodes.DEVELOPER_ERR, "easyrtc.setUsername called after authentication"); - return false; - } - else if (self.isNameValid(username)) { - self.username = username; - return true; - } - else { - self.showError(self.errCodes.BAD_NAME, self.format(self.getConstantString("badUserName"), username)); - return false; - } - }; - /** - * Get an array of easyrtcids that are using a particular username - * @param {String} username - the username of interest. - * @param {String} room - an optional room name argument limiting results to a particular room. - * @returns {Array} an array of {easyrtcid:id, roomName: roomName}. - */ - this.usernameToIds = function(username, room) { - var results = []; - var id, roomName; - for (roomName in lastLoggedInList) { - if (!lastLoggedInList.hasOwnProperty(roomName)) { - continue; - } - if (room && roomName !== room) { - continue; - } - for (id in lastLoggedInList[roomName]) { - if (!lastLoggedInList[roomName].hasOwnProperty(id)) { - continue; - } - if (lastLoggedInList[roomName][id].username === username) { - results.push({ - easyrtcid: id, - roomName: roomName - }); - } - } - } - return results; - }; - /** - * Returns another peers API field, if it exists. - * @param {type} roomName - * @param {type} easyrtcid - * @param {type} fieldName - * @returns {Object} Undefined if the attribute does not exist, its value otherwise. - */ - this.getRoomApiField = function(roomName, easyrtcid, fieldName) { - if (lastLoggedInList[roomName] && - lastLoggedInList[roomName][easyrtcid] && - lastLoggedInList[roomName][easyrtcid].apiField && - lastLoggedInList[roomName][easyrtcid].apiField[fieldName]) { - return lastLoggedInList[roomName][easyrtcid].apiField[fieldName].fieldValue; - } - else { - return undefined; - } - }; - /** - * Set the authentication credential if needed. - * @param {Object} credentialParm - a JSONable object. - */ - this.setCredential = function(credentialParm) { - try { - JSON.stringify(credentialParm); - credential = credentialParm; - return true; - } - catch (oops) { - self.showError(self.errCodes.BAD_CREDENTIAL, "easyrtc.setCredential passed a non-JSON-able object"); - throw "easyrtc.setCredential passed a non-JSON-able object"; - } - }; - /** - * Sets the listener for socket disconnection by external (to the API) reasons. - * @param {Function} disconnectListener takes no arguments and is not called as a result of calling easyrtc.disconnect. - * @example - * easyrtc.setDisconnectListener(function(){ - * easyrtc.showError("SYSTEM-ERROR", "Lost our connection to the socket server"); - * }); - */ - this.setDisconnectListener = function(disconnectListener) { - self.disconnectListener = disconnectListener; - }; - /** - * Convert an easyrtcid to a user name. This is useful for labeling buttons and messages - * regarding peers. - * @param {String} easyrtcid - * @return {String} the username associated with the easyrtcid, or the easyrtcid if there is - * no associated username. - * @example - * console.log(easyrtcid + " is actually " + easyrtc.idToName(easyrtcid)); - */ - this.idToName = function(easyrtcid) { - var roomName; - for (roomName in lastLoggedInList) { - if (!lastLoggedInList.hasOwnProperty(roomName)) { - continue; - } - if (lastLoggedInList[roomName][easyrtcid]) { - if (lastLoggedInList[roomName][easyrtcid].username) { - return lastLoggedInList[roomName][easyrtcid].username; - } - } - } - return easyrtcid; - }; - /* used in easyrtc.connect */ - /** @private */ - this.webSocket = null; - var pc_config = {}; - var pc_config_to_use = null; - var use_fresh_ice_each_peer = false; - /** - * Determines whether fresh ice server configuration should be requested from the server for each peer connection. - * @param {Boolean} value the default is false. - */ - this.setUseFreshIceEachPeerConnection = function(value) { - use_fresh_ice_each_peer = value; - }; - /** - * Returns the last ice config supplied by the EasyRTC server. This function is not normally used, it is provided - * for people who want to try filtering ice server configuration on the client. - * @return {Object} which has the form {iceServers:[ice_server_entry, ice_server_entry, ...]} - */ - this.getServerIce = function() { - return pc_config; - }; - /** - * Sets the ice server configuration that will be used in subsequent calls. You only need this function if you are filtering - * the ice server configuration on the client or if you are using TURN certificates that have a very short lifespan. - * @param {Object} ice An object with iceServers element containing an array of ice server entries. - * @example - * easyrtc.setIceUsedInCalls( {"iceServers": [ - * { - * "url": "stun:stun.sipgate.net" - * }, - * { - * "url": "stun:217.10.68.152" - * }, - * { - * "url": "stun:stun.sipgate.net:10000" - * } - * ]}); - * easyrtc.call(...); - */ - this.setIceUsedInCalls = function(ice) { - if (!ice.iceServers) { - easyrtc.showError(easyrtc.errCodes.DEVELOPER_ERR, "Bad ice configuration passed to easyrtc.setIceUsedInCalls"); - } - else { - pc_config_to_use = ice; - } - }; - var closedChannel = null; - /** @private - * @param easyrtcid - * @param checkAudio - */ - function _haveTracks(easyrtcid, checkAudio, streamName) { - var stream, peerConnObj; - if (!easyrtcid) { - stream = getLocalMediaStreamByName(streamName); - } - else { - peerConnObj = peerConns[easyrtcid]; - if (!peerConnObj) { - console.error("Developer error: haveTracks called about a peer you don't have a connection to"); - return false; - } - stream = peerConnObj.getRemoteStreamByName(streamName); - } - if (!stream) { - return false; - } - - var tracks; - try { - if (checkAudio) { - tracks = stream.getAudioTracks(); - } - else { - tracks = stream.getVideoTracks(); - } - } catch (oops) { - return true; - } - if (!tracks) - return false; - return tracks.length > 0; - } - ; - /** Determines if a particular peer2peer connection has an audio track. - * @param {String} easyrtcid - the id of the other caller in the connection. If easyrtcid is not supplied, checks the local media. - * @param {String} streamName - an optional stream id. - * @return {Boolean} true if there is an audio track or the browser can't tell us. - */ - this.haveAudioTrack = function(easyrtcid, streamName) { - return _haveTracks(easyrtcid, true, streamName); - }; - /** Determines if a particular peer2peer connection has a video track. - * @param {String} easyrtcid - the id of the other caller in the connection. If easyrtcid is not supplied, checks the local media. - * @param {String} streamName - an optional stream id. * - * @return {Boolean} true if there is an video track or the browser can't tell us. - */ - this.haveVideoTrack = function(easyrtcid, streamName) { - return _haveTracks(easyrtcid, false, streamName); - }; - /** - * Gets a data field associated with a room. - * @param {String} roomName - the name of the room. - * @param {String} fieldName - the name of the field. - * @return {Object} dataValue - the value of the field if present, undefined if not present. - */ - this.getRoomField = function(roomName, fieldName) { - var fields = self.getRoomFields(roomName); - if (!fields || !fields[fieldName]) - return undefined; - return fields[fieldName].fieldValue; - }; -// -// Experimental function to determine if statistics gathering is supported. -// - this.supportsStatistics = function() { - var peer; - try { - peer = new RTCPeerConnection({iceServers: []}, {}); - return !!peer.getStats; - } - catch (err) { - return false; - } - }; - /** - * Connects to the EasyRTC signaling server. You must connect before trying to - * call other users. - * @param {String} applicationName is a string that identifies the application so that different applications can have different - * lists of users. Note that the server configuration specifies a regular expression that is used to check application names - * for validity. The default pattern is that of an identifier, spaces are not allowed. - * @param {Function} successCallback (easyrtcId, roomOwner) - is called on successful connect. easyrtcId is the - * unique name that the client is known to the server by. A client usually only needs it's own easyrtcId for debugging purposes. - * roomOwner is true if the user is the owner of a room. It's value is random if the user is in multiple rooms. - * @param {Function} errorCallback (errorCode, errorText) - is called on unsuccessful connect. if null, an alert is called instead. - * The errorCode takes it's value from easyrtc.errCodes. - * @example - * easyrtc.connect("mychat_app", - * function(easyrtcid, roomOwner){ - * if( roomOwner){ console.log("I'm the room owner"); } - * console.log("my id is " + easyrtcid); - * }, - * function(errorText){ - * console.log("failed to connect ", erFrText); - * }); - */ - - var fields = null; - function isEmptyObj(obj) { - if (obj === null || obj === undefined) { - return true; - } - var key; - for (key in obj) { - if (obj.hasOwnProperty(key)) { - return false; - } - } - return true; - } - - // -// easyrtc.disconnect performs a clean disconnection of the client from the server. -// - function disconnectBody() { - var key; - self.loggingOut = true; - offersPending = {}; - acceptancePending = {}; - self.disconnecting = true; - closedChannel = self.webSocket; - if (self.webSocketConnected) { - if (!preallocatedSocketIo) { - self.webSocket.close(); - } - self.webSocketConnected = false; - } - self.hangupAll(); - if (roomOccupantListener) { - for (key in lastLoggedInList) { - if (lastLoggedInList.hasOwnProperty(key)) { - roomOccupantListener(key, {}, false); - } - } - } - lastLoggedInList = {}; - self.emitEvent("roomOccupant", {}); - self.roomData = {}; - self.roomJoin = {}; - self.loggingOut = false; - self.myEasyrtcid = null; - self.disconnecting = false; - oldConfig = {}; - } - ; - this.disconnect = function() { - - if (self.debugPrinter) { - self.debugPrinter("attempt to disconnect from WebRTC signalling server"); - } - - self.disconnecting = true; - self.hangupAll(); - self.loggingOut = true; - // - // The hangupAll may try to send configuration information back to the server. - // Collecting that information is asynchronous, we don't actually close the - // connection until it's had a chance to be sent. We allocate 100ms for collecting - // the info, so 250ms should be sufficient for the disconnecting. - // - setTimeout(function() { - if (self.webSocket) { - try { - self.webSocket.disconnect(); - } catch (e) { - // we don't really care if this fails. - } - - closedChannel = self.webSocket; - self.webSocket = 0; - } - self.loggingOut = false; - self.disconnecting = false; - if (roomOccupantListener) { - roomOccupantListener(null, {}, false); - } - self.emitEvent("roomOccupant", {}); - oldConfig = {}; - }, 250); - }; - // - // This function is used to send WebRTC signaling messages to another client. These messages all the form: - // destUser: some id or null - // msgType: one of ["offer"/"answer"/"candidate","reject","hangup", "getRoomList"] - // msgData: either null or an SDP record - // successCallback: a function with the signature function(msgType, wholeMsg); - // errorCallback: a function with signature function(errorCode, errorText) - // - function sendSignalling(destUser, msgType, msgData, successCallback, errorCallback) { - if (!self.webSocket) { - throw "Attempt to send message without a valid connection to the server."; - } - else { - var dataToShip = { - msgType: msgType - }; - if (destUser) { - dataToShip.targetEasyrtcid = destUser; - } - if (msgData) { - dataToShip.msgData = msgData; - } - - if (self.debugPrinter) { - self.debugPrinter("sending socket message " + JSON.stringify(dataToShip)); - } - self.webSocket.json.emit("easyrtcCmd", dataToShip, - function(ackMsg) { - if (ackMsg.msgType !== "error") { - if (!ackMsg.hasOwnProperty("msgData")) { - ackMsg.msgData = null; - } - if (successCallback) { - successCallback(ackMsg.msgType, ackMsg.msgData); - } - } - else { - if (errorCallback) { - errorCallback(ackMsg.msgData.errorCode, ackMsg.msgData.errorText); - } - else { - self.showError(ackMsg.msgData.errorCode, ackMsg.msgData.errorText); - } - } - } - ); - } - } - - - /** - *Sends data to another user using previously established data channel. This method will - * fail if no data channel has been established yet. Unlike the easyrtc.sendWS method, - * you can't send a dictionary, convert dictionaries to strings using JSON.stringify first. - * What data types you can send, and how large a data type depends on your browser. - * @param {String} destUser (an easyrtcid) - * @param {String} msgType - the type of message being sent (application specific). - * @param {Object} msgData - a JSONable object. - * @example - * easyrtc.sendDataP2P(someEasyrtcid, "roomData", {room:499, bldgNum:'asd'}); - */ - this.sendDataP2P = function(destUser, msgType, msgData) { - - var flattenedData = JSON.stringify({msgType: msgType, msgData: msgData}); - if (self.debugPrinter) { - self.debugPrinter("sending p2p message to " + destUser + " with data=" + JSON.stringify(flattenedData)); - } - - if (!peerConns[destUser]) { - self.showError(self.errCodes.DEVELOPER_ERR, "Attempt to send data peer to peer without a connection to " + destUser + ' first.'); - } - else if (!peerConns[destUser].dataChannelS) { - self.showError(self.errCodes.DEVELOPER_ERR, "Attempt to send data peer to peer without establishing a data channel to " + destUser + ' first.'); - } - else if (!peerConns[destUser].dataChannelReady) { - self.showError(self.errCodes.DEVELOPER_ERR, "Attempt to use data channel to " + destUser + " before it's ready to send."); - } - else { - try { - peerConns[destUser].dataChannelS.send(flattenedData); - } catch (oops) { - console.log("error=", oops); - throw oops; - } - } - }; - /** Sends data to another user using websockets. The easyrtc.sendServerMessage or easyrtc.sendPeerMessage methods - * are wrappers for this method; application code should use them instead. - * @param {String} destination - either a string containing the easyrtcId of the other user, or an object containing some subset of the following fields: targetEasyrtcid, targetGroup, targetRoom. - * Specifying multiple fields restricts the scope of the destination (operates as a logical AND, not a logical OR). - * @param {String} msgType -the type of message being sent (application specific). - * @param {Object} msgData - a JSONable object. - * @param {Function} ackhandler - by default, the ackhandler handles acknowledgments from the server that your message was delivered to it's destination. - * However, application logic in the server can over-ride this. If you leave this null, a stub ackHandler will be used. The ackHandler - * gets passed a message with the same msgType as your outgoing message, or a message type of "error" in which case - * msgData will contain a errorCode and errorText fields. - * @example - * easyrtc.sendDataWS(someEasyrtcid, "setPostalAddress", {room:499, bldgNum:'asd'}, - * function(ackMsg){ - * console.log("saw the following acknowledgment " + JSON.stringify(ackMsg)); - * } - * ); - */ - this.sendDataWS = function(destination, msgType, msgData, ackhandler) { - if (self.debugPrinter) { - self.debugPrinter("sending client message via websockets to " + destination + " with data=" + JSON.stringify(msgData)); - } - if (!ackhandler) { - ackhandler = function(msg) { - if (msg.msgType === "error") { - self.showError(msg.msgData.errorCode, msg.msgData.errorText); - } - }; - } - - var outgoingMessage = { - msgType: msgType, - msgData: msgData - }; - if (destination) { - if (typeof destination === 'string') { - outgoingMessage.targetEasyrtcid = destination; - } - else if (typeof destination === 'object') { - if (destination.targetEasyrtcid) { - outgoingMessage.targetEasyrtcid = destination.targetEasyrtcid; - } - if (destination.targetRoom) { - outgoingMessage.targetRoom = destination.targetRoom; - } - if (destination.targetGroup) { - outgoingMessage.targetGroup = destination.targetGroup; - } - } - } - - - if (self.webSocket) { - self.webSocket.json.emit("easyrtcMsg", outgoingMessage, ackhandler); - } - else { - if (self.debugPrinter) { - self.debugPrinter("websocket failed because no connection to server"); - } - throw "Attempt to send message without a valid connection to the server."; - } - }; - /** Sends data to another user. This method uses data channels if one has been set up, or websockets otherwise. - * @param {String} destUser - a string containing the easyrtcId of the other user. - * Specifying multiple fields restricts the scope of the destination (operates as a logical AND, not a logical OR). - * @param {String} msgType -the type of message being sent (application specific). - * @param {Object} msgData - a JSONable object. - * @param {Function} ackHandler - a function which receives acknowledgments. May only be invoked in - * the websocket case. - * @example - * easyrtc.sendData(someEasyrtcid, "roomData", {room:499, bldgNum:'asd'}, - * function ackHandler(msgType, msgData); - * ); - */ - this.sendData = function(destUser, msgType, msgData, ackHandler) { - if (peerConns[destUser] && peerConns[destUser].dataChannelReady) { - self.sendDataP2P(destUser, msgType, msgData); - } - else { - self.sendDataWS(destUser, msgType, msgData, ackHandler); - } - }; - /** - * Sends a message to another peer on the easyrtcMsg channel. - * @param {String} destination - either a string containing the easyrtcId of the other user, or an object containing some subset of the following fields: targetEasyrtcid, targetGroup, targetRoom. - * Specifying multiple fields restricts the scope of the destination (operates as a logical AND, not a logical OR). - * @param {String} msgType - the type of message being sent (application specific). - * @param {Object} msgData - a JSONable object with the message contents. - * @param {function(String, Object)} successCB - a callback function with results from the server. - * @param {function(String, String)} failureCB - a callback function to handle errors. - * @example - * easyrtc.sendPeerMessage(otherUser, 'offer_candy', {candy_name:'mars'}, - * function(msgType, msgBody ){ - * console.log("message was sent"); - * }, - * function(errorCode, errorText){ - * console.log("error was " + errorText); - * }); - */ - this.sendPeerMessage = function(destination, msgType, msgData, successCB, failureCB) { - if (!destination) { - console.error("Developer error, destination was null in sendPeerMessage"); - } - - if (self.debugPrinter) { - self.debugPrinter("sending peer message " + JSON.stringify(msgData)); - } - function ackHandler(response) { - if (response.msgType === "error") { - if (failureCB) { - failureCB(response.msgData.errorCode, response.msgData.errorText); - } - } - else { - if (successCB) { - // firefox complains if you pass an undefined as an parameter. - successCB(response.msgType, response.msgData ? response.msgData : null); - } - } - } - - self.sendDataWS(destination, msgType, msgData, ackHandler); - }; - /** - * Sends a message to the application code in the server (ie, on the easyrtcMsg channel). - * @param {String} msgType - the type of message being sent (application specific). - * @param {Object} msgData - a JSONable object with the message contents. - * @param {function(String, Object)} successCB - a callback function with results from the server. - * @param {function(String, String)} failureCB - a callback function to handle errors. - * @example - * easyrtc.sendServerMessage('get_candy', {candy_name:'mars'}, - * function(msgType, msgData ){ - * console.log("got candy count of " + msgData.barCount); - * }, - * function(errorCode, errorText){ - * console.log("error was " + errorText); - * }); - */ - this.sendServerMessage = function(msgType, msgData, successCB, failureCB) { - if (self.debugPrinter) { - var dataToShip = {msgType: msgType, msgData: msgData}; - self.debugPrinter("sending server message " + JSON.stringify(dataToShip)); - } - function ackhandler(response) { - if (response.msgType === "error") { - if (failureCB) { - failureCB(response.msgData.errorCode, response.msgData.errorText); - } - } - else { - if (successCB) { - successCB(response.msgType, response.msgData ? response.msgData : null); - } - } - } - - self.sendDataWS(null, msgType, msgData, ackhandler); - }; - /** Sends the server a request for the list of rooms the user can see. - * You must have already be connected to use this function. - * @param {function(Object)} callback - on success, this function is called with a map of the form { roomName:{"roomName":String, "numberClients": Number}}. - * The roomName appears as both the key to the map, and as the value of the "roomName" field. - * @param {function(String, String)} errorCallback is called on failure. It gets an errorCode and errorText as it's too arguments. - * @example - * easyrtc.getRoomList( - * function(roomList){ - * for(roomName in roomList){ - * console.log("saw room " + roomName); - * } - * }, - * function(errorCode, errorText){ - * easyrtc.showError(errorCode, errorText); - * } - * ); - */ - this.getRoomList = function(callback, errorCallback) { - sendSignalling(null, "getRoomList", null, - function(msgType, msgData) { - callback(msgData.roomList); - }, - function(errorCode, errorText) { - if (errorCallback) { - errorCallback(errorCode, errorText); - } - else { - self.showError(errorCode, errorText); - } - } - ); - }; - /** Value returned by easyrtc.getConnectStatus if the other user isn't connected to us. */ - this.NOT_CONNECTED = "not connected"; - /** Value returned by easyrtc.getConnectStatus if the other user is in the process of getting connected */ - this.BECOMING_CONNECTED = "connection in progress to us."; - /** Value returned by easyrtc.getConnectStatus if the other user is connected to us. */ - this.IS_CONNECTED = "is connected"; - /** - * Check if the client has a peer-2-peer connection to another user. - * The return values are text strings so you can use them in debugging output. - * @param {String} otherUser - the easyrtcid of the other user. - * @return {String} one of the following values: easyrtc.NOT_CONNECTED, easyrtc.BECOMING_CONNECTED, easyrtc.IS_CONNECTED - * @example - * if( easyrtc.getConnectStatus(otherEasyrtcid) == easyrtc.NOT_CONNECTED ){ - * easyrtc.call(otherEasyrtcid, - * function(){ console.log("success"); }, - * function(){ console.log("failure"); }); - * } - */ - this.getConnectStatus = function(otherUser) { - if (!peerConns.hasOwnProperty(otherUser)) { - return self.NOT_CONNECTED; - } - var peer = peerConns[otherUser]; - if ((peer.sharingAudio || peer.sharingVideo) && !peer.startedAV) { - return self.BECOMING_CONNECTED; - } - else if (peer.sharingData && !peer.dataChannelReady) { - return self.BECOMING_CONNECTED; - } - else { - return self.IS_CONNECTED; - } - }; - /** - * @private - */ - function buildPeerConstraints() { - var options = []; - options.push({'DtlsSrtpKeyAgreement': 'true'}); // for interoperability - return {optional: options}; - } - - - /** - * Initiates a call to another user. If it succeeds, the streamAcceptor callback will be called. - * @param {String} otherUser - the easyrtcid of the peer being called. - * @param {Function} callSuccessCB (otherCaller, mediaType) - is called when the datachannel is established or the MediaStream is established. mediaType will have a value of "audiovideo" or "datachannel" - * @param {Function} callFailureCB (errorCode, errMessage) - is called if there was a system error interfering with the call. - * @param {Function} wasAcceptedCB (wasAccepted:boolean,otherUser:string) - is called when a call is accepted or rejected by another party. It can be left null. - * @param {Array} streamNames - optional array of streamNames. - * @example - * easyrtc.call( otherEasyrtcid, - * function(easyrtcid, mediaType){ - * console.log("Got mediaType " + mediaType + " from " + easyrtc.idToName(easyrtcid)); - * }, - * function(errorCode, errMessage){ - * console.log("call to " + easyrtc.idToName(otherEasyrtcid) + " failed:" + errMessage); - * }, - * function(wasAccepted, easyrtcid){ - * if( wasAccepted ){ - * console.log("call accepted by " + easyrtc.idToName(easyrtcid)); - * } - * else{ - * console.log("call rejected" + easyrtc.idToName(easyrtcid)); - * } - * }); - */ - this.call = function(otherUser, callSuccessCB, callFailureCB, wasAcceptedCB, streamNames) { - - if (streamNames) { - if (typeof streamNames === "string") { // accept a string argument if passed. - streamNames = [streamNames]; - } - else if (streamNames.length === undefined) { - easyrtc.showError(self.errCodes.DEVELOPER_ERR, "easyrtc.call passed bad streamNames"); - return; - } - } - - if (self.debugPrinter) { - self.debugPrinter("initiating peer to peer call to " + otherUser + - " audio=" + audioEnabled + - " video=" + videoEnabled + - " data=" + dataEnabled); - } - - if (!self.supportsPeerConnections()) { - callFailureCB(self.errCodes.CALL_ERR, self.getConstantString("noWebrtcSupport")); - return; - } - - var message; - // - // If we are sharing audio/video and we haven't allocated the local media stream yet, - // we'll do so, recalling ourself on success. - // - if (!streamNames && autoInitUserMedia) { - var stream = self.getLocalStream(); - if (!stream && (audioEnabled || videoEnabled)) { - self.initMediaSource(function() { - self.call(otherUser, callSuccessCB, callFailureCB, wasAcceptedCB); - }, callFailureCB); - return; - } - } - - if (!self.webSocket) { - message = "Attempt to make a call prior to connecting to service"; - if (self.debugPrinter) { - self.debugPrinter(message); - } - throw message; - } - - // - // If B calls A, and then A calls B before accepting, then A should treat the attempt to - // call B as a positive offer to B's offer. - // - if (offersPending[otherUser]) { - wasAcceptedCB(true); - doAnswer(otherUser, offersPending[otherUser], streamNames); - delete offersPending[otherUser]; - self.callCancelled(otherUser, false); - return; - } - - // do we already have a pending call? - if (typeof acceptancePending[otherUser] !== 'undefined') { - message = "Call already pending acceptance"; - if (self.debugPrinter) { - self.debugPrinter(message); - } - callFailureCB(self.errCodes.ALREADY_CONNECTED, message); - return; - } - - if (use_fresh_ice_each_peer) { - self.getFreshIceConfig(function(succeeded) { - if (succeeded) { - callBody(otherUser, callSuccessCB, callFailureCB, wasAcceptedCB, streamNames); - } - else { - callFailureCB(self.errCodes.CALL_ERR, "Attempt to get fresh ice configuration failed"); - } - }); - } - else { - callBody(otherUser, callSuccessCB, callFailureCB, wasAcceptedCB, streamNames); - } - }; - function callBody(otherUser, callSuccessCB, callFailureCB, wasAcceptedCB, streamNames) { - acceptancePending[otherUser] = true; - var pc = buildPeerConnection(otherUser, true, callFailureCB, streamNames); - if (!pc) { - message = "buildPeerConnection failed, call not completed"; - if (self.debugPrinter) { - self.debugPrinter(message); - } - throw message; - } - - peerConns[otherUser].callSuccessCB = callSuccessCB; - peerConns[otherUser].callFailureCB = callFailureCB; - peerConns[otherUser].wasAcceptedCB = wasAcceptedCB; - var peerConnObj = peerConns[otherUser]; - var setLocalAndSendMessage0 = function(sessionDescription) { - if (peerConnObj.cancelled) { - return; - } - var sendOffer = function() { - - sendSignalling(otherUser, "offer", sessionDescription, null, callFailureCB); - }; - if (sdpLocalFilter) { - sessionDescription.sdp = sdpLocalFilter(sessionDescription.sdp); - } - pc.setLocalDescription(sessionDescription, sendOffer, - function(errorText) { - callFailureCB(self.errCodes.CALL_ERR, errorText); - }); - }; - setTimeout(function() { - // - // if the call was cancelled, we don't want to continue getting the offer. - // we can tell the call was cancelled because there won't be a peerConn object - // for it. - // - if( !peerConns[otherUser]) { - return; - } - pc.createOffer(setLocalAndSendMessage0, function(errorObj) { - callFailureCB(self.errCodes.CALL_ERR, JSON.stringify(errorObj)); - }, - receivedMediaContraints); - }, 100); - } - ; - function hangupBody(otherUser) { - var i; - if (self.debugPrinter) { - self.debugPrinter("Hanging up on " + otherUser); - } - clearQueuedMessages(otherUser); - if (peerConns[otherUser]) { - if (peerConns[otherUser].pc) { - var remoteStreams = peerConns[otherUser].pc.getRemoteStreams(); - for (i = 0; i < remoteStreams.length; i++) { - if( !remoteStreams[i].ended ) { - emitOnStreamClosed(otherUser, remoteStreams[i]); - try { - remoteStreams[i].close(); - } catch (err) { - } - } - } - // - // todo: may need to add a few lines here for closing the data channels - // - try { - peerConns[otherUser].pc.close(); - } catch (err) { - } - } - - peerConns[otherUser].cancelled = true; - delete peerConns[otherUser]; - if (self.webSocket) { - sendSignalling(otherUser, "hangup", null, function() { - }, function(errorCode, errorText) { - if (self.debugPrinter) { - self.debugPrinter("hangup failed:" + errorText); - } - }); - } - if (acceptancePending[otherUser]) { - delete acceptancePending[otherUser]; - } - } - } - - /** - * Hang up on a particular user or all users. - * @param {String} otherUser - the easyrtcid of the person to hang up on. - * @example - * easyrtc.hangup(someEasyrtcid); - */ - this.hangup = function(otherUser) { - hangupBody(otherUser); - updateConfigurationInfo(); - }; - /** - * Hangs up on all current connections. - * @example - * easyrtc.hangupAll(); - */ - this.hangupAll = function() { - - var sawAConnection = false, - onHangupSuccess = function() { - }, - onHangupFailure = function(errorCode, errorText) { - if (self.debugPrinter) { - self.debugPrinter("hangup failed:" + errorText); - } - }; - for (var otherUser in peerConns) { - if (!peerConns.hasOwnProperty(otherUser)) { - continue; - } - sawAConnection = true; - hangupBody(otherUser); - } - - if (sawAConnection) { - updateConfigurationInfo(); - } - }; - /** Checks to see if data channels work between two peers. - * @param {String} otherUser - the other peer. - * @returns {Boolean} true if data channels work and are ready to be used - * between the two peers. - */ - this.doesDataChannelWork = function(otherUser) { - if (!peerConns[otherUser]) { - return false; - } - return !!peerConns[otherUser].dataChannelReady; - }; - /** - * Return the media stream shared by a particular peer. This is needed when you - * add a stream in the middle of a call. - * @param {String} easyrtcid the peer. - * @param {String} remotestreamName an optional argument supplying the streamName. - * @returns {Object} A mediaStream. - */ - this.getRemoteStream = function(easyrtcid, remotestreamName) { - if (!peerConns[easyrtcid]) { - self.showError(self.errCodes.DEVELOPER_ERR, "attempt to get stream of uncalled party"); - throw "Developer err: no such stream"; - } - else { - return peerConns[easyrtcid].getRemoteStreamByName(remotestreamName); - } - } - /** - * Assign a local streamName to a remote stream so that it can be forwarded to other callers. - * @param {String} easyrtcid the peer supplying the remote stream - * @param {String} remotestreamName the streamName supplied by the peer. - * @param {String} localstreamName streamName used when passing the stream to other peers. - * @example - * easyrtc.makeLocalStreamFromRemoteStream(sourcePeer, "default", "forwardedStream"); - * easyrtc.call(nextPeer, callSuccessCB, callFailureCB, wasAcceptedCB, ["forwardedStream"]); - */ - this.makeLocalStreamFromRemoteStream = function(easyrtcid, remotestreamName, localstreamName) { - if (!streamName) { - streamName = "default"; - } - var remoteStream; - if (peerConns[easyrtcid].pc) { - remoteStream = peerConns[easyrtcid].getRemoteStreamByName(remotestreamName); - if (remoteStream) { - registerLocalMediaStreamByName(remoteStream, localstreamName); - } - else { - throw "Developer err: no such stream"; - } - } - else { - throw "Developer err: no such peer "; - } - } - - /** - * Add a named local stream to a call. - * @param {String} easyrtcId The id of client receiving the stream. - * @param {String} streamName The name of the stream. - * @param {Function} receiptHandler is a function that gets called when the other side sends a message - * that the stream has been received. The receiptHandler gets called with an easyrtcid and a stream name. This - * argument is optional. - */ - this.addStreamToCall = function(easyrtcId, streamName, receiptHandler) { - if( !streamName) { - streamName = "default"; - } - var stream = getLocalMediaStreamByName(streamName); - if (!stream) { - console.log("attempt to add nonexistent stream " + streamName); - } - else if (!peerConns[easyrtcId] || !peerConns[easyrtcId].pc) { - console.log("Can't add stream before a call has started."); - } - else { - var pc = peerConns[easyrtcId].pc; - peerConns[easyrtcId].enableNegotiateListener = true; - pc.addStream(stream); - if( receiptHandler ) { - peerConns[easyrtcId].streamsAddedAcks[streamName] = receiptHandler; - } - } - } - - // - // these three listeners support the ability to add/remove additional mediastreams on the fly. - // - this.setPeerListener(function(easyrtcid, msgType, msgData) { - if (!peerConns[easyrtcid] || !peerConns[easyrtcid].pc) { - easyrtc.showError(self.errCodes.DEVELOPER_ERR, - "Attempt to add additional stream before establishing the base call."); - } - else { - var sdp = msgData.sdp; - var pc = peerConns[easyrtcid].pc; - - var setLocalAndSendMessage1 = function(sessionDescription) { - var sendAnswer = function() { - if (self.debugPrinter) { - self.debugPrinter("sending answer"); - } - function onSignalSuccess() { - } - - function onSignalFailure(errorCode, errorText) { - delete peerConns[easyrtcid]; - self.showError(errorCode, errorText); - } - - sendSignalling(easyrtcid, "answer", sessionDescription, - onSignalSuccess, onSignalFailure); - peerConns[easyrtcid].connectionAccepted = true; - sendQueuedCandidates(easyrtcid, onSignalSuccess, onSignalFailure); - }; - - if (sdpLocalFilter) { - sessionDescription.sdp = sdpLocalFilter(sessionDescription.sdp); - } - pc.setLocalDescription(sessionDescription, sendAnswer, function(message) { - self.showError(self.errCodes.INTERNAL_ERR, "setLocalDescription: " + msgData); - }); - }; - - var invokeCreateAnswer = function() { - pc.createAnswer(setLocalAndSendMessage1, - function(message) { - self.showError(self.errCodes.INTERNAL_ERR, "create-answer: " + message); - }, - receivedMediaContraints); - self.sendPeerMessage(easyrtcid, "__gotAddedMediaStream", {sdp: sdp}); - }; - - if (self.debugPrinter) { - self.debugPrinter("about to call setRemoteDescription in doAnswer"); - } - try { - - if (sdpRemoteFilter) { - sdp.sdp = sdpRemoteFilter(sdp.sdp); - } - pc.setRemoteDescription(new RTCSessionDescription(sdp), - invokeCreateAnswer, function(message) { - self.showError(self.errCodes.INTERNAL_ERR, "set-remote-description: " + message); - }); - } catch (srdError) { - console.log("set remote description failed"); - if (self.debugPrinter) { - self.debugPrinter("saw exception in setRemoteDescription"); - } - self.showError(self.errCodes.INTERNAL_ERR, "setRemoteDescription failed: " + srdError.message); - } - } - }, "__addedMediaStream"); - this.setPeerListener(function(easyrtcid, msgType, msgData) { - if (!peerConns[easyrtcid] || !peerConns[easyrtcid].pc) { - } - else { - var sdp = msgData.sdp; - if (sdpRemoteFilter) { - sdp.sdp = sdpRemoteFilter(sdp.sdp); - } - var pc = peerConns[easyrtcid].pc; - pc.setRemoteDescription(new RTCSessionDescription(sdp), function(){}, - function(message) { - self.showError(self.errCodes.INTERNAL_ERR, "set-remote-description: " + message); - }); - } - - }, "__gotAddedMediaStream"); - this.setPeerListener(function(easyrtcid, msgType, msgData) { - if (!peerConns[easyrtcid] || !peerConns[easyrtcid].pc) { - } - else { - var stream = peerConns[easyrtcid].getRemoteStreamByName(msgData.streamName); - if (stream) { - onRemoveStreamHelper(easyrtcid, stream, msgData.streamName); - stream.ended = true; - } - } - - }, "__closingMediaStream"); - function onRemoveStreamHelper(easyrtcid, stream) { - if (peerConns[easyrtcid]) { - emitOnStreamClosed(easyrtcid, stream); - updateConfigurationInfo(); - if( peerConns[easyrtcid].pc ) { - try { - peerConns[easyrtcid].pc.removeStream(stream); - } catch( err) {} - } - - } - } - - - this.dumpPeerConnectionInfo = function() { - for (var peer in peerConns) { - console.log("For peer " + peer); - var pc = peerConns[peer].pc; - var remotes = pc.getRemoteStreams(); - var remoteIds = []; - for (var i = 0; i < remotes.length; i++) { - remoteIds.push(remotes[i].id); - } - var locals = pc.getLocalStreams(); - var localIds = []; - for (var i = 0; i < locals.length; i++) { - localIds.push(locals[i].id); - } - console.log(" " + JSON.stringify({local: localIds, remote: remoteIds})); - } - } - - - var buildPeerConnection = function(otherUser, isInitiator, failureCB, streamNames) { - var pc; - var message; - var newPeerConn; - var iceConfig = pc_config_to_use ? pc_config_to_use : pc_config; - if (self.debugPrinter) { - self.debugPrinter("building peer connection to " + otherUser); - } - - // - // we don't support data channels on chrome versions < 31 - // - try { - pc = self.createRTCPeerConnection(iceConfig, buildPeerConstraints()); - if (!pc) { - message = "Unable to create PeerConnection object, check your ice configuration(" + - JSON.stringify(ice_config) + ")"; - if (self.debugPrinter) { - self.debugPrinter(message); - } - throw(message); - } - - // - // turn off data channel support if the browser doesn't support it. - // - if (dataEnabled && typeof pc.createDataChannel === 'undefined') { - dataEnabled = false; - } - pc.onnegotiationneeded = function(event) { - if( peerConns[otherUser].enableNegotiateListener ) { - pc.createOffer(function(sdp) { - if (sdpLocalFilter) { - sdp.sdp = sdpLocalFilter(sdp.sdp); - } - pc.setLocalDescription(sdp, function() { - self.sendPeerMessage(otherUser, "__addedMediaStream", {sdp: sdp}); - }, function() { - }); - }, function(errorObj) { - console.log("unexpected error in creating offer"); - }); - } - } - - pc.onconnection = function() { - if (self.debugPrinter) { - self.debugPrinter("onconnection called prematurely"); - } - }; - newPeerConn = { - pc: pc, - candidatesToSend: [], - startedAV: false, - connectionAccepted: false, - isInitiator: isInitiator, - remoteStreamIdToName: {}, - streamsAddedAcks: {}, - liveRemoteStreams: {}, - getRemoteStreamByName: function(streamName) { - var remoteStreams = pc.getRemoteStreams(); - var i = 0; - var keyToMatch = null; - var roomName; - if (!streamName) { - streamName = "default"; - } - - if (streamName === "default") { - if (remoteStreams.length > 0) { - return remoteStreams[0]; - } - else { - return null; - } - } - for (roomName in self.roomData) { - var mediaIds = self.getRoomApiField(roomName, otherUser, "mediaIds"); - keyToMatch = mediaIds ? mediaIds[streamName] : null; - if (keyToMatch) { - break; - } - } - if (!keyToMatch) { - self.showError(self.errCodes.DEVELOPER_ERR, "remote peer does not have media stream called " + streamName); - } - - for (i = 0; i < remoteStreams.length; i++) { - var remoteId; - if (remoteStreams[i].hasOwnProperty("id")) { - remoteId = remoteStreams[i].id; - } - else { - remoteId = "default"; - } - - if (!keyToMatch || remoteId === keyToMatch) { - return remoteStreams[i]; - } - - } - return null; - } - // var remoteStreams = peerConns[i].pc.getRemoteStreams(); - }; - pc.onicecandidate = function(event) { - if (newPeerConn.cancelled) { - return; - } - var candidateData; - if (event.candidate && peerConns[otherUser]) { - candidateData = { - type: 'candidate', - label: event.candidate.sdpMLineIndex, - id: event.candidate.sdpMid, - candidate: event.candidate.candidate - }; - - if( iceCandidateFilter ) { - candidateData = iceCandidateFilter(candidateData, false); - if( !candidateData ) { - return; - } - } - // - // some candidates include ip addresses of turn servers. we'll want those - // later so we can see if our actual connection uses a turn server. - // The keyword "relay" in the candidate identifies it as referencing a - // turn server. The \d symbol in the regular expression matches a number. - // - if (event.candidate.candidate.indexOf("typ relay") > 0) { - var ipAddress = event.candidate.candidate.match(/(udp|tcp) \d+ (\d+\.\d+\.\d+\.\d+)/i)[2]; - self._turnServers[ipAddress] = true; - } - - if (peerConns[otherUser].connectionAccepted) { - sendSignalling(otherUser, "candidate", candidateData, null, function() { - failureCB(self.errCodes.PEER_GONE, "Candidate disappeared"); - }); - } - else { - peerConns[otherUser].candidatesToSend.push(candidateData); - } - } - }; - pc.onaddstream = function(event) { - if (self.debugPrinter) { - self.debugPrinter("saw incoming media stream"); - } - if (newPeerConn.cancelled) - return; - if (!peerConns[otherUser].startedAV) { - peerConns[otherUser].startedAV = true; - peerConns[otherUser].sharingAudio = haveAudioVideo.audio; - peerConns[otherUser].sharingVideo = haveAudioVideo.video; - peerConns[otherUser].connectTime = new Date().getTime(); - if (peerConns[otherUser].callSuccessCB) { - if (peerConns[otherUser].sharingAudio || peerConns[otherUser].sharingVideo) { - peerConns[otherUser].callSuccessCB(otherUser, "audiovideo"); - } - } - if (audioEnabled || videoEnabled) { - updateConfiguration(); - } - } - var remoteName = getNameOfRemoteStream(otherUser, event.stream.id || "default"); - if (!remoteName) { - remoteName = "default"; - } - peerConns[otherUser].remoteStreamIdToName[event.stream.id || "default"] = remoteName; - peerConns[otherUser].liveRemoteStreams[remoteName] = true; - event.stream.streamName = remoteName; - if (self.streamAcceptor) { - self.streamAcceptor(otherUser, event.stream, remoteName); - // - // Inform the other user that the stream they provided has been received. - // This should be moved into signalling at some point - // - self.sendDataWS(otherUser, "easyrtc_streamReceived", {streamName:remoteName},function(){}); - } - }; - pc.onremovestream = function(event) { - if (self.debugPrinter) { - self.debugPrinter("saw remove on remote media stream"); - } - onRemoveStreamHelper(otherUser, event.stream, event.stream.id || "default"); - }; - peerConns[otherUser] = newPeerConn; - } catch (e) { - if (self.debugPrinter) { - self.debugPrinter(JSON.stringify(e)); - } - failureCB(self.errCodes.SYSTEM_ERR, e.message); - return null; - } - - var i, stream; - if (streamNames) { - for (i = 0; i < streamNames.length; i++) { - stream = getLocalMediaStreamByName(streamNames[i]); - if (stream) { - pc.addStream(stream); - } - else { - console.log("Developer error, attempt to access unknown local media stream " + streamNames[i]); - } - } - } - else if (autoInitUserMedia && (videoEnabled || audioEnabled)) { - stream = self.getLocalStream(); - pc.addStream(stream); - } - - // - // This function handles data channel message events. - // - function dataChannelMessageHandler(event) { - if (self.debugPrinter) { - self.debugPrinter("saw dataChannel.onmessage event: " + JSON.stringify(event.data)); - } - - if (event.data === "dataChannelPrimed") { - self.sendDataWS(otherUser, "dataChannelPrimed", ""); - } - else { - // - // Chrome and Firefox Interop is passing a event with a strange data="", perhaps - // as it's own form of priming message. Comparing the data against "" doesn't - // work, so I'm going with parsing and trapping the parse error. - // - try { - var msg = JSON.parse(event.data); - if (msg) { - self.receivePeerDistribute(otherUser, msg, null); - } - } - catch (err) { - } - } - } - - function initOutGoingChannel(otherUser) { - if (self.debugPrinter) { - self.debugPrinter("saw initOutgoingChannel call"); - } - var dataChannel = pc.createDataChannel(dataChannelName, self.getDatachannelConstraints()); - peerConns[otherUser].dataChannelS = dataChannel; - peerConns[otherUser].dataChannelR = dataChannel; - dataChannel.onmessage = dataChannelMessageHandler; - dataChannel.onopen = function(event) { - if (self.debugPrinter) { - self.debugPrinter("saw dataChannel.onopen event"); - } - if (peerConns[otherUser]) { - dataChannel.send("dataChannelPrimed"); - } - }; - dataChannel.onclose = function(event) { - if (self.debugPrinter) { - self.debugPrinter("saw dataChannelS.onclose event"); - } - if (peerConns[otherUser]) { - peerConns[otherUser].dataChannelReady = false; - delete peerConns[otherUser].dataChannelS; - } - if (onDataChannelClose) { - onDataChannelClose(otherUser); - } - - updateConfigurationInfo(); - }; - } - - function initIncomingChannel(otherUser) { - if (self.debugPrinter) { - self.debugPrinter("initializing incoming channel handler for " + otherUser); - } - - peerConns[otherUser].pc.ondatachannel = function(event) { - - if (self.debugPrinter) { - self.debugPrinter("saw incoming data channel"); - } - - var dataChannel = event.channel; - peerConns[otherUser].dataChannelR = dataChannel; - peerConns[otherUser].dataChannelS = dataChannel; - peerConns[otherUser].dataChannelReady = true; - dataChannel.onmessage = dataChannelMessageHandler; - dataChannel.onclose = function(event) { - if (self.debugPrinter) { - self.debugPrinter("saw dataChannelR.onclose event"); - } - if (peerConns[otherUser]) { - peerConns[otherUser].dataChannelReady = false; - delete peerConns[otherUser].dataChannelR; - } - if (onDataChannelClose) { - onDataChannelClose(otherUser); - } - - updateConfigurationInfo(); - }; - dataChannel.onopen = function(event) { - if (self.debugPrinter) { - self.debugPrinter("saw dataChannel.onopen event"); - } - if (peerConns[otherUser]) { - dataChannel.send("dataChannelPrimed"); - } - }; - }; - } - - // - // added for interoperability - // - var doDataChannels = dataEnabled; - if (doDataChannels) { - - // check if both sides have the same browser and versions - } - - if (doDataChannels) { - self.setPeerListener(function() { - peerConns[otherUser].dataChannelReady = true; - if (peerConns[otherUser].callSuccessCB) { - peerConns[otherUser].callSuccessCB(otherUser, "datachannel"); - } - if (onDataChannelOpen) { - onDataChannelOpen(otherUser, true); - } - updateConfigurationInfo(); - }, "dataChannelPrimed", otherUser); - if (isInitiator) { - try { - - initOutGoingChannel(otherUser); - } catch (channelErrorEvent) { - console.log("failed to init outgoing channel"); - failureCB(self.errCodes.SYSTEM_ERR, - self.formatError(channelErrorEvent)); - } - } - if (!isInitiator) { - initIncomingChannel(otherUser); - } - } - - pc.onconnection = function() { - if (self.debugPrinter) { - self.debugPrinter("setup pc.onconnection "); - } - }; - - // - // Temporary support for responding to acknowledgements of about streams being added. - // - self.setPeerListener(function(easyrtcid, msgType, msgData, targeting){ - if( newPeerConn.streamsAddedAcks[msgData.streamName]) { - (newPeerConn.streamsAddedAcks[msgData.streamName])(easyrtcid, msgData.streamName); - delete newPeerConn.streamsAddedAcks[msgData.streamName]; - } - }, "easyrtc_streamReceived", otherUser); - return pc; - }; - var doAnswer = function(caller, msgData, streamNames) { - if (!streamNames && autoInitUserMedia) { - var localStream = self.getLocalStream(); - if (!localStream && (videoEnabled || audioEnabled)) { - self.initMediaSource( - function() { - doAnswer(caller, msgData); - }, - function(errorCode, errorObj) { - self.showError(self.errCodes.MEDIA_ERR, self.format(self.getConstantString("localMediaError"))); - }); - return; - } - } - if (use_fresh_ice_each_peer) { - self.getFreshIceConfig(function(succeeded) { - if (succeeded) { - doAnswerBody(caller, msgData, streamNames); - } - else { - self.showError(self.errCodes.CALL_ERR, "Failed to get fresh ice config"); - } - }); - } - else { - doAnswerBody(caller, msgData, streamNames); - } - } - - - var doAnswerBody = function(caller, msgData, streamNames) { - var pc = buildPeerConnection(caller, false, function(message) { - self.showError(self.errCodes.SYSTEM_ERR, message); - }, streamNames); - var newPeerConn = peerConns[caller]; - if (!pc) { - if (self.debugPrinter) { - self.debugPrinter("buildPeerConnection failed. Call not answered"); - } - return; - } - var setLocalAndSendMessage1 = function(sessionDescription) { - if (newPeerConn.cancelled) - return; - var sendAnswer = function() { - if (self.debugPrinter) { - self.debugPrinter("sending answer"); - } - function onSignalSuccess() { - } - - function onSignalFailure(errorCode, errorText) { - delete peerConns[caller]; - self.showError(errorCode, errorText); - } - - sendSignalling(caller, "answer", sessionDescription, - onSignalSuccess, onSignalFailure); - peerConns[caller].connectionAccepted = true; - sendQueuedCandidates(caller, onSignalSuccess, onSignalFailure); - if (pc.connectDataConnection) { - if (self.debugPrinter) { - self.debugPrinter("calling connectDataConnection(5002,5001)"); - } - pc.connectDataConnection(5002, 5001); - } - }; - if (sdpLocalFilter) { - sessionDescription.sdp = sdpLocalFilter(sessionDescription.sdp); - } - pc.setLocalDescription(sessionDescription, sendAnswer, function(message) { - self.showError(self.errCodes.INTERNAL_ERR, "setLocalDescription: " + message); - }); - }; - var sd = null; - if (window.mozRTCSessionDescription) { - sd = new mozRTCSessionDescription(msgData); - } - else { - sd = new RTCSessionDescription(msgData); - } - if (self.debugPrinter) { - self.debugPrinter("sdp || " + JSON.stringify(sd)); - } - var invokeCreateAnswer = function() { - if (newPeerConn.cancelled) - return; - pc.createAnswer(setLocalAndSendMessage1, - function(message) { - self.showError(self.errCodes.INTERNAL_ERR, "create-answer: " + message); - }, - receivedMediaContraints); - }; - if (self.debugPrinter) { - self.debugPrinter("about to call setRemoteDescription in doAnswer"); - } - try { - - if (sdpRemoteFilter) { - sd.sdp = sdpRemoteFilter(sd.sdp); - } - pc.setRemoteDescription(sd, invokeCreateAnswer, function(message) { - self.showError(self.errCodes.INTERNAL_ERR, "set-remote-description: " + message); - }); - } catch (srdError) { - console.log("set remote description failed"); - if (self.debugPrinter) { - self.debugPrinter("saw exception in setRemoteDescription"); - } - self.showError(self.errCodes.INTERNAL_ERR, "setRemoteDescription failed: " + srdError.message); - } - }; - // - // This function calls the users onStreamClosed handler, passing it the easyrtcid of the peer, the stream itself, - // and the name of the stream. - // - function emitOnStreamClosed(easyrtcid, stream) { - if (!peerConns[easyrtcid]) { - return; - } - var streamName; - var id; - if (stream.hasOwnProperty("id")) { - id = stream.id; - } - else { - id = "default"; - } - streamName = peerConns[easyrtcid].remoteStreamIdToName[id] || "default"; - if (peerConns[easyrtcid].liveRemoteStreams[streamName] && - self.onStreamClosed) { - delete peerConns[easyrtcid].liveRemoteStreams[streamName]; - self.onStreamClosed(easyrtcid, stream, streamName); - } - delete peerConns[easyrtcid].remoteStreamIdToName[id]; - } - - var onRemoteHangup = function(caller) { - delete offersPending[caller]; - if (self.debugPrinter) { - self.debugPrinter("Saw onRemote hangup event"); - } - if (peerConns[caller]) { - peerConns[caller].cancelled = true; - if (peerConns[caller].pc) { - // - // close any remote streams. - // - var remoteStreams = peerConns[caller].pc.getRemoteStreams(); - if (remoteStreams) { - var i; - for (i = 0; i < remoteStreams.length; i++) { - emitOnStreamClosed(caller, remoteStreams[i]); - try { - remoteStreams[i].stop(); - } catch (err) { - } - ; - } - } - - try { - peerConns[caller].pc.close(); - } catch (anyErrors) { - } - } - else { - if (self.callCancelled) { - self.callCancelled(caller, true); - } - } - delete peerConns[caller]; - updateConfigurationInfo(); - } - else { - if (self.callCancelled) { - self.callCancelled(caller, true); - } - } - }; - var queuedMessages = {}; - var clearQueuedMessages = function(caller) { - queuedMessages[caller] = { - candidates: [] - }; - }; - // - // checks to see if a particular peer is in any room at all. - // - function isPeerInAnyRoom(id) { - var roomName; - for (roomName in lastLoggedInList) { - if (!lastLoggedInList.hasOwnProperty(roomName)) { - continue; - } - if (lastLoggedInList[roomName][id]) { - return true; - } - } - return false; - } - - /** - * Checks to see if a particular peer is present in any room. - * If it isn't, we assume it's logged out. - * @param easyrtcid the easyrtcId of the peer. - */ - this.isPeerInAnyRoom = function(easyrtcId) { - return isPeerInAnyRoom(easyrtcId); - } - - // - // - // - function processLostPeers(peersInRoom) { - var id; - // - // check to see the person is still in at least one room. If not, we'll hangup - // on them. This isn't the correct behavior, but it's the best we can do without - // changes to the server. - // - for (id in peerConns) { - if (peerConns.hasOwnProperty(id) && - typeof peersInRoom[id] === 'undefined') { - if (!isPeerInAnyRoom(id)) { - if (peerConns[id].pc || peerConns[id].isInitiator) { - onRemoteHangup(id); - } - delete offersPending[id]; - delete acceptancePending[id]; - clearQueuedMessages(id); - } - } - } - - for (id in offersPending) { - if (offersPending.hasOwnProperty(id) && !isPeerInAnyRoom(id)) { - onRemoteHangup(id); - clearQueuedMessages(id); - delete offersPending[id]; - delete acceptancePending[id]; - } - } - - for (id in acceptancePending) { - if (acceptancePending.hasOwnProperty(id) && !isPeerInAnyRoom(id)) { - onRemoteHangup(id); - clearQueuedMessages(id); - delete acceptancePending[id]; - } - } - - } - - /** - * The idea of aggregating timers is that there are events that convey state and these can fire more frequently - * than desired. Aggregating timers allow a bunch of events to be collapsed into one by only firing the last - * event. - * @private - */ - var aggregatingTimers = {}; - - /** - * This function sets a timeout for a function to be called with the feature that if another - * invocation comes along within a particular interval (with the same key), the second invocation - * replaces the first. To prevent a continuous stream of events from preventing a callback from ever - * firing, we'll collapse no more than 20 events. - * @param {String} key A key used to identify callbacks that should be aggregated. - * @param {Function} callback The callback to invoke. - * @param {Number} period The aggregating period in milliseconds. - * @private - */ - function addAggregatingTimer(key, callback, period) { - if( !period) { - period = 100; // 0.1 second - } - var counter = 0; - if( aggregatingTimers[key]) { - clearTimeout(aggregatingTimers[key].timer); - counter = aggregatingTimers[key].counter; - } - if( counter > 20) { - delete aggregatingTimers[key]; - callback(); - } - else { - aggregatingTimers[key] = {counter: counter +1}; - aggregatingTimers[key].timer = setTimeout(function () { - delete aggregatingTimers[key]; - callback(); - }, period); - } - } - - // - // this function gets called for each room when there is a room update. - // - function processOccupantList(roomName, occupantList) { - var myInfo = null; - self.reducedList = {}; - var id; - for (id in occupantList) { - if (occupantList.hasOwnProperty(id)) { - if (id === self.myEasyrtcid) { - myInfo = occupantList[id]; - } - else { - self.reducedList[id] = occupantList[id]; - } - } - } - // - // processLostPeers detects peers that have gone away and performs - // house keeping accordingly. - // - processLostPeers(self.reducedList); - // - // - // - addAggregatingTimer("roomOccupants&" + roomName, function(){ - if (roomOccupantListener) { - roomOccupantListener(roomName, self.reducedList, myInfo); - } - self.emitEvent("roomOccupants", {roomName:roomName, occupants:lastLoggedInList}); - }, 100); - - } - - function sendQueuedCandidates(peer, onSignalSuccess, onSignalFailure) { - var i; - for (i = 0; i < peerConns[peer].candidatesToSend.length; i++) { - sendSignalling( - peer, - "candidate", - peerConns[peer].candidatesToSend[i], - onSignalSuccess, - onSignalFailure - ); - } - } - - var onChannelMsg = function(msg, ackAcceptorFunc) { - - var targeting = {}; - if (ackAcceptorFunc) { - ackAcceptorFunc(self.ackMessage); - } - if (msg.targetEasyrtcid) { - targeting.targetEasyrtcid = msg.targetEasyrtcid; - } - if (msg.targetRoom) { - targeting.targetRoom = msg.targetRoom; - } - if (msg.targetGroup) { - targeting.targetGroup = msg.targetGroup; - } - if (msg.senderEasyrtcid) { - self.receivePeerDistribute(msg.senderEasyrtcid, msg, targeting); - } - else { - if (receiveServerCB) { - receiveServerCB(msg.msgType, msg.msgData, targeting); - } - else { - console.log("Unhandled server message " + JSON.stringify(msg)); - } - } - }; - var onChannelCmd = function(msg, ackAcceptorFn) { - - var caller = msg.senderEasyrtcid; - var msgType = msg.msgType; - var msgData = msg.msgData; - var pc; - if (self.debugPrinter) { - self.debugPrinter('received message of type ' + msgType); - } - - if (typeof queuedMessages[caller] === "undefined") { - clearQueuedMessages(caller); - } - - var processCandidateBody = function(caller, msgData) { - var candidate = null; - - if( iceCandidateFilter ) { - msgData = iceCandidateFilter(msgData, true); - if( !msgData ) { - return; - } - } - - if (window.mozRTCIceCandidate) { - candidate = new mozRTCIceCandidate({ - sdpMLineIndex: msgData.label, - candidate: msgData.candidate - }); - } - else { - candidate = new RTCIceCandidate({ - sdpMLineIndex: msgData.label, - candidate: msgData.candidate - }); - } - pc = peerConns[caller].pc; - - function iceAddSuccess() {} - function iceAddFailure(domError) { - easyrtc.showError(self.errCodes.ICECANDIDATE_ERR, "bad ice candidate (" + domError.name + "): " + - JSON.stringify(candidate)); - } - pc.addIceCandidate(candidate, iceAddSuccess, iceAddFailure); - - if (msgData.candidate.indexOf("typ relay") > 0) { - var ipAddress = msgData.candidate.match(/(udp|tcp) \d+ (\d+\.\d+\.\d+\.\d+)/i)[1]; - self._turnServers[ipAddress] = true; - } - }; - var flushCachedCandidates = function(caller) { - var i; - if (queuedMessages[caller]) { - for (i = 0; i < queuedMessages[caller].candidates.length; i++) { - processCandidateBody(caller, queuedMessages[caller].candidates[i]); - } - delete queuedMessages[caller]; - } - }; - var processOffer = function(caller, msgData) { - - var helper = function(wasAccepted, streamNames) { - - if (streamNames) { - if (typeof streamNames === "string") { - streamNames = [streamNames]; - } - else if (streamNames.length === undefined) { - easyrtc.showError(self.errCodes.DEVELOPER_ERR, "accept callback passed invalid streamNames"); - return; - } - } - if (self.debugPrinter) { - self.debugPrinter("offer accept=" + wasAccepted); - } - delete offersPending[caller]; - if (!self.supportsPeerConnections()) { - callFailureCB(self.errCodes.CALL_ERR, self.getConstantString("noWebrtcSupport")); - return; - } - - if (wasAccepted) { - doAnswer(caller, msgData, streamNames); - flushCachedCandidates(caller); - } - else { - sendSignalling(caller, "reject", null, null, null); - clearQueuedMessages(caller); - } - }; - // - // There is a very rare case of two callers sending each other offers - // before receiving the others offer. In such a case, the caller with the - // greater valued easyrtcid will delete its pending call information and do a - // simple answer to the other caller's offer. - // - if (acceptancePending[caller] && caller < self.myEasyrtcid) { - delete acceptancePending[caller]; - if (queuedMessages[caller]) { - delete queuedMessages[caller]; - } - if (peerConns[caller].wasAcceptedCB) { - peerConns[caller].wasAcceptedCB(true, caller); - } - delete peerConns[caller]; - helper(true); - return; - } - - offersPending[caller] = msgData; - if (!self.acceptCheck) { - helper(true); - } - else { - self.acceptCheck(caller, helper); - } - }; - function processReject(caller) { - delete acceptancePending[caller]; - if (queuedMessages[caller]) { - delete queuedMessages[caller]; - } - if (peerConns[caller]) { - if (peerConns[caller].wasAcceptedCB) { - peerConns[caller].wasAcceptedCB(false, caller); - } - delete peerConns[caller]; - } - } - - function processAnswer(caller, msgData) { - - - - delete acceptancePending[caller]; - - // - // if we've discarded the peer connection, ignore the answer. - // - if (!peerConns[caller]) { - return; - } - peerConns[caller].connectionAccepted = true; - - - - if (peerConns[caller].wasAcceptedCB) { - peerConns[caller].wasAcceptedCB(true, caller); - } - - var onSignalSuccess = function() { - - }; - var onSignalFailure = function(errorCode, errorText) { - if (peerConns[caller]) { - delete peerConns[caller]; - } - self.showError(errorCode, errorText); - }; - var i; - // peerConns[caller].startedAV = true; - sendQueuedCandidates(caller, onSignalSuccess, onSignalFailure); - pc = peerConns[caller].pc; - var sd = null; - if (window.mozRTCSessionDescription) { - sd = new mozRTCSessionDescription(msgData); - } - else { - sd = new RTCSessionDescription(msgData); - } - if (!sd) { - throw "Could not create the RTCSessionDescription"; - } - - if (self.debugPrinter) { - self.debugPrinter("about to call initiating setRemoteDescription"); - } - try { - if (sdpRemoteFilter) { - sd.sdp = sdpRemoteFilter(sd.sdp); - } - pc.setRemoteDescription(sd, function() { - if (pc.connectDataConnection) { - if (self.debugPrinter) { - self.debugPrinter("calling connectDataConnection(5001,5002)"); - } - pc.connectDataConnection(5001, 5002); // these are like ids for data channels - } - }, function(message){ - console.log("setRemoteDescription failed ", message); - }); - } catch (smdException) { - console.log("setRemoteDescription failed ", smdException); - } - flushCachedCandidates(caller); - } - - function processCandidateQueue(caller, msgData) { - - if (peerConns[caller] && peerConns[caller].pc) { - processCandidateBody(caller, msgData); - } - else { - if (!peerConns[caller]) { - queuedMessages[caller] = { - candidates: [] - }; - } - queuedMessages[caller].candidates.push(msgData); - } - } - - switch (msgType) { - case "sessionData": - processSessionData(msgData.sessionData); - break; - case "roomData": - processRoomData(msgData.roomData); - break; - case "iceConfig": - processIceConfig(msgData.iceConfig); - break; - case "forwardToUrl": - if (msgData.newWindow) { - window.open(msgData.forwardToUrl.url); - } - else { - window.location.href = msgData.forwardToUrl.url; - } - break; - case "offer": - processOffer(caller, msgData); - break; - case "reject": - processReject(caller); - break; - case "answer": - processAnswer(caller, msgData); - break; - case "candidate": - processCandidateQueue(caller, msgData); - break; - case "hangup": - onRemoteHangup(caller); - clearQueuedMessages(caller); - break; - case "error": - self.showError(msg.errorCode, msg.errorText); - break; - default: - console.error("received unknown message type from server, msgType is " + msgType); - return; - } - - if (ackAcceptorFn) { - ackAcceptorFn(self.ackMessage); - } - }; - function connectToWSServer(successCallback, errorCallback) { - var i; - if (preallocatedSocketIo) { - self.webSocket = preallocatedSocketIo; - } - else if (!self.webSocket) { - try { - self.webSocket = io.connect(serverPath, connectionOptions); - } catch(socketErr) { - errorCallback( self.errCodes.SYSTEM_ERROR, - socketError.toString()); - return; - } - if (!self.webSocket) { - throw "io.connect failed"; - } - } - else { - for (i in self.websocketListeners) { - if (!self.websocketListeners.hasOwnProperty(i)) { - continue; - } - self.webSocket.removeEventListener(self.websocketListeners[i].event, - self.websocketListeners[i].handler); - } - } - self.websocketListeners = []; - function addSocketListener(event, handler) { - self.webSocket.on(event, handler); - self.websocketListeners.push({event: event, handler: handler}); - } - - addSocketListener("close", function(event) { - console.log("the web socket closed"); - }); - addSocketListener('error', function(event) { - function handleErrorEvent() { - if (self.myEasyrtcid) { - // - // socket.io version 1 got rid of the socket member, moving everything up one level. - // - if (self.webSocket.connected || (self.webSocket.socket && self.webSocket.socket.connected)) { - self.showError(self.errCodes.SIGNAL_ERROR, self.getConstantString("miscSignalError")); - } - else { - /* socket server went down. this will generate a 'disconnect' event as well, so skip this event */ - errorCallback(self.errCodes.CONNECT_ERR, self.getConstantString("noServer")); - } - } - else { - errorCallback(self.errCodes.CONNECT_ERR, self.getConstantString("noServer")); - } - } - handleErrorEvent(); - }); - function connectHandler(event) { - self.webSocketConnected = true; - if (!self.webSocket) { - self.showError(self.errCodes.CONNECT_ERR, self.getConstantString("badsocket")); - } - - if (self.debugPrinter) { - self.debugPrinter("saw socketserver onconnect event"); - } - if (self.webSocketConnected) { - sendAuthenticate(successCallback, errorCallback); - } - else { - errorCallback(self.errCodes.SIGNAL_ERROR, self.getConstantString("icf")); - } - } - if (preallocatedSocketIo && preallocatedSocketIo.socket.connected) { - connectHandler(null); - } - else { - addSocketListener("connect", connectHandler); - } - addSocketListener("easyrtcMsg", onChannelMsg); - addSocketListener("easyrtcCmd", onChannelCmd); - addSocketListener("disconnect", function(/* code, reason, wasClean */) { - self.webSocketConnected = false; - updateConfigurationInfo = function() { - }; // dummy update function - oldConfig = {}; - disconnectBody(); - if (self.disconnectListener) { - self.disconnectListener(); - } - }); - } - - - function buildDeltaRecord(added, deleted, modified) { - function objectNotEmpty(obj) { - var i; - for (i in obj) { - if (obj.hasOwnProperty(i)) { - return true; - } - } - return false; - } - - var result = {}; - if (objectNotEmpty(added)) { - result.added = added; - } - - if (objectNotEmpty(deleted)) { - result.deleted = deleted; - } - - if (objectNotEmpty(result)) { - return result; - } - else { - return null; - } - } - - function findDeltas(oldVersion, newVersion) { - var i; - var added = {}, deleted = {}; - var subPart; - for (i in newVersion) { - if (!newVersion.hasOwnProperty(i)) { - // do nothing - } - else if (oldVersion === null || typeof oldVersion[i] === 'undefined') { - added[i] = newVersion[i]; - } - else if (typeof newVersion[i] === 'object') { - subPart = findDeltas(oldVersion[i], newVersion[i]); - if (subPart !== null) { - added[i] = newVersion[i]; - } - } - else if (newVersion[i] !== oldVersion[i]) { - added[i] = newVersion[i]; - } - } - for (i in oldVersion) { - if (!newVersion.hasOwnProperty(i)) { - // do nothing - } - else if (typeof newVersion[i] === 'undefined') { - deleted = oldVersion[i]; - } - } - - return buildDeltaRecord(added, deleted); - } - -// -// this function collects configuration info that will be sent to the server. -// It returns that information, leaving it the responsibility of the caller to -// do the actual sending. -// - function collectConfigurationInfo(/* forAuthentication */) { - var p2pList = {}; - var i; - for (i in peerConns) { - if (!peerConns.hasOwnProperty(i)) { - continue; - } - p2pList[i] = { - connectTime: peerConns[i].connectTime, - isInitiator: !!peerConns[i].isInitiator - }; - } - - var newConfig = { - userSettings: { - sharingAudio: !!haveAudioVideo.audio, - sharingVideo: !!haveAudioVideo.video, - sharingData: !!dataEnabled, - nativeVideoWidth: self.nativeVideoWidth, - nativeVideoHeight: self.nativeVideoHeight, - windowWidth: window.innerWidth, - windowHeight: window.innerHeight, - screenWidth: window.screen.width, - screenHeight: window.screen.height, - cookieEnabled: navigator.cookieEnabled, - os: navigator.oscpu, - language: navigator.language - } - }; - if (!isEmptyObj(p2pList)) { - newConfig.p2pList = p2pList; - } - return newConfig; - } - ; - function updateConfiguration() { - - var newConfig = collectConfigurationInfo(false); - // - // we need to give the getStats calls a chance to fish out the data. - // The longest I've seen it take is 5 milliseconds so 100 should be overkill. - // - var sendDeltas = function() { - var alteredData = findDeltas(oldConfig, newConfig); - // - // send all the configuration information that changes during the session - // - if (alteredData) { - if (self.debugPrinter) { - self.debugPrinter("cfg=" + JSON.stringify(alteredData.added)); - } - if (self.webSocket) { - sendSignalling(null, "setUserCfg", {setUserCfg: alteredData.added}, null, null); - } - } - oldConfig = newConfig; - }; - if (oldConfig === {}) { - sendDeltas(); - } - else { - setTimeout(sendDeltas, 100); - } - } - - updateConfigurationInfo = function() { - updateConfiguration(); - }; - /** - * Sets the presence state on the server. - * @param {String} state - one of 'away','chat','dnd','xa' - * @param {String} statusText - User configurable status string. May be length limited. - * @example easyrtc.updatePresence('dnd', 'sleeping'); - */ - this.updatePresence = function(state, statusText) { - self.presenceShow = state; - self.presenceStatus = statusText; - if (self.webSocketConnected) { - sendSignalling(null, 'setPresence', {setPresence: {'show': state, 'status': statusText}}, null); - } - }; - /** - * Fetch the collection of session fields as a map. The map has the structure: - * {key1: {"fieldName": key1, "fieldValue": value1}, ..., - * key2: {"fieldName": key2, "fieldValue": value2} - * } - * @returns {Object} - */ - this.getSessionFields = function() { - return sessionFields; - }; - /** - * Fetch the value of a session field by name. - * @param {String} name - name of the session field to be fetched. - * @returns the field value (which can be anything). Returns undefined if the field does not exist. - */ - this.getSessionField = function(name) { - if (sessionFields[name]) { - return sessionFields[name].fieldValue; - } - else { - return undefined; - } - }; - function processSessionData(sessionData) { - if (sessionData) { - if (sessionData.easyrtcsid) { - self.easyrtcsid = sessionData.easyrtcsid; - } - if (sessionData.field) { - sessionFields = sessionData.field; - } - } - } - - - function processRoomData(roomData) { - self.roomData = roomData; - var roomName; - var stuffToRemove; - var stuffToAdd; - var id, removeId; - for (roomName in self.roomData) { - if (!self.roomData.hasOwnProperty(roomName)) { - continue; - } - if (roomData[roomName].roomStatus === "join") { - if (!(self.roomJoin[roomName])) { - self.roomJoin[roomName] = roomData[roomName]; - } - var mediaIds = buildMediaIds(); - if (mediaIds !== {}) { - self.setRoomApiField(roomName, "mediaIds", mediaIds); - } - } - else if (roomData[roomName].roomStatus === "leave") { - if (self.roomEntryListener) { - self.roomEntryListener(false, roomName); - } - delete self.roomJoin[roomName]; - delete lastLoggedInList[roomName]; - continue; - } - - if (roomData[roomName].clientList) { - lastLoggedInList[roomName] = roomData[roomName].clientList; - } - else if (roomData[roomName].clientListDelta) { - stuffToAdd = roomData[roomName].clientListDelta.updateClient; - if (stuffToAdd) { - for (id in stuffToAdd) { - if (!stuffToAdd.hasOwnProperty(id)) { - continue; - } - if (!lastLoggedInList[roomName]) { - lastLoggedInList[roomName] = []; - } - lastLoggedInList[roomName][id] = stuffToAdd[id]; - } - } - stuffToRemove = roomData[roomName].clientListDelta.removeClient; - if (stuffToRemove && lastLoggedInList[roomName]) { - for (removeId in stuffToRemove) { - if (stuffToRemove.hasOwnProperty(removeId)) { - delete lastLoggedInList[roomName][removeId]; - } - } - } - } - if (self.roomJoin[roomName] && roomData[roomName].field) { - fields.rooms[roomName] = roomData[roomName].field; - } - if (roomData[roomName].roomStatus === "join") { - if (self.roomEntryListener) { - self.roomEntryListener(true, roomName); - } - } - processOccupantList(roomName, lastLoggedInList[roomName]); - } - self.emitEvent("roomOccupant", lastLoggedInList); - } - - /** - * Returns an array of easyrtcid's of peers in a particular room. - * @param roomName - * @returns {Array} of easyrtcids or null if the client is not in the room. - * @example - * var occupants = easyrtc.getRoomOccupants("default"); - * var i; - * for( i = 0; i < occupants.length; i++ ) { - * console.log( occupants[i] + " is in the room"); - * } - */ - this.getRoomOccupantsAsArray = function(roomName) { - if (!lastLoggedInList[roomName]) { - return null; - } - else { - return Object.keys(lastLoggedInList[roomName]); - } - } - - /** - * Returns a map of easyrtcid's of peers in a particular room. You should only test elements in the map to see if they are - * null; their actual values are not guaranteed to be the same in different releases. - * @param roomName - * @returns {Object} of easyrtcids or null if the client is not in the room. - * @example - * if( easyrtc.getRoomOccupantsAsMap("default")[some_easyrtcid]) { - * console.log("yep, " + some_easyrtcid + " is in the room"); - * } - */ - this.getRoomOccupantsAsMap = function(roomName) { - return lastLoggedInList[roomName]; - } - - /** - * Returns true if the ipAddress parameter was the address of a turn server. This is done by checking against information - * collected during peer to peer calls. Don't expect it to work before the first call, or to identify turn servers that aren't - * in the ice config. - * @param ipAddress - * @returns {boolean} true if ip address is known to be that of a turn server, false otherwise. - */ - this.isTurnServer = function(ipAddress) { - return !!self._turnServers[ipAddress]; - }; - function processIceConfig(iceConfig) { - pc_config = {iceServers: []}; - self._turnServers = {}; - var i; - var item, fixedItem, username, ipAddress; - if (!window.createIceServer) { - return; - } - for (i = 0; i < iceConfig.iceServers.length; i++) { - item = iceConfig.iceServers[i]; - if (item.url.indexOf('turn:') === 0) { - if (item.username) { - fixedItem = createIceServer(item.url, item.username, item.credential); - } - else { - self.showError("Developer error", "Iceserver entry doesn't have a username: " + JSON.stringify(item)); - } - ipAddress = item.url.split(/[@:&]/g)[1]; - self._turnServers[ipAddress] = true; - } - else { // is stun server entry - fixedItem = item; - } - if (fixedItem) { - pc_config.iceServers.push(fixedItem); - } - } - } - - /** - * Request fresh ice config information from the server. - * This should be done periodically by long running applications. - * @param {Function} callback is called with a value of true on success, false on failure. - */ - this.getFreshIceConfig = function(callback) { - var dataToShip = { - msgType: "getIceConfig", - msgData: {} - }; - if (!callback) { - callback = function() { - }; - } - self.webSocket.json.emit("easyrtcCmd", dataToShip, - function(ackMsg) { - if (ackMsg.msgType === "iceConfig") { - processIceConfig(ackMsg.msgData.iceConfig); - callback(true); - } - else { - self.showError(ackMsg.msgData.errorCode, ackMsg.msgData.errorText); - callback(false); - } - } - ); - }; - function processToken(msg) { - if (self.debugPrinter) { - self.debugPrinter("entered process token"); - } - var msgData = msg.msgData; - if (msgData.easyrtcid) { - self.myEasyrtcid = msgData.easyrtcid; - } - if (msgData.field) { - fields.connection = msgData.field; - } - if (msgData.iceConfig) { - processIceConfig(msgData.iceConfig); - } - - if (msgData.sessionData) { - processSessionData(msgData.sessionData); - } - - if (msgData.roomData) { - processRoomData(msgData.roomData); - } - - if (msgData.application.field) { - fields.application = msgData.application.field; - } - - } - - function sendAuthenticate(successCallback, errorCallback) { - // - // find our easyrtcsid - // - var cookies, target, i; - var easyrtcsid = null; - if (self.cookieId && document.cookie) { - cookies = document.cookie.split(/[; ]/g); - target = self.cookieId + "="; - for (i = 0; i < cookies.length; i++) { - if (cookies[i].indexOf(target) === 0) { - easyrtcsid = cookies[i].substring(target.length); - } - } - } - - if (!self.roomJoin) { - self.roomJoin = {}; - } - - var msgData = { - apiVersion: self.apiVersion, - applicationName: self.applicationName, - setUserCfg: collectConfigurationInfo(true) - }; - if (self.presenceShow) { - msgData.setPresence = {show: self.presenceShow, status: self.presenceStatus}; - } - if (self.username) { - msgData.username = self.username; - } - if (self.roomJoin && !isEmptyObj(self.roomJoin)) { - msgData.roomJoin = self.roomJoin; - } - if (easyrtcsid) { - msgData.easyrtcsid = easyrtcsid; - } - if (credential) { - msgData.credential = credential; - } - - self.webSocket.json.emit("easyrtcAuth", - {msgType: "authenticate", - msgData: msgData - }, - function(msg) { - var room; - if (msg.msgType === "error") { - errorCallback(msg.msgData.errorCode, msg.msgData.errorText); - self.roomJoin = {}; - } - else { - processToken(msg); - if (self._roomApiFields) { - for (room in self._roomApiFields) { - if (self._roomApiFields.hasOwnProperty(room)) { - _enqueueSendRoomApi(room, self._roomApiFields[room]); - } - } - } - - if (successCallback) { - successCallback(self.myEasyrtcid); - } - } - } - ); - } - - /** Get a list of the rooms you are in. You must be connected to call this function. - * @returns {Object} A map whose keys are the room names - */ - this.getRoomsJoined = function() { - var roomsIn = {}; - var key; - for (key in self.roomJoin) { - if (self.roomJoin.hasOwnProperty(key)) { - roomsIn[key] = true; - } - } - return roomsIn; - }; - /** Get server defined fields associated with a particular room. Only valid - * after a connection has been made. - * @param {String} roomName - the name of the room you want the fields for. - * @returns {Object} A dictionary containing entries of the form {key:{'fieldName':key, 'fieldValue':value1}} or undefined - * if you are not connected to the room. - */ - this.getRoomFields = function(roomName) { - if (!fields || !fields.rooms || !fields.rooms[roomName]) - return undefined; - return fields.rooms[roomName]; - }; - /** Get server defined fields associated with the current application. Only valid - * after a connection has been made. - * @returns {Object} A dictionary containing entries of the form {key:{'fieldName':key, 'fieldValue':value1}} - */ - this.getApplicationFields = function() { - return fields.application; - }; - /** Get server defined fields associated with the connection. Only valid - * after a connection has been made. - * @returns {Object} A dictionary containing entries of the form {key:{'fieldName':key, 'fieldValue':value1}} - */ - this.getConnectionFields = function() { - return fields.connection; - }; -// this flag controls whether the easyApp routine adds close buttons to the caller -// video objects - - /** @private */ - var autoAddCloseButtons = true; - /** By default, the easyApp routine sticks a "close" button on top of each caller - * video object that it manages. Call this function(before calling easyApp) to disable that particular feature. - * @example - * easyrtc.dontAddCloseButtons(); - */ - this.dontAddCloseButtons = function() { - autoAddCloseButtons = false; - }; - /** - * Validates that the video ids correspond to dom objects. - * @param {String} monitorVideoId - * @param {Array} videoIds - * @returns {Boolean} - * @private - */ - function _validateVideoIds(monitorVideoId, videoIds) { - var i; - // verify that video ids were not typos. - if (monitorVideoId && !document.getElementById(monitorVideoId)) { - self.showError(self.errCodes.DEVELOPER_ERR, "The monitor video id passed to easyApp was bad, saw " + monitorVideoId); - return false; - } - - for (i in videoIds) { - if (!videoIds.hasOwnProperty(i)) { - continue; - } - var name = videoIds[i]; - if (!document.getElementById(name)) { - self.showError(self.errCodes.DEVELOPER_ERR, "The caller video id '" + name + "' passed to easyApp was bad."); - return false; - } - } - return true; - } - ; - /** - * This is a helper function for the easyApp method. It manages the assignment of video streams - * to video objects. It assumes - * @param {String} monitorVideoId is the id of the mirror video tag. - * @param {Array} videoIds is an array of ids of the caller video tags. - * @private - */ - function easyAppBody(monitorVideoId, videoIds) { - var numPEOPLE = videoIds.length; - var videoIdsP = videoIds; - var refreshPane = 0; - var onCall = null, onHangup = null; - - if (!videoIdsP) { - videoIdsP = []; - } - - easyrtc.addEventListener("roomOccupants", - function(eventName, eventData) { - for (i = 0; i < numPEOPLE; i++) { - var video = getIthVideo(i); - if (!videoIsFree(video)) { - if( !easyrtc.isPeerInAnyRoom(video.dataset.caller)){ - if( onHangup ) { - onHangup(i, easyrtc.dataset.caller); - } - easyrtc.dataset.caller = null; - } - } - } - } - ); - - function videoIsFree(obj) { - return (obj.dataset.caller === "" || obj.dataset.caller === null || obj.dataset.caller === undefined); - } - - if (!_validateVideoIds(monitorVideoId, videoIdsP)) { - throw "bad video element id"; - } - - if (monitorVideoId) { - document.getElementById(monitorVideoId).muted = "muted"; - } - - /** Sets an event handler that gets called when an incoming MediaStream is assigned - * to a video object. The name is poorly chosen and reflects a simpler era when you could - * only have one media stream per peer connection. - * @param {Function} cb has the signature function(easyrtcid, slot){} - * @example - * easyrtc.setOnCall( function(easyrtcid, slot){ - * console.log("call with " + easyrtcid + "established"); - * }); - */ - self.setOnCall = function(cb) { - onCall = cb; - }; - /** Sets an event handler that gets called when a call is ended. - * it's only purpose (so far) is to support transitions on video elements. - x * this function is only defined after easyrtc.easyApp is called. - * The slot is parameter is the index into the array of video ids. - * Note: if you call easyrtc.getConnectionCount() from inside your callback - * it's count will reflect the number of connections before the hangup started. - * @param {Function} cb has the signature function(easyrtcid, slot){} - * @example - * easyrtc.setOnHangup( function(easyrtcid, slot){ - * console.log("call with " + easyrtcid + "ended"); - * }); - */ - self.setOnHangup = function(cb) { - onHangup = cb; - }; - - function getIthVideo(i) { - if (videoIdsP[i]) { - return document.getElementById(videoIdsP[i]); - } - else { - return null; - } - } - - - self.getIthCaller = function(i) { - if (i < 0 || i > videoIdsP.length) { - return null; - } - var vid = getIthVideo(i); - return vid.dataset.caller; - }; - - self.getSlotOfCaller = function(easyrtcid) { - var i; - for (i = 0; i < numPEOPLE; i++) { - if (self.getIthCaller(i) === easyrtcid) { - return i; - } - } - return -1; // caller not connected - }; - function hideVideo(video) { - self.setVideoObjectSrc(video, ""); - video.style.visibility = "hidden"; - } - - self.setOnStreamClosed(function(caller) { - var i; - for (i = 0; i < numPEOPLE; i++) { - var video = getIthVideo(i); - if (video.dataset.caller === caller) { - hideVideo(video); - video.dataset.caller = ""; - if (onHangup) { - onHangup(caller, i); - } - } - } - }); - // - // Only accept incoming calls if we have a free video object to display - // them in. - // - self.setAcceptChecker(function(caller, helper) { - var i; - for (i = 0; i < numPEOPLE; i++) { - var video = getIthVideo(i); - if (videoIsFree(video)) { - helper(true); - return; - } - } - helper(false); - }); - self.setStreamAcceptor(function(caller, stream) { - var i; - if (self.debugPrinter) { - self.debugPrinter("stream acceptor called"); - } - function showVideo(video, stream) { - self.setVideoObjectSrc(video, stream); - if (video.style.visibility) { - video.style.visibility = 'visible'; - } - } - - var video; - if (refreshPane && videoIsFree(refreshPane)) { - showVideo(refreshPane, stream); - if (onCall) { - onCall(caller, refreshPane); - } - refreshPane = null; - return; - } - for (i = 0; i < numPEOPLE; i++) { - video = getIthVideo(i); - if (video.dataset.caller === caller) { - showVideo(video, stream); - if (onCall) { - onCall(caller, i); - } - return; - } - } - - for (i = 0; i < numPEOPLE; i++) { - video = getIthVideo(i); - if (!video.dataset.caller || videoIsFree(video)) { - video.dataset.caller = caller; - if (onCall) { - onCall(caller, i); - } - showVideo(video, stream); - return; - } - } -// -// no empty slots, so drop whatever caller we have in the first slot and use that one. -// - video = getIthVideo(0); - if (video) { - self.hangup(video.dataset.caller); - showVideo(video, stream); - if (onCall) { - onCall(caller, 0); - } - } - video.dataset.caller = caller; - }); - (function() { - var addControls, parentDiv, closeButton, i; - if (autoAddCloseButtons) { - - addControls = function(video) { - parentDiv = video.parentNode; - video.dataset.caller = ""; - closeButton = document.createElement("div"); - closeButton.className = "easyrtc_closeButton"; - closeButton.onclick = function() { - if (video.dataset.caller) { - self.hangup(video.dataset.caller); - hideVideo(video); - video.dataset.caller = ""; - } - }; - parentDiv.appendChild(closeButton); - }; - for (i = 0; i < numPEOPLE; i++) { - addControls(getIthVideo(i)); - } - } - })(); - var monitorVideo = null; - if (videoEnabled && monitorVideoId !== null) { - monitorVideo = document.getElementById(monitorVideoId); - if (!monitorVideo) { - console.error("Programmer error: no object called " + monitorVideoId); - return; - } - monitorVideo.muted = "muted"; - monitorVideo.defaultMuted = true; - } - - - } - ; - /** - * Provides a layer on top of the easyrtc.initMediaSource and easyrtc.connect, assign the local media stream to - * the video object identified by monitorVideoId, assign remote video streams to - * the video objects identified by videoIds, and then call onReady. One of it's - * side effects is to add hangup buttons to the remote video objects, buttons - * that only appear when you hover over them with the mouse cursor. This method will also add the - * easyrtcMirror class to the monitor video object so that it behaves like a mirror. - * @param {String} applicationName - name of the application. - * @param {String} monitorVideoId - the id of the video object used for monitoring the local stream. - * @param {Array} videoIds - an array of video object ids (strings) - * @param {Function} onReady - a callback function used on success. It is called with the easyrtcId this peer is known to the server as. - * @param {Function} onFailure - a callback function used on failure (failed to get local media or a connection of the signaling server). - * @example - * easyrtc.easyApp('multiChat', 'selfVideo', ['remote1', 'remote2', 'remote3'], - * function(easyrtcId){ - * console.log("successfully connected, I am " + easyrtcId); - * }, - * function(errorCode, errorText){ - * console.log(errorText); - * ); - */ - this.easyApp = function(applicationName, monitorVideoId, videoIds, onReady, onFailure) { - var gotMediaCallback = null, - gotConnectionCallback = null; - easyAppBody(monitorVideoId, videoIds); - self.setGotMedia = function(gotMediaCB) { - gotMediaCallback = gotMediaCB; - }; - /** Sets an event handler that gets called when a connection to the signaling - * server has or has not been made. Can only be called after calling easyrtc.easyApp. - * @param {Function} gotConnectionCB has the signature (gotConnection, errorText) - * @example - * easyrtc.setGotConnection( function(gotConnection, errorText){ - * if( gotConnection ){ - * console.log("Successfully connected to signaling server"); - * } - * else{ - * console.log("Failed to connect to signaling server because: " + errorText); - * } - * }); - */ - self.setGotConnection = function(gotConnectionCB) { - gotConnectionCallback = gotConnectionCB; - }; - var nextInitializationStep; - nextInitializationStep = function(/* token */) { - if (gotConnectionCallback) { - gotConnectionCallback(true, ""); - } - onReady(self.myEasyrtcid); - }; - function postGetUserMedia() { - if (gotMediaCallback) { - gotMediaCallback(true, null); - } - if (monitorVideoId !== null) { - self.setVideoObjectSrc(document.getElementById(monitorVideoId), self.getLocalStream()); - } - function connectError(errorCode, errorText) { - if (gotConnectionCallback) { - gotConnectionCallback(false, errorText); - } - else if (onFailure) { - onFailure(self.errCodes.CONNECT_ERR, errorText); - } - else { - self.showError(self.errCodes.CONNECT_ERR, errorText); - } - } - - self.connect(applicationName, nextInitializationStep, connectError); - } - - var stream = getLocalMediaStreamByName(null); - if (stream) { - postGetUserMedia(); - } - else { - self.initMediaSource( - postGetUserMedia, - function(errorCode, errorText) { - if (gotMediaCallback) { - gotMediaCallback(false, errorText); - } - else if (onFailure) { - onFailure(self.errCodes.MEDIA_ERR, errorText); - } - else { - self.showError(self.errCodes.MEDIA_ERR, errorText); - } - }, - null // default stream - ); - } - }; - /** - * - * @deprecated now called easyrtc.easyApp. - */ - this.initManaged = this.easyApp; - var preallocatedSocketIo = null; - /** - * Supply a socket.io connection that will be used instead of allocating a new socket. - * The expected usage is that you allocate a websocket, assign options to it, call - * easyrtc.useThisSocketConnection, followed by easyrtc.connect or easyrtc.easyApp. Easyrtc will not attempt to - * close sockets that were supplied with easyrtc.useThisSocketConnection. - * @param {Object} alreadyAllocatedSocketIo A value allocated with the connect method of socket.io. - */ - this.useThisSocketConnection = function(alreadyAllocatedSocketIo) { - preallocatedSocketIo = alreadyAllocatedSocketIo; - } - /** - * Connect to the easyrtc signaling server. - * @param applicationName - * @param successCallback - * @param errorCallback - */ - this.connect = function(applicationName, successCallback, errorCallback) { - - if (!window.io) { - self.showError("Developer error", "Your HTML has not included the socket.io.js library"); - } - - if (!preallocatedSocketIo && self.webSocket) { - console.error("Developer error: attempt to connect when already connected to socket server"); - return; - } - pc_config = {}; - closedChannel = null; - oldConfig = {}; // used internally by updateConfiguration - queuedMessages = {}; - self.applicationName = applicationName; - fields = { - rooms: {}, - application: {}, - connection: {} - }; - if (self.debugPrinter) { - self.debugPrinter("attempt to connect to WebRTC signalling server with application name=" + applicationName); - } - - if (errorCallback === null) { - errorCallback = function(errorCode, errorText) { - console.error("easyrtc.connect: " + errorText); - }; - } - - connectToWSServer(successCallback, errorCallback); - }; -}; -window.easyrtc = new Easyrtc(); diff --git a/messenger/js/easyrtc/node_modules/easyrtc/api/easyrtc_lang_en.js b/messenger/js/easyrtc/node_modules/easyrtc/api/easyrtc_lang_en.js deleted file mode 100644 index acce863742..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/api/easyrtc_lang_en.js +++ /dev/null @@ -1,15 +0,0 @@ - -var easyrtc_constantStrings = { - "unableToEnterRoom":"Unable to enter room {0} because {1}" , - "resolutionWarning": "Requested video size of {0}x{1} but got size of {2}x{3}", - "badUserName": "Illegal username {0}", - "localMediaError": "Error getting local media stream: {0}", - "miscSignalError": "Miscellaneous error from signalling server. It may be ignorable.", - "noServer": "Unable to reach the EasyRTC signalling server.", - "badsocket": "Socket.io connect event fired with bad websocket.", - "icf": "Internal communications failure", - "statsNotSupported":"call statistics not supported by this browser, try Chrome.", - "noWebrtcSupport":"Your browser doesn't appear to support WebRTC.", - "gumFailed":"Failed to get access to local media. Error code was {0}.", - "requireAudioOrVideo":"At least one of audio and video must be provided" -}; \ No newline at end of file diff --git a/messenger/js/easyrtc/node_modules/easyrtc/api/img/LICENSE b/messenger/js/easyrtc/node_modules/easyrtc/api/img/LICENSE deleted file mode 100644 index 898d608680..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/api/img/LICENSE +++ /dev/null @@ -1,6 +0,0 @@ -Licenses for images In img folder ----------------------------------- - -Logos for Priologic Software Inc, and EasyRTC are owned by Priologic Software Inc. - -Permission is granted to use powered_by_easyrtc.png within your own application as long as it is not altered in any way. \ No newline at end of file diff --git a/messenger/js/easyrtc/node_modules/easyrtc/api/img/easyrtc.png b/messenger/js/easyrtc/node_modules/easyrtc/api/img/easyrtc.png deleted file mode 100644 index fb509f4561b080fd0268943c71ad084c7d46508b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3483 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 JPDHLkV1g#_b7lYl diff --git a/messenger/js/easyrtc/node_modules/easyrtc/api/img/powered_by_easyrtc.png b/messenger/js/easyrtc/node_modules/easyrtc/api/img/powered_by_easyrtc.png deleted file mode 100644 index 989c1fb4476b744019afcd75d1b29ff951bed098..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4178 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 diff --git a/messenger/js/easyrtc/node_modules/easyrtc/api/img/priologic_logo_white.png b/messenger/js/easyrtc/node_modules/easyrtc/api/img/priologic_logo_white.png deleted file mode 100644 index 1693dcd7357bf55acefe1476184727ba398fafde..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2810 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 M07*qoM6N<$f+s6bh5!Hn diff --git a/messenger/js/easyrtc/node_modules/easyrtc/api/img/x.svg b/messenger/js/easyrtc/node_modules/easyrtc/api/img/x.svg deleted file mode 100644 index bf6fad8c07..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/api/img/x.svg +++ /dev/null @@ -1,27 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/messenger/js/easyrtc/node_modules/easyrtc/api/labs/README.md b/messenger/js/easyrtc/node_modules/easyrtc/api/labs/README.md deleted file mode 100644 index df6148ab4d..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/api/labs/README.md +++ /dev/null @@ -1,3 +0,0 @@ -Labs Folder -=========== -The code in the labs folder is experimental. It may change, it hasn't been throughly tested, use at your own risk. diff --git a/messenger/js/easyrtc/node_modules/easyrtc/api/labs/desktopCapture.zip b/messenger/js/easyrtc/node_modules/easyrtc/api/labs/desktopCapture.zip deleted file mode 100644 index f7584f8ab00aae031a448429552ff31a8beb0bf3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4718 zcma)=1yEFNqsN!7B?Tl_8YBeiZUL285Tv^$mT&FViX!wa>3>EPzU=Lm)9Xt>Vs16%R>1Ah2d z60se>Rv=N3vcNH_>4@qgsp_6egABy1(sZTW$Z}T+i4&7vXCL;TFy!X~ifhBQ`wL!r z@e{UqG~NHP^y3+Z;rNOTJ$7gt^Nig4Ox$oc?*Oy%_bkpaI`4BL>@MD`MlvpGd7Syy znq|Djik^3JvLKb4Y~Y=fmvqeAOu3#8g;aUfb^zK6%k zMLFoZv5IkBrr$yShGuWjR4J55$-p;Vzl~^;+k>}s4rvp7?FyMlXx{;z8`7qtlJmbCqtk5kXWaJtZdca)qJ)n z@HAChQOC@4G3F$%*jOV~d&^*2_;V9w9IBEx==z{JKW^lRx~Y*IsrHGVVg`FKh?6?8 zG>N!4wAy@yVs{S%nbo4K^XzH>9KLA|GMzWpoII>Lyc)b-`*N8MMdZJN6IN!YO|6jh z-8(hf)i4xS5y_G>$xbc=_8J{1w0IBoy`%&O6}TPH;ISsj#9u|Dlon!VTKNGY$ zq{-^2u>N<*JiFk|%DIvqT^M(HcBz&Ht<)Ge(`RGtOeC-ATnG@;fGIL0%|M|?dl|jf z{Jhuy6&pezbA8mwtFwzsU#_eCC&m)RF8w}G(C|tKhK!koO8cQuWL{+j|%O@31zcdOhbOPI=U}X`r$~Tg{ zE#(`=r`%ydY?M!*PRyOr1F6}A@lSOUw7(`^9}S8WJ5pn$E^z9(wJKW1Y=ewSjsEJc zj=SLXK)-$46II;GcTMmW+jg8%O@Y#>rwoG(bP#5F2l938q5V1C7A8t%kp z>q>o7hsD*q$n@%dm?zrC3{&F4T2xyU5J-Q~c*9nOc}6(EpwI>c>N)~}#JoUYd!Qom zLmC>@pn?`v3yX@h&JHFsetZ3FVlBnuZjoFzakK24m01 z#>cO!<0Y`L;)@C+t)GM)%%nC~r+}2FM~xODio8fY$jLpf`s>Pb4l}>7Jq%)sE_U8N z!yAR1^v|bd4_YEmJ+C$04?r0SP{&YosL@!n%J8LJx*zmN2#lAZwr>I*m1~c!tsR7` zSOuvY4c5}u2V4tOwbyUeZHN2ZdteXF`0NBEk$4V4`Th9RCXa5}SymYeI2V0Wy8h94 z!OW7i&~qhl)br>4Ardx-M@4!-OZWPV2{6M%4R&RX#>^|isoohXgJrlA~>`8x}FuSC*ax!njdBr1Ei z0>Ma!-s3*%9ZFR7LdL#katf=&!3G3uhA1G778){l(dw_YZ;XX3BgRYnE6sH+o^JbH z^cJk2OGeRFow#bgSeH69ubMc|;J;XQNR$&*(QGfcln0}))eS*H z?`R^LXHFP#8AONYpsdUKiBkoo`aIhu?IyHzd#9H5O#HM0-c9F?aH#4FOu%o~Gkipq zwRd0mM&2%m%2)sZ=ug)nmM#u`!vP1{l^2Y zxM@>^lMGT#KS&z8D%0m¨X>`p^fCEMVfsyag2gnwIp}5=@zB0 z=3-nn8vN{zYMiE^?|M+>OL(kcbt->jPmf)kt@PTDFyFHHL`1)QUY=Xpxxh;G0rzB} zz!^hi8(lEi<=LGNxpYyFCc+$xYvZ|Iz|<{J3q^B&x?=a3+m$Br%bi|q35;d&J=M<| zTp=?VokIBB_((W+HlY~5>&i6B**Ajx_7Ku7u-8{5JXH=EYvXx{ge(S*byoK$&nA!J zcu>w~TXMfA(XvED88%^yQ-ucr=-dGSX#Si;ZDj=|4P`!vO}>GX>#QjCl}pFXUn&@m zevVJw7rSTn@`#-aMMURuD?_Z1_|gg8v=glFjNzIN!{rQo$&}Q=sshlf1m%lptH5 zaPmi%4DQjAh*2OHNv!JR6KmGxoPHG>w&#(-2d}MkRXFVJ9OP`N*kN=dLRMNwCs_yT z6-4(vahab@xJsXS`>4aqh++k?Y^Jlei1#=}g?%*g#CceqzWL?cL)a=u26Oq97IAzs zTv*J}oq4zF_+=zi>i9vV%OQGXHpPhar#FlGJliwwp$6xvoxgGmMNr28 zT`YwW){gyV6DAf)-d9!Z?Wo%Z=`D`JyVzBJ&f~))xbX}Es60KupgQcM1e5@$q8xx|M$Z7Uj;l38w9x7p3E|twY4u7isa<%CciLan+@&MT zpt1+UVC81vU_$0L(czGVBM?|`8e%7KvJ_{KF zK0!HlY4u!5c*avIqRD(CY#zkFF#EuZ$jXN?In5(POldwhghkhNitywffU)v6MPAF`OM7!aF`tq#>*@-mZ80^%}B((L=ng-mPqfrz{EU|=OdP((Z ztwvLR(H4RfDSjvF@n^c{XEz8We%AZB_XHtah$RP8&Q*yhu%Sh$&S!232SSf;PRm3$-WbEuu9NP z+N?b0*qkMAX8DyLEIg^KGSH@zwSIE@RoXG*Ny%M~?v@dR`O@%8OrU}Vbut`lU3K)n zjyV+LFemT@aZrGxrCRwzo#vZE?70 z#N>2UW1btmT+vhzaAiLDc^@XJ%XF8rNP349AMff;x;M8s(OJ#U)?ByK{1ro5ScavG!{d5w@oSU?|AbTQ@g!NO z&e<7|4U8TZW#5B6VbE#u|BS z+ImWMXKGfjnUojqp_9)#X)Lh}G4uE~$WT!!^H`5>k2EAu$&03jFlT{S>)k;xBd!Pq z9+$wUyB7p%g?HG~xgUjE`J=`fQrZ;ZckP;79M<%L)s*%Lz>ufRRA8?tcudwgS7bA_*TT{#b; zc@F}kq+91dI_~W1txGbPIn2^OzE}=6wZC$yn3{8uT2ExP94ZPp^W^5Tq1eesMVcN* zXDoe>6jnnGJwW+fVQC(FE$k-yNi~<7ZMLF%#>_UIKi1tRe!^ zrtY_gCoieBlmt_SM;dmVhW7MK&em>**R@XW&a@7mM_pabJ@uSeeN*|meR1ii7D?V} z&87JXHqT|m+PmerlZ$ZOQ6^-BqU)*Z16YT7_KmlB=qYhunKNZqT6}AelxtS{`XjAI zOhtO0%4otnl0`D<$OM(Cl)gqSLpeoNZ$QgaMRmofrG|k?3HZNHIc_(50LFj!*k4co zk28 - * - * easyrtc.chromeInstall("custom-app_id", function() { - * // success - * }, - * function(errorCode, errorText) { - * // failure - * }); - * - * @param {String} extensionId The id of the `link` tag pointing to your extension. - * @param {Function} successCallback Function to call on success. - * @param {Function} failureCallback Function to call on failure. Will pass argument `errorCode` and `errorMessage`. - */ -easyrtc.chromeInstaller = function(extensionId, successCallback, failureCallback) { - return function() { - var el, url; - if( !navigator.webkitGetUserMedia || - !window.chrome || - !chrome.webstore || - !chrome.webstore.install ) { - failureCallback(easyrtc.errCodes.DEVELOPER_ERR, "Can't install plugin on non-chrome browsers"); - } - else { - try { - var el = document.querySelector('head link#' + extensionId); - - if ( ! el) throw new Error("Can't find a `link` element in `head` with id `"+extensionId+"`"); - - // get the chrome extension url from the link's href attribute - var url = el.attributes.href.value; - - chrome.webstore.install(url, successCallback, function(error) { - failureCallback(easyrtc.errCodes.DEVELOPER_ERR, error); - }); - - } - catch (error) { - failureCallback(easyrtc.errCodes.DEVELOPER_ERR, error.message); - } - } - } -} diff --git a/messenger/js/easyrtc/node_modules/easyrtc/api/labs/easyrtc_rates.js b/messenger/js/easyrtc/node_modules/easyrtc/api/labs/easyrtc_rates.js deleted file mode 100644 index 6d60a6a6a7..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/api/labs/easyrtc_rates.js +++ /dev/null @@ -1,245 +0,0 @@ -// -// This code builds sdp filter functions -(function () { - - function buildSdpFilter(options, isLocal) { - - var audioSendBitrate = options.audioSendBitrate; - var audioRecvBitrate = options.audioRecvBitrate; - var videoSendBitrate = options.videoSendBitrate; - var videoRecvBitrate = options.videoRecvBitrate; - var videoSendBitrate = options.videoSendBitrate; - var videoSendInitialBitrate = options.videoSendInitialBitrate; - var audioSendCodec = options.audioSendCodec || ''; - var audioRecvCodec = options.audioRecvCodec || ''; - var stereo = options.stereo; - function trace(arg) { - console.log("trace:" + arg); - } - // these functions were cribbed from the google apprtc.appspot.com demo. - - function maybeSetAudioSendBitRate(sdp) { - if (!audioSendBitrate) { - return sdp; - } - trace('Prefer audio send bitrate: ' + audioSendBitrate); - return preferBitRate(sdp, audioSendBitrate, 'audio'); - } - - function maybeSetAudioReceiveBitRate(sdp) { - if (!audioRecvBitrate) { - return sdp; - } - trace('Prefer audio receive bitrate: ' + audioRecvBitrate); - return preferBitRate(sdp, audioRecvBitrate, 'audio'); - } - - function maybeSetVideoSendBitRate(sdp) { - if (!videoSendBitrate) { - return sdp; - } - trace('Prefer video send bitrate: ' + videoSendBitrate); - return preferBitRate(sdp, videoSendBitrate, 'video'); - } - - function maybeSetVideoReceiveBitRate(sdp) { - if (!videoRecvBitrate) { - return sdp; - } - trace('Prefer video receive bitrate: ' + videoRecvBitrate); - return preferBitRate(sdp, videoRecvBitrate, 'video'); - } - - function preferBitRate(sdp, bitrate, mediaType) { - var sdpLines = sdp.split('\r\n'); - var mLineIndex = findLine(sdpLines, 'm=', mediaType); - if (mLineIndex === null) { - messageError('Failed to add bandwidth line to sdp, as no m-line found'); - return sdp; - } - var nextMLineIndex = findLineInRange(sdpLines, mLineIndex + 1, -1, 'm='); - if (nextMLineIndex === null) { - nextMLineIndex = sdpLines.length; - } - var cLineIndex = findLineInRange(sdpLines, mLineIndex + 1, nextMLineIndex, 'c='); - if (cLineIndex === null) { - messageError('Failed to add bandwidth line to sdp, as no c-line found'); - return sdp; - } - var bLineIndex = findLineInRange(sdpLines, cLineIndex + 1, nextMLineIndex, 'b=AS'); - if (bLineIndex) { - sdpLines.splice(bLineIndex, 1); - } - var bwLine = 'b=AS:' + bitrate; - sdpLines.splice(cLineIndex + 1, 0, bwLine); - sdp = sdpLines.join('\r\n'); - return sdp; - } - - function maybeSetVideoSendInitialBitRate(sdp) { - if (!videoSendInitialBitrate) { - return sdp; - } - var maxBitrate = videoSendInitialBitrate; - if (videoSendBitrate) { - if (videoSendInitialBitrate > videoSendBitrate) { - messageError('Clamping initial bitrate to max bitrate of ' + videoSendBitrate + ' kbps.'); - videoSendInitialBitrate = videoSendBitrate; - } - maxBitrate = videoSendBitrate; - } - var sdpLines = sdp.split('\r\n'); - var mLineIndex = findLine(sdpLines, 'm=', 'video'); - if (mLineIndex === null) { - messageError('Failed to find video m-line'); - return sdp; - } - var vp8RtpmapIndex = findLine(sdpLines, 'a=rtpmap', 'VP8/90000'); - var vp8Payload = getCodecPayloadType(sdpLines[vp8RtpmapIndex]); - var vp8Fmtp = 'a=fmtp:' + vp8Payload + ' x-google-min-bitrate=' + videoSendInitialBitrate.toString() + '; x-google-max-bitrate=' + maxBitrate.toString(); - sdpLines.splice(vp8RtpmapIndex + 1, 0, vp8Fmtp); - return sdpLines.join('\r\n'); - } - - function maybePreferAudioSendCodec(sdp) { - if (audioSendCodec === '') { - trace('No preference on audio send codec.'); - return sdp; - } - trace('Prefer audio send codec: ' + audioSendCodec); - return preferAudioCodec(sdp, audioSendCodec); - } - - function maybePreferAudioReceiveCodec(sdp) { - if (audioRecvCodec === '') { - trace('No preference on audio receive codec.'); - return sdp; - } - trace('Prefer audio receive codec: ' + audioRecvCodec); - return preferAudioCodec(sdp, audioRecvCodec); - } - - function preferAudioCodec(sdp, codec) { - var sdpLines = sdp.split('\r\n'); - var mLineIndex = findLine(sdpLines, 'm=', 'audio'); - if (mLineIndex === null) { - return sdp; - } - var codecIndex = findLine(sdpLines, 'a=rtpmap', codec); - if (codecIndex) { - var payload = getCodecPayloadType(sdpLines[codecIndex]); - if (payload) { - sdpLines[mLineIndex] = setDefaultCodec(sdpLines[mLineIndex], payload); - } - } - sdp = sdpLines.join('\r\n'); - return sdp; - } - - function addStereo(sdp) { - var sdpLines = sdp.split('\r\n'); - var opusIndex = findLine(sdpLines, 'a=rtpmap', 'opus/48000'); - var opusPayload; - if (opusIndex) { - opusPayload = getCodecPayloadType(sdpLines[opusIndex]); - } - var fmtpLineIndex = findLine(sdpLines, 'a=fmtp:' + opusPayload.toString()); - if (fmtpLineIndex === null) { - return sdp; - } - sdpLines[fmtpLineIndex] = sdpLines[fmtpLineIndex].concat('; stereo=1'); - sdp = sdpLines.join('\r\n'); - return sdp; - } - - function findLine(sdpLines, prefix, substr) { - return findLineInRange(sdpLines, 0, -1, prefix, substr); - } - - function findLineInRange(sdpLines, startLine, endLine, prefix, substr) { - var realEndLine = endLine !== -1 ? endLine : sdpLines.length; - for (var i = startLine; i < realEndLine; ++i) { - if (sdpLines[i].indexOf(prefix) === 0) { - if (!substr || sdpLines[i].toLowerCase().indexOf(substr.toLowerCase()) !== -1) { - return i; - } - } - } - return null; - } - - function getCodecPayloadType(sdpLine) { - var pattern = new RegExp('a=rtpmap:(\\d+) \\w+\\/\\d+'); - var result = sdpLine.match(pattern); - return (result && result.length === 2) ? result[1] : null; - } - - function setDefaultCodec(mLine, payload) { - var elements = mLine.split(' '); - var newLine = []; - var index = 0; - for (var i = 0; i < elements.length; i++) { - if (index === 3) { - newLine[index++] = payload; - } - if (elements[i] !== payload) { - newLine[index++] = elements[i]; - } - } - return newLine.join(' '); - } - - - - if( isLocal ) { - return function(insdp) { - console.log("modifying local sdp"); - var sdp; - sdp = maybePreferAudioReceiveCodec(insdp); - sdp = maybeSetAudioReceiveBitRate(sdp); - sdp = maybeSetVideoReceiveBitRate(sdp); - if( sdp != insdp ) { - console.log("changed the sdp from \n" + insdp + "\nto\n" + sdp); - } - return sdp; - }; - } - else { - return function(insdp) { - console.log("modifying remote sdp"); - if (stereo) { - sdp = addStereo(sdp); - } - var sdp = maybePreferAudioSendCodec(insdp); - sdp = maybeSetAudioSendBitRate(sdp); - sdp = maybeSetVideoSendBitRate(sdp); - sdp = maybeSetVideoSendInitialBitRate(sdp); - if( sdp != insdp ) { - console.log("changed the sdp from \n" + insdp + "\nto\n" + sdp); - } - return sdp; - }; - } - - } - - /** - * This function returns an sdp filter function. - * @param options A map that optionally includes values for the following keys: audioRecvCodec, audioRecvBitrate, videoRecvBitrate - * @returns {Function} which takes an SDP string and returns a modified SDP string. - */ - easyrtc.buildLocalSdpFilter = function (options) { - return buildSdpFilter(options, true); - } - - /** - * This function returns an sdp filter function. - * @param options A map that optionally includes values for the following keys: stereo, audioSendCodec, audioSendBitrate, videoSendBitrate, videoSendInitialBitRate - * @returns {Function} which takes an SDP string and returns a modified SDP string. - */ - easyrtc.buildRemoteSdpFilter = function(options) { - return buildSdpFilter(options, false); - } -})(); - - diff --git a/messenger/js/easyrtc/node_modules/easyrtc/api/labs/inline-installcode.html b/messenger/js/easyrtc/node_modules/easyrtc/api/labs/inline-installcode.html deleted file mode 100644 index 54acd7de01..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/api/labs/inline-installcode.html +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/css/demo4.css b/messenger/js/easyrtc/node_modules/easyrtc/demos/css/demo4.css deleted file mode 100644 index 915d155633..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/css/demo4.css +++ /dev/null @@ -1,47 +0,0 @@ - #demoContainer { - position:relative; - } - #connectControls { - float:left; - width:250px; - text-align:center; - border: 2px solid black; - } - #otherClients { - height:200px; - overflow-y:scroll; - } - #selfVideo { - height:225px; - width:300px; - float:left; - border:1px solid gray; - margin-left:10px; - } - .callerVideoBox { - position:relative; - } - .callerVideo { - height:225px; - width:300px; - border:1px solid gray; - margin-left:10px; - } - .easyrtc_closeButton { - position:absolute; - right:2px; - background-color: transparent; - background-image: url('../images/button_close.png'); - border:none; - margin:0px; - padding:0px; - top:0px; - width:56px; - height:56px; - z-index: 2; - opacity:0.4; - } - .easyrtc_closeButton:hover { - cursor: pointer; - opacity:1; - } diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/css/demo_audio_video_simple.css b/messenger/js/easyrtc/node_modules/easyrtc/demos/css/demo_audio_video_simple.css deleted file mode 100644 index b9976db8f9..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/css/demo_audio_video_simple.css +++ /dev/null @@ -1,27 +0,0 @@ -#demoContainer { - position:relative; -} -#connectControls { - float:left; - width:250px; - text-align:center; - border: 2px solid black; -} -#otherClients { - height:200px; - overflow-y:scroll; -} -#selfVideo { - height:225px; - width:300px; - float:left; - border:1px solid gray; - margin-left:10px; -} - -#callerVideo { - height:225px; - width:300px; - border:1px solid gray; - margin-left:10px; -} \ No newline at end of file diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/css/demo_audio_video_simple_hd.css b/messenger/js/easyrtc/node_modules/easyrtc/demos/css/demo_audio_video_simple_hd.css deleted file mode 100644 index b49ec796fb..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/css/demo_audio_video_simple_hd.css +++ /dev/null @@ -1,51 +0,0 @@ -#demoContainer { - position:relative; -} -#container { - width:1330px; -} -.callButton { - float:left; -} -#connectControls { - float:left; -} -#otherClients { - height:50px; -} -#selfVideo { - volume: 0; - position:absolute; - left: 10px; - top:10px; - z-index: 2; - opacity: 0.8; - height:120px; - width:160px; -} -#callerVideoBox { - position:relative; - border: 1px solid gray; -} -#callerVideo { - height:720px; - width:1280px; -} -.closeButton { - position:absolute; - right:2px; - background-color: transparent; - background-image: url('../images/button_close.png'); - border:none; - margin:0px; - padding:0px; - top:0px; - width:56px; - height:56px; - z-index: 2; - opacity:0.4; -} -.closeButton:hover { - cursor: pointer; - opacity:1; -} \ No newline at end of file diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/css/demo_lowbandwidth.css b/messenger/js/easyrtc/node_modules/easyrtc/demos/css/demo_lowbandwidth.css deleted file mode 100644 index b9976db8f9..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/css/demo_lowbandwidth.css +++ /dev/null @@ -1,27 +0,0 @@ -#demoContainer { - position:relative; -} -#connectControls { - float:left; - width:250px; - text-align:center; - border: 2px solid black; -} -#otherClients { - height:200px; - overflow-y:scroll; -} -#selfVideo { - height:225px; - width:300px; - float:left; - border:1px solid gray; - margin-left:10px; -} - -#callerVideo { - height:225px; - width:300px; - border:1px solid gray; - margin-left:10px; -} \ No newline at end of file diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/css/demo_room.css b/messenger/js/easyrtc/node_modules/easyrtc/demos/css/demo_room.css deleted file mode 100644 index 90da0cb969..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/css/demo_room.css +++ /dev/null @@ -1,74 +0,0 @@ - -.transit { - transition: left 1s, top 1s, right 1s, bottom 1s, width 1s, height 1s, transform 1s; - -moz-transition: left 1s, top 1s, right 1s, bottom 1s, width 1s, height 1s, -moz-transform 1s; - -webkit-transition: left 1s, top 1s, right 1s, bottom 1s, width 1s, height 1s, -webkit-transform 1s; - -o-transition: left 1s, top 1s, right 1s, bottom 1s, width 1s, height 1s,-o-transform 1s; -} - -.hidden { - background-color: transparent; - border-color: 2px solid blue; -} - -.boxCommon { - position:absolute; -} - -.closeButton { - display: none; /* hide the easyApp's close button because we have our own */ -} - -.thumbCommon { - z-index:2; - box-shadow: 5px 5px 5px #000000; -} - -#controlArea { - background-color: #ff8000; -} - -body { - background-color:#ffd0d0; - margin-left:0px; - margin-top:0px; -} - -#killButton { - opacity:0.7; -} - -#killButton:hover { - opacity:1.0; -} - -#muteButton { - opacity:0.7; -} - -#muteButton:hover { - opacity:1.0; -} - -#textentryBox { - border:2px solid #a0ffa0; - border-radius:10px; - z-index:5; - position: absolute; - background-color: #ffffff; - box-shadow: 5px 5px 5px #000000; - font-family: 'Courier New',Courier,monospace; -} - -#textentryField { - font-size:x-large; - margin: 20px; -} - -#textentrySubmit { - font-size:larger; -} - -#textentryCancel { - font-size:larger; -} diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/css/landing.css b/messenger/js/easyrtc/node_modules/easyrtc/demos/css/landing.css deleted file mode 100644 index 5253d51f19..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/css/landing.css +++ /dev/null @@ -1,125 +0,0 @@ -/* - General CSS for easyrtc local landing site. - Only general layout is here. - Any CSS related directly to the operation of a demo is kept in another file. -*/ - -body { - background-image:url("../images/bg_light.png"); - font-family:Arial, Helvetica, sans-serif; -} - -#container { - width:960px; - margin-left: auto; - margin-right:auto; - - background-image:url("../images/bg_dark.png"); - background-color:black; - - border-color: #FF6600; - border-width: 1px; - border-style: solid; - border-radius:10px; -} - -#logo_easyrtc { - margin-top:5px; - margin-left:5px; -} -#logo_priologic { - margin-top:5px; - margin-right:5px; -} - -#menu { - text-align: right; - clear: both; - padding-bottom: 2px; - padding-top: 2px; -} -.menu_item { - display: inline; - text-decoration: none; - border-color: gray; - border-width: 2px; - border-style: outset; - color: white; - padding: 0px 3px 0px 3px; - background-color: rgba(0,0,0,.4); -} -.menu_item:hover { - border-style:inset; - background-color: rgba(100,100,100,0); -} -.menu_link { - text-decoration:none; -} -.menu_link:focus { - text-decoration:underline; -} - - - -#main { - background-color:white; - overflow:hidden; - padding-left: 10px; - padding-right: 10px; -} - -#footer { - font-size: small; - padding: 5px; - color:white; - min-height:60px; -} -#footer p { - margin: 0px; - color:white; - text-align:center; -} -#footer a { - color:white; -} -#license { - font-size: x-small; -} -#logo_priologic { - float:left; - padding-top: 10px; - margin-right: 10px; -} -#logo_pb_easyrtc { - float:right; - margin-left: 10px; -} - - -.demo_table { - border-collapse:collapse; - border:1px solid gray; -} -.demo_table th{ - padding:3px; - text-align:left; -} -.demo_table td{ - border-top:1px solid gray; - padding:3px; -} -.demo_table #browser_note{ - text-align:center; - font-size: smaller; - color: gray; -} - -hr { - clear:both; -} - -.prettyprint { - white-space: pre-wrap; - max-height:400px; - overflow-y:scroll; -} \ No newline at end of file diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo4.html b/messenger/js/easyrtc/node_modules/easyrtc/demos/demo4.html deleted file mode 100644 index 0b3bff68ea..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo4.html +++ /dev/null @@ -1,118 +0,0 @@ - - - - - EasyRTC Demo: Simple 4-Way Video Chat - - - - - - - - - - - - - - - - - - - - - - - - - -
- - -
- - -

EasyRTC Demo: Simple 4-Way Video Chat

- -

The application provides a 4-way video chat using the easyrtc.easyApp method. It is a variation on the Simple Audio Video Chat demo. -

- -

Connection is handled using an onload statement in the body. Requests are automatically accepted.

- -

To hang-up on a call, hover your mouse over the upper right of the video, and click on the red handset which appears.

- -

- Important note: 3 way and 4 way chats require much more network - bandwidth and CPU resources; they may crash your browser. - We recommend using a video conferencing server for production environments. -

-
-

The Demo

- -
-
-
Not yet connected...
-
- Connected users: -
-
-
- - -
- -

-
- -
-
- -
-
-
- -
-
- -

The Code

-

HTML

-
-                
- -

CSS

-

In order to show the 'X' in the upper right corner, the callerVideo video tag must be in a div with relative positioning.

-
-                
- -

JavaScript

-

The contents of demo_audio_video_simple.js:

-
-                
- - - - - - -
- -
- - - diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_audio_only.html b/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_audio_only.html deleted file mode 100644 index ab914443f4..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_audio_only.html +++ /dev/null @@ -1,128 +0,0 @@ - - - - - EasyRTC Demo: Audio Only - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- -

EasyRTC Demo: Audio Only

- -

The application provides an audio only chat by disabling video - before initializing the local media stream.

- -

To use it, press the Connect button. - You should see buttons representing other people using this demo. - Click one of those buttons to initiate a chat.

- -
-

The Demo

- - -
-
- - -
Not yet connected...
-
- Connected users: -
-
- - -
- -
-
- -
-
-
- - -
-
-

The Code

-

HTML

-
-                
-

JavaScript

-

The contents of demo_audio_only.js:

-
-                
- - - - -
- - -
- - - diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_audio_video.html b/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_audio_video.html deleted file mode 100644 index 0ba10a48c2..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_audio_video.html +++ /dev/null @@ -1,146 +0,0 @@ - - - - - EasyRTC Demo: Audio and Video - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - -

EasyRTC Demo: Audio and Video

- -

The application provides an audio-video chat where sharing of audio and video can be controlled individually before connection.

- -

To use it, press the Connect button. - You should see buttons representing other people using this demo. - Click one of those buttons to initiate a chat.

- -
-

The Demo

- -
-
- Share audio - Share video
- Expect audio - Expect video
- - Fresh Ice
- - - -
Not yet connected...
-
- Connected users: -
-
- -
- - -
-
- -
-
-
- -
-
- -

The Code

-

HTML

-
-                
-

JavaScript

-

The contents of demo_audio_video.js:

-
-                
- - - - - - - -
- -
- - - diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_audio_video_simple.html b/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_audio_video_simple.html deleted file mode 100644 index d9d802a87d..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_audio_video_simple.html +++ /dev/null @@ -1,98 +0,0 @@ - - - - - EasyRTC Demo: Simple Video+Audio - - - - - - - - - - - - - - - - - - - - -
- - -
- -

EasyRTC Demo: Simple Video+Audio

- -

The application provides a simple audio-video chat using the easyrtc.easyApp method.

- -

Connection is handled using an onload statement in the body. Requests are automatically accepted.

- -

To hang-up on a call, hover your mouse over the upper right of the video, and click on the 'X' which appears at the top right of other person's video object.

- -
-

The Demo

- -
-
-
Not yet connected...
-
- Connected users: -
-
-
- -
- -
- -
-
- -
-
- -

The Code

-

HTML

-
-
-                
- -

CSS

-

In order to show the 'X' in the upper right corner, the callerVideo video tag must be in a div with relative positioning.:

-
-                
- -

JavaScript

-

The contents of demo_audio_video_simple.js:

-
-                
- - - - - - -
- -
- - - diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_audio_video_simple_hd.html b/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_audio_video_simple_hd.html deleted file mode 100644 index bd5161369d..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_audio_video_simple_hd.html +++ /dev/null @@ -1,95 +0,0 @@ - - - - - EasyRTC Demo:EasyRTC Demo: Video+Audio HD 720 - - - - - - - - - - - - - - - - - - - - - -
- - -
- - -

EasyRTC Demo: Video+Audio HD 720p

-
-
- Note: your own image will show up postage stamp sized, while the other party's video will be shown in high-definition (1280x720). Note: not all webcams are seen by WebRTC as providing high-definition video; the fallback is to use standard definition (640x480). -
-
-
Not yet connected...
-
- Connected users: -
-
-
- -
- - -
- -
-
- -
-
- -

The Code

-

HTML

-
-
-                
- -

CSS

-

In order to show the 'X' in the upper right corner, the callerVideo video tag must be in a div with relative positioning.:

-
-
-                
- -

JavaScript

-

The contents of demo_audio_video_simple_hd.js:

-
-
-                
- - - - - -
- -
- - - diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_data_channel_filesharing.html b/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_data_channel_filesharing.html deleted file mode 100644 index 8fe35cf088..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_data_channel_filesharing.html +++ /dev/null @@ -1,141 +0,0 @@ - - - - - EasyRTC Demo: Data Channel File-sharing - - - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -

EasyRTC Demo: Data Channel File-sharing

-

This application demonstrates file sharing using the easyrtc.sendData method. - It should connect to the server upon start up, and display drag-and-drop areas for other peers.

- -

To use it, connect to a peer then drop a file into the drag-and-drop area for that peer. The peer should receive it. -

- -

Warn - This demo requires reliable data channels which means it needs Firefox or Chrome (version 32+). - In the absence of reliable data channels it will fallback to using websockets to transfer a file. - Notice that it uses easyrtc_ft.js as well as easyrtc.js. -

-
-

The Demo

- -
Obtaining ID...

-
-
- - -
- -

The Code

-

HTML

-
-
-                
-

JavaScript

-

The contents of demo_instant_messaging.js:

- -
-                
- - - - - - - -
- - -
- - - diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_data_channel_messaging.html b/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_data_channel_messaging.html deleted file mode 100644 index 6a418b99d0..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_data_channel_messaging.html +++ /dev/null @@ -1,105 +0,0 @@ - - - - - EasyRTC Demo: Data Channel Messaging - - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -

EasyRTC Demo: Data Channel Messaging

-

This application demonstrates text messaging using data channels via the easyrtc.sendDataP2P method.

- -
- -

The Demo

- -
-
Obtaining ID...
- -
-
-
- Received Messages: -
-
- - -
- -

The Code

-

HTML

-
-                
- -

JavaScript

-

The contents of demo_instant_messaging.js:

-
-            
- - - - - - -
- - - -
-
- - - diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_ice_filter.html b/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_ice_filter.html deleted file mode 100644 index 915edd8185..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_ice_filter.html +++ /dev/null @@ -1,95 +0,0 @@ - - - - - EasyRTC Demo: Ice Filter - - - - - - - - - - - - - - - - - - - - -
- - -
- -

EasyRTC Demo: Ice Filter

- -

Client side filtering of ICE configuration.

- -

Client-side ice filtering is meant as a experimenting tool, not something you should need to do in a - production environment. -

- -


-

The Demo

- -
-
-
Not yet connected...
-
-
-
-

Connected users:

-
-
- -
- -
- -
- -
- -
- -
-
- -

The Code

-

HTML

-
-                
- -

JavaScript

-

The contents of demo_audio_video_simple.js:

-
-                
- - - - - - -
- -
- - - diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_instant_messaging.html b/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_instant_messaging.html deleted file mode 100644 index dc978a4fc9..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_instant_messaging.html +++ /dev/null @@ -1,104 +0,0 @@ - - - - - EasyRTC Demo: Instant Messaging - - - - - - - - - - - - - - - - - - - - - - -
- - -
- - -

EasyRTC Demo: Instant Messaging

-

This application demonstrates text messaging using the easyrtc.sendDataWS method. - It should connect to the server upon start up, and display buttons for the other - peers running the same application.

- -

To use it, enter a message into the text box on the left side of the page. - Then press one of the buttons for another peer to send the message to that peer. - The message should appear on the text box to the right on both this page, and that of the peer.

- -
-

The Demo

- -
-
Obtaining ID...
- -
-
-
- Received Messages: -
-
- - -
- -

The Code

-

HTML

-
-                
-

JavaScript

-

The contents of demo_instant_messaging.js:

-
-                
- - - - - - -
- - -
- - - diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_instant_messaging_rooms.html b/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_instant_messaging_rooms.html deleted file mode 100644 index 49e72857d1..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_instant_messaging_rooms.html +++ /dev/null @@ -1,194 +0,0 @@ - - - - - EasyRTC Demo: Instant Messaging + Rooms - - - - - - - - - - - - - - - - - - - - - - -
- - -
- - -

EasyRTC Demo: Instant Messaging + Rooms

-

Note: This is primarily an application - developed to test new features going into EasyRTC Modular (v1.0.x). It's currently not written to be a tutorial, - but it does demonstrate how to use various features like presence and room targeted messaging.

-
-

The Demo

- -
- Username: - Password: -
- -
-
-
-
- -
-
- Presence: - away - chat - dnd - xa - -
-
-
- Quick Join - - -
- - -
- Optional room parameters - -
- -
-
-
- -
Not connected yet
- - - Rooms: -
-
-
- Received Messages: -
-
-
- -
-
- -

Adding api fields

- -
-
- -
- -
-

Getting the list of room occupants

- - -
- -
-
-

Fields from server

-
-
-
- - - -
-

Name To Id

-
- - -
-
-
- - -
-

Testing the following EasyRTC Features:

-
    -
  • Authentication - If username is provided, it will be available to others to see.
  • -
  • Define Rooms during Authentication - You can join rooms before you press 'Connect'.
  • -
  • Default Rooms - If you join no rooms before you connect, you will join the default room.
  • -
  • Messages to All In Room (targetRoom) - Type a message, then click on a room name to send it to everyone in the same room. When received, the other client will know it was sent to the room at large.
  • -
  • Message to Individual In Room (targetRoom + targetEasyrtcid) - Type a message, then click on another client in a room to send it to just that person. That person will know it was sent directly to them, and that it was sent via a specific room.
  • -
  • Presence - Your presence gets sent to all clients in rooms you share. DND=Do not disturb. XE=Extended Away. The status field can be any string.
  • -
  • Delta Lists - After initial login, the client should only receive changes to who is online.
  • -
- - -
- - -
- - - diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_instant_messaging_selfconnect.html b/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_instant_messaging_selfconnect.html deleted file mode 100644 index d19326471d..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_instant_messaging_selfconnect.html +++ /dev/null @@ -1,106 +0,0 @@ - - - - - EasyRTC Demo: User Supplied Socket.io - - - - - - - - - - - - - - - - - - - - - - -
- - -
- - -

EasyRTC Demo: User Supplied Socket.io

-

This variation on instant messaging uses a socket.io connection - allocated by the application rather than internally. This can be useful if you have more advanced - socket.io requirements.

- -

It supports two options, connecting immediately after creating a websocket, - connecting 10 seconds after creating the websocket.

- -
-

The Demo

- - -
- -
-
Obtaining ID...
- -
-
-
- Received Messages: -
-
- - -
- -

The Code

-

HTML

-
-                
-

JavaScript

-

The contents of demo_instant_messaging.js:

-
-                
- - - - - - -
- - -
- - - diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_lowbandwidth.html b/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_lowbandwidth.html deleted file mode 100644 index 5275744932..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_lowbandwidth.html +++ /dev/null @@ -1,100 +0,0 @@ - - - - - EasyRTC Demo: Low-bandwidth Chat - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -

EasyRTC Demo: Low-bandwidth Chat

- -

The application provides a simple audio-video chat using experimental SDP filters to reduce the bandwidth used.

- -

Connection is handled using an onload statement in the body. Requests are automatically accepted.

- -

To hang-up on a call, hover your mouse over the upper right of the video, and click on the 'X' which appears at the top right of other person's video object.

- -
-

The Demo

- -
-
-
Not yet connected...
-
- Connected users: -
-
-
- -
- -
- -
-
- -
-
- -

The Code

-

HTML

-
-
-                
- -

CSS

-

In order to show the 'X' in the upper right corner, the callerVideo video tag must be in a div with relative positioning.:

-
-                
- -

JavaScript

-

The contents of demo_audio_video_simple.js:

-
-                
- - - - - - -
- -
- - - diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_multiparty.html b/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_multiparty.html deleted file mode 100644 index 24848b8386..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_multiparty.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - Multiparty Chatroom - - - - - - - - - - - -
- - - - - - - - - -
- - diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_multistream.html b/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_multistream.html deleted file mode 100644 index fc4d302e71..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_multistream.html +++ /dev/null @@ -1,147 +0,0 @@ - - - - - EasyRTC Demo: Multistream calls - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - -

EasyRTC Demo: Multistream calls

- -

This application demonstrates sending multiple video streams from one caller to another. - You can open up the media streams before or after establishing the call to the other peer.

- -

To use it, press the Connect button. - You should see buttons representing the video sources and a list of buttons representing other people using this demo. - Click one of those buttons to initiate a chat. Note: this demo looks much better when hosted on an https site.

- -
-

The Demo

- -
-
- - -
Not yet connected...
-

Video sources

-
- -
- -
- Connected users: -
-
- -
-

Local media streams

-
-

Remote media streams

-
-
-
- -
-
-
- -
-
- -

The Code

-

HTML

-
-                
-

JavaScript

-

The contents of demo_audio_video.js:

-
-                
- - - - - - - -
- -
- - - diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_multistream_iframe.html b/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_multistream_iframe.html deleted file mode 100644 index d8db39c602..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_multistream_iframe.html +++ /dev/null @@ -1,148 +0,0 @@ - - - - - EasyRTC Demo: Multistream calls - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - -

EasyRTC Demo: Multistream calls

- -

This application demonstrates sending multiple video streams from one caller to another. - You can open up the media streams before or after establishing the call to the other peer.

- -

To use it, press the Connect button. - You should see buttons representing the video sources and a list of buttons representing other people using this demo. - Click one of those buttons to initiate a chat. Note: this demo looks much better when hosted on an https site.

- -
-

The Demo

- -
-
- - -
Not yet connected...
-

Video sources

-
- -
- -
- Connected users: -
-
- -
-

Local media streams

-
-

Remote media streams

-
-
-
- -
-
-
- -
-
- -

The Code

-

HTML

-
-                
-

JavaScript

-

The contents of demo_audio_video.js:

-
-                
- - - - - - - -
- -
- - - diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_multistream_no_iframe.html b/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_multistream_no_iframe.html deleted file mode 100644 index 0c14ce4809..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_multistream_no_iframe.html +++ /dev/null @@ -1,153 +0,0 @@ - - - - - EasyRTC Demo: Multistream calls - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
- - - -

EasyRTC Demo: Multistream calls

- -

This application demonstrates sending multiple video streams from one caller to another. - You can open up the media streams before or after establishing the call to the other peer.

- -

To use it, press the Connect button. - You should see buttons representing the video sources and a list of buttons representing other people using this demo. - Click one of those buttons to initiate a chat. Note: this demo looks much better when hosted on an https site.

- -
-

The Demo

- -
- -
- - - - -
-
Not yet connected...
-

Video sources

-
- -
- Connected users: -
-
- -
-

Local media streams

-
-

Remote media streams

-
-
-
- -
-
-
- -
-
- -

The Code

-

HTML

-
-                
-

JavaScript

-

The contents of demo_audio_video.js:

-
-                
- - - - - - - - -
- -
- - - diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_reconnect.html b/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_reconnect.html deleted file mode 100644 index f886035f19..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_reconnect.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - - EasyRTC Demo: Reconnect - - - - - - - - - - State =
Unconnected
- - - - - diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_room.html b/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_room.html deleted file mode 100644 index d5bccdeade..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_room.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - EasyRTC Room - - - - - - - - - - - -
- - - - - - - - - -
- - diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_screen_receive.html b/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_screen_receive.html deleted file mode 100644 index 2d724f8fef..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_screen_receive.html +++ /dev/null @@ -1,168 +0,0 @@ - - - - - EasyRTC Demo: Screen Sharing Receiver - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -

EasyRTC Demo: Screen Sharing Receiver

- -

The application receives a video screen capture from a complementary sending program.

- -

To use it, press the Connect button. - You should see buttons representing other people using this demo. - Click one of those buttons to see (with their permission) their live screen.

-
-

The Demo

- -
-
- - - Your name: -
-
- - - - -
Not yet connected...
-
- - - -
-
-
-

- Click here to exit
- full screen. -

-
- -

-
- -
-

Browser Note: Until there is better interoperability among browsers, both clients may need to be using the same browser type.

-
- -

The Code

-

HTML

-
-
-                
-

JavaScript

-

The contents of demo_audio_video.js:

-
-                
- - - - - - -
- -
- - - diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_screen_send.html b/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_screen_send.html deleted file mode 100644 index 69393e5870..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_screen_send.html +++ /dev/null @@ -1,121 +0,0 @@ - - - - - EasyRTC Demo: Screen Sharing Sender - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -

EasyRTC Demo: Screen share - Sender

- -

This application shares the screen(s) of it's host.

-

Currently this demo only runs in - Chrome. It must be hosted on an https server. -

- -
-

The Demo

- -
-
- - Your name: -
-
- - -
-
-
-
Not yet connected...
-
-
- -
- -
-
- -
-
-
- -
-

Browser Note: Until there is better interoperability among browsers, both clients may need to be using the same browser type.

-
- -

The Code

-

HTML

-
-                
-

JavaScript

-

The contents of demo_audio_video.js:

-
-                
- - - - - - - -
- -
- - - diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_video_only.html b/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_video_only.html deleted file mode 100644 index 23856287a3..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/demo_video_only.html +++ /dev/null @@ -1,135 +0,0 @@ - - - - - EasyRTC Demo: Video Only - - - - - - - - - - - - - - - - - - - - - - - - -
- - -
- -

EasyRTC Demo: Video Only

- -

The application provides a video-only chat by disabling audio before initializing the local media stream.

- -

To use it, press the Connect button. - You should see buttons representing other people using the video-only chat page. - Click one of those buttons to initiate a chat.

- -
-

The Demo

- -
-
- - -
Not yet connected...
-
- Connected users: -
-
- -
- - -
-
- -
-
-
- -
-
- -

The Code

-

HTML

-
-                
-

JavaScript

-

The contents of demo_video_only.js:

-
-                
- - - - - - -
- -
- - - diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/images/LICENSE b/messenger/js/easyrtc/node_modules/easyrtc/demos/images/LICENSE deleted file mode 100644 index 345e7756b9..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/images/LICENSE +++ /dev/null @@ -1,8 +0,0 @@ -Licenses for images In demo folder ----------------------------------- - -Browser logos are copyright by their respective owner. - -Logos for Priologic Software Inc, and EasyRTC are owned by Priologic Software Inc. - -Permission is granted to use powered_by_easyrtc.png within your own application as long as it is not altered in any way. \ No newline at end of file diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/images/bg_dark.png b/messenger/js/easyrtc/node_modules/easyrtc/demos/images/bg_dark.png deleted file mode 100644 index aeea8af0b5cbd7e72754a0c003bb958d7261814d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9165 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 d{mj9gV6$3N%XxpU{v zOt-u2F8#OdZh%@VBpMaBNg-~iDKA!RB|%K%K3EfoFTUY}k;KFY2(JXR#6PjIfUp}t ziK$(pl7=FJHnm_`Nu+C++A{6#bmq>Td(R&q&YjuWo!Lzrcrl*j*>9=938{+ zKuC}|_iW=^Fez9AN`cl8mG|=bZyXaJiNJ{$e|WO|!6V~2Tc;2%2W`Du(?P_5F^)hS zLrRI}$V0E+@zo#fx^4m|etE#=FHhln5adC6Af*Eq9Sd#tG#R+jPNp@)iL;0rI>4Qi zQ{tKl{ORZWtzVfY$V1KpAwUX8prySKOXhD`p#^L$80*Mr1C1Ee(0=YZG~IXYX2lvQLCsGy^X$W?SK{SX3i>WScH89yd>^C* zBb@m);F(qImia+j_il_M-*O9pCqcja*w~sDIQ{EAc5rY+ghbiD#8uJ zZWfEs%q)^*YqWCUEv|kJq^XyWKe5NIYJpNbgY;o+3!IyGe$KI^1;E(NFnIgVkbXbb z7=)AvxsFlWB%XVmwEFTgwS?F4F2Jan-Y$4^`p^YxPbEM;?1SJEG!h^SM1Y$<34>pF zndbS!sODb~au7iQV=Cmr&k}C?F7iL4BnwZp0TD%@52Wv8c8)X057}G4^psdeARnI^ z0Q}bP4Z|?|FBj2;0B-pN42>V7`u5%>&BPowI|<3cEXl$%^nL0$LQ0bAi@ndifFh^5 zV<1##@`5Ca+%L0*-V{GH=*|4g9IbrS|jxp3B{Ri z0>VVgG9AF?O;C?v^9GQ)^~9A64m=~Ev)LkG6vUTi!6f8@)skNyo)@it3_FJx!009j zd{DJ_FewNNLc62bCTyG=T1U{D7~u~u=az#4MNLULt zy@HT_?+s0g)jbFp1D@?pG}4FuA@KXhF{&dK%M}H|cBEwyU{t*~ffdBsUQcz1(W{U) zAcFxsA5<&gTEUkEqfS93;D_K9x1yq%-ka$;j0w95MBWa^-gcC@jTX62C({}R$Db!YcetnNTg59=iwCC?bm7}-$S!1!x$Jw~_=LacmgwcH`7>VAeasE-4 zGe#c53%7Ckjoo+w$Y5(v?V$?5`E<`59PO@aul{(K9TF!A!XAOPVgy-swFXoJY9B(e z4~m<&_5gO^CXHBZ>|*VTxz@uldtt~F2`2EV*9OEl@ylPcH<6~p_r z2d<2N?a3R~?1<8ViK$C+f@;;(bXt90r!`tL%V_yh2Y8!V1?&X}-hj*X2`w;Hadw{y06KeDv>k$wBW z{=JWMGn#(p7ayeci>gpNaigEi=EL+oq=*^238e38o;HP`p>O7@-p;?1-B7r3asPdj z{U7Vy@TIAv-%sM`PNfoMwZ>u-V3R;pgy-dQxqOr_6kpqS;QmMdXKu&;1^$1{h2Wqf QsQ>@~07*qoM6N<$g35RMxBvhE diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/images/br_ff.png b/messenger/js/easyrtc/node_modules/easyrtc/demos/images/br_ff.png deleted file mode 100644 index 7795a5d9f53dc530e55291a5bc0cc4792acc71b7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2818 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 UCY{sm!vFvP07*qoM6N<$f)SQvCIA2c diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/images/br_ff_aurora.png b/messenger/js/easyrtc/node_modules/easyrtc/demos/images/br_ff_aurora.png deleted file mode 100644 index d16285405c80bb8202a95b102d8675aa74549536..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2621 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 O0000?qR9pU zHkpvY3Pn2UKG-K++x51+-}im*`+d&wkK1*dZP$&M_>U(!Id9H;p7Z?jJkNQ~bKrm6 zv};*>a$sOjbA5d*5sP+4HN7DMQKXm%f(J{=UBNy|1O^ zv8LJ@uqseCA(H{e0oMm5z%U>Zfm9>Z#32$P7X%C`9=>Jy9gn)w5c=W`M$xBhRIx zk(D@3jDcei_$VPbbKnKepMhmB+7<^eKVT#(OW;LJ{65{bN6C&G?b7i zDNv1#i1vBdrJ~=y{WtMhEpYz%XO(7Ikjuj0VAYhRGMGiI@igP6$-EEWvTwGyX}kH> zeR;>GR4n2l&+c>U`efkty#Grg&|3_y8cxTVwP8#JhSQcVz4B=D= zZJW@k5ZE@Z>rnAMYFk>fvjNn0bYv~h#R~%}j!ng`OpRtXgAjsZzQBvyw{4#W(2&c` z$MXn>&LJF|&~*qM8{c;DU7Jt{yddBUU%U6A*#K&ish>HXhX5?Qg5}tlwuLzfVU3QW zbdB<{qiZh6L@s>9#?uMc_Yvt)gyW#3Kq!S00;wbl5TUqY)?Bsb&Y>SQL@*2k)3K3K zAf%k?Ms|W|qMpp@Q|;3Ly!0s1WRf70K{z&2O5~)VlmcDXQ9{g}+@->ZM6ev2Pzt0} z2vr>ke2khJtg$rH01D${#A<4(6blF`kU}DrK!{0z#v~eQPW?&>B1RQJD2bE`sU%`@ zZ18;?vpgLjH!(r7r4_4URRx74R8{3tN>WYD=yU5Qs=$aC*uIC55~bACsFWh=*f^ES zbb!3;(owOnT$@l<0fZ7rp$L_rS=TYt+ypVeFbo{uL&>UARrL%?f$KWRXmmP2StxAF z!gL*k5EuQgs^tsFPK(w>-XeM7E&@>#+#r1q_-@^@j zJl`h_LmK08_Wx<;ZL=vqu=_6yQi+5Jf`FOgHPoRLhBV%=_>F0asJ44??|89@jK%N* zA1?^-13?f-!cgIPKB?LSBA;72>j^9t)+Or_8P{=VEIe#YQB)c&H{SI0G=Mdm9{#o| zB%xF&X&^%&oV2(A$F^yzuNQJG{kd6>;8^;TT?+n0m97<)A`LS5}~Xg|_hRa*tKuK`e7cZ6 z_;T%ah=#wjkAKU*@ z*EPQje*VpGyw?B6-{06I!(>t_>ScA_h(%enU;)X7MnWmbmP(u)9-2Bdd0nTVG|W(W zcdWZ_V#5{AebF9#H!n@olVKP! zT(3?-a~O{!bpt)w=q9?lPF%lqX})vOqJO!DagP7DIoiJgU?e@Iw_)Kn00000NkvXX Hu0mjfy{4y1 diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/images/br_safari.png b/messenger/js/easyrtc/node_modules/easyrtc/demos/images/br_safari.png deleted file mode 100644 index f31d239643ed085bd50998644b1322df61e2db72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2460 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 diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/images/br_status_warn.png b/messenger/js/easyrtc/node_modules/easyrtc/demos/images/br_status_warn.png deleted file mode 100644 index 069039d220e4bb1614d479cfc12e4acab9dea9ec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 819 zcmV-31I+x1P)Q@A(aTg!lQc0>+p=V>e3ZEwMid%; z2@EPKsuhDuf`mxSN_#?)Bvc?2ahiKpyxx7?d)w8pfnm6F&dm88Ju~Ml;U5c4NC0sW z32aJO<5|D5R?>D4JydYodDZ(!;J%EXGG0*E?lufB{4`ENq@?oJ)&=xN`OTOBc`* z;~tttd8iK@;52TtNzgbq-U7m`+KG;7z|g>G&nMOh%Eynt1`w4^H;1^%0pPXJMY5H?R(EgplZPGGhhfMcFF0A=@!sR$p<0~|*>n@e5?x7=rd zc&+c;d~X2qZ$rh%Fa;ov%5qbhPMFuIt@k_u&ME*Oyv#2c@TkVl%-w19kc-AfUI|=?n89b%!r0a=W{TH|L=qEK$lav9rx;n z4ND=NM5QOde%bL7jbsqJt^(n4s-v$1)Rb%#KzTz(P?fYU0FjF*HqVV_5P95)rbnud z&)uM!wMN4gu~ChyMY{lUbn4z+*5p7~4~~4&jblKE!wkSfI)gYBAX`4MkC@2-OAU5daCX7u9TX$6@hq)+OY?kOn|P?7;@O x9-hjf)O-D!73DIzBX{4ZK2j#;Z^Qoz;13yW#vu^$jeGzA002ovPDHLkV1m|OZX5sr diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/images/button_close.png b/messenger/js/easyrtc/node_modules/easyrtc/demos/images/button_close.png deleted file mode 100644 index 17bb3bb0437b945011bf4a0ee1e3e7e4878defde..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4303 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 diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/images/button_mute.png b/messenger/js/easyrtc/node_modules/easyrtc/demos/images/button_mute.png deleted file mode 100644 index 9d4e4dd89f825b0e577d357a8fee415ca5a60227..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6011 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 TQRdeF{f{&^vBuUwp2YtE$&fx{ diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/images/button_refresh.png b/messenger/js/easyrtc/node_modules/easyrtc/demos/images/button_refresh.png deleted file mode 100644 index b94e832c8765620f35e3edbc4f5dff2180f34d95..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1619 zcmV-Z2CVssP)6?sRu&=eI9VR=1U;o$ia>+5gNn&)oNO-`DlK?&rC$ zDsq6GJV3kIPi@Z>S0oNjT-6bmq2!iwoWT0Gyv|=#g5j*;mjwR_GZIAUFBB)L!5_ICQ=Z z)rcR1=WF!tHF{ky09NT93(#d>q0_cZyLE{+%MuFn=2PR?oX@MZa3EblL_|cy)Z#bn zPghVVcZUXe{N!2e!AvDB19J>ceoen;4UJ=&CjAU|yM5H@rcsz4(d$}8=UheOSV3i7 zLO!xctI1D`@ezW_kJ=vKUhfR==5??$Q9`kN0;%y)Xn<;+BQm>kn1RV4w>u|^&sVcM zrIp<&twblwh)$NVJ6T4oSRk=P&-FGpYR3xQV*wQACF=U;xv750XM%^)4j=XXb5v*_ zQmdb%X>cJlzz3JrNC##)U8rMks=%%!8E=Xe9L?+e!HxMfCibTbWRx4Jx<5sgZk8_; zUM|Z#}oR&hIvZbeO#2f`F-;QIgKuI8eIq`KRXkp+XL)LX(dJ^oB}j<>RLc#ehic73a;wdJ zT5AgX?%vaSIGm%RX<&iEwg+5jbdg=}&7W?W4=#0qE?0yz?8(t~_Oa^^aiz47rwgD_cdgVGjAoB7$iV z!Q@96@gpBuq}{qqmu;CnDY74xP}qt}kPxngbhKC0x@B)9wY=8RH-Gx>M`yG0_*rNG z+sp>GnGHs#H?T~tV|)-~a5Bh{H%Nnih69<3pL~pAoq%?Z;(40A5jSsPJP)+qhXdJl@D?47|GQR&Q;nuTVW@;+Cf&G zliVg37aCk7-?4J)`Y<0}GjgJIm{Vn=9KUJdccm8Ixvb~y92I~2`#(Yh)a$1?`24Qd zw%gd3){5vWBPAU^E=k>_+;xyxVdu;p8=sWh_~`cNOJ?KbEi1=wS~+&z%&}4nM?Nz zI8kQh_)QDPZkRco-^1Qifv!P!cmPoe5>$qXt;HUXhq19SEEWq&O+Tr{9mI&F9Lek8 zc#(m`ugr+5?1-uzoU3&3QJIAgiiS9xf1g;foYPmj7#^JnzkbxK$6r}IF)@MNZbz%t zZdElwsf@o?DUeXm!mqPhh)IzWeNM_R&q|3+lkt9@f`SSy-Fg#FrxUN&`_nt1*X#XW zIej6uS{PU@7Lr+f+{r&wIjYe!X+YX1r5$W-G{xj|O|N5WNKLJZ$G+uvT RXBq$i002ovPDHLkV1lYhC941c diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/images/button_unmute.png b/messenger/js/easyrtc/node_modules/easyrtc/demos/images/button_unmute.png deleted file mode 100644 index 3689d4c12d31d3e9ca83296665a31cb86980167c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7915 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 diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/images/by_priologic_logo.png b/messenger/js/easyrtc/node_modules/easyrtc/demos/images/by_priologic_logo.png deleted file mode 100644 index 0fcbf92f101eb8ac306a408fdc5c3039a9c9e958..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2492 zcmV;t2}AaYP)FuG00006VoOIv0RI60 z0RN!9r;`8x010qNS#tmY3hMv>3hM!aiw#-;00~@4L_t(|+U;D;j~qu8|Gn8=l2}C3 zBo+_^>_CLqP84t5>h8 z2C%TOu&|gQ2B(hj;M5Vemaw?pP_ZVkumrZSm=I>=Uq1fn;V;kKi`PK(9WeeeB>LHd z=Pv$T_2TuX4lT@L<|2r%`qwTkG&~G<|94{H(A-?*G8peym)0M)X0|9L0)OsaI!8p` zBj7$FJTc4s=Z{W(>l>;U4=!D~%;56`didK99X_#VRLtQx05I_z*2EU25txC4TRc4c z8MeR4z}q0)e-CC}hidwf!&4J%+`nifEe3J4Lq>4 z{uY3L66ncKP9FI#@lN_M0&MzVQ7(bMI^2FV{Q3R^_dPE1;y~BPi18}`m?3_az&~JM z_$fwjTJu_zO5hnD{pR|~g@>-6SU5Dpco_hg=`CF&?_D|Y8kjdg^fZVZfdBfHr7NFU z^IDWjU=VK1RVvr!<|>zo@E9}yduvF));03@JMV0dn0`wDiHQ71Yg&ua34D`hpJ8B? z8J~f%G8_$$e)08-ADJ|CZAiao;HDS}HvhFK1yoc+n@=tLxI&dT7`*PByYxsI!ZWi6 z;HXkDBBgGFGh;clbgcTyx~Gxv7!i4QGMOU!t`bpW+L2**xp2i!XfDUA6|OZn$==5i@0p_#=jW&l)-QQmuHX5hk7h5ral5!mo9zH zn$bcakaFPQwjl6?(FWk8d}kaBi#5w#0DueNm2i1v&2a~;%J~)=)*{oG16x>3ItONE zH|GCcA_~MaEdWh11y`kKHUM}4dPLMSh)Oj8Erb3X@my2Ns|ElXMC3~{)l>};k((k? z)+OEQ5&ZyQ6@V{v^h$`_O(9Pmz@kDHPqtOYK5C+mrb6dc06o!1U*Wfah`Ne48&Znq znc7P7bwl`bQIexC@hgaHAPx;?t~0aGW(agsrD!v@ztDlq+)sK&F-7lzq2U@yZ6xT} z97hTv0jx0d z8Py0iG;T{;2#hnzxd2|w@ajB(WoAAPpcO`_G08I!(Z?5y)jIa>Je~&7Waiyj$sp2s zF;U$Y(XK8&^TO}T%zUQks)CsHx)E7?5&30=GXwxUC-iOZ(N{A9v!azD0=ow7=8nK3 zauoqTDFT{CV1?fO1p7HL&({q|6P-zWA~jG3l8FD^q9QOe*CK6S)!3)b%oifFpkqSd zJm{;8qaiSlo50N6E?CcA9s(=u;hUrd;=O*XQ};jLF$pk=!JqsN?<}~@K#%7rb9C_wy zPJJCy0@qWF>?mp(3G9n#*@(RB>%BZWaQI!D3`*!}O!C(jnrbAZH(W3Ea<9 z8yC7PGxLkP+|otfl&kG1+8GGkHB=@of%~Qd%^+H82e|=(dnT!f!PJ_V8bsu77tlv0 z0*l!!#7bEk86AUXl1Sc6Dbsl(YN22V0>xER&KlNKi_{YUej?Yvv*;zNAZMjNH5B#U zdFfBRjD4&Y;0D=7XUib)s!5qh6s!jcrMNU`V?0Qju1uZkWo$ogK*=`j<EDBwzz?sc0)maKJQ^5KT@ZT8(4lp zePqRA#FnL`5T+=ipzmXRs3j27FF?k{9MPyh#da&wzlFivTBoG*wdL4gi+5~5pC z{S-mqAY;(TOyGuL1aJ~^z-hUykVG)k(`C&9^Ey9cnx*rTuj!{zKp$DLR&aY-0#{A; z%#mFB@~4ErNoA^*VMIvM)60;z$_{Pi(5)4xXA%8~fjeKY53gGf+Nqib)>DdTgkd@?4IK6hGTHd(>0J!Wj`lkzivwXjow#0 zXMAWV<_w4z^Q_5Ph_0?3P4wM82qga_&20ovd`!*?x2B1}2@cukAnBt$bYv)B!@%im zn6kwkb*v?&0cmc}i1vFCn-oD{hnY9i`dp!}n}xt>(9IA9%OJ3m;);~Xndf>Q0>|jl z)1+;xt4A#Zdv#)Fot9`b{B$A#$}93pk%9v{eQOb)U5GxAbi^>rt&G?yYSILjNbKb# zZ=lO1QxI4+sQO~Ikjdr7$lXd|vsOx<_Jn+e-iZ@(Y)16$L;h6F6eI@HE)P*wb zn0oI(tT0`JLmEj(^U`hxqNV?vgEMMPHp02QSQt4_9Kqu?P zSs{NLKwHcr;f2xg(q~_>dumd-2qfPI26FfSj)}p28n>?1N89uO{7$u_OJM|#=|lM) zuaRgHjPV3n=@1Jc*@*o~ZH0?yQ;#^^n~*FW?A!_lcFt@!$E>&c8IPnC0u~n7cM;Q_ z7P;(KOIaAzUn8kw&l1>Tk||PJ$P4q0DLGweQ;55eykQB=&9M{LnnuMef$t6i2dcWO zDoP8o2c}=*VhLJxn!j1Yjq z2vV-YuPojB-Og7x0xx|PMHps)b^QulvschkfWdwwke^!-!C-KhuBM^#mA$vOx390S zzrTNAU|?`?aA;^~czAeZWaRhn-=m|WV`F3EGN?&CSiNtt|+Gwzs!; zc6N4mclY-8_V@P>4h{|v508$Hj*pK|PEJlwPtVWKFD@=FFE6i%{a^XN4E#@LpnBvL z^Oa6u-ul`GSF`SabAcHglWE5tvqdE zx>k;^-Uw}F!`r?O5uylTA)y1$To{Z~P3?(-p`ZEIXL9SQ+KOLt0v3cmR=*X=J*@PM z-RtIW%$;9eb`;&}?s)Ff^y|rbf=$m5L+n5LikYM@_v z`@;ZK6=qxhuISN;RQ8$ZQd)~cJiSL@kO*4PpP!`V8Bd0c?9j@t!o%jKq@=c8cpzr_ zbIWYcUrh)TRWzgSl3DNZjji&RGxa zx8|c0c_fpmFQgUxgUHZw9WGz-1QJ}%2~HD7O#zaLdgc7H@~5QT_Vfp<#_ham6KJ&P zb?IZFftsx8TS%s9Mtce9M8r-)-i^0_Lw%_oL}_?X&-74lKz@bbk1$GQk!Z103Y&2B zni*r+Ce#`D?70MgKy~-@>qG3;-#^DlueWp6^ycGWKUS@@idlj!!?j9)vEt^Vhw~8| zKkuo2mKk)e1z5yDZyEWJ8^^1rw1Iy#f#h*)BGMZT$`!OS( zaIow}f3(~QPDFa5#nd{#MXerDB4njCaB`a9^Rk4xR;9XlAk)ee!(DfzX|_|*7Z_bA zUnVmlcNZIh^gxe!C7Z-^oSzI4);$7D#7@#}=KdAMR<)9h^_BJy>FN9%;}~ibHuNm> zAIn)5#i3qz-{i(Yij7Cvq5aw3KFZko)m4{L@s*OlHkGt4M(+#O+cZD__^0za2u{Sg z&6#wkQFjF*!hu?FxsyneR|4i?es4_9Zb(*rIaO(h<91nGi#|9?z0;%cd=?_Sg%-?v za)f1RZ#mta3_w?JhwLo`%|*DLz1AcwOswzqA2k4$V-?{Q{3J&HT6R8VHx78MZoYf5 zp+Ec#2o##wfAuQ%Cl)j&vf7gz(==pe8?GI=6~oIAIjP@wy~Tf_E8i%(@_Iy_=bgPRpO|dh z700W_2}*4S+;LFZPYDV6Qa%czyoHVpw1+V6PTP;;r?LVinVeONUgM*_l$FMg8AY#4 zi1%OiQD8`?)*xYx8O+M6EN z0_xB1)XgoYg>c;dd3;UcC~{c*ar&IOc64s$*F0qQJEypukX@%XS+p29iYudC&C1)9 z*%V3j6`yyvQ>$6M7hh|yB;?W`?=*02dIf?mdNVZ=>%+m6sb8mbXZq99*Q89sY_AE- zT8W-IrvsO3d>K0`wvVX-6~2T8UB))a2Y!&6>^tqxAGo=vcxUPDYhSeW6!DkH*~i}#K{bXuKoJq1I|^yhdcETMphnEq#L z=8%K-B8Rd;yQ%J|#;oZwr>#jcbeh(o-eR@I%T7sbm+MULFOS1;r!TII*v!7+*O$o4 z&ACGp{Xp#y6gOu2yQSDyfAqxc0qYje-iz$GpA;bm!7^^Tz6;G*ASok1rkcsM8ix6i zUNtgm((0_G4t6_Ef?8%Owc8)_gZ0N-mDVHPvZ-rkru!V1sS9Es^bN~C+{cKwQCT@A zm8qetQ4E59N*52q2YY-+G)ZRT%re-Ua{vt^^kRb*+ZKP~y7UH7zDSQxUk%IG>^6?u zBNz8sGmQOb&h~#lHh^5m?rQzbE>@!JvVEv|#7TC1TxkYU)BuLbkCwa}S*PV{S7K}1 zrPFpr7hP!u&r4t3-ihq;C2*2?c$DET7Q-}?cDbEaln&_8{bcQp8LpOJvc4QcwL@lEJgD%gc-zUI?R8w`OVsd)5V~k46j46mJ@gvAZsHy??0{R1|701>g!~PLMLwqg9_6z3uhy!bI*c-^N4I2+Iz zILpr#fSLFvWs(1kbK}EwgDwWdON6-yY>!HuN_AA@(7=*@0>JSgz_jIx1t!_h;X>f! z#`kvckfrpD?JBN)Ppj-XLvQNXJQPbufv|JD9S!QBHup42y^@)6pS|dzi=jd4&p@-5Tqz`xNk=o!PX?pOuL|%oySiKB~62%i+UyQ=KtTy-6SQK1`%zgrTMa-ZhbZ+#q*rp z$d&=ytMctd1T}BWyNu(@vhfZ16Q~3dd*ICq=WY({c(N~G@T?Ya(pqrI=U@sgO0TT5 zSGKhUN=f`)+L3UNG>TjB{{cat}p#0DqMGh#sqRy#EZ`O2i=AN>X2Z5rByWf_c(<^o zw;8jx)=7}#jh$+eqNua20TwNp_8;kTK0@{W2hWltz`~Flu=|z+zkePGM3MuB6y0{KAY>h=uyeEp)$Bi+F7YANr_??thNaMx_QTf$VwOi*nF|uaj z?;nWZmKms-NS;UFa}6Vkm?qTSk%gT%Hp7{34vYUWTu7P2#NI47ARKMduHBHlwB5}@ zr*RQ)a|FA=?k^W{u?pMlXZbSGz>Db+iqyvSMWAvU%qcRJR@&Swa2)l7BFCJVvXcgv zy{U$#5f06exJIc{8~27_l#*{%pL@v*@~mdN3et8!O=fDGWqGCH1DIWcbzpc)0g@SF zHvf|k!1FGs>_CQ~7>>A?|CnnK3vl_gy9H~&@L`1JKLQ89**YZQ=O^;@?oB{I4=Stp z#2{D+=5*%{+Fqxomqp0*Gz2!<{(*32?G}10-db~19^An{IVMF5>%pV`-bS10U|EJ= z4ywoz>&kuLa_2y!m7ud%hyAc(nwgY;Sl|s7Ri~!(G&zS8E~J>YX(qdd_}(M2h9v8|A*uN0(!UQSy7|I{@Z)^+=-@jJFQ!(6 zkeXRMFo5SoTkA8i1c&lXy^CIT@|_dvh93m1x`-}xaaVy>_Bp5SJL%HRMTDp4oCqH)t3NA2R-IQ<_bA+E1EQZ=(E z`b2`??h;Btjle5id14ABdu?5%3Mp_I<#g4i!mmd`wfY@W;Ag$AP%EaJuXXH#bBgGY z7x4#LFd_LV=~G#>zrsQD(~!CD zOgAHs&UA$%mZ;F^N6oE|MJ?aI^B&q=dtCzHjOe7VI?}vBuCliHdfOunZ9i}z0~2bF zl0BdOkk}3`<5j}anT5!TZhc5<2R{!P$pn+Y`sDdryya60u)qi0A=4=p>?5Z{j=KIN z%5`shodst3hSO2Ch;()ylIn2}CDL8H|MZ)U75XbvO!cT3tm#IOyis!M=Mh~>cC?^S)>)M_(01H1m2Pn>fp1d`yhK)T0bx5@K22gw_>+_m zNAkV}h5lA{tx15UMnj4x7TZhSavdGUHY6-JV;Er4gwiIqR=8YqRpc|)%;HV1~pZf4GDr8~e#Hx+Cf z3Nrm6PiNv!uP8SaD2qn=rO|vip95u>G3=O;Zzx+q6#UIZa5W4Ix;cVW*$=~7yew(f zt@tFMJZ`G;cX`3L{eQQqT3ibyN~~2r-Oi&WF@8GVuo|==rA5Bc-UGjoFmpDuX915k^WIWS!m}mE^n6=T zJL>L4OS*qZ(aroxkGYbYt_(X)w~z}<*xoSVjBUa|U7jy|GH$hTE_6*I#gvUDZDGJ% zp>DL9v&=lgk8^Z>+;ngn>e+r7^gE5fk`?k%sz=9ULYT-Ut^ei#FK(GV@!AXG9ZA+m zz@4e?M%8h(LZ^Z7Rh24e^!5Fjl&c;kS&y#MU0EnLtqppwl0N=AOp7%ds0NiEP?g6l zx-&uH6ACUDW3E?pC2fw+Zd8MXwiHMU(ohrZ_v>hBB+i%V>~)xo`>}q#eK>Xt5wA{g zB+tdi(NR*fg$R%&aGtw&p6)Kzi8>g8j|+V;_*vzfb`{1wdLG%p2upVF%Bhv$a|PmN zhMO1%6t6T>YyF?TCCG1i;*9J~*5e3-x=gwf7co7=8&`D_jx=9-ktJ;D0NXecZb^l| z70mh{e3p1P2KyKh1uiCXcA^jt@^Ev@Pvo3RSpfa*xbF?@FoWmUZ|&ih;X=sM0GOr+ zr%jhvns;XlvrvCwBIh7Vw%;kw4HnATASD75C%uYnSAd#`XL#oiEgsk^#shV4aKrz- z;7V>HHPRCo5wvwp#0}kv&Go-gJ}pz)vjnh**XXyi3T}CV%I_(R<&$gIXEqSqZkg*+ zFiT={E{#*@-cpTJu94MU=1>!dsbwc_gFT#b9>GTy(T?BhUzTdlESSH^1e3$wmZx$# zT9NVN0-eOX>hFg_aUD3055 z7NmaegYLmMD4;A^Wn&J9O6BG=fcvdCa!Bq9QE&g%O8BB)vjC~TtJP)t$n)h+#lhWi zcp7-2n~xwQwj@BQh!5zNrqAaA9Bu`e#?c8v%S6il(E+mC+-W#4cu|k3Ti6ob`1M9n zKG^5k4O-LH6l$#EdhpAKj0!+9Ijr~Vg{OMu&Z@a+CQE?T`jE>s6;JdNyJLzXF6a#fZNh7-zYmwf!(xiZG}{O{rkQG&)etny(uP}bp}{I zK^2Cdu)PdY3uz5EV3qFF^}WMTIxrgFd=h1Tr-{s0`lR;5Gj>zOZk+sYxXj?DheP7yJA%!NYr$9nz1x6IO}Nvl7CdSAfzK4D;P*jsYHCEl_C5N-}GE?ei=riB?P)4aGdrO8%BiH7LtZg*qvuM59`` z<#bb|1!bskhvxz}+1E^L?*{GF)@szBLx&p-d2ec`Kn7G;J~GVe*DRl}Po2d}TlOB1 zV~=(hb0vgZsdXP${$5smsNqH1`UyOL6nyR8AIi1gvmP^uDt6#HP#Tc8VFt4dUuNkf zza#Bd6-eZp7LX@Ke98_R9ehSz8}dUp%?cg3cZb@ABTSf4mbx}x&Xzx}8Pfk+(A08G zs2yGM#e=ol=+UTc7m5m-%cMcq#7chOe$A09jtjityZh?U1y=l7xE-MW zUOHSt+<~%;Pn10=V_orruS2S}8w*R$mSnC}cU*n=>)(2(^>*C}=78bt6rmX>+F+t} z#2(PZTO~DV;lQ~qe>IvUM+d>M;`B+n_#KG)Ru{^gE(&P6F`BG)u5#u_J%XZ2`LRs$ zF-&Q^)E+sbSPK-z5t(ii(rp$8;8^%rwj*#`Lt~R-1e!uQI>DD=4#*mfI6BoGLOS=n zxgS<(VBs6Mi$^HI--APv9`~D`Y4@B7x4Psnit~#h5QpJJA7i*!(fMv9@~CrKLk)v+ z+x1(U5H(-p-~4S7d9Av@c>Xpva6jG(T@ykJJW#0D#MZP}OAv>H;I0jIeZIoybB%Ec zx5(+OtY*lQ&fuj9+(%@YzI8fc|B+%%uL4|zGDr5G`?UTg=1UuZ;L=s8olUsZ+Q}i@{`;?pWYazH{XE3nd6m<@dRRdlP-6KH&Io+ z30Z@JcUfzI?V-R{mJO0?IjnZFG2D=hka)B;8aeDKjJ^HRTQyALo;{D7vieOC_FI5zrply{}=@qYL z@PedwZ{ouvFviB2iTzI1PKU!w&uk1AHEDhT!wwgrI$IeEFzjsKkv&svn$|PMQ zk7t^BH97nF>MPTD_H{-clkiYbLAF=ny>X6EHPUXrg#iNqvkAc%&$Nh3`fhXgIBYg? z%~Egn{Z`xuGYG1NTgY$@a&UUWkROlhyxUy-%o~>~B1>`J$fxx#Ked#m&f;a0=H4D+ zz211RO}Gs9ln(ZDb%GZm9>(mBT;8x-zWX6_U(4US*RNnxjX60du3Q? z{?T&0B0M>z8KLj|ye`OMf3Y%xAUw?xaCCgc?h{_n@^mVtme+P58NsJp%u{=|Y%+GFP zyrKbGi7r1xLIZv^kxQ$TO=~gmedC6o>|gqa4O>-M1*X z9?0RAT+!TsNy1F5eOI=6i0F0E*-<&aY3azD=@$9tGjl0O{DS$@=Y!<4`3^UJWt7Mi zIr>-2jd|tIsBIk232Dp^5+SMBTqk4lk}@psm9@lQK8npVze&8eJmRcxV&k__b!w3B zp_r=qiW~!{+&7?R*O~V4xdNG_w*2rn0`cLJ;-a?rbZPgM(G{N9K6=hq6j|g_?tcf z`n0Yu*L``940=dI{lI7cZdq_4W{xYXo78Ln?x+4*jWBq>N$u5fL6&M)t^j(_xV!7} znQg}%Fk$s?^APk|nWu(f!bKZ%>7Z^7uc^>N%Bak*LdKKrac`37DtD$?-aVj|2#Z_s zcxmPBp5BA&w+FqF(RDkfbQ;#t366r@jt@l)v7Ct9j7sqtj^OBk$@&d++U4&_MP&a? zZzM5uYwK#chW6S-GvjzN;??VWT{V8MvMjPsci%;DHySKX>-mtTG7^^ync7%O zJyvZL_~i7(qk2h~hNizS<}X>gc4{i5arOcHCe)St=Ih;)lRH2brIN?OcP9E6`goI) zoa!j0Myi$6S?*ESZ|=y7wc7M{4GH{D6(6QeUYCdS4^k{^6kZ(-S^gp&V`*|jn(|Ak z^)dX@l-o;dW<+!E-ZqmQxsg@eKRf2_Uh@6m*&~w5K*C76JBM~J{kDzz|2*E#LhR7~ zJ7XgA7GOQj zzcTK|aL+z&{`)6r+oQ8~V8Y}H5IP3Ya>NzWeX@D3lW2M`k<;_#IIdPzaf4cf%EZt- z$aC#RlU71i6uL6qjxHuk>|CFpX4QBbQ5n}6jG-AXo2K*(GU{USpLY+c9QtlpP_MQG z`GX`=W-pl{Hi^CFBY&5r(M!#X;*4G{36wGskJPb*&#>o2zI`aEXOr{D2jYm*oFEUV zTo`Wk#F0PI-xhH6Yt9ywT@oo(UX>R2YwiSj}^##LM0+%XRD>%JrS|# zRmcG7nUC9W+kfK;c38s7l-pJ3o0t!S6#VKOLWar@9M@fXP=`ht9VU-xve5~Wl0*9J z$JOH98Q+$f@(5nFsG1y#(Pd4u2K~s3WU0dff}Or2lF&xeS7({qViAm&$&HEPnFXYU zYvB5X)*BQI8XvG5m)n#ajHV01Ox!ZcqVgA=!_dfn>68+|a5eI=4hYYf!ysmB8H0WT zjLp-ap2b7wF4;x__X(j)Kib_*eWudVc-Y^nf1 z4u(q^kpjjbAaI_6030LGY5-5PTD330N+xB40WSiWD&!*|002Y)BM`My7?2~#As|o_ zRpAq38zcbJg+K%ZVp#%UlmuX~kcEIid`KWDLJR@|wGl)Vs{{n^vyxPldhWsTnFN`p`^ z#$D$*+kG--> z&J!5CZWArn@Cwz6xMW`$hPcx($Q22>cs<%;43MIf`E1u16#x6N`5K7x7;k>gIEpKE6WKTs2DEizYG($Qh4@EF(D?|0oCn|lvfV&8 zd+q03>LJ|H&V}o~@`E^!C_HhzcLun=P3Z3|l_N{7`+gr3$6EUvTN#%7{qfHM6FCeb z+}G2MypEJK*@+xPAdGf0$BF??@EWm;#2Eg0f+xK%)An=JjG>4Kz0z&?ZO7#HMG!>5 zgaIxNEh=9B@{FGJe(WhWC*=khUbw^oJ;|$U8ysS(BX5B7zGp38r|;6oZdjxvk(z7R_!%?R`G|4 zFb;lasclE@!?2B;9BG$xl;!qqlFH7-t!y}0rbWg|4+5|yRWW@!Mdmt)ke#j~lO><1 z4e}uFc^lx!o0rhF^1v&Rw&W8y@0bB1YO=?3J+KgI^WOzytj_y5@0$zv6K{aoU5(xg zGNJ~SClDs+!KlpJ*JMi3*<*`JypwCSpF7IH5E(0-fUDZukP0MB5ZCObkh}Cs*n(9n ztnH>e*vI8I*#i<0q^zEB{^l>WDyG!=LZ~Be4iQMa%>{?cwHO&D6YrfgkCVoM8{5k* zhahs#eozLEjwDeD3b2|a_MF)u!)THRtiFdjVgjU&UE_Pgx$DB`3IO{{0;az+T=t~i zzoeqlG!`C*ijI<=5?NTzL5OoW?tZFT`@-b#&6@&VdZvDP%dl%jSpkAUmJ1z^r}>+vj6m<)^o(l4?BV=bVB)=L;a9W6Rxd5y0LlA7& z+y$v!7qgpxXIbo-h5^qXUx%DMG~rTXbY38}%`zwaS|tDi)u{G6r#xM+L^3>&74*Y9 z>zAO@MQF(g$(X^VNO);*8v5F_l#>GhN&-5PJyDr>lI~11iA?Iy6^`7;8a6Om0NUoY zQRL9!$e9T_duXF3z|7?_uki_L(AF)1ed6z|wNvx|suO98w!k+h7yAAkEtVW@-8MYd z(~hwo9bmzzr%WDLRM>qykV4OE`3gPI=n=@z1`pZ2i*JGua;Z(8f3O7C+q+o2C4oYz~&gHb3 zB8KBWJ!O5dJ`YlS0#ch!jbgDFWAMNH1oY20#(bw|hT!_wO(*E>}G zd!cIJ)xmD$?W}-WW7}%6Ps6MN1xtDo{KQfoR9)9j!CQwSZbM4<+uYZ+;2vm9s!Tik#e)cY?_+;GbliYJ))z36kRhvqFMsV9k%bp}U*WqW1 z04a{+WD>Nk|Aw~ZEik7$X3=3>XQbNUS@0f^mKjO#hmDIRh^_-Qs&7)49>9)|Q=)t$ z(g@RgyRoF8B1~$DF>E~M!y>mE(>n5$=N-T5tYGb-h#9jnmZfXJe7tMt0 z@z)~C-@a>H!V|edGx`9Oiv}SORXIy0?&(0-R^r6hCnLN5Y!btwLLd5iJQ(iQQ#$E+ zfgFTWW(e>|p=EoC4j}miv7CbhzuFWN)GGrE48&B=EVmMM4Py+(PlX{OG!l$s z2hUnX)AxKDDK(?2)Ew}q)JnhHo1v9MF~#~S10LK{fl`t|l+x~@N4hx=@o5I;9&QOq zdQb;>OH7HUJ@*k%^m6P5`85Sb(V?(_hzQESv6h>0#92zuj~r;s(ht;;Wj@$(<8P zsGMRP-UsF4VUf;v?g2;6bZA@FTQuk5L@Ooe%udUeg@3b zI((k%kyqe*Iv3FDSHol(ZJI;@mJd!t?)FlIb9TlM2pYI~w~h_{Wu$Tkz@XMDcGcKf z$N)^r_hM?#G~AYHpuO7kePE@NvaOp5hZE_`zmA!KP6WO=cS7I4GmegPq_5i7DEFvt z!~4+n;KzP2jW`j(e%0-f70L~S|Ha1;+`1uFWH~cnyW!r(b6$Qg%I+BwS2hcd$yoVA zWNC@tAnd)O_R8F{6A~65@IsNya+%yS4bwa7;KVGEWZn^A%^_d7Z+@L)@94yKX%5*I zfNmHu&uP`GwzW(6aESFcD<gNJOCG zB50e}#3#;ce+55vH0hg<>VtbbaNL;XH1&-Ec%`r$pLu0SEOmWebD0Z%&f<=#r6XxM zNHs@RK8xU|Z#SK5V-mEj@1Szc-x9JI)j2{ak^UYP^YZFdx^0k$dU!mTtrja~bHMxi zn*c*^mL!?mouN-_hbjD(7(?FwyeJH$ZY@*~)xhTAZWxlBlANePPwrp(D17s$fuBCw zfF9JYv`mr^czYSVk4}KG>l4dO^U|N;TlgTnGslJA&R5%g)CL5zK|i#$&!gF1z zTr1y2<;Wjq$HRTxAX$M==cYc^=g<>UxZ_{vc><#Mr2xH)?e zf#iX?Tbox9a6<@15JVtM5LaXsH6hNcgaiaZ&g+3{)4`n294i#zl^}>fc%VA>FxLk1 zHw&Q%f(QVBXTke1pK0%}5`swr#Lpij+ah)A116untjz3AD1*m99X%1u=?O3WCnC^^ zLqd>(Am=9BvtI(sNMOTM)#5?M7%JvZ6M_^W);Wp`xiQgi|3;L*5ebqC?QPZ-TaIwGdtkAeNd42-KN_ z2zm$z)Iksiv1UO)pjLtaJA@bn1ZpS9^UZMskAOgmK>&Tq0H7qN&x?$)sX`_K0zg%5 zodC3xN+)Hb)#`oIh$sg{UjooY;x2IhdJP;U;5h=hGFI(9^MBXcPJQch`%VA=002ov JPDHLkV1g#_b7lYl diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/images/irongrip.png b/messenger/js/easyrtc/node_modules/easyrtc/demos/images/irongrip.png deleted file mode 100644 index b4df134dee0896f31dda02cc8773a68a263e771d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 56156 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 LNkvXXu0mjfZuDE* diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/images/powered_by_easyrtc.png b/messenger/js/easyrtc/node_modules/easyrtc/demos/images/powered_by_easyrtc.png deleted file mode 100644 index 989c1fb4476b744019afcd75d1b29ff951bed098..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4178 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 diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/images/priologic_logo_white.png b/messenger/js/easyrtc/node_modules/easyrtc/demos/images/priologic_logo_white.png deleted file mode 100644 index 1693dcd7357bf55acefe1476184727ba398fafde..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2810 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 M07*qoM6N<$f+s6bh5!Hn diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/images/textEntry.png b/messenger/js/easyrtc/node_modules/easyrtc/demos/images/textEntry.png deleted file mode 100644 index 83f9ecbab5300fcb027315a631dbde8c14e6df7b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3232 zcmeHJ`#;lt8~;iUAt_0*?s8bdsHkO18FC1Fh{riXp_JCw98#8<9njduuzWRIvKZY% zSh*{8JFdoEQVw_JwmGJpBBVXL@4w=Cy`JZ~-q-v3T<`1i({;T*uh%Ej3*)j;O-~H~ zfQ@dhPN(D<`a4t=<@{Te)eU)4h(G1x0Mv+K6Y^qxG};pl0D@fgAK^*>pa^(*_@0pK zfUVpCAWH6lEggtz0O+va+sGsn@C0 zR4Nruqb1X5S823sEY@WX=M0Av0YOn5&RGs8ip`E?voEsQaS#*(LFXYTmcxl*GUJ&{ z9Fv*AVqsYazlAMe?H%b&-df;f_S_TK0iPpz%(?tH8glMH#-Uh-U5LymwSfG zjie6(4KiSm4#*mSmX>4f?KZDoS@rgs4-CKuWq@oD7#{v*d|Y>CX4BG=s!S%os3CCa00f1TtBEAX2GvWMpNLva-lD8i_`u=H_PR=4LaQa?qH}92P5= z#iFxV3^qHD&CX}D3m}LEL4_PnAq24@sF=fHb2xG?;cz%yF2v=^xs1!@@_2HT^Z6A# z9*@tz&*$?6f+~TaMj#OUJ@)_Gf58N3Zx^=7-wA*_h4GR7ZyVsVqym?(WCPYUFdhK5 z{1XZ{4TUOlQ4e<_0OxZ#3YQcPo&&tX&&S~`F(-U?Ct6z`vOKVV{{mPB04hsvPH5lc z&}nEotQQG;cDZ}5v;%{F57RKQRr;O48_ZWkHuWt6J0TDDcfhB=ZFF>dm+Urt;z82+ z;tHf&dv@wauaxt1YX@^Z^Ze*Ki~Bv#=EZKQ zHLo1;!V2`q`n@Ktz0O2Wsyzn+RcK!_ZSNKqPTc+kcjCHP3jK$l8Q%4!t^|DFdgrwv zWk`fIc0rGfcxD7^l_(E@gTn!T{P3`PyA0g%y<@tBgkFYiaC(Weqr~WpcUGU?FZSB@ zHA;1}=nux=7l;^8E$D4jV2FC?>Lv!xRWB3Q6lSx%yX?L`^x0&UJeGg>U+_k}_Fv#L zex<}zQczupEGVDcN7vkSe`q8xr?$Q|I+ngwmp!!hV7D6OWwm|8QDbl_Y4^Gc#0QeZ zhARDnvWUA>fN@L@%m9;gKShl7b~h6azM)Dm!P5^U$+}93>x6G=s?KjA>)*jDjOBHQI^qYizW8Kw6Wjb?;a>lfX_mSx1mJe>FMFVF{;s_5q*m@Lf-wI9#zhmb8X=7$0dK&^ZnHF?CynGt51Zv=i9VAakk(O5_ z*Z|>B$WfQgBGPLYJ%mYB)v^Se$`UP?>{bFFP==50LR2*CYp4k$&4fFOUMmajelJ~eeUq3tan-du9gKgL=l=LEyJU?UIq9%2nV9QB3b*Ke^Omh;1=jSGiI_!!F)~y0d zmw8r)(x^45Pa31^EXn9TwDP`Cf1mZeS_{y;s!*L$MjsAEmWX=a#8PLNaS<86$blwJ^b7%2RRaPq}OUJELF_B0Cy|bXX|K zlEPY_fi5W>3u6`7iy7*|ewx}OF;d>6ef8zPbhcsW547i!|7nHJ4PA(2m8lCg5z*z@ zSOb^a-#M6P$M@LKgJaI1%r9js3i~(8TNYP#FLhpa5<4d(?Dj8zQ-dTIFG`zZo)5HH zKTQ<|<#qM%#Vty)3@*4$tt1sSXIs<}xEI$ab(Je~O8bHW3XM+WbOmlN3Mk~7Yu$&I zGae-f7h@Ovjj)ySEnz?Eh}hk{!2mol{RfG-+51^B44pD~G_sOdz5c-5xh%CkjV)A$^$r{O6frR2T;I1w zsn_8jL211->#le4(-sRihqzNS@o}f%nm)}Z5&Kt*cA$neVM?7f=J#R*L^0ucm#LrC zyjuenK?-`DykQt{4;!SQX}LUp$1! zUWj^;51XtN9IM!Cf;QY^(f;R$pe^rq5u7}N#HFT4(j~l+6&O=q|F2!fvybdcJ^gZ? z9)54fPHhQ6;eI^jZ7uvs?%k0Lj(aR8j)mC|AVP$Pb%&X+n`X6*OVZ3Kc-cBjv&V|;s#rA{3?Z&aPiW% zYYE4$@=PdRZ=yb=M2Cz0N%vsl!EpDK4`+D{?$%4F1>5Zpdm?+gm8*ql_zI}H6S<x@~q0Ry1+`SI$ZAJRi-n>e7lHvu+{5ewA2vKq%c`+!7iWoA(8zD(Q}Li(uhN8`b;n>NJHKMI6DR@mZqHiN& - - - EasyRTC - Landing Page - - - -
- - -
- - -

EasyRTC Landing Page

-

Congratulations! With EasyRTC installed you are on the road to creating your own WebRTC enabled applications.

-

The easiest way to run these demos to create two browser windows and open an instance of a particular demo - in each window. Please make sure that Skype or other programs aren't using your webcam before - starting the video chat demos. -

-

Local EasyRTC Demos

- -

These are the easy very basic demos.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DemoChromeChrome CanaryFirefoxFirefox AuroraFirefox NightlyOperaInternet ExplorerSafari
Instant MessagingPassPassPassPassPassPassPassPass
Data Channel MessagingFailWarnFailPassPassPassFailFail
Simple Video+AudioPassPassFailPassPassPassFailFail
Multiparty ChatroomPassPassFailPassPassPassFailFail
- -

More technical demos that illustrate particular capabilities.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
DemoChromeChrome CanaryFirefoxFirefox AuroraFirefox NightlyOperaInternet ExplorerSafari
Instant Messaging + Rooms PassPassPassPassPassPassPassPass
User Supplied Socket.ioPassPassPassPassPassPassPassPass
Video+Audio HD 720pPassPassFailPassPassPassFailFail
Video OnlyPassPassPassPassPassPassFailFail
Audio OnlyPassPassPassPassPassPassFailFail
Video+AudioPassPassFailPassPassPassFailFail
Multistream callsPassPassFailFailFailPassFailFail
Desktop capture with iframe
-
PassPassFailFailFailFailFailFail
Desktop capture without iframe
-
PassPassFailFailFailFailFailFail
Data Channel File-sharingPailPassFailPassPassPassFailFail
Low-bandwidth ChatPassPassFailPassPassPassFailFail
Note: Browser compatability subject to change.
- -

EasyRTC Links

- - -

Other WebRTC Resources

- - - -
- -
- - diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo4.js b/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo4.js deleted file mode 100644 index 7d4dd2830a..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo4.js +++ /dev/null @@ -1,89 +0,0 @@ -// -//Copyright (c) 2014, Priologic Software Inc. -//All rights reserved. -// -//Redistribution and use in source and binary forms, with or without -//modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -//AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -//LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -//CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -//SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -//INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -//CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -//POSSIBILITY OF SUCH DAMAGE. -// -var selfEasyrtcid = ""; - - -function connect() { - easyrtc.enableDebug(false); - easyrtc.setRoomOccupantListener(convertListToButtons); - easyrtc.easyApp("easyrtc.demo4", "selfVideo", - ["callerVideo", "callerVideo2", "callerVideo3"], loginSuccess, loginFailure); -} - - -function clearConnectList() { - otherClientDiv = document.getElementById('otherClients'); - while (otherClientDiv.hasChildNodes()) { - otherClientDiv.removeChild(otherClientDiv.lastChild); - } -} - - -function convertListToButtons (roomName, occupants, isPrimary) { - clearConnectList(); - var otherClientDiv = document.getElementById('otherClients'); - for(var easyrtcid in occupants) { - var button = document.createElement('button'); - button.onclick = function(easyrtcid) { - return function() { - performCall(easyrtcid); - }; - }(easyrtcid); - - var label = document.createTextNode(easyrtcid); - button.appendChild(label); - otherClientDiv.appendChild(button); - } -} - - -function performCall(otherEasyrtcid) { - var acceptedCB = function(accepted, easyrtcid) { - if( !accepted ) { - alert("Sorry, your call to " + easyrtcid + " was rejected"); - } - }; - var successCB = function() {}; - var failureCB = function() {}; - easyrtc.call(otherEasyrtcid, successCB, failureCB, acceptedCB); -} - - -function loginSuccess(easyrtcid) { - selfEasyrtcid = easyrtcid; - document.getElementById("iam").innerHTML = "I am " + easyrtc.cleanId(easyrtcid); -} - - -function loginFailure(errorCode, message) { - easyrtc.showError(errorCode, message); -} - - -// Sets calls so they are automatically accepted (this is default behaviour) -easyrtc.setAcceptChecker(function(easyrtcid, callback) { - callback(true); -} ); diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_audio_only.js b/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_audio_only.js deleted file mode 100644 index 2ee22a2658..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_audio_only.js +++ /dev/null @@ -1,169 +0,0 @@ -// -//Copyright (c) 2014, Priologic Software Inc. -//All rights reserved. -// -//Redistribution and use in source and binary forms, with or without -//modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -//AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -//LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -//CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -//SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -//INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -//CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -//POSSIBILITY OF SUCH DAMAGE. -// -var selfEasyrtcid = ""; - -function disable(domId) { - document.getElementById(domId).disabled = "disabled"; -} - - -function enable(domId) { - document.getElementById(domId).disabled = ""; -} - - -function connect() { - console.log("Initializing."); - easyrtc.enableVideo(false); - easyrtc.enableVideoReceive(false); - easyrtc.setRoomOccupantListener(convertListToButtons); - easyrtc.initMediaSource( - function(){ // success callback - easyrtc.connect("easyrtc.audioOnly", loginSuccess, loginFailure); - }, - function(errorCode, errmesg){ - easyrtc.showError(errorCode, errmesg); - } // failure callback - ); -} - - -function terminatePage() { - easyrtc.disconnect(); -} - - -function hangup() { - easyrtc.hangupAll(); - disable('hangupButton'); -} - - -function clearConnectList() { - otherClientDiv = document.getElementById('otherClients'); - while (otherClientDiv.hasChildNodes()) { - otherClientDiv.removeChild(otherClientDiv.lastChild); - } - -} - - -function convertListToButtons (roomName, occupants, isPrimary) { - clearConnectList(); - var otherClientDiv = document.getElementById('otherClients'); - for(var easyrtcid in occupants) { - var button = document.createElement('button'); - button.onclick = function(easyrtcid) { - return function() { - performCall(easyrtcid); - }; - }(easyrtcid); - - var label = document.createElement('text'); - label.innerHTML = easyrtc.idToName(easyrtcid); - button.appendChild(label); - otherClientDiv.appendChild(button); - } -} - - -function performCall(otherEasyrtcid) { - easyrtc.hangupAll(); - var acceptedCB = function(accepted, caller) { - if( !accepted ) { - easyrtc.showError("CALL-REJECTED", "Sorry, your call to " + easyrtc.idToName(caller) + " was rejected"); - enable('otherClients'); - } - }; - var successCB = function() { - enable('hangupButton'); - }; - var failureCB = function() { - enable('otherClients'); - }; - easyrtc.call(otherEasyrtcid, successCB, failureCB, acceptedCB); -} - - -function loginSuccess(easyrtcid) { - disable("connectButton"); - // enable("disconnectButton"); - enable('otherClients'); - selfEasyrtcid = easyrtcid; - document.getElementById("iam").innerHTML = "I am " + easyrtcid; -} - - -function loginFailure(errorCode, message) { - easyrtc.showError(errorCode, message); -} - - -function disconnect() { - document.getElementById("iam").innerHTML = "logged out"; - easyrtc.disconnect(); - console.log("disconnecting from server"); - enable("connectButton"); - // disable("disconnectButton"); - clearConnectList(); -} - - -easyrtc.setStreamAcceptor( function(easyrtcid, stream) { - var audio = document.getElementById('callerAudio'); - easyrtc.setVideoObjectSrc(audio,stream); - enable("hangupButton"); -}); - - -easyrtc.setOnStreamClosed( function (easyrtcid) { - easyrtc.setVideoObjectSrc(document.getElementById('callerAudio'), ""); - disable("hangupButton"); -}); - - -easyrtc.setAcceptChecker(function(easyrtcid, callback) { - document.getElementById('acceptCallBox').style.display = "block"; - if( easyrtc.getConnectionCount() > 0 ) { - document.getElementById('acceptCallLabel').textContent = "Drop current call and accept new from " + easyrtcid + " ?"; - } - else { - document.getElementById('acceptCallLabel').textContent = "Accept incoming call from " + easyrtcid + " ?"; - } - var acceptTheCall = function(wasAccepted) { - document.getElementById('acceptCallBox').style.display = "none"; - if( wasAccepted && easyrtc.getConnectionCount() > 0 ) { - easyrtc.hangupAll(); - } - callback(wasAccepted); - }; - document.getElementById("callAcceptButton").onclick = function() { - acceptTheCall(true); - }; - document.getElementById("callRejectButton").onclick =function() { - acceptTheCall(false); - }; -} ); diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_audio_video.js b/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_audio_video.js deleted file mode 100644 index 2704555c2b..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_audio_video.js +++ /dev/null @@ -1,193 +0,0 @@ -// -//Copyright (c) 2014, Priologic Software Inc. -//All rights reserved. -// -//Redistribution and use in source and binary forms, with or without -//modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -//AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -//LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -//CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -//SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -//INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -//CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -//POSSIBILITY OF SUCH DAMAGE. -// -var selfEasyrtcid = ""; -var haveSelfVideo = false; - -function disable(domId) { - document.getElementById(domId).disabled = "disabled"; -} - - -function enable(domId) { - document.getElementById(domId).disabled = ""; -} - - -function connect() { - easyrtc.enableAudio(document.getElementById("shareAudio").checked); - easyrtc.enableVideo(document.getElementById("shareVideo").checked); - easyrtc.enableDataChannels(true); - easyrtc.setRoomOccupantListener( convertListToButtons); - easyrtc.initMediaSource( - function(){ // success callback - var selfVideo = document.getElementById("selfVideo"); - easyrtc.setVideoObjectSrc(selfVideo, easyrtc.getLocalStream()); - easyrtc.connect("easyrtc.audioVideo", loginSuccess, loginFailure); - }, - loginFailure - ); -} - - -function hangup() { - easyrtc.hangupAll(); - disable('hangupButton'); -} - - -function clearConnectList() { - var otherClientDiv = document.getElementById('otherClients'); - while (otherClientDiv.hasChildNodes()) { - otherClientDiv.removeChild(otherClientDiv.lastChild); - } -} - - -function convertListToButtons (roomName, occupants, isPrimary) { - clearConnectList(); - var otherClientDiv = document.getElementById('otherClients'); - for(var easyrtcid in occupants) { - var button = document.createElement('button'); - button.onclick = function(easyrtcid) { - return function() { - performCall(easyrtcid); - }; - }(easyrtcid); - - var label = document.createTextNode("Call " + easyrtc.idToName(easyrtcid)); - button.appendChild(label); - otherClientDiv.appendChild(button); - } -} - - -function setUpMirror() { - if( !haveSelfVideo) { - var selfVideo = document.getElementById("selfVideo"); - easyrtc.setVideoObjectSrc(selfVideo, easyrtc.getLocalStream()); - selfVideo.muted = true; - haveSelfVideo = true; - } -} - -function performCall(otherEasyrtcid) { - easyrtc.hangupAll(); - var acceptedCB = function(accepted, easyrtcid) { - if( !accepted ) { - easyrtc.showError("CALL-REJECTEd", "Sorry, your call to " + easyrtc.idToName(easyrtcid) + " was rejected"); - enable('otherClients'); - } - }; - - var successCB = function() { - setUpMirror(); - enable('hangupButton'); - }; - var failureCB = function() { - enable('otherClients'); - }; - easyrtc.call(otherEasyrtcid, successCB, failureCB, acceptedCB); - enable('hangupButton'); -} - - -function loginSuccess(easyrtcid) { - disable("connectButton"); - // enable("disconnectButton"); - enable('otherClients'); - selfEasyrtcid = easyrtcid; - document.getElementById("iam").innerHTML = "I am " + easyrtc.cleanId(easyrtcid); - easyrtc.showError("noerror", "logged in"); -} - - -function loginFailure(errorCode, message) { - easyrtc.showError(errorCode, message); -} - - -function disconnect() { - easyrtc.disconnect(); - document.getElementById("iam").innerHTML = "logged out"; - enable("connectButton"); - disable("disconnectButton"); - easyrtc.clearMediaStream( document.getElementById('selfVideo')); - easyrtc.setVideoObjectSrc(document.getElementById("selfVideo"),""); - easyrtc.closeLocalMediaStream(); - easyrtc.setRoomOccupantListener( function(){}); - clearConnectList(); -} - - -easyrtc.setStreamAcceptor( function(easyrtcid, stream) { - setUpMirror(); - var video = document.getElementById('callerVideo'); - easyrtc.setVideoObjectSrc(video,stream); - enable("hangupButton"); -}); - - - -easyrtc.setOnStreamClosed( function (easyrtcid) { - easyrtc.setVideoObjectSrc(document.getElementById('callerVideo'), ""); - disable("hangupButton"); -}); - - -var callerPending = null; - -easyrtc.setCallCancelled( function(easyrtcid){ - if( easyrtcid === callerPending) { - document.getElementById('acceptCallBox').style.display = "none"; - callerPending = false; - } -}); - - -easyrtc.setAcceptChecker(function(easyrtcid, callback) { - document.getElementById('acceptCallBox').style.display = "block"; - callerPending = easyrtcid; - if( easyrtc.getConnectionCount() > 0 ) { - document.getElementById('acceptCallLabel').innerHTML = "Drop current call and accept new from " + easyrtc.idToName(easyrtcid) + " ?"; - } - else { - document.getElementById('acceptCallLabel').innerHTML = "Accept incoming call from " + easyrtc.idToName(easyrtcid) + " ?"; - } - var acceptTheCall = function(wasAccepted) { - document.getElementById('acceptCallBox').style.display = "none"; - if( wasAccepted && easyrtc.getConnectionCount() > 0 ) { - easyrtc.hangupAll(); - } - callback(wasAccepted); - callerPending = null; - }; - document.getElementById("callAcceptButton").onclick = function() { - acceptTheCall(true); - }; - document.getElementById("callRejectButton").onclick =function() { - acceptTheCall(false); - }; -} ); \ No newline at end of file diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_audio_video_simple.js b/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_audio_video_simple.js deleted file mode 100644 index 2851ebc4a0..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_audio_video_simple.js +++ /dev/null @@ -1,54 +0,0 @@ -var selfEasyrtcid = ""; - - -function connect() { - easyrtc.setVideoDims(640,480); - easyrtc.setRoomOccupantListener(convertListToButtons); - easyrtc.easyApp("easyrtc.audioVideoSimple", "selfVideo", ["callerVideo"], loginSuccess, loginFailure); - } - - -function clearConnectList() { - var otherClientDiv = document.getElementById('otherClients'); - while (otherClientDiv.hasChildNodes()) { - otherClientDiv.removeChild(otherClientDiv.lastChild); - } -} - - -function convertListToButtons (roomName, data, isPrimary) { - clearConnectList(); - var otherClientDiv = document.getElementById('otherClients'); - for(var easyrtcid in data) { - var button = document.createElement('button'); - button.onclick = function(easyrtcid) { - return function() { - performCall(easyrtcid); - }; - }(easyrtcid); - - var label = document.createTextNode(easyrtc.idToName(easyrtcid)); - button.appendChild(label); - otherClientDiv.appendChild(button); - } -} - - -function performCall(otherEasyrtcid) { - easyrtc.hangupAll(); - - var successCB = function() {}; - var failureCB = function() {}; - easyrtc.call(otherEasyrtcid, successCB, failureCB); -} - - -function loginSuccess(easyrtcid) { - selfEasyrtcid = easyrtcid; - document.getElementById("iam").innerHTML = "I am " + easyrtc.cleanId(easyrtcid); -} - - -function loginFailure(errorCode, message) { - easyrtc.showError(errorCode, message); -} diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_audio_video_simple_hd.js b/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_audio_video_simple_hd.js deleted file mode 100644 index c1c6903292..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_audio_video_simple_hd.js +++ /dev/null @@ -1,91 +0,0 @@ -// -//Copyright (c) 2014, Priologic Software Inc. -//All rights reserved. -// -//Redistribution and use in source and binary forms, with or without -//modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -//AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -//LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -//CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -//SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -//INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -//CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -//POSSIBILITY OF SUCH DAMAGE. -// -var selfEasyrtcid = ""; - - -function connect() { - easyrtc.setVideoDims(1280,720); - easyrtc.enableDebug(false); - easyrtc.setRoomOccupantListener(convertListToButtons); - easyrtc.easyApp("easyrtc.videoChatHd", "selfVideo", ["callerVideo"], loginSuccess, loginFailure); -} - - -function clearConnectList() { - var otherClientDiv = document.getElementById('otherClients'); - while (otherClientDiv.hasChildNodes()) { - otherClientDiv.removeChild(otherClientDiv.lastChild); - } -} - - -function convertListToButtons (roomName, data, isPrimary) { - clearConnectList(); - var otherClientDiv = document.getElementById('otherClients'); - for(var easyrtcid in data) { - var button = document.createElement('button'); - button.onclick = function(easyrtcid) { - return function() { - performCall(easyrtcid); - }; - }(easyrtcid); - - var label = document.createTextNode(easyrtc.idToName(easyrtcid)); - button.appendChild(label); - button.className = "callbutton"; - otherClientDiv.appendChild(button); - } -} - - -function performCall(otherEasyrtcid) { - easyrtc.hangupAll(); - var acceptedCB = function(accepted, caller) { - if( !accepted ) { - easyrtc.showError("CALL-REJECTED", "Sorry, your call to " + easyrtc.idToName(caller) + " was rejected"); - } - }; - var successCB = function() {}; - var failureCB = function() {}; - easyrtc.call(otherEasyrtcid, successCB, failureCB, acceptedCB); -} - - -function loginSuccess(easyrtcid) { - selfEasyrtcid = easyrtcid; - document.getElementById("iam").innerHTML = "I am " + easyrtc.cleanId(easyrtcid); -} - - -function loginFailure(errorCode, message) { - easyrtc.showError(errorCode, message); -} - - -// Sets calls so they are automatically accepted (this is default behaviour) -easyrtc.setAcceptChecker(function(caller, cb) { - cb(true); -} ); diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_data_channel_filesharing.js b/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_data_channel_filesharing.js deleted file mode 100644 index 48fbe2ccc1..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_data_channel_filesharing.js +++ /dev/null @@ -1,292 +0,0 @@ -// -//Copyright (c) 2014, Priologic Software Inc. -//All rights reserved. -// -//Redistribution and use in source and binary forms, with or without -//modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -//AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -//LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -//CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -//SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -//INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -//CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -//POSSIBILITY OF SUCH DAMAGE. -// -var selfEasyrtcid = ""; -var peers = {}; - -function buildPeerBlockName(easyrtcid) { - return "peerzone_" + easyrtcid; -} - -function buildDragNDropName(easyrtcid) { - return "dragndrop_" + easyrtcid; -} - -function buildReceiveAreaName(easyrtcid) { - return "receivearea_" + easyrtcid; -} - - -function connect() { - var otherClientsDiv = document.getElementById('otherClients'); - - easyrtc.enableDataChannels(true); - easyrtc.enableVideo(false); - easyrtc.enableAudio(false); - easyrtc.setRoomOccupantListener(convertListToButtons); - - easyrtc.setAcceptChecker(function(easyrtcid, responsefn) { - responsefn(true); - document.getElementById("connectbutton_" + easyrtcid).style.visibility = "hidden"; - }); - - easyrtc.setDataChannelOpenListener(function(easyrtcid, usesPeer) { - var obj = document.getElementById(buildDragNDropName(easyrtcid)); - if (!obj) { - console.log("no such object "); - } - jQuery(obj).addClass("connected"); - jQuery(obj).removeClass("notConnected"); - }); - - easyrtc.setDataChannelCloseListener(function(easyrtcid) { - jQuery(buildDragNDropName(easyrtcid)).addClass("notConnected"); - jQuery(buildDragNDropName(easyrtcid)).removeClass("connected"); - }); - - easyrtc.connect("easyrtc.dataFileTransfer", loginSuccess, loginFailure); -} - - -function removeIfPresent(parent, childname) { - var item = document.getElementById(childname); - if (item) { - parent.removeChild(item); - } - else { - console.log("didn't see item " + childname + " for delete eh"); - } -} - - - -function convertListToButtons(roomName, occupants, isPrimary) { - var peerZone = document.getElementById('peerZone'); - for (var oldPeer in peers) { - if (!occupants[oldPeer]) { - removeIfPresent(peerZone, buildPeerBlockName(oldPeer)); - delete peers[oldPeer]; - } - } - - - function buildDropDiv(easyrtcid) { - var statusDiv = document.createElement("div"); - statusDiv.className = "dragndropStatus"; - - var dropArea = document.createElement("div"); - var connectButton = document.createElement("button"); - connectButton.appendChild(document.createTextNode("Connect")); - connectButton.className = "connectButton"; - connectButton.id = "connectbutton_" + easyrtcid; - connectButton.onclick = function() { - statusDiv.innerHTML = "Waiting for connection to be established"; - easyrtc.call(easyrtcid, - function(caller, mediatype) { - statusDiv.innerHTML = "Connection established"; - dropArea.className = "dragndrop connected"; - connectButton.style.visibility = "hidden"; - }, - function(errorCode, errorText) { - dropArea.className = "dragndrop connected"; - statusDiv.innerHTML = "Connection failed"; - connectButton.style.visibility = "hidden"; - noDCs[easyrtcid] = true; - }, - function wasAccepted(yup) { - } - ); - } - - dropArea.id = buildDragNDropName(easyrtcid); - dropArea.className = "dragndrop notConnected"; - dropArea.innerHTML = "File drop area"; - - - function updateStatusDiv(state) { - switch (state.status) { - case "waiting": - statusDiv.innerHTML = "waiting for other partyto accept transmission"; - break; - case "started_file": - statusDiv.innerHTML = "started file: " + state.name; - case "working": - statusDiv.innerHTML = state.name + ":" + state.position + "/" + state.size + "(" + state.numFiles + " files)"; - break; - case "rejected": - statusDiv.innerHTML = "cancelled"; - setTimeout(function() { - statusDiv.innerHTML = ""; - }, 2000); - break; - case "done": - statusDiv.innerHTML = "done"; - setTimeout(function() { - statusDiv.innerHTML = ""; - }, 3000); - break; - } - return true; - } - - - var noDCs = {}; // which users don't support data channels - - var fileSender = null; - function filesHandler(files) { - // if we haven't eastablished a connection to the other party yet, do so now, - // and on completion, send the files. Otherwise send the files now. - var timer = null; - if (easyrtc.getConnectStatus(easyrtcid) === easyrtc.NOT_CONNECTED && noDCs[easyrtcid] === undefined) { - // - // calls between firefrox and chrome ( version 30) have problems one way if you - // use data channels. - // - - } - else if (easyrtc.getConnectStatus(easyrtcid) === easyrtc.IS_CONNECTED || noDCs[easyrtcid]) { - if (!fileSender) { - fileSender = easyrtc_ft.buildFileSender(easyrtcid, updateStatusDiv); - } - fileSender(files, true /* assume binary */); - } - else { - easyrtc.showError("user-error", "Wait for the connection to complete before adding more files!"); - } - } - easyrtc_ft.buildDragNDropRegion(dropArea, filesHandler); - var container = document.createElement("div"); - container.appendChild(connectButton); - container.appendChild(dropArea); - container.appendChild(statusDiv); - return container; - } - - - function buildReceiveDiv(i) { - var div = document.createElement("div"); - div.id = buildReceiveAreaName(i); - div.className = "receiveBlock"; - div.style.display = "none"; - return div; - } - - - for (var easyrtcid in occupants) { - if (!peers[easyrtcid]) { - var peerBlock = document.createElement("div"); - peerBlock.id = buildPeerBlockName(easyrtcid); - peerBlock.className = "peerblock"; - peerBlock.appendChild(document.createTextNode(" For peer " + easyrtcid)); - peerBlock.appendChild(document.createElement("br")); - peerBlock.appendChild(buildDropDiv(easyrtcid)); - peerBlock.appendChild(buildReceiveDiv(easyrtcid)); - peerZone.appendChild(peerBlock); - peers[easyrtcid] = true; - } - } -} - - - -function acceptRejectCB(otherGuy, fileNameList, wasAccepted) { - - var receiveBlock = document.getElementById(buildReceiveAreaName(otherGuy)); - jQuery(receiveBlock).empty(); - receiveBlock.style.display = "inline-block"; - - // - // list the files being offered - // - receiveBlock.appendChild(document.createTextNode("Files offered")); - receiveBlock.appendChild(document.createElement("br")); - for (var i = 0; i < fileNameList.length; i++) { - receiveBlock.appendChild( - document.createTextNode(" " + fileNameList[i].name + "(" + fileNameList[i].size + " bytes)")); - receiveBlock.appendChild(document.createElement("br")); - } - // - // provide accept/reject buttons - // - var button = document.createElement("button"); - button.appendChild(document.createTextNode("Accept")); - button.onclick = function() { - jQuery(receiveBlock).empty(); - wasAccepted(true); - }; - receiveBlock.appendChild(button); - - button = document.createElement("button"); - button.appendChild(document.createTextNode("Reject")); - button.onclick = function() { - wasAccepted(false); - receiveBlock.style.display = "none"; - }; - receiveBlock.appendChild(button); -} - - -function receiveStatusCB(otherGuy, msg) { - var receiveBlock = document.getElementById(buildReceiveAreaName(otherGuy)); - if( !receiveBlock) return; - - switch (msg.status) { - case "started": - break; - case "eof": - receiveBlock.innerHTML = "Finished file"; - break; - case "done": - receiveBlock.innerHTML = "Stopped because " +msg.reason; - setTimeout(function() { - receiveBlock.style.display = "none"; - }, 1000); - break; - case "started_file": - receiveBlock.innerHTML = "Beginning receive of " + msg.name; - break; - case "progress": - receiveBlock.innerHTML = msg.name + " " + msg.received + "/" + msg.size; - break; - default: - console.log("strange file receive cb message = ", JSON.stringify(msg)); - } - return true; -} - -function blobAcceptor(otherGuy, blob, filename) { - easyrtc_ft.saveAs(blob, filename); -} - -function loginSuccess(easyrtcid) { - selfEasyrtcid = easyrtcid; - document.getElementById("iam").innerHTML = "I am " + easyrtcid; - easyrtc_ft.buildFileReceiver(acceptRejectCB, blobAcceptor, receiveStatusCB); -} - - -function loginFailure(errorCode, message) { - easyrtc.showError(errorCode, message); -} diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_data_channel_messaging.js b/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_data_channel_messaging.js deleted file mode 100644 index ceb56854d0..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_data_channel_messaging.js +++ /dev/null @@ -1,172 +0,0 @@ -// -//Copyright (c) 2014, Priologic Software Inc. -//All rights reserved. -// -//Redistribution and use in source and binary forms, with or without -//modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -//AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -//LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -//CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -//SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -//INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -//CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -//POSSIBILITY OF SUCH DAMAGE. -// -var selfEasyrtcid = ""; -var connectList = {}; -var channelIsActive = {}; // tracks which channels are active - - -function connect() { - easyrtc.enableDebug(false); - easyrtc.enableDataChannels(true); - easyrtc.enableVideo(false); - easyrtc.enableAudio(false); - easyrtc.enableVideoReceive(false); - easyrtc.enableAudioReceive(false); - easyrtc.setDataChannelOpenListener(openListener); - easyrtc.setDataChannelCloseListener(closeListener); - easyrtc.setPeerListener(addToConversation); - easyrtc.setRoomOccupantListener(convertListToButtons); - easyrtc.connect("easyrtc.dataMessaging", loginSuccess, loginFailure); -} - - -function addToConversation(who, msgType, content) { - // Escape html special characters, then add linefeeds. - content = content.replace(/&/g, '&').replace(//g, '>'); - content = content.replace(/\n/g, '
'); - document.getElementById('conversation').innerHTML += - "" + who + ": " + content + "
"; -} - - -function openListener(otherParty) { - channelIsActive[otherParty] = true; - updateButtonState(otherParty); -} - - -function closeListener(otherParty) { - channelIsActive[otherParty] = false; - updateButtonState(otherParty); -} - -function convertListToButtons(roomName, occupantList, isPrimary) { - connectList = occupantList; - - var otherClientDiv = document.getElementById('otherClients'); - while (otherClientDiv.hasChildNodes()) { - otherClientDiv.removeChild(otherClientDiv.lastChild); - } - - var label, button; - for (var easyrtcid in connectList) { - var rowGroup = document.createElement("span"); - var rowLabel = document.createTextNode(easyrtc.idToName(easyrtcid)); - rowGroup.appendChild(rowLabel); - - button = document.createElement('button'); - button.id = "connect_" + easyrtcid; - button.onclick = function(easyrtcid) { - return function() { - startCall(easyrtcid); - }; - }(easyrtcid); - label = document.createTextNode("Connect"); - button.appendChild(label); - rowGroup.appendChild(button); - - button = document.createElement('button'); - button.id = "send_" + easyrtcid; - button.onclick = function(easyrtcid) { - return function() { - sendStuffP2P(easyrtcid); - }; - }(easyrtcid); - label = document.createTextNode("Send Message"); - button.appendChild(label); - rowGroup.appendChild(button); - otherClientDiv.appendChild(rowGroup); - updateButtonState(easyrtcid); - } - if (!otherClientDiv.hasChildNodes()) { - otherClientDiv.innerHTML = "Nobody else logged in to talk to..."; - } -} - -function updateButtonState(otherEasyrtcid) { - var isConnected = channelIsActive[otherEasyrtcid]; - if(document.getElementById('connect_' + otherEasyrtcid)) { - document.getElementById('connect_' + otherEasyrtcid).disabled = isConnected; - } - if( document.getElementById('send_' + otherEasyrtcid)) { - document.getElementById('send_' + otherEasyrtcid).disabled = !isConnected; - } -} - - -function startCall(otherEasyrtcid) { - if (easyrtc.getConnectStatus(otherEasyrtcid) === easyrtc.NOT_CONNECTED) { - try { - easyrtc.call(otherEasyrtcid, - function(caller, media) { // success callback - if (media === 'datachannel') { - // console.log("made call succesfully"); - connectList[otherEasyrtcid] = true; - } - }, - function(errorCode, errorText) { - connectList[otherEasyrtcid] = false; - easyrtc.showError(errorCode, errorText); - }, - function(wasAccepted) { - // console.log("was accepted=" + wasAccepted); - } - ); - }catch( callerror) { - console.log("saw call error ", callerror); - } - } - else { - easyrtc.showError("ALREADY-CONNECTED", "already connected to " + easyrtc.idToName(otherEasyrtcid)); - } -} - -function sendStuffP2P(otherEasyrtcid) { - var text = document.getElementById('sendMessageText').value; - if (text.replace(/\s/g, "").length === 0) { // Don't send just whitespace - return; - } - if (easyrtc.getConnectStatus(otherEasyrtcid) === easyrtc.IS_CONNECTED) { - easyrtc.sendDataP2P(otherEasyrtcid, 'msg', text); - } - else { - easyrtc.showError("NOT-CONNECTED", "not connected to " + easyrtc.idToName(otherEasyrtcid) + " yet."); - } - - addToConversation("Me", "msgtype", text); - document.getElementById('sendMessageText').value = ""; -} - - -function loginSuccess(easyrtcid) { - selfEasyrtcid = easyrtcid; - document.getElementById("iam").innerHTML = "I am " + easyrtcid; -} - - -function loginFailure(errorCode, message) { - easyrtc.showError(errorCode, "failure to login"); -} diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_ice_filter.js b/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_ice_filter.js deleted file mode 100644 index 452964b269..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_ice_filter.js +++ /dev/null @@ -1,84 +0,0 @@ -var selfEasyrtcid = ""; - - -function connect() { - easyrtc.setRoomOccupantListener(convertListToButtons); - easyrtc.easyApp("easyrtc.iceFilter", "selfVideo", ["callerVideo"], loginSuccess, loginFailure); - } - - -function clearConnectList() { - var otherClientDiv = document.getElementById('otherClients'); - while (otherClientDiv.hasChildNodes()) { - otherClientDiv.removeChild(otherClientDiv.lastChild); - } -} - - -function convertListToButtons (roomName, data, isPrimary) { - clearConnectList(); - var otherClientDiv = document.getElementById('otherClients'); - for(var easyrtcid in data) { - var button = document.createElement('button'); - button.onclick = function(easyrtcid) { - return function() { - performCall(easyrtcid); - }; - }(easyrtcid); - - var label = document.createTextNode(easyrtc.idToName(easyrtcid)); - button.appendChild(label); - otherClientDiv.appendChild(button); - } -} - - -function performCall(otherEasyrtcid) { - easyrtc.hangupAll(); - easyrtc.setIceUsedInCalls( getModifiedIceList()); - var successCB = function() {}; - var failureCB = function() {}; - easyrtc.call(otherEasyrtcid, successCB, failureCB); -} - - - - - -var iceMap = []; - -function getModifiedIceList(){ - var iceList = []; - var i; - - for( i = 0; i < iceMap.length; i++ ) { - if( document.getElementById("iscb" + i).checked ) { - iceList.push( iceMap[i]); - } - } - return {iceServers: iceList}; -} - - -function loginSuccess(easyrtcid) { - var i; - - selfEasyrtcid = easyrtcid; - document.getElementById("iam").innerHTML = "I am " + easyrtc.cleanId(easyrtcid); - var blockentries = "

Ice Entries

"; - var iceServers = easyrtc.getServerIce(); - for(i = 0; i < iceServers.iceServers.length; i++ ) { - iceMap[i] = iceServers.iceServers[i]; - var label = "iscb" + i; - blockentries += '
' + iceServers.iceServers[i].url + '>
'; - - } - document.getElementById("iceEntries").innerHTML = blockentries; - -} - - -function loginFailure(errorCode, message) { - easyrtc.showError(errorCode, message); -} diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_instant_messaging.js b/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_instant_messaging.js deleted file mode 100644 index e433619d25..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_instant_messaging.js +++ /dev/null @@ -1,87 +0,0 @@ -// -//Copyright (c) 2014, Priologic Software Inc. -//All rights reserved. -// -//Redistribution and use in source and binary forms, with or without -//modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -//AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -//LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -//CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -//SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -//INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -//CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -//POSSIBILITY OF SUCH DAMAGE. -// -var selfEasyrtcid = ""; -function addToConversation(who, msgType, content) { - // Escape html special characters, then add linefeeds. - content = content.replace(/&/g,'&').replace(//g,'>'); - content = content.replace(/\n/g, '
'); - document.getElementById('conversation').innerHTML += - "" + who + ": " + content + "
"; -} - - -function connect() { - easyrtc.setPeerListener(addToConversation); - easyrtc.setRoomOccupantListener(convertListToButtons); - easyrtc.connect("easyrtc.instantMessaging", loginSuccess, loginFailure); -} - - -function convertListToButtons (roomName, occupants, isPrimary) { - var otherClientDiv = document.getElementById('otherClients'); - while (otherClientDiv.hasChildNodes()) { - otherClientDiv.removeChild(otherClientDiv.lastChild); - } - - for(var easyrtcid in occupants) { - var button = document.createElement('button'); - button.onclick = function(easyrtcid) { - return function() { - sendStuffWS(easyrtcid); - }; - }(easyrtcid); - var label = document.createTextNode("Send to " + easyrtc.idToName(easyrtcid)); - button.appendChild(label); - - otherClientDiv.appendChild(button); - } - if( !otherClientDiv.hasChildNodes() ) { - otherClientDiv.innerHTML = "Nobody else logged in to talk to..."; - } -} - - -function sendStuffWS(otherEasyrtcid) { - var text = document.getElementById('sendMessageText').value; - if(text.replace(/\s/g, "").length === 0) { // Don't send just whitespace - return; - } - - easyrtc.sendDataWS(otherEasyrtcid, "message", text); - addToConversation("Me", "message", text); - document.getElementById('sendMessageText').value = ""; -} - - -function loginSuccess(easyrtcid) { - selfEasyrtcid = easyrtcid; - document.getElementById("iam").innerHTML = "I am " + easyrtcid; -} - - -function loginFailure(errorCode, message) { - easyrtc.showError(errorCode, message); -} \ No newline at end of file diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_instant_messaging_rooms.js b/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_instant_messaging_rooms.js deleted file mode 100644 index c754f24a76..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_instant_messaging_rooms.js +++ /dev/null @@ -1,418 +0,0 @@ -// -//Copyright (c) 2014, Priologic Software Inc. -//All rights reserved. -// -//Redistribution and use in source and binary forms, with or without -//modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -//AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -//LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -//CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -//SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -//INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -//CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -//POSSIBILITY OF SUCH DAMAGE. -// -var selfEasyrtcid = ""; -var waitingForRoomList = true; -var isConnected = false; - -function initApp() { - document.getElementById("main").className = "notconnected"; -} - -function addToConversation(who, msgType, content, targeting) { - // Escape html special characters, then add linefeeds. - if( !content) { - content = "**no body**"; - } - content = content.replace(/&/g, '&').replace(//g, '>'); - content = content.replace(/\n/g, '
'); - var targetingStr = ""; - if (targeting) { - if (targeting.targetEasyrtcid) { - targetingStr += "user=" + targeting.targetEasyrtcid; - } - if (targeting.targetRoom) { - targetingStr += " room=" + targeting.targetRoom; - } - if (targeting.targetGroup) { - targetingStr += " group=" + targeting.targetGroup; - } - } - document.getElementById('conversation').innerHTML += - "" + who + " sent " + targetingStr + ": " + content + "
"; -} - -function genRoomDivName(roomName) { - return "roomblock_" + roomName; -} - -function genRoomOccupantName(roomName) { - return "roomOccupant_" + roomName; -} - -function setCredential(event, value) { - if (event.keyCode === 13) { - easyrtc.setCredential(value); - } -} - - -function addRoom(roomName, parmString, userAdded) { - if (!roomName) { - roomName = document.getElementById("roomToAdd").value; - parmString = document.getElementById("optRoomParms").value; - } - var roomid = genRoomDivName(roomName); - if (document.getElementById(roomid)) { - return; - } - function addRoomButton() { - - var roomButtonHolder = document.getElementById('rooms'); - var roomdiv = document.createElement("div"); - roomdiv.id = roomid; - roomdiv.className = "roomDiv"; - - var roomButton = document.createElement("button"); - roomButton.onclick = function() { - sendMessage(null, roomName); - }; - var roomLabel = (document.createTextNode(roomName)); - roomButton.appendChild(roomLabel); - - roomdiv.appendChild(roomButton); - roomButtonHolder.appendChild(roomdiv); - var roomOccupants = document.createElement("div"); - roomOccupants.id = genRoomOccupantName(roomName); - roomOccupants.className = "roomOccupants"; - roomdiv.appendChild(roomOccupants); - $(roomdiv).append(" -leave"); - } - - var roomParms = null; - if (parmString && parmString !== "") { - try { - roomParms = JSON.parse(parmString); - } catch (error) { - roomParms = null; - easyrtc.showError(easyrtc.errCodes.DEVELOPER_ERR, "Room Parameters must be an object containing key/value pairs. eg: {\"fruit\":\"banana\",\"color\":\"yellow\"}"); - return; - } - } - if (!isConnected || !userAdded) { - addRoomButton(); - console.log("adding gui for room " + roomName); - } - else { - console.log("not adding gui for room " + roomName + " because already connected and it's a user action"); - } - if (userAdded) { - console.log("calling joinRoom(" + roomName + ") because it was a user action "); - - easyrtc.joinRoom(roomName, roomParms, - function() { - /* we'll geta room entry event for the room we were actually added to */ - }, - function(errorCode, errorText, roomName) { - easyrtc.showError(errorCode, errorText + ": room name was(" + roomName + ")"); - }); - } -} - - -function leaveRoom(roomName) { - if (!roomName) { - roomName = document.getElementById("roomToAdd").value; - } - var entry = document.getElementById(genRoomDivName(roomName)); - var roomButtonHolder = document.getElementById('rooms'); - easyrtc.leaveRoom(roomName, null); - roomButtonHolder.removeChild(entry); -} - - -function roomEntryListener(entered, roomName) { - if (entered) { // entered a room - console.log("saw add of room " + roomName); - addRoom(roomName, null, false); - } - else { - var roomNode = document.getElementById(genRoomDivName(roomName)); - if (roomNode) { - document.getElementById('#rooms').removeChildNode(roomNode); - } - } - refreshRoomList(); -} - - -function refreshRoomList() { - if( isConnected) { - easyrtc.getRoomList(addQuickJoinButtons, null); - } -} - - -function peerListener(who, msgType, content, targeting) { - addToConversation(who, msgType, content, targeting); -} - -function connect() { - easyrtc.setPeerListener(peerListener); - easyrtc.setRoomOccupantListener(occupantListener); - easyrtc.setRoomEntryListener(roomEntryListener); - easyrtc.setDisconnectListener(function() { - jQuery('#rooms').empty(); - document.getElementById("main").className = "notconnected"; - console.log("disconnect listener fired"); - }); - updatePresence(); - var username = document.getElementById("userNameField").value; - var password = document.getElementById("credentialField").value; - if (username) { - easyrtc.setUsername(username); - } - if (password) { - easyrtc.setCredential({password: password}); - } - easyrtc.connect("easyrtc.instantMessaging", loginSuccess, loginFailure); -} - -function disconnect() { - easyrtc.disconnect(); -} - -function addQuickJoinButtons(roomList) { - var quickJoinBlock = document.getElementById("quickJoinBlock"); - var n = quickJoinBlock.childNodes.length; - for (var i = n - 1; i >= 0; i--) { - quickJoinBlock.removeChild(quickJoinBlock.childNodes[i]); - } - function addQuickJoinButton(roomname, numberClients) { - var checkid = "roomblock_" + roomname; - if (document.getElementById(checkid)) { - return; // already present so don't add again - } - var id = "quickjoin_" + roomname; - var div = document.createElement("div"); - div.id = id; - div.className = "quickJoin"; - var parmsField = document.getElementById("optRoomParms"); - var button = document.createElement("button"); - button.onclick = function() { - addRoom(roomname, parmsField.value, true); - refreshRoomList(); - }; - button.appendChild(document.createTextNode("Join " + roomname + "(" + numberClients + ")")); - div.appendChild(button); - quickJoinBlock.appendChild(div); - - } - if( !roomList["room1"]) { - roomList["room1"] = { numberClients:0}; - } - if( !roomList["room2"]) { - roomList["room2"] = { numberClients:0}; - } - if( !roomList["room3"]) { - roomList["room3"] = { numberClients:0}; - } - for (var roomName in roomList) { - addQuickJoinButton(roomName, roomList[roomName].numberClients); - } -} - - - -function occupantListener(roomName, occupants, isPrimary) { - if (roomName === null) { - return; - } - var roomId = genRoomOccupantName(roomName); - var roomDiv = document.getElementById(roomId); - if (!roomDiv) { - addRoom(roomName, "", false); - roomDiv = document.getElementById(roomId); - } - else { - jQuery(roomDiv).empty(); - } - for (var easyrtcid in occupants) { - var button = document.createElement("button"); - button.onclick = (function(roomname, easyrtcid) { - return function() { - sendMessage(easyrtcid, roomName); - }; - })(roomName, easyrtcid); - var presenceText = ""; - if (occupants[easyrtcid].presence) { - presenceText += "("; - if (occupants[easyrtcid].presence.show) { - presenceText += "show=" + occupants[easyrtcid].presence.show + " "; - } - if (occupants[easyrtcid].presence.status) { - presenceText += "status=" + occupants[easyrtcid].presence.status; - } - presenceText += ")"; - } - var label = document.createTextNode(easyrtc.idToName(easyrtcid) + presenceText); - button.appendChild(label); - roomDiv.appendChild(button); - } - refreshRoomList(); -} - - - -function getGroupId() { - return null; -} - - -function sendMessage(destTargetId, destRoom) { - var text = document.getElementById('sendMessageText').value; - if (text.replace(/\s/g, "").length === 0) { // Don't send just whitespace - return; - } - var dest; - var destGroup = getGroupId(); - if (destRoom || destGroup) { - dest = {}; - if (destRoom) { - dest.targetRoom = destRoom; - } - if (destGroup) { - dest.targetGroup = destGroup; - } - if (destTargetId) { - dest.targetEasyrtcid = destTargetId; - } - } - else if (destTargetId) { - dest = destTargetId; - } - else { - easyrtc.showError("user error", "no destination selected"); - return; - } - - if( text === "empty") { - easyrtc.sendPeerMessage(dest, "message"); - } - else { - easyrtc.sendDataWS(dest, "message", text, function(reply) { - if (reply.msgType === "error") { - easyrtc.showError(reply.msgData.errorCode, reply.msgData.errorText); - } - }); - } - addToConversation("Me", "message", text); - document.getElementById('sendMessageText').value = ""; -} - - -function loginSuccess(easyrtcid) { - selfEasyrtcid = easyrtcid; - document.getElementById("iam").innerHTML = "I am " + easyrtcid; - refreshRoomList(); - isConnected = true; - displayFields(); - document.getElementById("main").className = "connected"; -} - - -function displayFields() { - - var outstr = "Application fields
"; - outstr += JSON.stringify(easyrtc.getApplicationFields()); - outstr += "

"; - - outstr += "Session fields
"; - outstr += JSON.stringify(easyrtc.getSessionFields()); - outstr += "

"; - - outstr += "Connection fields
"; - outstr += JSON.stringify(easyrtc.getConnectionFields()); - outstr += "

"; - - var roomlist = easyrtc.getRoomsJoined(); - for (var roomname in roomlist) { - var roomfields = easyrtc.getRoomFields(roomname); - if (roomfields != null) { - outstr += "Room " + roomname + " fields
"; - outstr += JSON.stringify(roomfields); - outstr += "

"; - } - } - document.getElementById('fields').innerHTML = outstr; -} - - - - -function loginFailure(errorCode, message) { - easyrtc.showError("LOGIN-FAILURE", message); - document.getElementById('connectButton').disabled = false; - jQuery('#rooms').empty(); -} - -var currentShowState = 'chat'; -var currentShowText = ''; - -function setPresence(value) { - currentShowState = value; - updatePresence(); -} - -function updatePresenceStatus(value) { - currentShowText = value; - updatePresence(); -} - -function updatePresence() -{ - easyrtc.updatePresence(currentShowState, currentShowText); -} - -function queryRoomNames() { - var roomName = document.getElementById("queryRoom").value; - if( !roomName ) { - roomName = "default"; - } - if( roomName ) { - console.log("getRoomOccupantsAsArray("+ roomName + ")=" + JSON.stringify(easyrtc.getRoomOccupantsAsArray(roomName))); - console.log("getRoomOccupantsAsMap(" + roomName + ")=" + JSON.stringify(easyrtc.getRoomOccupantsAsMap(roomName))); - } -} -function addApiField() { - var roomName = document.getElementById("apiroomname").value; - var fieldname = document.getElementById("apifieldname").value; - var fieldvaluetext = document.getElementById("apifieldvalue").value; - var fieldvalue; - if(fieldvaluetext.indexOf("{") >= 0) { - fieldvalue = JSON.parse(fieldvaluetext); - } - else { - fieldvalue = fieldvaluetext; - } - easyrtc.setRoomApiField(roomName, fieldname, fieldvalue); -} - - -function getIdsOfName() { - var name = document.getElementById("targetName").value; - var ids = easyrtc.usernameToIds(name); - document.getElementById("foundIds").innerHTML = JSON.stringify(ids); -} \ No newline at end of file diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_instant_messaging_selfconnect.js b/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_instant_messaging_selfconnect.js deleted file mode 100644 index 84b84af892..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_instant_messaging_selfconnect.js +++ /dev/null @@ -1,111 +0,0 @@ -// -//Copyright (c) 2014, Priologic Software Inc. -//All rights reserved. -// -//Redistribution and use in source and binary forms, with or without -//modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -//AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -//LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -//CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -//SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -//INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -//CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -//POSSIBILITY OF SUCH DAMAGE. -// -var selfEasyrtcid = ""; -function addToConversation(who, msgType, content) { - // Escape html special characters, then add linefeeds. - content = content.replace(/&/g,'&').replace(//g,'>'); - content = content.replace(/\n/g, '
'); - document.getElementById('conversation').innerHTML += - "" + who + ": " + content + "
"; -} - - - -function connect(immediateMode) { - easyrtc.setPeerListener(addToConversation); - easyrtc.setRoomOccupantListener(convertListToButtons); - - var mysocket = io.connect(null, { - 'connect timeout': 10000, - 'force new connection': true - }); - - - if (!mysocket) { - throw "io.connect failed"; - } - else { - console.log("application allocated socket ", mysocket); - easyrtc.useThisSocketConnection(mysocket); - } - if( immediateMode) { - easyrtc.connect("easyrtc.reconnect", loginSuccess, loginFailure); - } - else { - setTimeout(function() { - easyrtc.connect("easyrtc.reconnect", loginSuccess, loginFailure); - }, 10*1000); - } -} - - -function convertListToButtons (roomName, occupants, isPrimary) { - var otherClientDiv = document.getElementById('otherClients'); - while (otherClientDiv.hasChildNodes()) { - otherClientDiv.removeChild(otherClientDiv.lastChild); - } - - for(var easyrtcid in occupants) { - var button = document.createElement('button'); - button.onclick = function(easyrtcid) { - return function() { - sendStuffWS(easyrtcid); - }; - }(easyrtcid); - var label = document.createTextNode("Send to " + easyrtc.idToName(easyrtcid)); - button.appendChild(label); - - otherClientDiv.appendChild(button); - } - if( !otherClientDiv.hasChildNodes() ) { - otherClientDiv.innerHTML = "Nobody else logged in to talk to..."; - } -} - - -function sendStuffWS(otherEasyrtcid) { - var text = document.getElementById('sendMessageText').value; - if(text.replace(/\s/g, "").length === 0) { // Don't send just whitespace - return; - } - - easyrtc.sendDataWS(otherEasyrtcid, "message", text); - addToConversation("Me", "message", text); - document.getElementById('sendMessageText').value = ""; -} - - -function loginSuccess(easyrtcid) { - selfEasyrtcid = easyrtcid; - document.getElementById("iam").innerHTML = "I am " + easyrtcid; - document.getElementById("buttonImmediate").enabled = false; - document.getElementById("buttonDelayed").enabled = false; -} - - -function loginFailure(errorCode, message) { - easyrtc.showError(errorCode, message); -} \ No newline at end of file diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_lowbandwidth.js b/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_lowbandwidth.js deleted file mode 100644 index 17abe0757d..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_lowbandwidth.js +++ /dev/null @@ -1,61 +0,0 @@ -var selfEasyrtcid = ""; - - -function connect() { - - var localFilter = easyrtc.buildLocalSdpFilter( { - audioRecvBitrate:20, videoRecvBitrate:30 - }); - var remoteFilter = easyrtc.buildRemoteSdpFilter({ - audioSendBitrate: 20, videoSendBitrate:30 - }); - easyrtc.setSdpFilters(localFilter, remoteFilter); - easyrtc.setRoomOccupantListener(convertListToButtons); - easyrtc.easyApp("easyrtc.lowbandwidth", "selfVideo", ["callerVideo"], loginSuccess, loginFailure); - } - - -function clearConnectList() { - var otherClientDiv = document.getElementById('otherClients'); - while (otherClientDiv.hasChildNodes()) { - otherClientDiv.removeChild(otherClientDiv.lastChild); - } -} - - -function convertListToButtons (roomName, data, isPrimary) { - clearConnectList(); - var otherClientDiv = document.getElementById('otherClients'); - for(var easyrtcid in data) { - var button = document.createElement('button'); - button.onclick = function(easyrtcid) { - return function() { - performCall(easyrtcid); - }; - }(easyrtcid); - - var label = document.createTextNode(easyrtc.idToName(easyrtcid)); - button.appendChild(label); - otherClientDiv.appendChild(button); - } -} - - -function performCall(otherEasyrtcid) { - easyrtc.hangupAll(); - - var successCB = function() {}; - var failureCB = function() {}; - easyrtc.call(otherEasyrtcid, successCB, failureCB); -} - - -function loginSuccess(easyrtcid) { - selfEasyrtcid = easyrtcid; - document.getElementById("iam").innerHTML = "I am " + easyrtc.cleanId(easyrtcid); -} - - -function loginFailure(errorCode, message) { - easyrtc.showError(errorCode, message); -} diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_multiparty.js b/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_multiparty.js deleted file mode 100644 index 402bb408d5..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_multiparty.js +++ /dev/null @@ -1,727 +0,0 @@ - - -var activeBox = -1; // nothing selected -var aspectRatio = 4/3; // standard definition video aspect ratio -var maxCALLERS = 3; -var numVideoOBJS = maxCALLERS+1; -var layout; - - -easyrtc.dontAddCloseButtons(true); - -function getIdOfBox(boxNum) { - return "box" + boxNum; -} - - -function reshapeFull(parentw, parenth) { - return { - left:0, - top:0, - width:parentw, - height:parenth - }; -} - -function reshapeTextEntryBox(parentw, parenth) { - return { - left:parentw/4, - top:parenth/4, - width:parentw/2, - height: parenth/4 - } -} - -function reshapeTextEntryField(parentw, parenth) { - return { - width:parentw -40 - } -} - -var margin = 20; - -function reshapeToFullSize(parentw, parenth) { - var left, top, width, height; - var margin= 20; - - if( parentw < parenth*aspectRatio){ - width = parentw -margin; - height = width/aspectRatio; - } - else { - height = parenth-margin; - width = height*aspectRatio; - } - left = (parentw - width)/2; - top = (parenth - height)/2; - return { - left:left, - top:top, - width:width, - height:height - }; -} - -// -// a negative percentLeft is interpreted as setting the right edge of the object -// that distance from the right edge of the parent. -// Similar for percentTop. -// -function setThumbSizeAspect(percentSize, percentLeft, percentTop, parentw, parenth, aspect) { - - var width, height; - if( parentw < parenth*aspectRatio){ - width = parentw * percentSize; - height = width/aspect; - } - else { - height = parenth * percentSize; - width = height*aspect; - } - var left; - if( percentLeft < 0) { - left = parentw - width; - } - else { - left = 0; - } - left += Math.floor(percentLeft*parentw); - var top = 0; - if( percentTop < 0) { - top = parenth - height; - } - else { - top = 0; - } - top += Math.floor(percentTop*parenth); - return { - left:left, - top:top, - width:width, - height:height - }; -} - - -function setThumbSize(percentSize, percentLeft, percentTop, parentw, parenth) { - return setThumbSizeAspect(percentSize, percentLeft, percentTop, parentw, parenth, aspectRatio); -} - -function setThumbSizeButton(percentSize, percentLeft, percentTop, parentw, parenth, imagew, imageh) { - return setThumbSizeAspect(percentSize, percentLeft, percentTop, parentw, parenth, imagew/imageh); -} - - -var sharedVideoWidth = 1; -var sharedVideoHeight = 1; - -function reshape1of2(parentw, parenth) { - if( layout== 'p' ) { - return { - left: (parentw-sharedVideoWidth)/2, - top: (parenth -sharedVideoHeight*2)/3, - width: sharedVideoWidth, - height: sharedVideoHeight - }; - } - else { - return{ - left: (parentw-sharedVideoWidth*2)/3, - top: (parenth -sharedVideoHeight)/2, - width: sharedVideoWidth, - height: sharedVideoHeight - } - } -} - - - -function reshape2of2(parentw, parenth){ - if( layout== 'p' ) { - return { - left: (parentw-sharedVideoWidth)/2, - top: (parenth -sharedVideoHeight*2)/3 *2 + sharedVideoHeight, - width: sharedVideoWidth, - height: sharedVideoHeight - }; - } - else { - return{ - left: (parentw-sharedVideoWidth*2)/3 *2 + sharedVideoWidth, - top: (parenth -sharedVideoHeight)/2, - width: sharedVideoWidth, - height: sharedVideoHeight - } - } -} - -function reshape1of3(parentw, parenth) { - if( layout== 'p' ) { - return { - left: (parentw-sharedVideoWidth)/2, - top: (parenth -sharedVideoHeight*3)/4 , - width: sharedVideoWidth, - height: sharedVideoHeight - }; - } - else { - return{ - left: (parentw-sharedVideoWidth*2)/3, - top: (parenth -sharedVideoHeight*2)/3, - width: sharedVideoWidth, - height: sharedVideoHeight - } - } -} - -function reshape2of3(parentw, parenth){ - if( layout== 'p' ) { - return { - left: (parentw-sharedVideoWidth)/2, - top: (parenth -sharedVideoHeight*3)/4*2+ sharedVideoHeight, - width: sharedVideoWidth, - height: sharedVideoHeight - }; - } - else { - return{ - left: (parentw-sharedVideoWidth*2)/3*2+sharedVideoWidth, - top: (parenth -sharedVideoHeight*2)/3, - width: sharedVideoWidth, - height: sharedVideoHeight - } - } -} - -function reshape3of3(parentw, parenth) { - if( layout== 'p' ) { - return { - left: (parentw-sharedVideoWidth)/2, - top: (parenth -sharedVideoHeight*3)/4*3+ sharedVideoHeight*2, - width: sharedVideoWidth, - height: sharedVideoHeight - }; - } - else { - return{ - left: (parentw-sharedVideoWidth*2)/3*1.5+sharedVideoWidth/2, - top: (parenth -sharedVideoHeight*2)/3*2+ sharedVideoHeight, - width: sharedVideoWidth, - height: sharedVideoHeight - } - } -} - - -function reshape1of4(parentw, parenth) { - return { - left: (parentw - sharedVideoWidth*2)/3, - top: (parenth - sharedVideoHeight*2)/3, - width: sharedVideoWidth, - height: sharedVideoHeight - } -} - -function reshape2of4(parentw, parenth) { - return { - left: (parentw - sharedVideoWidth*2)/3*2+ sharedVideoWidth, - top: (parenth - sharedVideoHeight*2)/3, - width: sharedVideoWidth, - height: sharedVideoHeight - } -} -function reshape3of4(parentw, parenth) { - return { - left: (parentw - sharedVideoWidth*2)/3, - top: (parenth - sharedVideoHeight*2)/3*2 + sharedVideoHeight, - width: sharedVideoWidth, - height: sharedVideoHeight - } -} - -function reshape4of4(parentw, parenth) { - return { - left: (parentw - sharedVideoWidth*2)/3*2 + sharedVideoWidth, - top: (parenth - sharedVideoHeight*2)/3*2 + sharedVideoHeight, - width: sharedVideoWidth, - height: sharedVideoHeight - } -} - -var boxUsed = [true, false, false, false]; -var connectCount = 0; - - -function setSharedVideoSize(parentw, parenth) { - layout = ((parentw /aspectRatio) < parenth)?'p':'l'; - var w, h; - - function sizeBy(fullsize, numVideos) { - return (fullsize - margin*(numVideos+1) )/numVideos; - } - - switch(layout+(connectCount+1)) { - case 'p1': - case 'l1': - w = sizeBy(parentw, 1); - h = sizeBy(parenth, 1); - break; - case 'l2': - w = sizeBy(parentw, 2); - h = sizeBy(parenth, 1); - break; - case 'p2': - w = sizeBy(parentw, 1); - h = sizeBy(parenth, 2); - break; - case 'p4': - case 'l4': - case 'l3': - w = sizeBy(parentw, 2); - h = sizeBy(parenth, 2); - break; - case 'p3': - w = sizeBy(parentw, 1); - h = sizeBy(parenth, 3); - break; - } - sharedVideoWidth = Math.min(w, h * aspectRatio); - sharedVideoHeight = Math.min(h, w/aspectRatio); -} - -var reshapeThumbs = [ - function(parentw, parenth) { - - if( activeBox > 0 ) { - return setThumbSize(0.20, 0.01, 0.01, parentw, parenth); - } - else { - setSharedVideoSize(parentw, parenth) - switch(connectCount) { - case 0:return reshapeToFullSize(parentw, parenth); - case 1:return reshape1of2(parentw, parenth); - case 2:return reshape1of3(parentw, parenth); - case 3:return reshape1of4(parentw, parenth); - } - } - }, - function(parentw, parenth) { - if( activeBox >= 0 || !boxUsed[1]) { - return setThumbSize(0.20, 0.01, -0.01, parentw, parenth); - } - else{ - switch(connectCount) { - case 1: - return reshape2of2(parentw, parenth); - case 2: - return reshape2of3(parentw, parenth); - case 3: - return reshape2of4(parentw, parenth); - } - } - }, - function(parentw, parenth) { - if( activeBox >= 0 || !boxUsed[2] ) { - return setThumbSize(0.20, -0.01, 0.01, parentw, parenth); - } - else { - switch(connectCount){ - case 1: - return reshape2of2(parentw, parenth); - case 2: - if( !boxUsed[1]) { - return reshape2of3(parentw, parenth); - } - else { - return reshape3of3(parentw, parenth); - } - case 3: - return reshape3of4(parentw, parenth); - } - } - }, - function(parentw, parenth) { - if( activeBox >= 0 || !boxUsed[3]) { - return setThumbSize(0.20, -0.01, -0.01, parentw, parenth); - } - else{ - switch(connectCount){ - case 1: - return reshape2of2(parentw, parenth); - case 2: - return reshape3of3(parentw, parenth); - case 3: - return reshape4of4(parentw, parenth); - } - } - }, -]; - - -function killButtonReshaper(parentw, parenth) { - var imagew = 128; - var imageh = 128; - if( parentw < parenth) { - return setThumbSizeButton(0.1, -.51, -0.01, parentw, parenth, imagew, imageh); - } - else { - return setThumbSizeButton(0.1, -.01, -.51, parentw, parenth, imagew, imageh); - } -} - - -function muteButtonReshaper(parentw, parenth) { - var imagew = 32; - var imageh = 32; - if( parentw < parenth) { - return setThumbSizeButton(0.10, -.51, 0.01, parentw, parenth, imagew, imageh); - } - else { - return setThumbSizeButton(0.10, 0.01, -.51, parentw, parenth, imagew, imageh); - } -} - -function reshapeTextEntryButton(parentw, parenth) { - var imagew = 32; - var imageh = 32; - if( parentw < parenth) { - return setThumbSizeButton(0.10, .51, 0.01, parentw, parenth, imagew, imageh); - } - else { - return setThumbSizeButton(0.10, 0.01, .51, parentw, parenth, imagew, imageh); - } -} - - -function handleWindowResize() { - var fullpage = document.getElementById('fullpage'); - fullpage.style.width = window.innerWidth + "px"; - fullpage.style.height = window.innerHeight + "px"; - connectCount = easyrtc.getConnectionCount(); - - function applyReshape(obj, parentw, parenth) { - var myReshape = obj.reshapeMe(parentw, parenth); - - if(typeof myReshape.left !== 'undefined' ) { - obj.style.left = Math.round(myReshape.left) + "px"; - } - if(typeof myReshape.top !== 'undefined' ) { - obj.style.top = Math.round(myReshape.top) + "px"; - } - if(typeof myReshape.width !== 'undefined' ) { - obj.style.width = Math.round(myReshape.width) + "px"; - } - if(typeof myReshape.height !== 'undefined' ) { - obj.style.height = Math.round(myReshape.height) + "px"; - } - - var n = obj.childNodes.length; - for(var i = 0; i < n; i++ ) { - var childNode = obj.childNodes[i]; - if( childNode.reshapeMe) { - applyReshape(childNode, myReshape.width, myReshape.height); - } - } - } - - applyReshape(fullpage, window.innerWidth, window.innerHeight); -} - - -function setReshaper(elementId, reshapeFn) { - var element = document.getElementById(elementId); - if( !element) { - alert("Attempt to apply to reshapeFn to non-existent element " + elementId); - } - if( !reshapeFn) { - alert("Attempt to apply misnamed reshapeFn to element " + elementId); - } - element.reshapeMe = reshapeFn; -} - - -function collapseToThumbHelper() { - if( activeBox >= 0) { - var id = getIdOfBox(activeBox); - document.getElementById(id).style.zIndex = 2; - setReshaper(id, reshapeThumbs[activeBox]); - document.getElementById('muteButton').style.display = "none"; - document.getElementById('killButton').style.display = "none"; - activeBox = -1; - } -} - -function collapseToThumb() { - collapseToThumbHelper(); - activeBox = -1; - updateMuteImage(false); - handleWindowResize(); - -} - -function updateMuteImage(toggle) { - var muteButton = document.getElementById('muteButton'); - if( activeBox > 0) { // no kill button for self video - muteButton.style.display = "block"; - var videoObject = document.getElementById( getIdOfBox(activeBox)); - var isMuted = videoObject.muted?true:false; - if( toggle) { - isMuted = !isMuted; - videoObject.muted = isMuted; - } - muteButton.src = isMuted?"images/button_unmute.png":"images/button_mute.png"; - } - else { - muteButton.style.display = "none"; - } -} - - -function expandThumb(whichBox) { - var lastActiveBox = activeBox; - if( activeBox >= 0 ) { - collapseToThumbHelper(); - } - if( lastActiveBox != whichBox) { - var id = getIdOfBox(whichBox); - activeBox = whichBox; - setReshaper(id, reshapeToFullSize); - document.getElementById(id).style.zIndex = 1; - if( whichBox > 0) { - document.getElementById('muteButton').style.display = "block"; - updateMuteImage(); - document.getElementById('killButton').style.display = "block"; - } - } - updateMuteImage(false); - handleWindowResize(); -} - -function prepVideoBox(whichBox) { - var id = getIdOfBox(whichBox); - setReshaper(id, reshapeThumbs[whichBox]); - document.getElementById(id).onclick = function() { - expandThumb(whichBox); - }; -} - - -function killActiveBox() { - if( activeBox > 0) { - var easyrtcid = easyrtc.getIthCaller(activeBox-1); - collapseToThumb(); - setTimeout( function() { - easyrtc.hangup(easyrtcid); - }, 400); - } -} - - -function muteActiveBox() { - updateMuteImage(true); -} - - - - -function callEverybodyElse(roomName, otherPeople) { - - easyrtc.setRoomOccupantListener(null); // so we're only called once. - - var list = []; - var connectCount = 0; - for(var easyrtcid in otherPeople ) { - list.push(easyrtcid); - } - // - // Connect in reverse order. Latter arriving people are more likely to have - // empty slots. - // - function establishConnection(position) { - function callSuccess() { - connectCount++; - if( connectCount < maxCALLERS && position > 0) { - establishConnection(position-1); - } - } - function callFailure(errorCode, errorText) { - easyrtc.showError(errorCode, errorText); - if( connectCount < maxCALLERS && position > 0) { - establishConnection(position-1); - } - } - easyrtc.call(list[position], callSuccess, callFailure); - - } - if( list.length > 0) { - establishConnection(list.length-1); - } -} - - -function loginSuccess() { - expandThumb(0); // expand the mirror image initially. -} - - -function cancelText() { - document.getElementById('textentryBox').style.display = "none"; - document.getElementById('textEntryButton').style.display = "block"; -} - - -function sendText(e) { - document.getElementById('textentryBox').style.display = "none"; - document.getElementById('textEntryButton').style.display = "block"; - var stringToSend = document.getElementById('textentryField').value; - if( stringToSend && stringToSend != "") { - for(var i = 0; i < maxCALLERS; i++ ) { - var easyrtcid = easyrtc.getIthCaller(i); - if( easyrtcid && easyrtcid != "") { - easyrtc.sendPeerMessage(easyrtcid, "im", stringToSend); - } - } - } - return false; -} - - -function showTextEntry() { - document.getElementById('textentryField').value = ""; - document.getElementById('textentryBox').style.display = "block"; - document.getElementById('textEntryButton').style.display = "none"; - document.getElementById('textentryField').focus(); -} - - -function showMessage(startX, startY, content) { - var fullPage = document.getElementById('fullpage'); - var fullW = parseInt(fullPage.offsetWidth); - var fullH = parseInt(fullPage.offsetHeight); - var centerEndX = .2*startX + .8*fullW/2; - var centerEndY = .2*startY + .8*fullH/2; - - - var cloudObject = document.createElement("img"); - cloudObject.src = "images/cloud.png"; - cloudObject.style.width = "1px"; - cloudObject.style.height = "1px"; - cloudObject.style.left = startX + "px"; - cloudObject.style.top = startY + "px"; - fullPage.appendChild(cloudObject); - - cloudObject.onload = function() { - cloudObject.style.left = startX + "px"; - cloudObject.style.top = startY + "px"; - cloudObject.style.width = "4px"; - cloudObject.style.height = "4px"; - cloudObject.style.opacity = 0.7; - cloudObject.style.zIndex = 5; - cloudObject.className = "transit boxCommon"; - var textObject; - function removeCloud() { - if( textObject) { - fullPage.removeChild(textObject); - fullPage.removeChild(cloudObject); - } - } - setTimeout(function() { - cloudObject.style.left = centerEndX - fullW/4 + "px"; - cloudObject.style.top = centerEndY - fullH/4+ "px"; - cloudObject.style.width = (fullW/2) + "px"; - cloudObject.style.height = (fullH/2) + "px"; - }, 10); - setTimeout(function() { - textObject = document.createElement('div'); - textObject.className = "boxCommon"; - textObject.style.left = Math.floor(centerEndX-fullW/8) + "px"; - textObject.style.top = Math.floor(centerEndY) + "px"; - textObject.style.fontSize = "36pt"; - textObject.style.width = (fullW*.4) + "px"; - textObject.style.height = (fullH*.4) + "px"; - textObject.style.zIndex = 6; - textObject.appendChild( document.createTextNode(content)); - fullPage.appendChild(textObject); - textObject.onclick = removeCloud; - cloudObject.onclick = removeCloud; - }, 1000); - setTimeout(function() { - cloudObject.style.left = startX + "px"; - cloudObject.style.top = startY + "px"; - cloudObject.style.width = "4px"; - cloudObject.style.height = "4px"; - fullPage.removeChild(textObject); - }, 9000); - setTimeout(function(){ - fullPage.removeChild(cloudObject); - }, 10000); - } -} - -function messageListener(easyrtcid, msgType, content) { - for(var i = 0; i < maxCALLERS; i++) { - if( easyrtc.getIthCaller(i) == easyrtcid) { - var startArea = document.getElementById(getIdOfBox(i+1)); - var startX = parseInt(startArea.offsetLeft) + parseInt(startArea.offsetWidth)/2; - var startY = parseInt(startArea.offsetTop) + parseInt(startArea.offsetHeight)/2; - showMessage(startX, startY, content); - } - } -} - - -function appInit() { - - // Prep for the top-down layout manager - setReshaper('fullpage', reshapeFull); - for(var i = 0; i < numVideoOBJS; i++) { - prepVideoBox(i); - } - setReshaper('killButton', killButtonReshaper); - setReshaper('muteButton', muteButtonReshaper); - setReshaper('textentryBox', reshapeTextEntryBox); - setReshaper('textentryField', reshapeTextEntryField); - setReshaper('textEntryButton', reshapeTextEntryButton); - - updateMuteImage(false); - window.onresize = handleWindowResize; - handleWindowResize(); //initial call of the top-down layout manager - - - easyrtc.setRoomOccupantListener(callEverybodyElse); - easyrtc.easyApp("easyrtc.multiparty", "box0", ["box1", "box2", "box3"], loginSuccess); - easyrtc.setPeerListener(messageListener); - easyrtc.setDisconnectListener( function() { - easyrtc.showError("LOST-CONNECTION", "Lost connection to signaling server"); - }); - easyrtc.setOnCall( function(easyrtcid, slot) { - console.log("getConnection count=" + easyrtc.getConnectionCount() ); - boxUsed[slot+1] = true; - if(activeBox == 0 ) { // first connection - collapseToThumb(); - document.getElementById('textEntryButton').style.display = 'block'; - } - document.getElementById(getIdOfBox(slot+1)).style.visibility = "visible"; - handleWindowResize(); - }); - - - easyrtc.setOnHangup(function(easyrtcid, slot) { - boxUsed[slot+1] = false; - if(activeBox > 0 && slot+1 == activeBox) { - collapseToThumb(); - } - setTimeout(function() { - document.getElementById(getIdOfBox(slot+1)).style.visibility = "hidden"; - - if( easyrtc.getConnectionCount() == 0 ) { // no more connections - expandThumb(0); - document.getElementById('textEntryButton').style.display = 'none'; - document.getElementById('textentryBox').style.display = 'none'; - } - handleWindowResize(); - },20); - }); -} - - diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_multistream.js b/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_multistream.js deleted file mode 100644 index 1940db0106..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_multistream.js +++ /dev/null @@ -1,255 +0,0 @@ -// -//Copyright (c) 2014, Priologic Software Inc. -//All rights reserved. -// -//Redistribution and use in source and binary forms, with or without -//modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -//AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -//LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -//CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -//SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -//INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -//CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -//POSSIBILITY OF SUCH DAMAGE. -// -var selfEasyrtcid = ""; -var haveSelfVideo = false; -var otherEasyrtcid = null; - - -function disable(domId) { - console.log("about to try disabling " +domId); - document.getElementById(domId).disabled = "disabled"; -} - - -function enable(domId) { - console.log("about to try enabling " +domId); - document.getElementById(domId).disabled = ""; -} - - -function createLabelledButton(buttonLabel) { - var button = document.createElement("button"); - button.appendChild(document.createTextNode(buttonLabel)); - document.getElementById("videoSrcBlk").appendChild(button); - return button; -} - - -function addMediaStreamToDiv(divId, stream, streamName) -{ - var container = document.createElement("div"); - container.style.marginBottom = "10px"; - var formattedName = streamName.replace("(", "
").replace(")", ""); - var labelBlock = document.createElement("div"); - labelBlock.style.width = "220px"; - labelBlock.style.cssFloat = "left"; - labelBlock.innerHTML = "
" + formattedName + "

"; - container.appendChild(labelBlock); - var video = document.createElement("video"); - video.width = 320; - video.height = 240; - video.style.verticalAlign= "middle"; - container.appendChild(video); - document.getElementById(divId).appendChild(container); - video.autoplay = true; - video.muted = false; - easyrtc.setVideoObjectSrc(video, stream); - return labelBlock; -} - - - -function createLocalVideo(stream, streamName) { - var labelBlock = addMediaStreamToDiv("localVideos", stream, streamName); - var closeButton = createLabelledButton("close"); - closeButton.onclick = function() { - easyrtc.closeLocalStream(streamName); - labelBlock.parentNode.parentNode.removeChild(labelBlock.parentNode); - } - labelBlock.appendChild(closeButton); - - console.log("created local video, stream.streamName = " + stream.streamName); -} - -function addSrcButton(buttonLabel, videoId) { - var button = createLabelledButton(buttonLabel); - button.onclick = function() { - easyrtc.setVideoSource(videoId); - easyrtc.initMediaSource( - function(stream) { - createLocalVideo(stream, buttonLabel); - if( otherEasyrtcid) { - easyrtc.addStreamToCall(otherEasyrtcid, buttonLabel, function(easyrtcid, streamName){ - easyrtc.showError("Informational", "other party " + easyrtcid + " acknowledges receiving " + streamName); - }); - } - }, - function(errCode, errText) { - easyrtc.showError(errCode, errText); - }, buttonLabel); - }; -} - -function connect() { - console.log("Initializing."); - easyrtc.setRoomOccupantListener(convertListToButtons); - easyrtc.connect("easyrtc.multistream", loginSuccess, loginFailure); - easyrtc.setAutoInitUserMedia(false); - easyrtc.getVideoSourceList(function(videoSrcList) { - for (var i = 0; i < videoSrcList.length; i++) { - var videoEle = videoSrcList[i]; - var videoLabel = (videoSrcList[i].label &&videoSrcList[i].label.length > 0)? - (videoSrcList[i].label):("src_" + i); - addSrcButton(videoLabel, videoSrcList[i].id); - } - // - // add an extra button for screen sharing - // - var screenShareButton = createLabelledButton("Screen capture/share"); - var numScreens = 0; - if (!chrome.desktopCapture) { - screenShareButton.disabled = true; - } - else { - screenShareButton.onclick = function() { - numScreens++; - var streamName = "screen" + numScreens; - easyrtc.initScreenCapture( - function(stream) { - createLocalVideo(stream, streamName); - if( otherEasyrtcid) { - easyrtc.addStreamToCall(otherEasyrtcid, "screen"); - } - }, - function(errCode, errText) { - easyrtc.showError(errCode, errText); - }, streamName); - }; - } - }); -} - - -function hangup() { - easyrtc.hangupAll(); - disable('hangupButton'); -} - - -function clearConnectList() { - var otherClientDiv = document.getElementById('otherClients'); - while (otherClientDiv.hasChildNodes()) { - otherClientDiv.removeChild(otherClientDiv.lastChild); - } -} - - -function convertListToButtons(roomName, occupants, isPrimary) { - clearConnectList(); - var otherClientDiv = document.getElementById('otherClients'); - for (var easyrtcid in occupants) { - var button = document.createElement('button'); - button.onclick = function(easyrtcid) { - return function() { - performCall(easyrtcid); - }; - }(easyrtcid); - - var label = document.createTextNode("Call " + easyrtc.idToName(easyrtcid)); - button.appendChild(label); - otherClientDiv.appendChild(button); - } -} - - -function performCall(targetEasyrtcId) { - var acceptedCB = function(accepted, easyrtcid) { - if (!accepted) { - easyrtc.showError("CALL-REJECTED", "Sorry, your call to " + easyrtc.idToName(easyrtcid) + " was rejected"); - enable('otherClients'); - } - else { - otherEasyrtcid = targetEasyrtcId; - } - }; - - var successCB = function() { - enable('hangupButton'); - }; - var failureCB = function() { - enable('otherClients'); - }; - var keys = easyrtc.getLocalMediaIds(); - - easyrtc.call(targetEasyrtcId, successCB, failureCB, acceptedCB, keys); - enable('hangupButton'); -} - - -function loginSuccess(easyrtcid) { - disable("connectButton"); - // enable("disconnectButton"); - enable('otherClients'); - selfEasyrtcid = easyrtcid; - document.getElementById("iam").innerHTML = "I am " + easyrtc.cleanId(easyrtcid); -} - - -function loginFailure(errorCode, message) { - easyrtc.showError(errorCode, message); -} - - -function disconnect() { - document.getElementById("iam").innerHTML = "logged out"; - easyrtc.disconnect(); - enable("connectButton"); -// disable("disconnectButton"); - clearConnectList(); - easyrtc.setVideoObjectSrc(document.getElementById('selfVideo'), ""); -} - -easyrtc.setStreamAcceptor(function(easyrtcid, stream, streamName) { - var labelBlock = addMediaStreamToDiv("remoteVideos", stream, streamName); - labelBlock.parentNode.id = "remoteBlock" + easyrtcid + streamName; - console.log("accepted incoming stream with name " + stream.streamName); - console.log("checking incoming " + easyrtc.getNameOfRemoteStream(easyrtcid, stream)); -}); - - - -easyrtc.setOnStreamClosed(function(easyrtcid, stream, streamName) { - var item = document.getElementById("remoteBlock" + easyrtcid + streamName); - item.parentNode.removeChild(item); -}); - - -var callerPending = null; - -easyrtc.setCallCancelled(function(easyrtcid) { - if (easyrtcid === callerPending) { - document.getElementById('acceptCallBox').style.display = "none"; - callerPending = false; - } -}); - -easyrtc.setAcceptChecker(function(easyrtcid, callback) { - otherEasyrtcid = easyrtcid; - if (easyrtc.getConnectionCount() > 0) { - easyrtc.hangupAll(); - } - callback(true, easyrtc.getLocalMediaIds()); -}); \ No newline at end of file diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_multistream_iframe.js b/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_multistream_iframe.js deleted file mode 100644 index a7ce2d7213..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_multistream_iframe.js +++ /dev/null @@ -1,249 +0,0 @@ -// -//Copyright (c) 2014, Priologic Software Inc. -//All rights reserved. -// -//Redistribution and use in source and binary forms, with or without -//modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -//AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -//LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -//CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -//SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -//INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -//CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -//POSSIBILITY OF SUCH DAMAGE. -// -var selfEasyrtcid = ""; -var haveSelfVideo = false; -var otherEasyrtcid = null; - - -function disable(domId) { - console.log("about to try disabling " + domId); - document.getElementById(domId).disabled = "disabled"; -} - - -function enable(domId) { - console.log("about to try enabling " + domId); - document.getElementById(domId).disabled = ""; -} - - -function createLabelledButton(buttonLabel) { - var button = document.createElement("button"); - button.appendChild(document.createTextNode(buttonLabel)); - document.getElementById("videoSrcBlk").appendChild(button); - return button; -} - - -function addMediaStreamToDiv(divId, stream, streamName) -{ - var container = document.createElement("div"); - container.style.marginBottom = "10px"; - var formattedName = streamName.replace("(", "
").replace(")", ""); - var labelBlock = document.createElement("div"); - labelBlock.style.width = "220px"; - labelBlock.style.cssFloat = "left"; - labelBlock.innerHTML = "
" + formattedName + "

"; - container.appendChild(labelBlock); - var video = document.createElement("video"); - video.width = 320; - video.height = 240; - video.style.verticalAlign = "middle"; - container.appendChild(video); - document.getElementById(divId).appendChild(container); - video.autoplay = true; - video.muted = false; - easyrtc.setVideoObjectSrc(video, stream); - return labelBlock; -} - - - -function createLocalVideo(stream, streamName) { - var labelBlock = addMediaStreamToDiv("localVideos", stream, streamName); - var closeButton = createLabelledButton("close"); - closeButton.onclick = function() { - easyrtc.closeLocalStream(streamName); - labelBlock.parentNode.parentNode.removeChild(labelBlock.parentNode); - } - labelBlock.appendChild(closeButton); -} - -function addSrcButton(buttonLabel, videoId) { - var button = createLabelledButton(buttonLabel); - button.onclick = function() { - easyrtc.setVideoSource(videoId); - easyrtc.initMediaSource( - function(stream) { - createLocalVideo(stream, buttonLabel); - if (otherEasyrtcid) { - easyrtc.addStreamToCall(otherEasyrtcid, buttonLabel); - } - }, - function(errCode, errText) { - easyrtc.showError(errCode, errText); - }, buttonLabel); - }; -} - -function connect() { - console.log("Initializing."); - easyrtc.setRoomOccupantListener(convertListToButtons); - easyrtc.connect("easyrtc.multistream", loginSuccess, loginFailure); - easyrtc.setAutoInitUserMedia(false); - - easyrtc.getVideoSourceList(function(videoSrcList) { - for (var i = 0; i < videoSrcList.length; i++) { - var videoEle = videoSrcList[i]; - var videoLabel = (videoSrcList[i].label && videoSrcList[i].label.length > 0) ? - (videoSrcList[i].label) : ("src_" + i); - addSrcButton(videoLabel, videoSrcList[i].id); - } - }); - // - // add an extra button for screen sharing - // - var screenShareButton = createLabelledButton("Desktop capture/share"); - var numScreens = 0; - - screenShareButton.onclick = function() { - numScreens++; - var streamName = "screen" + numScreens; - easyrtc.initDesktopStream( - function(stream) { - createLocalVideo(stream, streamName); - if (otherEasyrtcid) { - easyrtc.addStreamToCall(otherEasyrtcid, streamName); - } - }, - function(errCode, errText) { - easyrtc.showError(errCode, errText); - }, - streamName); - }; - -} - - -function hangup() { - easyrtc.hangupAll(); - disable('hangupButton'); -} - - -function clearConnectList() { - var otherClientDiv = document.getElementById('otherClients'); - while (otherClientDiv.hasChildNodes()) { - otherClientDiv.removeChild(otherClientDiv.lastChild); - } -} - - -function convertListToButtons(roomName, occupants, isPrimary) { - clearConnectList(); - var otherClientDiv = document.getElementById('otherClients'); - for (var easyrtcid in occupants) { - var button = document.createElement('button'); - button.onclick = function(easyrtcid) { - return function() { - performCall(easyrtcid); - }; - }(easyrtcid); - - var label = document.createTextNode("Call " + easyrtc.idToName(easyrtcid)); - button.appendChild(label); - otherClientDiv.appendChild(button); - } -} - - -function performCall(targetEasyrtcId) { - var acceptedCB = function(accepted, easyrtcid) { - if (!accepted) { - easyrtc.showError("CALL-REJECTED", "Sorry, your call to " + easyrtc.idToName(easyrtcid) + " was rejected"); - enable('otherClients'); - } - else { - otherEasyrtcid = targetEasyrtcId; - } - }; - - var successCB = function() { - enable('hangupButton'); - }; - var failureCB = function() { - enable('otherClients'); - }; - var keys = easyrtc.getLocalMediaIds(); - - easyrtc.call(targetEasyrtcId, successCB, failureCB, acceptedCB, keys); - enable('hangupButton'); -} - - -function loginSuccess(easyrtcid) { - disable("connectButton"); - // enable("disconnectButton"); - enable('otherClients'); - selfEasyrtcid = easyrtcid; - document.getElementById("iam").innerHTML = "I am " + easyrtc.cleanId(easyrtcid); -} - - -function loginFailure(errorCode, message) { - easyrtc.showError(errorCode, message); -} - - -function disconnect() { - document.getElementById("iam").innerHTML = "logged out"; - easyrtc.disconnect(); - enable("connectButton"); -// disable("disconnectButton"); - clearConnectList(); - easyrtc.setVideoObjectSrc(document.getElementById('selfVideo'), ""); -} - -easyrtc.setStreamAcceptor(function(easyrtcid, stream, streamName) { - var labelBlock = addMediaStreamToDiv("remoteVideos", stream, streamName); - labelBlock.parentNode.id = "remoteBlock" + easyrtcid + streamName; - -}); - - - -easyrtc.setOnStreamClosed(function(easyrtcid, stream, streamName) { - var item = document.getElementById("remoteBlock" + easyrtcid + streamName); - item.parentNode.removeChild(item); -}); - - -var callerPending = null; - -easyrtc.setCallCancelled(function(easyrtcid) { - if (easyrtcid === callerPending) { - document.getElementById('acceptCallBox').style.display = "none"; - callerPending = false; - } -}); - -easyrtc.setAcceptChecker(function(easyrtcid, callback) { - otherEasyrtcid = easyrtcid; - if (easyrtc.getConnectionCount() > 0) { - easyrtc.hangupAll(); - } - callback(true, easyrtc.getLocalMediaIds()); -}); \ No newline at end of file diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_multistream_no_iframe.js b/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_multistream_no_iframe.js deleted file mode 100644 index 593ec5ad77..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_multistream_no_iframe.js +++ /dev/null @@ -1,265 +0,0 @@ -// -//Copyright (c) 2014, Priologic Software Inc. -//All rights reserved. -// -//Redistribution and use in source and binary forms, with or without -//modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -//AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -//LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -//CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -//SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -//INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -//CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -//POSSIBILITY OF SUCH DAMAGE. -// -var selfEasyrtcid = ""; -var haveSelfVideo = false; -var otherEasyrtcid = null; - - -function disable(domId) { - console.log("about to try disabling " + domId); - document.getElementById(domId).disabled = "disabled"; -} - - -function enable(domId) { - console.log("about to try enabling " + domId); - document.getElementById(domId).disabled = ""; -} - - -function createLabelledButton(buttonLabel) { - var button = document.createElement("button"); - button.appendChild(document.createTextNode(buttonLabel)); - document.getElementById("videoSrcBlk").appendChild(button); - return button; -} - - -function addMediaStreamToDiv(divId, stream, streamName) -{ - var container = document.createElement("div"); - container.style.marginBottom = "10px"; - var formattedName = streamName.replace("(", "
").replace(")", ""); - var labelBlock = document.createElement("div"); - labelBlock.style.width = "220px"; - labelBlock.style.cssFloat = "left"; - labelBlock.innerHTML = "
" + formattedName + "

"; - container.appendChild(labelBlock); - var video = document.createElement("video"); - video.width = 320; - video.height = 240; - video.style.verticalAlign = "middle"; - container.appendChild(video); - document.getElementById(divId).appendChild(container); - video.autoplay = true; - video.muted = false; - easyrtc.setVideoObjectSrc(video, stream); - return labelBlock; -} - - - -function createLocalVideo(stream, streamName) { - var labelBlock = addMediaStreamToDiv("localVideos", stream, streamName); - var closeButton = createLabelledButton("close"); - closeButton.onclick = function() { - easyrtc.closeLocalStream(streamName); - labelBlock.parentNode.parentNode.removeChild(labelBlock.parentNode); - } - labelBlock.appendChild(closeButton); -} - -function addSrcButton(buttonLabel, videoId) { - var button = createLabelledButton(buttonLabel); - button.onclick = function() { - easyrtc.setVideoSource(videoId); - easyrtc.initMediaSource( - function(stream) { - createLocalVideo(stream, buttonLabel); - if (otherEasyrtcid) { - easyrtc.addStreamToCall(otherEasyrtcid, buttonLabel); - } - }, - function(errCode, errText) { - easyrtc.showError(errCode, errText); - }, buttonLabel); - }; -} - -function connect() { - console.log("Initializing."); - easyrtc.setRoomOccupantListener(convertListToButtons); - easyrtc.connect("easyrtc.multistream", loginSuccess, loginFailure); - easyrtc.setAutoInitUserMedia(false); - - easyrtc.getVideoSourceList(function(videoSrcList) { - for (var i = 0; i < videoSrcList.length; i++) { - var videoEle = videoSrcList[i]; - var videoLabel = (videoSrcList[i].label && videoSrcList[i].label.length > 0) ? - (videoSrcList[i].label) : ("src_" + i); - addSrcButton(videoLabel, videoSrcList[i].id); - } - }); - // - // add an extra button for screen sharing - // - var screenShareButton = createLabelledButton("Desktop capture/share"); - var numScreens = 0; - - screenShareButton.onclick = function() { - numScreens++; - var streamName = "screen" + numScreens; - easyrtc.initDesktopStream( - function(stream) { - createLocalVideo(stream, streamName); - if (otherEasyrtcid) { - easyrtc.addStreamToCall(otherEasyrtcid, streamName); - } - }, - function(errCode, errText) { - easyrtc.showError(errCode, errText); - }, - streamName); - }; - -} - - -function hangup() { - easyrtc.hangupAll(); - disable('hangupButton'); -} - - -function clearConnectList() { - var otherClientDiv = document.getElementById('otherClients'); - while (otherClientDiv.hasChildNodes()) { - otherClientDiv.removeChild(otherClientDiv.lastChild); - } -} - - -function convertListToButtons(roomName, occupants, isPrimary) { - clearConnectList(); - var otherClientDiv = document.getElementById('otherClients'); - for (var easyrtcid in occupants) { - var button = document.createElement('button'); - button.onclick = function(easyrtcid) { - return function() { - performCall(easyrtcid); - }; - }(easyrtcid); - - var label = document.createTextNode("Call " + easyrtc.idToName(easyrtcid)); - button.appendChild(label); - otherClientDiv.appendChild(button); - } -} - - -function performCall(targetEasyrtcId) { - var acceptedCB = function(accepted, easyrtcid) { - if (!accepted) { - easyrtc.showError("CALL-REJECTED", "Sorry, your call to " + easyrtc.idToName(easyrtcid) + " was rejected"); - enable('otherClients'); - } - else { - otherEasyrtcid = targetEasyrtcId; - } - }; - - var successCB = function() { - enable('hangupButton'); - }; - var failureCB = function() { - enable('otherClients'); - }; - var keys = easyrtc.getLocalMediaIds(); - - easyrtc.call(targetEasyrtcId, successCB, failureCB, acceptedCB, keys); - enable('hangupButton'); -} - - -function loginSuccess(easyrtcid) { - disable("connectButton"); - // enable("disconnectButton"); - enable('otherClients'); - selfEasyrtcid = easyrtcid; - document.getElementById("iam").innerHTML = "I am " + easyrtc.cleanId(easyrtcid); -} - - -function loginFailure(errorCode, message) { - easyrtc.showError(errorCode, message); -} - - -function disconnect() { - document.getElementById("iam").innerHTML = "logged out"; - easyrtc.disconnect(); - enable("connectButton"); -// disable("disconnectButton"); - clearConnectList(); - easyrtc.setVideoObjectSrc(document.getElementById('selfVideo'), ""); -} - -easyrtc.setStreamAcceptor(function(easyrtcid, stream, streamName) { - var labelBlock = addMediaStreamToDiv("remoteVideos", stream, streamName); - labelBlock.parentNode.id = "remoteBlock" + easyrtcid + streamName; - - console.log("accepted incoming stream with name " + stream.streamName); - console.log("checking incoming " + easyrtc.getNameOfRemoteStream(easyrtcid, stream)); - -}); - - - -easyrtc.setOnStreamClosed(function(easyrtcid, stream, streamName) { - var item = document.getElementById("remoteBlock" + easyrtcid + streamName); - item.parentNode.removeChild(item); -}); - - -var callerPending = null; - -easyrtc.setCallCancelled(function(easyrtcid) { - if (easyrtcid === callerPending) { - document.getElementById('acceptCallBox').style.display = "none"; - callerPending = false; - } -}); - -easyrtc.setAcceptChecker(function(easyrtcid, callback) { - otherEasyrtcid = easyrtcid; - if (easyrtc.getConnectionCount() > 0) { - easyrtc.hangupAll(); - } - callback(true, easyrtc.getLocalMediaIds()); -}); - -var mypluginId = "tawk-desktop-capture/bemabaogbdfpbkkganibcmhbgjogabfj"; - -setTimeout( - function() { - document.getElementById("pluginstatus").innerHTML = easyrtc.isDesktopCaptureInstalled() - ?"Desktop capture ready" - :"Desktop capture not installed"; - }, 3000); - -document.getElementById("installPluginButton").onclick = function() { -chrome.webstore.install(); -}; \ No newline at end of file diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_reconnect.js b/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_reconnect.js deleted file mode 100644 index 1b88de8d75..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_reconnect.js +++ /dev/null @@ -1,73 +0,0 @@ -// -//Copyright (c) 2014, Priologic Software Inc. -//All rights reserved. -// -//Redistribution and use in source and binary forms, with or without -//modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -//AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -//LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -//CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -//SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -//INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -//CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -//POSSIBILITY OF SUCH DAMAGE. -// -var selfEasyrtcid = ""; - - - -function initApp() { - console.log("Initializing."); - easyrtc.enableVideo(false); - easyrtc.enableAudio(false); - connect(); -} - -function connect() { - easyrtc.connect("easyrtc.reconnect", loginSuccess, loginFailure); -} - -function disconnect() { - easyrtc.disconnect(); -} - -easyrtc.enableDebug(true); - -easyrtc.setDisconnectListener(function() { - easyrtc.showError("xx", "saw disconnect"); -}); - - -function sendDummy() { - easyrtc.getRoomList( - function() { - easyrtc.showError("xx", "got fresh roomlist"); - }, - function(){ - easyrtc.showError("xx", "failed on fresh roomlist"); - }); -} - -function loginSuccess(easyrtcid) { - document.getElementById("stateLabel").innerHTML = " connected as " + easyrtcid; - easyrtc.showError("xx", "login success"); -} - - -function loginFailure(errorCode, message) { - document.getElementById("stateLabel").innerHTML = "disconnected"; - easyrtc.showError("xx", "login failure"); -} - - diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_room.js b/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_room.js deleted file mode 100644 index 00b4105d80..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_room.js +++ /dev/null @@ -1,726 +0,0 @@ - - -var activeBox = -1; // nothing selected -var aspectRatio = 4/3; // standard definition video aspect ratio -var maxCALLERS = 3; -var numVideoOBJS = maxCALLERS+1; -var layout; - -function getIdOfBox(boxNum) { - return "box" + boxNum; -} - - -function reshapeFull(parentw, parenth) { - return { - left:0, - top:0, - width:parentw, - height:parenth - }; -} - -function reshapeTextEntryBox(parentw, parenth) { - return { - left:parentw/4, - top:parenth/4, - width:parentw/2, - height: parenth/4 - }; -} - -function reshapeTextEntryField(parentw, parenth) { - return { - width:parentw -40 - }; -} - -var margin = 20; - -function reshapeToFullSize(parentw, parenth) { - var left, top, width, height; - var margin= 20; - - if( parentw < parenth*aspectRatio){ - width = parentw -margin; - height = width/aspectRatio; - } - else { - height = parenth-margin; - width = height*aspectRatio; - } - left = (parentw - width)/2; - top = (parenth - height)/2; - return { - left:left, - top:top, - width:width, - height:height - }; -} - -// -// a negative percentLeft is interpreted as setting the right edge of the object -// that distance from the right edge of the parent. -// Similar for percentTop. -// -function setThumbSizeAspect(percentSize, percentLeft, percentTop, parentw, parenth, aspect) { - - var width, height; - if( parentw < parenth*aspectRatio){ - width = parentw * percentSize; - height = width/aspect; - } - else { - height = parenth * percentSize; - width = height*aspect; - } - var left; - if( percentLeft < 0) { - left = parentw - width; - } - else { - left = 0; - } - left += Math.floor(percentLeft*parentw); - var top = 0; - if( percentTop < 0) { - top = parenth - height; - } - else { - top = 0; - } - top += Math.floor(percentTop*parenth); - return { - left:left, - top:top, - width:width, - height:height - }; -} - - -function setThumbSize(percentSize, percentLeft, percentTop, parentw, parenth) { - return setThumbSizeAspect(percentSize, percentLeft, percentTop, parentw, parenth, aspectRatio); -} - -function setThumbSizeButton(percentSize, percentLeft, percentTop, parentw, parenth, imagew, imageh) { - return setThumbSizeAspect(percentSize, percentLeft, percentTop, parentw, parenth, imagew/imageh); -} - - -var sharedVideoWidth = 1; -var sharedVideoHeight = 1; - -function reshape1of2(parentw, parenth) { - if( layout=== 'p' ) { - return { - left: (parentw-sharedVideoWidth)/2, - top: (parenth -sharedVideoHeight*2)/3, - width: sharedVideoWidth, - height: sharedVideoHeight - }; - } - else { - return{ - left: (parentw-sharedVideoWidth*2)/3, - top: (parenth -sharedVideoHeight)/2, - width: sharedVideoWidth, - height: sharedVideoHeight - }; - } -} - - - -function reshape2of2(parentw, parenth){ - if( layout=== 'p' ) { - return { - left: (parentw-sharedVideoWidth)/2, - top: (parenth -sharedVideoHeight*2)/3 *2 + sharedVideoHeight, - width: sharedVideoWidth, - height: sharedVideoHeight - }; - } - else { - return{ - left: (parentw-sharedVideoWidth*2)/3 *2 + sharedVideoWidth, - top: (parenth -sharedVideoHeight)/2, - width: sharedVideoWidth, - height: sharedVideoHeight - }; - } -} - -function reshape1of3(parentw, parenth) { - if( layout=== 'p' ) { - return { - left: (parentw-sharedVideoWidth)/2, - top: (parenth -sharedVideoHeight*3)/4 , - width: sharedVideoWidth, - height: sharedVideoHeight - }; - } - else { - return{ - left: (parentw-sharedVideoWidth*2)/3, - top: (parenth -sharedVideoHeight*2)/3, - width: sharedVideoWidth, - height: sharedVideoHeight - }; - } -} - -function reshape2of3(parentw, parenth){ - if( layout=== 'p' ) { - return { - left: (parentw-sharedVideoWidth)/2, - top: (parenth -sharedVideoHeight*3)/4*2+ sharedVideoHeight, - width: sharedVideoWidth, - height: sharedVideoHeight - }; - } - else { - return{ - left: (parentw-sharedVideoWidth*2)/3*2+sharedVideoWidth, - top: (parenth -sharedVideoHeight*2)/3, - width: sharedVideoWidth, - height: sharedVideoHeight - }; - } -} - -function reshape3of3(parentw, parenth) { - if( layout=== 'p' ) { - return { - left: (parentw-sharedVideoWidth)/2, - top: (parenth -sharedVideoHeight*3)/4*3+ sharedVideoHeight*2, - width: sharedVideoWidth, - height: sharedVideoHeight - }; - } - else { - return{ - left: (parentw-sharedVideoWidth*2)/3*1.5+sharedVideoWidth/2, - top: (parenth -sharedVideoHeight*2)/3*2+ sharedVideoHeight, - width: sharedVideoWidth, - height: sharedVideoHeight - }; - } -} - - -function reshape1of4(parentw, parenth) { - return { - left: (parentw - sharedVideoWidth*2)/3, - top: (parenth - sharedVideoHeight*2)/3, - width: sharedVideoWidth, - height: sharedVideoHeight - }; -} - -function reshape2of4(parentw, parenth) { - return { - left: (parentw - sharedVideoWidth*2)/3*2+ sharedVideoWidth, - top: (parenth - sharedVideoHeight*2)/3, - width: sharedVideoWidth, - height: sharedVideoHeight - }; -} -function reshape3of4(parentw, parenth) { - return { - left: (parentw - sharedVideoWidth*2)/3, - top: (parenth - sharedVideoHeight*2)/3*2 + sharedVideoHeight, - width: sharedVideoWidth, - height: sharedVideoHeight - }; -} - -function reshape4of4(parentw, parenth) { - return { - left: (parentw - sharedVideoWidth*2)/3*2 + sharedVideoWidth, - top: (parenth - sharedVideoHeight*2)/3*2 + sharedVideoHeight, - width: sharedVideoWidth, - height: sharedVideoHeight - }; -} - -var boxUsed = [true, false, false, false]; -var connectCount = 0; - - -function setSharedVideoSize(parentw, parenth) { - layout = ((parentw /aspectRatio) < parenth)?'p':'l'; - var w, h; - - function sizeBy(fullsize, numVideos) { - return (fullsize - margin*(numVideos+1) )/numVideos; - } - - switch(layout+(connectCount+1)) { - case 'p1': - case 'l1': - w = sizeBy(parentw, 1); - h = sizeBy(parenth, 1); - break; - case 'l2': - w = sizeBy(parentw, 2); - h = sizeBy(parenth, 1); - break; - case 'p2': - w = sizeBy(parentw, 1); - h = sizeBy(parenth, 2); - break; - case 'p4': - case 'l4': - case 'l3': - w = sizeBy(parentw, 2); - h = sizeBy(parenth, 2); - break; - case 'p3': - w = sizeBy(parentw, 1); - h = sizeBy(parenth, 3); - break; - } - sharedVideoWidth = Math.min(w, h * aspectRatio); - sharedVideoHeight = Math.min(h, w/aspectRatio); -} - -var reshapeThumbs = [ - function(parentw, parenth) { - - if( activeBox > 0 ) { - return setThumbSize(0.20, 0.01, 0.01, parentw, parenth); - } - else { - setSharedVideoSize(parentw, parenth); - switch(connectCount) { - case 0:return reshapeToFullSize(parentw, parenth); - case 1:return reshape1of2(parentw, parenth); - case 2:return reshape1of3(parentw, parenth); - case 3:return reshape1of4(parentw, parenth); - } - } - }, - function(parentw, parenth) { - if( activeBox >= 0 || !boxUsed[1]) { - return setThumbSize(0.20, 0.01, -0.01, parentw, parenth); - } - else{ - switch(connectCount) { - case 1: - return reshape2of2(parentw, parenth); - case 2: - return reshape2of3(parentw, parenth); - case 3: - return reshape2of4(parentw, parenth); - } - } - }, - function(parentw, parenth) { - if( activeBox >= 0 || !boxUsed[2] ) { - return setThumbSize(0.20, -0.01, 0.01, parentw, parenth); - } - else { - switch(connectCount){ - case 1: - return reshape2of2(parentw, parenth); - case 2: - if( !boxUsed[1]) { - return reshape2of3(parentw, parenth); - } - else { - return reshape3of3(parentw, parenth); - } - case 3: - return reshape3of4(parentw, parenth); - } - } - }, - function(parentw, parenth) { - if( activeBox >= 0 || !boxUsed[3]) { - return setThumbSize(0.20, -0.01, -0.01, parentw, parenth); - } - else{ - switch(connectCount){ - case 1: - return reshape2of2(parentw, parenth); - case 2: - return reshape3of3(parentw, parenth); - case 3: - return reshape4of4(parentw, parenth); - } - } - } -]; - - -function killButtonReshaper(parentw, parenth) { - var imagew = 128; - var imageh = 128; - if( parentw < parenth) { - return setThumbSizeButton(0.1, -.51, -0.01, parentw, parenth, imagew, imageh); - } - else { - return setThumbSizeButton(0.1, -.01, -.51, parentw, parenth, imagew, imageh); - } -} - - -function muteButtonReshaper(parentw, parenth) { - var imagew = 32; - var imageh = 32; - if( parentw < parenth) { - return setThumbSizeButton(0.10, -.51, 0.01, parentw, parenth, imagew, imageh); - } - else { - return setThumbSizeButton(0.10, 0.01, -.51, parentw, parenth, imagew, imageh); - } -} - -function reshapeTextEntryButton(parentw, parenth) { - var imagew = 32; - var imageh = 32; - if( parentw < parenth) { - return setThumbSizeButton(0.10, .51, 0.01, parentw, parenth, imagew, imageh); - } - else { - return setThumbSizeButton(0.10, 0.01, .51, parentw, parenth, imagew, imageh); - } -} - - -function handleWindowResize() { - var fullpage = document.getElementById('fullpage'); - fullpage.style.width = window.innerWidth + "px"; - fullpage.style.height = window.innerHeight + "px"; - connectCount = easyrtc.getConnectionCount(); - - function applyReshape(obj, parentw, parenth) { - var myReshape = obj.reshapeMe(parentw, parenth); - - if(typeof myReshape.left !== 'undefined' ) { - obj.style.left = Math.round(myReshape.left) + "px"; - } - if(typeof myReshape.top !== 'undefined' ) { - obj.style.top = Math.round(myReshape.top) + "px"; - } - if(typeof myReshape.width !== 'undefined' ) { - obj.style.width = Math.round(myReshape.width) + "px"; - } - if(typeof myReshape.height !== 'undefined' ) { - obj.style.height = Math.round(myReshape.height) + "px"; - } - - var n = obj.childNodes.length; - for(var i = 0; i < n; i++ ) { - var childNode = obj.childNodes[i]; - if( childNode.reshapeMe) { - applyReshape(childNode, myReshape.width, myReshape.height); - } - } - } - - applyReshape(fullpage, window.innerWidth, window.innerHeight); -} - - -function setReshaper(elementId, reshapeFn) { - var element = document.getElementById(elementId); - if( !element) { - alert("Attempt to apply to reshapeFn to non-existent element " + elementId); - } - if( !reshapeFn) { - alert("Attempt to apply misnamed reshapeFn to element " + elementId); - } - element.reshapeMe = reshapeFn; -} - - -function collapseToThumbHelper() { - if( activeBox >= 0) { - var id = getIdOfBox(activeBox); - document.getElementById(id).style.zIndex = 2; - setReshaper(id, reshapeThumbs[activeBox]); - document.getElementById('muteButton').style.display = "none"; - document.getElementById('killButton').style.display = "none"; - activeBox = -1; - } -} - -function collapseToThumb() { - collapseToThumbHelper(); - activeBox = -1; - updateMuteImage(false); - handleWindowResize(); - -} - -function updateMuteImage(toggle) { - var muteButton = document.getElementById('muteButton'); - if( activeBox > 0) { // no kill button for self video - muteButton.style.display = "block"; - var videoObject = document.getElementById( getIdOfBox(activeBox)); - var isMuted = videoObject.muted?true:false; - if( toggle) { - isMuted = !isMuted; - videoObject.muted = isMuted; - } - muteButton.src = isMuted?"images/button_unmute.png":"images/button_mute.png"; - } - else { - muteButton.style.display = "none"; - } -} - - -function expandThumb(whichBox) { - var lastActiveBox = activeBox; - if( activeBox >= 0 ) { - collapseToThumbHelper(); - } - if( lastActiveBox !== whichBox) { - var id = getIdOfBox(whichBox); - activeBox = whichBox; - setReshaper(id, reshapeToFullSize); - document.getElementById(id).style.zIndex = 1; - if( whichBox > 0) { - document.getElementById('muteButton').style.display = "block"; - updateMuteImage(); - document.getElementById('killButton').style.display = "block"; - } - } - updateMuteImage(false); - handleWindowResize(); -} - -function prepVideoBox(whichBox) { - var id = getIdOfBox(whichBox); - setReshaper(id, reshapeThumbs[whichBox]); - document.getElementById(id).onclick = function() { - expandThumb(whichBox); - }; -} - - -function killActiveBox() { - if( activeBox > 0) { - var easyrtcid = easyrtc.getIthCaller(activeBox-1); - collapseToThumb(); - setTimeout( function() { - easyrtc.hangup(easyrtcid); - easyrtc.sendServerMessage(null, "hangup", {hangupEasyrtcid:caller}); - }, 400); - } -} - - -function muteActiveBox() { - updateMuteImage(true); -} - - - - -function callEverybodyElse(roomName, otherPeople) { - - easyrtc.setRoomOccupantListener(null, null); // so we're only called once. - - var list = []; - var connectCount = 0; - - for(var i in otherPeople ) { - list.push(i); - } - - // - // Connect in reverse order. Latter arriving people are more likely to have - // empty slots. - // - function establishConnection(position) { - function callSuccess() { - connectCount++; - if( connectCount < maxCALLERS && position > 0) { - establishConnection(position-1); - } - } - function callFailure(errorCode, errorText) { - easyrtc.showError(errorCode, errorText); - if( connectCount < maxCALLERS && position > 0) { - establishConnection(position-1); - } - } - easyrtc.call(list[position], callSuccess, callFailure); - - } - if( list.length > 0) { - establishConnection(list.length-1); - } -} - - -function loginSuccess() { - console.log("Successfully connected"); - expandThumb(0); // expand the mirror image initially. -} - -function loginFailure(errorCode, errorText ) { - easyrtc.showError(errorCode, errorText); -} - - -function cancelText() { - document.getElementById('textentryBox').style.display = "none"; - document.getElementById('textEntryButton').style.display = "block"; -} - - -function sendText(e) { - document.getElementById('textentryBox').style.display = "none"; - document.getElementById('textEntryButton').style.display = "block"; - var stringToSend = document.getElementById('textentryField').value; - if( stringToSend && stringToSend !== "") { - for(var i = 0; i < maxCALLERS; i++ ) { - var easyrtcid = easyrtc.getIthCaller(i); - if( easyrtcid && easyrtcid !== "") { - easyrtc.sendPeerMessage(easyrtcid, "img", stringToSend); - } - } - } - return false; -} - - -function showTextEntry() { - document.getElementById('textentryField').value = ""; - document.getElementById('textentryBox').style.display = "block"; - document.getElementById('textEntryButton').style.display = "none"; - document.getElementById('textentryField').focus(); -} - - -function showMessage(startX, startY, content) { - var fullPage = document.getElementById('fullpage'); - var fullW = parseInt(fullPage.offsetWidth); - var fullH = parseInt(fullPage.offsetHeight); - var centerEndX = .2*startX + .8*fullW/2; - var centerEndY = .2*startY + .8*fullH/2; - - var cloudObject = document.createElement("img"); - cloudObject.src = "images/cloud.png"; - cloudObject.onload = function() { - cloudObject.style.left = startX + "px"; - cloudObject.style.top = startY + "px"; - cloudObject.style.width = "4px"; - cloudObject.style.height = "4px"; - cloudObject.style.opacity = 0.7; - cloudObject.style.zIndex = 5; - cloudObject.className = "transit boxCommon"; - fullPage.appendChild(cloudObject); - var textObject; - function removeCloud() { - if( textObject) { - fullPage.removeChild(textObject); - fullPage.removeChild(cloudObject); - } - } - setTimeout(function() { - cloudObject.style.left = centerEndX - fullW/4 + "px"; - cloudObject.style.top = centerEndY - fullH/4+ "px"; - cloudObject.style.width = (fullW/2) + "px"; - cloudObject.style.height = (fullH/2) + "px"; - }, 10); - setTimeout(function() { - textObject = document.createElement('div'); - textObject.className = "boxCommon"; - textObject.style.left = Math.floor(centerEndX-fullW/8) + "px"; - textObject.style.top = Math.floor(centerEndY) + "px"; - textObject.style.fontSize = "36pt"; - textObject.style.width = (fullW*.4) + "px"; - textObject.style.height = (fullH*.4) + "px"; - textObject.style.zIndex = 6; - textObject.appendChild( document.createTextNode(content)); - fullPage.appendChild(textObject); - textObject.onclick = removeCloud; - cloudObject.onclick = removeCloud; - }, 1000); - setTimeout(function() { - cloudObject.style.left = startX + "px"; - cloudObject.style.top = startY + "px"; - cloudObject.style.width = "4px"; - cloudObject.style.height = "4px"; - fullPage.removeChild(textObject); - }, 9000); - setTimeout(function(){ - fullPage.removeChild(cloudObject); - }, 10000); - }; -} - -function messageListener(easyrtcid, msgType, content) { - for(var i = 0; i < maxCALLERS; i++) { - if( easyrtc.getIthCaller(i) === easyrtcid) { - var startArea = document.getElementById(getIdOfBox(i+1)); - var startX = parseInt(startArea.offsetLeft) + parseInt(startArea.offsetWidth)/2; - var startY = parseInt(startArea.offsetTop) + parseInt(startArea.offsetHeight)/2; - showMessage(startX, startY, content); - } - } -} - - -function appInit() { - - // Prep for the top-down layout manager - setReshaper('fullpage', reshapeFull); - for(var i = 0; i < numVideoOBJS; i++) { - prepVideoBox(i); - } - setReshaper('killButton', killButtonReshaper); - setReshaper('muteButton', muteButtonReshaper); - setReshaper('textentryBox', reshapeTextEntryBox); - setReshaper('textentryField', reshapeTextEntryField); - setReshaper('textEntryButton', reshapeTextEntryButton); - - updateMuteImage(false); - window.onresize = handleWindowResize; - handleWindowResize(); //initial call of the top-down layout manager - - // easyrtc.setVideoBandwidth(20); - easyrtc.setRoomOccupantListener(callEverybodyElse); - easyrtc.easyApp("easyrtc.room", "box0", ["box1", "box2", "box3"], loginSuccess, loginFailure); - easyrtc.setPeerListener(messageListener); - easyrtc.setDisconnectListener( function() { - easyrtc.showError("LOST-CONNECTION", "Lost connection to signaling server"); - }); - easyrtc.setOnCall( function(easyrtcid, slot) { - boxUsed[slot+1] = true; - if(activeBox === 0 && easyrtc.getConnectionCount() === 1) { // first connection - collapseToThumb(); - document.getElementById('textEntryButton').style.display = 'block'; - } - document.getElementById(getIdOfBox(slot+1)).style.visibility = "visible"; - handleWindowResize(); - }); - - - easyrtc.setOnHangup(function(easyrtcid, slot) { - boxUsed[slot+1] = false; - console.log("hanging up on " + easyrtcid); - if(activeBox > 0 && slot+1 === activeBox) { - collapseToThumb(); - } - setTimeout(function() { - document.getElementById(getIdOfBox(slot+1)).style.visibility = "hidden"; - - if( easyrtc.getConnectionCount() === 0 ) { // no more connections - expandThumb(0); - document.getElementById('textEntryButton').style.display = 'none'; - document.getElementById('textentryBox').style.display = 'none'; - } - handleWindowResize(); - },20); - }); -} - - diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_screen_receive.js b/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_screen_receive.js deleted file mode 100644 index d60aca8874..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_screen_receive.js +++ /dev/null @@ -1,209 +0,0 @@ -// -//Copyright (c) 2014, Priologic Software Inc. -//All rights reserved. -// -//Redistribution and use in source and binary forms, with or without -//modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -//AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -//LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -//CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -//SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -//INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -//CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -//POSSIBILITY OF SUCH DAMAGE. -// -var selfEasyrtcid = ""; - - -function initApp() { - if( window.localStorage && window.localStorage.easyrtcUserName ) { - document.getElementById('userName').value = window.localStorage.easyrtcUserName; - } -} - -function disable(domId) { - document.getElementById(domId).disabled = "disabled"; -} - - -function enable(domId) { - document.getElementById(domId).disabled = ""; -} - - -function connect() { - console.log("Initializing."); - - var userName = document.getElementById('userName').value; - if( !easyrtc.isNameValid(userName)) { - easyrtc.showError("BAD-USER-NAME", "illegal user name"); - return; - } - - easyrtc.setUsername(userName); - if( window.localStorage ) { - window.localStorage.easyrtcUserName = document.getElementById('userName').value; - } - - - easyrtc.enableAudio(document.getElementById('shareAudio').checked); - easyrtc.enableVideo(false); - easyrtc.setRoomOccupantListener(convertListToButtons); - easyrtc.connect("easyrtc.videoScreen", loginSuccess, loginFailure); - -} - - -function hangup() { - easyrtc.hangupAll(); - disable('hangupButton'); -} - - - -// -// this method actually just removes old buttons. -// The adding of buttons is done with the data listener. -// -function convertListToButtons(roomName, data, isPrimary){ - console.log("saw data list of " + JSON.stringify(data)); - var otherClientDiv = document.getElementById('otherClients'); - var i, nextChild; - - for( i = otherClientDiv.childNodes[0]; i; i = nextChild ){ - nextChild = i.nextSibling; - var buttonId = i.id; - if( !data[buttonId]){ - console.log(" removing button with id " + buttonId); - otherClientDiv.removeChild(i); - } - } -} - - - - - -function requestFullScreen() { - var elem = document.getElementById('videos'); - elem.className = 'bigBox'; - if (elem.requestFullscreen) { - elem.requestFullscreen(); - } else if (elem.mozRequestFullScreen) { - elem.mozRequestFullScreen(); - } else if (elem.webkitRequestFullscreen) { - elem.webkitRequestFullscreen(); - } - var hideBox = document.getElementById('shrinkBox'); - hideBox.className = 'yesShrink'; - hideBox.onclick = function() { - hideBox.className = 'noShrink'; - if (document.exitFullscreen) { - document.exitFullscreen(); - } - else if (document.mozCancelFullScreen) { - document.mozCancelFullScreen(); - } - else if (document.webkitCancelFullScreen) { - document.webkitCancelFullScreen(); - } - elem.className = 'smallBox'; - }; - -} - - -easyrtc.setPeerListener(function(easyrtcid, msgType, data){ - var otherClientDiv = document.getElementById('otherClients'); - var button = document.createElement('button'); - button.onclick = function(easyrtcid) { - return function() { - performCall(easyrtcid); - }; - }(easyrtcid); - button.id = "callbutton_" +easyrtcid; - console.log("adding button for id =" + easyrtcid); - var label = document.createTextNode("Get screen of " + easyrtc.idToName(easyrtcid)); - button.appendChild(label); - otherClientDiv.appendChild(button); -}); - - -function performCall(otherEasyrtcid) { - easyrtc.hangupAll(); - var acceptedCB = function(accepted, easyrtcid) { - if( !accepted ) { - easyrtc.showError("CALL-REJECTED", "Sorry, your call to " + easyrtc.idToName(easyrtcid) + " was rejected"); - enable('otherClients'); - } - }; - - var successCB = function() { - enable('hangupButton'); - }; - var failureCB = function() { - enable('otherClients'); - }; - easyrtc.call(otherEasyrtcid, successCB, failureCB, acceptedCB); - enable('hangupButton'); -} - - -function loginSuccess(easyrtcid) { - disable("connectButton"); - enable("disconnectButton"); - enable('otherClients'); - document.getElementById("iam").innerHTML = "Connected"; - selfEasyrtcid = easyrtcid; -} - - -function loginFailure(errorCode, message) { - easyrtc.showError("LOGIN-FAILURE", "failure to login"); -} - - -function disconnect() { - document.getElementById("iam").innerHTML = "logged out"; - easyrtc.disconnect(); - console.log("disconnecting from server"); - enable("connectButton"); - disable("disconnectButton"); -} - - -easyrtc.setStreamAcceptor( function(caller, stream) { - var video = document.getElementById('callerVideo'); - easyrtc.setVideoObjectSrc(video,stream); - console.log("saw video from " + caller); - enable("hangupButton"); -}); - - - -easyrtc.setOnStreamClosed( function (easyrtcid) { - easyrtc.setVideoObjectSrc(document.getElementById('callerVideo'), ""); - document.cancelFullScreen(); - disable("hangupButton"); -}); - - -var callerPending = null; - -easyrtc.setCallCancelled( function(easyrtcid){ - if( easyrtcid === callerPending) { - document.getElementById('acceptCallBox').style.display = "none"; - callerPending = false; - } -}); diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_screen_send.js b/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_screen_send.js deleted file mode 100644 index 8a20ceecf8..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_screen_send.js +++ /dev/null @@ -1,156 +0,0 @@ -// -//Copyright (c) 2014, Priologic Software Inc. -//All rights reserved. -// -//Redistribution and use in source and binary forms, with or without -//modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -//AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -//LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -//CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -//SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -//INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -//CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -//POSSIBILITY OF SUCH DAMAGE. -// -var selfEasyrtcid = ""; - -function initApp() { - if( window.localStorage && window.localStorage.easyrtcUserName ) { - document.getElementById('userName').value = window.localStorage.easyrtcUserName; - } -} - - -function disable(domId) { - document.getElementById(domId).disabled = "disabled"; -} - - -function enable(domId) { - document.getElementById(domId).disabled = ""; -} - -var contactedListeners = {}; -var nameToIdMap = {}; - -function connect() { - easyrtc.enableDebug(false); - var tempName = document.getElementById('userName').value; - if( !easyrtc.isNameValid(tempName)) { - easyrtc.showError("BAD-USER-NAME", "illegal user name"); - return; - } - easyrtc.setUsername(tempName); - if( window.localStorage && window.localStorage.easyrtcUserName ) { - window.localStorage.easyrtcUserName = tempName; - } - console.log("Initializing with username " + tempName); - easyrtc.setScreenCapture(); - easyrtc.enableAudio(document.getElementById("shareAudio").checked); - easyrtc.setRoomOccupantListener(function (roomName, otherPeers){ - var easyrtcid; - for(easyrtcid in otherPeers ) { - if( !contactedListeners[easyrtcid]) { - easyrtc.sendPeerMessage(easyrtcid, "available", { - sender:true - }, function(){}, function(errCode, errorText) { - console.log("messaging error" + errorText); - }); - } - } - contactedListeners = otherPeers; - }); - - easyrtc.setPeerListener(function(easyrtcid, msgType, data){}); - - easyrtc.connect("easyrtc.videoScreen", loginSuccess, loginFailure); -} - - -function hangup() { - easyrtc.hangupAll(); - disable('hangupButton'); -} - - -function loginSuccess(easyrtcid) { - disable("connectButton"); - disable("shareAudio"); - enable("disconnectButton"); - selfEasyrtcid = easyrtcid; - document.getElementById("iam").innerHTML = "Connected"; -} - - -function loginFailure(errorCode, message) { - easyrtc.showError(errorCode, message); -} - - -function disconnect() { - document.getElementById("iam").innerHTML = "logged out"; - easyrtc.disconnect(); - enable("shareAudio"); - console.log("disconnecting from server"); - enable("connectButton"); - disable("disconnectButton"); - easyrtc.setVideoObjectSrc(document.getElementById('callerAudio'), ""); -} - - -easyrtc.setStreamAcceptor( function(easyrtcid, stream) { - var audio = document.getElementById('callerAudio'); - easyrtc.setVideoObjectSrc(audio,stream); - console.log("got audio from " + easyrtc.idToName(easyrtcid)); - enable("hangupButton"); -}); - - - -easyrtc.setOnStreamClosed( function (easyrtcid) { - easyrtc.setVideoObjectSrc(document.getElementById('callerAudio'), ""); - disable("hangupButton"); -}); - - -var callerPending = null; - -easyrtc.setCallCancelled( function(easyrtcid){ - if( easyrtcid === callerPending) { - document.getElementById('acceptCallBox').style.display = "none"; - callerPending = false; - } -}); - - -easyrtc.setAcceptChecker(function(easyrtcid, cb) { - document.getElementById('acceptCallBox').style.display = "block"; - callerPending = easyrtcid; - - document.getElementById('acceptCallLabel').innerHTML = "Accept incoming call from " + easyrtc.idToName(easyrtcid) + " ?"; - - var acceptTheCall = function(wasAccepted) { - document.getElementById('acceptCallBox').style.display = "none"; - cb(wasAccepted); - callerPending = null; - }; - document.getElementById("callAcceptButton").onclick = function() { - console.log("accepted the call"); - acceptTheCall(true); - }; - document.getElementById("callRejectButton").onclick =function() { - console.log("rejected the call"); - acceptTheCall(false); - }; -} ); \ No newline at end of file diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_video_only.js b/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_video_only.js deleted file mode 100644 index dc384ac64f..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/demo_video_only.js +++ /dev/null @@ -1,176 +0,0 @@ -// -//Copyright (c) 2014, Priologic Software Inc. -//All rights reserved. -// -//Redistribution and use in source and binary forms, with or without -//modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -//AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -//IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -//ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -//LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -//CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -//SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -//INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -//CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -//ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -//POSSIBILITY OF SUCH DAMAGE. -// -var selfEasyrtcid = ""; - -function disable(domId) { - document.getElementById(domId).disabled = "disabled"; -} - - -function enable(domId) { - document.getElementById(domId).disabled = ""; -} - - -function connect() { - easyrtc.enableDebug(false); - console.log("Initializing."); - easyrtc.enableAudio(false); - easyrtc.enableAudioReceive(false); - easyrtc.setRoomOccupantListener(convertListToButtons); - easyrtc.initMediaSource( - function(){ // success callback - var selfVideo = document.getElementById("selfVideo"); - easyrtc.setVideoObjectSrc(selfVideo, easyrtc.getLocalStream()); - easyrtc.connect("easyrtc.videoOnly", loginSuccess, loginFailure); - }, - function(errorCode, errmesg){ - easyrtc.showError("MEDIA-ERROR", errmesg); - } // failure callback - ); -} - - -function terminatePage() { - easyrtc.disconnect(); -} - - -function hangup() { - easyrtc.hangupAll(); - disable('hangupButton'); -} - - -function clearConnectList() { - var otherClientDiv = document.getElementById('otherClients'); - while (otherClientDiv.hasChildNodes()) { - otherClientDiv.removeChild(otherClientDiv.lastChild); - } - -} - - -function convertListToButtons (roomName, occupants, isPrimary) { - clearConnectList(); - var otherClientDiv = document.getElementById('otherClients'); - for(var easyrtcid in occupants) { - var button = document.createElement('button'); - button.onclick = function(easyrtcid) { - return function() { - performCall(easyrtcid); - }; - }(easyrtcid); - - var label = document.createTextNode( easyrtc.idToName(easyrtcid)); - button.appendChild(label); - otherClientDiv.appendChild(button); - } - if( !otherClientDiv.hasChildNodes() ) { - otherClientDiv.innerHTML = "Nobody else is on..."; - } -} - - -function performCall(otherEasyrtcid) { - easyrtc.hangupAll(); - var acceptedCB = function(accepted, easyrtcid) { - if( !accepted ) { - easyrtc.showError("CALL-REJECTED", "Sorry, your call to " + easyrtc.idToName(easyrtcid) + " was rejected"); - enable('otherClients'); - } - }; - var successCB = function() { - enable('hangupButton'); - }; - var failureCB = function() { - enable('otherClients'); - }; - easyrtc.call(otherEasyrtcid, successCB, failureCB, acceptedCB); -} - - -function loginSuccess(easyrtcid) { - disable("connectButton"); - // enable("disconnectButton"); - enable('otherClients'); - selfEasyrtcid = easyrtcid; - document.getElementById("iam").innerHTML = "I am " + easyrtcid; -} - - -function loginFailure(errorCode, message) { - easyrtc.showError(errorCode, message); -} - - -function disconnect() { - document.getElementById("iam").innerHTML = "logged out"; - easyrtc.disconnect(); - console.log("disconnecting from server"); - enable("connectButton"); - // disable("disconnectButton"); - clearConnectList(); - easyrtc.setVideoObjectSrc(document.getElementById('selfVideo'), ""); -} - - -easyrtc.setStreamAcceptor( function(easyrtcid, stream) { - var video = document.getElementById('callerVideo'); - easyrtc.setVideoObjectSrc(video,stream); - console.log("saw video from " + easyrtcid); - enable("hangupButton"); -}); - - -easyrtc.setOnStreamClosed( function (easyrtcid) { - easyrtc.setVideoObjectSrc(document.getElementById('callerVideo'), ""); - disable("hangupButton"); -}); - - -easyrtc.setAcceptChecker(function(easyrtcid, callback) { - document.getElementById('acceptCallBox').style.display = "block"; - if( easyrtc.getConnectionCount() > 0 ) { - document.getElementById('acceptCallLabel').innerHTML = "Drop current call and accept new from " + easyrtc.idToName(easyrtcid) + " ?"; - } - else { - document.getElementById('acceptCallLabel').innerHTML = "Accept incoming call from " + easyrtc.idToName(easyrtcid) + " ?"; - } - var acceptTheCall = function(wasAccepted) { - document.getElementById('acceptCallBox').style.display = "none"; - if( wasAccepted && easyrtc.getConnectionCount() > 0 ) { - easyrtc.hangupAll(); - } - callback(wasAccepted); - }; - document.getElementById("callAcceptButton").onclick = function() { - acceptTheCall(true); - }; - document.getElementById("callRejectButton").onclick =function() { - acceptTheCall(false); - }; -} ); diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/prettify/README b/messenger/js/easyrtc/node_modules/easyrtc/demos/js/prettify/README deleted file mode 100644 index 1b259b9212..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/prettify/README +++ /dev/null @@ -1,214 +0,0 @@ -This folder contains code from the Google Code Prettify Project. - -EasyRTC uses Prettify within its demo applications to display the source code nicely to the user. - -The project homepage can be found at https://code.google.com/p/google-code-prettify/ - -Our Changes: ------------- - 1. Removed some language files for programming languages we weren't going to be using - 2. Small change to the css file to enable line numbers to be shown on every line - -License: --------- - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/prettify/jquery-1.9.1.min.js b/messenger/js/easyrtc/node_modules/easyrtc/demos/js/prettify/jquery-1.9.1.min.js deleted file mode 100644 index 006e953102..0000000000 --- a/messenger/js/easyrtc/node_modules/easyrtc/demos/js/prettify/jquery-1.9.1.min.js +++ /dev/null @@ -1,5 +0,0 @@ -/*! jQuery v1.9.1 | (c) 2005, 2012 jQuery Foundation, Inc. | jquery.org/license -//@ sourceMappingURL=jquery.min.map -*/(function(e,t){var n,r,i=typeof t,o=e.document,a=e.location,s=e.jQuery,u=e.$,l={},c=[],p="1.9.1",f=c.concat,d=c.push,h=c.slice,g=c.indexOf,m=l.toString,y=l.hasOwnProperty,v=p.trim,b=function(e,t){return new b.fn.init(e,t,r)},x=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,w=/\S+/g,T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,N=/^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,k=/^[\],:{}\s]*$/,E=/(?:^|:|,)(?:\s*\[)+/g,S=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,A=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,j=/^-ms-/,D=/-([\da-z])/gi,L=function(e,t){return t.toUpperCase()},H=function(e){(o.addEventListener||"load"===e.type||"complete"===o.readyState)&&(q(),b.ready())},q=function(){o.addEventListener?(o.removeEventListener("DOMContentLoaded",H,!1),e.removeEventListener("load",H,!1)):(o.detachEvent("onreadystatechange",H),e.detachEvent("onload",H))};b.fn=b.prototype={jquery:p,constructor:b,init:function(e,n,r){var i,a;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof b?n[0]:n,b.merge(this,b.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:o,!0)),C.test(i[1])&&b.isPlainObject(n))for(i in n)b.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(a=o.getElementById(i[2]),a&&a.parentNode){if(a.id!==i[2])return r.find(e);this.length=1,this[0]=a}return this.context=o,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):b.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),b.makeArray(e,this))},selector:"",length:0,size:function(){return this.length},toArray:function(){return h.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=b.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return b.each(this,e,t)},ready:function(e){return b.ready.promise().done(e),this},slice:function(){return this.pushStack(h.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(b.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:d,sort:[].sort,splice:[].splice},b.fn.init.prototype=b.fn,b.extend=b.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},u=1,l=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},u=2),"object"==typeof s||b.isFunction(s)||(s={}),l===u&&(s=this,--u);l>u;u++)if(null!=(o=arguments[u]))for(i in o)e=s[i],r=o[i],s!==r&&(c&&r&&(b.isPlainObject(r)||(n=b.isArray(r)))?(n?(n=!1,a=e&&b.isArray(e)?e:[]):a=e&&b.isPlainObject(e)?e:{},s[i]=b.extend(c,a,r)):r!==t&&(s[i]=r));return s},b.extend({noConflict:function(t){return e.$===b&&(e.$=u),t&&e.jQuery===b&&(e.jQuery=s),b},isReady:!1,readyWait:1,holdReady:function(e){e?b.readyWait++:b.ready(!0)},ready:function(e){if(e===!0?!--b.readyWait:!b.isReady){if(!o.body)return setTimeout(b.ready);b.isReady=!0,e!==!0&&--b.readyWait>0||(n.resolveWith(o,[b]),b.fn.trigger&&b(o).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===b.type(e)},isArray:Array.isArray||function(e){return"array"===b.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[m.call(e)]||"object":typeof e},isPlainObject:function(e){if(!e||"object"!==b.type(e)||e.nodeType||b.isWindow(e))return!1;try{if(e.constructor&&!y.call(e,"constructor")&&!y.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||y.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||o;var r=C.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=b.buildFragment([e],t,i),i&&b(i).remove(),b.merge([],r.childNodes))},parseJSON:function(n){return e.JSON&&e.JSON.parse?e.JSON.parse(n):null===n?n:"string"==typeof n&&(n=b.trim(n),n&&k.test(n.replace(S,"@").replace(A,"]").replace(E,"")))?Function("return "+n)():(b.error("Invalid JSON: "+n),t)},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return r&&r.documentElement&&!r.getElementsByTagName("parsererror").length||b.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&b.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(j,"ms-").replace(D,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,a=M(e);if(n){if(a){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(a){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:v&&!v.call("\ufeff\u00a0")?function(e){return null==e?"":v.call(e)}:function(e){return null==e?"":(e+"").replace(T,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(M(Object(e))?b.merge(n,"string"==typeof e?[e]:e):d.call(n,e)),n},inArray:function(e,t,n){var r;if(t){if(g)return g.call(t,e,n);for(r=t.length,n=n?0>n?Math.max(0,r+n):n:0;r>n;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,o=0;if("number"==typeof r)for(;r>o;o++)e[i++]=n[o];else while(n[o]!==t)e[i++]=n[o++];return e.length=i,e},grep:function(e,t,n){var r,i=[],o=0,a=e.length;for(n=!!n;a>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,a=M(e),s=[];if(a)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(s[s.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(s[s.length]=r);return f.apply([],s)},guid:1,proxy:function(e,n){var r,i,o;return"string"==typeof n&&(o=e[n],n=e,e=o),b.isFunction(e)?(r=h.call(arguments,2),i=function(){return e.apply(n||this,r.concat(h.call(arguments)))},i.guid=e.guid=e.guid||b.guid++,i):t},access:function(e,n,r,i,o,a,s){var u=0,l=e.length,c=null==r;if("object"===b.type(r)){o=!0;for(u in r)b.access(e,n,u,r[u],!0,a,s)}else if(i!==t&&(o=!0,b.isFunction(i)||(s=!0),c&&(s?(n.call(e,i),n=null):(c=n,n=function(e,t,n){return c.call(b(e),n)})),n))for(;l>u;u++)n(e[u],r,s?i:i.call(e[u],u,n(e[u],r)));return o?e:c?n.call(e):l?n(e[0],r):a},now:function(){return(new Date).getTime()}}),b.ready.promise=function(t){if(!n)if(n=b.Deferred(),"complete"===o.readyState)setTimeout(b.ready);else if(o.addEventListener)o.addEventListener("DOMContentLoaded",H,!1),e.addEventListener("load",H,!1);else{o.attachEvent("onreadystatechange",H),e.attachEvent("onload",H);var r=!1;try{r=null==e.frameElement&&o.documentElement}catch(i){}r&&r.doScroll&&function a(){if(!b.isReady){try{r.doScroll("left")}catch(e){return setTimeout(a,50)}q(),b.ready()}}()}return n.promise(t)},b.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){l["[object "+t+"]"]=t.toLowerCase()});function M(e){var t=e.length,n=b.type(e);return b.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}r=b(o);var _={};function F(e){var t=_[e]={};return b.each(e.match(w)||[],function(e,n){t[n]=!0}),t}b.Callbacks=function(e){e="string"==typeof e?_[e]||F(e):b.extend({},e);var n,r,i,o,a,s,u=[],l=!e.once&&[],c=function(t){for(r=e.memory&&t,i=!0,a=s||0,s=0,o=u.length,n=!0;u&&o>a;a++)if(u[a].apply(t[0],t[1])===!1&&e.stopOnFalse){r=!1;break}n=!1,u&&(l?l.length&&c(l.shift()):r?u=[]:p.disable())},p={add:function(){if(u){var t=u.length;(function i(t){b.each(t,function(t,n){var r=b.type(n);"function"===r?e.unique&&p.has(n)||u.push(n):n&&n.length&&"string"!==r&&i(n)})})(arguments),n?o=u.length:r&&(s=t,c(r))}return this},remove:function(){return u&&b.each(arguments,function(e,t){var r;while((r=b.inArray(t,u,r))>-1)u.splice(r,1),n&&(o>=r&&o--,a>=r&&a--)}),this},has:function(e){return e?b.inArray(e,u)>-1:!(!u||!u.length)},empty:function(){return u=[],this},disable:function(){return u=l=r=t,this},disabled:function(){return!u},lock:function(){return l=t,r||p.disable(),this},locked:function(){return!l},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],!u||i&&!l||(n?l.push(t):c(t)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!i}};return p},b.extend({Deferred:function(e){var t=[["resolve","done",b.Callbacks("once memory"),"resolved"],["reject","fail",b.Callbacks("once memory"),"rejected"],["notify","progress",b.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return b.Deferred(function(n){b.each(t,function(t,o){var a=o[0],s=b.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&b.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?b.extend(e,r):r}},i={};return r.pipe=r.then,b.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=h.call(arguments),r=n.length,i=1!==r||e&&b.isFunction(e.promise)?r:0,o=1===i?e:b.Deferred(),a=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?h.call(arguments):r,n===s?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},s,u,l;if(r>1)for(s=Array(r),u=Array(r),l=Array(r);r>t;t++)n[t]&&b.isFunction(n[t].promise)?n[t].promise().done(a(t,l,n)).fail(o.reject).progress(a(t,u,s)):--i;return i||o.resolveWith(l,n),o.promise()}}),b.support=function(){var t,n,r,a,s,u,l,c,p,f,d=o.createElement("div");if(d.setAttribute("className","t"),d.innerHTML="
a",n=d.getElementsByTagName("*"),r=d.getElementsByTagName("a")[0],!n||!r||!n.length)return{};s=o.createElement("select"),l=s.appendChild(o.createElement("option")),a=d.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={getSetAttribute:"t"!==d.className,leadingWhitespace:3===d.firstChild.nodeType,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:"/a"===r.getAttribute("href"),opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:!!a.value,optSelected:l.selected,enctype:!!o.createElement("form").enctype,html5Clone:"<:nav>"!==o.createElement("nav").cloneNode(!0).outerHTML,boxModel:"CSS1Compat"===o.compatMode,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},a.checked=!0,t.noCloneChecked=a.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!l.disabled;try{delete d.test}catch(h){t.deleteExpando=!1}a=o.createElement("input"),a.setAttribute("value",""),t.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),t.radioValue="t"===a.value,a.setAttribute("checked","t"),a.setAttribute("name","t"),u=o.createDocumentFragment(),u.appendChild(a),t.appendChecked=a.checked,t.checkClone=u.cloneNode(!0).cloneNode(!0).lastChild.checked,d.attachEvent&&(d.attachEvent("onclick",function(){t.noCloneEvent=!1}),d.cloneNode(!0).click());for(f in{submit:!0,change:!0,focusin:!0})d.setAttribute(c="on"+f,"t"),t[f+"Bubbles"]=c in e||d.attributes[c].expando===!1;return d.style.backgroundClip="content-box",d.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===d.style.backgroundClip,b(function(){var n,r,a,s="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",u=o.getElementsByTagName("body")[0];u&&(n=o.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",u.appendChild(n).appendChild(d),d.innerHTML="
t
",a=d.getElementsByTagName("td"),a[0].style.cssText="padding:0;margin:0;border:0;display:none",p=0===a[0].offsetHeight,a[0].style.display="",a[1].style.display="none",t.reliableHiddenOffsets=p&&0===a[0].offsetHeight,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=4===d.offsetWidth,t.doesNotIncludeMarginInBodyOffset=1!==u.offsetTop,e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(d,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(d,null)||{width:"4px"}).width,r=d.appendChild(o.createElement("div")),r.style.cssText=d.style.cssText=s,r.style.marginRight=r.style.width="0",d.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),typeof d.style.zoom!==i&&(d.innerHTML="",d.style.cssText=s+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=3===d.offsetWidth,d.style.display="block",d.innerHTML="
",d.firstChild.style.width="5px",t.shrinkWrapBlocks=3!==d.offsetWidth,t.inlineBlockNeedsLayout&&(u.style.zoom=1)),u.removeChild(n),n=d=a=r=null)}),n=s=u=l=r=a=null,t}();var O=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,B=/([A-Z])/g;function P(e,n,r,i){if(b.acceptData(e)){var o,a,s=b.expando,u="string"==typeof n,l=e.nodeType,p=l?b.cache:e,f=l?e[s]:e[s]&&s;if(f&&p[f]&&(i||p[f].data)||!u||r!==t)return f||(l?e[s]=f=c.pop()||b.guid++:f=s),p[f]||(p[f]={},l||(p[f].toJSON=b.noop)),("object"==typeof n||"function"==typeof n)&&(i?p[f]=b.extend(p[f],n):p[f].data=b.extend(p[f].data,n)),o=p[f],i||(o.data||(o.data={}),o=o.data),r!==t&&(o[b.camelCase(n)]=r),u?(a=o[n],null==a&&(a=o[b.camelCase(n)])):a=o,a}}function R(e,t,n){if(b.acceptData(e)){var r,i,o,a=e.nodeType,s=a?b.cache:e,u=a?e[b.expando]:b.expando;if(s[u]){if(t&&(o=n?s[u]:s[u].data)){b.isArray(t)?t=t.concat(b.map(t,b.camelCase)):t in o?t=[t]:(t=b.camelCase(t),t=t in o?[t]:t.split(" "));for(r=0,i=t.length;i>r;r++)delete o[t[r]];if(!(n?$:b.isEmptyObject)(o))return}(n||(delete s[u].data,$(s[u])))&&(a?b.cleanData([e],!0):b.support.deleteExpando||s!=s.window?delete s[u]:s[u]=null)}}}b.extend({cache:{},expando:"jQuery"+(p+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?b.cache[e[b.expando]]:e[b.expando],!!e&&!$(e)},data:function(e,t,n){return P(e,t,n)},removeData:function(e,t){return R(e,t)},_data:function(e,t,n){return P(e,t,n,!0)},_removeData:function(e,t){return R(e,t,!0)},acceptData:function(e){if(e.nodeType&&1!==e.nodeType&&9!==e.nodeType)return!1;var t=e.nodeName&&b.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),b.fn.extend({data:function(e,n){var r,i,o=this[0],a=0,s=null;if(e===t){if(this.length&&(s=b.data(o),1===o.nodeType&&!b._data(o,"parsedAttrs"))){for(r=o.attributes;r.length>a;a++)i=r[a].name,i.indexOf("data-")||(i=b.camelCase(i.slice(5)),W(o,i,s[i]));b._data(o,"parsedAttrs",!0)}return s}return"object"==typeof e?this.each(function(){b.data(this,e)}):b.access(this,function(n){return n===t?o?W(o,e,b.data(o,e)):null:(this.each(function(){b.data(this,e,n)}),t)},null,n,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){b.removeData(this,e)})}});function W(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(B,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:O.test(r)?b.parseJSON(r):r}catch(o){}b.data(e,n,r)}else r=t}return r}function $(e){var t;for(t in e)if(("data"!==t||!b.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}b.extend({queue:function(e,n,r){var i;return e?(n=(n||"fx")+"queue",i=b._data(e,n),r&&(!i||b.isArray(r)?i=b._data(e,n,b.makeArray(r)):i.push(r)),i||[]):t},dequeue:function(e,t){t=t||"fx";var n=b.queue(e,t),r=n.length,i=n.shift(),o=b._queueHooks(e,t),a=function(){b.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),o.cur=i,i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return b._data(e,n)||b._data(e,n,{empty:b.Callbacks("once memory").add(function(){b._removeData(e,t+"queue"),b._removeData(e,n)})})}}),b.fn.extend({queue:function(e,n){var r=2;return"string"!=typeof e&&(n=e,e="fx",r--),r>arguments.length?b.queue(this[0],e):n===t?this:this.each(function(){var t=b.queue(this,e,n);b._queueHooks(this,e),"fx"===e&&"inprogress"!==t[0]&&b.dequeue(this,e)})},dequeue:function(e){return this.each(function(){b.dequeue(this,e)})},delay:function(e,t){return e=b.fx?b.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,o=b.Deferred(),a=this,s=this.length,u=function(){--i||o.resolveWith(a,[a])};"string"!=typeof e&&(n=e,e=t),e=e||"fx";while(s--)r=b._data(a[s],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(u));return u(),o.promise(n)}});var I,z,X=/[\t\r\n]/g,U=/\r/g,V=/^(?:input|select|textarea|button|object)$/i,Y=/^(?:a|area)$/i,J=/^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i,G=/^(?:checked|selected)$/i,Q=b.support.getSetAttribute,K=b.support.input;b.fn.extend({attr:function(e,t){return b.access(this,b.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){b.removeAttr(this,e)})},prop:function(e,t){return b.access(this,b.prop,e,t,arguments.length>1)},removeProp:function(e){return e=b.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,o,a=0,s=this.length,u="string"==typeof e&&e;if(b.isFunction(e))return this.each(function(t){b(this).addClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(X," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=b.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,a=0,s=this.length,u=0===arguments.length||"string"==typeof e&&e;if(b.isFunction(e))return this.each(function(t){b(this).removeClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(X," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?b.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e,r="boolean"==typeof t;return b.isFunction(e)?this.each(function(n){b(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var o,a=0,s=b(this),u=t,l=e.match(w)||[];while(o=l[a++])u=r?u:!s.hasClass(o),s[u?"addClass":"removeClass"](o)}else(n===i||"boolean"===n)&&(this.className&&b._data(this,"__className__",this.className),this.className=this.className||e===!1?"":b._data(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(X," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,o=this[0];{if(arguments.length)return i=b.isFunction(e),this.each(function(n){var o,a=b(this);1===this.nodeType&&(o=i?e.call(this,n,a.val()):e,null==o?o="":"number"==typeof o?o+="":b.isArray(o)&&(o=b.map(o,function(e){return null==e?"":e+""})),r=b.valHooks[this.type]||b.valHooks[this.nodeName.toLowerCase()],r&&"set"in r&&r.set(this,o,"value")!==t||(this.value=o))});if(o)return r=b.valHooks[o.type]||b.valHooks[o.nodeName.toLowerCase()],r&&"get"in r&&(n=r.get(o,"value"))!==t?n:(n=o.value,"string"==typeof n?n.replace(U,""):null==n?"":n)}}}),b.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,a=o?null:[],s=o?i+1:r.length,u=0>i?s:o?i:0;for(;s>u;u++)if(n=r[u],!(!n.selected&&u!==i||(b.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&b.nodeName(n.parentNode,"optgroup"))){if(t=b(n).val(),o)return t;a.push(t)}return a},set:function(e,t){var n=b.makeArray(t);return b(e).find("option").each(function(){this.selected=b.inArray(b(this).val(),n)>=0}),n.length||(e.selectedIndex=-1),n}}},attr:function(e,n,r){var o,a,s,u=e.nodeType;if(e&&3!==u&&8!==u&&2!==u)return typeof e.getAttribute===i?b.prop(e,n,r):(a=1!==u||!b.isXMLDoc(e),a&&(n=n.toLowerCase(),o=b.attrHooks[n]||(J.test(n)?z:I)),r===t?o&&a&&"get"in o&&null!==(s=o.get(e,n))?s:(typeof e.getAttribute!==i&&(s=e.getAttribute(n)),null==s?t:s):null!==r?o&&a&&"set"in o&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r):(b.removeAttr(e,n),t))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(w);if(o&&1===e.nodeType)while(n=o[i++])r=b.propFix[n]||n,J.test(n)?!Q&&G.test(n)?e[b.camelCase("default-"+n)]=e[r]=!1:e[r]=!1:b.attr(e,n,""),e.removeAttribute(Q?n:r)},attrHooks:{type:{set:function(e,t){if(!b.support.radioValue&&"radio"===t&&b.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(e,n,r){var i,o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return a=1!==s||!b.isXMLDoc(e),a&&(n=b.propFix[n]||n,o=b.propHooks[n]),r!==t?o&&"set"in o&&(i=o.set(e,r,n))!==t?i:e[n]=r:o&&"get"in o&&null!==(i=o.get(e,n))?i:e[n]},propHooks:{tabIndex:{get:function(e){var n=e.getAttributeNode("tabindex");return n&&n.specified?parseInt(n.value,10):V.test(e.nodeName)||Y.test(e.nodeName)&&e.href?0:t}}}}),z={get:function(e,n){var r=b.prop(e,n),i="boolean"==typeof r&&e.getAttribute(n),o="boolean"==typeof r?K&&Q?null!=i:G.test(n)?e[b.camelCase("default-"+n)]:!!i:e.getAttributeNode(n);return o&&o.value!==!1?n.toLowerCase():t},set:function(e,t,n){return t===!1?b.removeAttr(e,n):K&&Q||!G.test(n)?e.setAttribute(!Q&&b.propFix[n]||n,n):e[b.camelCase("default-"+n)]=e[n]=!0,n}},K&&Q||(b.attrHooks.value={get:function(e,n){var r=e.getAttributeNode(n);return b.nodeName(e,"input")?e.defaultValue:r&&r.specified?r.value:t},set:function(e,n,r){return b.nodeName(e,"input")?(e.defaultValue=n,t):I&&I.set(e,n,r)}}),Q||(I=b.valHooks.button={get:function(e,n){var r=e.getAttributeNode(n);return r&&("id"===n||"name"===n||"coords"===n?""!==r.value:r.specified)?r.value:t},set:function(e,n,r){var i=e.getAttributeNode(r);return i||e.setAttributeNode(i=e.ownerDocument.createAttribute(r)),i.value=n+="","value"===r||n===e.getAttribute(r)?n:t}},b.attrHooks.contenteditable={get:I.get,set:function(e,t,n){I.set(e,""===t?!1:t,n)}},b.each(["width","height"],function(e,n){b.attrHooks[n]=b.extend(b.attrHooks[n],{set:function(e,r){return""===r?(e.setAttribute(n,"auto"),r):t}})})),b.support.hrefNormalized||(b.each(["href","src","width","height"],function(e,n){b.attrHooks[n]=b.extend(b.attrHooks[n],{get:function(e){var r=e.getAttribute(n,2);return null==r?t:r}})}),b.each(["href","src"],function(e,t){b.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}})),b.support.style||(b.attrHooks.style={get:function(e){return e.style.cssText||t},set:function(e,t){return e.style.cssText=t+""}}),b.support.optSelected||(b.propHooks.selected=b.extend(b.propHooks.selected,{get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}})),b.support.enctype||(b.propFix.enctype="encoding"),b.support.checkOn||b.each(["radio","checkbox"],function(){b.valHooks[this]={get:function(e){return null===e.getAttribute("value")?"on":e.value}}}),b.each(["radio","checkbox"],function(){b.valHooks[this]=b.extend(b.valHooks[this],{set:function(e,n){return b.isArray(n)?e.checked=b.inArray(b(e).val(),n)>=0:t}})});var Z=/^(?:input|select|textarea)$/i,et=/^key/,tt=/^(?:mouse|contextmenu)|click/,nt=/^(?:focusinfocus|focusoutblur)$/,rt=/^([^.]*)(?:\.(.+)|)$/;function it(){return!0}function ot(){return!1}b.event={global:{},add:function(e,n,r,o,a){var s,u,l,c,p,f,d,h,g,m,y,v=b._data(e);if(v){r.handler&&(c=r,r=c.handler,a=c.selector),r.guid||(r.guid=b.guid++),(u=v.events)||(u=v.events={}),(f=v.handle)||(f=v.handle=function(e){return typeof b===i||e&&b.event.triggered===e.type?t:b.event.dispatch.apply(f.elem,arguments)},f.elem=e),n=(n||"").match(w)||[""],l=n.length;while(l--)s=rt.exec(n[l])||[],g=y=s[1],m=(s[2]||"").split(".").sort(),p=b.event.special[g]||{},g=(a?p.delegateType:p.bindType)||g,p=b.event.special[g]||{},d=b.extend({type:g,origType:y,data:o,handler:r,guid:r.guid,selector:a,needsContext:a&&b.expr.match.needsContext.test(a),namespace:m.join(".")},c),(h=u[g])||(h=u[g]=[],h.delegateCount=0,p.setup&&p.setup.call(e,o,m,f)!==!1||(e.addEventListener?e.addEventListener(g,f,!1):e.attachEvent&&e.attachEvent("on"+g,f))),p.add&&(p.add.call(e,d),d.handler.guid||(d.handler.guid=r.guid)),a?h.splice(h.delegateCount++,0,d):h.push(d),b.event.global[g]=!0;e=null}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,p,f,d,h,g,m=b.hasData(e)&&b._data(e);if(m&&(c=m.events)){t=(t||"").match(w)||[""],l=t.length;while(l--)if(s=rt.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){p=b.event.special[d]||{},d=(r?p.delegateType:p.bindType)||d,f=c[d]||[],s=s[2]&&RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),u=o=f.length;while(o--)a=f[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&("**"!==r||!a.selector)||(f.splice(o,1),a.selector&&f.delegateCount--,p.remove&&p.remove.call(e,a));u&&!f.length&&(p.teardown&&p.teardown.call(e,h,m.handle)!==!1||b.removeEvent(e,d,m.handle),delete c[d])}else for(d in c)b.event.remove(e,d+t[l],n,r,!0);b.isEmptyObject(c)&&(delete m.handle,b._removeData(e,"events"))}},trigger:function(n,r,i,a){var s,u,l,c,p,f,d,h=[i||o],g=y.call(n,"type")?n.type:n,m=y.call(n,"namespace")?n.namespace.split("."):[];if(l=f=i=i||o,3!==i.nodeType&&8!==i.nodeType&&!nt.test(g+b.event.triggered)&&(g.indexOf(".")>=0&&(m=g.split("."),g=m.shift(),m.sort()),u=0>g.indexOf(":")&&"on"+g,n=n[b.expando]?n:new b.Event(g,"object"==typeof n&&n),n.isTrigger=!0,n.namespace=m.join("."),n.namespace_re=n.namespace?RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,n.result=t,n.target||(n.target=i),r=null==r?[n]:b.makeArray(r,[n]),p=b.event.special[g]||{},a||!p.trigger||p.trigger.apply(i,r)!==!1)){if(!a&&!p.noBubble&&!b.isWindow(i)){for(c=p.delegateType||g,nt.test(c+g)||(l=l.parentNode);l;l=l.parentNode)h.push(l),f=l;f===(i.ownerDocument||o)&&h.push(f.defaultView||f.parentWindow||e)}d=0;while((l=h[d++])&&!n.isPropagationStopped())n.type=d>1?c:p.bindType||g,s=(b._data(l,"events")||{})[n.type]&&b._data(l,"handle"),s&&s.apply(l,r),s=u&&l[u],s&&b.acceptData(l)&&s.apply&&s.apply(l,r)===!1&&n.preventDefault();if(n.type=g,!(a||n.isDefaultPrevented()||p._default&&p._default.apply(i.ownerDocument,r)!==!1||"click"===g&&b.nodeName(i,"a")||!b.acceptData(i)||!u||!i[g]||b.isWindow(i))){f=i[u],f&&(i[u]=null),b.event.triggered=g;try{i[g]()}catch(v){}b.event.triggered=t,f&&(i[u]=f)}return n.result}},dispatch:function(e){e=b.event.fix(e);var n,r,i,o,a,s=[],u=h.call(arguments),l=(b._data(this,"events")||{})[e.type]||[],c=b.event.special[e.type]||{};if(u[0]=e,e.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,e)!==!1){s=b.event.handlers.call(this,e,l),n=0;while((o=s[n++])&&!e.isPropagationStopped()){e.currentTarget=o.elem,a=0;while((i=o.handlers[a++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(i.namespace))&&(e.handleObj=i,e.data=i.data,r=((b.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,u),r!==t&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,n){var r,i,o,a,s=[],u=n.delegateCount,l=e.target;if(u&&l.nodeType&&(!e.button||"click"!==e.type))for(;l!=this;l=l.parentNode||this)if(1===l.nodeType&&(l.disabled!==!0||"click"!==e.type)){for(o=[],a=0;u>a;a++)i=n[a],r=i.selector+" ",o[r]===t&&(o[r]=i.needsContext?b(r,this).index(l)>=0:b.find(r,this,null,[l]).length),o[r]&&o.push(i);o.length&&s.push({elem:l,handlers:o})}return n.length>u&&s.push({elem:this,handlers:n.slice(u)}),s},fix:function(e){if(e[b.expando])return e;var t,n,r,i=e.type,a=e,s=this.fixHooks[i];s||(this.fixHooks[i]=s=tt.test(i)?this.mouseHooks:et.test(i)?this.keyHooks:{}),r=s.props?this.props.concat(s.props):this.props,e=new b.Event(a),t=r.length;while(t--)n=r[t],e[n]=a[n];return e.target||(e.target=a.srcElement||o),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,a):e},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,i,a,s=n.button,u=n.fromElement;return null==e.pageX&&null!=n.clientX&&(i=e.target.ownerDocument||o,a=i.documentElement,r=i.body,e.pageX=n.clientX+(a&&a.scrollLeft||r&&r.scrollLeft||0)-(a&&a.clientLeft||r&&r.clientLeft||0),e.pageY=n.clientY+(a&&a.scrollTop||r&&r.scrollTop||0)-(a&&a.clientTop||r&&r.clientTop||0)),!e.relatedTarget&&u&&(e.relatedTarget=u===e.target?n.toElement:u),e.which||s===t||(e.which=1&s?1:2&s?3:4&s?2:0),e}},special:{load:{noBubble:!0},click:{trigger:function(){return b.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):t}},focus:{trigger:function(){if(this!==o.activeElement&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){return this===o.activeElement&&this.blur?(this.blur(),!1):t},delegateType:"focusout"},beforeunload:{postDispatch:function(e){e.result!==t&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=b.extend(new b.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?b.event.trigger(i,null,t):b.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},b.removeEvent=o.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]===i&&(e[r]=null),e.detachEvent(r,n))},b.Event=function(e,n){return this instanceof b.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?it:ot):this.type=e,n&&b.extend(this,n),this.timeStamp=e&&e.timeStamp||b.now(),this[b.expando]=!0,t):new b.Event(e,n)},b.Event.prototype={isDefaultPrevented:ot,isPropagationStopped:ot,isImmediatePropagationStopped:ot,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=it,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=it,e&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=it,this.stopPropagation()}},b.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){b.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj; -return(!i||i!==r&&!b.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),b.support.submitBubbles||(b.event.special.submit={setup:function(){return b.nodeName(this,"form")?!1:(b.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=b.nodeName(n,"input")||b.nodeName(n,"button")?n.form:t;r&&!b._data(r,"submitBubbles")&&(b.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),b._data(r,"submitBubbles",!0))}),t)},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&b.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return b.nodeName(this,"form")?!1:(b.event.remove(this,"._submit"),t)}}),b.support.changeBubbles||(b.event.special.change={setup:function(){return Z.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(b.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),b.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),b.event.simulate("change",this,e,!0)})),!1):(b.event.add(this,"beforeactivate._change",function(e){var t=e.target;Z.test(t.nodeName)&&!b._data(t,"changeBubbles")&&(b.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||b.event.simulate("change",this.parentNode,e,!0)}),b._data(t,"changeBubbles",!0))}),t)},handle:function(e){var n=e.target;return this!==n||e.isSimulated||e.isTrigger||"radio"!==n.type&&"checkbox"!==n.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return b.event.remove(this,"._change"),!Z.test(this.nodeName)}}),b.support.focusinBubbles||b.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){b.event.simulate(t,e.target,b.event.fix(e),!0)};b.event.special[t]={setup:function(){0===n++&&o.addEventListener(e,r,!0)},teardown:function(){0===--n&&o.removeEventListener(e,r,!0)}}}),b.fn.extend({on:function(e,n,r,i,o){var a,s;if("object"==typeof e){"string"!=typeof n&&(r=r||n,n=t);for(a in e)this.on(a,n,r,e[a],o);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=ot;else if(!i)return this;return 1===o&&(s=i,i=function(e){return b().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=b.guid++)),this.each(function(){b.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,o;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,b(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(o in e)this.off(o,n,e[o]);return this}return(n===!1||"function"==typeof n)&&(r=n,n=t),r===!1&&(r=ot),this.each(function(){b.event.remove(this,e,r,n)})},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},trigger:function(e,t){return this.each(function(){b.event.trigger(e,t,this)})},triggerHandler:function(e,n){var r=this[0];return r?b.event.trigger(e,n,r,!0):t}}),function(e,t){var n,r,i,o,a,s,u,l,c,p,f,d,h,g,m,y,v,x="sizzle"+-new Date,w=e.document,T={},N=0,C=0,k=it(),E=it(),S=it(),A=typeof t,j=1<<31,D=[],L=D.pop,H=D.push,q=D.slice,M=D.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},_="[\\x20\\t\\r\\n\\f]",F="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=F.replace("w","w#"),B="([*^$|!~]?=)",P="\\["+_+"*("+F+")"+_+"*(?:"+B+_+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+O+")|)|)"+_+"*\\]",R=":("+F+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+P.replace(3,8)+")*)|.*)\\)|)",W=RegExp("^"+_+"+|((?:^|[^\\\\])(?:\\\\.)*)"+_+"+$","g"),$=RegExp("^"+_+"*,"+_+"*"),I=RegExp("^"+_+"*([\\x20\\t\\r\\n\\f>+~])"+_+"*"),z=RegExp(R),X=RegExp("^"+O+"$"),U={ID:RegExp("^#("+F+")"),CLASS:RegExp("^\\.("+F+")"),NAME:RegExp("^\\[name=['\"]?("+F+")['\"]?\\]"),TAG:RegExp("^("+F.replace("w","w*")+")"),ATTR:RegExp("^"+P),PSEUDO:RegExp("^"+R),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+_+"*(even|odd|(([+-]|)(\\d*)n|)"+_+"*(?:([+-]|)"+_+"*(\\d+)|))"+_+"*\\)|)","i"),needsContext:RegExp("^"+_+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+_+"*((?:-\\d)?\\d*)"+_+"*\\)|)(?=[^-]|$)","i")},V=/[\x20\t\r\n\f]*[+~]/,Y=/^[^{]+\{\s*\[native code/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,G=/^(?:input|select|textarea|button)$/i,Q=/^h\d$/i,K=/'|\\/g,Z=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,et=/\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g,tt=function(e,t){var n="0x"+t-65536;return n!==n?t:0>n?String.fromCharCode(n+65536):String.fromCharCode(55296|n>>10,56320|1023&n)};try{q.call(w.documentElement.childNodes,0)[0].nodeType}catch(nt){q=function(e){var t,n=[];while(t=this[e++])n.push(t);return n}}function rt(e){return Y.test(e+"")}function it(){var e,t=[];return e=function(n,r){return t.push(n+=" ")>i.cacheLength&&delete e[t.shift()],e[n]=r}}function ot(e){return e[x]=!0,e}function at(e){var t=p.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}}function st(e,t,n,r){var i,o,a,s,u,l,f,g,m,v;if((t?t.ownerDocument||t:w)!==p&&c(t),t=t||p,n=n||[],!e||"string"!=typeof e)return n;if(1!==(s=t.nodeType)&&9!==s)return[];if(!d&&!r){if(i=J.exec(e))if(a=i[1]){if(9===s){if(o=t.getElementById(a),!o||!o.parentNode)return n;if(o.id===a)return n.push(o),n}else if(t.ownerDocument&&(o=t.ownerDocument.getElementById(a))&&y(t,o)&&o.id===a)return n.push(o),n}else{if(i[2])return H.apply(n,q.call(t.getElementsByTagName(e),0)),n;if((a=i[3])&&T.getByClassName&&t.getElementsByClassName)return H.apply(n,q.call(t.getElementsByClassName(a),0)),n}if(T.qsa&&!h.test(e)){if(f=!0,g=x,m=t,v=9===s&&e,1===s&&"object"!==t.nodeName.toLowerCase()){l=ft(e),(f=t.getAttribute("id"))?g=f.replace(K,"\\$&"):t.setAttribute("id",g),g="[id='"+g+"'] ",u=l.length;while(u--)l[u]=g+dt(l[u]);m=V.test(e)&&t.parentNode||t,v=l.join(",")}if(v)try{return H.apply(n,q.call(m.querySelectorAll(v),0)),n}catch(b){}finally{f||t.removeAttribute("id")}}}return wt(e.replace(W,"$1"),t,n,r)}a=st.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},c=st.setDocument=function(e){var n=e?e.ownerDocument||e:w;return n!==p&&9===n.nodeType&&n.documentElement?(p=n,f=n.documentElement,d=a(n),T.tagNameNoComments=at(function(e){return e.appendChild(n.createComment("")),!e.getElementsByTagName("*").length}),T.attributes=at(function(e){e.innerHTML="";var t=typeof e.lastChild.getAttribute("multiple");return"boolean"!==t&&"string"!==t}),T.getByClassName=at(function(e){return e.innerHTML="",e.getElementsByClassName&&e.getElementsByClassName("e").length?(e.lastChild.className="e",2===e.getElementsByClassName("e").length):!1}),T.getByName=at(function(e){e.id=x+0,e.innerHTML="
",f.insertBefore(e,f.firstChild);var t=n.getElementsByName&&n.getElementsByName(x).length===2+n.getElementsByName(x+0).length;return T.getIdNotName=!n.getElementById(x),f.removeChild(e),t}),i.attrHandle=at(function(e){return e.innerHTML="",e.firstChild&&typeof e.firstChild.getAttribute!==A&&"#"===e.firstChild.getAttribute("href")})?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},T.getIdNotName?(i.find.ID=function(e,t){if(typeof t.getElementById!==A&&!d){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},i.filter.ID=function(e){var t=e.replace(et,tt);return function(e){return e.getAttribute("id")===t}}):(i.find.ID=function(e,n){if(typeof n.getElementById!==A&&!d){var r=n.getElementById(e);return r?r.id===e||typeof r.getAttributeNode!==A&&r.getAttributeNode("id").value===e?[r]:t:[]}},i.filter.ID=function(e){var t=e.replace(et,tt);return function(e){var n=typeof e.getAttributeNode!==A&&e.getAttributeNode("id");return n&&n.value===t}}),i.find.TAG=T.tagNameNoComments?function(e,n){return typeof n.getElementsByTagName!==A?n.getElementsByTagName(e):t}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},i.find.NAME=T.getByName&&function(e,n){return typeof n.getElementsByName!==A?n.getElementsByName(name):t},i.find.CLASS=T.getByClassName&&function(e,n){return typeof n.getElementsByClassName===A||d?t:n.getElementsByClassName(e)},g=[],h=[":focus"],(T.qsa=rt(n.querySelectorAll))&&(at(function(e){e.innerHTML="",e.querySelectorAll("[selected]").length||h.push("\\["+_+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||h.push(":checked")}),at(function(e){e.innerHTML="",e.querySelectorAll("[i^='']").length&&h.push("[*^$]="+_+"*(?:\"\"|'')"),e.querySelectorAll(":enabled").length||h.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),h.push(",.*:")})),(T.matchesSelector=rt(m=f.matchesSelector||f.mozMatchesSelector||f.webkitMatchesSelector||f.oMatchesSelector||f.msMatchesSelector))&&at(function(e){T.disconnectedMatch=m.call(e,"div"),m.call(e,"[s!='']:x"),g.push("!=",R)}),h=RegExp(h.join("|")),g=RegExp(g.join("|")),y=rt(f.contains)||f.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},v=f.compareDocumentPosition?function(e,t){var r;return e===t?(u=!0,0):(r=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t))?1&r||e.parentNode&&11===e.parentNode.nodeType?e===n||y(w,e)?-1:t===n||y(w,t)?1:0:4&r?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var r,i=0,o=e.parentNode,a=t.parentNode,s=[e],l=[t];if(e===t)return u=!0,0;if(!o||!a)return e===n?-1:t===n?1:o?-1:a?1:0;if(o===a)return ut(e,t);r=e;while(r=r.parentNode)s.unshift(r);r=t;while(r=r.parentNode)l.unshift(r);while(s[i]===l[i])i++;return i?ut(s[i],l[i]):s[i]===w?-1:l[i]===w?1:0},u=!1,[0,0].sort(v),T.detectDuplicates=u,p):p},st.matches=function(e,t){return st(e,null,null,t)},st.matchesSelector=function(e,t){if((e.ownerDocument||e)!==p&&c(e),t=t.replace(Z,"='$1']"),!(!T.matchesSelector||d||g&&g.test(t)||h.test(t)))try{var n=m.call(e,t);if(n||T.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(r){}return st(t,p,null,[e]).length>0},st.contains=function(e,t){return(e.ownerDocument||e)!==p&&c(e),y(e,t)},st.attr=function(e,t){var n;return(e.ownerDocument||e)!==p&&c(e),d||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):d||T.attributes?e.getAttribute(t):((n=e.getAttributeNode(t))||e.getAttribute(t))&&e[t]===!0?t:n&&n.specified?n.value:null},st.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},st.uniqueSort=function(e){var t,n=[],r=1,i=0;if(u=!T.detectDuplicates,e.sort(v),u){for(;t=e[r];r++)t===e[r-1]&&(i=n.push(r));while(i--)e.splice(n[i],1)}return e};function ut(e,t){var n=t&&e,r=n&&(~t.sourceIndex||j)-(~e.sourceIndex||j);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function lt(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function ct(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function pt(e){return ot(function(t){return t=+t,ot(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}o=st.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=o(t);return n},i=st.selectors={cacheLength:50,createPseudo:ot,match:U,find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(et,tt),e[3]=(e[4]||e[5]||"").replace(et,tt),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||st.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&st.error(e[0]),e},PSEUDO:function(e){var t,n=!e[5]&&e[2];return U.CHILD.test(e[0])?null:(e[4]?e[2]=e[4]:n&&z.test(n)&&(t=ft(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){return"*"===e?function(){return!0}:(e=e.replace(et,tt).toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[e+" "];return t||(t=RegExp("(^|"+_+")"+e+"("+_+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==A&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=st.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,p,f,d,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!u&&!s;if(m){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){c=m[x]||(m[x]={}),l=c[e]||[],d=l[0]===N&&l[1],f=l[0]===N&&l[2],p=d&&m.childNodes[d];while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[N,d,f];break}}else if(v&&(l=(t[x]||(t[x]={}))[e])&&l[0]===N)f=l[1];else while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(v&&((p[x]||(p[x]={}))[e]=[N,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||st.error("unsupported pseudo: "+e);return r[x]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?ot(function(e,n){var i,o=r(e,t),a=o.length;while(a--)i=M.call(e,o[a]),e[i]=!(n[i]=o[a])}):function(e){return r(e,0,n)}):r}},pseudos:{not:ot(function(e){var t=[],n=[],r=s(e.replace(W,"$1"));return r[x]?ot(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:ot(function(e){return function(t){return st(e,t).length>0}}),contains:ot(function(e){return function(t){return(t.textContent||t.innerText||o(t)).indexOf(e)>-1}}),lang:ot(function(e){return X.test(e||"")||st.error("unsupported lang: "+e),e=e.replace(et,tt).toLowerCase(),function(t){var n;do if(n=d?t.getAttribute("xml:lang")||t.getAttribute("lang"):t.lang)return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===f},focus:function(e){return e===p.activeElement&&(!p.hasFocus||p.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!i.pseudos.empty(e)},header:function(e){return Q.test(e.nodeName)},input:function(e){return G.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:pt(function(){return[0]}),last:pt(function(e,t){return[t-1]}),eq:pt(function(e,t,n){return[0>n?n+t:n]}),even:pt(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:pt(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:pt(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:pt(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}};for(n in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})i.pseudos[n]=lt(n);for(n in{submit:!0,reset:!0})i.pseudos[n]=ct(n);function ft(e,t){var n,r,o,a,s,u,l,c=E[e+" "];if(c)return t?0:c.slice(0);s=e,u=[],l=i.preFilter;while(s){(!n||(r=$.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),u.push(o=[])),n=!1,(r=I.exec(s))&&(n=r.shift(),o.push({value:n,type:r[0].replace(W," ")}),s=s.slice(n.length));for(a in i.filter)!(r=U[a].exec(s))||l[a]&&!(r=l[a](r))||(n=r.shift(),o.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?st.error(e):E(e,u).slice(0)}function dt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function ht(e,t,n){var i=t.dir,o=n&&"parentNode"===i,a=C++;return t.first?function(t,n,r){while(t=t[i])if(1===t.nodeType||o)return e(t,n,r)}:function(t,n,s){var u,l,c,p=N+" "+a;if(s){while(t=t[i])if((1===t.nodeType||o)&&e(t,n,s))return!0}else while(t=t[i])if(1===t.nodeType||o)if(c=t[x]||(t[x]={}),(l=c[i])&&l[0]===p){if((u=l[1])===!0||u===r)return u===!0}else if(l=c[i]=[p],l[1]=e(t,n,s)||r,l[1]===!0)return!0}}function gt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function mt(e,t,n,r,i){var o,a=[],s=0,u=e.length,l=null!=t;for(;u>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),l&&t.push(s));return a}function yt(e,t,n,r,i,o){return r&&!r[x]&&(r=yt(r)),i&&!i[x]&&(i=yt(i,o)),ot(function(o,a,s,u){var l,c,p,f=[],d=[],h=a.length,g=o||xt(t||"*",s.nodeType?[s]:s,[]),m=!e||!o&&t?g:mt(g,f,e,s,u),y=n?i||(o?e:h||r)?[]:a:m;if(n&&n(m,y,s,u),r){l=mt(y,d),r(l,[],s,u),c=l.length;while(c--)(p=l[c])&&(y[d[c]]=!(m[d[c]]=p))}if(o){if(i||e){if(i){l=[],c=y.length;while(c--)(p=y[c])&&l.push(m[c]=p);i(null,y=[],l,u)}c=y.length;while(c--)(p=y[c])&&(l=i?M.call(o,p):f[c])>-1&&(o[l]=!(a[l]=p))}}else y=mt(y===a?y.splice(h,y.length):y),i?i(null,a,y,u):H.apply(a,y)})}function vt(e){var t,n,r,o=e.length,a=i.relative[e[0].type],s=a||i.relative[" "],u=a?1:0,c=ht(function(e){return e===t},s,!0),p=ht(function(e){return M.call(t,e)>-1},s,!0),f=[function(e,n,r){return!a&&(r||n!==l)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;o>u;u++)if(n=i.relative[e[u].type])f=[ht(gt(f),n)];else{if(n=i.filter[e[u].type].apply(null,e[u].matches),n[x]){for(r=++u;o>r;r++)if(i.relative[e[r].type])break;return yt(u>1&>(f),u>1&&dt(e.slice(0,u-1)).replace(W,"$1"),n,r>u&&vt(e.slice(u,r)),o>r&&vt(e=e.slice(r)),o>r&&dt(e))}f.push(n)}return gt(f)}function bt(e,t){var n=0,o=t.length>0,a=e.length>0,s=function(s,u,c,f,d){var h,g,m,y=[],v=0,b="0",x=s&&[],w=null!=d,T=l,C=s||a&&i.find.TAG("*",d&&u.parentNode||u),k=N+=null==T?1:Math.random()||.1;for(w&&(l=u!==p&&u,r=n);null!=(h=C[b]);b++){if(a&&h){g=0;while(m=e[g++])if(m(h,u,c)){f.push(h);break}w&&(N=k,r=++n)}o&&((h=!m&&h)&&v--,s&&x.push(h))}if(v+=b,o&&b!==v){g=0;while(m=t[g++])m(x,y,u,c);if(s){if(v>0)while(b--)x[b]||y[b]||(y[b]=L.call(f));y=mt(y)}H.apply(f,y),w&&!s&&y.length>0&&v+t.length>1&&st.uniqueSort(f)}return w&&(N=k,l=T),x};return o?ot(s):s}s=st.compile=function(e,t){var n,r=[],i=[],o=S[e+" "];if(!o){t||(t=ft(e)),n=t.length;while(n--)o=vt(t[n]),o[x]?r.push(o):i.push(o);o=S(e,bt(i,r))}return o};function xt(e,t,n){var r=0,i=t.length;for(;i>r;r++)st(e,t[r],n);return n}function wt(e,t,n,r){var o,a,u,l,c,p=ft(e);if(!r&&1===p.length){if(a=p[0]=p[0].slice(0),a.length>2&&"ID"===(u=a[0]).type&&9===t.nodeType&&!d&&i.relative[a[1].type]){if(t=i.find.ID(u.matches[0].replace(et,tt),t)[0],!t)return n;e=e.slice(a.shift().value.length)}o=U.needsContext.test(e)?0:a.length;while(o--){if(u=a[o],i.relative[l=u.type])break;if((c=i.find[l])&&(r=c(u.matches[0].replace(et,tt),V.test(a[0].type)&&t.parentNode||t))){if(a.splice(o,1),e=r.length&&dt(a),!e)return H.apply(n,q.call(r,0)),n;break}}}return s(e,p)(r,t,d,n,V.test(e)),n}i.pseudos.nth=i.pseudos.eq;function Tt(){}i.filters=Tt.prototype=i.pseudos,i.setFilters=new Tt,c(),st.attr=b.attr,b.find=st,b.expr=st.selectors,b.expr[":"]=b.expr.pseudos,b.unique=st.uniqueSort,b.text=st.getText,b.isXMLDoc=st.isXML,b.contains=st.contains}(e);var at=/Until$/,st=/^(?:parents|prev(?:Until|All))/,ut=/^.[^:#\[\.,]*$/,lt=b.expr.match.needsContext,ct={children:!0,contents:!0,next:!0,prev:!0};b.fn.extend({find:function(e){var t,n,r,i=this.length;if("string"!=typeof e)return r=this,this.pushStack(b(e).filter(function(){for(t=0;i>t;t++)if(b.contains(r[t],this))return!0}));for(n=[],t=0;i>t;t++)b.find(e,this[t],n);return n=this.pushStack(i>1?b.unique(n):n),n.selector=(this.selector?this.selector+" ":"")+e,n},has:function(e){var t,n=b(e,this),r=n.length;return this.filter(function(){for(t=0;r>t;t++)if(b.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e,!1))},filter:function(e){return this.pushStack(ft(this,e,!0))},is:function(e){return!!e&&("string"==typeof e?lt.test(e)?b(e,this.context).index(this[0])>=0:b.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,o=[],a=lt.test(e)||"string"!=typeof e?b(e,t||this.context):0;for(;i>r;r++){n=this[r];while(n&&n.ownerDocument&&n!==t&&11!==n.nodeType){if(a?a.index(n)>-1:b.find.matchesSelector(n,e)){o.push(n);break}n=n.parentNode}}return this.pushStack(o.length>1?b.unique(o):o)},index:function(e){return e?"string"==typeof e?b.inArray(this[0],b(e)):b.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?b(e,t):b.makeArray(e&&e.nodeType?[e]:e),r=b.merge(this.get(),n);return this.pushStack(b.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),b.fn.andSelf=b.fn.addBack;function pt(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}b.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return b.dir(e,"parentNode")},parentsUntil:function(e,t,n){return b.dir(e,"parentNode",n)},next:function(e){return pt(e,"nextSibling")},prev:function(e){return pt(e,"previousSibling")},nextAll:function(e){return b.dir(e,"nextSibling")},prevAll:function(e){return b.dir(e,"previousSibling")},nextUntil:function(e,t,n){return b.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return b.dir(e,"previousSibling",n)},siblings:function(e){return b.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return b.sibling(e.firstChild)},contents:function(e){return b.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:b.merge([],e.childNodes)}},function(e,t){b.fn[e]=function(n,r){var i=b.map(this,t,n);return at.test(e)||(r=n),r&&"string"==typeof r&&(i=b.filter(r,i)),i=this.length>1&&!ct[e]?b.unique(i):i,this.length>1&&st.test(e)&&(i=i.reverse()),this.pushStack(i)}}),b.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),1===t.length?b.find.matchesSelector(t[0],e)?[t[0]]:[]:b.find.matches(e,t)},dir:function(e,n,r){var i=[],o=e[n];while(o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!b(o).is(r)))1===o.nodeType&&i.push(o),o=o[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function ft(e,t,n){if(t=t||0,b.isFunction(t))return b.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return b.grep(e,function(e){return e===t===n});if("string"==typeof t){var r=b.grep(e,function(e){return 1===e.nodeType});if(ut.test(t))return b.filter(t,r,!n);t=b.filter(t,r)}return b.grep(e,function(e){return b.inArray(e,t)>=0===n})}function dt(e){var t=ht.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}var ht="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gt=/ jQuery\d+="(?:null|\d+)"/g,mt=RegExp("<(?:"+ht+")[\\s/>]","i"),yt=/^\s+/,vt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bt=/<([\w:]+)/,xt=/\s*$/g,At={option:[1,""],legend:[1,"
","
"],area:[1,"",""],param:[1,"",""],thead:[1,"","
"],tr:[2,"","
"],col:[2,"","
"],td:[3,"","
"],_default:b.support.htmlSerialize?[0,"",""]:[1,"X
","
"]},jt=dt(o),Dt=jt.appendChild(o.createElement("div"));At.optgroup=At.option,At.tbody=At.tfoot=At.colgroup=At.caption=At.thead,At.th=At.td,b.fn.extend({text:function(e){return b.access(this,function(e){return e===t?b.text(this):this.empty().append((this[0]&&this[0].ownerDocument||o).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(b.isFunction(e))return this.each(function(t){b(this).wrapAll(e.call(this,t))});if(this[0]){var t=b(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&1===e.firstChild.nodeType)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return b.isFunction(e)?this.each(function(t){b(this).wrapInner(e.call(this,t))}):this.each(function(){var t=b(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=b.isFunction(e);return this.each(function(n){b(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){b.nodeName(this,"body")||b(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&this.insertBefore(e,this.firstChild)})},before:function(){return this.domManip(arguments,!1,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,!1,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=0;for(;null!=(n=this[r]);r++)(!e||b.filter(e,[n]).length>0)&&(t||1!==n.nodeType||b.cleanData(Ot(n)),n.parentNode&&(t&&b.contains(n.ownerDocument,n)&&Mt(Ot(n,"script")),n.parentNode.removeChild(n)));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++){1===e.nodeType&&b.cleanData(Ot(e,!1));while(e.firstChild)e.removeChild(e.firstChild);e.options&&b.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return b.clone(this,e,t)})},html:function(e){return b.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return 1===n.nodeType?n.innerHTML.replace(gt,""):t;if(!("string"!=typeof e||Tt.test(e)||!b.support.htmlSerialize&&mt.test(e)||!b.support.leadingWhitespace&&yt.test(e)||At[(bt.exec(e)||["",""])[1].toLowerCase()])){e=e.replace(vt,"<$1>");try{for(;i>r;r++)n=this[r]||{},1===n.nodeType&&(b.cleanData(Ot(n,!1)),n.innerHTML=e);n=0}catch(o){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(e){var t=b.isFunction(e);return t||"string"==typeof e||(e=b(e).not(this).detach()),this.domManip([e],!0,function(e){var t=this.nextSibling,n=this.parentNode;n&&(b(this).remove(),n.insertBefore(e,t))})},detach:function(e){return this.remove(e,!0)},domManip:function(e,n,r){e=f.apply([],e);var i,o,a,s,u,l,c=0,p=this.length,d=this,h=p-1,g=e[0],m=b.isFunction(g);if(m||!(1>=p||"string"!=typeof g||b.support.checkClone)&&Ct.test(g))return this.each(function(i){var o=d.eq(i);m&&(e[0]=g.call(this,i,n?o.html():t)),o.domManip(e,n,r)});if(p&&(l=b.buildFragment(e,this[0].ownerDocument,!1,this),i=l.firstChild,1===l.childNodes.length&&(l=i),i)){for(n=n&&b.nodeName(i,"tr"),s=b.map(Ot(l,"script"),Ht),a=s.length;p>c;c++)o=l,c!==h&&(o=b.clone(o,!0,!0),a&&b.merge(s,Ot(o,"script"))),r.call(n&&b.nodeName(this[c],"table")?Lt(this[c],"tbody"):this[c],o,c);if(a)for(u=s[s.length-1].ownerDocument,b.map(s,qt),c=0;a>c;c++)o=s[c],kt.test(o.type||"")&&!b._data(o,"globalEval")&&b.contains(u,o)&&(o.src?b.ajax({url:o.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):b.globalEval((o.text||o.textContent||o.innerHTML||"").replace(St,"")));l=i=null}return this}});function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function Ht(e){var t=e.getAttributeNode("type");return e.type=(t&&t.specified)+"/"+e.type,e}function qt(e){var t=Et.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function Mt(e,t){var n,r=0;for(;null!=(n=e[r]);r++)b._data(n,"globalEval",!t||b._data(t[r],"globalEval"))}function _t(e,t){if(1===t.nodeType&&b.hasData(e)){var n,r,i,o=b._data(e),a=b._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)b.event.add(t,n,s[n][r])}a.data&&(a.data=b.extend({},a.data))}}function Ft(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!b.support.noCloneEvent&&t[b.expando]){i=b._data(t);for(r in i.events)b.removeEvent(t,r,i.handle);t.removeAttribute(b.expando)}"script"===n&&t.text!==e.text?(Ht(t).text=e.text,qt(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),b.support.html5Clone&&e.innerHTML&&!b.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Nt.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}b.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){b.fn[e]=function(e){var n,r=0,i=[],o=b(e),a=o.length-1;for(;a>=r;r++)n=r===a?this:this.clone(!0),b(o[r])[t](n),d.apply(i,n.get());return this.pushStack(i)}});function Ot(e,n){var r,o,a=0,s=typeof e.getElementsByTagName!==i?e.getElementsByTagName(n||"*"):typeof e.querySelectorAll!==i?e.querySelectorAll(n||"*"):t;if(!s)for(s=[],r=e.childNodes||e;null!=(o=r[a]);a++)!n||b.nodeName(o,n)?s.push(o):b.merge(s,Ot(o,n));return n===t||n&&b.nodeName(e,n)?b.merge([e],s):s}function Bt(e){Nt.test(e.type)&&(e.defaultChecked=e.checked)}b.extend({clone:function(e,t,n){var r,i,o,a,s,u=b.contains(e.ownerDocument,e);if(b.support.html5Clone||b.isXMLDoc(e)||!mt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(Dt.innerHTML=e.outerHTML,Dt.removeChild(o=Dt.firstChild)),!(b.support.noCloneEvent&&b.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||b.isXMLDoc(e)))for(r=Ot(o),s=Ot(e),a=0;null!=(i=s[a]);++a)r[a]&&Ft(i,r[a]);if(t)if(n)for(s=s||Ot(e),r=r||Ot(o),a=0;null!=(i=s[a]);a++)_t(i,r[a]);else _t(e,o);return r=Ot(o,"script"),r.length>0&&Mt(r,!u&&Ot(e,"script")),r=s=i=null,o},buildFragment:function(e,t,n,r){var i,o,a,s,u,l,c,p=e.length,f=dt(t),d=[],h=0;for(;p>h;h++)if(o=e[h],o||0===o)if("object"===b.type(o))b.merge(d,o.nodeType?[o]:o);else if(wt.test(o)){s=s||f.appendChild(t.createElement("div")),u=(bt.exec(o)||["",""])[1].toLowerCase(),c=At[u]||At._default,s.innerHTML=c[1]+o.replace(vt,"<$1>")+c[2],i=c[0];while(i--)s=s.lastChild;if(!b.support.leadingWhitespace&&yt.test(o)&&d.push(t.createTextNode(yt.exec(o)[0])),!b.support.tbody){o="table"!==u||xt.test(o)?""!==c[1]||xt.test(o)?0:s:s.firstChild,i=o&&o.childNodes.length;while(i--)b.nodeName(l=o.childNodes[i],"tbody")&&!l.childNodes.length&&o.removeChild(l) -}b.merge(d,s.childNodes),s.textContent="";while(s.firstChild)s.removeChild(s.firstChild);s=f.lastChild}else d.push(t.createTextNode(o));s&&f.removeChild(s),b.support.appendChecked||b.grep(Ot(d,"input"),Bt),h=0;while(o=d[h++])if((!r||-1===b.inArray(o,r))&&(a=b.contains(o.ownerDocument,o),s=Ot(f.appendChild(o),"script"),a&&Mt(s),n)){i=0;while(o=s[i++])kt.test(o.type||"")&&n.push(o)}return s=null,f},cleanData:function(e,t){var n,r,o,a,s=0,u=b.expando,l=b.cache,p=b.support.deleteExpando,f=b.event.special;for(;null!=(n=e[s]);s++)if((t||b.acceptData(n))&&(o=n[u],a=o&&l[o])){if(a.events)for(r in a.events)f[r]?b.event.remove(n,r):b.removeEvent(n,r,a.handle);l[o]&&(delete l[o],p?delete n[u]:typeof n.removeAttribute!==i?n.removeAttribute(u):n[u]=null,c.push(o))}}});var Pt,Rt,Wt,$t=/alpha\([^)]*\)/i,It=/opacity\s*=\s*([^)]*)/,zt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Ut=/^margin/,Vt=RegExp("^("+x+")(.*)$","i"),Yt=RegExp("^("+x+")(?!px)[a-z%]+$","i"),Jt=RegExp("^([+-])=("+x+")","i"),Gt={BODY:"block"},Qt={position:"absolute",visibility:"hidden",display:"block"},Kt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=en.length;while(i--)if(t=en[i]+n,t in e)return t;return r}function nn(e,t){return e=t||e,"none"===b.css(e,"display")||!b.contains(e.ownerDocument,e)}function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.style&&(o[a]=b._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&nn(r)&&(o[a]=b._data(r,"olddisplay",un(r.nodeName)))):o[a]||(i=nn(r),(n&&"none"!==n||!i)&&b._data(r,"olddisplay",i?n:b.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}b.fn.extend({css:function(e,n){return b.access(this,function(e,n,r){var i,o,a={},s=0;if(b.isArray(n)){for(o=Rt(e),i=n.length;i>s;s++)a[n[s]]=b.css(e,n[s],!1,o);return a}return r!==t?b.style(e,n,r):b.css(e,n)},e,n,arguments.length>1)},show:function(){return rn(this,!0)},hide:function(){return rn(this)},toggle:function(e){var t="boolean"==typeof e;return this.each(function(){(t?e:nn(this))?b(this).show():b(this).hide()})}}),b.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Wt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":b.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,u=b.camelCase(n),l=e.style;if(n=b.cssProps[u]||(b.cssProps[u]=tn(l,u)),s=b.cssHooks[n]||b.cssHooks[u],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:l[n];if(a=typeof r,"string"===a&&(o=Jt.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(b.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||b.cssNumber[u]||(r+="px"),b.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(l[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{l[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,u=b.camelCase(n);return n=b.cssProps[u]||(b.cssProps[u]=tn(e.style,u)),s=b.cssHooks[n]||b.cssHooks[u],s&&"get"in s&&(a=s.get(e,!0,r)),a===t&&(a=Wt(e,n,i)),"normal"===a&&n in Kt&&(a=Kt[n]),""===r||r?(o=parseFloat(a),r===!0||b.isNumeric(o)?o||0:a):a},swap:function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i}}),e.getComputedStyle?(Rt=function(t){return e.getComputedStyle(t,null)},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),u=s?s.getPropertyValue(n)||s[n]:t,l=e.style;return s&&(""!==u||b.contains(e.ownerDocument,e)||(u=b.style(e,n)),Yt.test(u)&&Ut.test(n)&&(i=l.width,o=l.minWidth,a=l.maxWidth,l.minWidth=l.maxWidth=l.width=u,u=s.width,l.width=i,l.minWidth=o,l.maxWidth=a)),u}):o.documentElement.currentStyle&&(Rt=function(e){return e.currentStyle},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),u=s?s[n]:t,l=e.style;return null==u&&l&&l[n]&&(u=l[n]),Yt.test(u)&&!zt.test(n)&&(i=l.left,o=e.runtimeStyle,a=o&&o.left,a&&(o.left=e.currentStyle.left),l.left="fontSize"===n?"1em":u,u=l.pixelLeft+"px",l.left=i,a&&(o.left=a)),""===u?"auto":u});function on(e,t,n){var r=Vt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function an(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;for(;4>o;o+=2)"margin"===n&&(a+=b.css(e,n+Zt[o],!0,i)),r?("content"===n&&(a-=b.css(e,"padding"+Zt[o],!0,i)),"margin"!==n&&(a-=b.css(e,"border"+Zt[o]+"Width",!0,i))):(a+=b.css(e,"padding"+Zt[o],!0,i),"padding"!==n&&(a+=b.css(e,"border"+Zt[o]+"Width",!0,i)));return a}function sn(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Rt(e),a=b.support.boxSizing&&"border-box"===b.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=Wt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Yt.test(i))return i;r=a&&(b.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+an(e,t,n||(a?"border":"content"),r,o)+"px"}function un(e){var t=o,n=Gt[e];return n||(n=ln(e,t),"none"!==n&&n||(Pt=(Pt||b("'; -html += '
'; -html += '
'; -html += '
Upload File
'; -html += '
Want to upload multiple files at once? Please upgrade to the latest Flash Player, then reload this page. For some reason our Flash based uploader did not load, so you are currently using our single file uploader.
'; -html += spacer(1,20) + '
'; -var url = zero_client.targetURL; -if (url.indexOf('?') > -1) url += '&'; else url += '?'; -url += 'format=jshtml&onafter=' + escape('window.parent.upload_basic_finish(response);'); -Debug.trace('upload', "Prepping basic upload: " + url); -html += '
'; -html += '
'; -html += '
'; -html += '

'; -html += ''; -html += ''; -html += ''; -html += '
' + large_icon_button('x', 'Cancel', "hide_popup_dialog()") + ' ' + large_icon_button('page_white_get.png', 'Upload', "upload_basic_go()") + '
'; -html += '
'; -html += ''; -html += '
'; -html += ''; -session.hooks.keys[ESC_KEY] = 'hide_popup_dialog'; -show_popup_dialog(528, 200, html); -} -function upload_basic_go() { -$('f_upload_basic').submit(); -$('d_upload_form').hide(); -$('d_upload_progress').show(); -} -function upload_basic_finish(response) { -Debug.trace('upload', "Basic upload complete: " + dumper(response)); -setTimeout( 'upload_basic_finish_2()', 100 ); -} -function upload_basic_finish_2() { -$('i_upload_basic').src = 'blank.html'; -setTimeout( 'upload_basic_finish_3()', 100 ); -} -function upload_basic_finish_3() { -hide_popup_dialog(); -delete session.progress; -show_progress_dialog( 0, 'Finishing Upload...', true ); -fire_callback( session.upload_callback ); -} -function upload_destroy() { -if (zero_client) { -zero_client.destroy(); -delete ZeroUpload.clients[ zero_client.id ]; -zero_client = null; -} -} -function prep_upload(dom_id, url, callback, types) { -session.upload_callback = callback; -if (url) { -if (url.indexOf('?') > -1) url += '&'; else url += '?'; -url += 'session=' + session.cookie.get('effect_session_id'); -} -upload_destroy(); -zero_client = new ZeroUpload.Client(); -if (url) zero_client.setURL( url ); -zero_client.setHandCursor( true ); -if (types) zero_client.setFileTypes( types[0], types[1] ); -zero_client.addEventListener( 'queueStart', uploadQueueStart ); -zero_client.addEventListener( 'fileStart', uploadFileStart ); -zero_client.addEventListener( 'progress', uploadProgress ); -zero_client.addEventListener( 'fileComplete', uploadFileComplete ); -zero_client.addEventListener( 'queueComplete', uploadQueueComplete ); -zero_client.addEventListener( 'error', uploadError ); -zero_client.addEventListener( 'debug', function(client, eventName, args) { -Debug.trace('upload', "Caught event: " + eventName); -} ); -if (dom_id) { -Debug.trace('upload', "Gluing ZeroUpload to: " + dom_id); -zero_client.glue( dom_id ); -} -} -Class.create( 'Debug', { -__static: { -enabled: false, -categories: { all: 1 }, -buffer: [], -max_rows: 5000, -win: null, -ie: !!navigator.userAgent.match(/MSIE/), -ie6: !!navigator.userAgent.match(/MSIE\D+6/), -init: function() { -Debug.enabled = true; -Debug.trace( 'debug', 'Debug log start' ); -var html = '

'; -if (Debug.ie) { -setTimeout( function() { -document.body.insertAdjacentHTML('beforeEnd', -'
' + html + '
' -); -}, 1000 ); -} -else { -var div = document.createElement('DIV'); -div.id = 'd_debug'; -div.setAttribute('id', 'd_debug'); -div.style.position = Debug.ie6 ? 'absolute' : 'fixed'; -div.style.zIndex = '101'; -div.style.left = '0px'; -div.style.top = '0px'; -div.style.width = '100%'; -div.innerHTML = html; -document.getElementsByTagName('body')[0].appendChild(div); -} -}, -show: function() { -if (!Debug.win || Debug.win.closed) { -Debug.trace('debug', "Opening debug window"); -Debug.win = window.open( '', 'DebugWindow', 'width=600,height=500,menubar=no,resizable=yes,scrollbars=yes,location=no,status=no,toolbar=no,directories=no' ); -if (!Debug.win) return alert("Failed to open window. Popup blocker maybe?"); -var doc = Debug.win.document; -doc.open(); -doc.writeln( 'Debug Log' ); -doc.writeln( '
' ); -doc.writeln( '
' ); -doc.writeln( '
' ); -doc.writeln( '' ); -doc.writeln( '' ); -doc.writeln( '
' ); -doc.writeln( '' ); -doc.close(); -} -Debug.win.focus(); -}, -console_execute: function() { -var cmd = Debug.win.document.getElementById('fe_command'); -if (cmd.value.length) { -Debug.trace( 'console', cmd.value ); -try { -Debug.trace( 'console', '' + eval(cmd.value) ); -} -catch (e) { -Debug.trace( 'error', 'JavaScript Interpreter Exception: ' + e.toString() ); -} -} -}, -get_time_stamp: function(now) { -var date = new Date( now * 1000 ); -var hh = date.getHours(); if (hh < 10) hh = "0" + hh; -var mi = date.getMinutes(); if (mi < 10) mi = "0" + mi; -var ss = date.getSeconds(); if (ss < 10) ss = "0" + ss; -var sss = '' + date.getMilliseconds(); while (sss.length < 3) sss = "0" + sss; -return '' + hh + ':' + mi + ':' + ss + '.' + sss; -}, -refresh_console: function() { -if (!Debug.win || Debug.win.closed) return; -var div = Debug.win.document.getElementById('d_debug_log'); -if (div) { -var row = null; -while ( row = Debug.buffer.shift() ) { -var time_stamp = Debug.get_time_stamp(row.time); -var msg = row.msg; -msg = msg.replace(/\t/g, "    "); -msg = msg.replace(//g, ">"); -msg = msg.replace(/\n/g, "
\n"); -var html = ''; -var sty = 'float:left; font-family: Consolas, Courier, mono; font-size: 12px; cursor:default; margin-right:10px; margin-bottom:1px; padding:2px;'; -html += '
' + time_stamp + '
'; -html += '
' + row.cat + '
'; -html += '
' + msg + '
'; -html += '
'; -var chunk = Debug.win.document.createElement('DIV'); -chunk.style['float'] = 'none'; -chunk.innerHTML = html; -div.appendChild(chunk); -} -var cmd = Debug.win.document.getElementById('fe_command'); -cmd.focus(); -} -Debug.dirty = 0; -Debug.win.scrollTo(0, 99999); -}, -hires_time_now: function() { -var now = new Date(); -return ( now.getTime() / 1000 ); -}, -trace: function(cat, msg) { -if (arguments.length == 1) { -msg = cat; -cat = 'debug'; -} -if (Debug.categories.all || Debug.categories[cat]) { -Debug.buffer.push({ cat: cat, msg: msg, time: Debug.hires_time_now() }); -if (Debug.buffer.length > Debug.max_rows) Debug.buffer.shift(); -if (!Debug.dirty) { -Debug.dirty = 1; -setTimeout( 'Debug.refresh_console();', 1 ); -} -} -} -} -} ); -var session = { -inited: false, -api_mod_cache: {}, -query: parseQueryString( ''+location.search ), -cookie: new CookieTree({ path: '/effect/' }), -storage: {}, -storage_dirty: false, -hooks: { -keys: {} -}, -username: '', -em_width: 11, -audioResourceMatch: /\.mp3$/i, -imageResourceMatch: /\.(jpe|jpeg|jpg|png|gif)$/i, -textResourceMatch: /\.xml$/i, -movieResourceMatch: /\.(flv|mp4|mp4v|mov|3gp|3g2)$/i, -imageResourceMatchString: '\.(jpe|jpeg|jpg|png|gif)$' -}; -session.debug = session.query.debug ? true : false; -var page_manager = null; -var preload_icons = []; -var preload_images = [ -'loading.gif', -'aquaprogressbar.gif', -'aquaprogressbar_bkgnd.gif' -]; -function get_base_url() { -return protocol + '://' + location.hostname + session.config.BaseURI; -} -function effect_init() { -if (session.inited) return; -session.inited = true; -assert( window.config, "Config not loaded" ); -session.config = window.config; -Debug.trace("Starting up"); -rendering_page = false; -preload(); -window.$R = {}; -for (var key in config.RegExpShortcuts) { -$R[key] = new RegExp( config.RegExpShortcuts[key] ); -} -ww_precalc_font("body", "effect_precalc_font_finish"); -page_manager = new Effect.PageManager( config.Pages.Page ); -var session_id = session.cookie.get('effect_session_id'); -if (session_id && session_id.match(/^login/)) { -do_session_recover(); -} -else { -show_default_login_status(); -Nav.init(); -} -Blog.search({ -stag: 'sidebar_docs', -limit: 20, -title_only: true, -sort_by: 'seq', -sort_dir: -1, -target: 'd_sidebar_documents', -outer_div_class: 'sidebar_blog_row', -title_class: 'sidebar_blog_title', -after: '' -}); -Blog.search({ -stag: 'sidebar_tutorials', -limit: 5, -title_only: true, -sort_by: 'seq', -sort_dir: -1, -target: 'd_sidebar_tutorials', -outer_div_class: 'sidebar_blog_row', -title_class: 'sidebar_blog_title', -after: '' -}); -Blog.search({ -stag: 'sidebar_plugins', -limit: 5, -title_only: true, -sort_by: 'seq', -sort_dir: -1, -target: 'd_sidebar_plugins', -outer_div_class: 'sidebar_blog_row', -title_class: 'sidebar_blog_title', -after: '' -}); -$('fe_search_bar').onkeydown = delay_onChange_input_text; -user_storage_idle(); -} -function effect_precalc_font_finish(width, height) { -session.em_width = width; -} -function preload() { -for (var idx = 0, len = preload_icons.length; idx < len; idx++) { -var url = images_uri + '/icons/' + preload_icons[idx] + '.gif'; -preload_icons[idx] = new Image(); -preload_icons[idx].src = url; -} -for (var idx = 0, len = preload_images.length; idx < len; idx++) { -var url = images_uri + '/' + preload_images[idx]; -preload_images[idx] = new Image(); -preload_images[idx].src = url; -} -} -function $P(id) { -if (!id) id = page_manager.current_page_id; -var page = page_manager.find(id); -assert( !!page, "Failed to locate page: " + id ); -return page; -} -function get_pref(name) { -if (!session.user || !session.user.Preferences) return alert("ASSERT FAILURE! Tried to lookup pref " + name + " and user is not yet loaded!"); -return session.user.Preferences[name]; -} -function get_bool_pref(name) { -return (get_pref(name) == 1); -} -function set_pref(name, value) { -session.user.Preferences[name] = value; -} -function set_bool_pref(name, value) { -set_pref(name, value ? '1' : '0'); -} -function save_prefs() { -var prefs_to_save = {}; -if (arguments.length) { -for (var idx = 0, len = arguments.length; idx < len; idx++) { -var key = arguments[idx]; -prefs_to_save[key] = get_pref(key); -} -} -else prefs_to_save = session.user.Preferences; -effect_api_mod_touch('user_get'); -effect_api_send('user_update', { -Username: session.username, -Preferences: prefs_to_save -}, 'save_prefs_2'); -} -function save_prefs_2(response) { -do_message('success', 'Preferences saved.'); -} - -function get_full_name(username) { -var user = session.users[username]; -if (!user) return username; -return user.FullName; -} -function get_buddy_icon_url(username, size) { -var mod = session.api_mod_cache.get_buddy_icon || 0; -if (!size) size = 32; -var url = '/effect/api/get_buddy_icon?username='+username + '&mod=' + mod + '&size=' + size; -return url; -} -function get_buddy_icon_display(username, show_icon, show_name) { -if ((typeof(show_icon) == 'undefined') && get_bool_pref('show_user_icons')) show_icon = 1; -if ((typeof(show_name) == 'undefined') && get_bool_pref('show_user_names')) show_name = 1; -var html = ''; -if (show_icon) html += ''; -if (show_icon && show_name) html += '
'; -if (show_name) html += username; -return html; -} -function do_session_recover() { -session.hooks.after_error = 'do_logout'; -effect_api_send('session_recover', {}, 'do_login_2', { _from_recover: 1 } ); -} -function require_login() { -if (session.user) return true; -Debug.trace('Page requires login, showing login page'); -session.nav_after_login = Nav.currentAnchor(); -setTimeout( function() { -Nav.go( 'Login' ); -}, 1 ); -return false; -} -function popup_window(url, name) { -if (!url) url = ''; -if (!name) name = ''; -var win = window.open(url, name); -if (!win) return alert('Failed to open popup window. If you have a popup blocker, please disable it for this website and try again.'); -return win; -} -function do_login_prompt() { -hide_popup_dialog(); -delete session.progress; -if (!session.temp_password) session.temp_password = ''; -if (!session.username) session.username = ''; -var temp_username = session.open_id || session.username || ''; -var html = ''; -html += '
'; -html += '
'; -html += '
Effect Developer Login
'; -html += '
'; -html += '
Effect Username  or  '+icon('openid', 'OpenID', 'popup_window(\'http://openid.net/\')', 'What is OpenID?')+'


'; -html += '
'; -html += '
'; -html += '

'; -html += ''; -html += ''; -html += ''; -html += '
' + large_icon_button('x', 'Cancel', "clear_login()") + ' ' + large_icon_button('check', 'Login', 'do_login()') + '
'; -html += '
'; -html += ''; -session.hooks.keys[ENTER_KEY] = 'do_login'; -session.hooks.keys[ESC_KEY] = 'clear_login'; -safe_focus( 'fe_username' ); -show_popup_dialog(450, 225, html); -} -function do_openid_reg(title, auto_login_button) { -hide_popup_dialog(); -delete session.progress; -if (!title) title = 'Register Account Using OpenID'; -if (typeof(auto_login_button) == 'undefined') auto_login_button = 1; -var html = ''; -html += '
'; -html += '
'; -html += '
'+title+'
'; -html += '
'; -html += '
'+icon('openid', 'Enter Your OpenID URL:')+'
'; -if (auto_login_button) html += '


'; -html += '
'; -html += '

'; -html += ''; -html += ''; -html += ''; -html += '
' + large_icon_button('x', 'Cancel', "hide_popup_dialog()") + ' ' + large_icon_button('check', title.match(/login/i) ? 'Login' : 'Register', 'do_openid_login()') + '
'; -html += '
'; -html += ''; -session.hooks.keys[ENTER_KEY] = 'do_openid_login'; -session.hooks.keys[ESC_KEY] = 'hide_popup_dialog'; -safe_focus( 'fe_username' ); -show_popup_dialog(450, 225, html); -} -function do_login_prompt_2() { -hide_popup_dialog(); -delete session.progress; -if (!session.temp_password) session.temp_password = ''; -if (!session.username) session.username = ''; -var html = ''; -html += '
'; -html += '
'; -html += '
Enter Your Password
'; -html += '
'; -html += '
Password:


'; -html += '
'; -html += '
'; -html += '

'; -html += ''; -html += ''; -html += ''; -html += '
' + large_icon_button('x', 'Cancel', "clear_login()") + ' ' + large_icon_button('check', 'Login', 'do_effect_login()') + '
'; -html += '
'; -html += ''; -session.hooks.keys[ENTER_KEY] = 'do_effect_login'; -session.hooks.keys[ESC_KEY] = 'clear_login'; -safe_focus( 'fe_lp_password' ); -show_popup_dialog(450, 225, html); -} -function clear_login() { -hide_popup_dialog(); -Nav.prev(); -} -function do_login() { -if ($('fe_username').value.match(/^\w+$/)) { -session.username = $('fe_username').value; -session.auto_login = $('fe_auto_login').checked; -do_login_prompt_2(); -return; -} -else { -do_openid_login(); -} -} -function do_openid_login() { -if (!$('fe_username').value) return; -session.openid_win = popup_window(''); -if (!session.openid_win) return; -session.open_id = $('fe_username').value; -session.auto_login = $('fe_auto_login') && $('fe_auto_login').checked; -hide_popup_dialog(); -show_progress_dialog(1, "Logging in..."); -session.hooks.before_error = 'close_openid_window'; -session.hooks.after_error = 'do_login_prompt'; -effect_api_send('openid_login', { -OpenID: session.open_id, -Infinite: session.auto_login ? 1 : 0 -}, 'do_openid_login_2'); -} -function close_openid_window() { -if (session.openid_win) { -session.openid_win.close(); -delete session.openid_win; -} -} -function do_openid_login_2(response) { -if (response.CheckURL) { -Debug.trace('openid', "Redirecting popup window to OpenID Check URL: " + response.CheckURL); -show_progress_dialog(1, "Waiting for popup window...", false, ['x', 'Cancel', 'do_login_prompt()']); -session.openid_win.location = response.CheckURL; -session.openid_win.focus(); -} -} -function receive_openid_response(iframe_response) { -var response = deep_copy_object(iframe_response); -Debug.trace('openid', "Received OpenID Response: " + dumper(response)); -hide_popup_dialog(); -if (response.Code) { -close_openid_window(); -return do_error( response.Description ); -} -delete session.hooks.before_error; -delete session.hooks.after_error; -if (response.SessionID) { -session.cookie.set( 'effect_session_id', response.SessionID ); -session.cookie.save(); -} -switch (response.Action) { -case 'popup': -show_progress_dialog(1, "Waiting for popup window...", false, ['x', 'Cancel', 'do_login_prompt()']); -Debug.trace('openid', "Redirecting popup window to OpenID Setup URL: " + response.SetupURL); -session.openid_win.location = response.SetupURL; -session.openid_win.focus(); -break; -case 'login': -close_openid_window(); -do_login_2(response); -break; -case 'register': -if (!response.Info) response.Info = {}; -close_openid_window(); -Debug.trace('openid', 'Original OpenID: ' + response.OpenID_Login); -Debug.trace('openid', 'Clean OpenID: ' + response.OpenID_Unique); -Debug.trace('openid', 'Registration Info: ' + dumper(response.Info)); -session.prereg = response.Info; -session.prereg.open_id_login = response.OpenID_Login; -session.prereg.open_id = response.OpenID_Unique; -if (session.user) { -if (!session.user.OpenIDs) session.user.OpenIDs = {}; -if (!session.user.OpenIDs.OpenID) session.user.OpenIDs.OpenID = []; -var dupe = find_object( session.user.OpenIDs.OpenID, { Unique: session.prereg.open_id } ); -if (dupe) return do_error("That OpenID is already registered and attached to your account. No need to add it again."); -session.user.OpenIDs.OpenID.push({ -Login: session.prereg.open_id_login, -Unique: session.prereg.open_id -}); -setTimeout( function() { -Nav.go('MyAccount', true); -do_message('success', 'Added new OpenID URL to account.'); -}, 1 ); -} -else { -setTimeout( function() { Nav.go('CreateAccount', true); }, 1 ); -} -break; -} -} -function do_effect_login() { -var password = $('fe_lp_password').value; -session.auto_login = $('fe_auto_login').checked; -hide_popup_dialog(); -show_progress_dialog(1, "Logging in..."); -session.hooks.after_error = 'do_login_prompt'; -effect_api_send('user_login', { -Username: session.username, -Password: password, -Infinite: session.auto_login ? 1 : 0 -}, 'do_login_2'); -} -function do_logout() { -effect_api_send('user_logout', {}, 'do_logout_2'); -} -function do_logout_2(response) { -hide_popup_dialog(); -show_default_login_status(); -delete session.hooks.after_error; -delete session.cookie.tree.effect_session_id; -session.cookie.save(); -session.storage = {}; -session.storage_dirty = false; -delete session.user; -delete session.first_login; -var old_username = session.username; -session.username = ''; -if (Nav.inited) { -Nav.go('Main'); -if (old_username) $GR.growl('success', "Logged out of account: " + old_username); -} -else { -Nav.init(); -} -} -function do_login_2(response, tx) { -if (response.FirstLogin) session.first_login = 1; -if (response.User.UserStorage) { -Debug.trace('Recovering site storage blob: session.storage = ' + response.User.UserStorage + ';'); -try { -eval( 'session.storage = ' + response.User.UserStorage + ';' ); -} -catch (e) { -Debug.trace("SITE STORAGE RECOVERY FAILED: " + e); -session.storage = {}; -} -delete response.User.UserStorage; -session.storage_dirty = false; -} -session.user = response.User; -session.username = session.user.Username; -hide_popup_dialog(); -delete session.hooks.after_error; -update_header(); -if (!tx || !tx._from_recover) $GR.growl('success', "Logged in as: " + session.username); -if (session.nav_after_login) { -Nav.go( session.nav_after_login ); -delete session.nav_after_login; -} -else if (Nav.currentAnchor().match(/^Login/)) { -Nav.go('Home'); -} -else { -Nav.refresh(); -} -Nav.init(); -} -function user_storage_mark() { -Debug.trace("Marking user storage as dirty"); -session.storage_dirty = true; -} -function user_storage_idle() { -if (session.storage_dirty && !session.mouseIsDown) { -user_storage_save(); -session.storage_dirty = false; -} -setTimeout( 'user_storage_idle()', 5000 ); -} -function user_storage_save() { -if (session.user) { -Debug.trace("Committing user storage blob"); -effect_api_send('update_user_storage', { Data: serialize(session.storage) }, 'user_storage_save_finish', { _silent: 1 } ); -} -} -function user_storage_save_finish(response, tx) { -} -function show_default_login_status() { -$('d_sidebar_wrapper_recent_games').hide(); -$('d_login_status').innerHTML = '
' + -'
' + -large_icon_button('key', "Login", '#Home') + '' + spacer(1,1) + '' + -'' + large_icon_button('user_add.png', "Signup", '#CreateAccount') + '
' + -'
'; -$('d_tagline').innerHTML = -'Login' + ' | ' + -'Create Account'; -} -function update_header() { -var html = ''; -html += '
'; -html += ''; -html += ''; -html += ''; -html += ''+spacer(2,2)+''; -html += session.user.FullName + '
'; -html += spacer(1,5) + '
'; -html += 'My Home  |  '; -html += 'Logout'; -html += '
'; -$('d_login_status').innerHTML = html; -$('d_tagline').innerHTML = -'Welcome '+session.user.FirstName+'' + ' | ' + -'My Home' + ' | ' + -'Logout'; -effect_api_get( 'get_user_games', { limit:5, offset:0 }, 'receive_sidebar_recent_games', { } ); -} -function receive_sidebar_recent_games(response, tx) { -var html = ''; -if (response.Rows && response.Rows.Row) { -var games = always_array( response.Rows.Row ); -for (var idx = 0, len = games.length; idx < len; idx++) { -var game = games[idx]; -html += ''; -} -html += ''; -$('d_sidebar_recent_games').innerHTML = html; -$('d_sidebar_wrapper_recent_games').show(); -} -else { -$('d_sidebar_wrapper_recent_games').hide(); -} -} -function check_privilege(key) { -if (!session.user) return false; -if (session.user.Privileges.admin == 1) return true; -if (!key.toString().match(/^\//)) key = '/' + key; -var value = lookup_path(key, session.user.Privileges); -return( value && (value != 0) ); -} -function is_admin() { -return check_privilege('admin'); -} -function upgrade_flash_error() { -return alert("Sorry, file upload requires Adobe Flash Player 9 or higher."); -} -function cancel_user_image_manager() { -upload_destroy(); -hide_popup_dialog(); -delete session.hooks.keys[DELETE_KEY]; -} -function do_user_image_manager(callback) { -if (callback) session.uim_callback = callback; -else session.uim_callback = null; -session.temp_last_user_img = null; -session.temp_last_user_image_filename = ''; -var html = '
'; -html += '
Image Manager
'; -html += '
'; -html += ''; -html += '
'; -html += '
'; -html += ''; -html += ''; -html += ''; -html += ''; -html += ''; -html += '
' + large_icon_button('x', 'Cancel', 'cancel_user_image_manager()') + ' ' + large_icon_button('bullet_upload.png', 'Upload Files...', 'upload_basic()', 'b_upload_user_image') + ' ' + large_icon_button('check', 'Choose', 'do_choose_user_image()', 'btn_choose_user_image', '', 'disabled') + '
'; -html += '
'; -session.hooks.keys[ENTER_KEY] = 'do_choose_user_image'; -session.hooks.keys[ESC_KEY] = 'cancel_user_image_manager'; -session.hooks.keys[DELETE_KEY] = 'do_delete_selected_user_image'; -show_popup_dialog(500, 300, html); -var self = this; -setTimeout( function() { -prep_upload('b_upload_user_image', '/effect/api/upload_user_image', [self, 'do_upload_user_image_2'], ['Image Files', '*.jpg;*.jpe;*.jpeg;*.gif;*.png']); -}, 1 ); -var args = { -limit: 50, -offset: 0, -random: Math.random() -}; -effect_api_get( 'user_images_get', args, 'uim_populate_images', { } ); -} -function do_upload_user_image_2() { -effect_api_mod_touch('user_images_get'); -effect_api_send('user_get', { -Username: session.username -}, [this, 'do_upload_user_image_3']); -} -function do_upload_user_image_3(response) { -if (response.User.LastUploadError) return do_error( "Failed to upload image: " + response.User.LastUploadError ); -do_user_image_manager( session.uim_callback ); -} -function uim_populate_images(response, tx) { -var html = ''; -var base_url = '/effect/api/view/users/' + session.username + '/images'; -if (response.Rows && response.Rows.Row) { -var imgs = always_array( response.Rows.Row ); -for (var idx = 0, len = imgs.length; idx < len; idx++) { -var img = imgs[idx]; -var class_name = ((img.Filename == session.temp_last_user_image_filename) ? 'choose_item_selected' : 'choose_item'); -html += ''; -} -} -else { -html = ''; -} -$('d_user_image_list').innerHTML = html; -} -function do_select_user_image(img, filename) { -if (session.temp_last_user_img) session.temp_last_user_img.className = 'choose_item'; -img.className = 'choose_item_selected'; -$('btn_choose_user_image').removeClass('disabled'); -session.temp_last_user_img = img; -session.temp_last_user_image_filename = filename; -} -function do_delete_selected_user_image() { -if (session.temp_last_user_image_filename) { -effect_api_send('user_image_delete', { Filename: session.temp_last_user_image_filename }, 'do_delete_selected_user_image_finish', {}); -} -} -function do_delete_selected_user_image_finish(response, tx) { -try { $('d_user_image_list').removeChild( session.temp_last_user_img ); } catch(e) {;} -session.temp_last_user_img = null; -session.temp_last_user_image_filename = null; -} -function do_choose_user_image() { -if (!session.temp_last_user_image_filename) return; -if (session.uim_callback) { -fire_callback( session.uim_callback, session.temp_last_user_image_filename ); -} -cancel_user_image_manager(); -} -function user_image_thumbnail(filename, width, height, attribs) { -var username = session.username; -if (filename.match(/^(\w+)\/(.+)$/)) { -username = RegExp.$1; -filename = RegExp.$2; -} -var url = '/effect/api/view/users/' + username + '/images/' + filename.replace(/\.(\w+)$/, '_thumb.jpg'); -return ''; -} -function get_user_display(username, full_name, base_url) { -if (!base_url) base_url = ''; -return icon('user', full_name || username, base_url + '#User/' + username); -} -function get_game_tab_bar(game_id, cur_page_name) { -return tab_bar([ -['#Game/' + game_id, 'Game', 'controller.png'], -['#GameDisplay/' + game_id, 'Display', 'monitor.png'], -['#GameAssets/' + game_id, 'Assets', 'folder_page_white.png'], -['#GameObjects/' + game_id, 'Objects', 'bricks.png'], -['#GameAudio/' + game_id, 'Audio', 'sound.gif'], -['#GameKeys/' + game_id, 'Keyboard', 'keyboard.png'], -['#GameLevels/' + game_id, 'Levels', 'world.png'], -['#GamePublisher/' + game_id, 'Publish', 'cd.png'] -], cur_page_name); -} -function get_user_tab_bar(cur_page_name) { -var tabs = [ -['#Home', 'My Home', 'house.png'] -]; -tabs.push( ['#MyAccount', 'Edit Account', 'user_edit.png'] ); -tabs.push( ['#ArticleEdit', 'Post Article', 'page_white_edit.png'] ); -if (config.ProEnabled) { -tabs.push( ['#UserPayments', 'Payments', 'money.png'] ); -} -tabs.push( ['#UserLog', 'Security Log', 'application_view_detail.png'] ); -return tab_bar(tabs, cur_page_name); -} -function get_admin_tab_bar(cur_page_name) { -var tabs = []; -tabs.push( ['#Admin', 'Admin', 'lock.png'] ); -tabs.push( ['#TicketSearch/bugs', 'Bug Tracker', 'bug.png'] ); -tabs.push( ['#TicketSearch/helpdesk', 'Help Desk', 'telephone.png'] ); -tabs.push( ['#AdminReport', 'Reports', 'chart_pie.png'] ); -return tab_bar(tabs, cur_page_name); -} -function get_string(path, args) { -assert(window.config, "get_string() called before config loaded"); -if (!args) args = {}; -args.config = config; -args.session = session; -args.query = session.query; -var value = lookup_path(path, config.Strings); -return (typeof(value) == 'string') ? substitute(value, args) : value; -} -function normalize_dir_path(path) { -if (!path.match(/^\//)) path = '/' + path; -if (!path.match(/\/$/)) path += '/'; -return path; -} -function textedit_window_save(storage_key, filename, content, callback) { -if (!callback) callback = null; -effect_api_mod_touch('textedit'); -if (storage_key.match(/^\/games\/([a-z0-9][a-z0-9\-]*[a-z0-9])\/assets(.+)$/)) { -var game_id = RegExp.$1; -var path = RegExp.$2; -show_progress_dialog(1, "Saving file..."); -effect_api_send('asset_save_file_contents', { -GameID: game_id, -Path: path, -Filename: filename, -Content: content -}, 'textedit_window_save_finish', { _mode: 'asset', _game_id: game_id, _filename: filename, _callback: callback } ); -} -else { -show_progress_dialog(1, "Saving data..."); -effect_api_send('admin_save_file_contents', { -Path: storage_key, -Filename: filename, -Content: content -}, 'textedit_window_save_finish', { _mode: 'admin', _storage_key: storage_key, _filename: filename, _callback: callback } ); -} -} -function textedit_window_save_finish(response, tx) { -hide_progress_dialog(); -if (tx._mode == 'asset') { -do_message('success', "Saved asset: \""+tx._filename+"\""); -show_glog_widget(); -} -else { -do_message('success', "Saved data: \""+tx._storage_key+'/'+tx._filename+"\""); -} -if (tx._callback) tx._callback(); -} -function do_buy(args) { -$P().hide(); -$('d_page_loading').show(); -effect_api_send('create_order', args, 'do_buy_redirect', { _buy_args: args } ); -} -function do_buy_redirect(response, tx) { -var args = tx._buy_args; -$('fe_gco_title').value = args.Title || ''; -$('fe_gco_desc').value = args.Desc || ''; -$('fe_gco_price').value = args.Price || ''; -$('fe_gco_after').value = args.After || ''; -$('fe_gco_unique_id').value = response.OrderID; -Debug.trace('payment', "Redirecting to Google Checkout"); -setTimeout( function() { $('BB_BuyButtonForm').submit(); }, 1 ); -} -function show_glog_widget(game_id) { -if (!game_id) game_id = session.glog_game_id; -if (!game_id) { -$('glog_widget').hide(); -return; -} -if (game_id != session.glog_game_id) { -$('glog_widget').hide(); -session.glog_game_id = game_id; -update_glog_widget(game_id); -} -else { -$('glog_widget').show(); -setTimeout( function() { update_glog_widget(game_id); }, 500 ); -} -} -function update_glog_widget(game_id) { -effect_api_get('game_get_log', { -id: game_id, -offset: 0, -limit: 1, -rand: Math.random() -}, 'receive_glog_data', { _game_id: game_id }); -} -function receive_glog_data(response, tx) { -var game_id = tx._game_id; -if (response && response.Rows && response.Rows.Row) { -var rows = always_array( response.Rows.Row ); -var row = rows[0]; -var html = ''; -html += '
'; -html += '
Latest Game Activity
'; -html += ''; -html += ''; -html += '
'; -html += '
'; -html += ''; -html += ''; -html += ''; -html += '
' + get_buddy_icon_display(row.Username, 1, 0) + ''; -html += '
' + icon( get_icon_for_glog_type(row.Type), ''+row.Message+'' ) + '
'; -html += '
' + get_relative_date(row.Date, true) + '
'; -html += '
'; -$('glog_widget').innerHTML = html; -$('glog_widget').show(); -} -} -function show_glog_post_dialog(game_id) { -hide_popup_dialog(); -delete session.progress; -var html = ''; -html += '
'; -html += '"; - second_cell = ""; - row = $("").attr("id", "s" + index).attr("class", "location_row").html(first_cell + second_cell); - $locationsDiv.append(row); - } - if (index === this.numSearchToDisplay) { - $locationsDiv.append(""); - return $locationsDiv.append(""); - } - }, this); - return this.geocoder.geocode({ - address: address - }, __bind(function(result, status) { - if (status !== "OK") { - $('.error_message').html(t("Search Address Failed")).fadeIn(); - return; - } - _.each(result, showResults); - $("#search_results").html($locationsDiv); - this.locationChange("search"); - this.searchResults = result; - return this.displaySearchLoc(); - }, this)); - }; - ClientsRequestView.prototype.mouseoverLocation = function(e) { - var $el, id, marker; - $el = $(e.currentTarget); - id = $el.attr("id").substring(1); - marker = this.markers[id]; - return marker.setAnimation(google.maps.Animation.BOUNCE); - }; - ClientsRequestView.prototype.mouseoutLocation = function(e) { - var $el, id, marker; - $el = $(e.currentTarget); - id = $el.attr("id").substring(1); - marker = this.markers[id]; - return marker.setAnimation(null); - }; - ClientsRequestView.prototype.searchLocation = function(e) { - e.preventDefault(); - $("#address").val($(e.currentTarget).html()); - return this.searchAddress(); - }; - ClientsRequestView.prototype.favoriteClick = function(e) { - var index, location; - e.preventDefault(); - $(".favorites").attr("href", ""); - index = $(e.currentTarget).removeAttr("href").attr("id"); - location = new google.maps.LatLng(USER.locations[index].latitude, USER.locations[index].longitude); - return this.panToLocation(location); - }; - ClientsRequestView.prototype.clickLocation = function(e) { - var id; - id = $(e.currentTarget).attr("id").substring(1); - return this.panToLocation(this.markers[id].getPosition()); - }; - ClientsRequestView.prototype.panToLocation = function(location) { - this.map.panTo(location); - this.map.setZoom(16); - return this.pickup_icon.setPosition(location); - }; - ClientsRequestView.prototype.locationLinkHandle = function(e) { - var panelName; - e.preventDefault(); - panelName = $(e.currentTarget).attr("id"); - return this.locationChange(panelName); - }; - ClientsRequestView.prototype.locationChange = function(type) { - $(".locations_link").attr("href", "").css("font-weight", "normal"); - switch (type) { - case "favorite": - $(".search_results").attr("href", ""); - $(".locations_link#favorite").removeAttr("href").css("font-weight", "bold"); - $("#search_results").hide(); - $("#favorite_results").fadeIn(); - return this.displayFavLoc(); - case "search": - $(".favorites").attr("href", ""); - $(".locations_link#search").removeAttr("href").css("font-weight", "bold"); - $("#favorite_results").hide(); - $("#search_results").fadeIn(); - return this.displaySearchLoc(); - } - }; - ClientsRequestView.prototype.rateTrip = function(e) { - var rating; - rating = $(e.currentTarget).attr("id"); - $(".stars").attr("src", "/web/img/star_inactive.png"); - return _(rating).times(function(index) { - return $(".stars#" + (index + 1)).attr("src", "/web/img/star_active.png"); - }); - }; - ClientsRequestView.prototype.pickupHandle = function(e) { - var $el, callback, message; - e.preventDefault(); - $el = $(e.currentTarget).find("span"); - switch ($el.html()) { - case t("Request Pickup"): - _.delay(this.requestRide, 3000); - $("#status_message").html(t("Sending pickup request...")); - $el.html(t("Cancel Pickup")).parent().attr("class", "button_red"); - this.pickup_icon.setDraggable(false); - this.map.panTo(this.pickup_icon.getPosition()); - return this.map.setZoom(18); - case t("Cancel Pickup"): - if (this.status === "ready") { - $el.html(t("Request Pickup")).parent().attr("class", "button_green"); - return this.pickup_icon.setDraggable(true); - } else { - callback = __bind(function(v, m, f) { - if (v) { - this.AskDispatch("PickupCanceledClient"); - return this.setStatus("ready"); - } - }, this); - message = t("Cancel Request Prompt"); - if (this.status === "arriving") { - message = 'Cancel Request Arrived Prompt'; - } - return $.prompt(message, { - buttons: { - Ok: true, - Cancel: false - }, - callback: callback - }); - } - } - }; - ClientsRequestView.prototype.requestRide = function() { - if ($("#pickupHandle").find("span").html() === t("Cancel Pickup")) { - this.AskDispatch("Pickup"); - return this.setStatus("searching"); - } - }; - ClientsRequestView.prototype.removeCabs = function() { - _.each(this.cabs, __bind(function(point) { - return point.setMap(null); - }, this)); - return this.cabs = []; - }; - ClientsRequestView.prototype.addToFavLoc = function(e) { - var $el, lat, lng, nickname; - e.preventDefault(); - $el = $(e.currentTarget); - $el.find(".error_message").html(""); - nickname = $el.find("#favLocNickname").val().toString(); - lat = $el.find("#pickupLat").val().toString(); - lng = $el.find("#pickupLng").val().toString(); - if (nickname.length < 3) { - $el.find(".error_message").html(t("Favorite Location Nickname Length Error")); - return; - } - this.ShowSpinner("submit"); - return $.ajax({ - type: 'POST', - url: API + "/locations", - dataType: 'json', - data: { - token: USER.token, - nickname: nickname, - latitude: lat, - longitude: lng - }, - success: __bind(function(data, textStatus, jqXHR) { - return $el.html(t("Favorite Location Save Succeeded")); - }, this), - error: __bind(function(jqXHR, textStatus, errorThrown) { - return $el.find(".error_message").html(t("Favorite Location Save Failed")); - }, this), - complete: __bind(function(data) { - return this.HideSpinner(); - }, this) - }); - }; - ClientsRequestView.prototype.showFavLoc = function(e) { - $(e.currentTarget).fadeOut(); - return $("#favLoc_form").fadeIn(); - }; - ClientsRequestView.prototype.selectInputText = function(e) { - e.currentTarget.focus(); - return e.currentTarget.select(); - }; - ClientsRequestView.prototype.displayFavLoc = function() { - var alphabet, bounds; - alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - this.removeMarkers(); - bounds = new google.maps.LatLngBounds(); - _.each(USER.locations, __bind(function(location, index) { - var marker; - marker = new google.maps.Marker({ - position: new google.maps.LatLng(location.latitude, location.longitude), - map: this.map, - title: t("Favorite Location Title", { - id: alphabet != null ? alphabet[index] : void 0 - }), - icon: "https://www.google.com/mapfiles/marker" + alphabet[index] + ".png" - }); - this.markers.push(marker); - bounds.extend(marker.getPosition()); - return google.maps.event.addListener(marker, 'click', __bind(function() { - return this.pickup_icon.setPosition(marker.getPosition()); - }, this)); - }, this)); - this.pickup_icon.setPosition(_.first(this.markers).getPosition()); - return this.map.fitBounds(bounds); - }; - ClientsRequestView.prototype.displaySearchLoc = function() { - var alphabet; - alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - this.removeMarkers(); - return _.each(this.searchResults, __bind(function(result, index) { - var marker; - if (index < this.numSearchToDisplay) { - marker = new google.maps.Marker({ - position: result.geometry.location, - map: this.map, - title: t("Search Location Title", { - id: alphabet != null ? alphabet[index] : void 0 - }), - icon: "https://www.google.com/mapfiles/marker" + alphabet[index] + ".png" - }); - this.markers.push(marker); - return this.panToLocation(result.geometry.location); - } - }, this)); - }; - ClientsRequestView.prototype.removeMarkers = function() { - _.each(this.markers, __bind(function(marker) { - return marker.setMap(null); - }, this)); - return this.markers = []; - }; - ClientsRequestView.prototype.AskDispatch = function(ask, options) { - var attrs, lowestETA, processData, showCab; - if (ask == null) { - ask = ""; - } - if (options == null) { - options = {}; - } - switch (ask) { - case "NearestCab": - attrs = { - latitude: this.pickup_icon.getPosition().lat(), - longitude: this.pickup_icon.getPosition().lng() - }; - lowestETA = 99999; - showCab = __bind(function(cab) { - var point; - point = new google.maps.Marker({ - position: new google.maps.LatLng(cab.latitude, cab.longitude), - map: this.map, - icon: this.cabMarker, - title: t("ETA Message", { - minutes: app.helpers.FormatSeconds(cab != null ? cab.eta : void 0, true) - }) - }); - if (cab.eta < lowestETA) { - lowestETA = cab.eta; - } - return this.cabs.push(point); - }, this); - processData = __bind(function(data, textStatus, jqXHR) { - if (this.status === "ready") { - this.removeCabs(); - if (data.sorry) { - $("#status_message").html(data.sorry).fadeIn(); - } else { - _.each(data.driverLocations, showCab); - $("#status_message").html(t("Nearest Cab Message", { - minutes: app.helpers.FormatSeconds(lowestETA, true) - })).fadeIn(); - } - if (Backbone.history.fragment === "!/request") { - return _.delay(this.showCabs, this.pollInterval); - } - } - }, this); - return this.AjaxCall(ask, processData, attrs); - case "StatusClient": - processData = __bind(function(data, textStatus, jqXHR) { - var bounds, cabLocation, locationSaved, point, userLocation; - if (data.messageType === "OK") { - switch (data.status) { - case "completed": - this.removeCabs(); - this.setStatus("rate"); - return this.fetchTripDetails(data.tripID); - case "open": - return this.setStatus("ready"); - case "begintrip": - this.setStatus("riding"); - cabLocation = new google.maps.LatLng(data.latitude, data.longitude); - this.removeCabs(); - this.pickup_icon.setMap(null); - point = new google.maps.Marker({ - position: cabLocation, - map: this.map, - icon: this.cabMarker - }); - this.cabs.push(point); - this.map.panTo(point.getPosition()); - $("#rideName").html(data.driverName); - $("#ridePhone").html(data.driverMobile); - $("#ride_address_wrapper").hide(); - if (Backbone.history.fragment === "!/request") { - return _.delay(this.AskDispatch, this.pollInterval, "StatusClient"); - } - break; - case "pending": - this.setStatus("searching"); - if (Backbone.history.fragment === "!/request") { - return _.delay(this.AskDispatch, this.pollInterval, "StatusClient"); - } - break; - case "accepted": - case "arrived": - if (data.status === "accepted") { - this.setStatus("waiting"); - $("#status_message").html(t("Arrival ETA Message", { - minutes: app.helpers.FormatSeconds(data.eta, true) - })); - } else { - this.setStatus("arriving"); - $("#status_message").html(t("Arriving Now Message")); - } - userLocation = new google.maps.LatLng(data.pickupLocation.latitude, data.pickupLocation.longitude); - cabLocation = new google.maps.LatLng(data.latitude, data.longitude); - this.pickup_icon.setPosition(userLocation); - this.removeCabs(); - $("#rideName").html(data.driverName); - $("#ridePhone").html(data.driverMobile); - if ($("#rideAddress").html() === "") { - locationSaved = false; - _.each(USER.locations, __bind(function(location) { - if (parseFloat(location.latitude) === parseFloat(data.pickupLocation.latitude) && parseFloat(location.longitude) === parseFloat(data.pickupLocation.longitude)) { - return locationSaved = true; - } - }, this)); - if (locationSaved) { - $("#addToFavButton").hide(); - } - $("#pickupLat").val(data.pickupLocation.latitude); - $("#pickupLng").val(data.pickupLocation.longitude); - this.geocoder.geocode({ - location: userLocation - }, __bind(function(result, status) { - $("#rideAddress").html(result[0].formatted_address); - return $("#favLocNickname").val("" + result[0].address_components[0].short_name + " " + result[0].address_components[1].short_name); - }, this)); - } - point = new google.maps.Marker({ - position: cabLocation, - map: this.map, - icon: this.cabMarker - }); - this.cabs.push(point); - bounds = bounds = new google.maps.LatLngBounds(); - bounds.extend(cabLocation); - bounds.extend(userLocation); - this.map.fitBounds(bounds); - if (Backbone.history.fragment === "!/request") { - return _.delay(this.AskDispatch, this.pollInterval, "StatusClient"); - } - } - } - }, this); - return this.AjaxCall(ask, processData); - case "Pickup": - attrs = { - latitude: this.pickup_icon.getPosition().lat(), - longitude: this.pickup_icon.getPosition().lng() - }; - processData = __bind(function(data, textStatus, jqXHR) { - if (data.messageType === "Error") { - return $("#status_message").html(data.description); - } else { - return this.AskDispatch("StatusClient"); - } - }, this); - return this.AjaxCall(ask, processData, attrs); - case "PickupCanceledClient": - processData = __bind(function(data, textStatus, jqXHR) { - if (data.messageType === "OK") { - return this.setStatus("ready"); - } else { - return $("#status_message").html(data.description); - } - }, this); - return this.AjaxCall(ask, processData, attrs); - case "RatingDriver": - attrs = { - rating: options.rating - }; - processData = __bind(function(data, textStatus, jqXHR) { - if (data.messageType === "OK") { - this.setStatus("init"); - } else { - $("status_message").html(t("Rating Driver Failed")); - } - return this.HideSpinner(); - }, this); - return this.AjaxCall(ask, processData, attrs); - case "Feedback": - attrs = { - message: options.message - }; - processData = __bind(function(data, textStatus, jqXHR) { - if (data.messageType === "OK") { - return alert("rated"); - } - }, this); - return this.AjaxCall(ask, processData, attrs); - } - }; - ClientsRequestView.prototype.AjaxCall = function(type, successCallback, attrs) { - if (attrs == null) { - attrs = {}; - } - _.extend(attrs, { - token: USER.token, - messageType: type, - app: "client", - version: "1.0.60", - device: "web" - }); - return $.ajax({ - type: 'POST', - url: DISPATCH + "/", - processData: false, - data: JSON.stringify(attrs), - success: successCallback, - dataType: 'json', - error: __bind(function(jqXHR, textStatus, errorThrown) { - $("#status_message").html(errorThrown); - return this.HideSpinner(); - }, this) - }); - }; - return ClientsRequestView; - })(); -}).call(this); -}, "views/clients/settings": function(exports, require, module) {(function() { - var clientsSettingsTemplate; - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { - for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } - function ctor() { this.constructor = child; } - ctor.prototype = parent.prototype; - child.prototype = new ctor; - child.__super__ = parent.prototype; - return child; - }; - clientsSettingsTemplate = require('templates/clients/settings'); - exports.ClientsSettingsView = (function() { - __extends(ClientsSettingsView, UberView); - function ClientsSettingsView() { - this.render = __bind(this.render, this); - this.initialize = __bind(this.initialize, this); - ClientsSettingsView.__super__.constructor.apply(this, arguments); - } - ClientsSettingsView.prototype.id = 'settings_view'; - ClientsSettingsView.prototype.className = 'view_container'; - ClientsSettingsView.prototype.events = { - 'submit #profile_pic_form': 'processPicUpload', - 'click #submit_pic': 'processPicUpload', - 'click a.setting_change': "changeTab", - 'submit #edit_info_form': "submitInfo", - 'click #change_password': 'changePass' - }; - ClientsSettingsView.prototype.divs = { - 'info_div': "Information", - 'pic_div': "Picture" - }; - ClientsSettingsView.prototype.pageTitle = t("Settings") + " | " + t("Uber"); - ClientsSettingsView.prototype.tabTitle = { - 'info_div': t("Information"), - 'pic_div': t("Picture") - }; - ClientsSettingsView.prototype.initialize = function() { - return this.mixin(require('web-lib/mixins/i18n_phone_form').i18nPhoneForm); - }; - ClientsSettingsView.prototype.render = function(type) { - if (type == null) { - type = "info"; - } - this.RefreshUserInfo(__bind(function() { - var $el, alphabet; - this.delegateEvents(); - this.HideSpinner(); - alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - $el = $(this.el); - $(this.el).html(clientsSettingsTemplate({ - type: type - })); - $el.find("#" + type + "_div").show(); - $el.find("a[href='" + type + "_div']").parent().addClass("active"); - return document.title = "" + this.tabTitle[type + '_div'] + " " + this.pageTitle; - }, this)); - this.delegateEvents(); - return this; - }; - ClientsSettingsView.prototype.changeTab = function(e) { - var $eTarget, $el, div, link, pageDiv, _i, _j, _len, _len2, _ref, _ref2; - e.preventDefault(); - $eTarget = $(e.currentTarget); - this.ClearGlobalStatus(); - $el = $(this.el); - _ref = $el.find(".setting_change"); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - link = _ref[_i]; - $(link).parent().removeClass("active"); - } - $eTarget.parent().addClass("active"); - _ref2 = _.keys(this.divs); - for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { - div = _ref2[_j]; - $el.find("#" + div).hide(); - } - pageDiv = $eTarget.attr('href'); - $el.find("#" + pageDiv).show(); - Backbone.history.navigate("!/settings/" + (this.divs[pageDiv].toLowerCase().replace(" ", "-")), false); - document.title = "" + this.tabTitle[pageDiv] + " " + this.pageTitle; - if (pageDiv === "loc_div") { - try { - google.maps.event.trigger(this.map, 'resize'); - return this.map.fitBounds(this.bounds); - } catch (_e) {} - } - }; - ClientsSettingsView.prototype.submitInfo = function(e) { - var $e, attrs, client, options; - $('#global_status').find('.success_message').text(''); - $('#global_status').find('.error_message').text(''); - $('.error_message').text(''); - e.preventDefault(); - $e = $(e.currentTarget); - attrs = $e.serializeToJson(); - attrs['mobile_country_id'] = this.$('#mobile_country_id').val(); - if (attrs['password'] === '') { - delete attrs['password']; - } - options = { - success: __bind(function(response) { - this.ShowSuccess(t("Information Update Succeeded")); - return this.RefreshUserInfo(); - }, this), - error: __bind(function(model, data) { - var errors; - if (data.status === 406) { - errors = JSON.parse(data.responseText); - return _.each(_.keys(errors), function(field) { - return $("#" + field).parent().find('span.error_message').text(errors[field]); - }); - } else { - return this.ShowError(t("Information Update Failed")); - } - }, this), - type: "PUT" - }; - client = new app.models.client({ - id: USER.id - }); - return client.save(attrs, options); - }; - ClientsSettingsView.prototype.changePass = function(e) { - e.preventDefault(); - $(e.currentTarget).hide(); - return $("#password").show(); - }; - ClientsSettingsView.prototype.processPicUpload = function(e) { - e.preventDefault(); - this.ShowSpinner("submit"); - return $.ajaxFileUpload({ - url: API + '/user_pictures', - secureuri: false, - fileElementId: 'picture', - data: { - token: USER.token - }, - dataType: 'json', - complete: __bind(function(data, status) { - this.HideSpinner(); - if (status === 'success') { - this.ShowSuccess(t("Picture Update Succeeded")); - return this.RefreshUserInfo(__bind(function() { - return $("#settingsProfPic").attr("src", USER.picture_url + ("?" + (Math.floor(Math.random() * 1000)))); - }, this)); - } else { - if (data.error) { - return this.ShowError(data.error); - } else { - return this.ShowError("Picture Update Failed"); - } - } - }, this) - }); - }; - return ClientsSettingsView; - })(); -}).call(this); -}, "views/clients/sign_up": function(exports, require, module) {(function() { - var clientsSignUpTemplate; - var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { - for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } - function ctor() { this.constructor = child; } - ctor.prototype = parent.prototype; - child.prototype = new ctor; - child.__super__ = parent.prototype; - return child; - }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; - clientsSignUpTemplate = require('templates/clients/sign_up'); - exports.ClientsSignUpView = (function() { - __extends(ClientsSignUpView, UberView); - function ClientsSignUpView() { - ClientsSignUpView.__super__.constructor.apply(this, arguments); - } - ClientsSignUpView.prototype.id = 'signup_view'; - ClientsSignUpView.prototype.className = 'view_container'; - ClientsSignUpView.prototype.initialize = function() { - this.mixin(require('web-lib/mixins/i18n_phone_form').i18nPhoneForm); - return $('#location_country').live('change', function() { - if (!$('#mobile').val()) { - return $('#mobile_country').find("option[value=" + ($(this).val()) + "]").attr('selected', 'selected').end().trigger('change'); - } - }); - }; - ClientsSignUpView.prototype.events = { - 'submit form': 'signup', - 'click button': 'signup', - 'change #card_number': 'showCardType', - 'change #location_country': 'countryChange' - }; - ClientsSignUpView.prototype.render = function(invite) { - this.HideSpinner(); - $(this.el).html(clientsSignUpTemplate({ - invite: invite - })); - return this; - }; - ClientsSignUpView.prototype.signup = function(e) { - var $el, attrs, client, error_messages, options; - e.preventDefault(); - $el = $("form"); - $el.find('#terms_error').hide(); - if (!$el.find('#signup_terms input[type=checkbox]').attr('checked')) { - $('#spinner.submit').hide(); - $el.find('#terms_error').show(); - return; - } - error_messages = $el.find('.error_message').html(""); - attrs = { - first_name: $el.find('#first_name').val(), - last_name: $el.find('#last_name').val(), - email: $el.find('#email').val(), - password: $el.find('#password').val(), - location_country: $el.find('#location_country option:selected').attr('data-iso2'), - location: $el.find('#location').val(), - language: $el.find('#language').val(), - mobile_country: $el.find('#mobile_country option:selected').attr('data-iso2'), - mobile: $el.find('#mobile').val(), - card_number: $el.find('#card_number').val(), - card_expiration_month: $el.find('#card_expiration_month').val(), - card_expiration_year: $el.find('#card_expiration_year').val(), - card_code: $el.find('#card_code').val(), - use_case: $el.find('#use_case').val(), - promotion_code: $el.find('#promotion_code').val() - }; - options = { - statusCode: { - 200: function(response) { - $.cookie('token', response.token); - amplify.store('USERjson', response); - app.refreshMenu(); - return app.routers.clients.navigate('!/dashboard', true); - }, - 406: function(e) { - var error, errors, _i, _len, _ref, _results; - errors = JSON.parse(e.responseText); - _ref = _.keys(errors); - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - error = _ref[_i]; - _results.push($('#' + error).parent().find('span').html($('#' + error).parent().find('span').html() + " " + errors[error])); - } - return _results; - } - }, - complete: __bind(function(response) { - return this.HideSpinner(); - }, this) - }; - client = new app.models.client; - $('.spinner#submit').show(); - return client.save(attrs, options); - }; - ClientsSignUpView.prototype.countryChange = function(e) { - var $e; - $e = $(e.currentTarget); - return $("#mobile_country").val($e.val()).trigger('change'); - }; - ClientsSignUpView.prototype.showCardType = function(e) { - var $el, reAmerica, reDiscover, reMaster, reVisa, validCard; - reVisa = /^4\d{3}-?\d{4}-?\d{4}-?\d{4}$/; - reMaster = /^5[1-5]\d{2}-?\d{4}-?\d{4}-?\d{4}$/; - reAmerica = /^6011-?\d{4}-?\d{4}-?\d{4}$/; - reDiscover = /^3[4,7]\d{13}$/; - $el = $("#card_logos_signup"); - validCard = false; - if (e.currentTarget.value.match(reVisa)) { - $el.find("#overlay_left").css('width', "0px"); - return $el.find("#overlay_right").css('width', "75%"); - } else if (e.currentTarget.value.match(reMaster)) { - $el.find("#overlay_left").css('width', "25%"); - return $el.find("#overlay_right").css('width', "50%"); - } else if (e.currentTarget.value.match(reAmerica)) { - $el.find("#overlay_left").css('width', "75%"); - $el.find("#overlay_right").css('width', "0px"); - return console.log("amex"); - } else if (e.currentTarget.value.match(reDiscover)) { - $el.find("#overlay_left").css('width', "50%"); - return $el.find("#overlay_right").css('width', "25%"); - } else { - $el.find("#overlay_left").css('width', "0px"); - return $el.find("#overlay_right").css('width', "0px"); - } - }; - return ClientsSignUpView; - })(); -}).call(this); -}, "views/clients/trip_detail": function(exports, require, module) {(function() { - var clientsTripDetailTemplate; - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { - for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } - function ctor() { this.constructor = child; } - ctor.prototype = parent.prototype; - child.prototype = new ctor; - child.__super__ = parent.prototype; - return child; - }; - clientsTripDetailTemplate = require('templates/clients/trip_detail'); - exports.TripDetailView = (function() { - __extends(TripDetailView, UberView); - function TripDetailView() { - this.resendReceipt = __bind(this.resendReceipt, this); - TripDetailView.__super__.constructor.apply(this, arguments); - } - TripDetailView.prototype.id = 'trip_detail_view'; - TripDetailView.prototype.className = 'view_container'; - TripDetailView.prototype.events = { - 'click a#fare_review': 'showFareReview', - 'click #fare_review_hide': 'hideFareReview', - 'submit #form_review_form': 'submitFareReview', - 'click #submit_fare_review': 'submitFareReview', - 'click .resendReceipt': 'resendReceipt' - }; - TripDetailView.prototype.render = function(id) { - if (id == null) { - id = 'invalid'; - } - this.ReadUserInfo(); - this.HideSpinner(); - this.model = new app.models.trip({ - id: id - }); - this.model.fetch({ - data: { - relationships: 'points,driver,city.country' - }, - dataType: 'json', - success: __bind(function() { - var trip; - trip = this.model; - $(this.el).html(clientsTripDetailTemplate({ - trip: trip - })); - this.RequireMaps(__bind(function() { - var bounds, endPos, map, myOptions, path, polyline, startPos; - bounds = new google.maps.LatLngBounds(); - path = []; - _.each(this.model.get('points'), __bind(function(point) { - path.push(new google.maps.LatLng(point.lat, point.lng)); - return bounds.extend(_.last(path)); - }, this)); - myOptions = { - zoom: 12, - center: path[0], - mapTypeId: google.maps.MapTypeId.ROADMAP, - zoomControl: false, - rotateControl: false, - panControl: false, - mapTypeControl: false, - scrollwheel: false - }; - map = new google.maps.Map(document.getElementById("trip_details_map"), myOptions); - map.fitBounds(bounds); - startPos = new google.maps.Marker({ - position: _.first(path), - map: map, - title: t("Trip started here"), - icon: 'https://uber-static.s3.amazonaws.com/marker_start.png' - }); - endPos = new google.maps.Marker({ - position: _.last(path), - map: map, - title: t("Trip ended here"), - icon: 'https://uber-static.s3.amazonaws.com/marker_end.png' - }); - startPos.setMap(map); - endPos.setMap(map); - polyline = new google.maps.Polyline({ - path: path, - strokeColor: '#003F87', - strokeOpacity: 1, - strokeWeight: 5 - }); - return polyline.setMap(map); - }, this)); - return this.HideSpinner(); - }, this) - }); - this.ShowSpinner('load'); - this.delegateEvents(); - return this; - }; - TripDetailView.prototype.showFareReview = function(e) { - e.preventDefault(); - $('#fare_review_box').slideDown(); - return $('#fare_review').hide(); - }; - TripDetailView.prototype.hideFareReview = function(e) { - e.preventDefault(); - $('#fare_review_box').slideUp(); - return $('#fare_review').show(); - }; - TripDetailView.prototype.submitFareReview = function(e) { - var attrs, errorMessage, id, options; - e.preventDefault(); - errorMessage = $(".error_message"); - errorMessage.hide(); - id = $("#tripid").val(); - this.model = new app.models.trip({ - id: id - }); - attrs = { - note: $('#form_review_message').val(), - note_type: 'client_fare_review' - }; - options = { - success: __bind(function(response) { - $(".success_message").fadeIn(); - return $("#fare_review_form_wrapper").slideUp(); - }, this), - error: __bind(function(error) { - return errorMessage.fadeIn(); - }, this) - }; - return this.model.save(attrs, options); - }; - TripDetailView.prototype.resendReceipt = function(e) { - var $e; - e.preventDefault(); - $e = $(e.currentTarget); - this.$(".resendReceiptSuccess").empty().show(); - this.$(".resentReceiptError").empty().show(); - e.preventDefault(); - $('#spinner').show(); - return $.ajax('/api/trips/func/resend_receipt', { - data: { - token: $.cookie('token'), - trip_id: this.model.id - }, - type: 'POST', - complete: __bind(function(xhr) { - var response; - response = JSON.parse(xhr.responseText); - $('#spinner').hide(); - switch (xhr.status) { - case 200: - this.$(".resendReceiptSuccess").html("Receipt has been emailed"); - return this.$(".resendReceiptSuccess").fadeOut(2000); - default: - this.$(".resendReceiptError").html("Receipt has failed to be emailed"); - return this.$(".resendReceiptError").fadeOut(2000); - } - }, this) - }); - }; - return TripDetailView; - })(); -}).call(this); -}, "views/shared/menu": function(exports, require, module) {(function() { - var menuTemplate; - var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { - for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } - function ctor() { this.constructor = child; } - ctor.prototype = parent.prototype; - child.prototype = new ctor; - child.__super__ = parent.prototype; - return child; - }; - menuTemplate = require('templates/shared/menu'); - exports.SharedMenuView = (function() { - __extends(SharedMenuView, Backbone.View); - function SharedMenuView() { - SharedMenuView.__super__.constructor.apply(this, arguments); - } - SharedMenuView.prototype.id = 'menu_view'; - SharedMenuView.prototype.render = function() { - var type; - if ($.cookie('token') === null) { - type = 'guest'; - } else { - type = 'client'; - } - $(this.el).html(menuTemplate({ - type: type - })); - return this; - }; - return SharedMenuView; - })(); -}).call(this); -}, "web-lib/collections/countries": function(exports, require, module) {(function() { - var UberCollection; - var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { - for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } - function ctor() { this.constructor = child; } - ctor.prototype = parent.prototype; - child.prototype = new ctor; - child.__super__ = parent.prototype; - return child; - }; - UberCollection = require('web-lib/uber_collection').UberCollection; - exports.CountriesCollection = (function() { - __extends(CountriesCollection, UberCollection); - function CountriesCollection() { - CountriesCollection.__super__.constructor.apply(this, arguments); - } - CountriesCollection.prototype.model = app.models.country; - CountriesCollection.prototype.url = '/countries'; - return CountriesCollection; - })(); -}).call(this); -}, "web-lib/collections/vehicle_types": function(exports, require, module) {(function() { - var UberCollection, vehicleType, _ref; - var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { - for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } - function ctor() { this.constructor = child; } - ctor.prototype = parent.prototype; - child.prototype = new ctor; - child.__super__ = parent.prototype; - return child; - }; - UberCollection = require('web-lib/uber_collection').UberCollection; - vehicleType = (typeof app !== "undefined" && app !== null ? (_ref = app.models) != null ? _ref.vehicleType : void 0 : void 0) || require('models/vehicle_type').VehicleType; - exports.VehicleTypesCollection = (function() { - __extends(VehicleTypesCollection, UberCollection); - function VehicleTypesCollection() { - VehicleTypesCollection.__super__.constructor.apply(this, arguments); - } - VehicleTypesCollection.prototype.model = vehicleType; - VehicleTypesCollection.prototype.url = '/vehicle_types'; - VehicleTypesCollection.prototype.defaultColumns = ['id', 'created_at', 'updated_at', 'deleted_at', 'created_by_user_id', 'updated_by_user_id', 'city_id', 'type', 'make', 'model', 'capacity', 'minimum_year', 'actions']; - VehicleTypesCollection.prototype.tableColumns = function(cols) { - var actions, c, capacity, city_id, columnValues, created_at, created_by_user_id, deleted_at, headerRow, id, make, minimum_year, model, type, updated_at, updated_by_user_id, _i, _len; - id = { - sTitle: 'Id' - }; - created_at = { - sTitle: 'Created At (UTC)', - 'sType': 'string' - }; - updated_at = { - sTitle: 'Updated At (UTC)', - 'sType': 'string' - }; - deleted_at = { - sTitle: 'Deleted At (UTC)', - 'sType': 'string' - }; - created_by_user_id = { - sTitle: 'Created By' - }; - updated_by_user_id = { - sTitle: 'Updated By' - }; - city_id = { - sTitle: 'City' - }; - type = { - sTitle: 'Type' - }; - make = { - sTitle: 'Make' - }; - model = { - sTitle: 'Model' - }; - capacity = { - sTitle: 'Capacity' - }; - minimum_year = { - sTitle: 'Min. Year' - }; - actions = { - sTitle: 'Actions' - }; - columnValues = { - id: id, - created_at: created_at, - updated_at: updated_at, - deleted_at: deleted_at, - created_by_user_id: created_by_user_id, - updated_by_user_id: updated_by_user_id, - city_id: city_id, - type: type, - make: make, - model: model, - capacity: capacity, - minimum_year: minimum_year, - actions: actions - }; - headerRow = []; - for (_i = 0, _len = cols.length; _i < _len; _i++) { - c = cols[_i]; - if (columnValues[c]) { - headerRow.push(columnValues[c]); - } - } - return headerRow; - }; - return VehicleTypesCollection; - })(); -}).call(this); -}, "web-lib/helpers": function(exports, require, module) {(function() { - var __indexOf = Array.prototype.indexOf || function(item) { - for (var i = 0, l = this.length; i < l; i++) { - if (this[i] === item) return i; - } - return -1; - }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; - exports.helpers = { - pin: function(num, color) { - if (color == null) { - color = 'FF0000'; - } - return ""; - }, - reverseGeocode: function(latitude, longitude) { - if (latitude && longitude) { - return "" + latitude + ", " + longitude + ""; - } else { - return ''; - } - }, - linkedName: function(model) { - var first_name, id, last_name, role, url; - role = model.role || model.get('role'); - id = model.id || model.get('id'); - first_name = model.first_name || model.get('first_name'); - last_name = model.last_name || model.get('last_name'); - url = "/" + role + "s/" + id; - return "" + first_name + " " + last_name + ""; - }, - linkedVehicle: function(vehicle, vehicleType) { - return " " + (vehicleType != null ? vehicleType.get('make') : void 0) + " " + (vehicleType != null ? vehicleType.get('model') : void 0) + " " + (vehicle.get('year')) + " "; - }, - linkedUserId: function(userType, userId) { - return "" + userType + " " + userId + ""; - }, - timeDelta: function(start, end) { - var delta; - if (typeof start === 'string') { - start = this.parseDate(start); - } - if (typeof end === 'string') { - end = this.parseDate(end); - } - if (end && start) { - delta = end.getTime() - start.getTime(); - return this.formatSeconds(delta / 1000); - } else { - return '00:00'; - } - }, - formatSeconds: function(s) { - var minutes, seconds; - s = Math.floor(s); - minutes = Math.floor(s / 60); - seconds = s - minutes * 60; - return "" + (this.leadingZero(minutes)) + ":" + (this.leadingZero(seconds)); - }, - formatCurrency: function(strValue, reverseSign, currency) { - var currency_locale, lc, mf; - if (reverseSign == null) { - reverseSign = false; - } - if (currency == null) { - currency = null; - } - strValue = String(strValue); - if (reverseSign) { - strValue = ~strValue.indexOf('-') ? strValue.split('-').join('') : ['-', strValue].join(''); - } - currency_locale = i18n.currencyToLocale[currency]; - try { - if (!(currency_locale != null) || currency_locale === i18n.locale) { - return i18n.jsworld.mf.format(strValue); - } else { - lc = new jsworld.Locale(POSIX_LC[currency_locale]); - mf = new jsworld.MonetaryFormatter(lc); - return mf.format(strValue); - } - } catch (error) { - i18n.log(error); - return strValue; - } - }, - formatTripFare: function(trip, type) { - var _ref, _ref2; - if (type == null) { - type = "fare"; - } - if (!trip.get('fare')) { - return 'n/a'; - } - if (((_ref = trip.get('fare_breakdown_local')) != null ? _ref.currency : void 0) != null) { - return app.helpers.formatCurrency(trip.get("" + type + "_local"), false, (_ref2 = trip.get('fare_breakdown_local')) != null ? _ref2.currency : void 0); - } else if (trip.get("" + type + "_string") != null) { - return trip.get("" + type + "_string"); - } else if (trip.get("" + type + "_local") != null) { - return trip.get("" + type + "_local"); - } else { - return 'n/a'; - } - }, - formatPhoneNumber: function(phoneNumber, countryCode) { - if (countryCode == null) { - countryCode = "+1"; - } - if (phoneNumber != null) { - phoneNumber = String(phoneNumber); - switch (countryCode) { - case '+1': - return countryCode + ' ' + phoneNumber.substring(0, 3) + '-' + phoneNumber.substring(3, 6) + '-' + phoneNumber.substring(6, 10); - case '+33': - return countryCode + ' ' + phoneNumber.substring(0, 1) + ' ' + phoneNumber.substring(1, 3) + ' ' + phoneNumber.substring(3, 5) + ' ' + phoneNumber.substring(5, 7) + ' ' + phoneNumber.substring(7, 9); - default: - countryCode + phoneNumber; - } - } - return "" + countryCode + " " + phoneNumber; - }, - parseDate: function(d, cityTime, tz) { - var city_filter, parsed, _ref; - if (cityTime == null) { - cityTime = true; - } - if (tz == null) { - tz = null; - } - if (((_ref = !d.substr(-6, 1)) === '+' || _ref === '-') || d.length === 19) { - d += '+00:00'; - } - if (/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})/.test(d)) { - parsed = d.match(/(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})/); - d = new Date(); - d.setUTCFullYear(parsed[1]); - d.setUTCMonth(parsed[2] - 1); - d.setUTCDate(parsed[3]); - d.setUTCHours(parsed[4]); - d.setUTCMinutes(parsed[5]); - d.setUTCSeconds(parsed[6]); - } else { - d = Date.parse(d); - } - if (typeof d === 'number') { - d = new Date(d); - } - d = new timezoneJS.Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds(), 'Etc/UTC'); - if (tz) { - d.convertToTimezone(tz); - } else if (cityTime) { - city_filter = $.cookie('city_filter'); - if (city_filter) { - tz = $("#city_filter option[value=" + city_filter + "]").attr('data-timezone'); - if (tz) { - d.convertToTimezone(tz); - } - } - } - return d; - }, - dateToTimezone: function(d) { - var city_filter, tz; - d = new timezoneJS.Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds(), 'Etc/UTC'); - city_filter = $.cookie('city_filter'); - if (city_filter) { - tz = $("#city_filter option[value=" + city_filter + "]").attr('data-timezone'); - d.convertToTimezone(tz); - } - return d; - }, - fixAMPM: function(d, formatted) { - if (d.hours >= 12) { - return formatted.replace(/\b[AP]M\b/, 'PM'); - } else { - return formatted.replace(/\b[AP]M\b/, 'AM'); - } - }, - formatDate: function(d, time, timezone) { - var formatted; - if (time == null) { - time = true; - } - if (timezone == null) { - timezone = null; - } - d = this.parseDate(d, true, timezone); - formatted = time ? ("" + (i18n.jsworld.dtf.formatDate(d)) + " ") + this.formatTime(d, d.getTimezoneInfo()) : i18n.jsworld.dtf.formatDate(d); - return this.fixAMPM(d, formatted); - }, - formatDateLong: function(d, time, timezone) { - if (time == null) { - time = true; - } - if (timezone == null) { - timezone = null; - } - d = this.parseDate(d, true, timezone); - timezone = d.getTimezoneInfo().tzAbbr; - if (time) { - return (i18n.jsworld.dtf.formatDateTime(d)) + (" " + timezone); - } else { - return i18n.jsworld.dtf.formatDate(d); - } - }, - formatTimezoneJSDate: function(d) { - var day, hours, jsDate, minutes, month, year; - year = d.getFullYear(); - month = this.leadingZero(d.getMonth()); - day = this.leadingZero(d.getDate()); - hours = this.leadingZero(d.getHours()); - minutes = this.leadingZero(d.getMinutes()); - jsDate = new Date(year, month, day, hours, minutes, 0); - return jsDate.toDateString(); - }, - formatTime: function(d, timezone) { - var formatted; - if (timezone == null) { - timezone = null; - } - formatted = ("" + (i18n.jsworld.dtf.formatTime(d))) + (timezone != null ? " " + (timezone != null ? timezone.tzAbbr : void 0) : ""); - return this.fixAMPM(d, formatted); - }, - formatISODate: function(d) { - var pad; - pad = function(n) { - if (n < 10) { - return '0' + n; - } - return n; - }; - return d.getUTCFullYear() + '-' + pad(d.getUTCMonth() + 1) + '-' + pad(d.getUTCDate()) + 'T' + pad(d.getUTCHours()) + ':' + pad(d.getUTCMinutes()) + ':' + pad(d.getUTCSeconds()) + 'Z'; - }, - formatExpDate: function(d) { - var month, year; - d = this.parseDate(d); - year = d.getFullYear(); - month = this.leadingZero(d.getMonth() + 1); - return "" + year + "-" + month; - }, - formatLatLng: function(lat, lng, precision) { - if (precision == null) { - precision = 8; - } - return parseFloat(lat).toFixed(precision) + ',' + parseFloat(lng).toFixed(precision); - }, - leadingZero: function(num) { - if (num < 10) { - return "0" + num; - } else { - return num; - } - }, - roundNumber: function(num, dec) { - return Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec); - }, - notesToHTML: function(notes) { - var i, note, notesHTML, _i, _len; - notesHTML = ''; - i = 1; - if (notes) { - for (_i = 0, _len = notes.length; _i < _len; _i++) { - note = notes[_i]; - notesHTML += "" + note['userid'] + "     " + (this.formatDate(note['created_at'])) + "

" + note['note'] + "

"; - notesHTML += "
"; - } - } - return notesHTML.replace("'", '"e'); - }, - formatPhone: function(n) { - var parts, phone, regexObj; - n = "" + n; - regexObj = /^(?:\+?1[-. ]?)?(?:\(?([0-9]{3})\)?[-. ]?)?([0-9]{3})[-. ]?([0-9]{4})$/; - if (regexObj.test(n)) { - parts = n.match(regexObj); - phone = ""; - if (parts[1]) { - phone += "(" + parts[1] + ") "; - } - phone += "" + parts[2] + "-" + parts[3]; - } else { - phone = n; - } - return phone; - }, - usStates: ['Alabama', 'Alaska', 'Arizona', 'Arkansas', 'California', 'Colorado', 'Connecticut', 'Delaware', 'District of Columbia', 'Florida', 'Georgia', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', 'New Mexico', 'New York', 'North Carolina', 'North Dakota', 'Ohio', 'Oklahoma', 'Oregon', 'Pennsylvania', 'Rhode Island', 'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virginia', 'Washington', 'West Virginia', 'Wisconsin', 'Wyoming'], - onboardingPages: ['applied', 'ready_to_interview', 'pending_interview', 'interviewed', 'accepted', 'ready_to_onboard', 'pending_onboarding', 'active', 'waitlisted', 'rejected'], - driverBreadCrumb: function(loc, model) { - var onboardingPage, out, _i, _len, _ref; - out = "Drivers > "; - if (!(model != null)) { - out += ""; - } else { - out += "" + (this.onboardingUrlToName(model.get('driver_status'))) + ""; - out += " > " + (this.linkedName(model)) + " (" + (model.get('role')) + ") #" + (model.get('id')); - } - return out; - }, - onboardingUrlToName: function(url) { - return url != null ? url.replace(/_/g, " ").replace(/(^|\s)([a-z])/g, function(m, p1, p2) { - return p1 + p2.toUpperCase(); - }) : void 0; - }, - formatVehicle: function(vehicle) { - if (vehicle.get('make') && vehicle.get('model') && vehicle.get('license_plate')) { - return "" + (vehicle.get('make')) + " " + (vehicle.get('model')) + " (" + (vehicle.get('license_plate')) + ")"; - } - }, - docArbitraryFields: function(docName, cityDocs) { - var doc, field, out, _i, _j, _len, _len2, _ref; - out = ""; - for (_i = 0, _len = cityDocs.length; _i < _len; _i++) { - doc = cityDocs[_i]; - if (doc.name === docName && __indexOf.call(_.keys(doc), "metaFields") >= 0) { - _ref = doc.metaFields; - for (_j = 0, _len2 = _ref.length; _j < _len2; _j++) { - field = _ref[_j]; - out += "" + field.label + ":
"; - } - } - } - return out; - }, - capitaliseFirstLetter: function(string) { - return string.charAt(0).toUpperCase() + string.slice(1); - }, - createDocUploadForm: function(docName, driverId, vehicleId, cityMeta, vehicleName, expirationRequired) { - var ddocs, expDropdowns, pdocs, vdocs; - if (driverId == null) { - driverId = "None"; - } - if (vehicleId == null) { - vehicleId = "None"; - } - if (cityMeta == null) { - cityMeta = []; - } - if (vehicleName == null) { - vehicleName = false; - } - if (expirationRequired == null) { - expirationRequired = false; - } - ddocs = cityMeta["driverRequiredDocs"] || []; - pdocs = cityMeta["partnerRequiredDocs"] || []; - vdocs = cityMeta["vehicleRequiredDocs"] || []; - expDropdowns = "Expiration Date:\n -\n"; - return " \n
\n \n \n \n\n
\n " + (vehicleName ? vehicleName : "") + " " + docName + "\n
\n\n
\n \n
\n\n
\n " + (expirationRequired ? expDropdowns : "") + "\n
\n\n
\n " + (app.helpers.docArbitraryFields(docName, _.union(ddocs, pdocs, vdocs))) + "\n
\n\n
\n \n
\n\n
\n"; - }, - countrySelector: function(name, options) { - var countries, countryCodePrefix, defaultOptions; - if (options == null) { - options = {}; - } - defaultOptions = { - selectedKey: 'telephone_code', - selectedValue: '+1', - silent: false - }; - _.extend(defaultOptions, options); - options = defaultOptions; - countries = new app.collections.countries(); - countries.fetch({ - data: { - limit: 300 - }, - success: function(countries) { - var $option, $select, country, selected, _i, _len, _ref; - selected = false; - _ref = countries.models || []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - country = _ref[_i]; - $select = $("select[name=" + name + "]"); - $option = $('').val(country.id).attr('data-iso2', country.get('iso2')).attr('data-prefix', country.get('telephone_code')).html(country.get('name')); - if (country.get(options.selectedKey) === options.selectedValue && !selected) { - selected = true; - $option.attr('selected', 'selected'); - } - $select.append($option); - } - if (selected && !options.silent) { - return $select.val(options.selected).trigger('change'); - } - } - }); - countryCodePrefix = options.countryCodePrefix ? "data-country-code-prefix='" + options.countryCodePrefix + "'" : ''; - return ""; - }, - missingDocsOnDriver: function(driver) { - var city, docsReq, documents, partnerDocs; - city = driver.get('city'); - documents = driver.get('documents'); - if ((city != null) && (documents != null)) { - docsReq = _.pluck(city != null ? city.get('meta')["driverRequiredDocs"] : void 0, "name"); - if (driver.get('role') === "partner") { - partnerDocs = _.pluck(city != null ? city.get('meta')["partnerRequiredDocs"] : void 0, "name"); - docsReq = _.union(docsReq, partnerDocs); - } - return _.reject(docsReq, __bind(function(doc) { - return __indexOf.call((documents != null ? documents.pluck("name") : void 0) || [], doc) >= 0; - }, this)); - } else { - return []; - } - } - }; -}).call(this); -}, "web-lib/i18n": function(exports, require, module) {(function() { - exports.i18n = { - defaultLocale: 'en_US', - cookieName: '_LOCALE_', - locales: { - 'en_US': "English (US)", - 'fr_FR': "Français" - }, - currencyToLocale: { - 'USD': 'en_US', - 'EUR': 'fr_FR' - }, - logglyKey: 'd2d5a9bc-7ebe-4538-a180-81e62c705b1b', - logglyHost: 'https://logs.loggly.com', - init: function() { - this.castor = new window.loggly({ - url: this.logglyHost + '/inputs/' + this.logglyKey + '?rt=1', - level: 'error' - }); - this.setLocale($.cookie(this.cookieName) || this.defaultLocale); - window.t = _.bind(this.t, this); - this.loadLocaleTranslations(this.locale); - if (!(this[this.defaultLocale] != null)) { - return this.loadLocaleTranslations(this.defaultLocale); - } - }, - loadLocaleTranslations: function(locale) { - var loadPaths, path, _i, _len, _results; - loadPaths = ['web-lib/translations/' + locale, 'web-lib/translations/' + locale.slice(0, 2), 'translations/' + locale, 'translations/' + locale.slice(0, 2)]; - _results = []; - for (_i = 0, _len = loadPaths.length; _i < _len; _i++) { - path = loadPaths[_i]; - locale = path.substring(path.lastIndexOf('/') + 1); - if (this[locale] == null) { - this[locale] = {}; - } - _results.push((function() { - try { - return _.extend(this[locale], require(path).translations); - } catch (error) { - - } - }).call(this)); - } - return _results; - }, - getLocale: function() { - return this.locale; - }, - setLocale: function(locale) { - var message, parts, _ref; - parts = locale.split('_'); - this.locale = parts[0].toLowerCase(); - if (parts.length > 1) { - this.locale += "_" + (parts[1].toUpperCase()); - } - if (this.locale) { - $.cookie(this.cookieName, this.locale, { - path: '/', - domain: '.uber.com' - }); - } - try { - ((_ref = this.jsworld) != null ? _ref : this.jsworld = {}).lc = new jsworld.Locale(POSIX_LC[this.locale]); - this.jsworld.mf = new jsworld.MonetaryFormatter(this.jsworld.lc); - this.jsworld.nf = new jsworld.NumericFormatter(this.jsworld.lc); - this.jsworld.dtf = new jsworld.DateTimeFormatter(this.jsworld.lc); - this.jsworld.np = new jsworld.NumericParser(this.jsworld.lc); - this.jsworld.mp = new jsworld.MonetaryParser(this.jsworld.lc); - return this.jsworld.dtp = new jsworld.DateTimeParser(this.jsworld.lc); - } catch (error) { - message = 'JsWorld error with locale: ' + this.locale; - return this.log({ - message: message, - error: error - }); - } - }, - getTemplate: function(id) { - var _ref, _ref2; - return ((_ref = this[this.locale]) != null ? _ref[id] : void 0) || ((_ref2 = this[this.locale.slice(0, 2)]) != null ? _ref2[id] : void 0); - }, - getTemplateDefault: function(id) { - var _ref, _ref2; - return ((_ref = this[this.defaultLocale]) != null ? _ref[id] : void 0) || ((_ref2 = this[this.defaultLocale.slice(0, 2)]) != null ? _ref2[id] : void 0); - }, - getTemplateOrDefault: function(id) { - return this.getTemplate(id) || this.getTemplateDefault(id); - }, - t: function(id, vars) { - var errStr, locale, template; - if (vars == null) { - vars = {}; - } - locale = this.getLocale(); - template = this.getTemplate(id); - if (template == null) { - if (/dev|test/.test(window.location.host)) { - template = "(?) " + id; - } else { - template = this.getTemplateDefault(id); - } - errStr = "Missing [" + locale + "] translation for [" + id + "] at [" + window.location.hash + "] - Default template is [" + template + "]"; - this.log({ - error: errStr, - locale: locale, - id: id, - defaultTemplate: template - }); - } - if (template) { - return _.template(template, vars); - } else { - return id; - } - }, - log: function(error) { - if (/dev/.test(window.location.host)) { - if ((typeof console !== "undefined" && console !== null ? console.log : void 0) != null) { - return console.log(error); - } - } else { - _.extend(error, { - host: window.location.host, - hash: window.location.hash - }); - return this.castor.error(JSON.stringify(error)); - } - } - }; -}).call(this); -}, "web-lib/mixins/i18n_phone_form": function(exports, require, module) {(function() { - exports.i18nPhoneForm = { - _events: { - 'change select[data-country-code-prefix]': 'setCountryCodePrefix' - }, - setCountryCodePrefix: function(e) { - var $el, prefix; - $el = $(e.currentTarget); - prefix = $el.find('option:selected').attr('data-prefix'); - return $("#" + ($el.attr('data-country-code-prefix'))).text(prefix); - } - }; -}).call(this); -}, "web-lib/models/country": function(exports, require, module) {(function() { - var UberModel; - var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { - for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } - function ctor() { this.constructor = child; } - ctor.prototype = parent.prototype; - child.prototype = new ctor; - child.__super__ = parent.prototype; - return child; - }; - UberModel = require('web-lib/uber_model').UberModel; - exports.Country = (function() { - __extends(Country, UberModel); - function Country() { - Country.__super__.constructor.apply(this, arguments); - } - Country.prototype.url = function() { - if (this.id) { - return "/countries/" + this.id; - } else { - return '/countries'; - } - }; - return Country; - })(); -}).call(this); -}, "web-lib/models/vehicle_type": function(exports, require, module) {(function() { - var UberModel; - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { - for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } - function ctor() { this.constructor = child; } - ctor.prototype = parent.prototype; - child.prototype = new ctor; - child.__super__ = parent.prototype; - return child; - }; - UberModel = require('web-lib/uber_model').UberModel; - exports.VehicleType = (function() { - __extends(VehicleType, UberModel); - function VehicleType() { - this.toString = __bind(this.toString, this); - VehicleType.__super__.constructor.apply(this, arguments); - } - VehicleType.prototype.endpoint = 'vehicle_types'; - VehicleType.prototype.toTableRow = function(cols) { - var actions, c, capacity, city_id, columnValues, created_at, created_by_user_id, deleted_at, id, make, minimum_year, model, rows, type, updated_at, updated_by_user_id, _i, _len, _ref; - id = "" + (this.get('id')) + ""; - if (this.get('created_at')) { - created_at = app.helpers.formatDate(this.get('created_at')); - } - if (this.get('updated_at')) { - updated_at = app.helpers.formatDate(this.get('updated_at')); - } - if (this.get('deleted_at')) { - deleted_at = app.helpers.formatDate(this.get('deleted_at')); - } - created_by_user_id = "" + (this.get('created_by_user_id')) + ""; - updated_by_user_id = "" + (this.get('updated_by_user_id')) + ""; - city_id = (_ref = this.get('city')) != null ? _ref.get('display_name') : void 0; - type = this.get('type'); - make = this.get('make'); - model = this.get('model'); - capacity = this.get('capacity'); - minimum_year = this.get('minimum_year'); - actions = "Show"; - if (!this.get('deleted_at')) { - actions += " Edit"; - actions += " Delete"; - } - columnValues = { - id: id, - created_at: created_at, - updated_at: updated_at, - deleted_at: deleted_at, - created_by_user_id: created_by_user_id, - updated_by_user_id: updated_by_user_id, - city_id: city_id, - type: type, - make: make, - model: model, - capacity: capacity, - minimum_year: minimum_year, - actions: actions - }; - rows = []; - for (_i = 0, _len = cols.length; _i < _len; _i++) { - c = cols[_i]; - rows.push(columnValues[c] ? columnValues[c] : '-'); - } - return rows; - }; - VehicleType.prototype.toString = function() { - return this.get('make') + ' ' + this.get('model') + ' ' + this.get('type') + (" (" + (this.get('capacity')) + ")"); - }; - return VehicleType; - })(); -}).call(this); -}, "web-lib/templates/footer": function(exports, require, module) {module.exports = function(__obj) { - if (!__obj) __obj = {}; - var __out = [], __capture = function(callback) { - var out = __out, result; - __out = []; - callback.call(this); - result = __out.join(''); - __out = out; - return __safe(result); - }, __sanitize = function(value) { - if (value && value.ecoSafe) { - return value; - } else if (typeof value !== 'undefined' && value != null) { - return __escape(value); - } else { - return ''; - } - }, __safe, __objSafe = __obj.safe, __escape = __obj.escape; - __safe = __obj.safe = function(value) { - if (value && value.ecoSafe) { - return value; - } else { - if (!(typeof value !== 'undefined' && value != null)) value = ''; - var result = new String(value); - result.ecoSafe = true; - return result; - } - }; - if (!__escape) { - __escape = __obj.escape = function(value) { - return ('' + value) - .replace(/&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"'); - }; - } - (function() { - (function() { - var locale, title, _ref; - __out.push('\n\n\n\n\n'); - }).call(this); - - }).call(__obj); - __obj.safe = __objSafe, __obj.escape = __escape; - return __out.join(''); -}}, "web-lib/translations/en": function(exports, require, module) {(function() { - exports.translations = { - "Info": "Info", - "Learn More": "Learn More", - "Pricing": "Pricing", - "FAQ": "FAQ", - "Support": "Support", - "Support & FAQ": "Support & FAQ", - "Contact Us": "Contact Us", - "Jobs": "Jobs", - "Phones": "Phones", - "Text Message": "Text Message", - "iPhone": "iPhone", - "Android": "Android", - "Drivers": "Drivers", - "Apply": "Apply", - "Sign In": "Sign In", - "Social": "Social", - "Twitter": "Twitter", - "Facebook": "Facebook", - "Blog": "Blog", - "Legal": "Legal", - "Company_Footer": "Company", - "Privacy Policy": "Privacy Policy", - "Terms": "Terms", - "Copyright © Uber Technologies, Inc.": "Copyright © Uber Technologies, Inc.", - "Language:": "Language:", - "Apply to Drive": "Apply to Drive", - "Expiration": "Expiration", - "Fare": "Fare", - "Driver": "Driver ", - "Dashboard": "Dashboard", - "Forgot Password": "Forgot Password", - "Trip Details": "Trip Details", - "Save": "Save", - "Cancel": "Cancel", - "Edit": "Edit", - "Password": "Password", - "First Name": "First Name", - "Last Name": "Last Name", - "Email Address": "Email Address", - "Submit": "Submit", - "Mobile Number": "Mobile Number", - "Zip Code": "Zip Code", - "Sign Out": "Sign Out", - "Confirm Email Message": "Attempting to confirm email...", - "Upload": "Upload", - "Rating": "Rating", - "Pickup Time": "Pickup Time", - "2011": "2011", - "2012": "2012", - "2013": "2013", - "2014": "2014", - "2015": "2015", - "2016": "2016", - "2017": "2017", - "2018": "2018", - "2019": "2019", - "2020": "2020", - "2021": "2021", - "2022": "2022", - "01": "01", - "02": "02", - "03": "03", - "04": "04", - "05": "05", - "06": "06", - "07": "07", - "08": "08", - "09": "09", - "10": "10", - "11": "11", - "12": "12" - }; -}).call(this); -}, "web-lib/translations/fr": function(exports, require, module) {(function() { - exports.translations = { - "Info": "Info", - "Learn More": "En Savoir Plus", - "Pricing": "Calcul du Prix", - "Support & FAQ": "Aide & FAQ", - "Contact Us": "Contactez Nous", - "Jobs": "Emplois", - "Phones": "Téléphones", - "Text Message": "SMS", - "iPhone": "iPhone", - "Android": "Android", - "Apply to Drive": "Candidature Chauffeur", - "Sign In": "Connexion", - "Social": "Contact", - "Twitter": "Twitter", - "Facebook": "Facebook", - "Blog": "Blog", - "Privacy Policy": "Protection des Données Personelles", - "Terms": "Conditions Générales", - "Copyright © Uber Technologies, Inc.": "© Uber, Inc.", - "Language:": "Langue:", - "Forgot Password": "Mot de passe oublié", - "Company_Footer": "À Propos d'Uber", - "Expiration": "Expiration", - "Fare": "Tarif", - "Driver": "Chauffeur", - "Drivers": "Chauffeurs", - "Dashboard": "Tableau de bord", - "Forgot Password": "Mot de passe oublié", - "Forgot Password?": "Mot de passe oublié?", - "Trip Details": "Détails de la course", - "Save": "Enregistrer", - "Cancel": "Annuler", - "Edit": "Modifier", - "Password": "Mot de passe", - "First Name": "Prénom", - "Last Name": "Nom", - "Email Address": "E-mail", - "Submit": "Soumettre", - "Mobile Number": "Téléphone Portable", - "Zip Code": "Code Postal", - "Sign Out": "Se déconnecter", - "Confirm Email Message": "E-mail de confirmation", - "Upload": "Télécharger", - "Rating": "Notation", - "Pickup Time": "Heure de prise en charge", - "2011": "2011", - "2012": "2012", - "2013": "2013", - "2014": "2014", - "2015": "2015", - "2016": "2016", - "2017": "2017", - "2018": "2018", - "2019": "2019", - "2020": "2020", - "2021": "2021", - "2022": "2022", - "01": "01", - "02": "02", - "03": "03", - "04": "04", - "05": "05", - "06": "06", - "07": "07", - "08": "08", - "09": "09", - "10": "10", - "11": "11", - "12": "12" - }; -}).call(this); -}, "web-lib/uber_collection": function(exports, require, module) {(function() { - var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { - for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } - function ctor() { this.constructor = child; } - ctor.prototype = parent.prototype; - child.prototype = new ctor; - child.__super__ = parent.prototype; - return child; - }; - exports.UberCollection = (function() { - __extends(UberCollection, Backbone.Collection); - function UberCollection() { - UberCollection.__super__.constructor.apply(this, arguments); - } - UberCollection.prototype.parse = function(data) { - var model, tmp, _i, _in, _len, _out; - _in = data.resources || data; - _out = []; - if (data.meta) { - this.meta = data.meta; - } - for (_i = 0, _len = _in.length; _i < _len; _i++) { - model = _in[_i]; - tmp = new this.model; - tmp.set(tmp.parse(model)); - _out.push(tmp); - } - return _out; - }; - UberCollection.prototype.isRenderable = function() { - if (this.models.length) { - return true; - } - }; - UberCollection.prototype.toTableRows = function(cols) { - var tableRows; - tableRows = []; - _.each(this.models, function(model) { - return tableRows.push(model.toTableRow(cols)); - }); - return tableRows; - }; - return UberCollection; - })(); -}).call(this); -}, "web-lib/uber_model": function(exports, require, module) {(function() { - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { - for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } - function ctor() { this.constructor = child; } - ctor.prototype = parent.prototype; - child.prototype = new ctor; - child.__super__ = parent.prototype; - return child; - }, __indexOf = Array.prototype.indexOf || function(item) { - for (var i = 0, l = this.length; i < l; i++) { - if (this[i] === item) return i; - } - return -1; - }; - exports.UberModel = (function() { - __extends(UberModel, Backbone.Model); - function UberModel() { - this.refetch = __bind(this.refetch, this); - this.fetch = __bind(this.fetch, this); - this.save = __bind(this.save, this); - this.parse = __bind(this.parse, this); - UberModel.__super__.constructor.apply(this, arguments); - } - UberModel.prototype.endpoint = 'set_api_endpoint_in_subclass'; - UberModel.prototype.refetchOptions = {}; - UberModel.prototype.url = function(type) { - var endpoint_path; - endpoint_path = "/" + this.endpoint; - if (this.get('id')) { - return endpoint_path + ("/" + (this.get('id'))); - } else { - return endpoint_path; - } - }; - UberModel.prototype.isRenderable = function() { - var i, key, value, _ref; - i = 0; - _ref = this.attributes; - for (key in _ref) { - if (!__hasProp.call(_ref, key)) continue; - value = _ref[key]; - if (this.attributes.hasOwnProperty(key)) { - i += 1; - } - if (i > 1) { - return true; - } - } - return !(i === 1); - }; - UberModel.prototype.parse = function(response) { - var attrs, key, model, models, _i, _j, _k, _len, _len2, _len3, _ref, _ref2; - if (typeof response === 'object') { - _ref = _.intersection(_.keys(app.models), _.keys(response)); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - key = _ref[_i]; - if (response[key]) { - attrs = this.parse(response[key]); - if (typeof attrs === 'object') { - response[key] = new app.models[key](attrs); - } - } - } - _ref2 = _.intersection(_.keys(app.collections), _.keys(response)); - for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { - key = _ref2[_j]; - models = response[key]; - if (_.isArray(models)) { - response[key] = new app.collections[key]; - for (_k = 0, _len3 = models.length; _k < _len3; _k++) { - model = models[_k]; - attrs = app.collections[key].prototype.model.prototype.parse(model); - response[key].add(new response[key].model(attrs)); - } - } - } - } - return response; - }; - UberModel.prototype.save = function(attributes, options) { - var attr, _i, _j, _len, _len2, _ref, _ref2; - if (options == null) { - options = {}; - } - _ref = _.intersection(_.keys(app.models), _.keys(this.attributes)); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - attr = _ref[_i]; - if (typeof this.get(attr) === "object") { - this.unset(attr, { - silent: true - }); - } - } - _ref2 = _.intersection(_.keys(app.collections), _.keys(this.attributes)); - for (_j = 0, _len2 = _ref2.length; _j < _len2; _j++) { - attr = _ref2[_j]; - if (typeof this.get(attr) === "object") { - this.unset(attr, { - silent: true - }); - } - } - if ((options != null) && options.diff && (attributes != null) && attributes !== {}) { - attributes['id'] = this.get('id'); - attributes['token'] = this.get('token'); - this.clear({ - 'silent': true - }); - this.set(attributes, { - silent: true - }); - } - if (__indexOf.call(_.keys(options), "data") < 0 && __indexOf.call(_.keys(this.refetchOptions || {}), "data") >= 0) { - options.data = this.refetchOptions.data; - } - return Backbone.Model.prototype.save.call(this, attributes, options); - }; - UberModel.prototype.fetch = function(options) { - this.refetchOptions = options; - return Backbone.Model.prototype.fetch.call(this, options); - }; - UberModel.prototype.refetch = function() { - return this.fetch(this.refetchOptions); - }; - return UberModel; - })(); -}).call(this); -}, "web-lib/uber_router": function(exports, require, module) {(function() { - var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { - for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } - function ctor() { this.constructor = child; } - ctor.prototype = parent.prototype; - child.prototype = new ctor; - child.__super__ = parent.prototype; - return child; - }; - exports.UberRouter = (function() { - __extends(UberRouter, Backbone.Router); - function UberRouter() { - UberRouter.__super__.constructor.apply(this, arguments); - } - UberRouter.prototype.datePickers = function(format) { - if (format == null) { - format = "%Z-%m-%dT%H:%i:%s%:"; - } - $('.datepicker').AnyTime_noPicker(); - return $('.datepicker').AnyTime_picker({ - 'format': format, - 'formatUtcOffset': '%@' - }); - }; - UberRouter.prototype.autoGrowInput = function() { - return $('.editable input').autoGrowInput(); - }; - UberRouter.prototype.windowTitle = function(title) { - return $(document).attr('title', title); - }; - return UberRouter; - })(); -}).call(this); -}, "web-lib/uber_show_view": function(exports, require, module) {(function() { - var UberView; - var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { - for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } - function ctor() { this.constructor = child; } - ctor.prototype = parent.prototype; - child.prototype = new ctor; - child.__super__ = parent.prototype; - return child; - }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; - UberView = require('web-lib/uber_view').UberView; - exports.UberShowView = (function() { - __extends(UberShowView, UberView); - function UberShowView() { - UberShowView.__super__.constructor.apply(this, arguments); - } - UberShowView.prototype.view = 'show'; - UberShowView.prototype.events = { - 'click #edit': 'edit', - 'submit form': 'save', - 'click .cancel': 'cancel' - }; - UberShowView.prototype.errors = null; - UberShowView.prototype.showTemplate = null; - UberShowView.prototype.editTemplate = null; - UberShowView.prototype.initialize = function() { - if (this.init_hook) { - this.init_hook(); - } - _.bindAll(this, 'render'); - return this.model.bind('change', this.render); - }; - UberShowView.prototype.render = function() { - var $el; - $el = $(this.el); - this.selectView(); - if (this.view === 'show') { - $el.html(this.showTemplate({ - model: this.model - })); - } else if (this.view === 'edit') { - $el.html(this.editTemplate({ - model: this.model, - errors: this.errors || {}, - collections: this.collections || {} - })); - } else { - $el.html(this.newTemplate({ - model: this.model, - errors: this.errors || {}, - collections: this.collections || {} - })); - } - if (this.render_hook) { - this.render_hook(); - } - this.errors = null; - this.userIdsToLinkedNames(); - this.datePickers(); - return this.place(); - }; - UberShowView.prototype.selectView = function() { - var url; - if (this.options.urlRendering) { - url = window.location.hash; - if (url.match(/\/new/)) { - return this.view = 'new'; - } else if (url.match(/\/edit/)) { - return this.view = 'edit'; - } else { - return this.view = 'show'; - } - } - }; - UberShowView.prototype.edit = function(e) { - e.preventDefault(); - if (this.options.urlRendering) { - window.location.hash = '#/' + this.model.endpoint + '/' + this.model.get('id') + '/edit'; - } else { - this.view = 'edit'; - } - return this.model.change(); - }; - UberShowView.prototype.save = function(e) { - var attributes, ele, form_attrs, _i, _len, _ref; - e.preventDefault(); - attributes = $(e.currentTarget).serializeToJson(); - form_attrs = {}; - _ref = $('input[type="radio"]'); - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - ele = _ref[_i]; - if ($(ele).is(':checked')) { - form_attrs[$(ele).attr('name')] = $(ele).attr('value'); - } - } - attributes = _.extend(attributes, form_attrs); - if (this.relationships) { - attributes = _.extend(attributes, { - relationships: this.relationships - }); - } - if (this.filter_attributes != null) { - this.filter_attributes(attributes); - } - return this.model.save(attributes, { - silent: true, - success: __bind(function(model) { - if (this.options.urlRendering) { - window.location.hash = '#/' + this.model.endpoint + '/' + this.model.get('id'); - } else { - this.view = 'show'; - } - return this.flash('success', "Uber save!"); - }, this), - statusCode: { - 406: __bind(function(xhr) { - this.errors = JSON.parse(xhr.responseText); - return this.flash('error', 'That was not Uber.'); - }, this) - }, - error: __bind(function(model, xhr) { - var code, message, responseJSON, responseText; - code = xhr.status; - responseText = xhr.responseText; - if (responseText) { - responseJSON = JSON.parse(responseText); - } - if (responseJSON && (typeof responseJSON === 'object') && (responseJSON.hasOwnProperty('error'))) { - message = responseJSON.error; - } - return this.flash('error', (code || 'Unknown') + ' error' + (': ' + message || '')); - }, this), - complete: __bind(function() { - return this.model.change(); - }, this) - }); - }; - UberShowView.prototype.cancel = function(e) { - e.preventDefault(); - if (this.options.urlRendering) { - window.location.hash = '#/' + this.model.endpoint + '/' + this.model.get('id'); - } else { - this.view = 'show'; - } - return this.model.fetch({ - silent: true, - complete: __bind(function() { - return this.model.change(); - }, this) - }); - }; - return UberShowView; - })(); -}).call(this); -}, "web-lib/uber_sync": function(exports, require, module) {(function() { - var methodType; - var __indexOf = Array.prototype.indexOf || function(item) { - for (var i = 0, l = this.length; i < l; i++) { - if (this[i] === item) return i; - } - return -1; - }; - methodType = { - create: 'POST', - update: 'PUT', - "delete": 'DELETE', - read: 'GET' - }; - exports.UberSync = function(method, model, options) { - var token; - options.type = methodType[method]; - options.url = _.isString(this.url) ? '/api' + this.url : '/api' + this.url(options.type); - options.data = _.extend({}, options.data); - if (__indexOf.call(_.keys(options.data), "city_id") < 0) { - if ($.cookie('city_filter')) { - _.extend(options.data, { - city_id: $.cookie('city_filter') - }); - } - } else { - delete options.data['city_id']; - } - if (options.type === 'POST' || options.type === 'PUT') { - _.extend(options.data, model.toJSON()); - } - token = $.cookie('token') ? $.cookie('token') : typeof USER !== "undefined" && USER !== null ? USER.get('token') : ""; - _.extend(options.data, { - token: token - }); - if (method === "delete") { - options.contentType = 'application/json'; - options.data = JSON.stringify(options.data); - } - return $.ajax(options); - }; -}).call(this); -}, "web-lib/uber_view": function(exports, require, module) {(function() { - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { - for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } - function ctor() { this.constructor = child; } - ctor.prototype = parent.prototype; - child.prototype = new ctor; - child.__super__ = parent.prototype; - return child; - }; - exports.UberView = (function() { - __extends(UberView, Backbone.View); - function UberView() { - this.processDocumentUpload = __bind(this.processDocumentUpload, this); - UberView.__super__.constructor.apply(this, arguments); - } - UberView.prototype.className = 'view_container'; - UberView.prototype.hashId = function() { - return parseInt(location.hash.split('/')[2]); - }; - UberView.prototype.place = function(content) { - var $target; - $target = this.options.scope ? this.options.scope.find(this.options.selector) : $(this.options.selector); - $target[this.options.method || 'html'](content || this.el); - this.delegateEvents(); - $('#spinner').hide(); - return this; - }; - UberView.prototype.mixin = function(m, args) { - var events, self; - if (args == null) { - args = {}; - } - self = this; - events = m._events; - _.extend(this, m); - if (m.initialize) { - m.initialize(self, args); - } - return _.each(_.keys(events), function(key) { - var event, func, selector, split; - split = key.split(' '); - event = split[0]; - selector = split[1]; - func = events[key]; - return $(self.el).find(selector).live(event, function(e) { - return self[func](e); - }); - }); - }; - UberView.prototype.datePickers = function(format) { - if (format == null) { - format = "%Z-%m-%dT%H:%i:%s%:"; - } - $('.datepicker').AnyTime_noPicker(); - return $('.datepicker').AnyTime_picker({ - 'format': format, - 'formatUtcOffset': '%@' - }); - }; - UberView.prototype.dataTable = function(collection, selector, options, params, cols) { - var defaults; - if (selector == null) { - selector = 'table'; - } - if (options == null) { - options = {}; - } - if (params == null) { - params = {}; - } - if (cols == null) { - cols = []; - } - $(selector).empty(); - if (!cols.length) { - cols = collection.defaultColumns; - } - defaults = { - aoColumns: collection.tableColumns(cols), - bDestroy: true, - bSort: false, - bProcessing: true, - bFilter: false, - bServerSide: true, - bPaginate: true, - bScrollInfinite: true, - bScrollCollapse: true, - sScrollY: '600px', - iDisplayLength: 50, - fnServerData: function(source, data, callback) { - var defaultParams; - defaultParams = { - limit: data[4].value, - offset: data[3].value - }; - return collection.fetch({ - data: _.extend(defaultParams, params), - success: function() { - return callback({ - aaData: collection.toTableRows(cols), - iTotalRecords: collection.meta.count, - iTotalDisplayRecords: collection.meta.count - }); - }, - error: function() { - return new Error({ - message: 'Loading error.' - }); - } - }); - }, - fnRowCallback: function(nRow, aData, iDisplayIndex, iDisplayIndexFull) { - $('[data-tooltip]', nRow).qtip({ - content: { - attr: 'data-tooltip' - }, - style: { - classes: "ui-tooltip-light ui-tooltip-rounded ui-tooltip-shadow" - } - }); - return nRow; - } - }; - return $(this.el).find(selector).dataTable(_.extend(defaults, options)); - }; - UberView.prototype.dataTableLocal = function(collection, selector, options, params, cols) { - var $dataTable, defaults; - if (selector == null) { - selector = 'table'; - } - if (options == null) { - options = {}; - } - if (params == null) { - params = {}; - } - if (cols == null) { - cols = []; - } - $(selector).empty(); - if (!cols.length || cols.length === 0) { - cols = collection.defaultColumns; - } - defaults = { - aaData: collection.toTableRows(cols), - aoColumns: collection.tableColumns(cols), - bDestroy: true, - bSort: false, - bProcessing: true, - bFilter: false, - bScrollInfinite: true, - bScrollCollapse: true, - sScrollY: '600px', - iDisplayLength: -1 - }; - $dataTable = $(this.el).find(selector).dataTable(_.extend(defaults, options)); - _.delay(__bind(function() { - if ($dataTable && $dataTable.length > 0) { - return $dataTable.fnAdjustColumnSizing(); - } - }, this), 1); - return $dataTable; - }; - UberView.prototype.reverseGeocode = function() { - var $el; - return ''; - $el = $(this.el); - return this.requireMaps(function() { - var geocoder; - geocoder = new google.maps.Geocoder(); - return $el.find('[data-point]').each(function() { - var $this, latLng, point; - $this = $(this); - point = JSON.parse($this.attr('data-point')); - latLng = new google.maps.LatLng(point.latitude, point.longitude); - return geocoder.geocode({ - latLng: latLng - }, function(data, status) { - if (status === google.maps.GeocoderStatus.OK) { - return $this.text(data[0].formatted_address); - } - }); - }); - }); - }; - UberView.prototype.userIdsToLinkedNames = function() { - var $el; - $el = $(this.el); - return $el.find('a[data-user-id][data-user-type]').each(function() { - var $this, user, userType; - $this = $(this); - userType = $this.attr('data-user-type') === 'user' ? 'client' : $this.attr('data-user-type'); - user = new app.models[userType]({ - id: $this.attr('data-user-id') - }); - return user.fetch({ - success: function(user) { - return $this.html(app.helpers.linkedName(user)).attr('href', "!/" + user.role + "s/" + user.id); - }, - error: function() { - if ($this.attr('data-user-type') === 'user') { - user = new app.models['driver']({ - id: $this.attr('data-user-id') - }); - return user.fetch({ - success: function(user) { - return $this.html(app.helpers.linkedName(user)).attr('href', "!/driver/" + user.id); - } - }); - } - } - }); - }); - }; - UberView.prototype.selectedCity = function() { - var $selected, city, cityFilter; - cityFilter = $.cookie('city_filter'); - $selected = $("#city_filter option[value=" + cityFilter + "]"); - if (city_filter && $selected.length) { - return city = { - lat: parseFloat($selected.attr('data-lat')), - lng: parseFloat($selected.attr('data-lng')), - timezone: $selected.attr('data-timezone') - }; - } else { - return city = { - lat: 37.775, - lng: -122.45, - timezone: 'Etc/UTC' - }; - } - }; - UberView.prototype.updateModel = function(e, success) { - var $el, attrs, model, self; - e.preventDefault(); - $el = $(e.currentTarget); - self = this; - model = new this.model.__proto__.constructor({ - id: this.model.id - }); - attrs = {}; - $el.find('[name]').each(function() { - var $this; - $this = $(this); - return attrs["" + ($this.attr('name'))] = $this.val(); - }); - self.model.set(attrs); - $el.find('span.error').text(''); - return model.save(attrs, { - complete: function(xhr) { - var response; - response = JSON.parse(xhr.responseText); - switch (xhr.status) { - case 200: - self.model = model; - $el.find('[name]').val(''); - if (success) { - return success(); - } - break; - case 406: - return _.each(response, function(error, field) { - return $el.find("[name=" + field + "]").parent().find('span.error').text(error); - }); - default: - return this.unanticipatedError(response); - } - } - }); - }; - UberView.prototype.autoUpdateModel = function(e) { - var $el, arg, model, self, val; - $el = $(e.currentTarget); - val = $el.val(); - self = this; - if (val !== this.model.get($el.attr('id'))) { - arg = {}; - arg[$el.attr('id')] = $el.is(':checkbox') ? $el.is(':checked') ? 1 : 0 : val; - $('.editable span').empty(); - this.model.set(arg); - model = new this.model.__proto__.constructor({ - id: this.model.id - }); - return model.save(arg, { - complete: function(xhr) { - var key, response, _i, _len, _ref, _results; - response = JSON.parse(xhr.responseText); - switch (xhr.status) { - case 200: - self.flash('success', 'Saved!'); - return $el.blur(); - case 406: - self.flash('error', 'That was not Uber.'); - _ref = _.keys(response); - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - key = _ref[_i]; - _results.push($el.parent().find('span').html(response[key])); - } - return _results; - break; - default: - return self.unanticipatedError; - } - } - }); - } - }; - UberView.prototype.unanticipatedError = function(response) { - return self.flash('error', response); - }; - UberView.prototype.flash = function(type, text) { - var $banner; - $banner = $("." + type); - $banner.find('p').text(text).end().css('border', '1px solid #999').animate({ - top: 0 - }, 500); - return setTimeout(function() { - return $banner.animate({ - top: -$banner.outerHeight() - }, 500); - }, 3000); - }; - UberView.prototype.requireMaps = function(callback) { - if (typeof google !== 'undefined' && google.maps) { - return callback(); - } else { - return $.getScript("https://www.google.com/jsapi?key=" + CONFIG.googleJsApiKey, function() { - return google.load('maps', 3, { - callback: callback, - other_params: 'sensor=false&language=en' - }); - }); - } - }; - UberView.prototype.select_drop_down = function(model, key) { - var value; - value = model.get(key); - if (value) { - return $("select[id='" + key + "'] option[value='" + value + "']").attr('selected', 'selected'); - } - }; - UberView.prototype.processDocumentUpload = function(e) { - var $fi, $form, arbData, curDate, data, expDate, expM, expY, expiration, fileElementId, invalid; - e.preventDefault(); - $form = $(e.currentTarget); - $fi = $("input[type=file]", $form); - $(".validationError").removeClass("validationError"); - if (!$fi.val()) { - return $fi.addClass("validationError"); - } else { - fileElementId = $fi.attr('id'); - expY = $("select[name=expiration-year]", $form).val(); - expM = $("select[name=expiration-month]", $form).val(); - invalid = false; - if (expY && expM) { - expDate = new Date(expY, expM, 28); - curDate = new Date(); - if (expDate < curDate) { - invalid = true; - $(".expiration", $form).addClass("validationError"); - } - expiration = "" + expY + "-" + expM + "-28T23:59:59Z"; - } - arbData = {}; - $(".arbitraryField", $form).each(__bind(function(i, e) { - arbData[$(e).attr('name')] = $(e).val(); - if ($(e).val() === "") { - invalid = true; - return $(e).addClass("validationError"); - } - }, this)); - if (!invalid) { - data = { - token: $.cookie('token') || USER.get('token'), - name: $("input[name=fileName]", $form).val(), - meta: escape(JSON.stringify(arbData)), - user_id: $("input[name=driver_id]", $form).val(), - vehicle_id: $("input[name=vehicle_id]", $form).val() - }; - if (expiration) { - data['expiration'] = expiration; - } - $("#spinner").show(); - return $.ajaxFileUpload({ - url: '/api/documents', - secureuri: false, - fileElementId: fileElementId, - data: data, - complete: __bind(function(resp, status) { - var key, _i, _len, _ref, _results; - $("#spinner").hide(); - if (status === "success") { - if (this.model) { - this.model.refetch(); - } else { - USER.refetch(); - } - } - if (status === "error") { - _ref = _.keys(resp); - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - key = _ref[_i]; - _results.push($("*[name=" + key + "]", $form).addClass("validationError")); - } - return _results; - } - }, this) - }); - } - } - }; - return UberView; - })(); -}).call(this); -}, "web-lib/views/footer": function(exports, require, module) {(function() { - var footerTemplate; - var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { - for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } - function ctor() { this.constructor = child; } - ctor.prototype = parent.prototype; - child.prototype = new ctor; - child.__super__ = parent.prototype; - return child; - }; - footerTemplate = require('web-lib/templates/footer'); - exports.SharedFooterView = (function() { - __extends(SharedFooterView, Backbone.View); - function SharedFooterView() { - SharedFooterView.__super__.constructor.apply(this, arguments); - } - SharedFooterView.prototype.id = 'footer_view'; - SharedFooterView.prototype.events = { - 'click .language': 'intl_set_cookie_locale' - }; - SharedFooterView.prototype.render = function() { - $(this.el).html(footerTemplate()); - this.delegateEvents(); - return this; - }; - SharedFooterView.prototype.intl_set_cookie_locale = function(e) { - var _ref; - i18n.setLocale(e != null ? (_ref = e.srcElement) != null ? _ref.id : void 0 : void 0); - return location.reload(); - }; - return SharedFooterView; - })(); -}).call(this); -}}); diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/embed-tokens.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/embed-tokens.js deleted file mode 100755 index 61307eeb94..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/embed-tokens.js +++ /dev/null @@ -1,15 +0,0 @@ -#! /usr/bin/env node - -global.sys = require(/^v0\.[012]/.test(process.version) ? "sys" : "util"); -var fs = require("fs"); -var uglify = require("uglify-js"), // symlink ~/.node_libraries/uglify-js.js to ../uglify-js.js - jsp = uglify.parser, - pro = uglify.uglify; - -var code = fs.readFileSync("embed-tokens.js", "utf8").replace(/^#.*$/mg, ""); -var ast = jsp.parse(code, null, true); - -// trololo -function fooBar() {} - -console.log(sys.inspect(ast, null, null)); diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/goto.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/goto.js deleted file mode 100644 index 945960c2e4..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/goto.js +++ /dev/null @@ -1,26 +0,0 @@ -function unique(arqw) { - var a = [], i, j - outer: for (i = 0; i < arqw.length; i++) { - for (j = 0; j < a.length; j++) { - if (a[j] == arqw[i]) { - continue outer - } - } - a[a.length] = arqw[i] - } - return a -} - - -function unique(arqw) { - var crap = [], i, j - outer: for (i = 0; i < arqw.length; i++) { - for (j = 0; j < crap.length; j++) { - if (crap[j] == arqw[i]) { - continue outer - } - } - crap[crap.length] = arqw[i] - } - return crap -} diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/goto2.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/goto2.js deleted file mode 100644 index d13b2bc0a0..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/goto2.js +++ /dev/null @@ -1,8 +0,0 @@ -function q(qooo) { - var a; - foo: for(;;) { - a++; - if (something) break foo; - return qooo; - } -} diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/hoist.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/hoist.js deleted file mode 100644 index 4bf2b94de6..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/hoist.js +++ /dev/null @@ -1,33 +0,0 @@ -function foo(arg1, arg2, arg3, arg4, arg5, arg6) { - var a = 5; - { - var d = 10, mak = 20, buz = 30; - var q = buz * 2; - } - if (moo) { - var a, b, c; - } - for (var arg1 = 0, d = 20; arg1 < 10; ++arg1) - console.log(arg3); - for (var i in mak) {} - for (j in d) {} - var d; - - function test() { - - }; - - //test(); - - (function moo(first, second){ - console.log(first); - })(1); - - (function moo(first, second){ - console.log(moo()); - })(1); -} - - -var foo; -var bar; diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/instrument.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/instrument.js deleted file mode 100644 index c6a9d798a8..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/instrument.js +++ /dev/null @@ -1,97 +0,0 @@ -// sample on how to use the parser and walker API to instrument some code - -var jsp = require("uglify-js").parser; -var pro = require("uglify-js").uglify; - -function instrument(code) { - var ast = jsp.parse(code, false, true); // true for the third arg specifies that we want - // to have start/end tokens embedded in the - // statements - var w = pro.ast_walker(); - - // we're gonna need this to push elements that we're currently looking at, to avoid - // endless recursion. - var analyzing = []; - function do_stat() { - var ret; - if (this[0].start && analyzing.indexOf(this) < 0) { - // without the `analyzing' hack, w.walk(this) would re-enter here leading - // to infinite recursion - analyzing.push(this); - ret = [ "splice", // XXX: "block" is safer - [ [ "stat", - [ "call", [ "name", "trace" ], - [ [ "string", this[0].toString() ], - [ "num", this[0].start.line ], - [ "num", this[0].start.col ], - [ "num", this[0].end.line ], - [ "num", this[0].end.col ]]]], - w.walk(this) ]]; - analyzing.pop(this); - } - return ret; - }; - var new_ast = w.with_walkers({ - "stat" : do_stat, - "label" : do_stat, - "break" : do_stat, - "continue" : do_stat, - "debugger" : do_stat, - "var" : do_stat, - "const" : do_stat, - "return" : do_stat, - "throw" : do_stat, - "try" : do_stat, - "defun" : do_stat, - "if" : do_stat, - "while" : do_stat, - "do" : do_stat, - "for" : do_stat, - "for-in" : do_stat, - "switch" : do_stat, - "with" : do_stat - }, function(){ - return w.walk(ast); - }); - return pro.gen_code(new_ast, { beautify: true }); -} - - - - -////// test code follows. - -var code = instrument(test.toString()); -console.log(code); - -function test() { - // simple stats - a = 5; - c += a + b; - "foo"; - - // var - var foo = 5; - const bar = 6, baz = 7; - - // switch block. note we can't track case lines the same way. - switch ("foo") { - case "foo": - return 1; - case "bar": - return 2; - } - - // for/for in - for (var i = 0; i < 5; ++i) { - console.log("Hello " + i); - } - for (var i in [ 1, 2, 3]) { - console.log(i); - } - - // note however that the following is broken. I guess we - // should add the block brackets in this case... - for (var i = 0; i < 5; ++i) - console.log("foo"); -} diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/instrument2.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/instrument2.js deleted file mode 100644 index 6aee5f3fe9..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/instrument2.js +++ /dev/null @@ -1,138 +0,0 @@ -// sample on how to use the parser and walker API to instrument some code - -var jsp = require("uglify-js").parser; -var pro = require("uglify-js").uglify; - -function instrument(code) { - var ast = jsp.parse(code, false, true); // true for the third arg specifies that we want - // to have start/end tokens embedded in the - // statements - var w = pro.ast_walker(); - - function trace (line, comment) { - var code = pro.gen_code(line, { beautify: true }); - var data = line[0] - - var args = [] - if (!comment) comment = "" - if (typeof data === "object") { - code = code.split(/\n/).shift() - args = [ [ "string", data.toString() ], - [ "string", code ], - [ "num", data.start.line ], - [ "num", data.start.col ], - [ "num", data.end.line ], - [ "num", data.end.col ]] - } else { - args = [ [ "string", data ], - [ "string", code ]] - - } - return [ "call", [ "name", "trace" ], args ]; - } - - // we're gonna need this to push elements that we're currently looking at, to avoid - // endless recursion. - var analyzing = []; - function do_stat() { - var ret; - if (this[0].start && analyzing.indexOf(this) < 0) { - // without the `analyzing' hack, w.walk(this) would re-enter here leading - // to infinite recursion - analyzing.push(this); - ret = [ "splice", - [ [ "stat", trace(this) ], - w.walk(this) ]]; - analyzing.pop(this); - } - return ret; - } - - function do_cond(c, t, f) { - return [ this[0], w.walk(c), - ["seq", trace(t), w.walk(t) ], - ["seq", trace(f), w.walk(f) ]]; - } - - function do_binary(c, l, r) { - if (c !== "&&" && c !== "||") { - return [this[0], c, w.walk(l), w.walk(r)]; - } - return [ this[0], c, - ["seq", trace(l), w.walk(l) ], - ["seq", trace(r), w.walk(r) ]]; - } - - var new_ast = w.with_walkers({ - "stat" : do_stat, - "label" : do_stat, - "break" : do_stat, - "continue" : do_stat, - "debugger" : do_stat, - "var" : do_stat, - "const" : do_stat, - "return" : do_stat, - "throw" : do_stat, - "try" : do_stat, - "defun" : do_stat, - "if" : do_stat, - "while" : do_stat, - "do" : do_stat, - "for" : do_stat, - "for-in" : do_stat, - "switch" : do_stat, - "with" : do_stat, - "conditional" : do_cond, - "binary" : do_binary - }, function(){ - return w.walk(ast); - }); - return pro.gen_code(new_ast, { beautify: true }); -} - - -////// test code follows. - -var code = instrument(test.toString()); -console.log(code); - -function test() { - // simple stats - a = 5; - c += a + b; - "foo"; - - // var - var foo = 5; - const bar = 6, baz = 7; - - // switch block. note we can't track case lines the same way. - switch ("foo") { - case "foo": - return 1; - case "bar": - return 2; - } - - // for/for in - for (var i = 0; i < 5; ++i) { - console.log("Hello " + i); - } - for (var i in [ 1, 2, 3]) { - console.log(i); - } - - for (var i = 0; i < 5; ++i) - console.log("foo"); - - for (var i = 0; i < 5; ++i) { - console.log("foo"); - } - - var k = plurp() ? 1 : 0; - var x = a ? doX(y) && goZoo("zoo") - : b ? blerg({ x: y }) - : null; - - var x = X || Y; -} diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/liftvars.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/liftvars.js deleted file mode 100644 index 2f4b7fe223..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/liftvars.js +++ /dev/null @@ -1,8 +0,0 @@ -var UNUSED_VAR1 = 19; - -function main() { - var unused_var2 = 20; - alert(100); -} - -main(); diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/test.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/test.js deleted file mode 100755 index f295fba847..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/test.js +++ /dev/null @@ -1,30 +0,0 @@ -#! /usr/bin/env node - -global.sys = require(/^v0\.[012]/.test(process.version) ? "sys" : "util"); -var fs = require("fs"); -var uglify = require("uglify-js"), // symlink ~/.node_libraries/uglify-js.js to ../uglify-js.js - jsp = uglify.parser, - pro = uglify.uglify; - -var code = fs.readFileSync("hoist.js", "utf8"); -var ast = jsp.parse(code); - -ast = pro.ast_lift_variables(ast); - -var w = pro.ast_walker(); -ast = w.with_walkers({ - "function": function() { - var node = w.dive(this); // walk depth first - console.log(pro.gen_code(node, { beautify: true })); - return node; - }, - "name": function(name) { - return [ this[0], "X" ]; - } -}, function(){ - return w.walk(ast); -}); - -console.log(pro.gen_code(ast, { - beautify: true -})); diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/uglify-hangs.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/uglify-hangs.js deleted file mode 100644 index 0d5b7e0ebf..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/uglify-hangs.js +++ /dev/null @@ -1,3930 +0,0 @@ -/** - * @fileoverview - * - * JsWorld - * - *

Javascript library for localised formatting and parsing of: - *

    - *
  • Numbers - *
  • Dates and times - *
  • Currency - *
- * - *

The library classes are configured with standard POSIX locale definitions - * derived from Unicode's Common Locale Data Repository (CLDR). - * - *

Website: JsWorld - * - * @author Vladimir Dzhuvinov - * @version 2.5 (2011-12-23) - */ - - - -/** - * @namespace Namespace container for the JsWorld library objects. - */ -jsworld = {}; - - -/** - * @function - * - * @description Formats a JavaScript Date object as an ISO-8601 date/time - * string. - * - * @param {Date} [d] A valid JavaScript Date object. If undefined the - * current date/time will be used. - * @param {Boolean} [withTZ] Include timezone offset, default false. - * - * @returns {String} The date/time formatted as YYYY-MM-DD HH:MM:SS. - */ -jsworld.formatIsoDateTime = function(d, withTZ) { - - if (typeof d === "undefined") - d = new Date(); // now - - if (typeof withTZ === "undefined") - withTZ = false; - - var s = jsworld.formatIsoDate(d) + " " + jsworld.formatIsoTime(d); - - if (withTZ) { - - var diff = d.getHours() - d.getUTCHours(); - var hourDiff = Math.abs(diff); - - var minuteUTC = d.getUTCMinutes(); - var minute = d.getMinutes(); - - if (minute != minuteUTC && minuteUTC < 30 && diff < 0) - hourDiff--; - - if (minute != minuteUTC && minuteUTC > 30 && diff > 0) - hourDiff--; - - var minuteDiff; - if (minute != minuteUTC) - minuteDiff = ":30"; - else - minuteDiff = ":00"; - - var timezone; - if (hourDiff < 10) - timezone = "0" + hourDiff + minuteDiff; - - else - timezone = "" + hourDiff + minuteDiff; - - if (diff < 0) - timezone = "-" + timezone; - - else - timezone = "+" + timezone; - - s = s + timezone; - } - - return s; -}; - - -/** - * @function - * - * @description Formats a JavaScript Date object as an ISO-8601 date string. - * - * @param {Date} [d] A valid JavaScript Date object. If undefined the current - * date will be used. - * - * @returns {String} The date formatted as YYYY-MM-DD. - */ -jsworld.formatIsoDate = function(d) { - - if (typeof d === "undefined") - d = new Date(); // now - - var year = d.getFullYear(); - var month = d.getMonth() + 1; - var day = d.getDate(); - - return year + "-" + jsworld._zeroPad(month, 2) + "-" + jsworld._zeroPad(day, 2); -}; - - -/** - * @function - * - * @description Formats a JavaScript Date object as an ISO-8601 time string. - * - * @param {Date} [d] A valid JavaScript Date object. If undefined the current - * time will be used. - * - * @returns {String} The time formatted as HH:MM:SS. - */ -jsworld.formatIsoTime = function(d) { - - if (typeof d === "undefined") - d = new Date(); // now - - var hour = d.getHours(); - var minute = d.getMinutes(); - var second = d.getSeconds(); - - return jsworld._zeroPad(hour, 2) + ":" + jsworld._zeroPad(minute, 2) + ":" + jsworld._zeroPad(second, 2); -}; - - -/** - * @function - * - * @description Parses an ISO-8601 formatted date/time string to a JavaScript - * Date object. - * - * @param {String} isoDateTimeVal An ISO-8601 formatted date/time string. - * - *

Accepted formats: - * - *

    - *
  • YYYY-MM-DD HH:MM:SS - *
  • YYYYMMDD HHMMSS - *
  • YYYY-MM-DD HHMMSS - *
  • YYYYMMDD HH:MM:SS - *
- * - * @returns {Date} The corresponding Date object. - * - * @throws Error on a badly formatted date/time string or on a invalid date. - */ -jsworld.parseIsoDateTime = function(isoDateTimeVal) { - - if (typeof isoDateTimeVal != "string") - throw "Error: The parameter must be a string"; - - // First, try to match "YYYY-MM-DD HH:MM:SS" format - var matches = isoDateTimeVal.match(/^(\d\d\d\d)-(\d\d)-(\d\d)[T ](\d\d):(\d\d):(\d\d)/); - - // If unsuccessful, try to match "YYYYMMDD HHMMSS" format - if (matches === null) - matches = isoDateTimeVal.match(/^(\d\d\d\d)(\d\d)(\d\d)[T ](\d\d)(\d\d)(\d\d)/); - - // ... try to match "YYYY-MM-DD HHMMSS" format - if (matches === null) - matches = isoDateTimeVal.match(/^(\d\d\d\d)-(\d\d)-(\d\d)[T ](\d\d)(\d\d)(\d\d)/); - - // ... try to match "YYYYMMDD HH:MM:SS" format - if (matches === null) - matches = isoDateTimeVal.match(/^(\d\d\d\d)-(\d\d)-(\d\d)[T ](\d\d):(\d\d):(\d\d)/); - - // Report bad date/time string - if (matches === null) - throw "Error: Invalid ISO-8601 date/time string"; - - // Force base 10 parse int as some values may have leading zeros! - // (to avoid implicit octal base conversion) - var year = parseInt(matches[1], 10); - var month = parseInt(matches[2], 10); - var day = parseInt(matches[3], 10); - - var hour = parseInt(matches[4], 10); - var mins = parseInt(matches[5], 10); - var secs = parseInt(matches[6], 10); - - // Simple value range check, leap years not checked - // Note: the originial ISO time spec for leap hours (24:00:00) and seconds (00:00:60) is not supported - if (month < 1 || month > 12 || - day < 1 || day > 31 || - hour < 0 || hour > 23 || - mins < 0 || mins > 59 || - secs < 0 || secs > 59 ) - - throw "Error: Invalid ISO-8601 date/time value"; - - var d = new Date(year, month - 1, day, hour, mins, secs); - - // Check if the input date was valid - // (JS Date does automatic forward correction) - if (d.getDate() != day || d.getMonth() +1 != month) - throw "Error: Invalid date"; - - return d; -}; - - -/** - * @function - * - * @description Parses an ISO-8601 formatted date string to a JavaScript - * Date object. - * - * @param {String} isoDateVal An ISO-8601 formatted date string. - * - *

Accepted formats: - * - *

    - *
  • YYYY-MM-DD - *
  • YYYYMMDD - *
- * - * @returns {Date} The corresponding Date object. - * - * @throws Error on a badly formatted date string or on a invalid date. - */ -jsworld.parseIsoDate = function(isoDateVal) { - - if (typeof isoDateVal != "string") - throw "Error: The parameter must be a string"; - - // First, try to match "YYYY-MM-DD" format - var matches = isoDateVal.match(/^(\d\d\d\d)-(\d\d)-(\d\d)/); - - // If unsuccessful, try to match "YYYYMMDD" format - if (matches === null) - matches = isoDateVal.match(/^(\d\d\d\d)(\d\d)(\d\d)/); - - // Report bad date/time string - if (matches === null) - throw "Error: Invalid ISO-8601 date string"; - - // Force base 10 parse int as some values may have leading zeros! - // (to avoid implicit octal base conversion) - var year = parseInt(matches[1], 10); - var month = parseInt(matches[2], 10); - var day = parseInt(matches[3], 10); - - // Simple value range check, leap years not checked - if (month < 1 || month > 12 || - day < 1 || day > 31 ) - - throw "Error: Invalid ISO-8601 date value"; - - var d = new Date(year, month - 1, day); - - // Check if the input date was valid - // (JS Date does automatic forward correction) - if (d.getDate() != day || d.getMonth() +1 != month) - throw "Error: Invalid date"; - - return d; -}; - - -/** - * @function - * - * @description Parses an ISO-8601 formatted time string to a JavaScript - * Date object. - * - * @param {String} isoTimeVal An ISO-8601 formatted time string. - * - *

Accepted formats: - * - *

    - *
  • HH:MM:SS - *
  • HHMMSS - *
- * - * @returns {Date} The corresponding Date object, with year, month and day set - * to zero. - * - * @throws Error on a badly formatted time string. - */ -jsworld.parseIsoTime = function(isoTimeVal) { - - if (typeof isoTimeVal != "string") - throw "Error: The parameter must be a string"; - - // First, try to match "HH:MM:SS" format - var matches = isoTimeVal.match(/^(\d\d):(\d\d):(\d\d)/); - - // If unsuccessful, try to match "HHMMSS" format - if (matches === null) - matches = isoTimeVal.match(/^(\d\d)(\d\d)(\d\d)/); - - // Report bad date/time string - if (matches === null) - throw "Error: Invalid ISO-8601 date/time string"; - - // Force base 10 parse int as some values may have leading zeros! - // (to avoid implicit octal base conversion) - var hour = parseInt(matches[1], 10); - var mins = parseInt(matches[2], 10); - var secs = parseInt(matches[3], 10); - - // Simple value range check, leap years not checked - if (hour < 0 || hour > 23 || - mins < 0 || mins > 59 || - secs < 0 || secs > 59 ) - - throw "Error: Invalid ISO-8601 time value"; - - return new Date(0, 0, 0, hour, mins, secs); -}; - - -/** - * @private - * - * @description Trims leading and trailing whitespace from a string. - * - *

Used non-regexp the method from http://blog.stevenlevithan.com/archives/faster-trim-javascript - * - * @param {String} str The string to trim. - * - * @returns {String} The trimmed string. - */ -jsworld._trim = function(str) { - - var whitespace = ' \n\r\t\f\x0b\xa0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000'; - - for (var i = 0; i < str.length; i++) { - - if (whitespace.indexOf(str.charAt(i)) === -1) { - str = str.substring(i); - break; - } - } - - for (i = str.length - 1; i >= 0; i--) { - if (whitespace.indexOf(str.charAt(i)) === -1) { - str = str.substring(0, i + 1); - break; - } - } - - return whitespace.indexOf(str.charAt(0)) === -1 ? str : ''; -}; - - - -/** - * @private - * - * @description Returns true if the argument represents a decimal number. - * - * @param {Number|String} arg The argument to test. - * - * @returns {Boolean} true if the argument represents a decimal number, - * otherwise false. - */ -jsworld._isNumber = function(arg) { - - if (typeof arg == "number") - return true; - - if (typeof arg != "string") - return false; - - // ensure string - var s = arg + ""; - - return (/^-?(\d+|\d*\.\d+)$/).test(s); -}; - - -/** - * @private - * - * @description Returns true if the argument represents a decimal integer. - * - * @param {Number|String} arg The argument to test. - * - * @returns {Boolean} true if the argument represents an integer, otherwise - * false. - */ -jsworld._isInteger = function(arg) { - - if (typeof arg != "number" && typeof arg != "string") - return false; - - // convert to string - var s = arg + ""; - - return (/^-?\d+$/).test(s); -}; - - -/** - * @private - * - * @description Returns true if the argument represents a decimal float. - * - * @param {Number|String} arg The argument to test. - * - * @returns {Boolean} true if the argument represents a float, otherwise false. - */ -jsworld._isFloat = function(arg) { - - if (typeof arg != "number" && typeof arg != "string") - return false; - - // convert to string - var s = arg + ""; - - return (/^-?\.\d+?$/).test(s); -}; - - -/** - * @private - * - * @description Checks if the specified formatting option is contained - * within the options string. - * - * @param {String} option The option to search for. - * @param {String} optionsString The options string. - * - * @returns {Boolean} true if the flag is found, else false - */ -jsworld._hasOption = function(option, optionsString) { - - if (typeof option != "string" || typeof optionsString != "string") - return false; - - if (optionsString.indexOf(option) != -1) - return true; - else - return false; -}; - - -/** - * @private - * - * @description String replacement function. - * - * @param {String} s The string to work on. - * @param {String} target The string to search for. - * @param {String} replacement The replacement. - * - * @returns {String} The new string. - */ -jsworld._stringReplaceAll = function(s, target, replacement) { - - var out; - - if (target.length == 1 && replacement.length == 1) { - // simple char/char case somewhat faster - out = ""; - - for (var i = 0; i < s.length; i++) { - - if (s.charAt(i) == target.charAt(0)) - out = out + replacement.charAt(0); - else - out = out + s.charAt(i); - } - - return out; - } - else { - // longer target and replacement strings - out = s; - - var index = out.indexOf(target); - - while (index != -1) { - - out = out.replace(target, replacement); - - index = out.indexOf(target); - } - - return out; - } -}; - - -/** - * @private - * - * @description Tests if a string starts with the specified substring. - * - * @param {String} testedString The string to test. - * @param {String} sub The string to match. - * - * @returns {Boolean} true if the test succeeds. - */ -jsworld._stringStartsWith = function (testedString, sub) { - - if (testedString.length < sub.length) - return false; - - for (var i = 0; i < sub.length; i++) { - if (testedString.charAt(i) != sub.charAt(i)) - return false; - } - - return true; -}; - - -/** - * @private - * - * @description Gets the requested precision from an options string. - * - *

Example: ".3" returns 3 decimal places precision. - * - * @param {String} optionsString The options string. - * - * @returns {integer Number} The requested precision, -1 if not specified. - */ -jsworld._getPrecision = function (optionsString) { - - if (typeof optionsString != "string") - return -1; - - var m = optionsString.match(/\.(\d)/); - if (m) - return parseInt(m[1], 10); - else - return -1; -}; - - -/** - * @private - * - * @description Takes a decimal numeric amount (optionally as string) and - * returns its integer and fractional parts packed into an object. - * - * @param {Number|String} amount The amount, e.g. "123.45" or "-56.78" - * - * @returns {object} Parsed amount object with properties: - * {String} integer : the integer part - * {String} fraction : the fraction part - */ -jsworld._splitNumber = function (amount) { - - if (typeof amount == "number") - amount = amount + ""; - - var obj = {}; - - // remove negative sign - if (amount.charAt(0) == "-") - amount = amount.substring(1); - - // split amount into integer and decimal parts - var amountParts = amount.split("."); - if (!amountParts[1]) - amountParts[1] = ""; // we need "" instead of null - - obj.integer = amountParts[0]; - obj.fraction = amountParts[1]; - - return obj; -}; - - -/** - * @private - * - * @description Formats the integer part using the specified grouping - * and thousands separator. - * - * @param {String} intPart The integer part of the amount, as string. - * @param {String} grouping The grouping definition. - * @param {String} thousandsSep The thousands separator. - * - * @returns {String} The formatted integer part. - */ -jsworld._formatIntegerPart = function (intPart, grouping, thousandsSep) { - - // empty separator string? no grouping? - // -> return immediately with no formatting! - if (thousandsSep == "" || grouping == "-1") - return intPart; - - // turn the semicolon-separated string of integers into an array - var groupSizes = grouping.split(";"); - - // the formatted output string - var out = ""; - - // the intPart string position to process next, - // start at string end, e.g. "10000000 0) { - - // get next group size (if any, otherwise keep last) - if (groupSizes.length > 0) - size = parseInt(groupSizes.shift(), 10); - - // int parse error? - if (isNaN(size)) - throw "Error: Invalid grouping"; - - // size is -1? -> no more grouping, so just copy string remainder - if (size == -1) { - out = intPart.substring(0, pos) + out; - break; - } - - pos -= size; // move to next sep. char. position - - // position underrun? -> just copy string remainder - if (pos < 1) { - out = intPart.substring(0, pos + size) + out; - break; - } - - // extract group and apply sep. char. - out = thousandsSep + intPart.substring(pos, pos + size) + out; - } - - return out; -}; - - -/** - * @private - * - * @description Formats the fractional part to the specified decimal - * precision. - * - * @param {String} fracPart The fractional part of the amount - * @param {integer Number} precision The desired decimal precision - * - * @returns {String} The formatted fractional part. - */ -jsworld._formatFractionPart = function (fracPart, precision) { - - // append zeroes up to precision if necessary - for (var i=0; fracPart.length < precision; i++) - fracPart = fracPart + "0"; - - return fracPart; -}; - - -/** - * @private - * - * @desription Converts a number to string and pad it with leading zeroes if the - * string is shorter than length. - * - * @param {integer Number} number The number value subjected to selective padding. - * @param {integer Number} length If the number has fewer digits than this length - * apply padding. - * - * @returns {String} The formatted string. - */ -jsworld._zeroPad = function(number, length) { - - // ensure string - var s = number + ""; - - while (s.length < length) - s = "0" + s; - - return s; -}; - - -/** - * @private - * @description Converts a number to string and pads it with leading spaces if - * the string is shorter than length. - * - * @param {integer Number} number The number value subjected to selective padding. - * @param {integer Number} length If the number has fewer digits than this length - * apply padding. - * - * @returns {String} The formatted string. - */ -jsworld._spacePad = function(number, length) { - - // ensure string - var s = number + ""; - - while (s.length < length) - s = " " + s; - - return s; -}; - - - -/** - * @class - * Represents a POSIX-style locale with its numeric, monetary and date/time - * properties. Also provides a set of locale helper methods. - * - *

The locale properties follow the POSIX standards: - * - *

- * - * @public - * @constructor - * @description Creates a new locale object (POSIX-style) with the specified - * properties. - * - * @param {object} properties An object containing the raw locale properties: - * - * @param {String} properties.decimal_point - * - * A string containing the symbol that shall be used as the decimal - * delimiter (radix character) in numeric, non-monetary formatted - * quantities. This property cannot be omitted and cannot be set to the - * empty string. - * - * - * @param {String} properties.thousands_sep - * - * A string containing the symbol that shall be used as a separator for - * groups of digits to the left of the decimal delimiter in numeric, - * non-monetary formatted monetary quantities. - * - * - * @param {String} properties.grouping - * - * Defines the size of each group of digits in formatted non-monetary - * quantities. The operand is a sequence of integers separated by - * semicolons. Each integer specifies the number of digits in each group, - * with the initial integer defining the size of the group immediately - * preceding the decimal delimiter, and the following integers defining - * the preceding groups. If the last integer is not -1, then the size of - * the previous group (if any) shall be repeatedly used for the - * remainder of the digits. If the last integer is -1, then no further - * grouping shall be performed. - * - * - * @param {String} properties.int_curr_symbol - * - * The first three letters signify the ISO-4217 currency code, - * the fourth letter is the international symbol separation character - * (normally a space). - * - * - * @param {String} properties.currency_symbol - * - * The local shorthand currency symbol, e.g. "$" for the en_US locale - * - * - * @param {String} properties.mon_decimal_point - * - * The symbol to be used as the decimal delimiter (radix character) - * - * - * @param {String} properties.mon_thousands_sep - * - * The symbol to be used as a separator for groups of digits to the - * left of the decimal delimiter. - * - * - * @param {String} properties.mon_grouping - * - * A string that defines the size of each group of digits. The - * operand is a sequence of integers separated by semicolons (";"). - * Each integer specifies the number of digits in each group, with the - * initial integer defining the size of the group preceding the - * decimal delimiter, and the following integers defining the - * preceding groups. If the last integer is not -1, then the size of - * the previous group (if any) must be repeatedly used for the - * remainder of the digits. If the last integer is -1, then no - * further grouping is to be performed. - * - * - * @param {String} properties.positive_sign - * - * The string to indicate a non-negative monetary amount. - * - * - * @param {String} properties.negative_sign - * - * The string to indicate a negative monetary amount. - * - * - * @param {integer Number} properties.frac_digits - * - * An integer representing the number of fractional digits (those to - * the right of the decimal delimiter) to be written in a formatted - * monetary quantity using currency_symbol. - * - * - * @param {integer Number} properties.int_frac_digits - * - * An integer representing the number of fractional digits (those to - * the right of the decimal delimiter) to be written in a formatted - * monetary quantity using int_curr_symbol. - * - * - * @param {integer Number} properties.p_cs_precedes - * - * An integer set to 1 if the currency_symbol precedes the value for a - * monetary quantity with a non-negative value, and set to 0 if the - * symbol succeeds the value. - * - * - * @param {integer Number} properties.n_cs_precedes - * - * An integer set to 1 if the currency_symbol precedes the value for a - * monetary quantity with a negative value, and set to 0 if the symbol - * succeeds the value. - * - * - * @param {integer Number} properties.p_sep_by_space - * - * Set to a value indicating the separation of the currency_symbol, - * the sign string, and the value for a non-negative formatted monetary - * quantity: - * - *

0 No space separates the currency symbol and value.

- * - *

1 If the currency symbol and sign string are adjacent, a space - * separates them from the value; otherwise, a space separates - * the currency symbol from the value.

- * - *

2 If the currency symbol and sign string are adjacent, a space - * separates them; otherwise, a space separates the sign string - * from the value.

- * - * - * @param {integer Number} properties.n_sep_by_space - * - * Set to a value indicating the separation of the currency_symbol, - * the sign string, and the value for a negative formatted monetary - * quantity. Rules same as for p_sep_by_space. - * - * - * @param {integer Number} properties.p_sign_posn - * - * An integer set to a value indicating the positioning of the - * positive_sign for a monetary quantity with a non-negative value: - * - *

0 Parentheses enclose the quantity and the currency_symbol.

- * - *

1 The sign string precedes the quantity and the currency_symbol.

- * - *

2 The sign string succeeds the quantity and the currency_symbol.

- * - *

3 The sign string precedes the currency_symbol.

- * - *

4 The sign string succeeds the currency_symbol.

- * - * - * @param {integer Number} properties.n_sign_posn - * - * An integer set to a value indicating the positioning of the - * negative_sign for a negative formatted monetary quantity. Rules same - * as for p_sign_posn. - * - * - * @param {integer Number} properties.int_p_cs_precedes - * - * An integer set to 1 if the int_curr_symbol precedes the value for a - * monetary quantity with a non-negative value, and set to 0 if the - * symbol succeeds the value. - * - * - * @param {integer Number} properties.int_n_cs_precedes - * - * An integer set to 1 if the int_curr_symbol precedes the value for a - * monetary quantity with a negative value, and set to 0 if the symbol - * succeeds the value. - * - * - * @param {integer Number} properties.int_p_sep_by_space - * - * Set to a value indicating the separation of the int_curr_symbol, - * the sign string, and the value for a non-negative internationally - * formatted monetary quantity. Rules same as for p_sep_by_space. - * - * - * @param {integer Number} properties.int_n_sep_by_space - * - * Set to a value indicating the separation of the int_curr_symbol, - * the sign string, and the value for a negative internationally - * formatted monetary quantity. Rules same as for p_sep_by_space. - * - * - * @param {integer Number} properties.int_p_sign_posn - * - * An integer set to a value indicating the positioning of the - * positive_sign for a positive monetary quantity formatted with the - * international format. Rules same as for p_sign_posn. - * - * - * @param {integer Number} properties.int_n_sign_posn - * - * An integer set to a value indicating the positioning of the - * negative_sign for a negative monetary quantity formatted with the - * international format. Rules same as for p_sign_posn. - * - * - * @param {String[] | String} properties.abday - * - * The abbreviated weekday names, corresponding to the %a conversion - * specification. The property must be either an array of 7 strings or - * a string consisting of 7 semicolon-separated substrings, each - * surrounded by double-quotes. The first must be the abbreviated name - * of the day corresponding to Sunday, the second the abbreviated name - * of the day corresponding to Monday, and so on. - * - * - * @param {String[] | String} properties.day - * - * The full weekday names, corresponding to the %A conversion - * specification. The property must be either an array of 7 strings or - * a string consisting of 7 semicolon-separated substrings, each - * surrounded by double-quotes. The first must be the full name of the - * day corresponding to Sunday, the second the full name of the day - * corresponding to Monday, and so on. - * - * - * @param {String[] | String} properties.abmon - * - * The abbreviated month names, corresponding to the %b conversion - * specification. The property must be either an array of 12 strings or - * a string consisting of 12 semicolon-separated substrings, each - * surrounded by double-quotes. The first must be the abbreviated name - * of the first month of the year (January), the second the abbreviated - * name of the second month, and so on. - * - * - * @param {String[] | String} properties.mon - * - * The full month names, corresponding to the %B conversion - * specification. The property must be either an array of 12 strings or - * a string consisting of 12 semicolon-separated substrings, each - * surrounded by double-quotes. The first must be the full name of the - * first month of the year (January), the second the full name of the second - * month, and so on. - * - * - * @param {String} properties.d_fmt - * - * The appropriate date representation. The string may contain any - * combination of characters and conversion specifications (%). - * - * - * @param {String} properties.t_fmt - * - * The appropriate time representation. The string may contain any - * combination of characters and conversion specifications (%). - * - * - * @param {String} properties.d_t_fmt - * - * The appropriate date and time representation. The string may contain - * any combination of characters and conversion specifications (%). - * - * - * @param {String[] | String} properties.am_pm - * - * The appropriate representation of the ante-meridiem and post-meridiem - * strings, corresponding to the %p conversion specification. The property - * must be either an array of 2 strings or a string consisting of 2 - * semicolon-separated substrings, each surrounded by double-quotes. - * The first string must represent the ante-meridiem designation, the - * last string the post-meridiem designation. - * - * - * @throws @throws Error on a undefined or invalid locale property. - */ -jsworld.Locale = function(properties) { - - - /** - * @private - * - * @description Identifies the class for internal library purposes. - */ - this._className = "jsworld.Locale"; - - - /** - * @private - * - * @description Parses a day or month name definition list, which - * could be a ready JS array, e.g. ["Mon", "Tue", "Wed"...] or - * it could be a string formatted according to the classic POSIX - * definition e.g. "Mon";"Tue";"Wed";... - * - * @param {String[] | String} namesAn array or string defining - * the week/month names. - * @param {integer Number} expectedItems The number of expected list - * items, e.g. 7 for weekdays, 12 for months. - * - * @returns {String[]} The parsed (and checked) items. - * - * @throws Error on missing definition, unexpected item count or - * missing double-quotes. - */ - this._parseList = function(names, expectedItems) { - - var array = []; - - if (names == null) { - throw "Names not defined"; - } - else if (typeof names == "object") { - // we got a ready array - array = names; - } - else if (typeof names == "string") { - // we got the names in the classic POSIX form, do parse - array = names.split(";", expectedItems); - - for (var i = 0; i < array.length; i++) { - // check for and strip double quotes - if (array[i][0] == "\"" && array[i][array[i].length - 1] == "\"") - array[i] = array[i].slice(1, -1); - else - throw "Missing double quotes"; - } - } - else { - throw "Names must be an array or a string"; - } - - if (array.length != expectedItems) - throw "Expected " + expectedItems + " items, got " + array.length; - - return array; - }; - - - /** - * @private - * - * @description Validates a date/time format string, such as "H:%M:%S". - * Checks that the argument is of type "string" and is not empty. - * - * @param {String} formatString The format string. - * - * @returns {String} The validated string. - * - * @throws Error on null or empty string. - */ - this._validateFormatString = function(formatString) { - - if (typeof formatString == "string" && formatString.length > 0) - return formatString; - else - throw "Empty or no string"; - }; - - - // LC_NUMERIC - - if (properties == null || typeof properties != "object") - throw "Error: Invalid/missing locale properties"; - - - if (typeof properties.decimal_point != "string") - throw "Error: Invalid/missing decimal_point property"; - - this.decimal_point = properties.decimal_point; - - - if (typeof properties.thousands_sep != "string") - throw "Error: Invalid/missing thousands_sep property"; - - this.thousands_sep = properties.thousands_sep; - - - if (typeof properties.grouping != "string") - throw "Error: Invalid/missing grouping property"; - - this.grouping = properties.grouping; - - - // LC_MONETARY - - if (typeof properties.int_curr_symbol != "string") - throw "Error: Invalid/missing int_curr_symbol property"; - - if (! /[A-Za-z]{3}.?/.test(properties.int_curr_symbol)) - throw "Error: Invalid int_curr_symbol property"; - - this.int_curr_symbol = properties.int_curr_symbol; - - - if (typeof properties.currency_symbol != "string") - throw "Error: Invalid/missing currency_symbol property"; - - this.currency_symbol = properties.currency_symbol; - - - if (typeof properties.frac_digits != "number" && properties.frac_digits < 0) - throw "Error: Invalid/missing frac_digits property"; - - this.frac_digits = properties.frac_digits; - - - // may be empty string/null for currencies with no fractional part - if (properties.mon_decimal_point === null || properties.mon_decimal_point == "") { - - if (this.frac_digits > 0) - throw "Error: Undefined mon_decimal_point property"; - else - properties.mon_decimal_point = ""; - } - - if (typeof properties.mon_decimal_point != "string") - throw "Error: Invalid/missing mon_decimal_point property"; - - this.mon_decimal_point = properties.mon_decimal_point; - - - if (typeof properties.mon_thousands_sep != "string") - throw "Error: Invalid/missing mon_thousands_sep property"; - - this.mon_thousands_sep = properties.mon_thousands_sep; - - - if (typeof properties.mon_grouping != "string") - throw "Error: Invalid/missing mon_grouping property"; - - this.mon_grouping = properties.mon_grouping; - - - if (typeof properties.positive_sign != "string") - throw "Error: Invalid/missing positive_sign property"; - - this.positive_sign = properties.positive_sign; - - - if (typeof properties.negative_sign != "string") - throw "Error: Invalid/missing negative_sign property"; - - this.negative_sign = properties.negative_sign; - - - - if (properties.p_cs_precedes !== 0 && properties.p_cs_precedes !== 1) - throw "Error: Invalid/missing p_cs_precedes property, must be 0 or 1"; - - this.p_cs_precedes = properties.p_cs_precedes; - - - if (properties.n_cs_precedes !== 0 && properties.n_cs_precedes !== 1) - throw "Error: Invalid/missing n_cs_precedes, must be 0 or 1"; - - this.n_cs_precedes = properties.n_cs_precedes; - - - if (properties.p_sep_by_space !== 0 && - properties.p_sep_by_space !== 1 && - properties.p_sep_by_space !== 2) - throw "Error: Invalid/missing p_sep_by_space property, must be 0, 1 or 2"; - - this.p_sep_by_space = properties.p_sep_by_space; - - - if (properties.n_sep_by_space !== 0 && - properties.n_sep_by_space !== 1 && - properties.n_sep_by_space !== 2) - throw "Error: Invalid/missing n_sep_by_space property, must be 0, 1, or 2"; - - this.n_sep_by_space = properties.n_sep_by_space; - - - if (properties.p_sign_posn !== 0 && - properties.p_sign_posn !== 1 && - properties.p_sign_posn !== 2 && - properties.p_sign_posn !== 3 && - properties.p_sign_posn !== 4) - throw "Error: Invalid/missing p_sign_posn property, must be 0, 1, 2, 3 or 4"; - - this.p_sign_posn = properties.p_sign_posn; - - - if (properties.n_sign_posn !== 0 && - properties.n_sign_posn !== 1 && - properties.n_sign_posn !== 2 && - properties.n_sign_posn !== 3 && - properties.n_sign_posn !== 4) - throw "Error: Invalid/missing n_sign_posn property, must be 0, 1, 2, 3 or 4"; - - this.n_sign_posn = properties.n_sign_posn; - - - if (typeof properties.int_frac_digits != "number" && properties.int_frac_digits < 0) - throw "Error: Invalid/missing int_frac_digits property"; - - this.int_frac_digits = properties.int_frac_digits; - - - if (properties.int_p_cs_precedes !== 0 && properties.int_p_cs_precedes !== 1) - throw "Error: Invalid/missing int_p_cs_precedes property, must be 0 or 1"; - - this.int_p_cs_precedes = properties.int_p_cs_precedes; - - - if (properties.int_n_cs_precedes !== 0 && properties.int_n_cs_precedes !== 1) - throw "Error: Invalid/missing int_n_cs_precedes property, must be 0 or 1"; - - this.int_n_cs_precedes = properties.int_n_cs_precedes; - - - if (properties.int_p_sep_by_space !== 0 && - properties.int_p_sep_by_space !== 1 && - properties.int_p_sep_by_space !== 2) - throw "Error: Invalid/missing int_p_sep_by_spacev, must be 0, 1 or 2"; - - this.int_p_sep_by_space = properties.int_p_sep_by_space; - - - if (properties.int_n_sep_by_space !== 0 && - properties.int_n_sep_by_space !== 1 && - properties.int_n_sep_by_space !== 2) - throw "Error: Invalid/missing int_n_sep_by_space property, must be 0, 1, or 2"; - - this.int_n_sep_by_space = properties.int_n_sep_by_space; - - - if (properties.int_p_sign_posn !== 0 && - properties.int_p_sign_posn !== 1 && - properties.int_p_sign_posn !== 2 && - properties.int_p_sign_posn !== 3 && - properties.int_p_sign_posn !== 4) - throw "Error: Invalid/missing int_p_sign_posn property, must be 0, 1, 2, 3 or 4"; - - this.int_p_sign_posn = properties.int_p_sign_posn; - - - if (properties.int_n_sign_posn !== 0 && - properties.int_n_sign_posn !== 1 && - properties.int_n_sign_posn !== 2 && - properties.int_n_sign_posn !== 3 && - properties.int_n_sign_posn !== 4) - throw "Error: Invalid/missing int_n_sign_posn property, must be 0, 1, 2, 3 or 4"; - - this.int_n_sign_posn = properties.int_n_sign_posn; - - - // LC_TIME - - if (properties == null || typeof properties != "object") - throw "Error: Invalid/missing time locale properties"; - - - // parse the supported POSIX LC_TIME properties - - // abday - try { - this.abday = this._parseList(properties.abday, 7); - } - catch (error) { - throw "Error: Invalid abday property: " + error; - } - - // day - try { - this.day = this._parseList(properties.day, 7); - } - catch (error) { - throw "Error: Invalid day property: " + error; - } - - // abmon - try { - this.abmon = this._parseList(properties.abmon, 12); - } catch (error) { - throw "Error: Invalid abmon property: " + error; - } - - // mon - try { - this.mon = this._parseList(properties.mon, 12); - } catch (error) { - throw "Error: Invalid mon property: " + error; - } - - // d_fmt - try { - this.d_fmt = this._validateFormatString(properties.d_fmt); - } catch (error) { - throw "Error: Invalid d_fmt property: " + error; - } - - // t_fmt - try { - this.t_fmt = this._validateFormatString(properties.t_fmt); - } catch (error) { - throw "Error: Invalid t_fmt property: " + error; - } - - // d_t_fmt - try { - this.d_t_fmt = this._validateFormatString(properties.d_t_fmt); - } catch (error) { - throw "Error: Invalid d_t_fmt property: " + error; - } - - // am_pm - try { - var am_pm_strings = this._parseList(properties.am_pm, 2); - this.am = am_pm_strings[0]; - this.pm = am_pm_strings[1]; - } catch (error) { - // ignore empty/null string errors - this.am = ""; - this.pm = ""; - } - - - /** - * @public - * - * @description Returns the abbreviated name of the specified weekday. - * - * @param {integer Number} [weekdayNum] An integer between 0 and 6. Zero - * corresponds to Sunday, one to Monday, etc. If omitted the - * method will return an array of all abbreviated weekday - * names. - * - * @returns {String | String[]} The abbreviated name of the specified weekday - * or an array of all abbreviated weekday names. - * - * @throws Error on invalid argument. - */ - this.getAbbreviatedWeekdayName = function(weekdayNum) { - - if (typeof weekdayNum == "undefined" || weekdayNum === null) - return this.abday; - - if (! jsworld._isInteger(weekdayNum) || weekdayNum < 0 || weekdayNum > 6) - throw "Error: Invalid weekday argument, must be an integer [0..6]"; - - return this.abday[weekdayNum]; - }; - - - /** - * @public - * - * @description Returns the name of the specified weekday. - * - * @param {integer Number} [weekdayNum] An integer between 0 and 6. Zero - * corresponds to Sunday, one to Monday, etc. If omitted the - * method will return an array of all weekday names. - * - * @returns {String | String[]} The name of the specified weekday or an - * array of all weekday names. - * - * @throws Error on invalid argument. - */ - this.getWeekdayName = function(weekdayNum) { - - if (typeof weekdayNum == "undefined" || weekdayNum === null) - return this.day; - - if (! jsworld._isInteger(weekdayNum) || weekdayNum < 0 || weekdayNum > 6) - throw "Error: Invalid weekday argument, must be an integer [0..6]"; - - return this.day[weekdayNum]; - }; - - - /** - * @public - * - * @description Returns the abbreviated name of the specified month. - * - * @param {integer Number} [monthNum] An integer between 0 and 11. Zero - * corresponds to January, one to February, etc. If omitted the - * method will return an array of all abbreviated month names. - * - * @returns {String | String[]} The abbreviated name of the specified month - * or an array of all abbreviated month names. - * - * @throws Error on invalid argument. - */ - this.getAbbreviatedMonthName = function(monthNum) { - - if (typeof monthNum == "undefined" || monthNum === null) - return this.abmon; - - if (! jsworld._isInteger(monthNum) || monthNum < 0 || monthNum > 11) - throw "Error: Invalid month argument, must be an integer [0..11]"; - - return this.abmon[monthNum]; - }; - - - /** - * @public - * - * @description Returns the name of the specified month. - * - * @param {integer Number} [monthNum] An integer between 0 and 11. Zero - * corresponds to January, one to February, etc. If omitted the - * method will return an array of all month names. - * - * @returns {String | String[]} The name of the specified month or an array - * of all month names. - * - * @throws Error on invalid argument. - */ - this.getMonthName = function(monthNum) { - - if (typeof monthNum == "undefined" || monthNum === null) - return this.mon; - - if (! jsworld._isInteger(monthNum) || monthNum < 0 || monthNum > 11) - throw "Error: Invalid month argument, must be an integer [0..11]"; - - return this.mon[monthNum]; - }; - - - - /** - * @public - * - * @description Gets the decimal delimiter (radix) character for - * numeric quantities. - * - * @returns {String} The radix character. - */ - this.getDecimalPoint = function() { - - return this.decimal_point; - }; - - - /** - * @public - * - * @description Gets the local shorthand currency symbol. - * - * @returns {String} The currency symbol. - */ - this.getCurrencySymbol = function() { - - return this.currency_symbol; - }; - - - /** - * @public - * - * @description Gets the internaltion currency symbol (ISO-4217 code). - * - * @returns {String} The international currency symbol. - */ - this.getIntCurrencySymbol = function() { - - return this.int_curr_symbol.substring(0,3); - }; - - - /** - * @public - * - * @description Gets the position of the local (shorthand) currency - * symbol relative to the amount. Assumes a non-negative amount. - * - * @returns {Boolean} True if the symbol precedes the amount, false if - * the symbol succeeds the amount. - */ - this.currencySymbolPrecedes = function() { - - if (this.p_cs_precedes == 1) - return true; - else - return false; - }; - - - /** - * @public - * - * @description Gets the position of the international (ISO-4217 code) - * currency symbol relative to the amount. Assumes a non-negative - * amount. - * - * @returns {Boolean} True if the symbol precedes the amount, false if - * the symbol succeeds the amount. - */ - this.intCurrencySymbolPrecedes = function() { - - if (this.int_p_cs_precedes == 1) - return true; - else - return false; - - }; - - - /** - * @public - * - * @description Gets the decimal delimiter (radix) for monetary - * quantities. - * - * @returns {String} The radix character. - */ - this.getMonetaryDecimalPoint = function() { - - return this.mon_decimal_point; - }; - - - /** - * @public - * - * @description Gets the number of fractional digits for local - * (shorthand) symbol formatting. - * - * @returns {integer Number} The number of fractional digits. - */ - this.getFractionalDigits = function() { - - return this.frac_digits; - }; - - - /** - * @public - * - * @description Gets the number of fractional digits for - * international (ISO-4217 code) formatting. - * - * @returns {integer Number} The number of fractional digits. - */ - this.getIntFractionalDigits = function() { - - return this.int_frac_digits; - }; -}; - - - -/** - * @class - * Class for localised formatting of numbers. - * - *

See: - * POSIX LC_NUMERIC. - * - * - * @public - * @constructor - * @description Creates a new numeric formatter for the specified locale. - * - * @param {jsworld.Locale} locale A locale object specifying the required - * POSIX LC_NUMERIC formatting properties. - * - * @throws Error on constructor failure. - */ -jsworld.NumericFormatter = function(locale) { - - if (typeof locale != "object" || locale._className != "jsworld.Locale") - throw "Constructor error: You must provide a valid jsworld.Locale instance"; - - this.lc = locale; - - - /** - * @public - * - * @description Formats a decimal numeric value according to the preset - * locale. - * - * @param {Number|String} number The number to format. - * @param {String} [options] Options to modify the formatted output: - *

    - *
  • "^" suppress grouping - *
  • "+" force positive sign for positive amounts - *
  • "~" suppress positive/negative sign - *
  • ".n" specify decimal precision 'n' - *
- * - * @returns {String} The formatted number. - * - * @throws "Error: Invalid input" on bad input. - */ - this.format = function(number, options) { - - if (typeof number == "string") - number = jsworld._trim(number); - - if (! jsworld._isNumber(number)) - throw "Error: The input is not a number"; - - var floatAmount = parseFloat(number, 10); - - // get the required precision - var reqPrecision = jsworld._getPrecision(options); - - // round to required precision - if (reqPrecision != -1) - floatAmount = Math.round(floatAmount * Math.pow(10, reqPrecision)) / Math.pow(10, reqPrecision); - - - // convert the float number to string and parse into - // object with properties integer and fraction - var parsedAmount = jsworld._splitNumber(String(floatAmount)); - - // format integer part with grouping chars - var formattedIntegerPart; - - if (floatAmount === 0) - formattedIntegerPart = "0"; - else - formattedIntegerPart = jsworld._hasOption("^", options) ? - parsedAmount.integer : - jsworld._formatIntegerPart(parsedAmount.integer, - this.lc.grouping, - this.lc.thousands_sep); - - // format the fractional part - var formattedFractionPart = - reqPrecision != -1 ? - jsworld._formatFractionPart(parsedAmount.fraction, reqPrecision) : - parsedAmount.fraction; - - - // join the integer and fraction parts using the decimal_point property - var formattedAmount = - formattedFractionPart.length ? - formattedIntegerPart + this.lc.decimal_point + formattedFractionPart : - formattedIntegerPart; - - // prepend sign? - if (jsworld._hasOption("~", options) || floatAmount === 0) { - // suppress both '+' and '-' signs, i.e. return abs value - return formattedAmount; - } - else { - if (jsworld._hasOption("+", options) || floatAmount < 0) { - if (floatAmount > 0) - // force '+' sign for positive amounts - return "+" + formattedAmount; - else if (floatAmount < 0) - // prepend '-' sign - return "-" + formattedAmount; - else - // zero case - return formattedAmount; - } - else { - // positive amount with no '+' sign - return formattedAmount; - } - } - }; -}; - - -/** - * @class - * Class for localised formatting of dates and times. - * - *

See: - * POSIX LC_TIME. - * - * @public - * @constructor - * @description Creates a new date/time formatter for the specified locale. - * - * @param {jsworld.Locale} locale A locale object specifying the required - * POSIX LC_TIME formatting properties. - * - * @throws Error on constructor failure. - */ -jsworld.DateTimeFormatter = function(locale) { - - - if (typeof locale != "object" || locale._className != "jsworld.Locale") - throw "Constructor error: You must provide a valid jsworld.Locale instance."; - - this.lc = locale; - - - /** - * @public - * - * @description Formats a date according to the preset locale. - * - * @param {Date|String} date A valid Date object instance or a string - * containing a valid ISO-8601 formatted date, e.g. "2010-31-03" - * or "2010-03-31 23:59:59". - * - * @returns {String} The formatted date - * - * @throws Error on invalid date argument - */ - this.formatDate = function(date) { - - var d = null; - - if (typeof date == "string") { - // assume ISO-8601 date string - try { - d = jsworld.parseIsoDate(date); - } catch (error) { - // try full ISO-8601 date/time string - d = jsworld.parseIsoDateTime(date); - } - } - else if (date !== null && typeof date == "object") { - // assume ready Date object - d = date; - } - else { - throw "Error: Invalid date argument, must be a Date object or an ISO-8601 date/time string"; - } - - return this._applyFormatting(d, this.lc.d_fmt); - }; - - - /** - * @public - * - * @description Formats a time according to the preset locale. - * - * @param {Date|String} date A valid Date object instance or a string - * containing a valid ISO-8601 formatted time, e.g. "23:59:59" - * or "2010-03-31 23:59:59". - * - * @returns {String} The formatted time. - * - * @throws Error on invalid date argument. - */ - this.formatTime = function(date) { - - var d = null; - - if (typeof date == "string") { - // assume ISO-8601 time string - try { - d = jsworld.parseIsoTime(date); - } catch (error) { - // try full ISO-8601 date/time string - d = jsworld.parseIsoDateTime(date); - } - } - else if (date !== null && typeof date == "object") { - // assume ready Date object - d = date; - } - else { - throw "Error: Invalid date argument, must be a Date object or an ISO-8601 date/time string"; - } - - return this._applyFormatting(d, this.lc.t_fmt); - }; - - - /** - * @public - * - * @description Formats a date/time value according to the preset - * locale. - * - * @param {Date|String} date A valid Date object instance or a string - * containing a valid ISO-8601 formatted date/time, e.g. - * "2010-03-31 23:59:59". - * - * @returns {String} The formatted time. - * - * @throws Error on invalid argument. - */ - this.formatDateTime = function(date) { - - var d = null; - - if (typeof date == "string") { - // assume ISO-8601 format - d = jsworld.parseIsoDateTime(date); - } - else if (date !== null && typeof date == "object") { - // assume ready Date object - d = date; - } - else { - throw "Error: Invalid date argument, must be a Date object or an ISO-8601 date/time string"; - } - - return this._applyFormatting(d, this.lc.d_t_fmt); - }; - - - /** - * @private - * - * @description Apples formatting to the Date object according to the - * format string. - * - * @param {Date} d A valid Date instance. - * @param {String} s The formatting string with '%' placeholders. - * - * @returns {String} The formatted string. - */ - this._applyFormatting = function(d, s) { - - s = s.replace(/%%/g, '%'); - s = s.replace(/%a/g, this.lc.abday[d.getDay()]); - s = s.replace(/%A/g, this.lc.day[d.getDay()]); - s = s.replace(/%b/g, this.lc.abmon[d.getMonth()]); - s = s.replace(/%B/g, this.lc.mon[d.getMonth()]); - s = s.replace(/%d/g, jsworld._zeroPad(d.getDate(), 2)); - s = s.replace(/%e/g, jsworld._spacePad(d.getDate(), 2)); - s = s.replace(/%F/g, d.getFullYear() + - "-" + - jsworld._zeroPad(d.getMonth()+1, 2) + - "-" + - jsworld._zeroPad(d.getDate(), 2)); - s = s.replace(/%h/g, this.lc.abmon[d.getMonth()]); // same as %b - s = s.replace(/%H/g, jsworld._zeroPad(d.getHours(), 2)); - s = s.replace(/%I/g, jsworld._zeroPad(this._hours12(d.getHours()), 2)); - s = s.replace(/%k/g, d.getHours()); - s = s.replace(/%l/g, this._hours12(d.getHours())); - s = s.replace(/%m/g, jsworld._zeroPad(d.getMonth()+1, 2)); - s = s.replace(/%n/g, "\n"); - s = s.replace(/%M/g, jsworld._zeroPad(d.getMinutes(), 2)); - s = s.replace(/%p/g, this._getAmPm(d.getHours())); - s = s.replace(/%P/g, this._getAmPm(d.getHours()).toLocaleLowerCase()); // safe? - s = s.replace(/%R/g, jsworld._zeroPad(d.getHours(), 2) + - ":" + - jsworld._zeroPad(d.getMinutes(), 2)); - s = s.replace(/%S/g, jsworld._zeroPad(d.getSeconds(), 2)); - s = s.replace(/%T/g, jsworld._zeroPad(d.getHours(), 2) + - ":" + - jsworld._zeroPad(d.getMinutes(), 2) + - ":" + - jsworld._zeroPad(d.getSeconds(), 2)); - s = s.replace(/%w/g, this.lc.day[d.getDay()]); - s = s.replace(/%y/g, new String(d.getFullYear()).substring(2)); - s = s.replace(/%Y/g, d.getFullYear()); - - s = s.replace(/%Z/g, ""); // to do: ignored until a reliable TMZ method found - - s = s.replace(/%[a-zA-Z]/g, ""); // ignore all other % sequences - - return s; - }; - - - /** - * @private - * - * @description Does 24 to 12 hour conversion. - * - * @param {integer Number} hour24 Hour [0..23]. - * - * @returns {integer Number} Corresponding hour [1..12]. - */ - this._hours12 = function(hour24) { - - if (hour24 === 0) - return 12; // 00h is 12AM - - else if (hour24 > 12) - return hour24 - 12; // 1PM to 11PM - - else - return hour24; // 1AM to 12PM - }; - - - /** - * @private - * - * @description Gets the appropriate localised AM or PM string depending - * on the day hour. Special cases: midnight is 12AM, noon is 12PM. - * - * @param {integer Number} hour24 Hour [0..23]. - * - * @returns {String} The corresponding localised AM or PM string. - */ - this._getAmPm = function(hour24) { - - if (hour24 < 12) - return this.lc.am; - else - return this.lc.pm; - }; -}; - - - -/** - * @class Class for localised formatting of currency amounts. - * - *

See: - * POSIX LC_MONETARY. - * - * @public - * @constructor - * @description Creates a new monetary formatter for the specified locale. - * - * @param {jsworld.Locale} locale A locale object specifying the required - * POSIX LC_MONETARY formatting properties. - * @param {String} [currencyCode] Set the currency explicitly by - * passing its international ISO-4217 code, e.g. "USD", "EUR", "GBP". - * Use this optional parameter to override the default local currency - * @param {String} [altIntSymbol] Non-local currencies are formatted - * with their international ISO-4217 code to prevent ambiguity. - * Use this optional argument to force a different symbol, such as the - * currency's shorthand sign. This is mostly useful when the shorthand - * sign is both internationally recognised and identifies the currency - * uniquely (e.g. the Euro sign). - * - * @throws Error on constructor failure. - */ -jsworld.MonetaryFormatter = function(locale, currencyCode, altIntSymbol) { - - if (typeof locale != "object" || locale._className != "jsworld.Locale") - throw "Constructor error: You must provide a valid jsworld.Locale instance"; - - this.lc = locale; - - /** - * @private - * @description Lookup table to determine the fraction digits for a - * specific currency; most currencies subdivide at 1/100 (2 fractional - * digits), so we store only those that deviate from the default. - * - *

The data is from Unicode's CLDR version 1.7.0. The two currencies - * with non-decimal subunits (MGA and MRO) are marked as having no - * fractional digits as well as all currencies that have no subunits - * in circulation. - * - *

It is "hard-wired" for referential convenience and is only looked - * up when an overriding currencyCode parameter is supplied. - */ - this.currencyFractionDigits = { - "AFN" : 0, "ALL" : 0, "AMD" : 0, "BHD" : 3, "BIF" : 0, - "BYR" : 0, "CLF" : 0, "CLP" : 0, "COP" : 0, "CRC" : 0, - "DJF" : 0, "GNF" : 0, "GYD" : 0, "HUF" : 0, "IDR" : 0, - "IQD" : 0, "IRR" : 0, "ISK" : 0, "JOD" : 3, "JPY" : 0, - "KMF" : 0, "KRW" : 0, "KWD" : 3, "LAK" : 0, "LBP" : 0, - "LYD" : 3, "MGA" : 0, "MMK" : 0, "MNT" : 0, "MRO" : 0, - "MUR" : 0, "OMR" : 3, "PKR" : 0, "PYG" : 0, "RSD" : 0, - "RWF" : 0, "SLL" : 0, "SOS" : 0, "STD" : 0, "SYP" : 0, - "TND" : 3, "TWD" : 0, "TZS" : 0, "UGX" : 0, "UZS" : 0, - "VND" : 0, "VUV" : 0, "XAF" : 0, "XOF" : 0, "XPF" : 0, - "YER" : 0, "ZMK" : 0 - }; - - - // optional currencyCode argument? - if (typeof currencyCode == "string") { - // user wanted to override the local currency - this.currencyCode = currencyCode.toUpperCase(); - - // must override the frac digits too, for some - // currencies have 0, 2 or 3! - var numDigits = this.currencyFractionDigits[this.currencyCode]; - if (typeof numDigits != "number") - numDigits = 2; // default for most currencies - this.lc.frac_digits = numDigits; - this.lc.int_frac_digits = numDigits; - } - else { - // use local currency - this.currencyCode = this.lc.int_curr_symbol.substring(0,3).toUpperCase(); - } - - // extract intl. currency separator - this.intSep = this.lc.int_curr_symbol.charAt(3); - - // flag local or intl. sign formatting? - if (this.currencyCode == this.lc.int_curr_symbol.substring(0,3)) { - // currency matches the local one? -> - // formatting with local symbol and parameters - this.internationalFormatting = false; - this.curSym = this.lc.currency_symbol; - } - else { - // currency doesn't match the local -> - - // do we have an overriding currency symbol? - if (typeof altIntSymbol == "string") { - // -> force formatting with local parameters, using alt symbol - this.curSym = altIntSymbol; - this.internationalFormatting = false; - } - else { - // -> force formatting with intl. sign and parameters - this.internationalFormatting = true; - } - } - - - /** - * @public - * - * @description Gets the currency symbol used in formatting. - * - * @returns {String} The currency symbol. - */ - this.getCurrencySymbol = function() { - - return this.curSym; - }; - - - /** - * @public - * - * @description Gets the position of the currency symbol relative to - * the amount. Assumes a non-negative amount and local formatting. - * - * @param {String} intFlag Optional flag to force international - * formatting by passing the string "i". - * - * @returns {Boolean} True if the symbol precedes the amount, false if - * the symbol succeeds the amount. - */ - this.currencySymbolPrecedes = function(intFlag) { - - if (typeof intFlag == "string" && intFlag == "i") { - // international formatting was forced - if (this.lc.int_p_cs_precedes == 1) - return true; - else - return false; - - } - else { - // check whether local formatting is on or off - if (this.internationalFormatting) { - if (this.lc.int_p_cs_precedes == 1) - return true; - else - return false; - } - else { - if (this.lc.p_cs_precedes == 1) - return true; - else - return false; - } - } - }; - - - /** - * @public - * - * @description Gets the decimal delimiter (radix) used in formatting. - * - * @returns {String} The radix character. - */ - this.getDecimalPoint = function() { - - return this.lc.mon_decimal_point; - }; - - - /** - * @public - * - * @description Gets the number of fractional digits. Assumes local - * formatting. - * - * @param {String} intFlag Optional flag to force international - * formatting by passing the string "i". - * - * @returns {integer Number} The number of fractional digits. - */ - this.getFractionalDigits = function(intFlag) { - - if (typeof intFlag == "string" && intFlag == "i") { - // international formatting was forced - return this.lc.int_frac_digits; - } - else { - // check whether local formatting is on or off - if (this.internationalFormatting) - return this.lc.int_frac_digits; - else - return this.lc.frac_digits; - } - }; - - - /** - * @public - * - * @description Formats a monetary amount according to the preset - * locale. - * - *

-	 * For local currencies the native shorthand symbol will be used for
-	 * formatting.
-	 * Example:
-	 *        locale is en_US
-	 *        currency is USD
-	 *        -> the "$" symbol will be used, e.g. $123.45
-	 *        
-	 * For non-local currencies the international ISO-4217 code will be
-	 * used for formatting.
-	 * Example:
-	 *       locale is en_US (which has USD as currency)
-	 *       currency is EUR
-	 *       -> the ISO three-letter code will be used, e.g. EUR 123.45
-	 *
-	 * If the currency is non-local, but an alternative currency symbol was
-	 * provided, this will be used instead.
-	 * Example
-	 *       locale is en_US (which has USD as currency)
-	 *       currency is EUR
-	 *       an alternative symbol is provided - "€"
-	 *       -> the alternative symbol will be used, e.g. €123.45
-	 * 
- * - * @param {Number|String} amount The amount to format as currency. - * @param {String} [options] Options to modify the formatted output: - *
    - *
  • "^" suppress grouping - *
  • "!" suppress the currency symbol - *
  • "~" suppress the currency symbol and the sign (positive or negative) - *
  • "i" force international sign (ISO-4217 code) formatting - *
  • ".n" specify decimal precision - * - * @returns The formatted currency amount as string. - * - * @throws "Error: Invalid amount" on bad amount. - */ - this.format = function(amount, options) { - - // if the amount is passed as string, check that it parses to a float - var floatAmount; - - if (typeof amount == "string") { - amount = jsworld._trim(amount); - floatAmount = parseFloat(amount); - - if (typeof floatAmount != "number" || isNaN(floatAmount)) - throw "Error: Amount string not a number"; - } - else if (typeof amount == "number") { - floatAmount = amount; - } - else { - throw "Error: Amount not a number"; - } - - // get the required precision, ".n" option arg overrides default locale config - var reqPrecision = jsworld._getPrecision(options); - - if (reqPrecision == -1) { - if (this.internationalFormatting || jsworld._hasOption("i", options)) - reqPrecision = this.lc.int_frac_digits; - else - reqPrecision = this.lc.frac_digits; - } - - // round - floatAmount = Math.round(floatAmount * Math.pow(10, reqPrecision)) / Math.pow(10, reqPrecision); - - - // convert the float amount to string and parse into - // object with properties integer and fraction - var parsedAmount = jsworld._splitNumber(String(floatAmount)); - - // format integer part with grouping chars - var formattedIntegerPart; - - if (floatAmount === 0) - formattedIntegerPart = "0"; - else - formattedIntegerPart = jsworld._hasOption("^", options) ? - parsedAmount.integer : - jsworld._formatIntegerPart(parsedAmount.integer, - this.lc.mon_grouping, - this.lc.mon_thousands_sep); - - - // format the fractional part - var formattedFractionPart; - - if (reqPrecision == -1) { - // pad fraction with trailing zeros accoring to default locale [int_]frac_digits - if (this.internationalFormatting || jsworld._hasOption("i", options)) - formattedFractionPart = - jsworld._formatFractionPart(parsedAmount.fraction, this.lc.int_frac_digits); - else - formattedFractionPart = - jsworld._formatFractionPart(parsedAmount.fraction, this.lc.frac_digits); - } - else { - // pad fraction with trailing zeros according to optional format parameter - formattedFractionPart = - jsworld._formatFractionPart(parsedAmount.fraction, reqPrecision); - } - - - // join integer and decimal parts using the mon_decimal_point property - var quantity; - - if (this.lc.frac_digits > 0 || formattedFractionPart.length) - quantity = formattedIntegerPart + this.lc.mon_decimal_point + formattedFractionPart; - else - quantity = formattedIntegerPart; - - - // do final formatting with sign and symbol - if (jsworld._hasOption("~", options)) { - return quantity; - } - else { - var suppressSymbol = jsworld._hasOption("!", options) ? true : false; - - var sign = floatAmount < 0 ? "-" : "+"; - - if (this.internationalFormatting || jsworld._hasOption("i", options)) { - - // format with ISO-4217 code (suppressed or not) - if (suppressSymbol) - return this._formatAsInternationalCurrencyWithNoSym(sign, quantity); - else - return this._formatAsInternationalCurrency(sign, quantity); - } - else { - // format with local currency code (suppressed or not) - if (suppressSymbol) - return this._formatAsLocalCurrencyWithNoSym(sign, quantity); - else - return this._formatAsLocalCurrency(sign, quantity); - } - } - }; - - - /** - * @private - * - * @description Assembles the final string with sign, separator and symbol as local - * currency. - * - * @param {String} sign The amount sign: "+" or "-". - * @param {String} q The formatted quantity (unsigned). - * - * @returns {String} The final formatted string. - */ - this._formatAsLocalCurrency = function (sign, q) { - - // assemble final formatted amount by going over all possible value combinations of: - // sign {+,-} , sign position {0,1,2,3,4} , separator {0,1,2} , symbol position {0,1} - if (sign == "+") { - - // parentheses - if (this.lc.p_sign_posn === 0 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 0) { - return "(" + q + this.curSym + ")"; - } - else if (this.lc.p_sign_posn === 0 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 1) { - return "(" + this.curSym + q + ")"; - } - else if (this.lc.p_sign_posn === 0 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 0) { - return "(" + q + " " + this.curSym + ")"; - } - else if (this.lc.p_sign_posn === 0 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 1) { - return "(" + this.curSym + " " + q + ")"; - } - - // sign before q + sym - else if (this.lc.p_sign_posn === 1 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 0) { - return this.lc.positive_sign + q + this.curSym; - } - else if (this.lc.p_sign_posn === 1 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 1) { - return this.lc.positive_sign + this.curSym + q; - } - else if (this.lc.p_sign_posn === 1 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 0) { - return this.lc.positive_sign + q + " " + this.curSym; - } - else if (this.lc.p_sign_posn === 1 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 1) { - return this.lc.positive_sign + this.curSym + " " + q; - } - else if (this.lc.p_sign_posn === 1 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 0) { - return this.lc.positive_sign + " " + q + this.curSym; - } - else if (this.lc.p_sign_posn === 1 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 1) { - return this.lc.positive_sign + " " + this.curSym + q; - } - - // sign after q + sym - else if (this.lc.p_sign_posn === 2 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 0) { - return q + this.curSym + this.lc.positive_sign; - } - else if (this.lc.p_sign_posn === 2 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 1) { - return this.curSym + q + this.lc.positive_sign; - } - else if (this.lc.p_sign_posn === 2 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 0) { - return q + " " + this.curSym + this.lc.positive_sign; - } - else if (this.lc.p_sign_posn === 2 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 1) { - return this.curSym + " " + q + this.lc.positive_sign; - } - else if (this.lc.p_sign_posn === 2 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 0) { - return q + this.curSym + " " + this.lc.positive_sign; - } - else if (this.lc.p_sign_posn === 2 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 1) { - return this.curSym + q + " " + this.lc.positive_sign; - } - - // sign before sym - else if (this.lc.p_sign_posn === 3 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 0) { - return q + this.lc.positive_sign + this.curSym; - } - else if (this.lc.p_sign_posn === 3 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 1) { - return this.lc.positive_sign + this.curSym + q; - } - else if (this.lc.p_sign_posn === 3 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 0) { - return q + " " + this.lc.positive_sign + this.curSym; - } - else if (this.lc.p_sign_posn === 3 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 1) { - return this.lc.positive_sign + this.curSym + " " + q; - } - else if (this.lc.p_sign_posn === 3 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 0) { - return q + this.lc.positive_sign + " " + this.curSym; - } - else if (this.lc.p_sign_posn === 3 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 1) { - return this.lc.positive_sign + " " + this.curSym + q; - } - - // sign after symbol - else if (this.lc.p_sign_posn === 4 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 0) { - return q + this.curSym + this.lc.positive_sign; - } - else if (this.lc.p_sign_posn === 4 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 1) { - return this.curSym + this.lc.positive_sign + q; - } - else if (this.lc.p_sign_posn === 4 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 0) { - return q + " " + this.curSym + this.lc.positive_sign; - } - else if (this.lc.p_sign_posn === 4 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 1) { - return this.curSym + this.lc.positive_sign + " " + q; - } - else if (this.lc.p_sign_posn === 4 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 0) { - return q + this.curSym + " " + this.lc.positive_sign; - } - else if (this.lc.p_sign_posn === 4 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 1) { - return this.curSym + " " + this.lc.positive_sign + q; - } - - } - else if (sign == "-") { - - // parentheses enclose q + sym - if (this.lc.n_sign_posn === 0 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 0) { - return "(" + q + this.curSym + ")"; - } - else if (this.lc.n_sign_posn === 0 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 1) { - return "(" + this.curSym + q + ")"; - } - else if (this.lc.n_sign_posn === 0 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 0) { - return "(" + q + " " + this.curSym + ")"; - } - else if (this.lc.n_sign_posn === 0 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 1) { - return "(" + this.curSym + " " + q + ")"; - } - - // sign before q + sym - else if (this.lc.n_sign_posn === 1 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 0) { - return this.lc.negative_sign + q + this.curSym; - } - else if (this.lc.n_sign_posn === 1 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 1) { - return this.lc.negative_sign + this.curSym + q; - } - else if (this.lc.n_sign_posn === 1 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 0) { - return this.lc.negative_sign + q + " " + this.curSym; - } - else if (this.lc.n_sign_posn === 1 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 1) { - return this.lc.negative_sign + this.curSym + " " + q; - } - else if (this.lc.n_sign_posn === 1 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 0) { - return this.lc.negative_sign + " " + q + this.curSym; - } - else if (this.lc.n_sign_posn === 1 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 1) { - return this.lc.negative_sign + " " + this.curSym + q; - } - - // sign after q + sym - else if (this.lc.n_sign_posn === 2 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 0) { - return q + this.curSym + this.lc.negative_sign; - } - else if (this.lc.n_sign_posn === 2 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 1) { - return this.curSym + q + this.lc.negative_sign; - } - else if (this.lc.n_sign_posn === 2 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 0) { - return q + " " + this.curSym + this.lc.negative_sign; - } - else if (this.lc.n_sign_posn === 2 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 1) { - return this.curSym + " " + q + this.lc.negative_sign; - } - else if (this.lc.n_sign_posn === 2 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 0) { - return q + this.curSym + " " + this.lc.negative_sign; - } - else if (this.lc.n_sign_posn === 2 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 1) { - return this.curSym + q + " " + this.lc.negative_sign; - } - - // sign before sym - else if (this.lc.n_sign_posn === 3 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 0) { - return q + this.lc.negative_sign + this.curSym; - } - else if (this.lc.n_sign_posn === 3 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 1) { - return this.lc.negative_sign + this.curSym + q; - } - else if (this.lc.n_sign_posn === 3 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 0) { - return q + " " + this.lc.negative_sign + this.curSym; - } - else if (this.lc.n_sign_posn === 3 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 1) { - return this.lc.negative_sign + this.curSym + " " + q; - } - else if (this.lc.n_sign_posn === 3 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 0) { - return q + this.lc.negative_sign + " " + this.curSym; - } - else if (this.lc.n_sign_posn === 3 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 1) { - return this.lc.negative_sign + " " + this.curSym + q; - } - - // sign after symbol - else if (this.lc.n_sign_posn === 4 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 0) { - return q + this.curSym + this.lc.negative_sign; - } - else if (this.lc.n_sign_posn === 4 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 1) { - return this.curSym + this.lc.negative_sign + q; - } - else if (this.lc.n_sign_posn === 4 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 0) { - return q + " " + this.curSym + this.lc.negative_sign; - } - else if (this.lc.n_sign_posn === 4 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 1) { - return this.curSym + this.lc.negative_sign + " " + q; - } - else if (this.lc.n_sign_posn === 4 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 0) { - return q + this.curSym + " " + this.lc.negative_sign; - } - else if (this.lc.n_sign_posn === 4 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 1) { - return this.curSym + " " + this.lc.negative_sign + q; - } - } - - // throw error if we fall through - throw "Error: Invalid POSIX LC MONETARY definition"; - }; - - - /** - * @private - * - * @description Assembles the final string with sign, separator and ISO-4217 - * currency code. - * - * @param {String} sign The amount sign: "+" or "-". - * @param {String} q The formatted quantity (unsigned). - * - * @returns {String} The final formatted string. - */ - this._formatAsInternationalCurrency = function (sign, q) { - - // assemble the final formatted amount by going over all possible value combinations of: - // sign {+,-} , sign position {0,1,2,3,4} , separator {0,1,2} , symbol position {0,1} - - if (sign == "+") { - - // parentheses - if (this.lc.int_p_sign_posn === 0 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 0) { - return "(" + q + this.currencyCode + ")"; - } - else if (this.lc.int_p_sign_posn === 0 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 1) { - return "(" + this.currencyCode + q + ")"; - } - else if (this.lc.int_p_sign_posn === 0 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 0) { - return "(" + q + this.intSep + this.currencyCode + ")"; - } - else if (this.lc.int_p_sign_posn === 0 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 1) { - return "(" + this.currencyCode + this.intSep + q + ")"; - } - - // sign before q + sym - else if (this.lc.int_p_sign_posn === 1 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 0) { - return this.lc.positive_sign + q + this.currencyCode; - } - else if (this.lc.int_p_sign_posn === 1 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 1) { - return this.lc.positive_sign + this.currencyCode + q; - } - else if (this.lc.int_p_sign_posn === 1 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 0) { - return this.lc.positive_sign + q + this.intSep + this.currencyCode; - } - else if (this.lc.int_p_sign_posn === 1 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 1) { - return this.lc.positive_sign + this.currencyCode + this.intSep + q; - } - else if (this.lc.int_p_sign_posn === 1 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 0) { - return this.lc.positive_sign + this.intSep + q + this.currencyCode; - } - else if (this.lc.int_p_sign_posn === 1 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 1) { - return this.lc.positive_sign + this.intSep + this.currencyCode + q; - } - - // sign after q + sym - else if (this.lc.int_p_sign_posn === 2 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 0) { - return q + this.currencyCode + this.lc.positive_sign; - } - else if (this.lc.int_p_sign_posn === 2 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 1) { - return this.currencyCode + q + this.lc.positive_sign; - } - else if (this.lc.int_p_sign_posn === 2 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 0) { - return q + this.intSep + this.currencyCode + this.lc.positive_sign; - } - else if (this.lc.int_p_sign_posn === 2 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 1) { - return this.currencyCode + this.intSep + q + this.lc.positive_sign; - } - else if (this.lc.int_p_sign_posn === 2 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 0) { - return q + this.currencyCode + this.intSep + this.lc.positive_sign; - } - else if (this.lc.int_p_sign_posn === 2 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 1) { - return this.currencyCode + q + this.intSep + this.lc.positive_sign; - } - - // sign before sym - else if (this.lc.int_p_sign_posn === 3 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 0) { - return q + this.lc.positive_sign + this.currencyCode; - } - else if (this.lc.int_p_sign_posn === 3 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 1) { - return this.lc.positive_sign + this.currencyCode + q; - } - else if (this.lc.int_p_sign_posn === 3 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 0) { - return q + this.intSep + this.lc.positive_sign + this.currencyCode; - } - else if (this.lc.int_p_sign_posn === 3 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 1) { - return this.lc.positive_sign + this.currencyCode + this.intSep + q; - } - else if (this.lc.int_p_sign_posn === 3 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 0) { - return q + this.lc.positive_sign + this.intSep + this.currencyCode; - } - else if (this.lc.int_p_sign_posn === 3 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 1) { - return this.lc.positive_sign + this.intSep + this.currencyCode + q; - } - - // sign after symbol - else if (this.lc.int_p_sign_posn === 4 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 0) { - return q + this.currencyCode + this.lc.positive_sign; - } - else if (this.lc.int_p_sign_posn === 4 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 1) { - return this.currencyCode + this.lc.positive_sign + q; - } - else if (this.lc.int_p_sign_posn === 4 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 0) { - return q + this.intSep + this.currencyCode + this.lc.positive_sign; - } - else if (this.lc.int_p_sign_posn === 4 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 1) { - return this.currencyCode + this.lc.positive_sign + this.intSep + q; - } - else if (this.lc.int_p_sign_posn === 4 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 0) { - return q + this.currencyCode + this.intSep + this.lc.positive_sign; - } - else if (this.lc.int_p_sign_posn === 4 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 1) { - return this.currencyCode + this.intSep + this.lc.positive_sign + q; - } - - } - else if (sign == "-") { - - // parentheses enclose q + sym - if (this.lc.int_n_sign_posn === 0 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 0) { - return "(" + q + this.currencyCode + ")"; - } - else if (this.lc.int_n_sign_posn === 0 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 1) { - return "(" + this.currencyCode + q + ")"; - } - else if (this.lc.int_n_sign_posn === 0 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 0) { - return "(" + q + this.intSep + this.currencyCode + ")"; - } - else if (this.lc.int_n_sign_posn === 0 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 1) { - return "(" + this.currencyCode + this.intSep + q + ")"; - } - - // sign before q + sym - else if (this.lc.int_n_sign_posn === 1 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 0) { - return this.lc.negative_sign + q + this.currencyCode; - } - else if (this.lc.int_n_sign_posn === 1 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 1) { - return this.lc.negative_sign + this.currencyCode + q; - } - else if (this.lc.int_n_sign_posn === 1 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 0) { - return this.lc.negative_sign + q + this.intSep + this.currencyCode; - } - else if (this.lc.int_n_sign_posn === 1 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 1) { - return this.lc.negative_sign + this.currencyCode + this.intSep + q; - } - else if (this.lc.int_n_sign_posn === 1 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 0) { - return this.lc.negative_sign + this.intSep + q + this.currencyCode; - } - else if (this.lc.int_n_sign_posn === 1 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 1) { - return this.lc.negative_sign + this.intSep + this.currencyCode + q; - } - - // sign after q + sym - else if (this.lc.int_n_sign_posn === 2 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 0) { - return q + this.currencyCode + this.lc.negative_sign; - } - else if (this.lc.int_n_sign_posn === 2 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 1) { - return this.currencyCode + q + this.lc.negative_sign; - } - else if (this.lc.int_n_sign_posn === 2 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 0) { - return q + this.intSep + this.currencyCode + this.lc.negative_sign; - } - else if (this.lc.int_n_sign_posn === 2 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 1) { - return this.currencyCode + this.intSep + q + this.lc.negative_sign; - } - else if (this.lc.int_n_sign_posn === 2 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 0) { - return q + this.currencyCode + this.intSep + this.lc.negative_sign; - } - else if (this.lc.int_n_sign_posn === 2 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 1) { - return this.currencyCode + q + this.intSep + this.lc.negative_sign; - } - - // sign before sym - else if (this.lc.int_n_sign_posn === 3 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 0) { - return q + this.lc.negative_sign + this.currencyCode; - } - else if (this.lc.int_n_sign_posn === 3 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 1) { - return this.lc.negative_sign + this.currencyCode + q; - } - else if (this.lc.int_n_sign_posn === 3 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 0) { - return q + this.intSep + this.lc.negative_sign + this.currencyCode; - } - else if (this.lc.int_n_sign_posn === 3 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 1) { - return this.lc.negative_sign + this.currencyCode + this.intSep + q; - } - else if (this.lc.int_n_sign_posn === 3 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 0) { - return q + this.lc.negative_sign + this.intSep + this.currencyCode; - } - else if (this.lc.int_n_sign_posn === 3 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 1) { - return this.lc.negative_sign + this.intSep + this.currencyCode + q; - } - - // sign after symbol - else if (this.lc.int_n_sign_posn === 4 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 0) { - return q + this.currencyCode + this.lc.negative_sign; - } - else if (this.lc.int_n_sign_posn === 4 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 1) { - return this.currencyCode + this.lc.negative_sign + q; - } - else if (this.lc.int_n_sign_posn === 4 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 0) { - return q + this.intSep + this.currencyCode + this.lc.negative_sign; - } - else if (this.lc.int_n_sign_posn === 4 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 1) { - return this.currencyCode + this.lc.negative_sign + this.intSep + q; - } - else if (this.lc.int_n_sign_posn === 4 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 0) { - return q + this.currencyCode + this.intSep + this.lc.negative_sign; - } - else if (this.lc.int_n_sign_posn === 4 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 1) { - return this.currencyCode + this.intSep + this.lc.negative_sign + q; - } - } - - // throw error if we fall through - throw "Error: Invalid POSIX LC MONETARY definition"; - }; - - - /** - * @private - * - * @description Assembles the final string with sign and separator, but suppress the - * local currency symbol. - * - * @param {String} sign The amount sign: "+" or "-". - * @param {String} q The formatted quantity (unsigned). - * - * @returns {String} The final formatted string - */ - this._formatAsLocalCurrencyWithNoSym = function (sign, q) { - - // assemble the final formatted amount by going over all possible value combinations of: - // sign {+,-} , sign position {0,1,2,3,4} , separator {0,1,2} , symbol position {0,1} - - if (sign == "+") { - - // parentheses - if (this.lc.p_sign_posn === 0) { - return "(" + q + ")"; - } - - // sign before q + sym - else if (this.lc.p_sign_posn === 1 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 0) { - return this.lc.positive_sign + q; - } - else if (this.lc.p_sign_posn === 1 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 1) { - return this.lc.positive_sign + q; - } - else if (this.lc.p_sign_posn === 1 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 0) { - return this.lc.positive_sign + q; - } - else if (this.lc.p_sign_posn === 1 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 1) { - return this.lc.positive_sign + q; - } - else if (this.lc.p_sign_posn === 1 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 0) { - return this.lc.positive_sign + " " + q; - } - else if (this.lc.p_sign_posn === 1 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 1) { - return this.lc.positive_sign + " " + q; - } - - // sign after q + sym - else if (this.lc.p_sign_posn === 2 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 0) { - return q + this.lc.positive_sign; - } - else if (this.lc.p_sign_posn === 2 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 1) { - return q + this.lc.positive_sign; - } - else if (this.lc.p_sign_posn === 2 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 0) { - return q + " " + this.lc.positive_sign; - } - else if (this.lc.p_sign_posn === 2 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 1) { - return q + this.lc.positive_sign; - } - else if (this.lc.p_sign_posn === 2 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 0) { - return q + this.lc.positive_sign; - } - else if (this.lc.p_sign_posn === 2 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 1) { - return q + " " + this.lc.positive_sign; - } - - // sign before sym - else if (this.lc.p_sign_posn === 3 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 0) { - return q + this.lc.positive_sign; - } - else if (this.lc.p_sign_posn === 3 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 1) { - return this.lc.positive_sign + q; - } - else if (this.lc.p_sign_posn === 3 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 0) { - return q + " " + this.lc.positive_sign; - } - else if (this.lc.p_sign_posn === 3 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 1) { - return this.lc.positive_sign + " " + q; - } - else if (this.lc.p_sign_posn === 3 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 0) { - return q + this.lc.positive_sign; - } - else if (this.lc.p_sign_posn === 3 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 1) { - return this.lc.positive_sign + " " + q; - } - - // sign after symbol - else if (this.lc.p_sign_posn === 4 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 0) { - return q + this.lc.positive_sign; - } - else if (this.lc.p_sign_posn === 4 && this.lc.p_sep_by_space === 0 && this.lc.p_cs_precedes === 1) { - return this.lc.positive_sign + q; - } - else if (this.lc.p_sign_posn === 4 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 0) { - return q + " " + this.lc.positive_sign; - } - else if (this.lc.p_sign_posn === 4 && this.lc.p_sep_by_space === 1 && this.lc.p_cs_precedes === 1) { - return this.lc.positive_sign + " " + q; - } - else if (this.lc.p_sign_posn === 4 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 0) { - return q + " " + this.lc.positive_sign; - } - else if (this.lc.p_sign_posn === 4 && this.lc.p_sep_by_space === 2 && this.lc.p_cs_precedes === 1) { - return this.lc.positive_sign + q; - } - - } - else if (sign == "-") { - - // parentheses enclose q + sym - if (this.lc.n_sign_posn === 0) { - return "(" + q + ")"; - } - - // sign before q + sym - else if (this.lc.n_sign_posn === 1 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 0) { - return this.lc.negative_sign + q; - } - else if (this.lc.n_sign_posn === 1 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 1) { - return this.lc.negative_sign + q; - } - else if (this.lc.n_sign_posn === 1 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 0) { - return this.lc.negative_sign + q; - } - else if (this.lc.n_sign_posn === 1 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 1) { - return this.lc.negative_sign + " " + q; - } - else if (this.lc.n_sign_posn === 1 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 0) { - return this.lc.negative_sign + " " + q; - } - else if (this.lc.n_sign_posn === 1 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 1) { - return this.lc.negative_sign + " " + q; - } - - // sign after q + sym - else if (this.lc.n_sign_posn === 2 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 0) { - return q + this.lc.negative_sign; - } - else if (this.lc.n_sign_posn === 2 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 1) { - return q + this.lc.negative_sign; - } - else if (this.lc.n_sign_posn === 2 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 0) { - return q + " " + this.lc.negative_sign; - } - else if (this.lc.n_sign_posn === 2 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 1) { - return q + this.lc.negative_sign; - } - else if (this.lc.n_sign_posn === 2 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 0) { - return q + " " + this.lc.negative_sign; - } - else if (this.lc.n_sign_posn === 2 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 1) { - return q + " " + this.lc.negative_sign; - } - - // sign before sym - else if (this.lc.n_sign_posn === 3 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 0) { - return q + this.lc.negative_sign; - } - else if (this.lc.n_sign_posn === 3 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 1) { - return this.lc.negative_sign + q; - } - else if (this.lc.n_sign_posn === 3 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 0) { - return q + " " + this.lc.negative_sign; - } - else if (this.lc.n_sign_posn === 3 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 1) { - return this.lc.negative_sign + " " + q; - } - else if (this.lc.n_sign_posn === 3 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 0) { - return q + this.lc.negative_sign; - } - else if (this.lc.n_sign_posn === 3 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 1) { - return this.lc.negative_sign + " " + q; - } - - // sign after symbol - else if (this.lc.n_sign_posn === 4 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 0) { - return q + this.lc.negative_sign; - } - else if (this.lc.n_sign_posn === 4 && this.lc.n_sep_by_space === 0 && this.lc.n_cs_precedes === 1) { - return this.lc.negative_sign + q; - } - else if (this.lc.n_sign_posn === 4 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 0) { - return q + " " + this.lc.negative_sign; - } - else if (this.lc.n_sign_posn === 4 && this.lc.n_sep_by_space === 1 && this.lc.n_cs_precedes === 1) { - return this.lc.negative_sign + " " + q; - } - else if (this.lc.n_sign_posn === 4 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 0) { - return q + " " + this.lc.negative_sign; - } - else if (this.lc.n_sign_posn === 4 && this.lc.n_sep_by_space === 2 && this.lc.n_cs_precedes === 1) { - return this.lc.negative_sign + q; - } - } - - // throw error if we fall through - throw "Error: Invalid POSIX LC MONETARY definition"; - }; - - - /** - * @private - * - * @description Assembles the final string with sign and separator, but suppress - * the ISO-4217 currency code. - * - * @param {String} sign The amount sign: "+" or "-". - * @param {String} q The formatted quantity (unsigned). - * - * @returns {String} The final formatted string. - */ - this._formatAsInternationalCurrencyWithNoSym = function (sign, q) { - - // assemble the final formatted amount by going over all possible value combinations of: - // sign {+,-} , sign position {0,1,2,3,4} , separator {0,1,2} , symbol position {0,1} - - if (sign == "+") { - - // parentheses - if (this.lc.int_p_sign_posn === 0) { - return "(" + q + ")"; - } - - // sign before q + sym - else if (this.lc.int_p_sign_posn === 1 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 0) { - return this.lc.positive_sign + q; - } - else if (this.lc.int_p_sign_posn === 1 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 1) { - return this.lc.positive_sign + q; - } - else if (this.lc.int_p_sign_posn === 1 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 0) { - return this.lc.positive_sign + q; - } - else if (this.lc.int_p_sign_posn === 1 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 1) { - return this.lc.positive_sign + this.intSep + q; - } - else if (this.lc.int_p_sign_posn === 1 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 0) { - return this.lc.positive_sign + this.intSep + q; - } - else if (this.lc.int_p_sign_posn === 1 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 1) { - return this.lc.positive_sign + this.intSep + q; - } - - // sign after q + sym - else if (this.lc.int_p_sign_posn === 2 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 0) { - return q + this.lc.positive_sign; - } - else if (this.lc.int_p_sign_posn === 2 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 1) { - return q + this.lc.positive_sign; - } - else if (this.lc.int_p_sign_posn === 2 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 0) { - return q + this.intSep + this.lc.positive_sign; - } - else if (this.lc.int_p_sign_posn === 2 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 1) { - return q + this.lc.positive_sign; - } - else if (this.lc.int_p_sign_posn === 2 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 0) { - return q + this.intSep + this.lc.positive_sign; - } - else if (this.lc.int_p_sign_posn === 2 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 1) { - return q + this.intSep + this.lc.positive_sign; - } - - // sign before sym - else if (this.lc.int_p_sign_posn === 3 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 0) { - return q + this.lc.positive_sign; - } - else if (this.lc.int_p_sign_posn === 3 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 1) { - return this.lc.positive_sign + q; - } - else if (this.lc.int_p_sign_posn === 3 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 0) { - return q + this.intSep + this.lc.positive_sign; - } - else if (this.lc.int_p_sign_posn === 3 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 1) { - return this.lc.positive_sign + this.intSep + q; - } - else if (this.lc.int_p_sign_posn === 3 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 0) { - return q + this.lc.positive_sign; - } - else if (this.lc.int_p_sign_posn === 3 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 1) { - return this.lc.positive_sign + this.intSep + q; - } - - // sign after symbol - else if (this.lc.int_p_sign_posn === 4 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 0) { - return q + this.lc.positive_sign; - } - else if (this.lc.int_p_sign_posn === 4 && this.lc.int_p_sep_by_space === 0 && this.lc.int_p_cs_precedes === 1) { - return this.lc.positive_sign + q; - } - else if (this.lc.int_p_sign_posn === 4 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 0) { - return q + this.intSep + this.lc.positive_sign; - } - else if (this.lc.int_p_sign_posn === 4 && this.lc.int_p_sep_by_space === 1 && this.lc.int_p_cs_precedes === 1) { - return this.lc.positive_sign + this.intSep + q; - } - else if (this.lc.int_p_sign_posn === 4 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 0) { - return q + this.intSep + this.lc.positive_sign; - } - else if (this.lc.int_p_sign_posn === 4 && this.lc.int_p_sep_by_space === 2 && this.lc.int_p_cs_precedes === 1) { - return this.lc.positive_sign + q; - } - - } - else if (sign == "-") { - - // parentheses enclose q + sym - if (this.lc.int_n_sign_posn === 0) { - return "(" + q + ")"; - } - - // sign before q + sym - else if (this.lc.int_n_sign_posn === 1 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 0) { - return this.lc.negative_sign + q; - } - else if (this.lc.int_n_sign_posn === 1 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 1) { - return this.lc.negative_sign + q; - } - else if (this.lc.int_n_sign_posn === 1 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 0) { - return this.lc.negative_sign + q; - } - else if (this.lc.int_n_sign_posn === 1 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 1) { - return this.lc.negative_sign + this.intSep + q; - } - else if (this.lc.int_n_sign_posn === 1 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 0) { - return this.lc.negative_sign + this.intSep + q; - } - else if (this.lc.int_n_sign_posn === 1 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 1) { - return this.lc.negative_sign + this.intSep + q; - } - - // sign after q + sym - else if (this.lc.int_n_sign_posn === 2 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 0) { - return q + this.lc.negative_sign; - } - else if (this.lc.int_n_sign_posn === 2 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 1) { - return q + this.lc.negative_sign; - } - else if (this.lc.int_n_sign_posn === 2 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 0) { - return q + this.intSep + this.lc.negative_sign; - } - else if (this.lc.int_n_sign_posn === 2 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 1) { - return q + this.lc.negative_sign; - } - else if (this.lc.int_n_sign_posn === 2 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 0) { - return q + this.intSep + this.lc.negative_sign; - } - else if (this.lc.int_n_sign_posn === 2 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 1) { - return q + this.intSep + this.lc.negative_sign; - } - - // sign before sym - else if (this.lc.int_n_sign_posn === 3 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 0) { - return q + this.lc.negative_sign; - } - else if (this.lc.int_n_sign_posn === 3 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 1) { - return this.lc.negative_sign + q; - } - else if (this.lc.int_n_sign_posn === 3 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 0) { - return q + this.intSep + this.lc.negative_sign; - } - else if (this.lc.int_n_sign_posn === 3 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 1) { - return this.lc.negative_sign + this.intSep + q; - } - else if (this.lc.int_n_sign_posn === 3 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 0) { - return q + this.lc.negative_sign; - } - else if (this.lc.int_n_sign_posn === 3 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 1) { - return this.lc.negative_sign + this.intSep + q; - } - - // sign after symbol - else if (this.lc.int_n_sign_posn === 4 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 0) { - return q + this.lc.negative_sign; - } - else if (this.lc.int_n_sign_posn === 4 && this.lc.int_n_sep_by_space === 0 && this.lc.int_n_cs_precedes === 1) { - return this.lc.negative_sign + q; - } - else if (this.lc.int_n_sign_posn === 4 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 0) { - return q + this.intSep + this.lc.negative_sign; - } - else if (this.lc.int_n_sign_posn === 4 && this.lc.int_n_sep_by_space === 1 && this.lc.int_n_cs_precedes === 1) { - return this.lc.negative_sign + this.intSep + q; - } - else if (this.lc.int_n_sign_posn === 4 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 0) { - return q + this.intSep + this.lc.negative_sign; - } - else if (this.lc.int_n_sign_posn === 4 && this.lc.int_n_sep_by_space === 2 && this.lc.int_n_cs_precedes === 1) { - return this.lc.negative_sign + q; - } - } - - // throw error if we fall through - throw "Error: Invalid POSIX LC_MONETARY definition"; - }; -}; - - -/** - * @class - * Class for parsing localised number strings. - * - * @public - * @constructor - * @description Creates a new numeric parser for the specified locale. - * - * @param {jsworld.Locale} locale A locale object specifying the required - * POSIX LC_NUMERIC formatting properties. - * - * @throws Error on constructor failure. - */ -jsworld.NumericParser = function(locale) { - - if (typeof locale != "object" || locale._className != "jsworld.Locale") - throw "Constructor error: You must provide a valid jsworld.Locale instance"; - - this.lc = locale; - - - /** - * @public - * - * @description Parses a numeric string formatted according to the - * preset locale. Leading and trailing whitespace is ignored; the number - * may also be formatted without thousands separators. - * - * @param {String} formattedNumber The formatted number. - * - * @returns {Number} The parsed number. - * - * @throws Error on a parse exception. - */ - this.parse = function(formattedNumber) { - - if (typeof formattedNumber != "string") - throw "Parse error: Argument must be a string"; - - // trim whitespace - var s = jsworld._trim(formattedNumber); - - // remove any thousand separator symbols - s = jsworld._stringReplaceAll(formattedNumber, this.lc.thousands_sep, ""); - - // replace any local decimal point symbols with the symbol used - // in JavaScript "." - s = jsworld._stringReplaceAll(s, this.lc.decimal_point, "."); - - // test if the string represents a number - if (jsworld._isNumber(s)) - return parseFloat(s, 10); - else - throw "Parse error: Invalid number string"; - }; -}; - - -/** - * @class - * Class for parsing localised date and time strings. - * - * @public - * @constructor - * @description Creates a new date/time parser for the specified locale. - * - * @param {jsworld.Locale} locale A locale object specifying the required - * POSIX LC_TIME formatting properties. - * - * @throws Error on constructor failure. - */ -jsworld.DateTimeParser = function(locale) { - - if (typeof locale != "object" || locale._className != "jsworld.Locale") - throw "Constructor error: You must provide a valid jsworld.Locale instance."; - - this.lc = locale; - - - /** - * @public - * - * @description Parses a time string formatted according to the - * POSIX LC_TIME t_fmt property of the preset locale. - * - * @param {String} formattedTime The formatted time. - * - * @returns {String} The parsed time in ISO-8601 format (HH:MM:SS), e.g. - * "23:59:59". - * - * @throws Error on a parse exception. - */ - this.parseTime = function(formattedTime) { - - if (typeof formattedTime != "string") - throw "Parse error: Argument must be a string"; - - var dt = this._extractTokens(this.lc.t_fmt, formattedTime); - - var timeDefined = false; - - if (dt.hour !== null && dt.minute !== null && dt.second !== null) { - timeDefined = true; - } - else if (dt.hourAmPm !== null && dt.am !== null && dt.minute !== null && dt.second !== null) { - if (dt.am) { - // AM [12(midnight), 1 .. 11] - if (dt.hourAmPm == 12) - dt.hour = 0; - else - dt.hour = parseInt(dt.hourAmPm, 10); - } - else { - // PM [12(noon), 1 .. 11] - if (dt.hourAmPm == 12) - dt.hour = 12; - else - dt.hour = parseInt(dt.hourAmPm, 10) + 12; - } - timeDefined = true; - } - - if (timeDefined) - return jsworld._zeroPad(dt.hour, 2) + - ":" + - jsworld._zeroPad(dt.minute, 2) + - ":" + - jsworld._zeroPad(dt.second, 2); - else - throw "Parse error: Invalid/ambiguous time string"; - }; - - - /** - * @public - * - * @description Parses a date string formatted according to the - * POSIX LC_TIME d_fmt property of the preset locale. - * - * @param {String} formattedDate The formatted date, must be valid. - * - * @returns {String} The parsed date in ISO-8601 format (YYYY-MM-DD), - * e.g. "2010-03-31". - * - * @throws Error on a parse exception. - */ - this.parseDate = function(formattedDate) { - - if (typeof formattedDate != "string") - throw "Parse error: Argument must be a string"; - - var dt = this._extractTokens(this.lc.d_fmt, formattedDate); - - var dateDefined = false; - - if (dt.year !== null && dt.month !== null && dt.day !== null) { - dateDefined = true; - } - - if (dateDefined) - return jsworld._zeroPad(dt.year, 4) + - "-" + - jsworld._zeroPad(dt.month, 2) + - "-" + - jsworld._zeroPad(dt.day, 2); - else - throw "Parse error: Invalid date string"; - }; - - - /** - * @public - * - * @description Parses a date/time string formatted according to the - * POSIX LC_TIME d_t_fmt property of the preset locale. - * - * @param {String} formattedDateTime The formatted date/time, must be - * valid. - * - * @returns {String} The parsed date/time in ISO-8601 format - * (YYYY-MM-DD HH:MM:SS), e.g. "2010-03-31 23:59:59". - * - * @throws Error on a parse exception. - */ - this.parseDateTime = function(formattedDateTime) { - - if (typeof formattedDateTime != "string") - throw "Parse error: Argument must be a string"; - - var dt = this._extractTokens(this.lc.d_t_fmt, formattedDateTime); - - var timeDefined = false; - var dateDefined = false; - - if (dt.hour !== null && dt.minute !== null && dt.second !== null) { - timeDefined = true; - } - else if (dt.hourAmPm !== null && dt.am !== null && dt.minute !== null && dt.second !== null) { - if (dt.am) { - // AM [12(midnight), 1 .. 11] - if (dt.hourAmPm == 12) - dt.hour = 0; - else - dt.hour = parseInt(dt.hourAmPm, 10); - } - else { - // PM [12(noon), 1 .. 11] - if (dt.hourAmPm == 12) - dt.hour = 12; - else - dt.hour = parseInt(dt.hourAmPm, 10) + 12; - } - timeDefined = true; - } - - if (dt.year !== null && dt.month !== null && dt.day !== null) { - dateDefined = true; - } - - if (dateDefined && timeDefined) - return jsworld._zeroPad(dt.year, 4) + - "-" + - jsworld._zeroPad(dt.month, 2) + - "-" + - jsworld._zeroPad(dt.day, 2) + - " " + - jsworld._zeroPad(dt.hour, 2) + - ":" + - jsworld._zeroPad(dt.minute, 2) + - ":" + - jsworld._zeroPad(dt.second, 2); - else - throw "Parse error: Invalid/ambiguous date/time string"; - }; - - - /** - * @private - * - * @description Parses a string according to the specified format - * specification. - * - * @param {String} fmtSpec The format specification, e.g. "%I:%M:%S %p". - * @param {String} s The string to parse. - * - * @returns {object} An object with set properties year, month, day, - * hour, minute and second if the corresponding values are - * found in the parsed string. - * - * @throws Error on a parse exception. - */ - this._extractTokens = function(fmtSpec, s) { - - // the return object containing the parsed date/time properties - var dt = { - // for date and date/time strings - "year" : null, - "month" : null, - "day" : null, - - // for time and date/time strings - "hour" : null, - "hourAmPm" : null, - "am" : null, - "minute" : null, - "second" : null, - - // used internally only - "weekday" : null - }; - - - // extract and process each token in the date/time spec - while (fmtSpec.length > 0) { - - // Do we have a valid "%\w" placeholder in stream? - if (fmtSpec.charAt(0) == "%" && fmtSpec.charAt(1) != "") { - - // get placeholder - var placeholder = fmtSpec.substring(0,2); - - if (placeholder == "%%") { - // escaped '%'' - s = s.substring(1); - } - else if (placeholder == "%a") { - // abbreviated weekday name - for (var i = 0; i < this.lc.abday.length; i++) { - - if (jsworld._stringStartsWith(s, this.lc.abday[i])) { - dt.weekday = i; - s = s.substring(this.lc.abday[i].length); - break; - } - } - - if (dt.weekday === null) - throw "Parse error: Unrecognised abbreviated weekday name (%a)"; - } - else if (placeholder == "%A") { - // weekday name - for (var i = 0; i < this.lc.day.length; i++) { - - if (jsworld._stringStartsWith(s, this.lc.day[i])) { - dt.weekday = i; - s = s.substring(this.lc.day[i].length); - break; - } - } - - if (dt.weekday === null) - throw "Parse error: Unrecognised weekday name (%A)"; - } - else if (placeholder == "%b" || placeholder == "%h") { - // abbreviated month name - for (var i = 0; i < this.lc.abmon.length; i++) { - - if (jsworld._stringStartsWith(s, this.lc.abmon[i])) { - dt.month = i + 1; - s = s.substring(this.lc.abmon[i].length); - break; - } - } - - if (dt.month === null) - throw "Parse error: Unrecognised abbreviated month name (%b)"; - } - else if (placeholder == "%B") { - // month name - for (var i = 0; i < this.lc.mon.length; i++) { - - if (jsworld._stringStartsWith(s, this.lc.mon[i])) { - dt.month = i + 1; - s = s.substring(this.lc.mon[i].length); - break; - } - } - - if (dt.month === null) - throw "Parse error: Unrecognised month name (%B)"; - } - else if (placeholder == "%d") { - // day of the month [01..31] - if (/^0[1-9]|[1-2][0-9]|3[0-1]/.test(s)) { - dt.day = parseInt(s.substring(0,2), 10); - s = s.substring(2); - } - else - throw "Parse error: Unrecognised day of the month (%d)"; - } - else if (placeholder == "%e") { - // day of the month [1..31] - - // Note: if %e is leading in fmt string -> space padded! - - var day = s.match(/^\s?(\d{1,2})/); - dt.day = parseInt(day, 10); - - if (isNaN(dt.day) || dt.day < 1 || dt.day > 31) - throw "Parse error: Unrecognised day of the month (%e)"; - - s = s.substring(day.length); - } - else if (placeholder == "%F") { - // equivalent to %Y-%m-%d (ISO-8601 date format) - - // year [nnnn] - if (/^\d\d\d\d/.test(s)) { - dt.year = parseInt(s.substring(0,4), 10); - s = s.substring(4); - } - else { - throw "Parse error: Unrecognised date (%F)"; - } - - // - - if (jsworld._stringStartsWith(s, "-")) - s = s.substring(1); - else - throw "Parse error: Unrecognised date (%F)"; - - // month [01..12] - if (/^0[1-9]|1[0-2]/.test(s)) { - dt.month = parseInt(s.substring(0,2), 10); - s = s.substring(2); - } - else - throw "Parse error: Unrecognised date (%F)"; - - // - - if (jsworld._stringStartsWith(s, "-")) - s = s.substring(1); - else - throw "Parse error: Unrecognised date (%F)"; - - // day of the month [01..31] - if (/^0[1-9]|[1-2][0-9]|3[0-1]/.test(s)) { - dt.day = parseInt(s.substring(0,2), 10); - s = s.substring(2); - } - else - throw "Parse error: Unrecognised date (%F)"; - } - else if (placeholder == "%H") { - // hour [00..23] - if (/^[0-1][0-9]|2[0-3]/.test(s)) { - dt.hour = parseInt(s.substring(0,2), 10); - s = s.substring(2); - } - else - throw "Parse error: Unrecognised hour (%H)"; - } - else if (placeholder == "%I") { - // hour [01..12] - if (/^0[1-9]|1[0-2]/.test(s)) { - dt.hourAmPm = parseInt(s.substring(0,2), 10); - s = s.substring(2); - } - else - throw "Parse error: Unrecognised hour (%I)"; - } - else if (placeholder == "%k") { - // hour [0..23] - var h = s.match(/^(\d{1,2})/); - dt.hour = parseInt(h, 10); - - if (isNaN(dt.hour) || dt.hour < 0 || dt.hour > 23) - throw "Parse error: Unrecognised hour (%k)"; - - s = s.substring(h.length); - } - else if (placeholder == "%l") { - // hour AM/PM [1..12] - var h = s.match(/^(\d{1,2})/); - dt.hourAmPm = parseInt(h, 10); - - if (isNaN(dt.hourAmPm) || dt.hourAmPm < 1 || dt.hourAmPm > 12) - throw "Parse error: Unrecognised hour (%l)"; - - s = s.substring(h.length); - } - else if (placeholder == "%m") { - // month [01..12] - if (/^0[1-9]|1[0-2]/.test(s)) { - dt.month = parseInt(s.substring(0,2), 10); - s = s.substring(2); - } - else - throw "Parse error: Unrecognised month (%m)"; - } - else if (placeholder == "%M") { - // minute [00..59] - if (/^[0-5][0-9]/.test(s)) { - dt.minute = parseInt(s.substring(0,2), 10); - s = s.substring(2); - } - else - throw "Parse error: Unrecognised minute (%M)"; - } - else if (placeholder == "%n") { - // new line - - if (s.charAt(0) == "\n") - s = s.substring(1); - else - throw "Parse error: Unrecognised new line (%n)"; - } - else if (placeholder == "%p") { - // locale's equivalent of AM/PM - if (jsworld._stringStartsWith(s, this.lc.am)) { - dt.am = true; - s = s.substring(this.lc.am.length); - } - else if (jsworld._stringStartsWith(s, this.lc.pm)) { - dt.am = false; - s = s.substring(this.lc.pm.length); - } - else - throw "Parse error: Unrecognised AM/PM value (%p)"; - } - else if (placeholder == "%P") { - // same as %p but forced lower case - if (jsworld._stringStartsWith(s, this.lc.am.toLowerCase())) { - dt.am = true; - s = s.substring(this.lc.am.length); - } - else if (jsworld._stringStartsWith(s, this.lc.pm.toLowerCase())) { - dt.am = false; - s = s.substring(this.lc.pm.length); - } - else - throw "Parse error: Unrecognised AM/PM value (%P)"; - } - else if (placeholder == "%R") { - // same as %H:%M - - // hour [00..23] - if (/^[0-1][0-9]|2[0-3]/.test(s)) { - dt.hour = parseInt(s.substring(0,2), 10); - s = s.substring(2); - } - else - throw "Parse error: Unrecognised time (%R)"; - - // : - if (jsworld._stringStartsWith(s, ":")) - s = s.substring(1); - else - throw "Parse error: Unrecognised time (%R)"; - - // minute [00..59] - if (/^[0-5][0-9]/.test(s)) { - dt.minute = parseInt(s.substring(0,2), 10); - s = s.substring(2); - } - else - throw "Parse error: Unrecognised time (%R)"; - - } - else if (placeholder == "%S") { - // second [00..59] - if (/^[0-5][0-9]/.test(s)) { - dt.second = parseInt(s.substring(0,2), 10); - s = s.substring(2); - } - else - throw "Parse error: Unrecognised second (%S)"; - } - else if (placeholder == "%T") { - // same as %H:%M:%S - - // hour [00..23] - if (/^[0-1][0-9]|2[0-3]/.test(s)) { - dt.hour = parseInt(s.substring(0,2), 10); - s = s.substring(2); - } - else - throw "Parse error: Unrecognised time (%T)"; - - // : - if (jsworld._stringStartsWith(s, ":")) - s = s.substring(1); - else - throw "Parse error: Unrecognised time (%T)"; - - // minute [00..59] - if (/^[0-5][0-9]/.test(s)) { - dt.minute = parseInt(s.substring(0,2), 10); - s = s.substring(2); - } - else - throw "Parse error: Unrecognised time (%T)"; - - // : - if (jsworld._stringStartsWith(s, ":")) - s = s.substring(1); - else - throw "Parse error: Unrecognised time (%T)"; - - // second [00..59] - if (/^[0-5][0-9]/.test(s)) { - dt.second = parseInt(s.substring(0,2), 10); - s = s.substring(2); - } - else - throw "Parse error: Unrecognised time (%T)"; - } - else if (placeholder == "%w") { - // weekday [0..6] - if (/^\d/.test(s)) { - dt.weekday = parseInt(s.substring(0,1), 10); - s = s.substring(1); - } - else - throw "Parse error: Unrecognised weekday number (%w)"; - } - else if (placeholder == "%y") { - // year [00..99] - if (/^\d\d/.test(s)) { - var year2digits = parseInt(s.substring(0,2), 10); - - // this conversion to year[nnnn] is arbitrary!!! - if (year2digits > 50) - dt.year = 1900 + year2digits; - else - dt.year = 2000 + year2digits; - - s = s.substring(2); - } - else - throw "Parse error: Unrecognised year (%y)"; - } - else if (placeholder == "%Y") { - // year [nnnn] - if (/^\d\d\d\d/.test(s)) { - dt.year = parseInt(s.substring(0,4), 10); - s = s.substring(4); - } - else - throw "Parse error: Unrecognised year (%Y)"; - } - - else if (placeholder == "%Z") { - // time-zone place holder is not supported - - if (fmtSpec.length === 0) - break; // ignore rest of fmt spec - } - - // remove the spec placeholder that was just parsed - fmtSpec = fmtSpec.substring(2); - } - else { - // If we don't have a placeholder, the chars - // at pos. 0 of format spec and parsed string must match - - // Note: Space chars treated 1:1 ! - - if (fmtSpec.charAt(0) != s.charAt(0)) - throw "Parse error: Unexpected symbol \"" + s.charAt(0) + "\" in date/time string"; - - fmtSpec = fmtSpec.substring(1); - s = s.substring(1); - } - } - - // parsing finished, return composite date/time object - return dt; - }; -}; - - -/** - * @class - * Class for parsing localised currency amount strings. - * - * @public - * @constructor - * @description Creates a new monetary parser for the specified locale. - * - * @param {jsworld.Locale} locale A locale object specifying the required - * POSIX LC_MONETARY formatting properties. - * - * @throws Error on constructor failure. - */ -jsworld.MonetaryParser = function(locale) { - - if (typeof locale != "object" || locale._className != "jsworld.Locale") - throw "Constructor error: You must provide a valid jsworld.Locale instance"; - - - this.lc = locale; - - - /** - * @public - * - * @description Parses a currency amount string formatted according to - * the preset locale. Leading and trailing whitespace is ignored; the - * amount may also be formatted without thousands separators. Both - * the local (shorthand) symbol and the ISO 4217 code are accepted to - * designate the currency in the formatted amount. - * - * @param {String} formattedCurrency The formatted currency amount. - * - * @returns {Number} The parsed amount. - * - * @throws Error on a parse exception. - */ - this.parse = function(formattedCurrency) { - - if (typeof formattedCurrency != "string") - throw "Parse error: Argument must be a string"; - - // Detect the format type and remove the currency symbol - var symbolType = this._detectCurrencySymbolType(formattedCurrency); - - var formatType, s; - - if (symbolType == "local") { - formatType = "local"; - s = formattedCurrency.replace(this.lc.getCurrencySymbol(), ""); - } - else if (symbolType == "int") { - formatType = "int"; - s = formattedCurrency.replace(this.lc.getIntCurrencySymbol(), ""); - } - else if (symbolType == "none") { - formatType = "local"; // assume local - s = formattedCurrency; - } - else - throw "Parse error: Internal assert failure"; - - // Remove any thousands separators - s = jsworld._stringReplaceAll(s, this.lc.mon_thousands_sep, ""); - - // Replace any local radix char with JavaScript's "." - s = s.replace(this.lc.mon_decimal_point, "."); - - // Remove all whitespaces - s = s.replace(/\s*/g, ""); - - // Remove any local non-negative sign - s = this._removeLocalNonNegativeSign(s, formatType); - - // Replace any local minus sign with JavaScript's "-" and put - // it in front of the amount if necessary - // (special parentheses rule checked too) - s = this._normaliseNegativeSign(s, formatType); - - // Finally, we should be left with a bare parsable decimal number - if (jsworld._isNumber(s)) - return parseFloat(s, 10); - else - throw "Parse error: Invalid currency amount string"; - }; - - - /** - * @private - * - * @description Tries to detect the symbol type used in the specified - * formatted currency string: local(shorthand), - * international (ISO-4217 code) or none. - * - * @param {String} formattedCurrency The the formatted currency string. - * - * @return {String} With possible values "local", "int" or "none". - */ - this._detectCurrencySymbolType = function(formattedCurrency) { - - // Check for whichever sign (int/local) is longer first - // to cover cases such as MOP/MOP$ and ZAR/R - - if (this.lc.getCurrencySymbol().length > this.lc.getIntCurrencySymbol().length) { - - if (formattedCurrency.indexOf(this.lc.getCurrencySymbol()) != -1) - return "local"; - else if (formattedCurrency.indexOf(this.lc.getIntCurrencySymbol()) != -1) - return "int"; - else - return "none"; - } - else { - if (formattedCurrency.indexOf(this.lc.getIntCurrencySymbol()) != -1) - return "int"; - else if (formattedCurrency.indexOf(this.lc.getCurrencySymbol()) != -1) - return "local"; - else - return "none"; - } - }; - - - /** - * @private - * - * @description Removes a local non-negative sign in a formatted - * currency string if it is found. This is done according to the - * locale properties p_sign_posn and int_p_sign_posn. - * - * @param {String} s The input string. - * @param {String} formatType With possible values "local" or "int". - * - * @returns {String} The processed string. - */ - this._removeLocalNonNegativeSign = function(s, formatType) { - - s = s.replace(this.lc.positive_sign, ""); - - // check for enclosing parentheses rule - if (((formatType == "local" && this.lc.p_sign_posn === 0) || - (formatType == "int" && this.lc.int_p_sign_posn === 0) ) && - /\(\d+\.?\d*\)/.test(s)) { - s = s.replace("(", ""); - s = s.replace(")", ""); - } - - return s; - }; - - - /** - * @private - * - * @description Replaces a local negative sign with the standard - * JavaScript minus ("-") sign placed in the correct position - * (preceding the amount). This is done according to the locale - * properties for negative sign symbol and relative position. - * - * @param {String} s The input string. - * @param {String} formatType With possible values "local" or "int". - * - * @returns {String} The processed string. - */ - this._normaliseNegativeSign = function(s, formatType) { - - // replace local negative symbol with JavaScript's "-" - s = s.replace(this.lc.negative_sign, "-"); - - // check for enclosing parentheses rule and replace them - // with negative sign before the amount - if ((formatType == "local" && this.lc.n_sign_posn === 0) || - (formatType == "int" && this.lc.int_n_sign_posn === 0) ) { - - if (/^\(\d+\.?\d*\)$/.test(s)) { - - s = s.replace("(", ""); - s = s.replace(")", ""); - return "-" + s; - } - } - - // check for rule negative sign succeeding the amount - if (formatType == "local" && this.lc.n_sign_posn == 2 || - formatType == "int" && this.lc.int_n_sign_posn == 2 ) { - - if (/^\d+\.?\d*-$/.test(s)) { - s = s.replace("-", ""); - return "-" + s; - } - } - - // check for rule cur. sym. succeeds and sign adjacent - if (formatType == "local" && this.lc.n_cs_precedes === 0 && this.lc.n_sign_posn == 3 || - formatType == "local" && this.lc.n_cs_precedes === 0 && this.lc.n_sign_posn == 4 || - formatType == "int" && this.lc.int_n_cs_precedes === 0 && this.lc.int_n_sign_posn == 3 || - formatType == "int" && this.lc.int_n_cs_precedes === 0 && this.lc.int_n_sign_posn == 4 ) { - - if (/^\d+\.?\d*-$/.test(s)) { - s = s.replace("-", ""); - return "-" + s; - } - } - - return s; - }; -}; - -// end-of-file diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/uglify-hangs2.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/uglify-hangs2.js deleted file mode 100644 index 4e9f96721d..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/tmp/uglify-hangs2.js +++ /dev/null @@ -1,166 +0,0 @@ -jsworld.Locale = function(properties) { - - // LC_NUMERIC - - - this.frac_digits = properties.frac_digits; - - - // may be empty string/null for currencies with no fractional part - if (properties.mon_decimal_point === null || properties.mon_decimal_point == "") { - - if (this.frac_digits > 0) - throw "Error: Undefined mon_decimal_point property"; - else - properties.mon_decimal_point = ""; - } - - if (typeof properties.mon_decimal_point != "string") - throw "Error: Invalid/missing mon_decimal_point property"; - - this.mon_decimal_point = properties.mon_decimal_point; - - - if (typeof properties.mon_thousands_sep != "string") - throw "Error: Invalid/missing mon_thousands_sep property"; - - this.mon_thousands_sep = properties.mon_thousands_sep; - - - if (typeof properties.mon_grouping != "string") - throw "Error: Invalid/missing mon_grouping property"; - - this.mon_grouping = properties.mon_grouping; - - - if (typeof properties.positive_sign != "string") - throw "Error: Invalid/missing positive_sign property"; - - this.positive_sign = properties.positive_sign; - - - if (typeof properties.negative_sign != "string") - throw "Error: Invalid/missing negative_sign property"; - - this.negative_sign = properties.negative_sign; - - - if (properties.p_cs_precedes !== 0 && properties.p_cs_precedes !== 1) - throw "Error: Invalid/missing p_cs_precedes property, must be 0 or 1"; - - this.p_cs_precedes = properties.p_cs_precedes; - - - if (properties.n_cs_precedes !== 0 && properties.n_cs_precedes !== 1) - throw "Error: Invalid/missing n_cs_precedes, must be 0 or 1"; - - this.n_cs_precedes = properties.n_cs_precedes; - - - if (properties.p_sep_by_space !== 0 && - properties.p_sep_by_space !== 1 && - properties.p_sep_by_space !== 2) - throw "Error: Invalid/missing p_sep_by_space property, must be 0, 1 or 2"; - - this.p_sep_by_space = properties.p_sep_by_space; - - - if (properties.n_sep_by_space !== 0 && - properties.n_sep_by_space !== 1 && - properties.n_sep_by_space !== 2) - throw "Error: Invalid/missing n_sep_by_space property, must be 0, 1, or 2"; - - this.n_sep_by_space = properties.n_sep_by_space; - - - if (properties.p_sign_posn !== 0 && - properties.p_sign_posn !== 1 && - properties.p_sign_posn !== 2 && - properties.p_sign_posn !== 3 && - properties.p_sign_posn !== 4) - throw "Error: Invalid/missing p_sign_posn property, must be 0, 1, 2, 3 or 4"; - - this.p_sign_posn = properties.p_sign_posn; - - - if (properties.n_sign_posn !== 0 && - properties.n_sign_posn !== 1 && - properties.n_sign_posn !== 2 && - properties.n_sign_posn !== 3 && - properties.n_sign_posn !== 4) - throw "Error: Invalid/missing n_sign_posn property, must be 0, 1, 2, 3 or 4"; - - this.n_sign_posn = properties.n_sign_posn; - - - if (typeof properties.int_frac_digits != "number" && properties.int_frac_digits < 0) - throw "Error: Invalid/missing int_frac_digits property"; - - this.int_frac_digits = properties.int_frac_digits; - - - if (properties.int_p_cs_precedes !== 0 && properties.int_p_cs_precedes !== 1) - throw "Error: Invalid/missing int_p_cs_precedes property, must be 0 or 1"; - - this.int_p_cs_precedes = properties.int_p_cs_precedes; - - - if (properties.int_n_cs_precedes !== 0 && properties.int_n_cs_precedes !== 1) - throw "Error: Invalid/missing int_n_cs_precedes property, must be 0 or 1"; - - this.int_n_cs_precedes = properties.int_n_cs_precedes; - - - if (properties.int_p_sep_by_space !== 0 && - properties.int_p_sep_by_space !== 1 && - properties.int_p_sep_by_space !== 2) - throw "Error: Invalid/missing int_p_sep_by_spacev, must be 0, 1 or 2"; - - this.int_p_sep_by_space = properties.int_p_sep_by_space; - - - if (properties.int_n_sep_by_space !== 0 && - properties.int_n_sep_by_space !== 1 && - properties.int_n_sep_by_space !== 2) - throw "Error: Invalid/missing int_n_sep_by_space property, must be 0, 1, or 2"; - - this.int_n_sep_by_space = properties.int_n_sep_by_space; - - - if (properties.int_p_sign_posn !== 0 && - properties.int_p_sign_posn !== 1 && - properties.int_p_sign_posn !== 2 && - properties.int_p_sign_posn !== 3 && - properties.int_p_sign_posn !== 4) - throw "Error: Invalid/missing int_p_sign_posn property, must be 0, 1, 2, 3 or 4"; - - this.int_p_sign_posn = properties.int_p_sign_posn; - - - if (properties.int_n_sign_posn !== 0 && - properties.int_n_sign_posn !== 1 && - properties.int_n_sign_posn !== 2 && - properties.int_n_sign_posn !== 3 && - properties.int_n_sign_posn !== 4) - throw "Error: Invalid/missing int_n_sign_posn property, must be 0, 1, 2, 3 or 4"; - - this.int_n_sign_posn = properties.int_n_sign_posn; - - - // LC_TIME - - if (properties == null || typeof properties != "object") - throw "Error: Invalid/missing time locale properties"; - - - // parse the supported POSIX LC_TIME properties - - // abday - try { - this.abday = this._parseList(properties.abday, 7); - } - catch (error) { - throw "Error: Invalid abday property: " + error; - } - -} diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/uglify-js.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/uglify-js.js deleted file mode 100644 index 4305e232ee..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/uglify-js.js +++ /dev/null @@ -1,17 +0,0 @@ -//convienence function(src, [options]); -function uglify(orig_code, options){ - options || (options = {}); - var jsp = uglify.parser; - var pro = uglify.uglify; - - var ast = jsp.parse(orig_code, options.strict_semicolons); // parse code and get the initial AST - ast = pro.ast_mangle(ast, options.mangle_options); // get a new AST with mangled names - ast = pro.ast_squeeze(ast, options.squeeze_options); // get an AST with compression optimizations - var final_code = pro.gen_code(ast, options.gen_options); // compressed code here - return final_code; -}; - -uglify.parser = require("./lib/parse-js"); -uglify.uglify = require("./lib/process"); - -module.exports = uglify \ No newline at end of file diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/.npmignore b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/.npmignore deleted file mode 100644 index 1eba800f80..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/.npmignore +++ /dev/null @@ -1,11 +0,0 @@ -npm-debug.log -node_modules -.*.swp -.lock-* -build - -bench -doc -examples -test - diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/.travis.yml b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/.travis.yml deleted file mode 100644 index 973586683f..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/.travis.yml +++ /dev/null @@ -1,5 +0,0 @@ -language: node_js -npm_args: --ws:native -node_js: - - "0.8" - - "0.10" diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/History.md b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/History.md deleted file mode 100644 index 63cf0ea6a9..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/History.md +++ /dev/null @@ -1,312 +0,0 @@ -v0.4.31 - September 23th, 2013 -===================== - -* Component support - -v0.4.30 - August 30th, 2013 -===================== - -* BufferedAmount could be undefined, default to 0 [TooTallNate] -* Support protocols as second argument and options as third [TooTallNate] -* Proper browserify shim [mcollina] -* Broadcasting example in README [stefanocudini] - -v0.4.29 - August 23th, 2013 -===================== -* Small clean up of the Node 0.11 support by using NAN from the NPM registry [kkoopa] -* Support for custom `Agent`'s through the options. [gramakri] & [TooTallNate] -* Support for custom headers through the options [3rd-Eden] -* Added a `gypfile` flag to the package.json for compiled module discovery [wolfeidau] - -v0.4.28 - August 16th, 2013 -===================== -* Node 0.11 support. [kkoopa] -* Authorization headers are sent when basic auth is used in the url [jcrugzz] -* Origin header will now include the port number [Jason Plum] -* Race condition fixed where data was received before the readyState was updated. [saschagehlich] - -v0.4.27 - June 27th, 2013 -===================== -* Frames are no longer masked in `wscat`. [slaskis] -* Don't retrain reference to large slab buffers. [jmatthewsr-msi] -* Don't use Buffer.byteLength for ArrayBuffer's. [Anthony Pesch] -* Fix browser field in package.json. [shtylman] -* Client-side certificate support & documentation improvements. [Lukas Berns] -* WebSocket readyState's is added to the prototype for spec compatiblity. [BallBearing] -* Use Object.defineProperty. [arlolra] -* Autodetect ArrayBuffers as binary when sending. [BallBearing] -* Check instanceof Buffer for binary data. [arlolra] -* Emit the close event before destroying the internal socket. [3rd-Eden] -* Don't setup multiply timeouts for one connection. [AndreasMadsen] -* Allow support for binding to ethereal port. [wpreul] -* Fix broken terminate reference. [3rd-Eden] -* Misc node 0.10 test fixes and documentation improvements. [3rd-Eden] -* Ensure ssl options are propagated to request. [einaros] -* Add 'Host' and 'Origin' to request header. [Lars-Magnus Skog] -* Subprotocol support. [kanaka] -* Honor ArrayBufferView's byteOffset when sending. [Anthony Pesch] -* Added target attribute for events. [arlolra] - -v0.4.26 - Skipped -===================== - -v0.4.25 - December 17th, 2012 -===================== -* Removed install.js. [shtylman] -* Added browser field to package.json. [shtylman] -* Support overwriting host header. [Raynos] -* Emit 'listening' also with custom http server. [sebiq] - -v0.4.24 - December 6th, 2012 -===================== -* Yet another intermediate release, to not delay minor features any longer. -* Native support installation issues further circumvented. [einaros] - -v0.4.23 - November 19th, 2012 -===================== -* Service release - last before major upgrade. -* Changes default host from 127.0.0.1 to 0.0.0.0. [einaros] - -v0.4.22 - October 3rd, 2012 -===================== -* clear failsafe cleanup timeout once cleanup is called [AndreasMadsen] -* added w3c compatible CloseEvent for onclose / addEventListener("close", ...). [einaros] -* fix the sub protocol header handler [sonnyp] -* fix unhandled exception if socket closes and 'error' is emitted [jmatthewsr-ms] - -v0.4.21 - July 14th, 2012 -===================== -* Emit error if server reponds with anything other than status code 101. [einaros] -* Added 'headers' event to server. [rauchg] -* path.exists moved to fs.exists. [blakmatrix] - -v0.4.20 - June 26th, 2012 -===================== -* node v0.8.0 compatibility release. - -v0.4.19 - June 19th, 2012 -===================== -* Change sender to merge buffers for relatively small payloads, may improve perf in some cases [einaros] -* Avoid EventEmitter for Receiver classes. As above this may improve perf. [einaros] -* Renamed fallback files from the somewhat misleading '*Windows'. [einaros] - -v0.4.18 - June 14th 2012 -===================== -* Fixed incorrect md5 digest encoding in Hixie handshake [nicokaiser] -* Added example of use with Express 3 [einaros] -* Change installation procedure to not require --ws:native to build native extensions. They will now build if a compiler is available. [einaros] - -v0.4.17 - June 13th 2012 -===================== -* Improve error handling during connection handshaking [einaros] -* Ensure that errors are caught also after connection teardown [nicokaiser] -* Update 'mocha' version to 1.1.0. [einaros] -* Stop showing 'undefined' for some error logs. [tricknotes] -* Update 'should' version to 0.6.3 [tricknotes] - -v0.4.16 - June 1st 2012 -===================== -* Build fix for Windows. [einaros] - -v0.4.15 - May 20th 2012 -===================== -* Enable fauxe streaming for hixie tansport. [einaros] -* Allow hixie sender to deal with buffers. [einaros/pigne] -* Allow error code 1011. [einaros] -* Fix framing for empty packets (empty pings and pongs might break). [einaros] -* Improve error and close handling, to avoid connections lingering in CLOSING state. [einaros] - -v0.4.14 - Apr 30th 2012 -===================== -* use node-gyp instead of node-waf [TooTallNate] -* remove old windows compatibility makefile, and silently fall back to native modules [einaros] -* ensure connection status [nicokaiser] -* websocket client updated to use port 443 by default for wss:// connections [einaros] -* support unix sockets [kschzt] - -v0.4.13 - Apr 12th 2012 -===================== - -* circumvent node 0.6+ related memory leak caused by Object.defineProperty [nicokaiser] -* improved error handling, improving stability in massive load use cases [nicokaiser] - -v0.4.12 - Mar 30th 2012 -===================== - -* various memory leak / possible memory leak cleanups [einaros] -* api documentation [nicokaiser] -* add option to disable client tracking [nicokaiser] - -v0.4.11 - Mar 24th 2012 -===================== - -* node v0.7 compatibillity release -* gyp support [TooTallNate] -* commander dependency update [jwueller] -* loadbalancer support [nicokaiser] - -v0.4.10 - Mar 22th 2012 -===================== - -* Final hixie close frame fixes. [nicokaiser] - -v0.4.9 - Mar 21st 2012 -===================== - -* Various hixie bugfixes (such as proper close frame handling). [einaros] - -v0.4.8 - Feb 29th 2012 -===================== - -* Allow verifyClient to run asynchronously [karlsequin] -* Various bugfixes and cleanups. [einaros] - -v0.4.7 - Feb 21st 2012 -===================== - -* Exposed bytesReceived from websocket client object, which makes it possible to implement bandwidth sampling. [einaros] -* Updated browser based file upload example to include and output per websocket channel bandwidth sampling. [einaros] -* Changed build scripts to check which architecture is currently in use. Required after the node.js changes to have prebuilt packages target ia32 by default. [einaros] - -v0.4.6 - Feb 9th 2012 -===================== - -* Added browser based file upload example. [einaros] -* Added server-to-browser status push example. [einaros] -* Exposed pause() and resume() on WebSocket object, to enable client stream shaping. [einaros] - -v0.4.5 - Feb 7th 2012 -===================== - -* Corrected regression bug in handling of connections with the initial frame delivered across both http upgrade head and a standalone packet. This would lead to a race condition, which in some cases could cause message corruption. [einaros] - -v0.4.4 - Feb 6th 2012 -===================== - -* Pass original request object to verifyClient, for cookie or authentication verifications. [einaros] -* Implemented addEventListener and slightly improved the emulation API by adding a MessageEvent with a readonly data attribute. [aslakhellesoy] -* Rewrite parts of hybi receiver to avoid stack overflows for large amounts of packets bundled in the same buffer / packet. [einaros] - -v0.4.3 - Feb 4th 2012 -===================== - -* Prioritized update: Corrected issue which would cause sockets to stay open longer than necessary, and resource leakage because of this. [einaros] - -v0.4.2 - Feb 4th 2012 -===================== - -* Breaking change: WebSocketServer's verifyOrigin option has been renamed to verifyClient. [einaros] -* verifyClient now receives { origin: 'origin header', secure: true/false }, where 'secure' will be true for ssl connections. [einaros] -* Split benchmark, in preparation for more thorough case. [einaros] -* Introduced hixie-76 draft support for server, since Safari (iPhone / iPad / OS X) and Opera still aren't updated to use Hybi. [einaros] -* Expose 'supports' object from WebSocket, to indicate e.g. the underlying transport's support for binary data. [einaros] -* Test and code cleanups. [einaros] - -v0.4.1 - Jan 25th 2012 -===================== - -* Use readline in wscat [tricknotes] -* Refactor _state away, in favor of the new _readyState [tricknotes] -* travis-ci integration [einaros] -* Fixed race condition in testsuite, causing a few tests to fail (without actually indicating errors) on travis [einaros] -* Expose pong event [paddybyers] -* Enabled running of WebSocketServer in noServer-mode, meaning that upgrades are passed in manually. [einaros] -* Reworked connection procedure for WebSocketServer, and cleaned up tests. [einaros] - -v0.4.0 - Jan 2nd 2012 -===================== - -* Windows compatibility [einaros] -* Windows compatible test script [einaros] - -v0.3.9 - Jan 1st 2012 -====================== - -* Improved protocol framing performance [einaros] -* WSS support [kazuyukitanimura] -* WSS tests [einaros] -* readyState exposed [justinlatimer, tricknotes] -* url property exposed [justinlatimer] -* Removed old 'state' property [einaros] -* Test cleanups [einaros] - -v0.3.8 - Dec 27th 2011 -====================== - -* Made it possible to listen on specific paths, which is especially good to have for precreated http servers [einaros] -* Extensive WebSocket / WebSocketServer cleanup, including changing all internal properties to unconfigurable, unenumerable properties [einaros] -* Receiver modifications to ensure even better performance with fragmented sends [einaros] -* Fixed issue in sender.js, which would cause SlowBuffer instances (such as returned from the crypto library's randomBytes) to be copied (and thus be dead slow) [einaros] -* Removed redundant buffer copy in sender.js, which should improve server performance [einaros] - -v0.3.7 - Dec 25nd 2011 -====================== - -* Added a browser based API which uses EventEmitters internally [3rd-Eden] -* Expose request information from upgrade event for websocket server clients [mmalecki] - -v0.3.6 - Dec 19th 2011 -====================== - -* Added option to let WebSocket.Server use an already existing http server [mmalecki] -* Migrating various option structures to use options.js module [einaros] -* Added a few more tests, options and handshake verifications to ensure that faulty connections are dealt with [einaros] -* Code cleanups in Sender and Receiver, to ensure even faster parsing [einaros] - -v0.3.5 - Dec 13th 2011 -====================== - -* Optimized Sender.js, Receiver.js and bufferutil.cc: - * Apply loop-unrolling-like small block copies rather than use node.js Buffer#copy() (which is slow). - * Mask blocks of data using combination of 32bit xor and loop-unrolling, instead of single bytes. - * Keep pre-made send buffer for small transfers. -* Leak fixes and code cleanups. - -v0.3.3 - Dec 12th 2011 -====================== - -* Compile fix for Linux. -* Rewrote parts of WebSocket.js, to avoid try/catch and thus avoid optimizer bailouts. - -v0.3.2 - Dec 11th 2011 -====================== - -* Further performance updates, including the additions of a native BufferUtil module, which deals with several of the cpu intensive WebSocket operations. - -v0.3.1 - Dec 8th 2011 -====================== - -* Service release, fixing broken tests. - -v0.3.0 - Dec 8th 2011 -====================== - -* Node.js v0.4.x compatibility. -* Code cleanups and efficiency improvements. -* WebSocket server added, although this will still mainly be a client library. -* WebSocket server certified to pass the Autobahn test suite. -* Protocol improvements and corrections - such as handling (redundant) masks for empty fragments. -* 'wscat' command line utility added, which can act as either client or server. - -v0.2.6 - Dec 3rd 2011 -====================== - -* Renamed to 'ws'. Big woop, right -- but easy-websocket really just doesn't cut it anymore! - -v0.2.5 - Dec 3rd 2011 -====================== - - * Rewrote much of the WebSocket parser, to ensure high speed for highly fragmented messages. - * Added a BufferPool, as a start to more efficiently deal with allocations for WebSocket connections. More work to come, in that area. - * Updated the Autobahn report, at http://einaros.github.com/easy-websocket, with comparisons against WebSocket-Node 1.0.2 and Chrome 16. - -v0.2.0 - Nov 25th 2011 -====================== - - * Major rework to make sure all the Autobahn test cases pass. Also updated the internal tests to cover more corner cases. - -v0.1.2 - Nov 14th 2011 -====================== - - * Back and forth, back and forth: now settled on keeping the api (event names, methods) closer to the websocket browser api. This will stick now. - * Started keeping this history record. Better late than never, right? diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/Makefile b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/Makefile deleted file mode 100644 index 151aa2ba53..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -ALL_TESTS = $(shell find test/ -name '*.test.js') -ALL_INTEGRATION = $(shell find test/ -name '*.integration.js') - -all: - node-gyp configure build - -clean: - node-gyp clean - -run-tests: - @./node_modules/.bin/mocha \ - -t 2000 \ - -s 2400 \ - $(TESTFLAGS) \ - $(TESTS) - -run-integrationtests: - @./node_modules/.bin/mocha \ - -t 5000 \ - -s 6000 \ - $(TESTFLAGS) \ - $(TESTS) - -test: - @$(MAKE) NODE_TLS_REJECT_UNAUTHORIZED=0 NODE_PATH=lib TESTS="$(ALL_TESTS)" run-tests - -integrationtest: - @$(MAKE) NODE_TLS_REJECT_UNAUTHORIZED=0 NODE_PATH=lib TESTS="$(ALL_INTEGRATION)" run-integrationtests - -benchmark: - @node bench/sender.benchmark.js - @node bench/parser.benchmark.js - -autobahn: - @NODE_PATH=lib node test/autobahn.js - -autobahn-server: - @NODE_PATH=lib node test/autobahn-server.js - -.PHONY: test diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/README.md b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/README.md deleted file mode 100644 index cf1f1fb885..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/README.md +++ /dev/null @@ -1,171 +0,0 @@ -[![Build Status](https://secure.travis-ci.org/einaros/ws.png)](http://travis-ci.org/einaros/ws) - -# ws: a node.js websocket library # - -`ws` is a simple to use websocket implementation, up-to-date against RFC-6455, and [probably the fastest WebSocket library for node.js](http://web.archive.org/web/20130314230536/http://hobbycoding.posterous.com/the-fastest-websocket-module-for-nodejs). - -Passes the quite extensive Autobahn test suite. See http://einaros.github.com/ws for the full reports. - -Comes with a command line utility, `wscat`, which can either act as a server (--listen), or client (--connect); Use it to debug simple websocket services. - -## Protocol support ## - -* **Hixie draft 76** (Old and deprecated, but still in use by Safari and Opera. Added to ws version 0.4.2, but server only. Can be disabled by setting the `disableHixie` option to true.) -* **HyBi drafts 07-12** (Use the option `protocolVersion: 8`, or argument `-p 8` for wscat) -* **HyBi drafts 13-17** (Current default, alternatively option `protocolVersion: 13`, or argument `-p 13` for wscat) - -_See the echo.websocket.org example below for how to use the `protocolVersion` option._ - -## Usage ## - -### Installing ### - -`npm install ws` - -### Sending and receiving text data ### - -```js -var WebSocket = require('ws'); -var ws = new WebSocket('ws://www.host.com/path'); -ws.on('open', function() { - ws.send('something'); -}); -ws.on('message', function(data, flags) { - // flags.binary will be set if a binary data is received - // flags.masked will be set if the data was masked -}); -``` - -### Sending binary data ### - -```js -var WebSocket = require('ws'); -var ws = new WebSocket('ws://www.host.com/path'); -ws.on('open', function() { - var array = new Float32Array(5); - for (var i = 0; i < array.length; ++i) array[i] = i / 2; - ws.send(array, {binary: true, mask: true}); -}); -``` - -Setting `mask`, as done for the send options above, will cause the data to be masked according to the websocket protocol. The same option applies for text data. - -### Server example ### - -```js -var WebSocketServer = require('ws').Server - , wss = new WebSocketServer({port: 8080}); -wss.on('connection', function(ws) { - ws.on('message', function(message) { - console.log('received: %s', message); - }); - ws.send('something'); -}); -``` - -### Server sending broadcast data ### - -```js -var WebSocketServer = require('ws').Server - , wss = new WebSocketServer({port: 8080}); - -wss.broadcast = function(data) { - for(var i in this.clients) - this.clients[i].send(data); -}; -``` - -### Error handling best practices ### - -```js -// If the WebSocket is closed before the following send is attempted -ws.send('something'); - -// Errors (both immediate and async write errors) can be detected in an optional callback. -// The callback is also the only way of being notified that data has actually been sent. -ws.send('something', function(error) { - // if error is null, the send has been completed, - // otherwise the error object will indicate what failed. -}); - -// Immediate errors can also be handled with try/catch-blocks, but **note** -// that since sends are inherently asynchronous, socket write failures will *not* -// be captured when this technique is used. -try { - ws.send('something'); -} -catch (e) { - // handle error -} -``` - -### echo.websocket.org demo ### - -```js -var WebSocket = require('ws'); -var ws = new WebSocket('ws://echo.websocket.org/', {protocolVersion: 8, origin: 'http://websocket.org'}); -ws.on('open', function() { - console.log('connected'); - ws.send(Date.now().toString(), {mask: true}); -}); -ws.on('close', function() { - console.log('disconnected'); -}); -ws.on('message', function(data, flags) { - console.log('Roundtrip time: ' + (Date.now() - parseInt(data)) + 'ms', flags); - setTimeout(function() { - ws.send(Date.now().toString(), {mask: true}); - }, 500); -}); -``` - -### wscat against echo.websocket.org ### - - $ npm install -g ws - $ wscat -c ws://echo.websocket.org - connected (press CTRL+C to quit) - > hi there - < hi there - > are you a happy parrot? - < are you a happy parrot? - -### Other examples ### - -For a full example with a browser client communicating with a ws server, see the examples folder. - -Note that the usage together with Express 3.0 is quite different from Express 2.x. The difference is expressed in the two different serverstats-examples. - -Otherwise, see the test cases. - -### Running the tests ### - -`make test` - -## API Docs ## - -See the doc/ directory for Node.js-like docs for the ws classes. - -## License ## - -(The MIT License) - -Copyright (c) 2011 Einar Otto Stangvik <einaros@gmail.com> - -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. diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/bin/wscat b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/bin/wscat deleted file mode 100755 index 7c66600de2..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/bin/wscat +++ /dev/null @@ -1,222 +0,0 @@ -#!/usr/bin/env node - -/*! - * ws: a node.js websocket client - * Copyright(c) 2011 Einar Otto Stangvik - * MIT Licensed - */ - -/** - * Module dependencies. - */ - -var WebSocket = require('../') - , fs = require('fs') - , program = require('commander') - , util = require('util') - , events = require('events') - , readline = require('readline'); - -/** - * InputReader - processes console input - */ - -function Console() { - this.stdin = process.stdin; - this.stdout = process.stdout; - - this.readlineInterface = readline.createInterface(this.stdin, this.stdout); - - var self = this; - this.readlineInterface.on('line', function(data) { - self.emit('line', data); - }); - this.readlineInterface.on('close', function() { - self.emit('close'); - }); - - this._resetInput = function() { - self.clear(); - } -} -util.inherits(Console, events.EventEmitter); - -Console.Colors = { - Red: '\033[31m', - Green: '\033[32m', - Yellow: '\033[33m', - Blue: '\033[34m', - Default: '\033[39m' -}; - -Console.prototype.prompt = function() { - this.readlineInterface.prompt(); -} - -Console.prototype.print = function(msg, color) { - this.clear(); - color = color || Console.Colors.Default; - this.stdout.write(color + msg + Console.Colors.Default + '\n'); - this.prompt(); -} - -Console.prototype.clear = function() { - this.stdout.write('\033[2K\033[E'); -} - -Console.prototype.pause = function() { - this.stdin.on('keypress', this._resetInput); -} - -Console.prototype.resume = function() { - this.stdin.removeListener('keypress', this._resetInput); -} - -function appender(xs) { - xs = xs || []; - return function (x) { - xs.push(x); - return xs; - } -} - -function into(obj, kvals) { - kvals.forEach(function (kv) { - obj[kv[0]] = kv[1]; - }); - return obj; -} - -function splitOnce(sep, str) { // sep can be either String or RegExp - var tokens = str.split(sep); - return [tokens[0], str.replace(sep, '').substr(tokens[0].length)]; -} - -/** - * The actual application - */ - -var version = JSON.parse(fs.readFileSync(__dirname + '/../package.json', 'utf8')).version; -program - .version(version) - .usage('[options] ') - .option('-l, --listen ', 'listen on port') - .option('-c, --connect ', 'connect to a websocket server') - .option('-p, --protocol ', 'optional protocol version') - .option('-o, --origin ', 'optional origin') - .option('--host ', 'optional host') - .option('-s, --subprotocol ', 'optional subprotocol') - .option('-n, --no-check', 'Do not check for unauthorized certificates') - .option('-H, --header ', 'Set an HTTP header. Repeat to set multiple. (--connect only)', appender(), []) - .option('--auth ', 'Add basic HTTP authentication header. (--connect only)') - .parse(process.argv); - -if (program.listen && program.connect) { - console.error('\033[33merror: use either --listen or --connect\033[39m'); - process.exit(-1); -} -else if (program.listen) { - var wsConsole = new Console(); - wsConsole.pause(); - var options = {}; - if (program.protocol) options.protocolVersion = program.protocol; - if (program.origin) options.origin = program.origin; - if (program.subprotocol) options.protocol = program.subprotocol; - if (!program.check) options.rejectUnauthorized = program.check; - var ws = null; - var wss = new WebSocket.Server({port: program.listen}, function() { - wsConsole.print('listening on port ' + program.listen + ' (press CTRL+C to quit)', Console.Colors.Green); - wsConsole.clear(); - }); - wsConsole.on('close', function() { - if (ws) { - try { - ws.close(); - } - catch (e) {} - } - process.exit(0); - }); - wsConsole.on('line', function(data) { - if (ws) { - ws.send(data, {mask: false}); - wsConsole.prompt(); - } - }); - wss.on('connection', function(newClient) { - if (ws) { - // limit to one client - newClient.terminate(); - return; - }; - ws = newClient; - wsConsole.resume(); - wsConsole.prompt(); - wsConsole.print('client connected', Console.Colors.Green); - ws.on('close', function() { - wsConsole.print('disconnected', Console.Colors.Green); - wsConsole.clear(); - wsConsole.pause(); - ws = null; - }); - ws.on('error', function(code, description) { - wsConsole.print('error: ' + code + (description ? ' ' + description : ''), Console.Colors.Yellow); - }); - ws.on('message', function(data, flags) { - wsConsole.print('< ' + data, Console.Colors.Blue); - }); - }); - wss.on('error', function(error) { - wsConsole.print('error: ' + error.toString(), Console.Colors.Yellow); - process.exit(-1); - }); -} -else if (program.connect) { - var wsConsole = new Console(); - var options = {}; - if (program.protocol) options.protocolVersion = program.protocol; - if (program.origin) options.origin = program.origin; - if (program.subprotocol) options.protocol = program.subprotocol; - if (program.host) options.host = program.host; - if (!program.check) options.rejectUnauthorized = program.check; - var headers = into({}, (program.header || []).map(function (s) { - return splitOnce(':', s) - })); - if (program.auth) { - headers['Authorization'] = 'Basic ' + new Buffer(program.auth).toString('base64'); - } - options.headers = headers; - var ws = new WebSocket(program.connect, options); - ws.on('open', function() { - wsConsole.print('connected (press CTRL+C to quit)', Console.Colors.Green); - wsConsole.on('line', function(data) { - ws.send(data, {mask: true}); - wsConsole.prompt(); - }); - }); - ws.on('close', function() { - wsConsole.print('disconnected', Console.Colors.Green); - wsConsole.clear(); - process.exit(); - }); - ws.on('error', function(code, description) { - wsConsole.print('error: ' + code + (description ? ' ' + description : ''), Console.Colors.Yellow); - process.exit(-1); - }); - ws.on('message', function(data, flags) { - wsConsole.print('< ' + data, Console.Colors.Blue); - }); - wsConsole.on('close', function() { - if (ws) { - try { - ws.close(); - } - catch(e) {} - process.exit(); - } - }); -} -else { - console.error('\033[33merror: use either --listen or --connect\033[39m'); - process.exit(-1); -} diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/binding.gyp b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/binding.gyp deleted file mode 100644 index 600f9d10f1..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/binding.gyp +++ /dev/null @@ -1,16 +0,0 @@ -{ - 'targets': [ - { - 'target_name': 'validation', - 'include_dirs': ["> $(depfile) -# Add extra rules as in (2). -# We remove slashes and replace spaces with new lines; -# remove blank lines; -# delete the first line and append a colon to the remaining lines. -sed -e 's|\\||' -e 'y| |\n|' $(depfile).raw |\ - grep -v '^$$' |\ - sed -e 1d -e 's|$$|:|' \ - >> $(depfile) -rm $(depfile).raw -endef - -# Command definitions: -# - cmd_foo is the actual command to run; -# - quiet_cmd_foo is the brief-output summary of the command. - -quiet_cmd_cc = CC($(TOOLSET)) $@ -cmd_cc = $(CC.$(TOOLSET)) $(GYP_CFLAGS) $(DEPFLAGS) $(CFLAGS.$(TOOLSET)) -c -o $@ $< - -quiet_cmd_cxx = CXX($(TOOLSET)) $@ -cmd_cxx = $(CXX.$(TOOLSET)) $(GYP_CXXFLAGS) $(DEPFLAGS) $(CXXFLAGS.$(TOOLSET)) -c -o $@ $< - -quiet_cmd_touch = TOUCH $@ -cmd_touch = touch $@ - -quiet_cmd_copy = COPY $@ -# send stderr to /dev/null to ignore messages when linking directories. -cmd_copy = rm -rf "$@" && cp -af "$<" "$@" - -quiet_cmd_alink = AR($(TOOLSET)) $@ -cmd_alink = rm -f $@ && $(AR.$(TOOLSET)) crs $@ $(filter %.o,$^) - -quiet_cmd_alink_thin = AR($(TOOLSET)) $@ -cmd_alink_thin = rm -f $@ && $(AR.$(TOOLSET)) crsT $@ $(filter %.o,$^) - -# Due to circular dependencies between libraries :(, we wrap the -# special "figure out circular dependencies" flags around the entire -# input list during linking. -quiet_cmd_link = LINK($(TOOLSET)) $@ -cmd_link = $(LINK.$(TOOLSET)) $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -o $@ -Wl,--start-group $(LD_INPUTS) -Wl,--end-group $(LIBS) - -# We support two kinds of shared objects (.so): -# 1) shared_library, which is just bundling together many dependent libraries -# into a link line. -# 2) loadable_module, which is generating a module intended for dlopen(). -# -# They differ only slightly: -# In the former case, we want to package all dependent code into the .so. -# In the latter case, we want to package just the API exposed by the -# outermost module. -# This means shared_library uses --whole-archive, while loadable_module doesn't. -# (Note that --whole-archive is incompatible with the --start-group used in -# normal linking.) - -# Other shared-object link notes: -# - Set SONAME to the library filename so our binaries don't reference -# the local, absolute paths used on the link command-line. -quiet_cmd_solink = SOLINK($(TOOLSET)) $@ -cmd_solink = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--whole-archive $(LD_INPUTS) -Wl,--no-whole-archive $(LIBS) - -quiet_cmd_solink_module = SOLINK_MODULE($(TOOLSET)) $@ -cmd_solink_module = $(LINK.$(TOOLSET)) -shared $(GYP_LDFLAGS) $(LDFLAGS.$(TOOLSET)) -Wl,-soname=$(@F) -o $@ -Wl,--start-group $(filter-out FORCE_DO_CMD, $^) -Wl,--end-group $(LIBS) - - -# Define an escape_quotes function to escape single quotes. -# This allows us to handle quotes properly as long as we always use -# use single quotes and escape_quotes. -escape_quotes = $(subst ','\'',$(1)) -# This comment is here just to include a ' to unconfuse syntax highlighting. -# Define an escape_vars function to escape '$' variable syntax. -# This allows us to read/write command lines with shell variables (e.g. -# $LD_LIBRARY_PATH), without triggering make substitution. -escape_vars = $(subst $$,$$$$,$(1)) -# Helper that expands to a shell command to echo a string exactly as it is in -# make. This uses printf instead of echo because printf's behaviour with respect -# to escape sequences is more portable than echo's across different shells -# (e.g., dash, bash). -exact_echo = printf '%s\n' '$(call escape_quotes,$(1))' - -# Helper to compare the command we're about to run against the command -# we logged the last time we ran the command. Produces an empty -# string (false) when the commands match. -# Tricky point: Make has no string-equality test function. -# The kernel uses the following, but it seems like it would have false -# positives, where one string reordered its arguments. -# arg_check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \ -# $(filter-out $(cmd_$@), $(cmd_$(1)))) -# We instead substitute each for the empty string into the other, and -# say they're equal if both substitutions produce the empty string. -# .d files contain ? instead of spaces, take that into account. -command_changed = $(or $(subst $(cmd_$(1)),,$(cmd_$(call replace_spaces,$@))),\ - $(subst $(cmd_$(call replace_spaces,$@)),,$(cmd_$(1)))) - -# Helper that is non-empty when a prerequisite changes. -# Normally make does this implicitly, but we force rules to always run -# so we can check their command lines. -# $? -- new prerequisites -# $| -- order-only dependencies -prereq_changed = $(filter-out FORCE_DO_CMD,$(filter-out $|,$?)) - -# Helper that executes all postbuilds until one fails. -define do_postbuilds - @E=0;\ - for p in $(POSTBUILDS); do\ - eval $$p;\ - E=$$?;\ - if [ $$E -ne 0 ]; then\ - break;\ - fi;\ - done;\ - if [ $$E -ne 0 ]; then\ - rm -rf "$@";\ - exit $$E;\ - fi -endef - -# do_cmd: run a command via the above cmd_foo names, if necessary. -# Should always run for a given target to handle command-line changes. -# Second argument, if non-zero, makes it do asm/C/C++ dependency munging. -# Third argument, if non-zero, makes it do POSTBUILDS processing. -# Note: We intentionally do NOT call dirx for depfile, since it contains ? for -# spaces already and dirx strips the ? characters. -define do_cmd -$(if $(or $(command_changed),$(prereq_changed)), - @$(call exact_echo, $($(quiet)cmd_$(1))) - @mkdir -p "$(call dirx,$@)" "$(dir $(depfile))" - $(if $(findstring flock,$(word 1,$(cmd_$1))), - @$(cmd_$(1)) - @echo " $(quiet_cmd_$(1)): Finished", - @$(cmd_$(1)) - ) - @$(call exact_echo,$(call escape_vars,cmd_$(call replace_spaces,$@) := $(cmd_$(1)))) > $(depfile) - @$(if $(2),$(fixup_dep)) - $(if $(and $(3), $(POSTBUILDS)), - $(call do_postbuilds) - ) -) -endef - -# Declare the "all" target first so it is the default, -# even though we don't have the deps yet. -.PHONY: all -all: - -# make looks for ways to re-generate included makefiles, but in our case, we -# don't have a direct way. Explicitly telling make that it has nothing to do -# for them makes it go faster. -%.d: ; - -# Use FORCE_DO_CMD to force a target to run. Should be coupled with -# do_cmd. -.PHONY: FORCE_DO_CMD -FORCE_DO_CMD: - -TOOLSET := target -# Suffix rules, putting all outputs into $(obj). -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.c FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cpp FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.cxx FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.S FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(srcdir)/%.s FORCE_DO_CMD - @$(call do_cmd,cc,1) - -# Try building from generated source, too. -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.c FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cpp FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.cxx FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.S FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj).$(TOOLSET)/%.s FORCE_DO_CMD - @$(call do_cmd,cc,1) - -$(obj).$(TOOLSET)/%.o: $(obj)/%.c FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.cpp FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.cxx FORCE_DO_CMD - @$(call do_cmd,cxx,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.S FORCE_DO_CMD - @$(call do_cmd,cc,1) -$(obj).$(TOOLSET)/%.o: $(obj)/%.s FORCE_DO_CMD - @$(call do_cmd,cc,1) - - -ifeq ($(strip $(foreach prefix,$(NO_LOAD),\ - $(findstring $(join ^,$(prefix)),\ - $(join ^,bufferutil.target.mk)))),) - include bufferutil.target.mk -endif -ifeq ($(strip $(foreach prefix,$(NO_LOAD),\ - $(findstring $(join ^,$(prefix)),\ - $(join ^,validation.target.mk)))),) - include validation.target.mk -endif - -quiet_cmd_regen_makefile = ACTION Regenerating $@ -cmd_regen_makefile = cd $(srcdir); /usr/lib/node_modules/npm/node_modules/node-gyp/gyp/gyp_main.py -fmake --ignore-environment "--toplevel-dir=." -I/var/www/egroupware/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/config.gypi -I/usr/lib/node_modules/npm/node_modules/node-gyp/addon.gypi -I/home/hadi/.node-gyp/0.10.29/common.gypi "--depth=." "-Goutput_dir=." "--generator-output=build" "-Dlibrary=shared_library" "-Dvisibility=default" "-Dnode_root_dir=/home/hadi/.node-gyp/0.10.29" "-Dmodule_root_dir=/var/www/egroupware/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws" binding.gyp -Makefile: $(srcdir)/../../../../../../../../../../../../home/hadi/.node-gyp/0.10.29/common.gypi $(srcdir)/build/config.gypi $(srcdir)/binding.gyp $(srcdir)/../../../../../../../../../../../../usr/lib/node_modules/npm/node_modules/node-gyp/addon.gypi - $(call do_cmd,regen_makefile) - -# "all" is a concatenation of the "all" targets from all the included -# sub-makefiles. This is just here to clarify. -all: - -# Add in dependency-tracking rules. $(all_deps) is the list of every single -# target in our tree. Only consider the ones with .d (dependency) info: -d_files := $(wildcard $(foreach f,$(all_deps),$(depsdir)/$(f).d)) -ifneq ($(d_files),) - include $(d_files) -endif diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/.deps/Release/bufferutil.node.d b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/.deps/Release/bufferutil.node.d deleted file mode 100644 index 03982bedf7..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/.deps/Release/bufferutil.node.d +++ /dev/null @@ -1 +0,0 @@ -cmd_Release/bufferutil.node := rm -rf "Release/bufferutil.node" && cp -af "Release/obj.target/bufferutil.node" "Release/bufferutil.node" diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/.deps/Release/obj.target/bufferutil.node.d b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/.deps/Release/obj.target/bufferutil.node.d deleted file mode 100644 index c329bd5905..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/.deps/Release/obj.target/bufferutil.node.d +++ /dev/null @@ -1 +0,0 @@ -cmd_Release/obj.target/bufferutil.node := flock ./Release/linker.lock g++ -shared -pthread -rdynamic -m64 -Wl,-soname=bufferutil.node -o Release/obj.target/bufferutil.node -Wl,--start-group Release/obj.target/bufferutil/src/bufferutil.o -Wl,--end-group diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/.deps/Release/obj.target/bufferutil/src/bufferutil.o.d b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/.deps/Release/obj.target/bufferutil/src/bufferutil.o.d deleted file mode 100644 index e2b8db6b59..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/.deps/Release/obj.target/bufferutil/src/bufferutil.o.d +++ /dev/null @@ -1,29 +0,0 @@ -cmd_Release/obj.target/bufferutil/src/bufferutil.o := g++ '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' -I/home/hadi/.node-gyp/0.10.29/src -I/home/hadi/.node-gyp/0.10.29/deps/uv/include -I/home/hadi/.node-gyp/0.10.29/deps/v8/include -I../node_modules/nan -fPIC -Wall -Wextra -Wno-unused-parameter -pthread -m64 -O2 -fno-strict-aliasing -fno-tree-vrp -fno-omit-frame-pointer -fno-rtti -fno-exceptions -MMD -MF ./Release/.deps/Release/obj.target/bufferutil/src/bufferutil.o.d.raw -c -o Release/obj.target/bufferutil/src/bufferutil.o ../src/bufferutil.cc -Release/obj.target/bufferutil/src/bufferutil.o: ../src/bufferutil.cc \ - /home/hadi/.node-gyp/0.10.29/deps/v8/include/v8.h \ - /home/hadi/.node-gyp/0.10.29/deps/v8/include/v8stdint.h \ - /home/hadi/.node-gyp/0.10.29/src/node.h \ - /home/hadi/.node-gyp/0.10.29/deps/uv/include/uv.h \ - /home/hadi/.node-gyp/0.10.29/deps/uv/include/uv-private/uv-unix.h \ - /home/hadi/.node-gyp/0.10.29/deps/uv/include/uv-private/ngx-queue.h \ - /home/hadi/.node-gyp/0.10.29/deps/uv/include/uv-private/uv-linux.h \ - /home/hadi/.node-gyp/0.10.29/src/node_object_wrap.h \ - /home/hadi/.node-gyp/0.10.29/src/node.h \ - /home/hadi/.node-gyp/0.10.29/src/node_buffer.h \ - /home/hadi/.node-gyp/0.10.29/src/node_object_wrap.h \ - ../node_modules/nan/nan.h \ - /home/hadi/.node-gyp/0.10.29/src/node_version.h -../src/bufferutil.cc: -/home/hadi/.node-gyp/0.10.29/deps/v8/include/v8.h: -/home/hadi/.node-gyp/0.10.29/deps/v8/include/v8stdint.h: -/home/hadi/.node-gyp/0.10.29/src/node.h: -/home/hadi/.node-gyp/0.10.29/deps/uv/include/uv.h: -/home/hadi/.node-gyp/0.10.29/deps/uv/include/uv-private/uv-unix.h: -/home/hadi/.node-gyp/0.10.29/deps/uv/include/uv-private/ngx-queue.h: -/home/hadi/.node-gyp/0.10.29/deps/uv/include/uv-private/uv-linux.h: -/home/hadi/.node-gyp/0.10.29/src/node_object_wrap.h: -/home/hadi/.node-gyp/0.10.29/src/node.h: -/home/hadi/.node-gyp/0.10.29/src/node_buffer.h: -/home/hadi/.node-gyp/0.10.29/src/node_object_wrap.h: -../node_modules/nan/nan.h: -/home/hadi/.node-gyp/0.10.29/src/node_version.h: diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/.deps/Release/obj.target/validation.node.d b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/.deps/Release/obj.target/validation.node.d deleted file mode 100644 index f39b7c9872..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/.deps/Release/obj.target/validation.node.d +++ /dev/null @@ -1 +0,0 @@ -cmd_Release/obj.target/validation.node := flock ./Release/linker.lock g++ -shared -pthread -rdynamic -m64 -Wl,-soname=validation.node -o Release/obj.target/validation.node -Wl,--start-group Release/obj.target/validation/src/validation.o -Wl,--end-group diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/.deps/Release/obj.target/validation/src/validation.o.d b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/.deps/Release/obj.target/validation/src/validation.o.d deleted file mode 100644 index 4ff3bbfa18..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/.deps/Release/obj.target/validation/src/validation.o.d +++ /dev/null @@ -1,29 +0,0 @@ -cmd_Release/obj.target/validation/src/validation.o := g++ '-D_LARGEFILE_SOURCE' '-D_FILE_OFFSET_BITS=64' '-DBUILDING_NODE_EXTENSION' -I/home/hadi/.node-gyp/0.10.29/src -I/home/hadi/.node-gyp/0.10.29/deps/uv/include -I/home/hadi/.node-gyp/0.10.29/deps/v8/include -I../node_modules/nan -fPIC -Wall -Wextra -Wno-unused-parameter -pthread -m64 -O2 -fno-strict-aliasing -fno-tree-vrp -fno-omit-frame-pointer -fno-rtti -fno-exceptions -MMD -MF ./Release/.deps/Release/obj.target/validation/src/validation.o.d.raw -c -o Release/obj.target/validation/src/validation.o ../src/validation.cc -Release/obj.target/validation/src/validation.o: ../src/validation.cc \ - /home/hadi/.node-gyp/0.10.29/deps/v8/include/v8.h \ - /home/hadi/.node-gyp/0.10.29/deps/v8/include/v8stdint.h \ - /home/hadi/.node-gyp/0.10.29/src/node.h \ - /home/hadi/.node-gyp/0.10.29/deps/uv/include/uv.h \ - /home/hadi/.node-gyp/0.10.29/deps/uv/include/uv-private/uv-unix.h \ - /home/hadi/.node-gyp/0.10.29/deps/uv/include/uv-private/ngx-queue.h \ - /home/hadi/.node-gyp/0.10.29/deps/uv/include/uv-private/uv-linux.h \ - /home/hadi/.node-gyp/0.10.29/src/node_object_wrap.h \ - /home/hadi/.node-gyp/0.10.29/src/node.h \ - /home/hadi/.node-gyp/0.10.29/src/node_buffer.h \ - /home/hadi/.node-gyp/0.10.29/src/node_object_wrap.h \ - ../node_modules/nan/nan.h \ - /home/hadi/.node-gyp/0.10.29/src/node_version.h -../src/validation.cc: -/home/hadi/.node-gyp/0.10.29/deps/v8/include/v8.h: -/home/hadi/.node-gyp/0.10.29/deps/v8/include/v8stdint.h: -/home/hadi/.node-gyp/0.10.29/src/node.h: -/home/hadi/.node-gyp/0.10.29/deps/uv/include/uv.h: -/home/hadi/.node-gyp/0.10.29/deps/uv/include/uv-private/uv-unix.h: -/home/hadi/.node-gyp/0.10.29/deps/uv/include/uv-private/ngx-queue.h: -/home/hadi/.node-gyp/0.10.29/deps/uv/include/uv-private/uv-linux.h: -/home/hadi/.node-gyp/0.10.29/src/node_object_wrap.h: -/home/hadi/.node-gyp/0.10.29/src/node.h: -/home/hadi/.node-gyp/0.10.29/src/node_buffer.h: -/home/hadi/.node-gyp/0.10.29/src/node_object_wrap.h: -../node_modules/nan/nan.h: -/home/hadi/.node-gyp/0.10.29/src/node_version.h: diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/.deps/Release/validation.node.d b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/.deps/Release/validation.node.d deleted file mode 100644 index 6b32ade13b..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/.deps/Release/validation.node.d +++ /dev/null @@ -1 +0,0 @@ -cmd_Release/validation.node := rm -rf "Release/validation.node" && cp -af "Release/obj.target/validation.node" "Release/validation.node" diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/bufferutil.node b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/bufferutil.node deleted file mode 100755 index 6f31e05465f9851550bc04f41b9231ce14b1b219..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24664 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 diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/validation.node b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/Release/validation.node deleted file mode 100755 index d31693f023b0ca38a3f2943c1d02d2d1e49bbe9b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2117680 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 diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/binding.Makefile b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/binding.Makefile deleted file mode 100644 index 5d26a451f7..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/binding.Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# This file is generated by gyp; do not edit. - -export builddir_name ?= ./build/. -.PHONY: all -all: - $(MAKE) validation bufferutil diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/bufferutil.target.mk b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/bufferutil.target.mk deleted file mode 100644 index 2c79e81359..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/bufferutil.target.mk +++ /dev/null @@ -1,133 +0,0 @@ -# This file is generated by gyp; do not edit. - -TOOLSET := target -TARGET := bufferutil -DEFS_Debug := \ - '-D_LARGEFILE_SOURCE' \ - '-D_FILE_OFFSET_BITS=64' \ - '-DBUILDING_NODE_EXTENSION' \ - '-DDEBUG' \ - '-D_DEBUG' - -# Flags passed to all source files. -CFLAGS_Debug := \ - -fPIC \ - -Wall \ - -Wextra \ - -Wno-unused-parameter \ - -pthread \ - -m64 \ - -O3 \ - -g \ - -O0 - -# Flags passed to only C files. -CFLAGS_C_Debug := - -# Flags passed to only C++ files. -CFLAGS_CC_Debug := \ - -fno-rtti \ - -fno-exceptions - -INCS_Debug := \ - -I/home/hadi/.node-gyp/0.10.29/src \ - -I/home/hadi/.node-gyp/0.10.29/deps/uv/include \ - -I/home/hadi/.node-gyp/0.10.29/deps/v8/include \ - -I$(srcdir)/node_modules/nan - -DEFS_Release := \ - '-D_LARGEFILE_SOURCE' \ - '-D_FILE_OFFSET_BITS=64' \ - '-DBUILDING_NODE_EXTENSION' - -# Flags passed to all source files. -CFLAGS_Release := \ - -fPIC \ - -Wall \ - -Wextra \ - -Wno-unused-parameter \ - -pthread \ - -m64 \ - -O2 \ - -fno-strict-aliasing \ - -fno-tree-vrp \ - -fno-omit-frame-pointer - -# Flags passed to only C files. -CFLAGS_C_Release := - -# Flags passed to only C++ files. -CFLAGS_CC_Release := \ - -fno-rtti \ - -fno-exceptions - -INCS_Release := \ - -I/home/hadi/.node-gyp/0.10.29/src \ - -I/home/hadi/.node-gyp/0.10.29/deps/uv/include \ - -I/home/hadi/.node-gyp/0.10.29/deps/v8/include \ - -I$(srcdir)/node_modules/nan - -OBJS := \ - $(obj).target/$(TARGET)/src/bufferutil.o - -# Add to the list of files we specially track dependencies for. -all_deps += $(OBJS) - -# CFLAGS et al overrides must be target-local. -# See "Target-specific Variable Values" in the GNU Make manual. -$(OBJS): TOOLSET := $(TOOLSET) -$(OBJS): GYP_CFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE)) -$(OBJS): GYP_CXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE)) - -# Suffix rules, putting all outputs into $(obj). - -$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) - -# Try building from generated source, too. - -$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) - -$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) - -# End of this set of suffix rules -### Rules for final target. -LDFLAGS_Debug := \ - -pthread \ - -rdynamic \ - -m64 - -LDFLAGS_Release := \ - -pthread \ - -rdynamic \ - -m64 - -LIBS := - -$(obj).target/bufferutil.node: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE)) -$(obj).target/bufferutil.node: LIBS := $(LIBS) -$(obj).target/bufferutil.node: TOOLSET := $(TOOLSET) -$(obj).target/bufferutil.node: $(OBJS) FORCE_DO_CMD - $(call do_cmd,solink_module) - -all_deps += $(obj).target/bufferutil.node -# Add target alias -.PHONY: bufferutil -bufferutil: $(builddir)/bufferutil.node - -# Copy this to the executable output path. -$(builddir)/bufferutil.node: TOOLSET := $(TOOLSET) -$(builddir)/bufferutil.node: $(obj).target/bufferutil.node FORCE_DO_CMD - $(call do_cmd,copy) - -all_deps += $(builddir)/bufferutil.node -# Short alias for building this executable. -.PHONY: bufferutil.node -bufferutil.node: $(obj).target/bufferutil.node $(builddir)/bufferutil.node - -# Add executable to "all" target. -.PHONY: all -all: $(builddir)/bufferutil.node - diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/config.gypi b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/config.gypi deleted file mode 100644 index 3816d1bc5c..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/config.gypi +++ /dev/null @@ -1,119 +0,0 @@ -# Do not edit. File was generated by node-gyp's "configure" step -{ - "target_defaults": { - "cflags": [], - "default_configuration": "Release", - "defines": [], - "include_dirs": [], - "libraries": [] - }, - "variables": { - "clang": 0, - "gcc_version": 48, - "host_arch": "x64", - "node_install_npm": "true", - "node_prefix": "/usr", - "node_shared_cares": "false", - "node_shared_http_parser": "false", - "node_shared_libuv": "false", - "node_shared_openssl": "false", - "node_shared_v8": "false", - "node_shared_zlib": "false", - "node_tag": "", - "node_unsafe_optimizations": 0, - "node_use_dtrace": "false", - "node_use_etw": "false", - "node_use_openssl": "true", - "node_use_perfctr": "false", - "node_use_systemtap": "false", - "python": "/usr/bin/python", - "target_arch": "x64", - "v8_enable_gdbjit": 0, - "v8_no_strict_aliasing": 1, - "v8_use_snapshot": "false", - "nodedir": "/home/hadi/.node-gyp/0.10.29", - "copy_dev_lib": "true", - "standalone_static_library": 1, - "cache_lock_stale": "60000", - "sign_git_tag": "", - "user_agent": "npm/1.4.14 node/v0.10.29 linux x64", - "always_auth": "", - "bin_links": "true", - "key": "", - "description": "true", - "fetch_retries": "2", - "heading": "npm", - "user": "1000", - "force": "", - "cache_min": "10", - "init_license": "ISC", - "editor": "vi", - "rollback": "true", - "cache_max": "Infinity", - "userconfig": "/home/hadi/.npmrc", - "engine_strict": "", - "init_author_name": "", - "init_author_url": "", - "tmp": "/home/hadi/tmp", - "depth": "Infinity", - "save_dev": "", - "usage": "", - "https_proxy": "", - "onload_script": "", - "rebuild_bundle": "true", - "save_bundle": "", - "shell": "/bin/bash", - "prefix": "/usr", - "registry": "https://registry.npmjs.org/", - "browser": "", - "cache_lock_wait": "10000", - "save_optional": "", - "searchopts": "", - "versions": "", - "cache": "/home/hadi/.npm", - "ignore_scripts": "", - "searchsort": "name", - "version": "", - "local_address": "", - "viewer": "man", - "color": "true", - "fetch_retry_mintimeout": "10000", - "umask": "18", - "fetch_retry_maxtimeout": "60000", - "message": "%s", - "ca": "", - "cert": "", - "global": "", - "link": "", - "save": "", - "unicode": "true", - "long": "", - "production": "", - "unsafe_perm": "", - "node_version": "v0.10.29", - "tag": "latest", - "git_tag_version": "true", - "shrinkwrap": "true", - "fetch_retry_factor": "10", - "npat": "", - "proprietary_attribs": "true", - "save_exact": "", - "strict_ssl": "true", - "username": "", - "dev": "", - "globalconfig": "/usr/etc/npmrc", - "init_module": "/home/hadi/.npm-init.js", - "parseable": "", - "globalignorefile": "/usr/etc/npmignore", - "cache_lock_retries": "10", - "save_prefix": "^", - "group": "1000", - "init_author_email": "", - "searchexclude": "", - "git": "git", - "optional": "true", - "email": "", - "json": "", - "spin": "true" - } -} diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/validation.target.mk b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/validation.target.mk deleted file mode 100644 index aa64ceb087..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/build/validation.target.mk +++ /dev/null @@ -1,133 +0,0 @@ -# This file is generated by gyp; do not edit. - -TOOLSET := target -TARGET := validation -DEFS_Debug := \ - '-D_LARGEFILE_SOURCE' \ - '-D_FILE_OFFSET_BITS=64' \ - '-DBUILDING_NODE_EXTENSION' \ - '-DDEBUG' \ - '-D_DEBUG' - -# Flags passed to all source files. -CFLAGS_Debug := \ - -fPIC \ - -Wall \ - -Wextra \ - -Wno-unused-parameter \ - -pthread \ - -m64 \ - -O3 \ - -g \ - -O0 - -# Flags passed to only C files. -CFLAGS_C_Debug := - -# Flags passed to only C++ files. -CFLAGS_CC_Debug := \ - -fno-rtti \ - -fno-exceptions - -INCS_Debug := \ - -I/home/hadi/.node-gyp/0.10.29/src \ - -I/home/hadi/.node-gyp/0.10.29/deps/uv/include \ - -I/home/hadi/.node-gyp/0.10.29/deps/v8/include \ - -I$(srcdir)/node_modules/nan - -DEFS_Release := \ - '-D_LARGEFILE_SOURCE' \ - '-D_FILE_OFFSET_BITS=64' \ - '-DBUILDING_NODE_EXTENSION' - -# Flags passed to all source files. -CFLAGS_Release := \ - -fPIC \ - -Wall \ - -Wextra \ - -Wno-unused-parameter \ - -pthread \ - -m64 \ - -O2 \ - -fno-strict-aliasing \ - -fno-tree-vrp \ - -fno-omit-frame-pointer - -# Flags passed to only C files. -CFLAGS_C_Release := - -# Flags passed to only C++ files. -CFLAGS_CC_Release := \ - -fno-rtti \ - -fno-exceptions - -INCS_Release := \ - -I/home/hadi/.node-gyp/0.10.29/src \ - -I/home/hadi/.node-gyp/0.10.29/deps/uv/include \ - -I/home/hadi/.node-gyp/0.10.29/deps/v8/include \ - -I$(srcdir)/node_modules/nan - -OBJS := \ - $(obj).target/$(TARGET)/src/validation.o - -# Add to the list of files we specially track dependencies for. -all_deps += $(OBJS) - -# CFLAGS et al overrides must be target-local. -# See "Target-specific Variable Values" in the GNU Make manual. -$(OBJS): TOOLSET := $(TOOLSET) -$(OBJS): GYP_CFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_C_$(BUILDTYPE)) -$(OBJS): GYP_CXXFLAGS := $(DEFS_$(BUILDTYPE)) $(INCS_$(BUILDTYPE)) $(CFLAGS_$(BUILDTYPE)) $(CFLAGS_CC_$(BUILDTYPE)) - -# Suffix rules, putting all outputs into $(obj). - -$(obj).$(TOOLSET)/$(TARGET)/%.o: $(srcdir)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) - -# Try building from generated source, too. - -$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj).$(TOOLSET)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) - -$(obj).$(TOOLSET)/$(TARGET)/%.o: $(obj)/%.cc FORCE_DO_CMD - @$(call do_cmd,cxx,1) - -# End of this set of suffix rules -### Rules for final target. -LDFLAGS_Debug := \ - -pthread \ - -rdynamic \ - -m64 - -LDFLAGS_Release := \ - -pthread \ - -rdynamic \ - -m64 - -LIBS := - -$(obj).target/validation.node: GYP_LDFLAGS := $(LDFLAGS_$(BUILDTYPE)) -$(obj).target/validation.node: LIBS := $(LIBS) -$(obj).target/validation.node: TOOLSET := $(TOOLSET) -$(obj).target/validation.node: $(OBJS) FORCE_DO_CMD - $(call do_cmd,solink_module) - -all_deps += $(obj).target/validation.node -# Add target alias -.PHONY: validation -validation: $(builddir)/validation.node - -# Copy this to the executable output path. -$(builddir)/validation.node: TOOLSET := $(TOOLSET) -$(builddir)/validation.node: $(obj).target/validation.node FORCE_DO_CMD - $(call do_cmd,copy) - -all_deps += $(builddir)/validation.node -# Short alias for building this executable. -.PHONY: validation.node -validation.node: $(obj).target/validation.node $(builddir)/validation.node - -# Add executable to "all" target. -.PHONY: all -all: $(builddir)/validation.node - diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/builderror.log b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/builderror.log deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/index.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/index.js deleted file mode 100644 index 3423ff2323..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/index.js +++ /dev/null @@ -1,26 +0,0 @@ -/*! - * ws: a node.js websocket client - * Copyright(c) 2011 Einar Otto Stangvik - * MIT Licensed - */ - -module.exports = require('./lib/WebSocket'); -module.exports.Server = require('./lib/WebSocketServer'); -module.exports.Sender = require('./lib/Sender'); -module.exports.Receiver = require('./lib/Receiver'); - -module.exports.createServer = function (options, connectionListener) { - var server = new module.exports.Server(options); - if (typeof connectionListener === 'function') { - server.on('connection', connectionListener); - } - return server; -}; - -module.exports.connect = module.exports.createConnection = function (address, openListener) { - var client = new module.exports(address); - if (typeof openListener === 'function') { - client.on('open', openListener); - } - return client; -}; diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/BufferPool.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/BufferPool.js deleted file mode 100644 index faf8637c04..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/BufferPool.js +++ /dev/null @@ -1,59 +0,0 @@ -/*! - * ws: a node.js websocket client - * Copyright(c) 2011 Einar Otto Stangvik - * MIT Licensed - */ - -var util = require('util'); - -function BufferPool(initialSize, growStrategy, shrinkStrategy) { - if (typeof initialSize === 'function') { - shrinkStrategy = growStrategy; - growStrategy = initialSize; - initialSize = 0; - } - else if (typeof initialSize === 'undefined') { - initialSize = 0; - } - this._growStrategy = (growStrategy || function(db, size) { - return db.used + size; - }).bind(null, this); - this._shrinkStrategy = (shrinkStrategy || function(db) { - return initialSize; - }).bind(null, this); - this._buffer = initialSize ? new Buffer(initialSize) : null; - this._offset = 0; - this._used = 0; - this._changeFactor = 0; - this.__defineGetter__('size', function(){ - return this._buffer == null ? 0 : this._buffer.length; - }); - this.__defineGetter__('used', function(){ - return this._used; - }); -} - -BufferPool.prototype.get = function(length) { - if (this._buffer == null || this._offset + length > this._buffer.length) { - var newBuf = new Buffer(this._growStrategy(length)); - this._buffer = newBuf; - this._offset = 0; - } - this._used += length; - var buf = this._buffer.slice(this._offset, this._offset + length); - this._offset += length; - return buf; -} - -BufferPool.prototype.reset = function(forceNewBuffer) { - var len = this._shrinkStrategy(); - if (len < this.size) this._changeFactor -= 1; - if (forceNewBuffer || this._changeFactor < -2) { - this._changeFactor = 0; - this._buffer = len ? new Buffer(len) : null; - } - this._offset = 0; - this._used = 0; -} - -module.exports = BufferPool; diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/BufferUtil.fallback.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/BufferUtil.fallback.js deleted file mode 100644 index 508542c9e5..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/BufferUtil.fallback.js +++ /dev/null @@ -1,47 +0,0 @@ -/*! - * ws: a node.js websocket client - * Copyright(c) 2011 Einar Otto Stangvik - * MIT Licensed - */ - -module.exports.BufferUtil = { - merge: function(mergedBuffer, buffers) { - var offset = 0; - for (var i = 0, l = buffers.length; i < l; ++i) { - var buf = buffers[i]; - buf.copy(mergedBuffer, offset); - offset += buf.length; - } - }, - mask: function(source, mask, output, offset, length) { - var maskNum = mask.readUInt32LE(0, true); - var i = 0; - for (; i < length - 3; i += 4) { - var num = maskNum ^ source.readUInt32LE(i, true); - if (num < 0) num = 4294967296 + num; - output.writeUInt32LE(num, offset + i, true); - } - switch (length % 4) { - case 3: output[offset + i + 2] = source[i + 2] ^ mask[2]; - case 2: output[offset + i + 1] = source[i + 1] ^ mask[1]; - case 1: output[offset + i] = source[i] ^ mask[0]; - case 0:; - } - }, - unmask: function(data, mask) { - var maskNum = mask.readUInt32LE(0, true); - var length = data.length; - var i = 0; - for (; i < length - 3; i += 4) { - var num = maskNum ^ data.readUInt32LE(i, true); - if (num < 0) num = 4294967296 + num; - data.writeUInt32LE(num, i, true); - } - switch (length % 4) { - case 3: data[i + 2] = data[i + 2] ^ mask[2]; - case 2: data[i + 1] = data[i + 1] ^ mask[1]; - case 1: data[i] = data[i] ^ mask[0]; - case 0:; - } - } -} diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/BufferUtil.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/BufferUtil.js deleted file mode 100644 index 15d35b98f5..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/BufferUtil.js +++ /dev/null @@ -1,16 +0,0 @@ -/*! - * ws: a node.js websocket client - * Copyright(c) 2011 Einar Otto Stangvik - * MIT Licensed - */ - -try { - module.exports = require('../build/Release/bufferutil'); -} catch (e) { try { - module.exports = require('../build/default/bufferutil'); -} catch (e) { try { - module.exports = require('./BufferUtil.fallback'); -} catch (e) { - console.error('bufferutil.node seems to not have been built. Run npm install.'); - throw e; -}}} diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/ErrorCodes.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/ErrorCodes.js deleted file mode 100644 index 55ebd529b7..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/ErrorCodes.js +++ /dev/null @@ -1,24 +0,0 @@ -/*! - * ws: a node.js websocket client - * Copyright(c) 2011 Einar Otto Stangvik - * MIT Licensed - */ - -module.exports = { - isValidErrorCode: function(code) { - return (code >= 1000 && code <= 1011 && code != 1004 && code != 1005 && code != 1006) || - (code >= 3000 && code <= 4999); - }, - 1000: 'normal', - 1001: 'going away', - 1002: 'protocol error', - 1003: 'unsupported data', - 1004: 'reserved', - 1005: 'reserved for extensions', - 1006: 'reserved for extensions', - 1007: 'inconsistent or invalid data', - 1008: 'policy violation', - 1009: 'message too big', - 1010: 'extension handshake missing', - 1011: 'an unexpected condition prevented the request from being fulfilled', -}; \ No newline at end of file diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/Receiver.hixie.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/Receiver.hixie.js deleted file mode 100644 index a8e41c47b5..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/Receiver.hixie.js +++ /dev/null @@ -1,180 +0,0 @@ -/*! - * ws: a node.js websocket client - * Copyright(c) 2011 Einar Otto Stangvik - * MIT Licensed - */ - -var util = require('util'); - -/** - * State constants - */ - -var EMPTY = 0 - , BODY = 1; -var BINARYLENGTH = 2 - , BINARYBODY = 3; - -/** - * Hixie Receiver implementation - */ - -function Receiver () { - this.state = EMPTY; - this.buffers = []; - this.messageEnd = -1; - this.spanLength = 0; - this.dead = false; - - this.onerror = function() {}; - this.ontext = function() {}; - this.onbinary = function() {}; - this.onclose = function() {}; - this.onping = function() {}; - this.onpong = function() {}; -} - -module.exports = Receiver; - -/** - * Add new data to the parser. - * - * @api public - */ - -Receiver.prototype.add = function(data) { - var self = this; - function doAdd() { - if (self.state === EMPTY) { - if (data.length == 2 && data[0] == 0xFF && data[1] == 0x00) { - self.reset(); - self.onclose(); - return; - } - if (data[0] === 0x80) { - self.messageEnd = 0; - self.state = BINARYLENGTH; - data = data.slice(1); - } else { - - if (data[0] !== 0x00) { - self.error('payload must start with 0x00 byte', true); - return; - } - data = data.slice(1); - self.state = BODY; - - } - } - if (self.state === BINARYLENGTH) { - var i = 0; - while ((i < data.length) && (data[i] & 0x80)) { - self.messageEnd = 128 * self.messageEnd + (data[i] & 0x7f); - ++i; - } - if (i < data.length) { - self.messageEnd = 128 * self.messageEnd + (data[i] & 0x7f); - self.state = BINARYBODY; - ++i; - } - if (i > 0) - data = data.slice(i); - } - if (self.state === BINARYBODY) { - var dataleft = self.messageEnd - self.spanLength; - if (data.length >= dataleft) { - // consume the whole buffer to finish the frame - self.buffers.push(data); - self.spanLength += dataleft; - self.messageEnd = dataleft; - return self.parse(); - } - // frame's not done even if we consume it all - self.buffers.push(data); - self.spanLength += data.length; - return; - } - self.buffers.push(data); - if ((self.messageEnd = bufferIndex(data, 0xFF)) != -1) { - self.spanLength += self.messageEnd; - return self.parse(); - } - else self.spanLength += data.length; - } - while(data) data = doAdd(); -}; - -/** - * Releases all resources used by the receiver. - * - * @api public - */ - -Receiver.prototype.cleanup = function() { - this.dead = true; - this.state = EMPTY; - this.buffers = []; -}; - -/** - * Process buffered data. - * - * @api public - */ - -Receiver.prototype.parse = function() { - var output = new Buffer(this.spanLength); - var outputIndex = 0; - for (var bi = 0, bl = this.buffers.length; bi < bl - 1; ++bi) { - var buffer = this.buffers[bi]; - buffer.copy(output, outputIndex); - outputIndex += buffer.length; - } - var lastBuffer = this.buffers[this.buffers.length - 1]; - if (this.messageEnd > 0) lastBuffer.copy(output, outputIndex, 0, this.messageEnd); - if (this.state !== BODY) --this.messageEnd; - var tail = null; - if (this.messageEnd < lastBuffer.length - 1) { - tail = lastBuffer.slice(this.messageEnd + 1); - } - this.reset(); - this.ontext(output.toString('utf8')); - return tail; -}; - -/** - * Handles an error - * - * @api private - */ - -Receiver.prototype.error = function (reason, terminate) { - this.reset(); - this.onerror(reason, terminate); - return this; -}; - -/** - * Reset parser state - * - * @api private - */ - -Receiver.prototype.reset = function (reason) { - if (this.dead) return; - this.state = EMPTY; - this.buffers = []; - this.messageEnd = -1; - this.spanLength = 0; -}; - -/** - * Internal api - */ - -function bufferIndex(buffer, byte) { - for (var i = 0, l = buffer.length; i < l; ++i) { - if (buffer[i] === byte) return i; - } - return -1; -} diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/Receiver.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/Receiver.js deleted file mode 100644 index 004cd32c16..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/Receiver.js +++ /dev/null @@ -1,585 +0,0 @@ -/*! - * ws: a node.js websocket client - * Copyright(c) 2011 Einar Otto Stangvik - * MIT Licensed - */ - -var util = require('util') - , Validation = require('./Validation').Validation - , ErrorCodes = require('./ErrorCodes') - , BufferPool = require('./BufferPool') - , bufferUtil = require('./BufferUtil').BufferUtil; - -/** - * HyBi Receiver implementation - */ - -function Receiver () { - // memory pool for fragmented messages - var fragmentedPoolPrevUsed = -1; - this.fragmentedBufferPool = new BufferPool(1024, function(db, length) { - return db.used + length; - }, function(db) { - return fragmentedPoolPrevUsed = fragmentedPoolPrevUsed >= 0 ? - (fragmentedPoolPrevUsed + db.used) / 2 : - db.used; - }); - - // memory pool for unfragmented messages - var unfragmentedPoolPrevUsed = -1; - this.unfragmentedBufferPool = new BufferPool(1024, function(db, length) { - return db.used + length; - }, function(db) { - return unfragmentedPoolPrevUsed = unfragmentedPoolPrevUsed >= 0 ? - (unfragmentedPoolPrevUsed + db.used) / 2 : - db.used; - }); - - this.state = { - activeFragmentedOperation: null, - lastFragment: false, - masked: false, - opcode: 0, - fragmentedOperation: false - }; - this.overflow = []; - this.headerBuffer = new Buffer(10); - this.expectOffset = 0; - this.expectBuffer = null; - this.expectHandler = null; - this.currentMessage = []; - this.expectHeader(2, this.processPacket); - this.dead = false; - - this.onerror = function() {}; - this.ontext = function() {}; - this.onbinary = function() {}; - this.onclose = function() {}; - this.onping = function() {}; - this.onpong = function() {}; -} - -module.exports = Receiver; - -/** - * Add new data to the parser. - * - * @api public - */ - -Receiver.prototype.add = function(data) { - var dataLength = data.length; - if (dataLength == 0) return; - if (this.expectBuffer == null) { - this.overflow.push(data); - return; - } - var toRead = Math.min(dataLength, this.expectBuffer.length - this.expectOffset); - fastCopy(toRead, data, this.expectBuffer, this.expectOffset); - this.expectOffset += toRead; - if (toRead < dataLength) { - this.overflow.push(data.slice(toRead)); - } - while (this.expectBuffer && this.expectOffset == this.expectBuffer.length) { - var bufferForHandler = this.expectBuffer; - this.expectBuffer = null; - this.expectOffset = 0; - this.expectHandler.call(this, bufferForHandler); - } -}; - -/** - * Releases all resources used by the receiver. - * - * @api public - */ - -Receiver.prototype.cleanup = function() { - this.dead = true; - this.overflow = null; - this.headerBuffer = null; - this.expectBuffer = null; - this.expectHandler = null; - this.unfragmentedBufferPool = null; - this.fragmentedBufferPool = null; - this.state = null; - this.currentMessage = null; - this.onerror = null; - this.ontext = null; - this.onbinary = null; - this.onclose = null; - this.onping = null; - this.onpong = null; -}; - -/** - * Waits for a certain amount of header bytes to be available, then fires a callback. - * - * @api private - */ - -Receiver.prototype.expectHeader = function(length, handler) { - if (length == 0) { - handler(null); - return; - } - this.expectBuffer = this.headerBuffer.slice(this.expectOffset, this.expectOffset + length); - this.expectHandler = handler; - var toRead = length; - while (toRead > 0 && this.overflow.length > 0) { - var fromOverflow = this.overflow.pop(); - if (toRead < fromOverflow.length) this.overflow.push(fromOverflow.slice(toRead)); - var read = Math.min(fromOverflow.length, toRead); - fastCopy(read, fromOverflow, this.expectBuffer, this.expectOffset); - this.expectOffset += read; - toRead -= read; - } -}; - -/** - * Waits for a certain amount of data bytes to be available, then fires a callback. - * - * @api private - */ - -Receiver.prototype.expectData = function(length, handler) { - if (length == 0) { - handler(null); - return; - } - this.expectBuffer = this.allocateFromPool(length, this.state.fragmentedOperation); - this.expectHandler = handler; - var toRead = length; - while (toRead > 0 && this.overflow.length > 0) { - var fromOverflow = this.overflow.pop(); - if (toRead < fromOverflow.length) this.overflow.push(fromOverflow.slice(toRead)); - var read = Math.min(fromOverflow.length, toRead); - fastCopy(read, fromOverflow, this.expectBuffer, this.expectOffset); - this.expectOffset += read; - toRead -= read; - } -}; - -/** - * Allocates memory from the buffer pool. - * - * @api private - */ - -Receiver.prototype.allocateFromPool = function(length, isFragmented) { - return (isFragmented ? this.fragmentedBufferPool : this.unfragmentedBufferPool).get(length); -}; - -/** - * Start processing a new packet. - * - * @api private - */ - -Receiver.prototype.processPacket = function (data) { - if ((data[0] & 0x70) != 0) { - this.error('reserved fields must be empty', 1002); - return; - } - this.state.lastFragment = (data[0] & 0x80) == 0x80; - this.state.masked = (data[1] & 0x80) == 0x80; - var opcode = data[0] & 0xf; - if (opcode === 0) { - // continuation frame - this.state.fragmentedOperation = true; - this.state.opcode = this.state.activeFragmentedOperation; - if (!(this.state.opcode == 1 || this.state.opcode == 2)) { - this.error('continuation frame cannot follow current opcode', 1002); - return; - } - } - else { - if (opcode < 3 && this.state.activeFragmentedOperation != null) { - this.error('data frames after the initial data frame must have opcode 0', 1002); - return; - } - this.state.opcode = opcode; - if (this.state.lastFragment === false) { - this.state.fragmentedOperation = true; - this.state.activeFragmentedOperation = opcode; - } - else this.state.fragmentedOperation = false; - } - var handler = opcodes[this.state.opcode]; - if (typeof handler == 'undefined') this.error('no handler for opcode ' + this.state.opcode, 1002); - else { - handler.start.call(this, data); - } -}; - -/** - * Endprocessing a packet. - * - * @api private - */ - -Receiver.prototype.endPacket = function() { - if (!this.state.fragmentedOperation) this.unfragmentedBufferPool.reset(true); - else if (this.state.lastFragment) this.fragmentedBufferPool.reset(false); - this.expectOffset = 0; - this.expectBuffer = null; - this.expectHandler = null; - if (this.state.lastFragment && this.state.opcode === this.state.activeFragmentedOperation) { - // end current fragmented operation - this.state.activeFragmentedOperation = null; - } - this.state.lastFragment = false; - this.state.opcode = this.state.activeFragmentedOperation != null ? this.state.activeFragmentedOperation : 0; - this.state.masked = false; - this.expectHeader(2, this.processPacket); -}; - -/** - * Reset the parser state. - * - * @api private - */ - -Receiver.prototype.reset = function() { - if (this.dead) return; - this.state = { - activeFragmentedOperation: null, - lastFragment: false, - masked: false, - opcode: 0, - fragmentedOperation: false - }; - this.fragmentedBufferPool.reset(true); - this.unfragmentedBufferPool.reset(true); - this.expectOffset = 0; - this.expectBuffer = null; - this.expectHandler = null; - this.overflow = []; - this.currentMessage = []; -}; - -/** - * Unmask received data. - * - * @api private - */ - -Receiver.prototype.unmask = function (mask, buf, binary) { - if (mask != null && buf != null) bufferUtil.unmask(buf, mask); - if (binary) return buf; - return buf != null ? buf.toString('utf8') : ''; -}; - -/** - * Concatenates a list of buffers. - * - * @api private - */ - -Receiver.prototype.concatBuffers = function(buffers) { - var length = 0; - for (var i = 0, l = buffers.length; i < l; ++i) length += buffers[i].length; - var mergedBuffer = new Buffer(length); - bufferUtil.merge(mergedBuffer, buffers); - return mergedBuffer; -}; - -/** - * Handles an error - * - * @api private - */ - -Receiver.prototype.error = function (reason, protocolErrorCode) { - this.reset(); - this.onerror(reason, protocolErrorCode); - return this; -}; - -/** - * Buffer utilities - */ - -function readUInt16BE(start) { - return (this[start]<<8) + - this[start+1]; -} - -function readUInt32BE(start) { - return (this[start]<<24) + - (this[start+1]<<16) + - (this[start+2]<<8) + - this[start+3]; -} - -function fastCopy(length, srcBuffer, dstBuffer, dstOffset) { - switch (length) { - default: srcBuffer.copy(dstBuffer, dstOffset, 0, length); break; - case 16: dstBuffer[dstOffset+15] = srcBuffer[15]; - case 15: dstBuffer[dstOffset+14] = srcBuffer[14]; - case 14: dstBuffer[dstOffset+13] = srcBuffer[13]; - case 13: dstBuffer[dstOffset+12] = srcBuffer[12]; - case 12: dstBuffer[dstOffset+11] = srcBuffer[11]; - case 11: dstBuffer[dstOffset+10] = srcBuffer[10]; - case 10: dstBuffer[dstOffset+9] = srcBuffer[9]; - case 9: dstBuffer[dstOffset+8] = srcBuffer[8]; - case 8: dstBuffer[dstOffset+7] = srcBuffer[7]; - case 7: dstBuffer[dstOffset+6] = srcBuffer[6]; - case 6: dstBuffer[dstOffset+5] = srcBuffer[5]; - case 5: dstBuffer[dstOffset+4] = srcBuffer[4]; - case 4: dstBuffer[dstOffset+3] = srcBuffer[3]; - case 3: dstBuffer[dstOffset+2] = srcBuffer[2]; - case 2: dstBuffer[dstOffset+1] = srcBuffer[1]; - case 1: dstBuffer[dstOffset] = srcBuffer[0]; - } -} - -/** - * Opcode handlers - */ - -var opcodes = { - // text - '1': { - start: function(data) { - var self = this; - // decode length - var firstLength = data[1] & 0x7f; - if (firstLength < 126) { - opcodes['1'].getData.call(self, firstLength); - } - else if (firstLength == 126) { - self.expectHeader(2, function(data) { - opcodes['1'].getData.call(self, readUInt16BE.call(data, 0)); - }); - } - else if (firstLength == 127) { - self.expectHeader(8, function(data) { - if (readUInt32BE.call(data, 0) != 0) { - self.error('packets with length spanning more than 32 bit is currently not supported', 1008); - return; - } - opcodes['1'].getData.call(self, readUInt32BE.call(data, 4)); - }); - } - }, - getData: function(length) { - var self = this; - if (self.state.masked) { - self.expectHeader(4, function(data) { - var mask = data; - self.expectData(length, function(data) { - opcodes['1'].finish.call(self, mask, data); - }); - }); - } - else { - self.expectData(length, function(data) { - opcodes['1'].finish.call(self, null, data); - }); - } - }, - finish: function(mask, data) { - var packet = this.unmask(mask, data, true); - if (packet != null) this.currentMessage.push(packet); - if (this.state.lastFragment) { - var messageBuffer = this.concatBuffers(this.currentMessage); - if (!Validation.isValidUTF8(messageBuffer)) { - this.error('invalid utf8 sequence', 1007); - return; - } - this.ontext(messageBuffer.toString('utf8'), {masked: this.state.masked, buffer: messageBuffer}); - this.currentMessage = []; - } - this.endPacket(); - } - }, - // binary - '2': { - start: function(data) { - var self = this; - // decode length - var firstLength = data[1] & 0x7f; - if (firstLength < 126) { - opcodes['2'].getData.call(self, firstLength); - } - else if (firstLength == 126) { - self.expectHeader(2, function(data) { - opcodes['2'].getData.call(self, readUInt16BE.call(data, 0)); - }); - } - else if (firstLength == 127) { - self.expectHeader(8, function(data) { - if (readUInt32BE.call(data, 0) != 0) { - self.error('packets with length spanning more than 32 bit is currently not supported', 1008); - return; - } - opcodes['2'].getData.call(self, readUInt32BE.call(data, 4, true)); - }); - } - }, - getData: function(length) { - var self = this; - if (self.state.masked) { - self.expectHeader(4, function(data) { - var mask = data; - self.expectData(length, function(data) { - opcodes['2'].finish.call(self, mask, data); - }); - }); - } - else { - self.expectData(length, function(data) { - opcodes['2'].finish.call(self, null, data); - }); - } - }, - finish: function(mask, data) { - var packet = this.unmask(mask, data, true); - if (packet != null) this.currentMessage.push(packet); - if (this.state.lastFragment) { - var messageBuffer = this.concatBuffers(this.currentMessage); - this.onbinary(messageBuffer, {masked: this.state.masked, buffer: messageBuffer}); - this.currentMessage = []; - } - this.endPacket(); - } - }, - // close - '8': { - start: function(data) { - var self = this; - if (self.state.lastFragment == false) { - self.error('fragmented close is not supported', 1002); - return; - } - - // decode length - var firstLength = data[1] & 0x7f; - if (firstLength < 126) { - opcodes['8'].getData.call(self, firstLength); - } - else { - self.error('control frames cannot have more than 125 bytes of data', 1002); - } - }, - getData: function(length) { - var self = this; - if (self.state.masked) { - self.expectHeader(4, function(data) { - var mask = data; - self.expectData(length, function(data) { - opcodes['8'].finish.call(self, mask, data); - }); - }); - } - else { - self.expectData(length, function(data) { - opcodes['8'].finish.call(self, null, data); - }); - } - }, - finish: function(mask, data) { - var self = this; - data = self.unmask(mask, data, true); - if (data && data.length == 1) { - self.error('close packets with data must be at least two bytes long', 1002); - return; - } - var code = data && data.length > 1 ? readUInt16BE.call(data, 0) : 1000; - if (!ErrorCodes.isValidErrorCode(code)) { - self.error('invalid error code', 1002); - return; - } - var message = ''; - if (data && data.length > 2) { - var messageBuffer = data.slice(2); - if (!Validation.isValidUTF8(messageBuffer)) { - self.error('invalid utf8 sequence', 1007); - return; - } - message = messageBuffer.toString('utf8'); - } - this.onclose(code, message, {masked: self.state.masked}); - this.reset(); - }, - }, - // ping - '9': { - start: function(data) { - var self = this; - if (self.state.lastFragment == false) { - self.error('fragmented ping is not supported', 1002); - return; - } - - // decode length - var firstLength = data[1] & 0x7f; - if (firstLength < 126) { - opcodes['9'].getData.call(self, firstLength); - } - else { - self.error('control frames cannot have more than 125 bytes of data', 1002); - } - }, - getData: function(length) { - var self = this; - if (self.state.masked) { - self.expectHeader(4, function(data) { - var mask = data; - self.expectData(length, function(data) { - opcodes['9'].finish.call(self, mask, data); - }); - }); - } - else { - self.expectData(length, function(data) { - opcodes['9'].finish.call(self, null, data); - }); - } - }, - finish: function(mask, data) { - this.onping(this.unmask(mask, data, true), {masked: this.state.masked, binary: true}); - this.endPacket(); - } - }, - // pong - '10': { - start: function(data) { - var self = this; - if (self.state.lastFragment == false) { - self.error('fragmented pong is not supported', 1002); - return; - } - - // decode length - var firstLength = data[1] & 0x7f; - if (firstLength < 126) { - opcodes['10'].getData.call(self, firstLength); - } - else { - self.error('control frames cannot have more than 125 bytes of data', 1002); - } - }, - getData: function(length) { - var self = this; - if (this.state.masked) { - this.expectHeader(4, function(data) { - var mask = data; - self.expectData(length, function(data) { - opcodes['10'].finish.call(self, mask, data); - }); - }); - } - else { - this.expectData(length, function(data) { - opcodes['10'].finish.call(self, null, data); - }); - } - }, - finish: function(mask, data) { - this.onpong(this.unmask(mask, data, true), {masked: this.state.masked, binary: true}); - this.endPacket(); - } - } -} diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/Sender.hixie.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/Sender.hixie.js deleted file mode 100644 index c715dbdc7e..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/Sender.hixie.js +++ /dev/null @@ -1,118 +0,0 @@ -/*! - * ws: a node.js websocket client - * Copyright(c) 2011 Einar Otto Stangvik - * MIT Licensed - */ - -var events = require('events') - , util = require('util') - , EventEmitter = events.EventEmitter; - -/** - * Hixie Sender implementation - */ - -function Sender(socket) { - this.socket = socket; - this.continuationFrame = false; - this.isClosed = false; -} - -module.exports = Sender; - -/** - * Inherits from EventEmitter. - */ - -util.inherits(Sender, events.EventEmitter); - -/** - * Frames and writes data. - * - * @api public - */ - -Sender.prototype.send = function(data, options, cb) { - if (this.isClosed) return; - - var isString = typeof data == 'string' - , length = isString ? Buffer.byteLength(data) : data.length - , lengthbytes = (length > 127) ? 2 : 1 // assume less than 2**14 bytes - , writeStartMarker = this.continuationFrame == false - , writeEndMarker = !options || !(typeof options.fin != 'undefined' && !options.fin) - , buffer = new Buffer((writeStartMarker ? ((options && options.binary) ? (1 + lengthbytes) : 1) : 0) + length + ((writeEndMarker && !(options && options.binary)) ? 1 : 0)) - , offset = writeStartMarker ? 1 : 0; - - if (writeStartMarker) { - if (options && options.binary) { - buffer.write('\x80', 'binary'); - // assume length less than 2**14 bytes - if (lengthbytes > 1) - buffer.write(String.fromCharCode(128+length/128), offset++, 'binary'); - buffer.write(String.fromCharCode(length&0x7f), offset++, 'binary'); - } else - buffer.write('\x00', 'binary'); - } - - if (isString) buffer.write(data, offset, 'utf8'); - else data.copy(buffer, offset, 0); - - if (writeEndMarker) { - if (options && options.binary) { - // sending binary, not writing end marker - } else - buffer.write('\xff', offset + length, 'binary'); - this.continuationFrame = false; - } - else this.continuationFrame = true; - - try { - this.socket.write(buffer, 'binary', cb); - } catch (e) { - this.error(e.toString()); - } -}; - -/** - * Sends a close instruction to the remote party. - * - * @api public - */ - -Sender.prototype.close = function(code, data, mask, cb) { - if (this.isClosed) return; - this.isClosed = true; - try { - if (this.continuationFrame) this.socket.write(new Buffer([0xff], 'binary')); - this.socket.write(new Buffer([0xff, 0x00]), 'binary', cb); - } catch (e) { - this.error(e.toString()); - } -}; - -/** - * Sends a ping message to the remote party. Not available for hixie. - * - * @api public - */ - -Sender.prototype.ping = function(data, options) {}; - -/** - * Sends a pong message to the remote party. Not available for hixie. - * - * @api public - */ - -Sender.prototype.pong = function(data, options) {}; - -/** - * Handles an error - * - * @api private - */ - -Sender.prototype.error = function (reason) { - this.emit('error', reason); - return this; -}; diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/Sender.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/Sender.js deleted file mode 100644 index bc6ea7308f..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/Sender.js +++ /dev/null @@ -1,227 +0,0 @@ -/*! - * ws: a node.js websocket client - * Copyright(c) 2011 Einar Otto Stangvik - * MIT Licensed - */ - -var events = require('events') - , util = require('util') - , EventEmitter = events.EventEmitter - , ErrorCodes = require('./ErrorCodes') - , bufferUtil = require('./BufferUtil').BufferUtil; - -/** - * HyBi Sender implementation - */ - -function Sender(socket) { - this._socket = socket; - this.firstFragment = true; -} - -/** - * Inherits from EventEmitter. - */ - -util.inherits(Sender, events.EventEmitter); - -/** - * Sends a close instruction to the remote party. - * - * @api public - */ - -Sender.prototype.close = function(code, data, mask) { - if (typeof code !== 'undefined') { - if (typeof code !== 'number' || - !ErrorCodes.isValidErrorCode(code)) throw new Error('first argument must be a valid error code number'); - } - code = code || 1000; - var dataBuffer = new Buffer(2 + (data ? Buffer.byteLength(data) : 0)); - writeUInt16BE.call(dataBuffer, code, 0); - if (dataBuffer.length > 2) dataBuffer.write(data, 2); - this.frameAndSend(0x8, dataBuffer, true, mask); -}; - -/** - * Sends a ping message to the remote party. - * - * @api public - */ - -Sender.prototype.ping = function(data, options) { - var mask = options && options.mask; - this.frameAndSend(0x9, data || '', true, mask); -}; - -/** - * Sends a pong message to the remote party. - * - * @api public - */ - -Sender.prototype.pong = function(data, options) { - var mask = options && options.mask; - this.frameAndSend(0xa, data || '', true, mask); -}; - -/** - * Sends text or binary data to the remote party. - * - * @api public - */ - -Sender.prototype.send = function(data, options, cb) { - var finalFragment = options && options.fin === false ? false : true; - var mask = options && options.mask; - var opcode = options && options.binary ? 2 : 1; - if (this.firstFragment === false) opcode = 0; - else this.firstFragment = false; - if (finalFragment) this.firstFragment = true - this.frameAndSend(opcode, data, finalFragment, mask, cb); -}; - -/** - * Frames and sends a piece of data according to the HyBi WebSocket protocol. - * - * @api private - */ - -Sender.prototype.frameAndSend = function(opcode, data, finalFragment, maskData, cb) { - var canModifyData = false; - - if (!data) { - try { - this._socket.write(new Buffer([opcode | (finalFragment ? 0x80 : 0), 0 | (maskData ? 0x80 : 0)].concat(maskData ? [0, 0, 0, 0] : [])), 'binary', cb); - } - catch (e) { - if (typeof cb == 'function') cb(e); - else this.emit('error', e); - } - return; - } - - if (!Buffer.isBuffer(data)) { - canModifyData = true; - if (data && (typeof data.byteLength !== 'undefined' || typeof data.buffer !== 'undefined')) { - data = getArrayBuffer(data); - } else { - data = new Buffer(data); - } - } - - var dataLength = data.length - , dataOffset = maskData ? 6 : 2 - , secondByte = dataLength; - - if (dataLength >= 65536) { - dataOffset += 8; - secondByte = 127; - } - else if (dataLength > 125) { - dataOffset += 2; - secondByte = 126; - } - - var mergeBuffers = dataLength < 32768 || (maskData && !canModifyData); - var totalLength = mergeBuffers ? dataLength + dataOffset : dataOffset; - var outputBuffer = new Buffer(totalLength); - outputBuffer[0] = finalFragment ? opcode | 0x80 : opcode; - - switch (secondByte) { - case 126: - writeUInt16BE.call(outputBuffer, dataLength, 2); - break; - case 127: - writeUInt32BE.call(outputBuffer, 0, 2); - writeUInt32BE.call(outputBuffer, dataLength, 6); - } - - if (maskData) { - outputBuffer[1] = secondByte | 0x80; - var mask = this._randomMask || (this._randomMask = getRandomMask()); - outputBuffer[dataOffset - 4] = mask[0]; - outputBuffer[dataOffset - 3] = mask[1]; - outputBuffer[dataOffset - 2] = mask[2]; - outputBuffer[dataOffset - 1] = mask[3]; - if (mergeBuffers) { - bufferUtil.mask(data, mask, outputBuffer, dataOffset, dataLength); - try { - this._socket.write(outputBuffer, 'binary', cb); - } - catch (e) { - if (typeof cb == 'function') cb(e); - else this.emit('error', e); - } - } - else { - bufferUtil.mask(data, mask, data, 0, dataLength); - try { - this._socket.write(outputBuffer, 'binary'); - this._socket.write(data, 'binary', cb); - } - catch (e) { - if (typeof cb == 'function') cb(e); - else this.emit('error', e); - } - } - } - else { - outputBuffer[1] = secondByte; - if (mergeBuffers) { - data.copy(outputBuffer, dataOffset); - try { - this._socket.write(outputBuffer, 'binary', cb); - } - catch (e) { - if (typeof cb == 'function') cb(e); - else this.emit('error', e); - } - } - else { - try { - this._socket.write(outputBuffer, 'binary'); - this._socket.write(data, 'binary', cb); - } - catch (e) { - if (typeof cb == 'function') cb(e); - else this.emit('error', e); - } - } - } -}; - -module.exports = Sender; - -function writeUInt16BE(value, offset) { - this[offset] = (value & 0xff00)>>8; - this[offset+1] = value & 0xff; -} - -function writeUInt32BE(value, offset) { - this[offset] = (value & 0xff000000)>>24; - this[offset+1] = (value & 0xff0000)>>16; - this[offset+2] = (value & 0xff00)>>8; - this[offset+3] = value & 0xff; -} - -function getArrayBuffer(data) { - // data is either an ArrayBuffer or ArrayBufferView. - var array = new Uint8Array(data.buffer || data) - , l = data.byteLength || data.length - , o = data.byteOffset || 0 - , buffer = new Buffer(l); - for (var i = 0; i < l; ++i) { - buffer[i] = array[o+i]; - } - return buffer; -} - -function getRandomMask() { - return new Buffer([ - ~~(Math.random() * 255), - ~~(Math.random() * 255), - ~~(Math.random() * 255), - ~~(Math.random() * 255) - ]); -} diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/Validation.fallback.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/Validation.fallback.js deleted file mode 100644 index 2c7c4fd48b..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/Validation.fallback.js +++ /dev/null @@ -1,12 +0,0 @@ -/*! - * ws: a node.js websocket client - * Copyright(c) 2011 Einar Otto Stangvik - * MIT Licensed - */ - -module.exports.Validation = { - isValidUTF8: function(buffer) { - return true; - } -}; - diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/Validation.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/Validation.js deleted file mode 100644 index 0f3109a05a..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/Validation.js +++ /dev/null @@ -1,16 +0,0 @@ -/*! - * ws: a node.js websocket client - * Copyright(c) 2011 Einar Otto Stangvik - * MIT Licensed - */ - -try { - module.exports = require('../build/Release/validation'); -} catch (e) { try { - module.exports = require('../build/default/validation'); -} catch (e) { try { - module.exports = require('./Validation.fallback'); -} catch (e) { - console.error('validation.node seems to not have been built. Run npm install.'); - throw e; -}}} diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/WebSocket.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/WebSocket.js deleted file mode 100644 index 8c304ebbd0..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/WebSocket.js +++ /dev/null @@ -1,794 +0,0 @@ -/*! - * ws: a node.js websocket client - * Copyright(c) 2011 Einar Otto Stangvik - * MIT Licensed - */ - -var util = require('util') - , events = require('events') - , http = require('http') - , https = require('https') - , crypto = require('crypto') - , url = require('url') - , stream = require('stream') - , Options = require('options') - , Sender = require('./Sender') - , Receiver = require('./Receiver') - , SenderHixie = require('./Sender.hixie') - , ReceiverHixie = require('./Receiver.hixie'); - -/** - * Constants - */ - -// Default protocol version - -var protocolVersion = 13; - -// Close timeout - -var closeTimeout = 30000; // Allow 5 seconds to terminate the connection cleanly - -/** - * WebSocket implementation - */ - -function WebSocket(address, protocols, options) { - - if (protocols && !Array.isArray(protocols) && 'object' == typeof protocols) { - // accept the "options" Object as the 2nd argument - options = protocols; - protocols = null; - } - if ('string' == typeof protocols) { - protocols = [ protocols ]; - } - if (!Array.isArray(protocols)) { - protocols = []; - } - // TODO: actually handle the `Sub-Protocols` part of the WebSocket client - - this._socket = null; - this.bytesReceived = 0; - this.readyState = null; - this.supports = {}; - - if (Array.isArray(address)) { - initAsServerClient.apply(this, address.concat(options)); - } else { - initAsClient.apply(this, [address, protocols, options]); - } -} - -/** - * Inherits from EventEmitter. - */ - -util.inherits(WebSocket, events.EventEmitter); - -/** - * Ready States - */ - -["CONNECTING", "OPEN", "CLOSING", "CLOSED"].forEach(function (state, index) { - WebSocket.prototype[state] = WebSocket[state] = index; -}); - -/** - * Gracefully closes the connection, after sending a description message to the server - * - * @param {Object} data to be sent to the server - * @api public - */ - -WebSocket.prototype.close = function(code, data) { - if (this.readyState == WebSocket.CLOSING || this.readyState == WebSocket.CLOSED) return; - if (this.readyState == WebSocket.CONNECTING) { - this.readyState = WebSocket.CLOSED; - return; - } - try { - this.readyState = WebSocket.CLOSING; - this._closeCode = code; - this._closeMessage = data; - var mask = !this._isServer; - this._sender.close(code, data, mask); - } - catch (e) { - this.emit('error', e); - } - finally { - this.terminate(); - } -} - -/** - * Pause the client stream - * - * @api public - */ - -WebSocket.prototype.pause = function() { - if (this.readyState != WebSocket.OPEN) throw new Error('not opened'); - return this._socket.pause(); -} - -/** - * Sends a ping - * - * @param {Object} data to be sent to the server - * @param {Object} Members - mask: boolean, binary: boolean - * @param {boolean} dontFailWhenClosed indicates whether or not to throw if the connection isnt open - * @api public - */ - -WebSocket.prototype.ping = function(data, options, dontFailWhenClosed) { - if (this.readyState != WebSocket.OPEN) { - if (dontFailWhenClosed === true) return; - throw new Error('not opened'); - } - options = options || {}; - if (typeof options.mask == 'undefined') options.mask = !this._isServer; - this._sender.ping(data, options); -} - -/** - * Sends a pong - * - * @param {Object} data to be sent to the server - * @param {Object} Members - mask: boolean, binary: boolean - * @param {boolean} dontFailWhenClosed indicates whether or not to throw if the connection isnt open - * @api public - */ - -WebSocket.prototype.pong = function(data, options, dontFailWhenClosed) { - if (this.readyState != WebSocket.OPEN) { - if (dontFailWhenClosed === true) return; - throw new Error('not opened'); - } - options = options || {}; - if (typeof options.mask == 'undefined') options.mask = !this._isServer; - this._sender.pong(data, options); -} - -/** - * Resume the client stream - * - * @api public - */ - -WebSocket.prototype.resume = function() { - if (this.readyState != WebSocket.OPEN) throw new Error('not opened'); - return this._socket.resume(); -} - -/** - * Sends a piece of data - * - * @param {Object} data to be sent to the server - * @param {Object} Members - mask: boolean, binary: boolean - * @param {function} Optional callback which is executed after the send completes - * @api public - */ - -WebSocket.prototype.send = function(data, options, cb) { - if (typeof options == 'function') { - cb = options; - options = {}; - } - if (this.readyState != WebSocket.OPEN) { - if (typeof cb == 'function') cb(new Error('not opened')); - else throw new Error('not opened'); - return; - } - if (!data) data = ''; - if (this._queue) { - var self = this; - this._queue.push(function() { self.send(data, options, cb); }); - return; - } - options = options || {}; - options.fin = true; - if (typeof options.binary == 'undefined') { - options.binary = (data instanceof ArrayBuffer || data instanceof Buffer || - data instanceof Uint8Array || - data instanceof Uint16Array || - data instanceof Uint32Array || - data instanceof Int8Array || - data instanceof Int16Array || - data instanceof Int32Array || - data instanceof Float32Array || - data instanceof Float64Array); - } - if (typeof options.mask == 'undefined') options.mask = !this._isServer; - var readable = typeof stream.Readable == 'function' ? stream.Readable : stream.Stream; - if (data instanceof readable) { - startQueue(this); - var self = this; - sendStream(this, data, options, function(error) { - process.nextTick(function() { executeQueueSends(self); }); - if (typeof cb == 'function') cb(error); - }); - } - else this._sender.send(data, options, cb); -} - -/** - * Streams data through calls to a user supplied function - * - * @param {Object} Members - mask: boolean, binary: boolean - * @param {function} 'function (error, send)' which is executed on successive ticks of which send is 'function (data, final)'. - * @api public - */ - -WebSocket.prototype.stream = function(options, cb) { - if (typeof options == 'function') { - cb = options; - options = {}; - } - var self = this; - if (typeof cb != 'function') throw new Error('callback must be provided'); - if (this.readyState != WebSocket.OPEN) { - if (typeof cb == 'function') cb(new Error('not opened')); - else throw new Error('not opened'); - return; - } - if (this._queue) { - this._queue.push(function() { self.stream(options, cb); }); - return; - } - options = options || {}; - if (typeof options.mask == 'undefined') options.mask = !this._isServer; - startQueue(this); - var send = function(data, final) { - try { - if (self.readyState != WebSocket.OPEN) throw new Error('not opened'); - options.fin = final === true; - self._sender.send(data, options); - if (!final) process.nextTick(cb.bind(null, null, send)); - else executeQueueSends(self); - } - catch (e) { - if (typeof cb == 'function') cb(e); - else { - delete self._queue; - self.emit('error', e); - } - } - } - process.nextTick(cb.bind(null, null, send)); -} - -/** - * Immediately shuts down the connection - * - * @api public - */ - -WebSocket.prototype.terminate = function() { - if (this.readyState == WebSocket.CLOSED) return; - if (this._socket) { - try { - // End the connection - this._socket.end(); - } - catch (e) { - // Socket error during end() call, so just destroy it right now - cleanupWebsocketResources.call(this, true); - return; - } - - // Add a timeout to ensure that the connection is completely - // cleaned up within 30 seconds, even if the clean close procedure - // fails for whatever reason - this._closeTimer = setTimeout(cleanupWebsocketResources.bind(this, true), closeTimeout); - } - else if (this.readyState == WebSocket.CONNECTING) { - cleanupWebsocketResources.call(this, true); - } -}; - -/** - * Expose bufferedAmount - * - * @api public - */ - -Object.defineProperty(WebSocket.prototype, 'bufferedAmount', { - get: function get() { - var amount = 0; - if (this._socket) { - amount = this._socket.bufferSize || 0; - } - return amount; - } -}); - -/** - * Emulates the W3C Browser based WebSocket interface using function members. - * - * @see http://dev.w3.org/html5/websockets/#the-websocket-interface - * @api public - */ - -['open', 'error', 'close', 'message'].forEach(function(method) { - Object.defineProperty(WebSocket.prototype, 'on' + method, { - /** - * Returns the current listener - * - * @returns {Mixed} the set function or undefined - * @api public - */ - - get: function get() { - var listener = this.listeners(method)[0]; - return listener ? (listener._listener ? listener._listener : listener) : undefined; - }, - - /** - * Start listening for events - * - * @param {Function} listener the listener - * @returns {Mixed} the set function or undefined - * @api public - */ - - set: function set(listener) { - this.removeAllListeners(method); - this.addEventListener(method, listener); - } - }); -}); - -/** - * Emulates the W3C Browser based WebSocket interface using addEventListener. - * - * @see https://developer.mozilla.org/en/DOM/element.addEventListener - * @see http://dev.w3.org/html5/websockets/#the-websocket-interface - * @api public - */ -WebSocket.prototype.addEventListener = function(method, listener) { - var target = this; - if (typeof listener === 'function') { - if (method === 'message') { - function onMessage (data, flags) { - listener.call(this, new MessageEvent(data, flags.binary ? 'Binary' : 'Text', target)); - } - // store a reference so we can return the original function from the addEventListener hook - onMessage._listener = listener; - this.on(method, onMessage); - } else if (method === 'close') { - function onClose (code, message) { - listener.call(this, new CloseEvent(code, message, target)); - } - // store a reference so we can return the original function from the addEventListener hook - onClose._listener = listener; - this.on(method, onClose); - } else if (method === 'error') { - function onError (event) { - event.target = target; - listener.call(this, event); - } - // store a reference so we can return the original function from the addEventListener hook - onError._listener = listener; - this.on(method, onError); - } else if (method === 'open') { - function onOpen () { - listener.call(this, new OpenEvent(target)); - } - // store a reference so we can return the original function from the addEventListener hook - onOpen._listener = listener; - this.on(method, onOpen); - } else { - this.on(method, listener); - } - } -} - -module.exports = WebSocket; - -/** - * W3C MessageEvent - * - * @see http://www.w3.org/TR/html5/comms.html - * @api private - */ - -function MessageEvent(dataArg, typeArg, target) { - this.data = dataArg; - this.type = typeArg; - this.target = target; -} - -/** - * W3C CloseEvent - * - * @see http://www.w3.org/TR/html5/comms.html - * @api private - */ - -function CloseEvent(code, reason, target) { - this.wasClean = (typeof code == 'undefined' || code == 1000); - this.code = code; - this.reason = reason; - this.target = target; -} - -/** - * W3C OpenEvent - * - * @see http://www.w3.org/TR/html5/comms.html - * @api private - */ - -function OpenEvent(target) { - this.target = target; -} - -/** - * Entirely private apis, - * which may or may not be bound to a sepcific WebSocket instance. - */ - -function initAsServerClient(req, socket, upgradeHead, options) { - options = new Options({ - protocolVersion: protocolVersion, - protocol: null - }).merge(options); - - // expose state properties - this.protocol = options.value.protocol; - this.protocolVersion = options.value.protocolVersion; - this.supports.binary = (this.protocolVersion != 'hixie-76'); - this.upgradeReq = req; - this.readyState = WebSocket.CONNECTING; - this._isServer = true; - - // establish connection - if (options.value.protocolVersion == 'hixie-76') establishConnection.call(this, ReceiverHixie, SenderHixie, socket, upgradeHead); - else establishConnection.call(this, Receiver, Sender, socket, upgradeHead); -} - -function initAsClient(address, protocols, options) { - options = new Options({ - origin: null, - protocolVersion: protocolVersion, - host: null, - headers: null, - protocol: null, - agent: null, - - // ssl-related options - pfx: null, - key: null, - passphrase: null, - cert: null, - ca: null, - ciphers: null, - rejectUnauthorized: null - }).merge(options); - if (options.value.protocolVersion != 8 && options.value.protocolVersion != 13) { - throw new Error('unsupported protocol version'); - } - - // verify url and establish http class - var serverUrl = url.parse(address); - var isUnixSocket = serverUrl.protocol === 'ws+unix:'; - if (!serverUrl.host && !isUnixSocket) throw new Error('invalid url'); - var isSecure = serverUrl.protocol === 'wss:' || serverUrl.protocol === 'https:'; - var httpObj = isSecure ? https : http; - var port = serverUrl.port || (isSecure ? 443 : 80); - var auth = serverUrl.auth; - - // expose state properties - this._isServer = false; - this.url = address; - this.protocolVersion = options.value.protocolVersion; - this.supports.binary = (this.protocolVersion != 'hixie-76'); - - // begin handshake - var key = new Buffer(options.value.protocolVersion + '-' + Date.now()).toString('base64'); - var shasum = crypto.createHash('sha1'); - shasum.update(key + '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'); - var expectedServerKey = shasum.digest('base64'); - - var agent = options.value.agent; - - var headerHost = serverUrl.hostname; - // Append port number to Host and Origin header, only if specified in the url and non-default - if(serverUrl.port) { - if((isSecure && (port != 443)) || (!isSecure && (port != 80))){ - headerHost = headerHost + ':' + port; - } - } - - var requestOptions = { - port: port, - host: serverUrl.hostname, - headers: { - 'Connection': 'Upgrade', - 'Upgrade': 'websocket', - 'Host': headerHost, - 'Origin': headerHost, - 'Sec-WebSocket-Version': options.value.protocolVersion, - 'Sec-WebSocket-Key': key - } - }; - - // If we have basic auth. - if (auth) { - requestOptions.headers['Authorization'] = 'Basic ' + new Buffer(auth).toString('base64'); - } - - if (options.value.protocol) { - requestOptions.headers['Sec-WebSocket-Protocol'] = options.value.protocol; - } - - if (options.value.host) { - requestOptions.headers['Host'] = options.value.host; - } - - if (options.value.headers) { - for (var header in options.value.headers) { - if (options.value.headers.hasOwnProperty(header)) { - requestOptions.headers[header] = options.value.headers[header]; - } - } - } - - if (options.isDefinedAndNonNull('pfx') - || options.isDefinedAndNonNull('key') - || options.isDefinedAndNonNull('passphrase') - || options.isDefinedAndNonNull('cert') - || options.isDefinedAndNonNull('ca') - || options.isDefinedAndNonNull('ciphers') - || options.isDefinedAndNonNull('rejectUnauthorized')) { - - if (options.isDefinedAndNonNull('pfx')) requestOptions.pfx = options.value.pfx; - if (options.isDefinedAndNonNull('key')) requestOptions.key = options.value.key; - if (options.isDefinedAndNonNull('passphrase')) requestOptions.passphrase = options.value.passphrase; - if (options.isDefinedAndNonNull('cert')) requestOptions.cert = options.value.cert; - if (options.isDefinedAndNonNull('ca')) requestOptions.ca = options.value.ca; - if (options.isDefinedAndNonNull('ciphers')) requestOptions.ciphers = options.value.ciphers; - if (options.isDefinedAndNonNull('rejectUnauthorized')) requestOptions.rejectUnauthorized = options.value.rejectUnauthorized; - - if (!agent) { - // global agent ignores client side certificates - agent = new httpObj.Agent(requestOptions); - } - } - - requestOptions.path = serverUrl.path || '/'; - - if (agent) { - requestOptions.agent = agent; - } - - if (isUnixSocket) { - requestOptions.socketPath = serverUrl.pathname; - } - if (options.value.origin) { - if (options.value.protocolVersion < 13) requestOptions.headers['Sec-WebSocket-Origin'] = options.value.origin; - else requestOptions.headers['Origin'] = options.value.origin; - } - - var self = this; - var req = httpObj.request(requestOptions); - - req.on('error', function(error) { - self.emit('error', error); - cleanupWebsocketResources.call(this, error); - }); - - req.once('response', function(res) { - if (!self.emit('unexpected-response', req, res)) { - var error = new Error('unexpected server response (' + res.statusCode + ')'); - req.abort(); - self.emit('error', error); - } - cleanupWebsocketResources.call(this, error); - }); - - req.once('upgrade', function(res, socket, upgradeHead) { - if (self.readyState == WebSocket.CLOSED) { - // client closed before server accepted connection - self.emit('close'); - self.removeAllListeners(); - socket.end(); - return; - } - var serverKey = res.headers['sec-websocket-accept']; - if (typeof serverKey == 'undefined' || serverKey !== expectedServerKey) { - self.emit('error', 'invalid server key'); - self.removeAllListeners(); - socket.end(); - return; - } - - var serverProt = res.headers['sec-websocket-protocol']; - var protList = (options.value.protocol || "").split(/, */); - var protError = null; - if (!options.value.protocol && serverProt) { - protError = 'server sent a subprotocol even though none requested'; - } else if (options.value.protocol && !serverProt) { - protError = 'server sent no subprotocol even though requested'; - } else if (serverProt && protList.indexOf(serverProt) === -1) { - protError = 'server responded with an invalid protocol'; - } - if (protError) { - self.emit('error', protError); - self.removeAllListeners(); - socket.end(); - return; - } else if (serverProt) { - self.protocol = serverProt; - } - - establishConnection.call(self, Receiver, Sender, socket, upgradeHead); - - // perform cleanup on http resources - req.removeAllListeners(); - req = null; - agent = null; - }); - - req.end(); - this.readyState = WebSocket.CONNECTING; -} - -function establishConnection(ReceiverClass, SenderClass, socket, upgradeHead) { - this._socket = socket; - socket.setTimeout(0); - socket.setNoDelay(true); - var self = this; - this._receiver = new ReceiverClass(); - - // socket cleanup handlers - socket.on('end', cleanupWebsocketResources.bind(this)); - socket.on('close', cleanupWebsocketResources.bind(this)); - socket.on('error', cleanupWebsocketResources.bind(this)); - - // ensure that the upgradeHead is added to the receiver - function firstHandler(data) { - if (self.readyState != WebSocket.OPEN) return; - if (upgradeHead && upgradeHead.length > 0) { - self.bytesReceived += upgradeHead.length; - var head = upgradeHead; - upgradeHead = null; - self._receiver.add(head); - } - dataHandler = realHandler; - if (data) { - self.bytesReceived += data.length; - self._receiver.add(data); - } - } - // subsequent packets are pushed straight to the receiver - function realHandler(data) { - if (data) self.bytesReceived += data.length; - self._receiver.add(data); - } - var dataHandler = firstHandler; - // if data was passed along with the http upgrade, - // this will schedule a push of that on to the receiver. - // this has to be done on next tick, since the caller - // hasn't had a chance to set event handlers on this client - // object yet. - process.nextTick(firstHandler); - - // receiver event handlers - self._receiver.ontext = function (data, flags) { - flags = flags || {}; - self.emit('message', data, flags); - }; - self._receiver.onbinary = function (data, flags) { - flags = flags || {}; - flags.binary = true; - self.emit('message', data, flags); - }; - self._receiver.onping = function(data, flags) { - flags = flags || {}; - self.pong(data, {mask: !self._isServer, binary: flags.binary === true}, true); - self.emit('ping', data, flags); - }; - self._receiver.onpong = function(data, flags) { - self.emit('pong', data, flags); - }; - self._receiver.onclose = function(code, data, flags) { - flags = flags || {}; - self.close(code, data); - }; - self._receiver.onerror = function(reason, errorCode) { - // close the connection when the receiver reports a HyBi error code - self.close(typeof errorCode != 'undefined' ? errorCode : 1002, ''); - self.emit('error', reason, errorCode); - }; - - // finalize the client - this._sender = new SenderClass(socket); - this._sender.on('error', function(error) { - self.close(1002, ''); - self.emit('error', error); - }); - this.readyState = WebSocket.OPEN; - this.emit('open'); - - socket.on('data', dataHandler); -} - -function startQueue(instance) { - instance._queue = instance._queue || []; -} - -function executeQueueSends(instance) { - var queue = instance._queue; - if (typeof queue == 'undefined') return; - delete instance._queue; - for (var i = 0, l = queue.length; i < l; ++i) { - queue[i](); - } -} - -function sendStream(instance, stream, options, cb) { - stream.on('data', function(data) { - if (instance.readyState != WebSocket.OPEN) { - if (typeof cb == 'function') cb(new Error('not opened')); - else { - delete instance._queue; - instance.emit('error', new Error('not opened')); - } - return; - } - options.fin = false; - instance._sender.send(data, options); - }); - stream.on('end', function() { - if (instance.readyState != WebSocket.OPEN) { - if (typeof cb == 'function') cb(new Error('not opened')); - else { - delete instance._queue; - instance.emit('error', new Error('not opened')); - } - return; - } - options.fin = true; - instance._sender.send(null, options); - if (typeof cb == 'function') cb(null); - }); -} - -function cleanupWebsocketResources(error) { - if (this.readyState == WebSocket.CLOSED) return; - var emitClose = this.readyState != WebSocket.CONNECTING; - this.readyState = WebSocket.CLOSED; - - clearTimeout(this._closeTimer); - this._closeTimer = null; - if (emitClose) this.emit('close', this._closeCode || 1000, this._closeMessage || ''); - - if (this._socket) { - this._socket.removeAllListeners(); - // catch all socket error after removing all standard handlers - var socket = this._socket; - this._socket.on('error', function() { - try { socket.destroy(); } catch (e) {} - }); - try { - if (!error) this._socket.end(); - else this._socket.destroy(); - } - catch (e) { /* Ignore termination errors */ } - this._socket = null; - } - if (this._sender) { - this._sender.removeAllListeners(); - this._sender = null; - } - if (this._receiver) { - this._receiver.cleanup(); - this._receiver = null; - } - this.removeAllListeners(); - this.on('error', function() {}); // catch all errors after this - delete this._queue; -} diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/WebSocketServer.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/WebSocketServer.js deleted file mode 100644 index 5cbd195b42..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/WebSocketServer.js +++ /dev/null @@ -1,465 +0,0 @@ -/*! - * ws: a node.js websocket client - * Copyright(c) 2011 Einar Otto Stangvik - * MIT Licensed - */ - -var util = require('util') - , events = require('events') - , http = require('http') - , crypto = require('crypto') - , Options = require('options') - , WebSocket = require('./WebSocket') - , tls = require('tls') - , url = require('url'); - -/** - * WebSocket Server implementation - */ - -function WebSocketServer(options, callback) { - options = new Options({ - host: '0.0.0.0', - port: null, - server: null, - verifyClient: null, - handleProtocols: null, - path: null, - noServer: false, - disableHixie: false, - clientTracking: true - }).merge(options); - - if (!options.isDefinedAndNonNull('port') && !options.isDefinedAndNonNull('server') && !options.value.noServer) { - throw new TypeError('`port` or a `server` must be provided'); - } - - var self = this; - - if (options.isDefinedAndNonNull('port')) { - this._server = http.createServer(function (req, res) { - res.writeHead(200, {'Content-Type': 'text/plain'}); - res.end('Not implemented'); - }); - this._server.listen(options.value.port, options.value.host, callback); - this._closeServer = function() { if (self._server) self._server.close(); }; - } - else if (options.value.server) { - this._server = options.value.server; - if (options.value.path) { - // take note of the path, to avoid collisions when multiple websocket servers are - // listening on the same http server - if (this._server._webSocketPaths && options.value.server._webSocketPaths[options.value.path]) { - throw new Error('two instances of WebSocketServer cannot listen on the same http server path'); - } - if (typeof this._server._webSocketPaths !== 'object') { - this._server._webSocketPaths = {}; - } - this._server._webSocketPaths[options.value.path] = 1; - } - } - if (this._server) this._server.once('listening', function() { self.emit('listening'); }); - - if (typeof this._server != 'undefined') { - this._server.on('error', function(error) { - self.emit('error', error) - }); - this._server.on('upgrade', function(req, socket, upgradeHead) { - //copy upgradeHead to avoid retention of large slab buffers used in node core - var head = new Buffer(upgradeHead.length); - upgradeHead.copy(head); - - self.handleUpgrade(req, socket, head, function(client) { - self.emit('connection'+req.url, client); - self.emit('connection', client); - }); - }); - } - - this.options = options.value; - this.path = options.value.path; - this.clients = []; -} - -/** - * Inherits from EventEmitter. - */ - -util.inherits(WebSocketServer, events.EventEmitter); - -/** - * Immediately shuts down the connection. - * - * @api public - */ - -WebSocketServer.prototype.close = function() { - // terminate all associated clients - var error = null; - try { - for (var i = 0, l = this.clients.length; i < l; ++i) { - this.clients[i].terminate(); - } - } - catch (e) { - error = e; - } - - // remove path descriptor, if any - if (this.path && this._server._webSocketPaths) { - delete this._server._webSocketPaths[this.path]; - if (Object.keys(this._server._webSocketPaths).length == 0) { - delete this._server._webSocketPaths; - } - } - - // close the http server if it was internally created - try { - if (typeof this._closeServer !== 'undefined') { - this._closeServer(); - } - } - finally { - delete this._server; - } - if (error) throw error; -} - -/** - * Handle a HTTP Upgrade request. - * - * @api public - */ - -WebSocketServer.prototype.handleUpgrade = function(req, socket, upgradeHead, cb) { - // check for wrong path - if (this.options.path) { - var u = url.parse(req.url); - if (u && u.pathname !== this.options.path) return; - } - - if (typeof req.headers.upgrade === 'undefined' || req.headers.upgrade.toLowerCase() !== 'websocket') { - abortConnection(socket, 400, 'Bad Request'); - return; - } - - if (req.headers['sec-websocket-key1']) handleHixieUpgrade.apply(this, arguments); - else handleHybiUpgrade.apply(this, arguments); -} - -module.exports = WebSocketServer; - -/** - * Entirely private apis, - * which may or may not be bound to a sepcific WebSocket instance. - */ - -function handleHybiUpgrade(req, socket, upgradeHead, cb) { - // handle premature socket errors - var errorHandler = function() { - try { socket.destroy(); } catch (e) {} - } - socket.on('error', errorHandler); - - // verify key presence - if (!req.headers['sec-websocket-key']) { - abortConnection(socket, 400, 'Bad Request'); - return; - } - - // verify version - var version = parseInt(req.headers['sec-websocket-version']); - if ([8, 13].indexOf(version) === -1) { - abortConnection(socket, 400, 'Bad Request'); - return; - } - - // verify protocol - var protocols = req.headers['sec-websocket-protocol']; - - // verify client - var origin = version < 13 ? - req.headers['sec-websocket-origin'] : - req.headers['origin']; - - // handler to call when the connection sequence completes - var self = this; - var completeHybiUpgrade2 = function(protocol) { - - // calc key - var key = req.headers['sec-websocket-key']; - var shasum = crypto.createHash('sha1'); - shasum.update(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); - key = shasum.digest('base64'); - - var headers = [ - 'HTTP/1.1 101 Switching Protocols' - , 'Upgrade: websocket' - , 'Connection: Upgrade' - , 'Sec-WebSocket-Accept: ' + key - ]; - - if (typeof protocol != 'undefined') { - headers.push('Sec-WebSocket-Protocol: ' + protocol); - } - - // allows external modification/inspection of handshake headers - self.emit('headers', headers); - - socket.setTimeout(0); - socket.setNoDelay(true); - try { - socket.write(headers.concat('', '').join('\r\n')); - } - catch (e) { - // if the upgrade write fails, shut the connection down hard - try { socket.destroy(); } catch (e) {} - return; - } - - var client = new WebSocket([req, socket, upgradeHead], { - protocolVersion: version, - protocol: protocol - }); - - if (self.options.clientTracking) { - self.clients.push(client); - client.on('close', function() { - var index = self.clients.indexOf(client); - if (index != -1) { - self.clients.splice(index, 1); - } - }); - } - - // signal upgrade complete - socket.removeListener('error', errorHandler); - cb(client); - } - - // optionally call external protocol selection handler before - // calling completeHybiUpgrade2 - var completeHybiUpgrade1 = function() { - // choose from the sub-protocols - if (typeof self.options.handleProtocols == 'function') { - var protList = (protocols || "").split(/, */); - var callbackCalled = false; - var res = self.options.handleProtocols(protList, function(result, protocol) { - callbackCalled = true; - if (!result) abortConnection(socket, 404, 'Unauthorized') - else completeHybiUpgrade2(protocol); - }); - if (!callbackCalled) { - // the handleProtocols handler never called our callback - abortConnection(socket, 501, 'Could not process protocols'); - } - return; - } else { - if (typeof protocols !== 'undefined') { - completeHybiUpgrade2(protocols.split(/, */)[0]); - } - else { - completeHybiUpgrade2(); - } - } - } - - // optionally call external client verification handler - if (typeof this.options.verifyClient == 'function') { - var info = { - origin: origin, - secure: typeof req.connection.authorized !== 'undefined' || typeof req.connection.encrypted !== 'undefined', - req: req - }; - if (this.options.verifyClient.length == 2) { - this.options.verifyClient(info, function(result, code, name) { - if (typeof code === 'undefined') code = 401; - if (typeof name === 'undefined') name = http.STATUS_CODES[code]; - - if (!result) abortConnection(socket, code, name); - else completeHybiUpgrade1(); - }); - return; - } - else if (!this.options.verifyClient(info)) { - abortConnection(socket, 401, 'Unauthorized'); - return; - } - } - - completeHybiUpgrade1(); -} - -function handleHixieUpgrade(req, socket, upgradeHead, cb) { - // handle premature socket errors - var errorHandler = function() { - try { socket.destroy(); } catch (e) {} - } - socket.on('error', errorHandler); - - // bail if options prevent hixie - if (this.options.disableHixie) { - abortConnection(socket, 401, 'Hixie support disabled'); - return; - } - - // verify key presence - if (!req.headers['sec-websocket-key2']) { - abortConnection(socket, 400, 'Bad Request'); - return; - } - - var origin = req.headers['origin'] - , self = this; - - // setup handshake completion to run after client has been verified - var onClientVerified = function() { - var wshost; - if (!req.headers['x-forwarded-host']) - wshost = req.headers.host; - else - wshost = req.headers['x-forwarded-host']; - var location = ((req.headers['x-forwarded-proto'] === 'https' || socket.encrypted) ? 'wss' : 'ws') + '://' + wshost + req.url - , protocol = req.headers['sec-websocket-protocol']; - - // handshake completion code to run once nonce has been successfully retrieved - var completeHandshake = function(nonce, rest) { - // calculate key - var k1 = req.headers['sec-websocket-key1'] - , k2 = req.headers['sec-websocket-key2'] - , md5 = crypto.createHash('md5'); - - [k1, k2].forEach(function (k) { - var n = parseInt(k.replace(/[^\d]/g, '')) - , spaces = k.replace(/[^ ]/g, '').length; - if (spaces === 0 || n % spaces !== 0){ - abortConnection(socket, 400, 'Bad Request'); - return; - } - n /= spaces; - md5.update(String.fromCharCode( - n >> 24 & 0xFF, - n >> 16 & 0xFF, - n >> 8 & 0xFF, - n & 0xFF)); - }); - md5.update(nonce.toString('binary')); - - var headers = [ - 'HTTP/1.1 101 Switching Protocols' - , 'Upgrade: WebSocket' - , 'Connection: Upgrade' - , 'Sec-WebSocket-Location: ' + location - ]; - if (typeof protocol != 'undefined') headers.push('Sec-WebSocket-Protocol: ' + protocol); - if (typeof origin != 'undefined') headers.push('Sec-WebSocket-Origin: ' + origin); - - socket.setTimeout(0); - socket.setNoDelay(true); - try { - // merge header and hash buffer - var headerBuffer = new Buffer(headers.concat('', '').join('\r\n')); - var hashBuffer = new Buffer(md5.digest('binary'), 'binary'); - var handshakeBuffer = new Buffer(headerBuffer.length + hashBuffer.length); - headerBuffer.copy(handshakeBuffer, 0); - hashBuffer.copy(handshakeBuffer, headerBuffer.length); - - // do a single write, which - upon success - causes a new client websocket to be setup - socket.write(handshakeBuffer, 'binary', function(err) { - if (err) return; // do not create client if an error happens - var client = new WebSocket([req, socket, rest], { - protocolVersion: 'hixie-76', - protocol: protocol - }); - if (self.options.clientTracking) { - self.clients.push(client); - client.on('close', function() { - var index = self.clients.indexOf(client); - if (index != -1) { - self.clients.splice(index, 1); - } - }); - } - - // signal upgrade complete - socket.removeListener('error', errorHandler); - cb(client); - }); - } - catch (e) { - try { socket.destroy(); } catch (e) {} - return; - } - } - - // retrieve nonce - var nonceLength = 8; - if (upgradeHead && upgradeHead.length >= nonceLength) { - var nonce = upgradeHead.slice(0, nonceLength); - var rest = upgradeHead.length > nonceLength ? upgradeHead.slice(nonceLength) : null; - completeHandshake.call(self, nonce, rest); - } - else { - // nonce not present in upgradeHead, so we must wait for enough data - // data to arrive before continuing - var nonce = new Buffer(nonceLength); - upgradeHead.copy(nonce, 0); - var received = upgradeHead.length; - var rest = null; - var handler = function (data) { - var toRead = Math.min(data.length, nonceLength - received); - if (toRead === 0) return; - data.copy(nonce, received, 0, toRead); - received += toRead; - if (received == nonceLength) { - socket.removeListener('data', handler); - if (toRead < data.length) rest = data.slice(toRead); - completeHandshake.call(self, nonce, rest); - } - } - socket.on('data', handler); - } - } - - // verify client - if (typeof this.options.verifyClient == 'function') { - var info = { - origin: origin, - secure: typeof req.connection.authorized !== 'undefined' || typeof req.connection.encrypted !== 'undefined', - req: req - }; - if (this.options.verifyClient.length == 2) { - var self = this; - this.options.verifyClient(info, function(result, code, name) { - if (typeof code === 'undefined') code = 401; - if (typeof name === 'undefined') name = http.STATUS_CODES[code]; - - if (!result) abortConnection(socket, code, name); - else onClientVerified.apply(self); - }); - return; - } - else if (!this.options.verifyClient(info)) { - abortConnection(socket, 401, 'Unauthorized'); - return; - } - } - - // no client verification required - onClientVerified(); -} - -function abortConnection(socket, code, name) { - try { - var response = [ - 'HTTP/1.1 ' + code + ' ' + name, - 'Content-type: text/html' - ]; - socket.write(response.concat('', '').join('\r\n')); - } - catch (e) { /* ignore errors - we've aborted this connection */ } - finally { - // ensure that an early aborted connection is shut down completely - try { socket.destroy(); } catch (e) {} - } -} diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/browser.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/browser.js deleted file mode 100644 index 8d3a755cd5..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/lib/browser.js +++ /dev/null @@ -1,43 +0,0 @@ - -/** - * Module dependencies. - */ - -var global = (function() { return this; })(); - -/** - * WebSocket constructor. - */ - -var WebSocket = global.WebSocket || global.MozWebSocket; - -/** - * Module exports. - */ - -module.exports = WebSocket ? ws : null; - -/** - * WebSocket constructor. - * - * The third `opts` options object gets ignored in web browsers, since it's - * non-standard, and throws a TypeError if passed to the constructor. - * See: https://github.com/einaros/ws/issues/227 - * - * @param {String} uri - * @param {Array} protocols (optional) - * @param {Object) opts (optional) - * @api public - */ - -function ws(uri, protocols, opts) { - var instance; - if (protocols) { - instance = new WebSocket(uri, protocols); - } else { - instance = new WebSocket(uri); - } - return instance; -} - -if (WebSocket) ws.prototype = WebSocket.prototype; diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/commander/Readme.md b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/commander/Readme.md deleted file mode 100644 index d1644012c5..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/commander/Readme.md +++ /dev/null @@ -1,195 +0,0 @@ -# Commander.js - - The complete solution for [node.js](http://nodejs.org) command-line interfaces, inspired by Ruby's [commander](https://github.com/visionmedia/commander). - - [![Build Status](https://secure.travis-ci.org/visionmedia/commander.js.png)](http://travis-ci.org/visionmedia/commander.js) - -## Installation - - $ npm install commander - -## Option parsing - - Options with commander are defined with the `.option()` method, also serving as documentation for the options. The example below parses args and options from `process.argv`, leaving remaining args as the `program.args` array which were not consumed by options. - -```js -#!/usr/bin/env node - -/** - * Module dependencies. - */ - -var program = require('commander'); - -program - .version('0.0.1') - .option('-p, --peppers', 'Add peppers') - .option('-P, --pineapple', 'Add pineapple') - .option('-b, --bbq', 'Add bbq sauce') - .option('-c, --cheese [type]', 'Add the specified type of cheese [marble]', 'marble') - .parse(process.argv); - -console.log('you ordered a pizza with:'); -if (program.peppers) console.log(' - peppers'); -if (program.pineapple) console.log(' - pineapple'); -if (program.bbq) console.log(' - bbq'); -console.log(' - %s cheese', program.cheese); -``` - - Short flags may be passed as a single arg, for example `-abc` is equivalent to `-a -b -c`. Multi-word options such as "--template-engine" are camel-cased, becoming `program.templateEngine` etc. - -## Automated --help - - The help information is auto-generated based on the information commander already knows about your program, so the following `--help` info is for free: - -``` - $ ./examples/pizza --help - - Usage: pizza [options] - - Options: - - -V, --version output the version number - -p, --peppers Add peppers - -P, --pineapple Add pineapple - -b, --bbq Add bbq sauce - -c, --cheese Add the specified type of cheese [marble] - -h, --help output usage information - -``` - -## Coercion - -```js -function range(val) { - return val.split('..').map(Number); -} - -function list(val) { - return val.split(','); -} - -program - .version('0.0.1') - .usage('[options] ') - .option('-i, --integer ', 'An integer argument', parseInt) - .option('-f, --float ', 'A float argument', parseFloat) - .option('-r, --range ..', 'A range', range) - .option('-l, --list ', 'A list', list) - .option('-o, --optional [value]', 'An optional value') - .parse(process.argv); - -console.log(' int: %j', program.integer); -console.log(' float: %j', program.float); -console.log(' optional: %j', program.optional); -program.range = program.range || []; -console.log(' range: %j..%j', program.range[0], program.range[1]); -console.log(' list: %j', program.list); -console.log(' args: %j', program.args); -``` - -## Custom help - - You can display arbitrary `-h, --help` information - by listening for "--help". Commander will automatically - exit once you are done so that the remainder of your program - does not execute causing undesired behaviours, for example - in the following executable "stuff" will not output when - `--help` is used. - -```js -#!/usr/bin/env node - -/** - * Module dependencies. - */ - -var program = require('../'); - -function list(val) { - return val.split(',').map(Number); -} - -program - .version('0.0.1') - .option('-f, --foo', 'enable some foo') - .option('-b, --bar', 'enable some bar') - .option('-B, --baz', 'enable some baz'); - -// must be before .parse() since -// node's emit() is immediate - -program.on('--help', function(){ - console.log(' Examples:'); - console.log(''); - console.log(' $ custom-help --help'); - console.log(' $ custom-help -h'); - console.log(''); -}); - -program.parse(process.argv); - -console.log('stuff'); -``` - -yielding the following help output: - -``` - -Usage: custom-help [options] - -Options: - - -h, --help output usage information - -V, --version output the version number - -f, --foo enable some foo - -b, --bar enable some bar - -B, --baz enable some baz - -Examples: - - $ custom-help --help - $ custom-help -h - -``` - -## .outputHelp() - - Output help information without exiting. - -## .help() - - Output help information and exit immediately. - -## Links - - - [API documentation](http://visionmedia.github.com/commander.js/) - - [ascii tables](https://github.com/LearnBoost/cli-table) - - [progress bars](https://github.com/visionmedia/node-progress) - - [more progress bars](https://github.com/substack/node-multimeter) - - [examples](https://github.com/visionmedia/commander.js/tree/master/examples) - -## License - -(The MIT License) - -Copyright (c) 2011 TJ Holowaychuk <tj@vision-media.ca> - -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. diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/commander/index.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/commander/index.js deleted file mode 100644 index 790a7519bd..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/commander/index.js +++ /dev/null @@ -1,851 +0,0 @@ - -/** - * Module dependencies. - */ - -var EventEmitter = require('events').EventEmitter; -var spawn = require('child_process').spawn; -var fs = require('fs'); -var exists = fs.existsSync; -var path = require('path'); -var dirname = path.dirname; -var basename = path.basename; - -/** - * Expose the root command. - */ - -exports = module.exports = new Command; - -/** - * Expose `Command`. - */ - -exports.Command = Command; - -/** - * Expose `Option`. - */ - -exports.Option = Option; - -/** - * Initialize a new `Option` with the given `flags` and `description`. - * - * @param {String} flags - * @param {String} description - * @api public - */ - -function Option(flags, description) { - this.flags = flags; - this.required = ~flags.indexOf('<'); - this.optional = ~flags.indexOf('['); - this.bool = !~flags.indexOf('-no-'); - flags = flags.split(/[ ,|]+/); - if (flags.length > 1 && !/^[[<]/.test(flags[1])) this.short = flags.shift(); - this.long = flags.shift(); - this.description = description || ''; -} - -/** - * Return option name. - * - * @return {String} - * @api private - */ - -Option.prototype.name = function(){ - return this.long - .replace('--', '') - .replace('no-', ''); -}; - -/** - * Check if `arg` matches the short or long flag. - * - * @param {String} arg - * @return {Boolean} - * @api private - */ - -Option.prototype.is = function(arg){ - return arg == this.short - || arg == this.long; -}; - -/** - * Initialize a new `Command`. - * - * @param {String} name - * @api public - */ - -function Command(name) { - this.commands = []; - this.options = []; - this._execs = []; - this._args = []; - this._name = name; -} - -/** - * Inherit from `EventEmitter.prototype`. - */ - -Command.prototype.__proto__ = EventEmitter.prototype; - -/** - * Add command `name`. - * - * The `.action()` callback is invoked when the - * command `name` is specified via __ARGV__, - * and the remaining arguments are applied to the - * function for access. - * - * When the `name` is "*" an un-matched command - * will be passed as the first arg, followed by - * the rest of __ARGV__ remaining. - * - * Examples: - * - * program - * .version('0.0.1') - * .option('-C, --chdir ', 'change the working directory') - * .option('-c, --config ', 'set config path. defaults to ./deploy.conf') - * .option('-T, --no-tests', 'ignore test hook') - * - * program - * .command('setup') - * .description('run remote setup commands') - * .action(function(){ - * console.log('setup'); - * }); - * - * program - * .command('exec ') - * .description('run the given remote command') - * .action(function(cmd){ - * console.log('exec "%s"', cmd); - * }); - * - * program - * .command('*') - * .description('deploy the given env') - * .action(function(env){ - * console.log('deploying "%s"', env); - * }); - * - * program.parse(process.argv); - * - * @param {String} name - * @param {String} [desc] - * @return {Command} the new command - * @api public - */ - -Command.prototype.command = function(name, desc){ - var args = name.split(/ +/); - var cmd = new Command(args.shift()); - if (desc) cmd.description(desc); - if (desc) this.executables = true; - if (desc) this._execs[cmd._name] = true; - this.commands.push(cmd); - cmd.parseExpectedArgs(args); - cmd.parent = this; - if (desc) return this; - return cmd; -}; - -/** - * Add an implicit `help [cmd]` subcommand - * which invokes `--help` for the given command. - * - * @api private - */ - -Command.prototype.addImplicitHelpCommand = function() { - this.command('help [cmd]', 'display help for [cmd]'); -}; - -/** - * Parse expected `args`. - * - * For example `["[type]"]` becomes `[{ required: false, name: 'type' }]`. - * - * @param {Array} args - * @return {Command} for chaining - * @api public - */ - -Command.prototype.parseExpectedArgs = function(args){ - if (!args.length) return; - var self = this; - args.forEach(function(arg){ - switch (arg[0]) { - case '<': - self._args.push({ required: true, name: arg.slice(1, -1) }); - break; - case '[': - self._args.push({ required: false, name: arg.slice(1, -1) }); - break; - } - }); - return this; -}; - -/** - * Register callback `fn` for the command. - * - * Examples: - * - * program - * .command('help') - * .description('display verbose help') - * .action(function(){ - * // output help here - * }); - * - * @param {Function} fn - * @return {Command} for chaining - * @api public - */ - -Command.prototype.action = function(fn){ - var self = this; - this.parent.on(this._name, function(args, unknown){ - // Parse any so-far unknown options - unknown = unknown || []; - var parsed = self.parseOptions(unknown); - - // Output help if necessary - outputHelpIfNecessary(self, parsed.unknown); - - // If there are still any unknown options, then we simply - // die, unless someone asked for help, in which case we give it - // to them, and then we die. - if (parsed.unknown.length > 0) { - self.unknownOption(parsed.unknown[0]); - } - - // Leftover arguments need to be pushed back. Fixes issue #56 - if (parsed.args.length) args = parsed.args.concat(args); - - self._args.forEach(function(arg, i){ - if (arg.required && null == args[i]) { - self.missingArgument(arg.name); - } - }); - - // Always append ourselves to the end of the arguments, - // to make sure we match the number of arguments the user - // expects - if (self._args.length) { - args[self._args.length] = self; - } else { - args.push(self); - } - - fn.apply(this, args); - }); - return this; -}; - -/** - * Define option with `flags`, `description` and optional - * coercion `fn`. - * - * The `flags` string should contain both the short and long flags, - * separated by comma, a pipe or space. The following are all valid - * all will output this way when `--help` is used. - * - * "-p, --pepper" - * "-p|--pepper" - * "-p --pepper" - * - * Examples: - * - * // simple boolean defaulting to false - * program.option('-p, --pepper', 'add pepper'); - * - * --pepper - * program.pepper - * // => Boolean - * - * // simple boolean defaulting to false - * program.option('-C, --no-cheese', 'remove cheese'); - * - * program.cheese - * // => true - * - * --no-cheese - * program.cheese - * // => true - * - * // required argument - * program.option('-C, --chdir ', 'change the working directory'); - * - * --chdir /tmp - * program.chdir - * // => "/tmp" - * - * // optional argument - * program.option('-c, --cheese [type]', 'add cheese [marble]'); - * - * @param {String} flags - * @param {String} description - * @param {Function|Mixed} fn or default - * @param {Mixed} defaultValue - * @return {Command} for chaining - * @api public - */ - -Command.prototype.option = function(flags, description, fn, defaultValue){ - var self = this - , option = new Option(flags, description) - , oname = option.name() - , name = camelcase(oname); - - // default as 3rd arg - if ('function' != typeof fn) defaultValue = fn, fn = null; - - // preassign default value only for --no-*, [optional], or - if (false == option.bool || option.optional || option.required) { - // when --no-* we make sure default is true - if (false == option.bool) defaultValue = true; - // preassign only if we have a default - if (undefined !== defaultValue) self[name] = defaultValue; - } - - // register the option - this.options.push(option); - - // when it's passed assign the value - // and conditionally invoke the callback - this.on(oname, function(val){ - // coercion - if (null != val && fn) val = fn(val); - - // unassigned or bool - if ('boolean' == typeof self[name] || 'undefined' == typeof self[name]) { - // if no value, bool true, and we have a default, then use it! - if (null == val) { - self[name] = option.bool - ? defaultValue || true - : false; - } else { - self[name] = val; - } - } else if (null !== val) { - // reassign - self[name] = val; - } - }); - - return this; -}; - -/** - * Parse `argv`, settings options and invoking commands when defined. - * - * @param {Array} argv - * @return {Command} for chaining - * @api public - */ - -Command.prototype.parse = function(argv){ - // implicit help - if (this.executables) this.addImplicitHelpCommand(); - - // store raw args - this.rawArgs = argv; - - // guess name - this._name = this._name || basename(argv[1]); - - // process argv - var parsed = this.parseOptions(this.normalize(argv.slice(2))); - var args = this.args = parsed.args; - - var result = this.parseArgs(this.args, parsed.unknown); - - // executable sub-commands - var name = result.args[0]; - if (this._execs[name]) return this.executeSubCommand(argv, args, parsed.unknown); - - return result; -}; - -/** - * Execute a sub-command executable. - * - * @param {Array} argv - * @param {Array} args - * @param {Array} unknown - * @api private - */ - -Command.prototype.executeSubCommand = function(argv, args, unknown) { - args = args.concat(unknown); - - if (!args.length) this.help(); - if ('help' == args[0] && 1 == args.length) this.help(); - - // --help - if ('help' == args[0]) { - args[0] = args[1]; - args[1] = '--help'; - } - - // executable - var dir = dirname(argv[1]); - var bin = basename(argv[1]) + '-' + args[0]; - - // check for ./ first - var local = path.join(dir, bin); - - // run it - args = args.slice(1); - var proc = spawn(local, args, { stdio: 'inherit', customFds: [0, 1, 2] }); - proc.on('error', function(err){ - if (err.code == "ENOENT") { - console.error('\n %s(1) does not exist, try --help\n', bin); - } else if (err.code == "EACCES") { - console.error('\n %s(1) not executable. try chmod or run with root\n', bin); - } - }); - - this.runningCommand = proc; -}; - -/** - * Normalize `args`, splitting joined short flags. For example - * the arg "-abc" is equivalent to "-a -b -c". - * This also normalizes equal sign and splits "--abc=def" into "--abc def". - * - * @param {Array} args - * @return {Array} - * @api private - */ - -Command.prototype.normalize = function(args){ - var ret = [] - , arg - , lastOpt - , index; - - for (var i = 0, len = args.length; i < len; ++i) { - arg = args[i]; - i > 0 && (lastOpt = this.optionFor(args[i-1])); - - if (lastOpt && lastOpt.required) { - ret.push(arg); - } else if (arg.length > 1 && '-' == arg[0] && '-' != arg[1]) { - arg.slice(1).split('').forEach(function(c){ - ret.push('-' + c); - }); - } else if (/^--/.test(arg) && ~(index = arg.indexOf('='))) { - ret.push(arg.slice(0, index), arg.slice(index + 1)); - } else { - ret.push(arg); - } - } - - return ret; -}; - -/** - * Parse command `args`. - * - * When listener(s) are available those - * callbacks are invoked, otherwise the "*" - * event is emitted and those actions are invoked. - * - * @param {Array} args - * @return {Command} for chaining - * @api private - */ - -Command.prototype.parseArgs = function(args, unknown){ - var cmds = this.commands - , len = cmds.length - , name; - - if (args.length) { - name = args[0]; - if (this.listeners(name).length) { - this.emit(args.shift(), args, unknown); - } else { - this.emit('*', args); - } - } else { - outputHelpIfNecessary(this, unknown); - - // If there were no args and we have unknown options, - // then they are extraneous and we need to error. - if (unknown.length > 0) { - this.unknownOption(unknown[0]); - } - } - - return this; -}; - -/** - * Return an option matching `arg` if any. - * - * @param {String} arg - * @return {Option} - * @api private - */ - -Command.prototype.optionFor = function(arg){ - for (var i = 0, len = this.options.length; i < len; ++i) { - if (this.options[i].is(arg)) { - return this.options[i]; - } - } -}; - -/** - * Parse options from `argv` returning `argv` - * void of these options. - * - * @param {Array} argv - * @return {Array} - * @api public - */ - -Command.prototype.parseOptions = function(argv){ - var args = [] - , len = argv.length - , literal - , option - , arg; - - var unknownOptions = []; - - // parse options - for (var i = 0; i < len; ++i) { - arg = argv[i]; - - // literal args after -- - if ('--' == arg) { - literal = true; - continue; - } - - if (literal) { - args.push(arg); - continue; - } - - // find matching Option - option = this.optionFor(arg); - - // option is defined - if (option) { - // requires arg - if (option.required) { - arg = argv[++i]; - if (null == arg) return this.optionMissingArgument(option); - this.emit(option.name(), arg); - // optional arg - } else if (option.optional) { - arg = argv[i+1]; - if (null == arg || ('-' == arg[0] && '-' != arg)) { - arg = null; - } else { - ++i; - } - this.emit(option.name(), arg); - // bool - } else { - this.emit(option.name()); - } - continue; - } - - // looks like an option - if (arg.length > 1 && '-' == arg[0]) { - unknownOptions.push(arg); - - // If the next argument looks like it might be - // an argument for this option, we pass it on. - // If it isn't, then it'll simply be ignored - if (argv[i+1] && '-' != argv[i+1][0]) { - unknownOptions.push(argv[++i]); - } - continue; - } - - // arg - args.push(arg); - } - - return { args: args, unknown: unknownOptions }; -}; - -/** - * Argument `name` is missing. - * - * @param {String} name - * @api private - */ - -Command.prototype.missingArgument = function(name){ - console.error(); - console.error(" error: missing required argument `%s'", name); - console.error(); - process.exit(1); -}; - -/** - * `Option` is missing an argument, but received `flag` or nothing. - * - * @param {String} option - * @param {String} flag - * @api private - */ - -Command.prototype.optionMissingArgument = function(option, flag){ - console.error(); - if (flag) { - console.error(" error: option `%s' argument missing, got `%s'", option.flags, flag); - } else { - console.error(" error: option `%s' argument missing", option.flags); - } - console.error(); - process.exit(1); -}; - -/** - * Unknown option `flag`. - * - * @param {String} flag - * @api private - */ - -Command.prototype.unknownOption = function(flag){ - console.error(); - console.error(" error: unknown option `%s'", flag); - console.error(); - process.exit(1); -}; - - -/** - * Set the program version to `str`. - * - * This method auto-registers the "-V, --version" flag - * which will print the version number when passed. - * - * @param {String} str - * @param {String} flags - * @return {Command} for chaining - * @api public - */ - -Command.prototype.version = function(str, flags){ - if (0 == arguments.length) return this._version; - this._version = str; - flags = flags || '-V, --version'; - this.option(flags, 'output the version number'); - this.on('version', function(){ - console.log(str); - process.exit(0); - }); - return this; -}; - -/** - * Set the description `str`. - * - * @param {String} str - * @return {String|Command} - * @api public - */ - -Command.prototype.description = function(str){ - if (0 == arguments.length) return this._description; - this._description = str; - return this; -}; - -/** - * Set / get the command usage `str`. - * - * @param {String} str - * @return {String|Command} - * @api public - */ - -Command.prototype.usage = function(str){ - var args = this._args.map(function(arg){ - return arg.required - ? '<' + arg.name + '>' - : '[' + arg.name + ']'; - }); - - var usage = '[options' - + (this.commands.length ? '] [command' : '') - + ']' - + (this._args.length ? ' ' + args : ''); - - if (0 == arguments.length) return this._usage || usage; - this._usage = str; - - return this; -}; - -/** - * Return the largest option length. - * - * @return {Number} - * @api private - */ - -Command.prototype.largestOptionLength = function(){ - return this.options.reduce(function(max, option){ - return Math.max(max, option.flags.length); - }, 0); -}; - -/** - * Return help for options. - * - * @return {String} - * @api private - */ - -Command.prototype.optionHelp = function(){ - var width = this.largestOptionLength(); - - // Prepend the help information - return [pad('-h, --help', width) + ' ' + 'output usage information'] - .concat(this.options.map(function(option){ - return pad(option.flags, width) - + ' ' + option.description; - })) - .join('\n'); -}; - -/** - * Return command help documentation. - * - * @return {String} - * @api private - */ - -Command.prototype.commandHelp = function(){ - if (!this.commands.length) return ''; - return [ - '' - , ' Commands:' - , '' - , this.commands.map(function(cmd){ - var args = cmd._args.map(function(arg){ - return arg.required - ? '<' + arg.name + '>' - : '[' + arg.name + ']'; - }).join(' '); - - return pad(cmd._name - + (cmd.options.length - ? ' [options]' - : '') + ' ' + args, 22) - + (cmd.description() - ? ' ' + cmd.description() - : ''); - }).join('\n').replace(/^/gm, ' ') - , '' - ].join('\n'); -}; - -/** - * Return program help documentation. - * - * @return {String} - * @api private - */ - -Command.prototype.helpInformation = function(){ - return [ - '' - , ' Usage: ' + this._name + ' ' + this.usage() - , '' + this.commandHelp() - , ' Options:' - , '' - , '' + this.optionHelp().replace(/^/gm, ' ') - , '' - , '' - ].join('\n'); -}; - -/** - * Output help information for this command - * - * @api public - */ - -Command.prototype.outputHelp = function(){ - process.stdout.write(this.helpInformation()); - this.emit('--help'); -}; - -/** - * Output help information and exit. - * - * @api public - */ - -Command.prototype.help = function(){ - this.outputHelp(); - process.exit(); -}; - -/** - * Camel-case the given `flag` - * - * @param {String} flag - * @return {String} - * @api private - */ - -function camelcase(flag) { - return flag.split('-').reduce(function(str, word){ - return str + word[0].toUpperCase() + word.slice(1); - }); -} - -/** - * Pad `str` to `width`. - * - * @param {String} str - * @param {Number} width - * @return {String} - * @api private - */ - -function pad(str, width) { - var len = Math.max(0, width - str.length); - return str + Array(len + 1).join(' '); -} - -/** - * Output help information if necessary - * - * @param {Command} command to output help for - * @param {Array} array of options to search for -h or --help - * @api private - */ - -function outputHelpIfNecessary(cmd, options) { - options = options || []; - for (var i = 0; i < options.length; i++) { - if (options[i] == '--help' || options[i] == '-h') { - cmd.outputHelp(); - process.exit(0); - } - } -} diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/commander/package.json b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/commander/package.json deleted file mode 100644 index d4f44070cb..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/commander/package.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "name": "commander", - "version": "2.1.0", - "description": "the complete solution for node.js command-line programs", - "keywords": [ - "command", - "option", - "parser", - "prompt", - "stdin" - ], - "author": { - "name": "TJ Holowaychuk", - "email": "tj@vision-media.ca" - }, - "repository": { - "type": "git", - "url": "https://github.com/visionmedia/commander.js.git" - }, - "devDependencies": { - "should": ">= 0.0.1" - }, - "scripts": { - "test": "make test" - }, - "main": "index", - "engines": { - "node": ">= 0.6.x" - }, - "files": [ - "index.js" - ], - "bugs": { - "url": "https://github.com/visionmedia/commander.js/issues" - }, - "homepage": "https://github.com/visionmedia/commander.js", - "_id": "commander@2.1.0", - "dist": { - "shasum": "d121bbae860d9992a3d517ba96f56588e47c6781", - "tarball": "http://registry.npmjs.org/commander/-/commander-2.1.0.tgz" - }, - "_from": "commander@~2.1.0", - "_npmVersion": "1.3.14", - "_npmUser": { - "name": "tjholowaychuk", - "email": "tj@vision-media.ca" - }, - "maintainers": [ - { - "name": "tjholowaychuk", - "email": "tj@vision-media.ca" - } - ], - "directories": {}, - "_shasum": "d121bbae860d9992a3d517ba96f56588e47c6781", - "_resolved": "https://registry.npmjs.org/commander/-/commander-2.1.0.tgz", - "readme": "ERROR: No README data found!" -} diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/nan/.dntrc b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/nan/.dntrc deleted file mode 100644 index 1c3e6243a3..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/nan/.dntrc +++ /dev/null @@ -1,36 +0,0 @@ -## DNT config file -## see https://github.com/rvagg/dnt - -NODE_VERSIONS="\ - master \ - v0.11.13 \ - v0.11.10 \ - v0.11.9 \ - v0.11.8 \ - v0.11.7 \ - v0.11.6 \ - v0.11.5 \ - v0.11.4 \ - v0.10.26 \ - v0.10.25 \ - v0.10.24 \ - v0.10.23 \ - v0.10.22 \ - v0.10.21 \ - v0.10.20 \ - v0.10.19 \ - v0.10.18 \ - v0.8.26 \ - v0.8.25 \ - v0.8.24 \ - v0.8.23 \ - v0.8.22 \ -" -OUTPUT_PREFIX="nan-" -TEST_CMD="\ - cd /dnt/test/ && \ - npm install && \ - node_modules/.bin/node-gyp --nodedir /usr/src/node/ rebuild && \ - node_modules/.bin/tap --gc js/*-test.js; \ -" - diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/nan/LICENSE b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/nan/LICENSE deleted file mode 100644 index d502e18a19..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/nan/LICENSE +++ /dev/null @@ -1,46 +0,0 @@ -Copyright 2013, NAN contributors: - - Rod Vagg - - Benjamin Byholm - - Trevor Norris - - Nathan Rajlich - - Brett Lawson - - Ben Noordhuis -(the "Original Author") -All rights reserved. - -MIT +no-false-attribs License - -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. - -Distributions of all or part of the Software intended to be used -by the recipients as they would use the unmodified Software, -containing modifications that substantially alter, remove, or -disable functionality of the Software, outside of the documented -configuration mechanisms provided by the Software, shall be -modified such that the Original Author's bug reporting email -addresses and urls are either replaced with the contact information -of the parties responsible for the changes, or removed entirely. - -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. - - -Except where noted, this license applies to any and all software -programs and associated documentation files created by the -Original Author, when distributed with the Software. diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/nan/README.md b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/nan/README.md deleted file mode 100644 index 7c8d6883f7..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/nan/README.md +++ /dev/null @@ -1,947 +0,0 @@ -Native Abstractions for Node.js -=============================== - -**A header file filled with macro and utility goodness for making add-on development for Node.js easier across versions 0.8, 0.10 and 0.11, and eventually 0.12.** - -***Current version: 1.0.0*** *(See [nan.h](https://github.com/rvagg/nan/blob/master/nan.h) for complete ChangeLog)* - -[![NPM](https://nodei.co/npm/nan.png?downloads=true)](https://nodei.co/npm/nan/) [![NPM](https://nodei.co/npm-dl/nan.png?months=6)](https://nodei.co/npm/nan/) - -Thanks to the crazy changes in V8 (and some in Node core), keeping native addons compiling happily across versions, particularly 0.10 to 0.11/0.12, is a minor nightmare. The goal of this project is to store all logic necessary to develop native Node.js addons without having to inspect `NODE_MODULE_VERSION` and get yourself into a macro-tangle. - -This project also contains some helper utilities that make addon development a bit more pleasant. - - * **[News & Updates](#news)** - * **[Usage](#usage)** - * **[Example](#example)** - * **[API](#api)** - - -## News & Updates - -### May-2013: Major changes for V8 3.25 / Node 0.11.13 - -Node 0.11.11 and 0.11.12 were both broken releases for native add-ons, you simply can't properly compile against either of them for different reasons. But we now have a 0.11.13 release that jumps a couple of versions of V8 ahead and includes some more, major (traumatic) API changes. - -Because we are now nearing Node 0.12 and estimate that the version of V8 we are using in Node 0.11.13 will be close to the API we get for 0.12, we have taken the opportunity to not only *fix* NAN for 0.11.13 but make some major changes to improve the NAN API. - -We have **removed support for Node 0.11 versions prior to 0.11.13**, (although our tests are still passing for 0.11.10). As usual, our tests are run against (and pass) the last 5 versions of Node 0.8 and Node 0.10. We also include Node 0.11.13 obviously. - -The major change is something that [Benjamin Byholm](kkoopa) has put many hours in to. We now have a fantastic new `NanNew(args)` interface for creating new `Local`s, this replaces `NanNewLocal()` and much more. If you look in [./nan.h](nan.h) you'll see a large number of overloaded versions of this method. In general you should be able to `NanNew(arguments)` for any type you want to make a `Local` from. This includes `Persistent` types, so we now have a `Local NanNew(const Persistent arg)` to replace `NanPersistentToLocal()`. - -We also now have `NanUndefined()`, `NanNull()`, `NanTrue()` and `NanFalse()`. Mainly because of the new requirement for an `Isolate` argument for each of the native V8 versions of this. - -V8 has now introduced an `EscapableHandleScope` from which you `scope.Escape(Local value)` to *return* a value from a one scope to another. This replaces the standard `HandleScope` and `scope.Close(Local value)`, although `HandleScope` still exists for when you don't need to return a handle to the caller. For NAN we are exposing it as `NanEscapableScope()` and `NanEscapeScope()`, while `NanScope()` is still how you create a new scope that doesn't need to return handles. For older versions of Node/V8, it'll still map to the older `HandleScope` functionality. - -`NanFromV8String()` was deprecated and has now been removed. You should use `NanCString()` or `NanRawString()` instead. - -Because `node::MakeCallback()` now takes an `Isolate`, and because it doesn't exist in older versions of Node, we've introduced `NanMakeCallabck()`. You should *always* use this when calling a JavaScript function from C++. - -There's lots more, check out the Changelog in nan.h or look through [#86](https://github.com/rvagg/nan/pull/86) for all the gory details. - -### Dec-2013: NanCString and NanRawString - -Two new functions have been introduced to replace the functionality that's been provided by `NanFromV8String` until now. NanCString has sensible defaults so it's super easy to fetch a null-terminated c-style string out of a `v8::String`. `NanFromV8String` is still around and has defaults that allow you to pass a single handle to fetch a `char*` while `NanRawString` requires a little more attention to arguments. - -### Nov-2013: Node 0.11.9+ breaking V8 change - -The version of V8 that's shipping with Node 0.11.9+ has changed the signature for new `Local`s to: `v8::Local::New(isolate, value)`, i.e. introducing the `isolate` argument and therefore breaking all new `Local` declarations for previous versions. NAN 0.6+ now includes a `NanNewLocal(value)` that can be used in place to work around this incompatibility and maintain compatibility with 0.8->0.11.9+ (minus a few early 0.11 releases). - -For example, if you wanted to return a `null` on a callback you will have to change the argument from `v8::Local::New(v8::Null())` to `NanNewLocal(v8::Null())`. - -### Nov-2013: Change to binding.gyp `"include_dirs"` for NAN - -Inclusion of NAN in a project's binding.gyp is now greatly simplified. You can now just use `" -## Usage - -Simply add **NAN** as a dependency in the *package.json* of your Node addon: - -``` bash -$ npm install --save nan -``` - -Pull in the path to **NAN** in your *binding.gyp* so that you can use `#include ` in your *.cpp* files: - -``` python -"include_dirs" : [ - "` when compiling your addon. - - -## Example - -See **[LevelDOWN](https://github.com/rvagg/node-leveldown/pull/48)** for a full example of **NAN** in use. - -For a simpler example, see the **[async pi estimation example](https://github.com/rvagg/nan/tree/master/examples/async_pi_estimate)** in the examples directory for full code and an explanation of what this Monte Carlo Pi estimation example does. Below are just some parts of the full example that illustrate the use of **NAN**. - -Compare to the current 0.10 version of this example, found in the [node-addon-examples](https://github.com/rvagg/node-addon-examples/tree/master/9_async_work) repository and also a 0.11 version of the same found [here](https://github.com/kkoopa/node-addon-examples/tree/5c01f58fc993377a567812597e54a83af69686d7/9_async_work). - -Note that there is no embedded version sniffing going on here and also the async work is made much simpler, see below for details on the `NanAsyncWorker` class. - -```c++ -// addon.cc -#include -#include -// ... - -using v8::FunctionTemplate; -using v8::Handle; -using v8::Object; - -void InitAll(Handle exports) { - exports->Set(NanSymbol("calculateSync"), - NanNew(CalculateSync)->GetFunction()); - - exports->Set(NanSymbol("calculateAsync"), - NanNew(CalculateAsync)->GetFunction()); -} - -NODE_MODULE(addon, InitAll) -``` - -```c++ -// sync.h -#include -#include - -NAN_METHOD(CalculateSync); -``` - -```c++ -// sync.cc -#include -#include -#include "./sync.h" -// ... - -using v8::Number; - -// Simple synchronous access to the `Estimate()` function -NAN_METHOD(CalculateSync) { - NanScope(); - - // expect a number as the first argument - int points = args[0]->Uint32Value(); - double est = Estimate(points); - - NanReturnValue(NanNew(est)); -} -``` - -```c++ -// async.cc -#include -#include -#include "./async.h" - -// ... - -using v8::Function; -using v8::Local; -using v8::Null; -using v8::Number; -using v8::Value; - -class PiWorker : public NanAsyncWorker { - public: - PiWorker(NanCallback *callback, int points) - : NanAsyncWorker(callback), points(points) {} - ~PiWorker() {} - - // Executed inside the worker-thread. - // It is not safe to access V8, or V8 data structures - // here, so everything we need for input and output - // should go on `this`. - void Execute () { - estimate = Estimate(points); - } - - // Executed when the async work is complete - // this function will be run inside the main event loop - // so it is safe to use V8 again - void HandleOKCallback () { - NanScope(); - - Local argv[] = { - NanNew(NanNull()) - , NanNew(estimate) - }; - - callback->Call(2, argv); - }; - - private: - int points; - double estimate; -}; - -// Asynchronous access to the `Estimate()` function -NAN_METHOD(CalculateAsync) { - NanScope(); - - int points = args[0]->Uint32Value(); - NanCallback *callback = new NanCallback(args[1].As()); - - NanAsyncQueueWorker(new PiWorker(callback, points)); - NanReturnUndefined(); -} -``` - - -## API - - * NAN_METHOD - * NAN_GETTER - * NAN_SETTER - * NAN_PROPERTY_GETTER - * NAN_PROPERTY_SETTER - * NAN_PROPERTY_ENUMERATOR - * NAN_PROPERTY_DELETER - * NAN_PROPERTY_QUERY - * NAN_INDEX_GETTER - * NAN_INDEX_SETTER - * NAN_INDEX_ENUMERATOR - * NAN_INDEX_DELETER - * NAN_INDEX_QUERY - * NAN_WEAK_CALLBACK - * NAN_DEPRECATED - * NAN_INLINE - * NanNew - * NanUndefined - * NanNull - * NanTrue - * NanFalse - * NanReturnValue - * NanReturnUndefined - * NanReturnNull - * NanReturnEmptyString - * NanScope - * NanEscapableScope - * NanEscapeScope - * NanLocker - * NanUnlocker - * NanGetInternalFieldPointer - * NanSetInternalFieldPointer - * NanObjectWrapHandle - * NanSymbol - * NanGetPointerSafe - * NanSetPointerSafe - * NanRawString - * NanCString - * NanBooleanOptionValue - * NanUInt32OptionValue - * NanError, NanTypeError, NanRangeError - * NanThrowError, NanThrowTypeError, NanThrowRangeError, NanThrowError(Handle), NanThrowError(Handle, int) - * NanNewBufferHandle(char *, size_t, FreeCallback, void *), NanNewBufferHandle(char *, uint32_t), NanNewBufferHandle(uint32_t) - * NanBufferUse(char *, uint32_t) - * NanNewContextHandle - * NanGetCurrentContext - * NanHasInstance - * NanDisposePersistent - * NanAssignPersistent - * NanMakeWeakPersistent - * NanSetTemplate - * NanMakeCallback - * NanCompileScript - * NanRunScript - * NanAdjustExternalMemory - * NanAddGCEpilogueCallback - * NanAddGCPrologueCallback - * NanRemoveGCEpilogueCallback - * NanRemoveGCPrologueCallback - * NanGetHeapStatistics - * NanCallback - * NanAsyncWorker - * NanAsyncQueueWorker - - -### NAN_METHOD(methodname) - -Use `NAN_METHOD` to define your V8 accessible methods: - -```c++ -// .h: -class Foo : public node::ObjectWrap { - ... - - static NAN_METHOD(Bar); - static NAN_METHOD(Baz); -} - - -// .cc: -NAN_METHOD(Foo::Bar) { - ... -} - -NAN_METHOD(Foo::Baz) { - ... -} -``` - -The reason for this macro is because of the method signature change in 0.11: - -```c++ -// 0.10 and below: -Handle name(const Arguments& args) - -// 0.11 and above -void name(const FunctionCallbackInfo& args) -``` - -The introduction of `FunctionCallbackInfo` brings additional complications: - - -### NAN_GETTER(methodname) - -Use `NAN_GETTER` to declare your V8 accessible getters. You get a `Local` `property` and an appropriately typed `args` object that can act like the `args` argument to a `NAN_METHOD` call. - -You can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_GETTER`. - - -### NAN_SETTER(methodname) - -Use `NAN_SETTER` to declare your V8 accessible setters. Same as `NAN_GETTER` but you also get a `Local` `value` object to work with. - - -### NAN_PROPERTY_GETTER(cbname) -Use `NAN_PROPERTY_GETTER` to declare your V8 accessible property getters. You get a `Local` `property` and an appropriately typed `args` object that can act similar to the `args` argument to a `NAN_METHOD` call. - -You can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_PROPERTY_GETTER`. - - -### NAN_PROPERTY_SETTER(cbname) -Use `NAN_PROPERTY_SETTER` to declare your V8 accessible property setters. Same as `NAN_PROPERTY_GETTER` but you also get a `Local` `value` object to work with. - - -### NAN_PROPERTY_ENUMERATOR(cbname) -Use `NAN_PROPERTY_ENUMERATOR` to declare your V8 accessible property enumerators. You get an appropriately typed `args` object like the `args` argument to a `NAN_PROPERTY_GETTER` call. - -You can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_PROPERTY_ENUMERATOR`. - - -### NAN_PROPERTY_DELETER(cbname) -Use `NAN_PROPERTY_DELETER` to declare your V8 accessible property deleters. Same as `NAN_PROPERTY_GETTER`. - -You can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_PROPERTY_DELETER`. - - -### NAN_PROPERTY_QUERY(cbname) -Use `NAN_PROPERTY_QUERY` to declare your V8 accessible property queries. Same as `NAN_PROPERTY_GETTER`. - -You can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_PROPERTY_QUERY`. - - -### NAN_INDEX_GETTER(cbname) -Use `NAN_INDEX_GETTER` to declare your V8 accessible index getters. You get a `uint32_t` `index` and an appropriately typed `args` object that can act similar to the `args` argument to a `NAN_METHOD` call. - -You can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_INDEX_GETTER`. - - -### NAN_INDEX_SETTER(cbname) -Use `NAN_INDEX_SETTER` to declare your V8 accessible index setters. Same as `NAN_INDEX_GETTER` but you also get a `Local` `value` object to work with. - - -### NAN_INDEX_ENUMERATOR(cbname) -Use `NAN_INDEX_ENUMERATOR` to declare your V8 accessible index enumerators. You get an appropriately typed `args` object like the `args` argument to a `NAN_INDEX_GETTER` call. - -You can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_INDEX_ENUMERATOR`. - - -### NAN_INDEX_DELETER(cbname) -Use `NAN_INDEX_DELETER` to declare your V8 accessible index deleters. Same as `NAN_INDEX_GETTER`. - -You can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_INDEX_DELETER`. - - -### NAN_INDEX_QUERY(cbname) -Use `NAN_INDEX_QUERY` to declare your V8 accessible index queries. Same as `NAN_INDEX_GETTER`. - -You can use `NanReturnNull()`, `NanReturnEmptyString()`, `NanReturnUndefined()` and `NanReturnValue()` in a `NAN_INDEX_QUERY`. - - -### NAN_WEAK_CALLBACK(cbname) - -Use `NAN_WEAK_CALLBACK` to define your V8 WeakReference callbacks. Do not use for declaration. There is an argument object `const _NanWeakCallbackData &data` allowing access to the weak object and the supplied parameter through its `GetValue` and `GetParameter` methods. - -```c++ -NAN_WEAK_CALLBACK(weakCallback) { - int *parameter = data.GetParameter(); - NanMakeCallback(NanGetCurrentContext()->Global(), data.GetValue(), 0, NULL); - if ((*parameter)++ == 0) { - data.Revive(); - } else { - delete parameter; - data.Dispose(); - } -} -``` - - -### NAN_DEPRECATED -Declares a function as deprecated. - -```c++ -static NAN_DEPRECATED NAN_METHOD(foo) { - ... -} -``` - - -### NAN_INLINE -Inlines a function. - -```c++ -NAN_INLINE int foo(int bar) { - ... -} -``` - - -### Local<T> NanNew<T>( ... ) - -Use `NanNew` to construct almost all v8 objects and make new local handles. - -```c++ -Local s = NanNew("value"); - -... - -Persistent o; - -... - -Local lo = NanNew(o); - -``` - - -### Handle<Primitive> NanUndefined() - -Use instead of `Undefined()` - - -### Handle<Primitive> NanNull() - -Use instead of `Null()` - - -### Handle<Primitive> NanTrue() - -Use instead of `True()` - - -### Handle<Primitive> NanFalse() - -Use instead of `False()` - - -### NanReturnValue(Handle<Value>) - -Use `NanReturnValue` when you want to return a value from your V8 accessible method: - -```c++ -NAN_METHOD(Foo::Bar) { - ... - - NanReturnValue(NanNew("FooBar!")); -} -``` - -No `return` statement required. - - -### NanReturnUndefined() - -Use `NanReturnUndefined` when you don't want to return anything from your V8 accessible method: - -```c++ -NAN_METHOD(Foo::Baz) { - ... - - NanReturnUndefined(); -} -``` - - -### NanReturnNull() - -Use `NanReturnNull` when you want to return `Null` from your V8 accessible method: - -```c++ -NAN_METHOD(Foo::Baz) { - ... - - NanReturnNull(); -} -``` - - -### NanReturnEmptyString() - -Use `NanReturnEmptyString` when you want to return an empty `String` from your V8 accessible method: - -```c++ -NAN_METHOD(Foo::Baz) { - ... - - NanReturnEmptyString(); -} -``` - - -### NanScope() - -The introduction of `isolate` references for many V8 calls in Node 0.11 makes `NanScope()` necessary, use it in place of `HandleScope scope`: - -```c++ -NAN_METHOD(Foo::Bar) { - NanScope(); - - NanReturnValue(NanNew("FooBar!")); -} -``` - - -### NanEscapableScope() - -The separation of handle scopes into escapable and inescapable scopes makes `NanEscapableScope()` necessary, use it in place of `HandleScope scope` when you later wish to `Close()` the scope: - -```c++ -Handle Foo::Bar() { - NanEscapableScope(); - - return NanEscapeScope(NanNew("FooBar!")); -} -``` - - -### Local<T> NanEscapeScope(Handle<T> value); -Use together with `NanEscapableScope` to escape the scope. Corresponds to `HandleScope::Close` or `EscapableHandleScope::Escape`. - - -### NanLocker() - -The introduction of `isolate` references for many V8 calls in Node 0.11 makes `NanLocker()` necessary, use it in place of `Locker locker`: - -```c++ -NAN_METHOD(Foo::Bar) { - NanLocker(); - ... - NanUnlocker(); -} -``` - - -### NanUnlocker() - -The introduction of `isolate` references for many V8 calls in Node 0.11 makes `NanUnlocker()` necessary, use it in place of `Unlocker unlocker`: - -```c++ -NAN_METHOD(Foo::Bar) { - NanLocker(); - ... - NanUnlocker(); -} -``` - - -### void * NanGetInternalFieldPointer(Handle<Object>, int) - -Gets a pointer to the internal field with at `index` from a V8 `Object` handle. - -```c++ -Local obj; -... -NanGetInternalFieldPointer(obj, 0); -``` - -### void NanSetInternalFieldPointer(Handle<Object>, int, void *) - -Sets the value of the internal field at `index` on a V8 `Object` handle. - -```c++ -static Persistent dataWrapperCtor; -... -Local wrapper = NanPersistentToLocal(dataWrapperCtor)->NewInstance(); -NanSetInternalFieldPointer(wrapper, 0, this); -``` - - -### Local<Object> NanObjectWrapHandle(Object) - -When you want to fetch the V8 object handle from a native object you've wrapped with Node's `ObjectWrap`, you should use `NanObjectWrapHandle`: - -```c++ -NanObjectWrapHandle(iterator)->Get(NanSymbol("end")) -``` - - -### String NanSymbol(char *) - -Use to create string symbol objects (i.e. `v8::String::NewSymbol(x)`), for getting and setting object properties, or names of objects. - -```c++ -bool foo = false; -if (obj->Has(NanSymbol("foo"))) - foo = optionsObj->Get(NanSymbol("foo"))->BooleanValue() -``` - - -### Type NanGetPointerSafe(Type *[, Type]) - -A helper for getting values from optional pointers. If the pointer is `NULL`, the function returns the optional default value, which defaults to `0`. Otherwise, the function returns the value the pointer points to. - -```c++ -char *plugh(uint32_t *optional) { - char res[] = "xyzzy"; - uint32_t param = NanGetPointerSafe(optional, 0x1337); - switch (param) { - ... - } - NanSetPointerSafe(optional, 0xDEADBEEF); -} -``` - - -### bool NanSetPointerSafe(Type *, Type) - -A helper for setting optional argument pointers. If the pointer is `NULL`, the function simply returns `false`. Otherwise, the value is assigned to the variable the pointer points to. - -```c++ -const char *plugh(size_t *outputsize) { - char res[] = "xyzzy"; - if !(NanSetPointerSafe(outputsize, strlen(res) + 1)) { - ... - } - - ... -} -``` - - -### void* NanRawString(Handle<Value>, enum Nan::Encoding, size_t *, void *, size_t, int) - -When you want to convert a V8 `String` to a `char*` buffer, use `NanRawString`. You have to supply an encoding as well as a pointer to a variable that will be assigned the number of bytes in the returned string. It is also possible to supply a buffer and its length to the function in order not to have a new buffer allocated. The final argument allows setting `String::WriteOptions`. -Just remember that you'll end up with an object that you'll need to `delete[]` at some point unless you supply your own buffer: - -```c++ -size_t count; -void* decoded = NanRawString(args[1], Nan::BASE64, &count, NULL, 0, String::HINT_MANY_WRITES_EXPECTED); -char param_copy[count]; -memcpy(param_copy, decoded, count); -delete[] decoded; -``` - - -### char* NanCString(Handle<Value>, size_t *[, char *, size_t, int]) - -When you want to convert a V8 `String` to a null-terminated C `char*` use `NanCString`. The resulting `char*` will be UTF-8-encoded, and you need to supply a pointer to a variable that will be assigned the number of bytes in the returned string. It is also possible to supply a buffer and its length to the function in order not to have a new buffer allocated. The final argument allows optionally setting `String::WriteOptions`, which default to `v8::String::NO_OPTIONS`. -Just remember that you'll end up with an object that you'll need to `delete[]` at some point unless you supply your own buffer: - -```c++ -size_t count; -char* name = NanCString(args[0], &count); -``` - - -### bool NanBooleanOptionValue(Handle<Value>, Handle<String>[, bool]) - -When you have an "options" object that you need to fetch properties from, boolean options can be fetched with this pair. They check first if the object exists (`IsEmpty`), then if the object has the given property (`Has`) then they get and convert/coerce the property to a `bool`. - -The optional last parameter is the *default* value, which is `false` if left off: - -```c++ -// `foo` is false unless the user supplies a truthy value for it -bool foo = NanBooleanOptionValue(optionsObj, NanSymbol("foo")); -// `bar` is true unless the user supplies a falsy value for it -bool bar = NanBooleanOptionValueDefTrue(optionsObj, NanSymbol("bar"), true); -``` - - -### uint32_t NanUInt32OptionValue(Handle<Value>, Handle<String>, uint32_t) - -Similar to `NanBooleanOptionValue`, use `NanUInt32OptionValue` to fetch an integer option from your options object. Can be any kind of JavaScript `Number` and it will be coerced to an unsigned 32-bit integer. - -Requires all 3 arguments as a default is not optional: - -```c++ -uint32_t count = NanUInt32OptionValue(optionsObj, NanSymbol("count"), 1024); -``` - - -### NanError(message), NanTypeError(message), NanRangeError(message) - -For making `Error`, `TypeError` and `RangeError` objects. - -```c++ -Local res = NanError("you must supply a callback argument"); -``` - - -### NanThrowError(message), NanThrowTypeError(message), NanThrowRangeError(message), NanThrowError(Local<Value>), NanThrowError(Local<Value>, int) - -For throwing `Error`, `TypeError` and `RangeError` objects. You should `return` this call: - -```c++ -return NanThrowError("you must supply a callback argument"); -``` - -Can also handle any custom object you may want to throw. If used with the error code argument, it will add the supplied error code to the error object as a property called `code`. - - -### Local<Object> NanNewBufferHandle(char *, uint32_t), Local<Object> NanNewBufferHandle(uint32_t) - -The `Buffer` API has changed a little in Node 0.11, this helper provides consistent access to `Buffer` creation: - -```c++ -NanNewBufferHandle((char*)value.data(), value.size()); -``` - -Can also be used to initialize a `Buffer` with just a `size` argument. - -Can also be supplied with a `NanFreeCallback` and a hint for the garbage collector. - - -### Local<Object> NanBufferUse(char*, uint32_t) - -`Buffer::New(char*, uint32_t)` prior to 0.11 would make a copy of the data. -While it was possible to get around this, it required a shim by passing a -callback. So the new API `Buffer::Use(char*, uint32_t)` was introduced to remove -needing to use this shim. - -`NanBufferUse` uses the `char*` passed as the backing data, and will free the -memory automatically when the weak callback is called. Keep this in mind, as -careless use can lead to "double free or corruption" and other cryptic failures. - - -### bool NanHasInstance(Persistent<FunctionTemplate>&, Handle<Value>) - -Can be used to check the type of an object to determine it is of a particular class you have already defined and have a `Persistent` handle for. - - -### Local<Context> NanNewContextHandle([ExtensionConfiguration*, Handle<ObjectTemplate>, Handle<Value>]) -Creates a new `Local` handle. - -```c++ -Local ftmpl = NanNew(); -Local otmpl = ftmpl->InstanceTemplate(); -Local ctx = NanNewContextHandle(NULL, otmpl); -``` - - -### Local NanGetCurrentContext() - -Gets the current context. - -```c++ -Local ctx = NanGetCurrentContext(); -``` - - -### void NanDisposePersistent(Persistent<T> &) - -Use `NanDisposePersistent` to dispose a `Persistent` handle. - -```c++ -NanDisposePersistent(persistentHandle); -``` - - -### NanAssignPersistent(type, handle, object) - -Use `NanAssignPersistent` to assign a non-`Persistent` handle to a `Persistent` one. You can no longer just declare a `Persistent` handle and assign directly to it later, you have to `Reset` it in Node 0.11, so this makes it easier. - -In general it is now better to place anything you want to protect from V8's garbage collector as properties of a generic `Object` and then assign that to a `Persistent`. This works in older versions of Node also if you use `NanAssignPersistent`: - -```c++ -Persistent persistentHandle; - -... - -Local obj = NanNew(); -obj->Set(NanSymbol("key"), keyHandle); // where keyHandle might be a Local -NanAssignPersistent(Object, persistentHandle, obj) -``` - - -### NanMakeWeakPersistent(Handle<T> handle, P* parameter, _NanWeakCallbackInfo<T, P>::Callback callback) - -Creates a weak persistent handle with the supplied parameter and `NAN_WEAK_CALLBACK`. The callback has to be fully specialized to work on all versions of Node. - -```c++ -NAN_WEAK_CALLBACK(weakCallback) { - -... - -} - -Local func; - -... - -int *parameter = new int(0); -NanMakeWeakPersistent(func, parameter, &weakCallback); -``` - - -### NanSetTemplate(templ, name, value) - -Use to add properties on object and function templates. - - -### NanMakeCallback(target, func, argc, argv) - -Use instead of `node::MakeCallback` to call javascript functions. This is the only proper way of calling functions. - - -### NanCompileScript(Handle s [, const ScriptOrigin& origin]) - -Use to create new scripts bound to the current context. - - -### NanRunScript(script) - -Use to run both bound and unbound scripts. - - -### NanAdjustExternalMemory(int change_in_bytes) - -Simply does `AdjustAmountOfExternalAllocatedMemory` - - -### NanAddGCEpilogueCallback(GCEpilogueCallback callback, GCType gc_type_filter=kGCTypeAll) - -Simply does `AddGCEpilogueCallback` - - -### NanAddGCPrologueCallback(GCPrologueCallback callback, GCType gc_type_filter=kGCTypeAll) - -Simply does `AddGCPrologueCallback` - - -### NanRemoveGCEpilogueCallback(GCEpilogueCallback callback) - -Simply does `RemoveGCEpilogueCallback` - - -### NanRemoveGCPrologueCallback(GCPrologueCallback callback) - -Simply does `RemoveGCPrologueCallback` - - -### NanGetHeapStatistics(HeapStatistics *heap_statistics) - -Simply does `GetHeapStatistics` - - -### NanCallback - -Because of the difficulties imposed by the changes to `Persistent` handles in V8 in Node 0.11, creating `Persistent` versions of your `Handle` is annoyingly tricky. `NanCallback` makes it easier by taking your handle, making it persistent until the `NanCallback` is deleted and even providing a handy `Call()` method to fetch and execute the callback `Function`. - -```c++ -Local callbackHandle = args[0].As(); -NanCallback *callback = new NanCallback(callbackHandle); -// pass `callback` around and it's safe from GC until you: -delete callback; -``` - -You can execute the callback like so: - -```c++ -// no arguments: -callback->Call(0, NULL); - -// an error argument: -Handle argv[] = { - NanError(NanNew("fail!")) -}; -callback->Call(1, argv); - -// a success argument: -Handle argv[] = { - NanNull(), - NanNew("w00t!") -}; -callback->Call(2, argv); -``` - -`NanCallback` also has a `Local GetCallback()` method that you can use -to fetch a local handle to the underlying callback function, as well as a -`void SetFunction(Handle)` for setting the callback on the -`NanCallback`. Additionally a generic constructor is available for using -`NanCallback` without performing heap allocations. - - -### NanAsyncWorker - -`NanAsyncWorker` is an abstract class that you can subclass to have much of the annoying async queuing and handling taken care of for you. It can even store arbitrary V8 objects for you and have them persist while the async work is in progress. - -See a rough outline of the implementation: - -```c++ -class NanAsyncWorker { -public: - NanAsyncWorker (NanCallback *callback); - - // Clean up persistent handles and delete the *callback - virtual ~NanAsyncWorker (); - - // Check the `char *errmsg` property and call HandleOKCallback() - // or HandleErrorCallback depending on whether it has been set or not - virtual void WorkComplete (); - - // You must implement this to do some async work. If there is an - // error then allocate `errmsg` to a message and the callback will - // be passed that string in an Error object - virtual void Execute (); - - // Save a V8 object in a Persistent handle to protect it from GC - void SavePersistent(const char *key, Local &obj); - - // Fetch a stored V8 object (don't call from within `Execute()`) - Local GetFromPersistent(const char *key); - -protected: - // Set this if there is an error, otherwise it's NULL - const char *errmsg; - - // Default implementation calls the callback function with no arguments. - // Override this to return meaningful data - virtual void HandleOKCallback (); - - // Default implementation calls the callback function with an Error object - // wrapping the `errmsg` string - virtual void HandleErrorCallback (); -}; -``` - - -### NanAsyncQueueWorker(NanAsyncWorker *) - -`NanAsyncQueueWorker` will run a `NanAsyncWorker` asynchronously via libuv. Both the *execute* and *after_work* steps are taken care of for you—most of the logic for this is embedded in `NanAsyncWorker`. - -### Contributors - -NAN is only possible due to the excellent work of the following contributors: - -
'; -html += '
Post Game Log Message
'; -html += '
'; -html += ''; -html += '
Enter your log message here. Plain text only please.
'; -html += '
'; -html += '

'; -html += ''; -html += ''; -html += ''; -html += '
' + large_icon_button('x', 'Cancel', "hide_popup_dialog()") + ' ' + large_icon_button('check', 'Post Message', "glog_post('"+game_id+"')") + '
'; -html += '
'; -html += ''; -session.hooks.keys[ESC_KEY] = 'hide_popup_dialog'; -safe_focus( 'fe_glog_body' ); -show_popup_dialog(500, 175, html); -} -function glog_post(game_id) { -var msg = trim( $('fe_glog_body').value ); -if (msg) { -hide_popup_dialog(); -effect_api_send('game_post_log', { -GameID: game_id, -Message: msg -}, [this, 'glog_post_finish'], { _game_id: game_id }); -} -} -function glog_post_finish(response, tx) { -show_glog_widget( tx._game_id ); -} -function hide_glog_widget() { -$('glog_widget').hide(); -} -function get_icon_for_glog_type(type) { -var icon = 'page_white.png'; -switch (type) { -case 'asset': icon = 'folder_page_white.png'; break; -case 'game': icon = 'controller.png'; break; -case 'member': icon = 'user'; break; -case 'comment': icon = 'comment.png'; break; -case 'level': icon = 'world.png'; break; -case 'sprite': icon = 'cog.png'; break; -case 'tile': icon = 'brick.png'; break; -case 'tileset': icon = 'color_swatch.png'; break; -case 'rev': icon = 'cd.png'; break; -case 'revision': icon = 'cd.png'; break; -case 'font': icon = 'style.png'; break; -case 'key': icon = 'keyboard.png'; break; -case 'audio': icon = 'sound'; break; -case 'payment': icon = 'money.png'; break; -case 'env': icon = 'weather.png'; break; -case 'environment': icon = 'weather.png'; break; -} -return icon; -} -function effect_load_script(url) { -Debug.trace('api', 'Loading script: ' + url); -load_script(url); -} -function effect_api_get_ie(cmd, params, userData) { -if (!session.api_state_ie) session.api_state_ie = {}; -var unique_id = get_unique_id(); -session.api_state_ie[unique_id] = userData; -params.format = 'js'; -params.onafter = 'effect_api_response_ie(' + unique_id + ', response);'; -var url = '/effect/api/' + cmd + composeQueryString(params); -Debug.trace('api', "Sending MSIE HTTP GET: " + url); -load_script(url); -} -function effect_api_response_ie(unique_id, tree) { -Debug.trace('api', "Got response from MSIE HTTP GET"); -var tx = session.api_state_ie[unique_id]; -delete session.api_state_ie[unique_id]; -if (tree.Code == 'session') { -do_logout_2(); -return; -} -if (tree.Code == 'access') { -do_notice("Access Denied", tree.Description, 'do_not_pass_go'); -return; -} -if (tree.Code != 0) { -if (tx._on_error) return fire_callback( tx._on_error, tree, tx ); -return do_error( tree.Description ); -} -if (tree.SessionID) { -if (tree.SessionID == '_DELETE_') { -delete session.cookie.tree.effect_session_id; -} -else { -session.cookie.set( 'effect_session_id', tree.SessionID ); -} -session.cookie.save(); -} -if (tx._api_callback) { -fire_callback( tx._api_callback, tree, tx ); -} -} -function effect_api_get(cmd, params, callback, userData) { -if (!userData) userData = {}; -userData._api_callback = callback; -if (!session.api_mod_cache[cmd] && session.username) session.api_mod_cache[cmd] = hires_time_now(); -if (!params.mod && session.api_mod_cache[cmd]) params.mod = session.api_mod_cache[cmd]; -if (ie) return effect_api_get_ie(cmd, params, userData); -var url = '/effect/api/' + cmd + composeQueryString(params); -Debug.trace('api', "Sending HTTP GET: " + url); -ajax.get( url, 'effect_api_response', userData ); -} -function effect_api_send(cmd, xml, callback, userData) { -if (!userData) userData = {}; -userData._api_callback = callback; -var data = compose_xml('EffectRequest', xml); -Debug.trace('api', "Sending API Command: " + cmd + ": " + data); -ajax.send({ -method: 'POST', -url: '/effect/api/' + cmd, -data: data, -headers: { 'Content-Type': 'text/xml' } -}, 'effect_api_response', userData); -} -function effect_api_response(tx) { -Debug.trace('api', "HTTP " + tx.response.code + ": " + tx.response.data); -if (tx.response.code == 999) { -if (tx.request._auto_retry) { -session.net_error = false; -show_progress_dialog(1, "Trying to reestablish connection..."); -session.net_error = true; -setTimeout( function() { ajax.send(tx.request); }, 1000 ); -return; -} -else return do_error( "HTTP ERROR: " + tx.response.code + ": " + tx.response.data + ' (URL: ' + tx.request.url + ')' ); -} -if (session.net_error) { -hide_progress_dialog(); -session.net_error = false; -} -if (tx.response.code != 200) { -if (tx._silent) return; -else return do_error( "HTTP ERROR: " + tx.response.code + ": " + tx.response.data + ' (URL: ' + tx.request.url + ')' ); -} -var tree = null; -if (!tx._raw) { -var parser = new XML({ -preserveAttributes: true, -text: tx.response.data -}); -if (parser.getLastError()) return do_error("XML PARSE ERROR: " + parser.getLastError()); -tree = parser.getTree(); -if (tree.Code == 'session') { -do_logout_2(); -return; -} -if (tree.Code == 'access') { -do_notice("Access Denied", tree.Description, 'do_not_pass_go'); -return; -} -if (tree.Code != 0) { -if (tx._on_error) return fire_callback( tx._on_error, tree, tx ); -return do_error( tree.Description ); -} -if (tree.SessionID) { -if (tree.SessionID == '_DELETE_') { -delete session.cookie.tree.effect_session_id; -} -else { -session.cookie.set( 'effect_session_id', tree.SessionID ); -} -session.cookie.save(); -} -} -if (tx._api_callback) { -fire_callback( tx._api_callback, tree, tx ); -} -} -function effect_api_mod_touch() { -for (var idx = 0, len = arguments.length; idx < len; idx++) { -session.api_mod_cache[ arguments[idx] ] = hires_time_now(); -} -} -function do_not_pass_go() { -Nav.go('Main'); -} -var Nav = { -loc: '', -old_loc: '', -inited: false, -nodes: [], -init: function() { -if (!this.inited) { -this.inited = true; -this.loc = 'init'; -this.monitor(); -} -}, -monitor: function() { -var parts = window.location.href.split(/\#/); -var anchor = parts[1]; -if (!anchor) anchor = 'Main'; -var full_anchor = '' + anchor; -var sub_anchor = ''; -anchor = anchor.replace(/\%7C/, '|'); -if (anchor.match(/\|(\w+)$/)) { -sub_anchor = RegExp.$1.toLowerCase(); -anchor = anchor.replace(/\|(\w+)$/, ''); -} -if ((anchor != this.loc) && !anchor.match(/^_/)) { -Debug.trace('nav', "Caught navigation anchor: " + full_anchor); -var page_name = ''; -var page_args = null; -if (full_anchor.match(/^\w+\?.+/)) { -parts = full_anchor.split(/\?/); -page_name = parts[0]; -page_args = parseQueryString( parts[1] ); -} -else if (full_anchor.match(/^(\w+)\/(.*)$/)) { -page_name = RegExp.$1; -page_args = RegExp.$2; -} -else { -parts = full_anchor.split(/\//); -page_name = parts[0]; -page_args = parts.slice(1); -} -Debug.trace('nav', "Calling page: " + page_name + ": " + serialize(page_args)); -hide_popup_dialog(); -var result = page_manager.click( page_name, page_args ); -if (result) { -if (window.pageTracker && (this.loc != 'init')) { -setTimeout( function() { pageTracker._trackPageview('/effect/' + anchor); }, 1000 ); -} -this.old_loc = this.loc; -if (this.old_loc == 'init') this.old_loc = 'Main'; -this.loc = anchor; -} -else { -this.go( this.loc ); -} -} -else if (sub_anchor != this.sub_anchor) { -Debug.trace('nav', "Caught sub-anchor: " + sub_anchor); -$P().gosub( sub_anchor ); -} -this.sub_anchor = sub_anchor; -setTimeout( 'Nav.monitor()', 100 ); -}, -go: function(anchor, force) { -anchor = anchor.replace(/^\#/, ''); -if (force) this.loc = 'init'; -window.location.href = '#' + anchor; -}, -prev: function() { -this.go( this.old_loc || 'Main' ); -}, -refresh: function() { -this.loc = 'refresh'; -}, -bar: function() { -var nodes = arguments; -var html = ''; -for (var idx = 0, len = nodes.length; idx < len; idx++) { -var node = nodes[idx]; -if (node) this.nodes[idx] = node; -else node = this.nodes[idx]; -if (node != '_ignore_') { -html += ''; -} -} -html += '
'; -$('d_nav_bar').innerHTML = html; -}, -title: function(name) { -if (name) document.title = name + ' | EffectGames.com'; -else document.title = 'EffectGames.com'; -}, -currentAnchor: function() { -var parts = window.location.href.split(/\#/); -var anchor = parts[1] || ''; -var sub_anchor = ''; -anchor = anchor.replace(/\%7C/, '|'); -if (anchor.match(/\|(\w+)$/)) { -sub_anchor = RegExp.$1.toLowerCase(); -anchor = anchor.replace(/\|(\w+)$/, ''); -} -return anchor; -} -}; -var Blog = { -edit_caption: '
*Bold*  |Italic|  {monospace}  [http://link]  Formatting Guide...
', -search: function(args) { -if (!args.mode) args.mode = 'and'; -if (!args.offset) args.offset = 0; -if (!args.limit) args.limit = 10; -if (!args.format) args.format = 'xml'; -var query_args = copy_object( args ); -delete query_args.callback; -effect_api_get( 'article_search', query_args, [this, 'search_response'], { _search_args: args } ); -}, -get_article_preview: function(row, args) { -var html = ''; -Debug.trace('blog', 'Row: ' + dumper(row)); -html += '
'; -var ext_article_url = 'http://' + location.hostname + '/effect/article.psp.html' + row.Path + '/' + row.ArticleID; -var article_url = '#Article' + row.Path + '/' + row.ArticleID; -html += ''; -if (!args.title_only) { -html += '
'; -html += row.Preview; -html += '  ' + (args.link_title || 'Read Full Story...') + ''; -html += '
'; -html += ''; -html += '
'; -var elem_class = args.footer_element_class || 'blog_preview_footer_element'; -if ((session.username == row.Username) || is_admin()) { -html += '
' + -icon('page_white_edit.png', "Edit", '#ArticleEdit?path=' + row.Path + '&id=' + row.ArticleID) + '
'; -} -html += '
' + get_user_display(row.Username) + '
'; -html += '
' + icon('calendar', get_short_date_time(row.Published)) + '
'; -html += '
' + icon('talk', row.Comments) + '
'; -if (0 && row.Tags) html += '
' + icon('note.png', make_tag_links(row.Tags, 3)) + '
'; -html += '
' + icon('facebook.png', 'Facebook', "window.open('http://www.facebook.com/sharer.php?u="+encodeURIComponent(ext_article_url)+'&t='+encodeURIComponent(row.Title)+"','sharer','toolbar=0,status=0,width=626,height=436')", "Share on Facebook") + '
'; -html += '
' + icon('twitter.png', 'Twitter', "window.open('http://twitter.com/home?status=Reading%20" + encodeURIComponent(row.Title) + "%3A%20" + encodeURIComponent(ext_article_url)+"')", "Share on Twitter") + '
'; -html += '
'; -html += '
'; -html += '
'; -} -html += '
'; -return html; -}, -search_response: function(response, tx) { -var args = tx._search_args; -if (args.callback) return fire_callback(args.callback, response, args); -var div = $(args.target); -assert(div, "Could not find target DIV: " + args.target); -var html = ''; -if (response.Rows && response.Rows.Row) { -var rows = always_array( response.Rows.Row ); -for (var idx = 0, len = rows.length; idx < len; idx++) { -var row = rows[idx]; -html += this.get_article_preview( row, args ); -} -if (args.more && (rows.length == args.limit)) { -html += large_icon_button('page_white_put.png', 'More...', "Blog.more(this, "+encode_object(args)+")") + '
'; -html += spacer(1,15) + '
'; -} -if (args.after) html += args.after; -} -else if (response.Code != 0) { -html = 'Search Error: ' . response.Code + ': ' + response.Description; -} -else { -html = args.none_found_msg || 'No articles found.'; -} -div.innerHTML = html; -}, -more: function(div, args) { -args.offset += args.limit; -Debug.trace('blog', "More Args: " + dumper(args)); -div.innerHTML = ''; -effect_api_get( 'article_search', args, [this, 'more_response'], { _search_args: args, _div: div } ); -}, -more_response: function(response, tx) { -var args = tx._search_args; -var button = tx._div; -var html = ''; -if (response.Rows && response.Rows.Row) { -var rows = always_array( response.Rows.Row ); -for (var idx = 0, len = rows.length; idx < len; idx++) { -var row = rows[idx]; -html += this.get_article_preview( row, args ); -} -if (args.more && (rows.length == args.limit)) { -html += large_icon_button('page_white_put.png', 'More...', "Blog.more(this, "+encode_object(args)+")") + '
'; -html += spacer(1,15) + '
'; -} -} -else if (response.Code != 0) { -html = 'Search Error: ' . response.Code + ': ' + response.Description; -} -else { -html = args.none_found_msg || 'No more articles found.'; -} -var div = document.createElement('div'); -div.innerHTML = html; -button.parentNode.replaceChild( div, button ); -} -}; -function make_tag_links(csv, max, base_url) { -if (!base_url) base_url = ''; -var tags = csv.split(/\,\s*/); -var append = ''; -if (max && (tags.length > max)) { -tags.length = max; -append = '...'; -} -var html = ''; -for (var idx = 0, len = tags.length; idx < len; idx++) { -html += ''+tags[idx]+''; -if (idx < len - 1) html += ', '; -} -html += append; -return html; -} -function get_url_friendly_title(title) { -title = title.toString().replace(/\W+/g, '_'); -if (title.length > 40) title = title.substring(0, 40); -title = title.replace(/^_+/, ''); -title = title.replace(/_+$/, ''); -return title; -} -function get_full_url(url) { -if (url.match(/^\#/)) { -var parts = window.location.href.split(/\#/); -url = parts[0] + url; -} -return url; -} -var Comments = { -comments_per_page: 10, -get: function(page_id) { -var html = ''; -html += '
'; -html += '
Comments'; -html += '
'; -html += '
'; -html += '
'; -setTimeout( function() { Comments.search({ page_id: page_id }); }, 1 ); -return html; -}, -search: function(args) { -if (!args.limit) args.limit = this.comments_per_page; -if (!args.offset) args.offset = 0; -assert(args.page_id, "Comments.search: No page_id specified"); -args.format = 'xml'; -this.last_search = args; -effect_api_get( 'comments_get', args, [this, 'search_response'], { _search_args: args } ); -}, -research: function(offset) { -var args = this.last_search; -if (!args) return; -args.offset = offset; -effect_api_get( 'comments_get', args, [this, 'search_response'], { _search_args: args } ); -}, -search_response: function(response, tx) { -this.comments = []; -var args = tx._search_args; -if (args.callback) return fire_callback(args.callback, response, args); -var html = ''; -html += '
' + -large_icon_button( 'comment_edit.png', 'Post Comment...', "Comments.add('"+args.page_id+"')" ) + '
'; -if (args.page_id.match(/^Article\//)) { -html += '
' + icon('feed.png', 'RSS', '/effect/api/comment_feed/' + args.page_id + '.rss', 'Comments RSS Feed') + '
'; -} -if (response.Items && response.Items.Item && response.List && response.List.length) { -html += ''; -html += '
'; -var items = this.comments = always_array( response.Items.Item ); -for (var idx = 0, len = items.length; idx < len; idx++) { -var item = items[idx]; -var extra_classes = (args.highlight && (args.highlight == item.ID)) ? ' highlight' : ''; -html += '
'; -html += '
'; -if (item.Username) html += ''; -html += '' + item.Name.toString().toUpperCase() + ''; -if (item.Username) html += ''; -html += ', ' + get_short_date_time(item.Date) + '
'; -html += '
'; -html += this.get_comment_controls( args.page_id, item ); -html += '
'; -html += '
'; -html += '
' + item.Comment + '
'; -html += '
'; -html += ''; -if (item.LastReply && ((item.LastReply >= time_now() - (86400 * 7)) || (session.username && (session.username == item.Username)))) { -setTimeout( "Comments.show_replies('"+args.page_id+"','"+item.ID+"')", 1 ); -} -} -} -else { -} -$( 'd_comments_' + args.page_id ).innerHTML = html; -}, -get_control: function(icon, code, text, status_text) { -if (!icon.match(/\.\w+$/)) icon += '.gif'; -return '' + code_link(code, text, status_text) + ''; -}, -get_comment_controls: function(page_id, comment) { -var html = ''; -var spacer_txt = '  |  '; -if (session.user) { -html += this.get_control('comment', "Comments.reply('"+page_id+"','"+comment.ID+"')", 'Reply') + spacer_txt; -} -if (comment.Replies) { -if (comment._replies_visible) html += this.get_control('magnify_minus', "Comments.hide_replies('"+page_id+"','"+comment.ID+"')", 'Hide Replies'); -else html += this.get_control('magnify_plus', "Comments.show_replies('"+page_id+"','"+comment.ID+"')", 'Show Replies ('+comment.Replies+')'); -if (session.user) html += spacer_txt; -} -if (session.user) { -html += this.get_control( -'star', -"Comments.like('"+page_id+"','"+comment.ID+"')", -'Like' + (comment.Like ? (' ('+comment.Like+')') : ''), -comment.Like ? (comment.Like + ' ' + ((comment.Like == 1) ? 'person likes this' : 'people like this')) : 'I like this comment' -) + spacer_txt; -if (is_admin()) html += this.get_control('trash', "Comments._delete('"+page_id+"','"+comment.ID+"')", 'Delete') + spacer_txt; -html += this.get_control('warning', "Comments.report('"+page_id+"','"+comment.ID+"')", 'Report Abuse'); -} -return html; -}, -reply: function(page_id, comment_id) { -hide_popup_dialog(); -delete session.progress; -var comment = find_object( this.comments, { ID: comment_id } ); -var html = ''; -html += '
'; -html += '\n \n \n \n'); - }; - __out.push('\n\n'); - __out.push(require('templates/clients/modules/sub_header').call(this, { - heading: t("Ride Request") - })); - __out.push('\n\n\n
\n
\n
\n
\n \n \n \n \n
\n\n
'; -html += '
Reply to Comment by "'+comment.Name+'"
'; -html += '
'; -var name = this.get_name(); -html += '

Posted by: ' + name; -if (!session.user) html += ' → Create Account'; -html += '


'; -html += ''; -html += Blog.edit_caption; -html += '
'; -html += '

'; -html += ''; -html += ''; -html += ''; -html += '
' + large_icon_button('x', 'Cancel', "hide_popup_dialog()") + ' ' + large_icon_button('check', 'Post Reply', "Comments.post_reply('"+page_id+"','"+comment_id+"')") + '
'; -html += '
'; -html += ''; -session.hooks.keys[ESC_KEY] = 'hide_popup_dialog'; -safe_focus( 'fe_comment_body' ); -show_popup_dialog(600, 300, html); -}, -post_reply: function(page_id, comment_id) { -var value = $('fe_comment_body').value; -if (!value) return; -hide_popup_dialog(); -show_progress_dialog(1, "Posting reply..."); -var name = this.get_name(); -effect_api_mod_touch('comment_replies_get'); -effect_api_send('comment_post_reply', { -PageID: page_id, -CommentID: comment_id, -Username: session.username || '', -Name: name, -Comment: value, -PageURL: location.href -}, [this, 'post_reply_finish'], { _page_id: page_id, _comment_id: comment_id } ); -}, -post_reply_finish: function(response, tx) { -hide_popup_dialog(); -var page_id = tx._page_id; -var comment_id = tx._comment_id; -var comment = find_object( this.comments, { ID: comment_id } ); -do_message('success', "Comment reply posted successfully."); -this.show_replies(page_id, comment_id); -if (!comment.Replies) comment.Replies = 1; else comment.Replies++; -$('d_comment_controls_'+comment_id).innerHTML = this.get_comment_controls( page_id, comment ); -}, -show_replies: function(page_id, comment_id) { -var comment = find_object( this.comments, { ID: comment_id } ); -if (!comment._replies_visible) { -$('d_comment_replies_' + comment_id).show().innerHTML = ''; -} -var args = { page_id: page_id, comment_id: comment_id, offset: 0, limit: 100 }; -effect_api_get( 'comment_replies_get', args, [this, 'receive_replies_response'], { _search_args: args } ); -}, -receive_replies_response: function(response, tx) { -var page_id = tx._search_args.page_id; -var comment_id = tx._search_args.comment_id; -var comment = find_object( this.comments, { ID: comment_id } ); -var html = ''; -var replies = always_array( response.Items.Item ); -for (var idx = 0, len = replies.length; idx < len; idx++) { -var reply = replies[idx]; -html += get_chat_balloon( -(reply.Username == session.username) ? 'blue' : 'grey', -reply.Username, -reply.Comment.replace(/^]*?>(.+)<\/div>$/i, '$1') -); -} -$('d_comment_replies_' + comment_id).innerHTML = html; -if (!comment._replies_visible) { -$('d_comment_replies_' + comment_id).hide(); -animate_div_visibility( 'd_comment_replies_' + comment_id, true ); -} -comment._replies_visible = true; -$('d_comment_controls_'+comment_id).innerHTML = this.get_comment_controls( page_id, comment ); -}, -hide_replies: function(page_id, comment_id) { -var comment = find_object( this.comments, { ID: comment_id } ); -if (comment._replies_visible) { -animate_div_visibility( 'd_comment_replies_' + comment_id, false ); -comment._replies_visible = false; -$('d_comment_controls_'+comment_id).innerHTML = this.get_comment_controls( page_id, comment ); -} -}, -like: function(page_id, comment_id) { -effect_api_mod_touch('comments_get'); -effect_api_send('comment_like', { -PageID: page_id, -CommentID: comment_id -}, [this, 'like_finish'], { _page_id: page_id, _comment_id: comment_id, _on_error: [this, 'like_error'] } ); -}, -like_error: function(response, tx) { -if (response.Code == 'comment_already_like') do_message('error', "You already like this comment."); -else do_error( response.Description ); -}, -like_finish: function(resopnse, tx) { -var page_id = tx._page_id; -var comment_id = tx._comment_id; -var comment = find_object( this.comments, { ID: comment_id } ); -do_message('success', "You now like this comment."); -if (!comment.Like) comment.Like = 1; else comment.Like++; -$('d_comment_controls_'+comment_id).innerHTML = this.get_comment_controls( page_id, comment ); -}, -add: function(page_id) { -hide_popup_dialog(); -delete session.progress; -var html = ''; -html += '
'; -html += '\n \n \n \n \n \n \n \n \n \n '); - }, this); - __out.push('\n\n
\n
'; -html += '
Post New Comment
'; -html += '
'; -var name = this.get_name(); -html += '

Posted by: ' + name; -if (!session.user) html += ' → Create Account'; -html += '


'; -html += ''; -html += Blog.edit_caption; -html += '
'; -html += '

'; -html += ''; -html += ''; -html += ''; -html += '
' + large_icon_button('x', 'Cancel', "hide_popup_dialog()") + ' ' + large_icon_button('check', 'Post Comment', "Comments.post('"+page_id+"')") + '
'; -html += '
'; -html += ''; -session.hooks.keys[ESC_KEY] = 'hide_popup_dialog'; -safe_focus( 'fe_comment_body' ); -show_popup_dialog(600, 300, html); -}, -report: function(page_id, comment_id) { -if (confirm('Are you sure you want to report this comment to the site administrators as abusive and/or spam?')) { -effect_api_send('comment_report_abuse', { -PageID: page_id, -CommentID: comment_id -}, [this, 'report_finish'], { _page_id: page_id, _comment_id: comment_id } ); -} -}, -report_finish: function(response, tx) { -do_message('success', 'Your abuse report has been received, and will be evaluated by the site administrators.'); -}, -_delete: function(page_id, comment_id) { -if (confirm('Are you sure you want to permanently delete this comment?')) { -effect_api_mod_touch('comments_get'); -effect_api_send('comment_delete', { -PageID: page_id, -CommentID: comment_id -}, [this, 'delete_finish'], { _page_id: page_id, _comment_id: comment_id } ); -} -}, -delete_finish: function(response, tx) { -do_message('success', 'The comment was deleted successfully.'); -var page_id = tx._page_id; -this.search({ page_id: page_id }); -}, -get_name: function() { -var name = '(Anonymous)'; -if (session.user) { -if (get_bool_pref('public_profile')) name = session.user.FullName; -else name = session.username; -} -return name; -}, -post: function(page_id) { -var value = $('fe_comment_body').value; -if (!value) return; -hide_popup_dialog(); -show_progress_dialog(1, "Posting comment..."); -var name = this.get_name(); -effect_api_mod_touch('comments_get'); -effect_api_send('comment_post', { -PageID: page_id, -Username: session.username || '', -Name: name, -Comment: value -}, [this, 'post_finish'], { _page_id: page_id } ); -}, -post_finish: function(response, tx) { -hide_popup_dialog(); -var comment_id = response.CommentID; -var page_id = tx._page_id; -this.search({ page_id: page_id, highlight: comment_id }); -} -}; -Class.create( 'Menu', { -id: '', -menu: null, -__construct: function(id) { -this.id = id; -}, -load: function() { -if (!this.menu) { -this.menu = $(this.id); -assert( !!this.menu, "Could not locate DOM element: " + this.id ); -} -}, -get_value: function() { -this.load(); -return this.menu.options[this.menu.selectedIndex].value; -}, -set_value: function(value, auto_add) { -value = str_value(value); -this.load(); -for (var idx = 0, len = this.menu.options.length; idx < len; idx++) { -if (this.menu.options[idx].value == value) { -this.menu.selectedIndex = idx; -return true; -} -} -if (auto_add) { -this.menu.options[this.menu.options.length] = new Option(value, value); -this.menu.selectedIndex = this.menu.options.length - 1; -return true; -} -return false; -}, -disable: function() { -this.load(); -this.menu.disabled = true; -this.menu.setAttribute( 'disabled', 'disabled' ); -}, -enable: function() { -this.load(); -this.menu.setAttribute( 'disabled', '' ); -this.menu.disabled = false; -}, -populate: function(items, sel_value) { -this.load(); -this.menu.options.length = 0; -for (var idx = 0, len = items.length; idx < len; idx++) { -var item = items[idx]; -var item_name = ''; -var item_value = ''; -if (isa_hash(item)) { -item_name = item.label; -item_value = item.data; -} -else if (isa_array(item)) { -item_name = item[0]; -item_value = item[1]; -} -else { -item_name = item_value = item; -} -this.menu.options[ this.menu.options.length ] = new Option( item_name, item_value ); -if (item_value == sel_value) this.menu.selectedIndex = idx; -} -} -} ); -Class.subclass( Menu, 'MultiMenu', { -__static: { -toggle_type: function(id) { -var menu = $(id); -assert(menu, "Could not find menu in DOM: " + id); -if (menu.disabled) return; -var obj = MenuManager.find(id); -assert(obj, "Could not find menu in MenuManager: " + id); -var div = $( 'd_inner_' + id ); -var ic = $( 'ic_' + id ); -var is_multiple = (ic.src.indexOf('contract') > -1); -obj.multi = !is_multiple; -var multiple_tag = !is_multiple ? -' multiple="multiple" size=5' : ''; -var items = []; -for (var idx = 0; idx < menu.options.length; idx++) { -var option = menu.options[idx]; -array_push( items, { -value: option.value, -text: option.text, -selected: option.selected -}); -} -var html = ''; -html += ''; -div.innerHTML = html; -ic.src = images_uri + '/menu_' + (is_multiple ? 'expand' : 'contract') + '.gif'; -obj.menu = null; -} -}, -attribs: null, -multi: false, -toggle: true, -__construct: function(id, attribs) { -this.id = id; -if (attribs) this.attribs = attribs; -}, -get_html: function(items, selected_csv, attribs) { -if (!items) items = []; -if (!selected_csv) selected_csv = ''; -if (attribs) this.attribs = attribs; -var selected = csv_to_hash(selected_csv); -this.menu = null; -if (num_keys(selected) > 1) this.multi = true; -var html = '
'; -html += ''; -html += ''; -html += ''; -if (this.toggle) html += ''; -html += '
' + spacer(1,1) + '
'+spacer(1,2)+'
'; -html += '
'; -return html; -}, -get_value: function() { -this.load(); -var value = ''; -for (var idx = 0; idx < this.menu.options.length; idx++) { -var option = this.menu.options[idx]; -if (option.selected && option.value.length) { -if (value.length > 0) value += ','; -value += option.value; -} -} -return value; -}, -set_value: function(value, auto_add) { -value = '' + value; -this.load(); -if (!value) { -value = ''; -for (var idx = 0; idx < this.menu.options.length; idx++) { -var option = this.menu.options[idx]; -option.selected = (option.value == value); -} -return; -} -var selected = csv_to_hash(value); -if ((num_keys(selected) > 1) && !this.multi) { -MultiMenu.toggle_type(this.id); -var self = this; -setTimeout( function() { -self.set_value(value, auto_add); -}, 1 ); -return; -} -for (var idx = 0; idx < this.menu.options.length; idx++) { -var option = this.menu.options[idx]; -option.selected = selected[option.value] ? true : false; -} -}, -populate: function(items, value) { -this.load(); -this.menu.options.length = 0; -if (!value) value = ''; -var selected = csv_to_hash(value); -for (var idx = 0, len = items.length; idx < len; idx++) { -var item = items[idx]; -var item_name = ''; -var item_value = ''; -if (isa_hash(item)) { -item_name = item.label; -item_value = item.data; -} -else if (isa_array(item)) { -item_name = item[0]; -item_value = item[1]; -} -else { -item_name = item_value = item; -} -var opt = new Option( item_name, item_value ); -this.menu.options[ this.menu.options.length ] = opt; -opt.selected = selected[item_value] ? true : false; -} -}, -collapse: function() { -if (this.multi) MultiMenu.toggle_type(this.id); -}, -expand: function() { -if (!this.multi) MultiMenu.toggle_type(this.id); -} -} ); -Class.create( 'MenuManager', { -__static: { -menus: {}, -register: function(menu) { -this.menus[ menu.id ] = menu; -return menu; -}, -find: function(id) { -return this.menus[id]; -} -} -} ); -Class.create( 'GrowlManager', { -lifetime: 10, -marginRight: 0, -marginTop: 0, -__construct: function() { -this.growls = []; -}, -growl: function(type, msg) { -if (find_object(this.growls, { type: type, msg: msg })) return; -var div = $(document.createElement('div')); -div.className = 'growl_message ' + type; -div.setOpacity(0.0); -div.innerHTML = '
' + msg + '
' + spacer(1,5) + '
'; -$('d_growl_wrapper').insertBefore( div, $('d_growl_top').nextSibling ); -var growl = { id:get_unique_id(), type: type, msg: msg, opacity:0.0, start:hires_time_now(), div:div }; -this.growls.push(growl); -this.handle_resize(); -this.animate(growl); -var self = this; -div.onclick = function() { -delete_object(self.growls, { id: growl.id }); -$('d_growl_wrapper').removeChild( div ); -}; -}, -animate: function(growl) { -if (growl.deleted) return; -var now = hires_time_now(); -var div = growl.div; -if (now - growl.start <= 0.5) { -div.setOpacity( tweenFrame(0.0, 1.0, (now - growl.start) * 2, 'EaseOut', 'Quadratic') ); -} -else if (now - growl.start <= this.lifetime) { -if (!growl._fully_opaque) { -div.setOpacity( 1.0 ); -growl._fully_opaque = true; -} -} -else if (now - growl.start <= this.lifetime + 1.0) { -div.setOpacity( tweenFrame(1.0, 0.0, (now - growl.start) - this.lifetime, 'EaseOut', 'Quadratic') ); -} -else { -delete_object(this.growls, { id: growl.id }); -$('d_growl_wrapper').removeChild( div ); -return; -} -var self = this; -setTimeout( function() { self.animate(growl); }, 33 ); -}, -handle_resize: function() { -var div = $('d_growl_wrapper'); -if (this.growls.length) { -var size = getInnerWindowSize(); -div.style.top = '' + (10 + this.marginTop) + 'px'; -div.style.left = '' + Math.floor((size.width - 310) - this.marginRight) + 'px'; -} -else { -div.style.left = '-2000px'; -} -} -} ); -window.$GR = new GrowlManager(); -if (window.addEventListener) { -window.addEventListener( "resize", function() { -$GR.handle_resize(); -}, false ); -} -else if (window.attachEvent && !ie6) { -window.attachEvent("onresize", function() { -$GR.handle_resize(); -}); -} -Class.create( 'Effect.Page', { -ID: '', -data: null, -active: false, -__construct: function(config) { -if (!config) return; -this.data = {}; -if (!config) config = {}; -for (var key in config) this[key] = config[key]; -this.div = $('page_' + this.ID); -assert(this.div, "Cannot find page div: page_" + this.ID); -}, -onInit: function() { -}, -onActivate: function() { -return true; -}, -onDeactivate: function() { -return true; -}, -show: function() { -this.div.show(); -}, -hide: function() { -this.div.hide(); -}, -gosub: function(anchor) { -} -} ); -Class.require( 'Effect.Page' ); -Class.create( 'Effect.PageManager', { -pages: null, -current_page_id: '', -on_demand: {}, -__construct: function(page_list) { -this.pages = []; -this.page_list = page_list; -for (var idx = 0, len = page_list.length; idx < len; idx++) { -Debug.trace( 'page', "Initializing page: " + page_list[idx].ID ); -if (Effect.Page[ page_list[idx].ID ]) { -var page = new Effect.Page[ page_list[idx].ID ]( page_list[idx] ); -page.onInit(); -this.pages.push(page); -} -else { -Debug.trace( 'page', 'Page ' + page_list[idx].ID + ' will be loaded on-demand' ); -} -} -}, -find: function(id) { -var page = find_object( this.pages, { ID: id } ); -if (!page) Debug.trace('PageManager', "Could not find page: " + id); -return page; -}, -notify_load: function(file, id) { -for (var idx = 0, len = this.page_list.length; idx < len; idx++) { -var page_config = this.page_list[idx]; -if (page_config.File == file) { -Debug.trace( 'page', "Initializing page on-demand: " + page_config.ID ); -var page = new Effect.Page[ page_config.ID ]( page_config ); -page.onInit(); -this.pages.push(page); -} -} -var self = this; -setTimeout( function() { -var result = self.activate(id, self.temp_args); -delete self.temp_args; -$('d_page_loading').hide(); -if (!result) { -$('page_'+id).hide(); -self.current_page_id = ''; -} -}, 1 ); -}, -activate: function(id, args) { -if (!find_object( this.pages, { ID: id } )) { -var page_config = find_object( this.page_list, { ID: id } ); -assert(!!page_config, "Page config not found: " + id ); -Debug.trace('page', "Loading file on-demand: " + page_config.File + " for page: " + id); -var url = '/effect/api/load_page/' + page_config.File + '?onafter=' + escape('page_manager.notify_load(\''+page_config.File+'\',\''+id+'\')'); -if (page_config.Requires) { -var files = page_config.Requires.split(/\,\s*/); -for (var idx = 0, len = files.length; idx < len; idx++) { -var filename = files[idx]; -if (!this.on_demand[filename]) { -Debug.trace('page', "Also loading file: " + filename); -url += '&file=' + filename; -this.on_demand[filename] = 1; -} -} -} -$('d_page_loading').show(); -this.temp_args = args; -load_script( url ); -return true; -} -$('page_'+id).show(); -var page = this.find(id); -page.active = true; -if (!args) args = []; -if (!isa_array(args)) args = [ args ]; -var result = page.onActivate.apply(page, args); -if (typeof(result) == 'boolean') return result; -else return alert("Page " + id + " onActivate did not return a boolean!"); -}, -deactivate: function(id, new_id) { -var page = this.find(id); -var result = page.onDeactivate(new_id); -if (result) { -$('page_'+id).hide(); -page.active = false; -} -return result; -}, -click: function(id, args) { -Debug.trace('page', "Switching pages to: " + id); -var old_id = this.current_page_id; -if (this.current_page_id) { -var result = this.deactivate( this.current_page_id, id ); -if (!result) return false; -} -this.current_page_id = id; -this.old_page_id = old_id; -window.scrollTo( 0, 0 ); -var result = this.activate(id, args); -if (!result) { -$('page_'+id).hide(); -this.current_page_id = ''; -} -return true; -} -} ); -Class.subclass( Effect.Page, "Effect.Page.Main", { -inited: false, -onActivate: function() { -Nav.bar( ['Main', 'EffectGames.com'] ); -Nav.title(''); -$('d_blog_news').innerHTML = loading_image(); -$('d_blog_community').innerHTML = loading_image(); -$('d_blog_featured').innerHTML = loading_image(); -Blog.search({ -stag: 'featured_game', -limit: 4, -full: 1, -callback: [this, 'receive_featured_games'] -}); -effect_api_get( 'get_site_info', { cat: 'pop_pub_games' }, [this, 'receive_pop_pub_games'], { } ); -Blog.search({ -stag: 'front_page', -limit: 5, -target: 'd_blog_news', -more: 1 -}); -Blog.search({ -path: '/community', -limit: 5, -target: 'd_blog_community', -more: 1 -}); -if (!this.inited) { -this.inited = true; -config.Strings.MainSlideshow.Slide = always_array( config.Strings.MainSlideshow.Slide ); -this.slide_idx = 0; -this.num_slides = config.Strings.MainSlideshow.Slide.length; -this.slide_div_num = 0; -this.slide_dir = 1; -this.bk_pos = -340; -this.bk_pos_target = -340; -this.slide_images = []; -for (var idx = 0, len = this.num_slides; idx < len; idx++) { -var url = images_uri + '/' + config.Strings.MainSlideshow.Slide[idx].Photo; -this.slide_images[idx] = new Image(); -this.slide_images[idx].src = png(url, true); -} -} -this.height_target = 470; -this.height_start = $('d_header').offsetHeight; -this.time_start = hires_time_now(); -this.duration = 0.75; -if (!this.timer) this.timer = setTimeout( '$P("Main").animate_mhs()', 33 ); -if (session.user) $('d_blurb_main').hide(); -else { -$('d_blurb_main').innerHTML = get_string('/Main/Blurb'); -$('d_blurb_main').show(); -} -return true; -}, -receive_pop_pub_games: function(response, tx) { -var html = ''; -if (response.Data && response.Data.Games && response.Data.Games.Game) { -var games = always_array( response.Data.Games.Game ); -for (var idx = 0, len = Math.min(games.length, 16); idx < len; idx++) { -var game = games[idx]; -html += '
' + -(game.Logo ? -user_image_thumbnail(game.Logo, 80, 60) : -'' -) + '
' + ww_fit_box(game.Title, 80, 2, session.em_width, 1) + '
'; -} -html += '
'; -} -else { -html += 'No active public games found! Why not create a new one?'; -} -$('d_main_pop_pub_games').innerHTML = html; -}, -receive_featured_games: function(response, tx) { -var html = ''; -if (response.Rows && response.Rows.Row) { -html += ''; -var rows = always_array( response.Rows.Row ); -for (var idx = 0, len = rows.length; idx < len; idx++) { -var row = rows[idx]; -var image_url = row.Params.featured_image; -if (image_url && image_url.match(/^(\w+)\/(\w+\.\w+)$/)) { -image_url = '/effect/api/view/users/' + RegExp.$1 + '/images/' + RegExp.$2; -} -if (idx % 2 == 0) html += ''; -html += ''; -if (idx % 2 == 1) html += ''; -} -if (rows.length % 2 == 1) { -html += ''; -html += ''; -} -html += '
'; -html += ''; -html += ''; -html += ''; -html += ''; -html += ''; -html += '
'; -html += ''; -html += '' + spacer(10,1) + ''; -html += ''; -html += ''; -html += '' + spacer(15,1) + '
'; -html += spacer(1,20); -html += '
'; -} -$('d_blog_featured').innerHTML = html; -}, -animate_mhs: function() { -var now = hires_time_now(); -if (now - this.time_start >= this.duration) { -$('d_header').style.height = '' + this.height_target + 'px'; -$('d_shadow').style.height = '' + this.height_target + 'px'; -delete this.timer; -} -else { -var height = tweenFrame(this.height_start, this.height_target, (now - this.time_start) / this.duration, 'EaseOut', 'Circular'); -$('d_header').style.height = '' + height + 'px'; -$('d_shadow').style.height = '' + height + 'px'; -this.timer = setTimeout( '$P("Main").animate_mhs()', 33 ); -} -}, -onDeactivate: function() { -$('d_blog_news').innerHTML = ''; -$('d_blog_community').innerHTML = ''; -this.height_target = 75; -this.height_start = $('d_header').offsetHeight; -this.time_start = hires_time_now(); -if (!this.timer) this.timer = setTimeout( '$P("Main").animate_mhs()', 33 ); -return true; -}, -draw_slide: function() { -if (this.slide_timer) return; -var slide = config.Strings.MainSlideshow.Slide[ this.slide_idx ]; -this.old_photo = $('d_header_slideshow_photo_' + this.slide_div_num); -this.old_text = $('d_header_slideshow_text_' + this.slide_div_num); -this.slide_div_num = 1 - this.slide_div_num; -this.new_photo = $('d_header_slideshow_photo_' + this.slide_div_num); -this.new_text = $('d_header_slideshow_text_' + this.slide_div_num); -this.new_photo.style.backgroundImage = 'url('+png(images_uri+'/'+slide.Photo, true)+')'; -this.new_photo.setOpacity(0.0); -var html = ''; -html += slide.Text; -this.slide_width = this.new_text.offsetWidth; -this.new_text.innerHTML = html; -if (this.slide_dir == 1) this.new_text.style.left = '' + this.slide_width + 'px'; -else this.new_text.style.left = '-' + this.slide_width + 'px'; -this.slide_time_start = hires_time_now(); -this.slide_timer = setTimeout( '$P("Main").animate_mhs_slide()', 33 ); -}, -animate_mhs_slide: function() { -var now = hires_time_now(); -if (now - this.slide_time_start >= this.duration) { -this.new_text.style.left = '0px'; -this.old_text.style.left = '-' + this.slide_width + 'px'; -this.new_photo.setOpacity( 1.0 ); -this.old_photo.setOpacity( 0.0 ); -delete this.slide_timer; -this.bk_pos = this.bk_pos_target; -} -else { -var value = tweenFrame(0.0, 1.0, (now - this.slide_time_start) / this.duration, 'EaseOut', 'Circular'); -if (this.slide_dir == 1) { -this.new_text.style.left = '' + Math.floor( this.slide_width - (this.slide_width * value) ) + 'px'; -this.old_text.style.left = '-' + Math.floor( this.slide_width * value ) + 'px'; -} -else { -this.new_text.style.left = '-' + Math.floor( this.slide_width - (this.slide_width * value) ) + 'px'; -this.old_text.style.left = '' + Math.floor( this.slide_width * value ) + 'px'; -} -this.new_photo.setOpacity( value ); -this.old_photo.setOpacity( 1.0 - value ); -var bkp = Math.floor( this.bk_pos + ((this.bk_pos_target - this.bk_pos) * value) ); -$('d_header').style.backgroundPosition = '' + bkp + 'px 0px'; -this.slide_timer = setTimeout( '$P("Main").animate_mhs_slide()', 33 ); -} -}, -prev_slide: function() { -this.bk_pos_target += 200; -this.slide_idx--; -if (this.slide_idx < 0) this.slide_idx += this.num_slides; -this.slide_dir = -1; -this.draw_slide(); -}, -next_slide: function() { -this.bk_pos_target -= 200; -this.slide_idx++; -if (this.slide_idx >= this.num_slides) this.slide_idx -= this.num_slides; -this.slide_dir = 1; -this.draw_slide(); -} -} ); -Class.subclass( Effect.Page, "Effect.Page.PublicGameList", { -onActivate: function() { -Nav.bar( -['Main', 'EffectGames.com'], -['PublicGameList', "All Public Games"] -); -Nav.title( "List of All Public Game Projects" ); -effect_api_get( 'get_site_info', { cat: 'all_pub_games' }, [this, 'receive_all_pub_games'], { } ); -this.div.innerHTML = loading_image(); -return true; -}, -onDeactivate: function() { -this.div.innerHTML = ''; -return true; -}, -receive_all_pub_games: function(response, tx) { -var html = ''; -html += '

List of All Public Game Projects

'; -html += '
This is the complete list of public games currently being built by our users, presented in alphabetical order. Maybe they could use some help! Check out the game project pages and see (requires user account).
'; -if (response.Data && response.Data.Games && response.Data.Games.Game) { -var games = always_array( response.Data.Games.Game ); -for (var idx = 0, len = games.length; idx < len; idx++) { -var game = games[idx]; -html += '
' + -(game.Logo ? -user_image_thumbnail(game.Logo, 80, 60) : -'' -) + '
' + ww_fit_box(game.Title, 80, 2, session.em_width, 1) + '
'; -} -html += '
'; -} -else { -html += 'No public games found! Why not create a new one?'; -} -this.div.innerHTML = html; -} -} ); -Class.subclass( Effect.Page, "Effect.Page.Search", { -onActivate: function(args) { -if (!args) args = {}; -var search_text = args.q; -var start = args.s || 0; -if (!start) start = 0; -var title = 'Search results for "'+search_text+'"'; -Nav.bar( -['Main', 'EffectGames.com'], -['Search?q=' + escape(search_text), "Search Results"] -); -Nav.title( title ); -this.last_search_text = search_text; -$('d_article_search').innerHTML = loading_image(); -load_script( 'http://www.google.com/uds/GwebSearch?callback=receive_google_search_results&context=0&lstkp=0&rsz=large&hl=en&source=gsc&gss=.com&sig=&q='+escape(search_text)+'%20site%3Ahttp%3A%2F%2Fwww.effectgames.com%2F&key=notsupplied&v=1.0&start='+start+'&nocache=' + (new Date()).getTime() ); -$('h_article_search').innerHTML = title; -return true; -}, -onDeactivate: function(new_page) { -$('fe_search_bar').value = ''; -$('d_article_search').innerHTML = ''; -return true; -} -} ); -function do_search_bar() { -var search_text = $('fe_search_bar').value; -if (search_text.length) { -Nav.go('Search?q=' + escape(search_text)); -} -} -function receive_google_search_results(context, response) { -var html = ''; -html += '
Powered by
'; -if (response.results.length) { -for (var idx = 0, len = response.results.length; idx < len; idx++) { -var row = response.results[idx]; -var url = row.unescapedUrl.replace(/^.+article\.psp\.html/, '#Article'); -html += '
'; -html += ''; -html += '
' + row.content + '
'; -html += '
'; -} -} -else { -html += 'No results found.'; -} -if (response.cursor.pages) { -html += '
Page: '; -for (var idx = 0, len = response.cursor.pages.length; idx < len; idx++) { -html += ''; -var page = response.cursor.pages[idx]; -var url = '#Search?q=' + escape($P('Search').last_search_text) + '&s=' + page.start; -if (response.cursor.currentPageIndex != idx) html += ''; -else html += ''; -html += page.label; -if (response.cursor.currentPageIndex != idx) html += ''; -else html += ''; -html += ''; -} -html += '
'; -} -$('d_article_search').innerHTML = html; -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/node_modules/zeparser/index.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/node_modules/zeparser/index.js deleted file mode 100644 index 8b164a425c..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/node_modules/zeparser/index.js +++ /dev/null @@ -1 +0,0 @@ -exports.ZeParser = require('./ZeParser').ZeParser; diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/node_modules/zeparser/package.json b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/node_modules/zeparser/package.json deleted file mode 100644 index 50d9f1d0c3..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/node_modules/zeparser/package.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "author": { - "name": "Peter van der Zee", - "url": "http://qfox.nl/" - }, - "name": "zeparser", - "description": "My JavaScript parser", - "version": "0.0.5", - "homepage": "https://github.com/qfox/ZeParser/", - "repository": { - "type": "git", - "url": "git://github.com/qfox/ZeParser.git" - }, - "main": "./index", - "engines": { - "node": "*" - }, - "dependencies": {}, - "devDependencies": {}, - "_npmUser": { - "name": "evilhackerdude", - "email": "evilhackerdude@gmail.com" - }, - "_id": "zeparser@0.0.5", - "_engineSupported": true, - "_npmVersion": "1.0.105", - "_nodeVersion": "v0.6.5", - "_defaultsLoaded": true, - "dist": { - "shasum": "03726561bc268f2e5444f54c665b7fd4a8c029e2", - "tarball": "http://registry.npmjs.org/zeparser/-/zeparser-0.0.5.tgz" - }, - "maintainers": [ - { - "name": "felixge", - "email": "felix@debuggable.com" - }, - { - "name": "evilhackerdude", - "email": "evilhackerdude@gmail.com" - } - ], - "directories": {}, - "_shasum": "03726561bc268f2e5444f54c665b7fd4a8c029e2", - "_from": "zeparser@0.0.5", - "_resolved": "https://registry.npmjs.org/zeparser/-/zeparser-0.0.5.tgz", - "bugs": { - "url": "https://github.com/qfox/ZeParser/issues" - }, - "readme": "ERROR: No README data found!" -} diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/node_modules/zeparser/test-parser.html b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/node_modules/zeparser/test-parser.html deleted file mode 100755 index 1ff5ff4324..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/node_modules/zeparser/test-parser.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - Parser Test Suite Page - - - - (c) qfox.nl
- Parser test suite
-
Running...
- - - - - - - \ No newline at end of file diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/node_modules/zeparser/test-tokenizer.html b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/node_modules/zeparser/test-tokenizer.html deleted file mode 100755 index 0e0d1b1a44..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/node_modules/zeparser/test-tokenizer.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - Tokenizer Test Suite Page - - - - (c) qfox.nl
- - - - - - \ No newline at end of file diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/node_modules/zeparser/tests.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/node_modules/zeparser/tests.js deleted file mode 100644 index 8a4138be3d..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/active-x-obfuscator/node_modules/zeparser/tests.js +++ /dev/null @@ -1,478 +0,0 @@ -// tests for both the tokenizer and parser. Parser test results could be checked tighter. -// api: [input, token-output-count, ?regex-hints, desc] -// regex-hints are for tokenizer, will tell for each token whether it might parse regex or not (parser's job) -var Tests = [ - -["var abc;", 4, "Variable Declaration"], -["var abc = 5;", 8, "Variable Declaration, Assignment"], -["/* */", 1, "Block Comment"], -["/** **/", 1, "JSDoc-style Comment"], -["var f = function(){;};", 13, "Assignment, Function Expression"], -["hi; // moo", 4, "Trailing Line Comment"], -["hi; // moo\n;", 6, "Trailing Line Comment, Linefeed, `;`"], -["var varwithfunction;", 4, "Variable Declaration, Identifier Containing Reserved Words, `;`"], -["a + b;", 6, "Addition/Concatenation"], - -["'a'", 1, "Single-Quoted String"], -["'a';", 2, "Single-Quoted String, `;`"], // Taken from the parser test suite. - -["'a\\n'", 1, "Single-Quoted String With Escaped Linefeed"], -["'a\\n';", 2, "Single-Quoted String With Escaped Linefeed, `;`"], // Taken from the parser test suite. - -["\"a\"", 1, "Double-Quoted String"], -["\"a\";", 2, "Double-Quoted String, `;`"], // Taken from the parser test suite. - -["\"a\\n\"", 1, "Double-Quoted String With Escaped Linefeed"], -["\"a\\n\";", 2, "Double-Quoted String With Escaped Linefeed, `;`"], // Taken from the parser test suite. - -["500", 1, "Integer"], -["500;", 2, "Integer, `;`"], // Taken from the parser test suite. - -["500.", 1, "Double With Trailing Decimal Point"], -["500.;", 2, "Double With Trailing Decimal Point"], // Taken from the parser test suite. - -["500.432", 1, "Double With Decimal Component"], -["500.432;", 2, "Double With Decimal Component, `;`"], // Taken from the parser test suite. - -[".432432", 1, "Number, 0 < Double < 1"], -[".432432;", 2, "Number, 0 < Double < 1, `;`"], // Taken from the parser test suite. - -["(a,b,c)", 7, "Parentheses, Comma-separated identifiers"], -["(a,b,c);", 8, "Parentheses, Comma-separated identifiers, `;`"], // Taken from the parser test suite. - -["[1,2,abc]", 7, "Array literal"], -["[1,2,abc];", 8, "Array literal, `;`"], // Taken from the parser test suite. - -["{a:1,\"b\":2,c:c}", 13, "Object literal"], -["var o = {a:1,\"b\":2,c:c};", 20, "Assignment, Object Literal, `;`"], // Taken from the parser test suite. - -["var x;\nvar y;", 9, "2 Variable Declarations, Multiple lines"], -["var x;\nfunction n(){ }", 13, "Variable, Linefeed, Function Declaration"], -["var x;\nfunction n(abc){ }", 14, "Variable, Linefeed, Function Declaration With One Argument"], -["var x;\nfunction n(abc, def){ }", 17, "Variable, Linefeed, Function Declaration With Multiple Arguments"], -["function n(){ \"hello\"; }", 11, "Function Declaration, Body"], - -["/a/;", 2, [true, false], "RegExp Literal, `;`"], -["/a/b;", 2, [true, true], "RegExp Literal, Flags, `;`"], -["++x;", 3, "Unary Increment, Prefix, `;`"], -[" / /;", 3, [true, true, false], "RegExp, Leading Whitespace, `;`"], -["/ / / / /", 5, [true, false, false, false, true], "RegExp Containing One Space, Space, Division, Space, RegExp Containing One Space"], - -// Taken from the parser test suite. - -["\"var\";", 2, "Keyword String, `;`"], -["\"variable\";", 2, "String Beginning With Keyword, `;`"], -["\"somevariable\";", 2, "String Containing Keyword, `;`"], -["\"somevar\";", 2, "String Ending With Keyword, `;`"], - -["var varwithfunction;", 4, "Keywords should not be matched in identifiers"], - -["var o = {a:1};", 12, "Object Literal With Unquoted Property"], -["var o = {\"b\":2};", 12, "Object Literal With Quoted Property"], -["var o = {c:c};", 12, "Object Literal With Equivalent Property Name and Identifier"], - -["/a/ / /b/;", 6, [true, true, false, false, true, false], "RegExp, Division, RegExp, `;`"], -["a/b/c;", 6, "Triple Division (Identifier / Identifier / Identifier)"], - -["+function(){/regex/;};", 9, [false, false, false, false, false, true, false, false, false], "Unary `+` Operator, Function Expression Containing RegExp and Semicolon, `;`"], - -// Line Terminators. -["\r\n", 1, "CRLF Line Ending = 1 Linefeed"], -["\r", 1, "CR Line Ending = 1 Linefeed"], -["\n", 1, "LF Line Ending = 1 Linefeed"], -["\r\n\n\u2028\u2029\r", 5, "Various Line Terminators"], - -// Whitespace. -["a \t\u000b\u000c\u00a0\uFFFFb", 8, "Whitespace"], - -// Comments. -["//foo!@#^&$1234\nbar;", 4, "Line Comment, Linefeed, Identifier, `;`"], -["/* abcd!@#@$* { } && null*/;", 2, "Single-Line Block Comment, `;`"], -["/*foo\nbar*/;", 2, "Multi-Line Block Comment, `;`"], -["/*x*x*/;", 2, "Block Comment With Asterisks, `;`"], -["/**/;", 2, "Empty Comment, `;`"], - -// Identifiers. -["x;", 2, "Single-Character Identifier, `;`"], -["_x;", 2, "Identifier With Leading `_`, `;`"], -["xyz;", 2, "Identifier With Letters Only, `;`"], -["$x;", 2, "Identifier With Leading `$`, `;`"], -["x5;", 2, "Identifier With Number As Second Character, `;`"], -["x_y;", 2, "Identifier Containing `_`, `;`"], -["x+5;", 4, "Identifier, Binary `+` Operator, Identifier, `;`"], -["xyz123;", 2, "Alphanumeric Identifier, `;`"], -["x1y1z1;", 2, "Alternating Alphanumeric Identifier, `;`"], -["foo\\u00d8bar;", 2, "Identifier With Unicode Escape Sequence (`\\uXXXX`), `;`"], -["f\u00d8\u00d8bar;", 2, "Identifier With Embedded Unicode Character"], - -// Numbers. -["5;", 2, "Integer, `;`"], -["5.5;", 2, "Double, `;`"], -["0;", 2, "Integer Zero, `;`"], -["0.0;", 2, "Double Zero, `;`"], -["0.001;", 2, "0 < Decimalized Double < 1, `;`"], -["1.e2;", 2, "Integer With Decimal and Exponential Component (`e`), `;`"], -["1.e-2;", 2, "Integer With Decimal and Negative Exponential Component, `;`"], -["1.E2;", 2, "Integer With Decimal and Uppercase Exponential Component (`E`), `;`"], -["1.E-2;", 2, "Integer With Decimal and Uppercase Negative Exponential Component, `;`"], -[".5;", 2, "0 < Double < 1, `;`"], -[".5e3;", 2, "(0 < Double < 1) With Exponential Component"], -[".5e-3;", 2, "(0 < Double < 1) With Negative Exponential Component"], -["0.5e3;", 2, "(0 < Decimalized Double < 1) With Exponential Component"], -["55;", 2, "Two-Digit Integer, `;`"], -["123;", 2, "Three-Digit Integer, `;`"], -["55.55;", 2, "Two-Digit Double, `;`"], -["55.55e10;", 2, "Two-Digit Double With Exponential Component, `;`"], -["123.456;", 2, "Three-Digit Double, `;`"], -["1+e;", 4, "Additive Expression, `;`"], -["0x01;", 2, "Hexadecimal `1` With 1 Leading Zero, `;`"], -["0xcafe;", 2, "Hexadecimal `51966`, `;`"], -["0x12345678;", 2, "Hexadecimal `305419896`, `;`"], -["0x1234ABCD;", 2, "Hexadecimal `305441741` With Uppercase Letters, `;`"], -["0x0001;", 2, "Hexadecimal `1` with 3 Leading Zeros, `;`"], - -// Strings. -["\"foo\";", 2, "Multi-Character Double-Quoted String, `;`"], -["\"a\\n\";", 2, "Double-Quoted String Containing Linefeed, `;`"], -["\'foo\';", 2, "Single-Quoted String, `;`"], -["'a\\n';", 2, "Single-Quoted String Containing Linefeed, `;`"], -["\"x\";", 2, "Single-Character Double-Quoted String, `;`"], -["'';", 2, "Empty Single-Quoted String, `;`"], -["\"foo\\tbar\";", 2, "Double-Quoted String With Tab Character, `;`"], -["\"!@#$%^&*()_+{}[]\";", 2, "Double-Quoted String Containing Punctuators, `;`"], -["\"/*test*/\";", 2, "Double-Quoted String Containing Block Comment, `;`"], -["\"//test\";", 2, "Double-Quoted String Containing Line Comment, `;`"], -["\"\\\\\";", 2, "Double-Quoted String Containing Reverse Solidus, `;`"], -["\"\\u0001\";", 2, "Double-Quoted String Containing Numeric Unicode Escape Sequence, `;`"], -["\"\\uFEFF\";", 2, "Double-Quoted String Containing Alphanumeric Unicode Escape Sequence, `;`"], -["\"\\u10002\";", 2, "Double-Quoted String Containing 5-Digit Unicode Escape Sequence, `;`"], -["\"\\x55\";", 2, "Double-Quoted String Containing Hex Escape Sequence, `;`"], -["\"\\x55a\";", 2, "Double-Quoted String Containing Hex Escape Sequence and Additional Character, `;`"], -["\"a\\\\nb\";", 2, "Double-Quoted String Containing Escaped Linefeed, `;`"], -["\";\"", 1, "Double-Quoted String Containing `;`"], -["\"a\\\nb\";", 2, "Double-Quoted String Containing Reverse Solidus and Linefeed, `;`"], -["'\\\\'+ ''", 4, "Single-Quoted String Containing Reverse Solidus, `+`, Empty Single-Quoted String"], - -// `null`, `true`, and `false`. -["null;", 2, "`null`, `;`"], -["true;", 2, "`true`, `;`"], -["false;", 2, "`false`, `;`"], - -// RegExps -["/a/;", 2, [true, true], "Single-Character RegExp, `;`"], -["/abc/;", 2, [true, true], "Multi-Character RegExp, `;`"], -["/abc[a-z]*def/g;", 2, [true, true], "RegExp Containing Character Range and Quantifier, `;`"], -["/\\b/;", 2, [true, true], "RegExp Containing Control Character, `;`"], -["/[a-zA-Z]/;", 2, [true, true], "RegExp Containing Extended Character Range, `;`"], -["/foo(.*)/g;", 2, [true, false], "RegExp Containing Capturing Group and Quantifier, `;`"], - -// Array Literals. -["[];", 3, "Empty Array, `;`"], -["[\b\n\f\r\t\x20];", 9, "Array Containing Whitespace, `;`"], -["[1];", 4, "Array Containing 1 Element, `;`"], -["[1,2];", 6, "Array Containing 2 Elements, `;`"], -["[1,2,,];", 8, "Array Containing 2 Elisions, `;`"], -["[1,2,3];", 8, "Array Containing 3 Elements, `;`"], -["[1,2,3,,,];", 11, "Array Containing 3 Elisions, `;`"], - -// Object Literals. -["({x:5});", 8, "Object Literal Containing 1 Member; `;`"], -["({x:5,y:6});", 12, "Object Literal Containing 2 Members, `;`"], -["({x:5,});", 9, "Object Literal Containing 1 Member and Trailing Comma, `;`"], -["({if:5});", 8, "Object Literal Containing Reserved Word Property Name, `;`"], -["({ get x() {42;} });", 17, "Object Literal Containing Getter, `;`"], -["({ set y(a) {1;} });", 18, "Object Literal Containing Setter, `;`"], - -// Member Expressions. -["o.m;", 4, "Dot Member Accessor, `;`"], -["o['m'];", 5, "Square Bracket Member Accessor, `;`"], -["o['n']['m'];", 8, "Nested Square Bracket Member Accessor, `;`"], -["o.n.m;", 6, "Nested Dot Member Accessor, `;`"], -["o.if;", 4, "Dot Reserved Property Name Accessor, `;`"], - -// Function Calls. -["f();", 4, "Function Call Operator, `;`"], -["f(x);", 5, "Function Call Operator With 1 Argument, `;`"], -["f(x,y);", 7, "Function Call Operator With Multiple Arguments, `;`"], -["o.m();", 6, "Dot Member Accessor, Function Call, `;`"], -["o['m']();", 7, "Square Bracket Member Accessor, Function Call, `;`"], -["o.m(x);", 7, "Dot Member Accessor, Function Call With 1 Argument, `;`"], -["o['m'](x);", 8, "Square Bracket Member Accessor, Function Call With 1 Argument, `;`"], -["o.m(x,y);", 9, "Dot Member Accessor, Function Call With 2 Arguments, `;`"], -["o['m'](x,y);", 10, "Square Bracket Member Accessor, Function Call With 2 Arguments, `;`"], -["f(x)(y);", 8, "Nested Function Call With 1 Argument Each, `;`"], -["f().x;", 6, "Function Call, Dot Member Accessor, `;`"], - -// `eval` Function. -["eval('x');", 5, "`eval` Invocation With 1 Argument, `;`"], -["(eval)('x');", 7, "Direct `eval` Call Example, `;`"], -["(1,eval)('x');", 9, "Indirect `eval` Call Example, `;`"], -["eval(x,y);", 7, "`eval` Invocation With 2 Arguments, `;`"], - -// `new` Operator. -["new f();", 6, "`new` Operator, Function Call, `;`"], -["new o;", 4, "`new` Operator, Identifier, `;`"], -["new o.m;", 6, "`new` Operator, Dot Member Accessor, `;`"], -["new o.m(x);", 9, "`new` Operator, Dot Member Accessor, Function Call With 1 Argument, `;`"], -["new o.m(x,y);", 11, "``new` Operator, Dot Member Accessor, Function Call With 2 Arguments , `;`"], - -// Prefix and Postfix Increment. -["++x;", 3, "Prefix Increment, Identifier, `;`"], -["x++;", 3, "Identifier, Postfix Increment, `;`"], -["--x;", 3, "Prefix Decrement, Identifier, `;`"], -["x--;", 3, "Postfix Decrement, Identifier, `;`"], -["x ++;", 4, "Identifier, Space, Postfix Increment, `;`"], -["x /* comment */ ++;", 6, "Identifier, Block Comment, Postfix Increment, `;`"], -["++ /* comment */ x;", 6, "Prefix Increment, Block Comment, Identifier, `;`"], - -// Unary Operators. -["delete x;", 4, "`delete` Operator, Space, Identifier, `;`"], -["void x;", 4, "`void` Operator, Space, Identifier, `;`"], -["typeof x;", 4, "`typeof` Operator, Space, Identifier, `;`"], -["+x;", 3, "Unary `+` Operator, Identifier, `;`"], -["-x;", 3, "Unary Negation Operator, Identifier, `;`"], -["~x;", 3, "Bitwise NOT Operator, Identifier, `;`"], -["!x;", 3, "Logical NOT Operator, Identifier, `;`"], - -// Comma Operator. -["x, y;", 5, "Comma Operator"], - -// Miscellaneous. -["new Date++;", 5, "`new` Operator, Identifier, Postfix Increment, `;`"], -["+x++;", 4, "Unary `+`, Identifier, Postfix Increment, `;`"], - -// Expressions. -["1 * 2;", 6, "Integer, Multiplication, Integer, `;`"], -["1 / 2;", 6, "Integer, Division, Integer, `;`"], -["1 % 2;", 6, "Integer, Modulus, Integer, `;`"], -["1 + 2;", 6, "Integer, Addition, Integer, `;`"], -["1 - 2;", 6, "Integer, Subtraction, Integer, `;`"], -["1 << 2;", 6, "Integer, Bitwise Left Shift, Integer, `;`"], -["1 >>> 2;", 6, "Integer, Bitwise Zero-fill Right Shift, Integer, `;`"], -["1 >> 2;", 6, "Integer, Bitwise Sign-Propagating Right Shift, Integer, `;`"], -["1 * 2 + 3;", 10, "Order-of-Operations Expression, `;`"], -["(1+2)*3;", 8, "Parenthesized Additive Expression, Multiplication, `;`"], -["1*(2+3);", 8, "Multiplication, Parenthesized Additive Expression, `;`"], -["xy;", 4, "Greater-Than Relational Operator, `;`"], -["x<=y;", 4, "Less-Than-or-Equal-To Relational Operator, `;`"], -["x>=y;", 4, "Greater-Than-or-Equal-To Relational Operator, `;`"], -["x instanceof y;", 6, "`instanceof` Operator, `;`"], -["x in y;", 6, "`in` Operator, `;`"], -["x&y;", 4, "Bitwise AND Operator, `;`"], -["x^y;", 4, "Bitwise XOR Operator, `;`"], -["x|y;", 4, "Bitwise OR Operator, `;`"], -["x+y>>= y;", 6, "Bitwise Zero-Fill Right Shift Assignment, `;`"], -["x <<= y;", 6, "Bitwise Left Shift Assignment, `;`"], -["x += y;", 6, "Additive Assignment, `;`"], -["x -= y;", 6, "Subtractive Assignment, `;`"], -["x *= y;", 6, "Multiplicative Assignment, `;`"], -["x /= y;", 6, "Divisive Assignment, `;`"], -["x %= y;", 6, "Modulus Assignment, `;`"], -["x >>= y;", 6, "Bitwise Sign-Propagating Right Shift Assignment, `;`"], -["x &= y;", 6, "Bitwise AND Assignment, `;`"], -["x ^= y;", 6, "Bitwise XOR Assignment, `;`"], -["x |= y;", 6, "Bitwise OR Assignment, `;`"], - -// Blocks. -["{};", 3, "Empty Block, `;`"], -["{x;};", 5, "Block Containing 1 Identifier, `;`"], -["{x;y;};", 7, "Block Containing 2 Identifiers, `;`"], - -// Variable Declarations. -["var abc;", 4, "Variable Declaration"], -["var x,y;", 6, "Comma-Separated Variable Declarations, `;`"], -["var x=1,y=2;", 10, "Comma-Separated Variable Initializations, `;`"], -["var x,y=2;", 8, "Variable Declaration, Variable Initialization, `;`"], - -// Empty Statements. -[";", 1, "Empty Statement"], -["\n;", 2, "Linefeed, `;`"], - -// Expression Statements. -["x;", 2, "Identifier, `;`"], -["5;", 2, "Integer, `;`"], -["1+2;", 4, "Additive Statement, `;`"], - -// `if...else` Statements. -["if (c) x; else y;", 13, "Space-Delimited `if...else` Statement"], -["if (c) x;", 8, "Space-Delimited `if` Statement, `;`"], -["if (c) {} else {};", 14, "Empty Block-Delimited `if...else` Statement"], -["if (c1) if (c2) s1; else s2;", 19, "Nested `if...else` Statement Without Dangling `else`"], - -// `while` and `do...while` Loops. -["do s; while (e);", 11, "Space-Delimited `do...while` Loop"], -["do { s; } while (e);", 15, "Block-Delimited `do...while` Loop"], -["while (e) s;", 8, "Space-Delimited `while` Loop"], -["while (e) { s; };", 13, "Block-Delimited `while` Loop"], - -// `for` and `for...in` Loops. -["for (;;) ;", 8, "Infinite Space-Delimited `for` Loop"], -["for (;c;x++) x;", 12, "`for` Loop: Empty Initialization Condition; Space-Delimited Body"], -["for (i;i - - - -UglifyJS – a JavaScript parser/compressor/beautifier - - - - - - - - - - - - - -
- -
- -
-

UglifyJS – a JavaScript parser/compressor/beautifier

- - - - -
-

1 UglifyJS — a JavaScript parser/compressor/beautifier

-
- - -

-This package implements a general-purpose JavaScript -parser/compressor/beautifier toolkit. It is developed on NodeJS, but it -should work on any JavaScript platform supporting the CommonJS module system -(and if your platform of choice doesn't support CommonJS, you can easily -implement it, or discard the exports.* lines from UglifyJS sources). -

-

-The tokenizer/parser generates an abstract syntax tree from JS code. You -can then traverse the AST to learn more about the code, or do various -manipulations on it. This part is implemented in parse-js.js and it's a -port to JavaScript of the excellent parse-js Common Lisp library from Marijn Haverbeke. -

-

-( See cl-uglify-js if you're looking for the Common Lisp version of -UglifyJS. ) -

-

-The second part of this package, implemented in process.js, inspects and -manipulates the AST generated by the parser to provide the following: -

-
    -
  • ability to re-generate JavaScript code from the AST. Optionally - indented—you can use this if you want to “beautify” a program that has - been compressed, so that you can inspect the source. But you can also run - our code generator to print out an AST without any whitespace, so you - achieve compression as well. - -
  • -
  • shorten variable names (usually to single characters). Our mangler will - analyze the code and generate proper variable names, depending on scope - and usage, and is smart enough to deal with globals defined elsewhere, or - with eval() calls or with{} statements. In short, if eval() or - with{} are used in some scope, then all variables in that scope and any - variables in the parent scopes will remain unmangled, and any references - to such variables remain unmangled as well. - -
  • -
  • various small optimizations that may lead to faster code but certainly - lead to smaller code. Where possible, we do the following: - -
      -
    • foo["bar"] ==> foo.bar - -
    • -
    • remove block brackets {} - -
    • -
    • join consecutive var declarations: - var a = 10; var b = 20; ==> var a=10,b=20; - -
    • -
    • resolve simple constant expressions: 1 +2 * 3 ==> 7. We only do the - replacement if the result occupies less bytes; for example 1/3 would - translate to 0.333333333333, so in this case we don't replace it. - -
    • -
    • consecutive statements in blocks are merged into a sequence; in many - cases, this leaves blocks with a single statement, so then we can remove - the block brackets. - -
    • -
    • various optimizations for IF statements: - -
        -
      • if (foo) bar(); else baz(); ==> foo?bar():baz(); -
      • -
      • if (!foo) bar(); else baz(); ==> foo?baz():bar(); -
      • -
      • if (foo) bar(); ==> foo&&bar(); -
      • -
      • if (!foo) bar(); ==> foo||bar(); -
      • -
      • if (foo) return bar(); else return baz(); ==> return foo?bar():baz(); -
      • -
      • if (foo) return bar(); else something(); ==> {if(foo)return bar();something()} - -
      • -
      - -
    • -
    • remove some unreachable code and warn about it (code that follows a - return, throw, break or continue statement, except - function/variable declarations). - -
    • -
    • act a limited version of a pre-processor (c.f. the pre-processor of - C/C++) to allow you to safely replace selected global symbols with - specified values. When combined with the optimisations above this can - make UglifyJS operate slightly more like a compilation process, in - that when certain symbols are replaced by constant values, entire code - blocks may be optimised away as unreachable. -
    • -
    - -
  • -
- - - -
- -
-

1.1 Unsafe transformations

-
- - -

-The following transformations can in theory break code, although they're -probably safe in most practical cases. To enable them you need to pass the ---unsafe flag. -

- -
- -
-

1.1.1 Calls involving the global Array constructor

-
- - -

-The following transformations occur: -

- - - -
new Array(1, 2, 3, 4)  => [1,2,3,4]
-Array(a, b, c)         => [a,b,c]
-new Array(5)           => Array(5)
-new Array(a)           => Array(a)
-
- - -

-These are all safe if the Array name isn't redefined. JavaScript does allow -one to globally redefine Array (and pretty much everything, in fact) but I -personally don't see why would anyone do that. -

-

-UglifyJS does handle the case where Array is redefined locally, or even -globally but with a function or var declaration. Therefore, in the -following cases UglifyJS doesn't touch calls or instantiations of Array: -

- - - -
// case 1.  globally declared variable
-  var Array;
-  new Array(1, 2, 3);
-  Array(a, b);
-
-  // or (can be declared later)
-  new Array(1, 2, 3);
-  var Array;
-
-  // or (can be a function)
-  new Array(1, 2, 3);
-  function Array() { ... }
-
-// case 2.  declared in a function
-  (function(){
-    a = new Array(1, 2, 3);
-    b = Array(5, 6);
-    var Array;
-  })();
-
-  // or
-  (function(Array){
-    return Array(5, 6, 7);
-  })();
-
-  // or
-  (function(){
-    return new Array(1, 2, 3, 4);
-    function Array() { ... }
-  })();
-
-  // etc.
-
- - -
- -
- -
-

1.1.2 obj.toString() ==> obj+“”

-
- - -
-
- -
- -
-

1.2 Install (NPM)

-
- - -

-UglifyJS is now available through NPM — npm install uglify-js should do -the job. -

-
- -
- -
-

1.3 Install latest code from GitHub

-
- - - - - -
## clone the repository
-mkdir -p /where/you/wanna/put/it
-cd /where/you/wanna/put/it
-git clone git://github.com/mishoo/UglifyJS.git
-
-## make the module available to Node
-mkdir -p ~/.node_libraries/
-cd ~/.node_libraries/
-ln -s /where/you/wanna/put/it/UglifyJS/uglify-js.js
-
-## and if you want the CLI script too:
-mkdir -p ~/bin
-cd ~/bin
-ln -s /where/you/wanna/put/it/UglifyJS/bin/uglifyjs
-  # (then add ~/bin to your $PATH if it's not there already)
-
- - -
- -
- -
-

1.4 Usage

-
- - -

-There is a command-line tool that exposes the functionality of this library -for your shell-scripting needs: -

- - - -
uglifyjs [ options... ] [ filename ]
-
- - -

-filename should be the last argument and should name the file from which -to read the JavaScript code. If you don't specify it, it will read code -from STDIN. -

-

-Supported options: -

-
    -
  • -b or --beautify — output indented code; when passed, additional - options control the beautifier: - -
      -
    • -i N or --indent N — indentation level (number of spaces) - -
    • -
    • -q or --quote-keys — quote keys in literal objects (by default, - only keys that cannot be identifier names will be quotes). - -
    • -
    - -
  • -
  • --ascii — pass this argument to encode non-ASCII characters as - \uXXXX sequences. By default UglifyJS won't bother to do it and will - output Unicode characters instead. (the output is always encoded in UTF8, - but if you pass this option you'll only get ASCII). - -
  • -
  • -nm or --no-mangle — don't mangle names. - -
  • -
  • -nmf or --no-mangle-functions – in case you want to mangle variable - names, but not touch function names. - -
  • -
  • -ns or --no-squeeze — don't call ast_squeeze() (which does various - optimizations that result in smaller, less readable code). - -
  • -
  • -mt or --mangle-toplevel — mangle names in the toplevel scope too - (by default we don't do this). - -
  • -
  • --no-seqs — when ast_squeeze() is called (thus, unless you pass - --no-squeeze) it will reduce consecutive statements in blocks into a - sequence. For example, "a = 10; b = 20; foo();" will be written as - "a=10,b=20,foo();". In various occasions, this allows us to discard the - block brackets (since the block becomes a single statement). This is ON - by default because it seems safe and saves a few hundred bytes on some - libs that I tested it on, but pass --no-seqs to disable it. - -
  • -
  • --no-dead-code — by default, UglifyJS will remove code that is - obviously unreachable (code that follows a return, throw, break or - continue statement and is not a function/variable declaration). Pass - this option to disable this optimization. - -
  • -
  • -nc or --no-copyright — by default, uglifyjs will keep the initial - comment tokens in the generated code (assumed to be copyright information - etc.). If you pass this it will discard it. - -
  • -
  • -o filename or --output filename — put the result in filename. If - this isn't given, the result goes to standard output (or see next one). - -
  • -
  • --overwrite — if the code is read from a file (not from STDIN) and you - pass --overwrite then the output will be written in the same file. - -
  • -
  • --ast — pass this if you want to get the Abstract Syntax Tree instead - of JavaScript as output. Useful for debugging or learning more about the - internals. - -
  • -
  • -v or --verbose — output some notes on STDERR (for now just how long - each operation takes). - -
  • -
  • -d SYMBOL[=VALUE] or --define SYMBOL[=VALUE] — will replace - all instances of the specified symbol where used as an identifier - (except where symbol has properly declared by a var declaration or - use as function parameter or similar) with the specified value. This - argument may be specified multiple times to define multiple - symbols - if no value is specified the symbol will be replaced with - the value true, or you can specify a numeric value (such as - 1024), a quoted string value (such as ="object"= or - ='https://github.com'), or the name of another symbol or keyword (such as =null or document). - This allows you, for example, to assign meaningful names to key - constant values but discard the symbolic names in the uglified - version for brevity/efficiency, or when used wth care, allows - UglifyJS to operate as a form of conditional compilation - whereby defining appropriate values may, by dint of the constant - folding and dead code removal features above, remove entire - superfluous code blocks (e.g. completely remove instrumentation or - trace code for production use). - Where string values are being defined, the handling of quotes are - likely to be subject to the specifics of your command shell - environment, so you may need to experiment with quoting styles - depending on your platform, or you may find the option - --define-from-module more suitable for use. - -
  • -
  • -define-from-module SOMEMODULE — will load the named module (as - per the NodeJS require() function) and iterate all the exported - properties of the module defining them as symbol names to be defined - (as if by the --define option) per the name of each property - (i.e. without the module name prefix) and given the value of the - property. This is a much easier way to handle and document groups of - symbols to be defined rather than a large number of --define - options. - -
  • -
  • --unsafe — enable other additional optimizations that are known to be - unsafe in some contrived situations, but could still be generally useful. - For now only these: - -
      -
    • foo.toString() ==> foo+"" -
    • -
    • new Array(x,…) ==> [x,…] -
    • -
    • new Array(x) ==> Array(x) - -
    • -
    - -
  • -
  • --max-line-len (default 32K characters) — add a newline after around - 32K characters. I've seen both FF and Chrome croak when all the code was - on a single line of around 670K. Pass –max-line-len 0 to disable this - safety feature. - -
  • -
  • --reserved-names — some libraries rely on certain names to be used, as - pointed out in issue #92 and #81, so this option allow you to exclude such - names from the mangler. For example, to keep names require and $super - intact you'd specify –reserved-names "require,$super". - -
  • -
  • --inline-script – when you want to include the output literally in an - HTML <script> tag you can use this option to prevent </script from - showing up in the output. - -
  • -
  • --lift-vars – when you pass this, UglifyJS will apply the following - transformations (see the notes in API, ast_lift_variables): - -
      -
    • put all var declarations at the start of the scope -
    • -
    • make sure a variable is declared only once -
    • -
    • discard unused function arguments -
    • -
    • discard unused inner (named) functions -
    • -
    • finally, try to merge assignments into that one var declaration, if - possible. -
    • -
    - -
  • -
- - - -
- -
-

1.4.1 API

-
- - -

-To use the library from JavaScript, you'd do the following (example for -NodeJS): -

- - - -
var jsp = require("uglify-js").parser;
-var pro = require("uglify-js").uglify;
-
-var orig_code = "... JS code here";
-var ast = jsp.parse(orig_code); // parse code and get the initial AST
-ast = pro.ast_mangle(ast); // get a new AST with mangled names
-ast = pro.ast_squeeze(ast); // get an AST with compression optimizations
-var final_code = pro.gen_code(ast); // compressed code here
-
- - -

-The above performs the full compression that is possible right now. As you -can see, there are a sequence of steps which you can apply. For example if -you want compressed output but for some reason you don't want to mangle -variable names, you would simply skip the line that calls -pro.ast_mangle(ast). -

-

-Some of these functions take optional arguments. Here's a description: -

-
    -
  • jsp.parse(code, strict_semicolons) – parses JS code and returns an AST. - strict_semicolons is optional and defaults to false. If you pass - true then the parser will throw an error when it expects a semicolon and - it doesn't find it. For most JS code you don't want that, but it's useful - if you want to strictly sanitize your code. - -
  • -
  • pro.ast_lift_variables(ast) – merge and move var declarations to the - scop of the scope; discard unused function arguments or variables; discard - unused (named) inner functions. It also tries to merge assignments - following the var declaration into it. - -

    - If your code is very hand-optimized concerning var declarations, this - lifting variable declarations might actually increase size. For me it - helps out. On jQuery it adds 865 bytes (243 after gzip). YMMV. Also - note that (since it's not enabled by default) this operation isn't yet - heavily tested (please report if you find issues!). -

    -

    - Note that although it might increase the image size (on jQuery it gains - 865 bytes, 243 after gzip) it's technically more correct: in certain - situations, dead code removal might drop variable declarations, which - would not happen if the variables are lifted in advance. -

    -

    - Here's an example of what it does: -

  • -
- - - - - -
function f(a, b, c, d, e) {
-    var q;
-    var w;
-    w = 10;
-    q = 20;
-    for (var i = 1; i < 10; ++i) {
-        var boo = foo(a);
-    }
-    for (var i = 0; i < 1; ++i) {
-        var boo = bar(c);
-    }
-    function foo(){ ... }
-    function bar(){ ... }
-    function baz(){ ... }
-}
-
-// transforms into ==>
-
-function f(a, b, c) {
-    var i, boo, w = 10, q = 20;
-    for (i = 1; i < 10; ++i) {
-        boo = foo(a);
-    }
-    for (i = 0; i < 1; ++i) {
-        boo = bar(c);
-    }
-    function foo() { ... }
-    function bar() { ... }
-}
-
- - -
    -
  • pro.ast_mangle(ast, options) – generates a new AST containing mangled - (compressed) variable and function names. It supports the following - options: - -
      -
    • toplevel – mangle toplevel names (by default we don't touch them). -
    • -
    • except – an array of names to exclude from compression. -
    • -
    • defines – an object with properties named after symbols to - replace (see the --define option for the script) and the values - representing the AST replacement value. - -
    • -
    - -
  • -
  • pro.ast_squeeze(ast, options) – employs further optimizations designed - to reduce the size of the code that gen_code would generate from the - AST. Returns a new AST. options can be a hash; the supported options - are: - -
      -
    • make_seqs (default true) which will cause consecutive statements in a - block to be merged using the "sequence" (comma) operator - -
    • -
    • dead_code (default true) which will remove unreachable code. - -
    • -
    - -
  • -
  • pro.gen_code(ast, options) – generates JS code from the AST. By - default it's minified, but using the options argument you can get nicely - formatted output. options is, well, optional :-) and if you pass it it - must be an object and supports the following properties (below you can see - the default values): - -
      -
    • beautify: false – pass true if you want indented output -
    • -
    • indent_start: 0 (only applies when beautify is true) – initial - indentation in spaces -
    • -
    • indent_level: 4 (only applies when beautify is true) -- - indentation level, in spaces (pass an even number) -
    • -
    • quote_keys: false – if you pass true it will quote all keys in - literal objects -
    • -
    • space_colon: false (only applies when beautify is true) – wether - to put a space before the colon in object literals -
    • -
    • ascii_only: false – pass true if you want to encode non-ASCII - characters as \uXXXX. -
    • -
    • inline_script: false – pass true to escape occurrences of - </script in strings -
    • -
    - -
  • -
- - -
- -
- -
-

1.4.2 Beautifier shortcoming – no more comments

-
- - -

-The beautifier can be used as a general purpose indentation tool. It's -useful when you want to make a minified file readable. One limitation, -though, is that it discards all comments, so you don't really want to use it -to reformat your code, unless you don't have, or don't care about, comments. -

-

-In fact it's not the beautifier who discards comments — they are dumped at -the parsing stage, when we build the initial AST. Comments don't really -make sense in the AST, and while we could add nodes for them, it would be -inconvenient because we'd have to add special rules to ignore them at all -the processing stages. -

-
- -
- -
-

1.4.3 Use as a code pre-processor

-
- - -

-The --define option can be used, particularly when combined with the -constant folding logic, as a form of pre-processor to enable or remove -particular constructions, such as might be used for instrumenting -development code, or to produce variations aimed at a specific -platform. -

-

-The code below illustrates the way this can be done, and how the -symbol replacement is performed. -

- - - -
CLAUSE1: if (typeof DEVMODE === 'undefined') {
-    DEVMODE = true;
-}
-
-CLAUSE2: function init() {
-    if (DEVMODE) {
-        console.log("init() called");
-    }
-    ....
-    DEVMODE &amp;&amp; console.log("init() complete");
-}
-
-CLAUSE3: function reportDeviceStatus(device) {
-    var DEVMODE = device.mode, DEVNAME = device.name;
-    if (DEVMODE === 'open') {
-        ....
-    }
-}
-
- - -

-When the above code is normally executed, the undeclared global -variable DEVMODE will be assigned the value true (see CLAUSE1) -and so the init() function (CLAUSE2) will write messages to the -console log when executed, but in CLAUSE3 a locally declared -variable will mask access to the DEVMODE global symbol. -

-

-If the above code is processed by UglifyJS with an argument of ---define DEVMODE=false then UglifyJS will replace DEVMODE with the -boolean constant value false within CLAUSE1 and CLAUSE2, but it -will leave CLAUSE3 as it stands because there DEVMODE resolves to -a validly declared variable. -

-

-And more so, the constant-folding features of UglifyJS will recognise -that the if condition of CLAUSE1 is thus always false, and so will -remove the test and body of CLAUSE1 altogether (including the -otherwise slightly problematical statement false = true; which it -will have formed by replacing DEVMODE in the body). Similarly, -within CLAUSE2 both calls to console.log() will be removed -altogether. -

-

-In this way you can mimic, to a limited degree, the functionality of -the C/C++ pre-processor to enable or completely remove blocks -depending on how certain symbols are defined - perhaps using UglifyJS -to generate different versions of source aimed at different -environments -

-

-It is recommmended (but not made mandatory) that symbols designed for -this purpose are given names consisting of UPPER_CASE_LETTERS to -distinguish them from other (normal) symbols and avoid the sort of -clash that CLAUSE3 above illustrates. -

-
-
- -
- -
-

1.5 Compression – how good is it?

-
- - -

-Here are updated statistics. (I also updated my Google Closure and YUI -installations). -

-

-We're still a lot better than YUI in terms of compression, though slightly -slower. We're still a lot faster than Closure, and compression after gzip -is comparable. -

- - -- - - - - - - - - - -
FileUglifyJSUglifyJS+gzipClosureClosure+gzipYUIYUI+gzip
jquery-1.6.2.js91001 (0:01.59)3189690678 (0:07.40)31979101527 (0:01.82)34646
paper.js142023 (0:01.65)43334134301 (0:07.42)42495173383 (0:01.58)48785
prototype.js88544 (0:01.09)2668086955 (0:06.97)2632692130 (0:00.79)28624
thelib-full.js (DynarchLIB)251939 (0:02.55)72535249911 (0:09.05)72696258869 (0:01.94)76584
- - -
- -
- -
-

1.6 Bugs?

-
- - -

-Unfortunately, for the time being there is no automated test suite. But I -ran the compressor manually on non-trivial code, and then I tested that the -generated code works as expected. A few hundred times. -

-

-DynarchLIB was started in times when there was no good JS minifier. -Therefore I was quite religious about trying to write short code manually, -and as such DL contains a lot of syntactic hacks1 such as “foo == bar ? a -= 10 : b = 20”, though the more readable version would clearly be to use -“if/else”. -

-

-Since the parser/compressor runs fine on DL and jQuery, I'm quite confident -that it's solid enough for production use. If you can identify any bugs, -I'd love to hear about them (use the Google Group or email me directly). -

-
- -
- -
-

1.7 Links

-
- - - - - -
- -
- -
-

1.8 License

-
- - -

-UglifyJS is released under the BSD license: -

- - - -
Copyright 2010 (c) Mihai Bazon <mihai.bazon@gmail.com>
-Based on parse-js (http://marijn.haverbeke.nl/parse-js/).
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-    * Redistributions of source code must retain the above
-      copyright notice, this list of conditions and the following
-      disclaimer.
-
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimer in the documentation and/or other materials
-      provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
-EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
-OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
-TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
-THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-SUCH DAMAGE.
-
- - -
-

Footnotes:

-
-

1 I even reported a few bugs and suggested some fixes in the original - parse-js library, and Marijn pushed fixes literally in minutes. -

-
-
- -
-
-
- -
-

Date: 2011-12-09 14:59:08 EET

-

Author: Mihai Bazon

-

Org version 7.7 with Emacs version 23

-Validate XHTML 1.0 - -
- - diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/README.org b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/README.org deleted file mode 100644 index 4d01fdfdb0..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/uglify-js/README.org +++ /dev/null @@ -1,574 +0,0 @@ -#+TITLE: UglifyJS -- a JavaScript parser/compressor/beautifier -#+KEYWORDS: javascript, js, parser, compiler, compressor, mangle, minify, minifier -#+DESCRIPTION: a JavaScript parser/compressor/beautifier in JavaScript -#+STYLE: -#+AUTHOR: Mihai Bazon -#+EMAIL: mihai.bazon@gmail.com - -* UglifyJS --- a JavaScript parser/compressor/beautifier - -This package implements a general-purpose JavaScript -parser/compressor/beautifier toolkit. It is developed on [[http://nodejs.org/][NodeJS]], but it -should work on any JavaScript platform supporting the CommonJS module system -(and if your platform of choice doesn't support CommonJS, you can easily -implement it, or discard the =exports.*= lines from UglifyJS sources). - -The tokenizer/parser generates an abstract syntax tree from JS code. You -can then traverse the AST to learn more about the code, or do various -manipulations on it. This part is implemented in [[../lib/parse-js.js][parse-js.js]] and it's a -port to JavaScript of the excellent [[http://marijn.haverbeke.nl/parse-js/][parse-js]] Common Lisp library from [[http://marijn.haverbeke.nl/][Marijn -Haverbeke]]. - -( See [[http://github.com/mishoo/cl-uglify-js][cl-uglify-js]] if you're looking for the Common Lisp version of -UglifyJS. ) - -The second part of this package, implemented in [[../lib/process.js][process.js]], inspects and -manipulates the AST generated by the parser to provide the following: - -- ability to re-generate JavaScript code from the AST. Optionally - indented---you can use this if you want to “beautify” a program that has - been compressed, so that you can inspect the source. But you can also run - our code generator to print out an AST without any whitespace, so you - achieve compression as well. - -- shorten variable names (usually to single characters). Our mangler will - analyze the code and generate proper variable names, depending on scope - and usage, and is smart enough to deal with globals defined elsewhere, or - with =eval()= calls or =with{}= statements. In short, if =eval()= or - =with{}= are used in some scope, then all variables in that scope and any - variables in the parent scopes will remain unmangled, and any references - to such variables remain unmangled as well. - -- various small optimizations that may lead to faster code but certainly - lead to smaller code. Where possible, we do the following: - - - foo["bar"] ==> foo.bar - - - remove block brackets ={}= - - - join consecutive var declarations: - var a = 10; var b = 20; ==> var a=10,b=20; - - - resolve simple constant expressions: 1 +2 * 3 ==> 7. We only do the - replacement if the result occupies less bytes; for example 1/3 would - translate to 0.333333333333, so in this case we don't replace it. - - - consecutive statements in blocks are merged into a sequence; in many - cases, this leaves blocks with a single statement, so then we can remove - the block brackets. - - - various optimizations for IF statements: - - - if (foo) bar(); else baz(); ==> foo?bar():baz(); - - if (!foo) bar(); else baz(); ==> foo?baz():bar(); - - if (foo) bar(); ==> foo&&bar(); - - if (!foo) bar(); ==> foo||bar(); - - if (foo) return bar(); else return baz(); ==> return foo?bar():baz(); - - if (foo) return bar(); else something(); ==> {if(foo)return bar();something()} - - - remove some unreachable code and warn about it (code that follows a - =return=, =throw=, =break= or =continue= statement, except - function/variable declarations). - - - act a limited version of a pre-processor (c.f. the pre-processor of - C/C++) to allow you to safely replace selected global symbols with - specified values. When combined with the optimisations above this can - make UglifyJS operate slightly more like a compilation process, in - that when certain symbols are replaced by constant values, entire code - blocks may be optimised away as unreachable. - -** <> - -The following transformations can in theory break code, although they're -probably safe in most practical cases. To enable them you need to pass the -=--unsafe= flag. - -*** Calls involving the global Array constructor - -The following transformations occur: - -#+BEGIN_SRC js -new Array(1, 2, 3, 4) => [1,2,3,4] -Array(a, b, c) => [a,b,c] -new Array(5) => Array(5) -new Array(a) => Array(a) -#+END_SRC - -These are all safe if the Array name isn't redefined. JavaScript does allow -one to globally redefine Array (and pretty much everything, in fact) but I -personally don't see why would anyone do that. - -UglifyJS does handle the case where Array is redefined locally, or even -globally but with a =function= or =var= declaration. Therefore, in the -following cases UglifyJS *doesn't touch* calls or instantiations of Array: - -#+BEGIN_SRC js -// case 1. globally declared variable - var Array; - new Array(1, 2, 3); - Array(a, b); - - // or (can be declared later) - new Array(1, 2, 3); - var Array; - - // or (can be a function) - new Array(1, 2, 3); - function Array() { ... } - -// case 2. declared in a function - (function(){ - a = new Array(1, 2, 3); - b = Array(5, 6); - var Array; - })(); - - // or - (function(Array){ - return Array(5, 6, 7); - })(); - - // or - (function(){ - return new Array(1, 2, 3, 4); - function Array() { ... } - })(); - - // etc. -#+END_SRC - -*** =obj.toString()= ==> =obj+“”= - -** Install (NPM) - -UglifyJS is now available through NPM --- =npm install uglify-js= should do -the job. - -** Install latest code from GitHub - -#+BEGIN_SRC sh -## clone the repository -mkdir -p /where/you/wanna/put/it -cd /where/you/wanna/put/it -git clone git://github.com/mishoo/UglifyJS.git - -## make the module available to Node -mkdir -p ~/.node_libraries/ -cd ~/.node_libraries/ -ln -s /where/you/wanna/put/it/UglifyJS/uglify-js.js - -## and if you want the CLI script too: -mkdir -p ~/bin -cd ~/bin -ln -s /where/you/wanna/put/it/UglifyJS/bin/uglifyjs - # (then add ~/bin to your $PATH if it's not there already) -#+END_SRC - -** Usage - -There is a command-line tool that exposes the functionality of this library -for your shell-scripting needs: - -#+BEGIN_SRC sh -uglifyjs [ options... ] [ filename ] -#+END_SRC - -=filename= should be the last argument and should name the file from which -to read the JavaScript code. If you don't specify it, it will read code -from STDIN. - -Supported options: - -- =-b= or =--beautify= --- output indented code; when passed, additional - options control the beautifier: - - - =-i N= or =--indent N= --- indentation level (number of spaces) - - - =-q= or =--quote-keys= --- quote keys in literal objects (by default, - only keys that cannot be identifier names will be quotes). - -- =--ascii= --- pass this argument to encode non-ASCII characters as - =\uXXXX= sequences. By default UglifyJS won't bother to do it and will - output Unicode characters instead. (the output is always encoded in UTF8, - but if you pass this option you'll only get ASCII). - -- =-nm= or =--no-mangle= --- don't mangle names. - -- =-nmf= or =--no-mangle-functions= -- in case you want to mangle variable - names, but not touch function names. - -- =-ns= or =--no-squeeze= --- don't call =ast_squeeze()= (which does various - optimizations that result in smaller, less readable code). - -- =-mt= or =--mangle-toplevel= --- mangle names in the toplevel scope too - (by default we don't do this). - -- =--no-seqs= --- when =ast_squeeze()= is called (thus, unless you pass - =--no-squeeze=) it will reduce consecutive statements in blocks into a - sequence. For example, "a = 10; b = 20; foo();" will be written as - "a=10,b=20,foo();". In various occasions, this allows us to discard the - block brackets (since the block becomes a single statement). This is ON - by default because it seems safe and saves a few hundred bytes on some - libs that I tested it on, but pass =--no-seqs= to disable it. - -- =--no-dead-code= --- by default, UglifyJS will remove code that is - obviously unreachable (code that follows a =return=, =throw=, =break= or - =continue= statement and is not a function/variable declaration). Pass - this option to disable this optimization. - -- =-nc= or =--no-copyright= --- by default, =uglifyjs= will keep the initial - comment tokens in the generated code (assumed to be copyright information - etc.). If you pass this it will discard it. - -- =-o filename= or =--output filename= --- put the result in =filename=. If - this isn't given, the result goes to standard output (or see next one). - -- =--overwrite= --- if the code is read from a file (not from STDIN) and you - pass =--overwrite= then the output will be written in the same file. - -- =--ast= --- pass this if you want to get the Abstract Syntax Tree instead - of JavaScript as output. Useful for debugging or learning more about the - internals. - -- =-v= or =--verbose= --- output some notes on STDERR (for now just how long - each operation takes). - -- =-d SYMBOL[=VALUE]= or =--define SYMBOL[=VALUE]= --- will replace - all instances of the specified symbol where used as an identifier - (except where symbol has properly declared by a var declaration or - use as function parameter or similar) with the specified value. This - argument may be specified multiple times to define multiple - symbols - if no value is specified the symbol will be replaced with - the value =true=, or you can specify a numeric value (such as - =1024=), a quoted string value (such as ="object"= or - ='https://github.com'=), or the name of another symbol or keyword - (such as =null= or =document=). - This allows you, for example, to assign meaningful names to key - constant values but discard the symbolic names in the uglified - version for brevity/efficiency, or when used wth care, allows - UglifyJS to operate as a form of *conditional compilation* - whereby defining appropriate values may, by dint of the constant - folding and dead code removal features above, remove entire - superfluous code blocks (e.g. completely remove instrumentation or - trace code for production use). - Where string values are being defined, the handling of quotes are - likely to be subject to the specifics of your command shell - environment, so you may need to experiment with quoting styles - depending on your platform, or you may find the option - =--define-from-module= more suitable for use. - -- =-define-from-module SOMEMODULE= --- will load the named module (as - per the NodeJS =require()= function) and iterate all the exported - properties of the module defining them as symbol names to be defined - (as if by the =--define= option) per the name of each property - (i.e. without the module name prefix) and given the value of the - property. This is a much easier way to handle and document groups of - symbols to be defined rather than a large number of =--define= - options. - -- =--unsafe= --- enable other additional optimizations that are known to be - unsafe in some contrived situations, but could still be generally useful. - For now only these: - - - foo.toString() ==> foo+"" - - new Array(x,...) ==> [x,...] - - new Array(x) ==> Array(x) - -- =--max-line-len= (default 32K characters) --- add a newline after around - 32K characters. I've seen both FF and Chrome croak when all the code was - on a single line of around 670K. Pass --max-line-len 0 to disable this - safety feature. - -- =--reserved-names= --- some libraries rely on certain names to be used, as - pointed out in issue #92 and #81, so this option allow you to exclude such - names from the mangler. For example, to keep names =require= and =$super= - intact you'd specify --reserved-names "require,$super". - -- =--inline-script= -- when you want to include the output literally in an - HTML = - - - */ - -(function() { - this.loggly = function(opts) { - this.user_agent = get_agent(); - this.browser_size = get_size(); - log_methods = {'error': 5, 'warn': 4, 'info': 3, 'debug': 2, 'log': 1}; - if (!opts.url) throw new Error("Please include a Loggly HTTP URL."); - if (!opts.level) { - this.level = log_methods['info']; - } else { - this.level = log_methods[opts.level]; - } - this.log = function(data) { - if (log_methods['log'] == this.level) { - opts.data = data; - janky(opts); - } - }; - this.debug = function(data) { - if (log_methods['debug'] >= this.level) { - opts.data = data; - janky(opts); - } - }; - this.info = function(data) { - if (log_methods['info'] >= this.level) { - opts.data = data; - janky(opts); - } - }; - this.warn = function(data) { - if (log_methods['warn'] >= this.level) { - opts.data = data; - janky(opts); - } - }; - this.error = function(data) { - if (log_methods['error'] >= this.level) { - opts.data = data; - janky(opts); - } - }; - }; - this.janky = function(opts) { - janky._form(function(iframe, form) { - form.setAttribute("action", opts.url); - form.setAttribute("method", "post"); - janky._input(iframe, form, opts.data); - form.submit(); - setTimeout(function(){ - document.body.removeChild(iframe); - }, 2000); - }); - }; - this.janky._form = function(cb) { - var iframe = document.createElement("iframe"); - document.body.appendChild(iframe); - iframe.style.display = "none"; - setTimeout(function() { - var form = iframe.contentWindow.document.createElement("form"); - iframe.contentWindow.document.body.appendChild(form); - cb(iframe, form); - }, 0); - }; - this.janky._input = function(iframe, form, data) { - var inp = iframe.contentWindow.document.createElement("input"); - inp.setAttribute("type", "hidden"); - inp.setAttribute("name", "source"); - inp.value = "castor " + data; - form.appendChild(inp); - }; - this.get_agent = function () { - return navigator.appCodeName + navigator.appName + navigator.appVersion; - }; - this.get_size = function () { - var width = 0; var height = 0; - if( typeof( window.innerWidth ) == 'number' ) { - width = window.innerWidth; height = window.innerHeight; - } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) { - width = document.documentElement.clientWidth; height = document.documentElement.clientHeight; - } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) { - width = document.body.clientWidth; height = document.body.clientHeight; - } - return {'height': height, 'width': width}; - }; -})(); - - -jsworld={};jsworld.formatIsoDateTime=function(a,b){if(typeof a==="undefined")a=new Date;if(typeof b==="undefined")b=false;var c=jsworld.formatIsoDate(a)+" "+jsworld.formatIsoTime(a);if(b){var d=a.getHours()-a.getUTCHours();var e=Math.abs(d);var f=a.getUTCMinutes();var g=a.getMinutes();if(g!=f&&f<30&&d<0)e--;if(g!=f&&f>30&&d>0)e--;var h;if(g!=f)h=":30";else h=":00";var i;if(e<10)i="0"+e+h;else i=""+e+h;if(d<0)i="-"+i;else i="+"+i;c=c+i}return c};jsworld.formatIsoDate=function(a){if(typeof a==="undefined")a=new Date;var b=a.getFullYear();var c=a.getMonth()+1;var d=a.getDate();return b+"-"+jsworld._zeroPad(c,2)+"-"+jsworld._zeroPad(d,2)};jsworld.formatIsoTime=function(a){if(typeof a==="undefined")a=new Date;var b=a.getHours();var c=a.getMinutes();var d=a.getSeconds();return jsworld._zeroPad(b,2)+":"+jsworld._zeroPad(c,2)+":"+jsworld._zeroPad(d,2)};jsworld.parseIsoDateTime=function(a){if(typeof a!="string")throw"Error: The parameter must be a string";var b=a.match(/^(\d\d\d\d)-(\d\d)-(\d\d)[T ](\d\d):(\d\d):(\d\d)/);if(b===null)b=a.match(/^(\d\d\d\d)(\d\d)(\d\d)[T ](\d\d)(\d\d)(\d\d)/);if(b===null)b=a.match(/^(\d\d\d\d)-(\d\d)-(\d\d)[T ](\d\d)(\d\d)(\d\d)/);if(b===null)b=a.match(/^(\d\d\d\d)-(\d\d)-(\d\d)[T ](\d\d):(\d\d):(\d\d)/);if(b===null)throw"Error: Invalid ISO-8601 date/time string";var c=parseInt(b[1],10);var d=parseInt(b[2],10);var e=parseInt(b[3],10);var f=parseInt(b[4],10);var g=parseInt(b[5],10);var h=parseInt(b[6],10);if(d<1||d>12||e<1||e>31||f<0||f>23||g<0||g>59||h<0||h>59)throw"Error: Invalid ISO-8601 date/time value";var i=new Date(c,d-1,e,f,g,h);if(i.getDate()!=e||i.getMonth()+1!=d)throw"Error: Invalid date";return i};jsworld.parseIsoDate=function(a){if(typeof a!="string")throw"Error: The parameter must be a string";var b=a.match(/^(\d\d\d\d)-(\d\d)-(\d\d)/);if(b===null)b=a.match(/^(\d\d\d\d)(\d\d)(\d\d)/);if(b===null)throw"Error: Invalid ISO-8601 date string";var c=parseInt(b[1],10);var d=parseInt(b[2],10);var e=parseInt(b[3],10);if(d<1||d>12||e<1||e>31)throw"Error: Invalid ISO-8601 date value";var f=new Date(c,d-1,e);if(f.getDate()!=e||f.getMonth()+1!=d)throw"Error: Invalid date";return f};jsworld.parseIsoTime=function(a){if(typeof a!="string")throw"Error: The parameter must be a string";var b=a.match(/^(\d\d):(\d\d):(\d\d)/);if(b===null)b=a.match(/^(\d\d)(\d\d)(\d\d)/);if(b===null)throw"Error: Invalid ISO-8601 date/time string";var c=parseInt(b[1],10);var d=parseInt(b[2],10);var e=parseInt(b[3],10);if(c<0||c>23||d<0||d>59||e<0||e>59)throw"Error: Invalid ISO-8601 time value";return new Date(0,0,0,c,d,e)};jsworld._trim=function(a){var b=" \n\r\t\f \u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000";for(var c=0;c=0;c--){if(b.indexOf(a.charAt(c))===-1){a=a.substring(0,c+1);break}}return b.indexOf(a.charAt(0))===-1?a:""};jsworld._isNumber=function(a){if(typeof a=="number")return true;if(typeof a!="string")return false;var b=a+"";return/^-?(\d+|\d*\.\d+)$/.test(b)};jsworld._isInteger=function(a){if(typeof a!="number"&&typeof a!="string")return false;var b=a+"";return/^-?\d+$/.test(b)};jsworld._isFloat=function(a){if(typeof a!="number"&&typeof a!="string")return false;var b=a+"";return/^-?\.\d+?$/.test(b)};jsworld._hasOption=function(a,b){if(typeof a!="string"||typeof b!="string")return false;if(b.indexOf(a)!=-1)return true;else return false};jsworld._stringReplaceAll=function(a,b,c){var d;if(b.length==1&&c.length==1){d="";for(var e=0;e0){if(d.length>0)g=parseInt(d.shift(),10);if(isNaN(g))throw"Error: Invalid grouping";if(g==-1){e=a.substring(0,f)+e;break}f-=g;if(f<1){e=a.substring(0,f+g)+e;break}e=c+a.substring(f,f+g)+e}return e};jsworld._formatFractionPart=function(a,b){for(var c=0;a.length0)return a;else throw"Empty or no string"};if(a==null||typeof a!="object")throw"Error: Invalid/missing locale properties";if(typeof a.decimal_point!="string")throw"Error: Invalid/missing decimal_point property";this.decimal_point=a.decimal_point;if(typeof a.thousands_sep!="string")throw"Error: Invalid/missing thousands_sep property";this.thousands_sep=a.thousands_sep;if(typeof a.grouping!="string")throw"Error: Invalid/missing grouping property";this.grouping=a.grouping;if(typeof a.int_curr_symbol!="string")throw"Error: Invalid/missing int_curr_symbol property";if(!/[A-Za-z]{3}.?/.test(a.int_curr_symbol))throw"Error: Invalid int_curr_symbol property";this.int_curr_symbol=a.int_curr_symbol;if(typeof a.currency_symbol!="string")throw"Error: Invalid/missing currency_symbol property";this.currency_symbol=a.currency_symbol;if(typeof a.frac_digits!="number"&&a.frac_digits<0)throw"Error: Invalid/missing frac_digits property";this.frac_digits=a.frac_digits;if(a.mon_decimal_point===null||a.mon_decimal_point==""){if(this.frac_digits>0)throw"Error: Undefined mon_decimal_point property";else a.mon_decimal_point=""}if(typeof a.mon_decimal_point!="string")throw"Error: Invalid/missing mon_decimal_point property";this.mon_decimal_point=a.mon_decimal_point;if(typeof a.mon_thousands_sep!="string")throw"Error: Invalid/missing mon_thousands_sep property";this.mon_thousands_sep=a.mon_thousands_sep;if(typeof a.mon_grouping!="string")throw"Error: Invalid/missing mon_grouping property";this.mon_grouping=a.mon_grouping;if(typeof a.positive_sign!="string")throw"Error: Invalid/missing positive_sign property";this.positive_sign=a.positive_sign;if(typeof a.negative_sign!="string")throw"Error: Invalid/missing negative_sign property";this.negative_sign=a.negative_sign;if(a.p_cs_precedes!==0&&a.p_cs_precedes!==1)throw"Error: Invalid/missing p_cs_precedes property, must be 0 or 1";this.p_cs_precedes=a.p_cs_precedes;if(a.n_cs_precedes!==0&&a.n_cs_precedes!==1)throw"Error: Invalid/missing n_cs_precedes, must be 0 or 1";this.n_cs_precedes=a.n_cs_precedes;if(a.p_sep_by_space!==0&&a.p_sep_by_space!==1&&a.p_sep_by_space!==2)throw"Error: Invalid/missing p_sep_by_space property, must be 0, 1 or 2";this.p_sep_by_space=a.p_sep_by_space;if(a.n_sep_by_space!==0&&a.n_sep_by_space!==1&&a.n_sep_by_space!==2)throw"Error: Invalid/missing n_sep_by_space property, must be 0, 1, or 2";this.n_sep_by_space=a.n_sep_by_space;if(a.p_sign_posn!==0&&a.p_sign_posn!==1&&a.p_sign_posn!==2&&a.p_sign_posn!==3&&a.p_sign_posn!==4)throw"Error: Invalid/missing p_sign_posn property, must be 0, 1, 2, 3 or 4";this.p_sign_posn=a.p_sign_posn;if(a.n_sign_posn!==0&&a.n_sign_posn!==1&&a.n_sign_posn!==2&&a.n_sign_posn!==3&&a.n_sign_posn!==4)throw"Error: Invalid/missing n_sign_posn property, must be 0, 1, 2, 3 or 4";this.n_sign_posn=a.n_sign_posn;if(typeof a.int_frac_digits!="number"&&a.int_frac_digits<0)throw"Error: Invalid/missing int_frac_digits property";this.int_frac_digits=a.int_frac_digits;if(a.int_p_cs_precedes!==0&&a.int_p_cs_precedes!==1)throw"Error: Invalid/missing int_p_cs_precedes property, must be 0 or 1";this.int_p_cs_precedes=a.int_p_cs_precedes;if(a.int_n_cs_precedes!==0&&a.int_n_cs_precedes!==1)throw"Error: Invalid/missing int_n_cs_precedes property, must be 0 or 1";this.int_n_cs_precedes=a.int_n_cs_precedes;if(a.int_p_sep_by_space!==0&&a.int_p_sep_by_space!==1&&a.int_p_sep_by_space!==2)throw"Error: Invalid/missing int_p_sep_by_spacev, must be 0, 1 or 2";this.int_p_sep_by_space=a.int_p_sep_by_space;if(a.int_n_sep_by_space!==0&&a.int_n_sep_by_space!==1&&a.int_n_sep_by_space!==2)throw"Error: Invalid/missing int_n_sep_by_space property, must be 0, 1, or 2";this.int_n_sep_by_space=a.int_n_sep_by_space;if(a.int_p_sign_posn!==0&&a.int_p_sign_posn!==1&&a.int_p_sign_posn!==2&&a.int_p_sign_posn!==3&&a.int_p_sign_posn!==4)throw"Error: Invalid/missing int_p_sign_posn property, must be 0, 1, 2, 3 or 4";this.int_p_sign_posn=a.int_p_sign_posn;if(a.int_n_sign_posn!==0&&a.int_n_sign_posn!==1&&a.int_n_sign_posn!==2&&a.int_n_sign_posn!==3&&a.int_n_sign_posn!==4)throw"Error: Invalid/missing int_n_sign_posn property, must be 0, 1, 2, 3 or 4";this.int_n_sign_posn=a.int_n_sign_posn;if(a==null||typeof a!="object")throw"Error: Invalid/missing time locale properties";try{this.abday=this._parseList(a.abday,7)}catch(b){throw"Error: Invalid abday property: "+b}try{this.day=this._parseList(a.day,7)}catch(b){throw"Error: Invalid day property: "+b}try{this.abmon=this._parseList(a.abmon,12)}catch(b){throw"Error: Invalid abmon property: "+b}try{this.mon=this._parseList(a.mon,12)}catch(b){throw"Error: Invalid mon property: "+b}try{this.d_fmt=this._validateFormatString(a.d_fmt)}catch(b){throw"Error: Invalid d_fmt property: "+b}try{this.t_fmt=this._validateFormatString(a.t_fmt)}catch(b){throw"Error: Invalid t_fmt property: "+b}try{this.d_t_fmt=this._validateFormatString(a.d_t_fmt)}catch(b){throw"Error: Invalid d_t_fmt property: "+b}try{var c=this._parseList(a.am_pm,2);this.am=c[0];this.pm=c[1]}catch(b){this.am="";this.pm=""}this.getAbbreviatedWeekdayName=function(a){if(typeof a=="undefined"||a===null)return this.abday;if(!jsworld._isInteger(a)||a<0||a>6)throw"Error: Invalid weekday argument, must be an integer [0..6]";return this.abday[a]};this.getWeekdayName=function(a){if(typeof a=="undefined"||a===null)return this.day;if(!jsworld._isInteger(a)||a<0||a>6)throw"Error: Invalid weekday argument, must be an integer [0..6]";return this.day[a]};this.getAbbreviatedMonthName=function(a){if(typeof a=="undefined"||a===null)return this.abmon;if(!jsworld._isInteger(a)||a<0||a>11)throw"Error: Invalid month argument, must be an integer [0..11]";return this.abmon[a]};this.getMonthName=function(a){if(typeof a=="undefined"||a===null)return this.mon;if(!jsworld._isInteger(a)||a<0||a>11)throw"Error: Invalid month argument, must be an integer [0..11]";return this.mon[a]};this.getDecimalPoint=function(){return this.decimal_point};this.getCurrencySymbol=function(){return this.currency_symbol};this.getIntCurrencySymbol=function(){return this.int_curr_symbol.substring(0,3)};this.currencySymbolPrecedes=function(){if(this.p_cs_precedes==1)return true;else return false};this.intCurrencySymbolPrecedes=function(){if(this.int_p_cs_precedes==1)return true;else return false};this.getMonetaryDecimalPoint=function(){return this.mon_decimal_point};this.getFractionalDigits=function(){return this.frac_digits};this.getIntFractionalDigits=function(){return this.int_frac_digits}};jsworld.NumericFormatter=function(a){if(typeof a!="object"||a._className!="jsworld.Locale")throw"Constructor error: You must provide a valid jsworld.Locale instance";this.lc=a;this.format=function(a,b){if(typeof a=="string")a=jsworld._trim(a);if(!jsworld._isNumber(a))throw"Error: The input is not a number";var c=parseFloat(a,10);var d=jsworld._getPrecision(b);if(d!=-1)c=Math.round(c*Math.pow(10,d))/Math.pow(10,d);var e=jsworld._splitNumber(String(c));var f;if(c===0)f="0";else f=jsworld._hasOption("^",b)?e.integer:jsworld._formatIntegerPart(e.integer,this.lc.grouping,this.lc.thousands_sep);var g=d!=-1?jsworld._formatFractionPart(e.fraction,d):e.fraction;var h=g.length?f+this.lc.decimal_point+g:f;if(jsworld._hasOption("~",b)||c===0){return h}else{if(jsworld._hasOption("+",b)||c<0){if(c>0)return"+"+h;else if(c<0)return"-"+h;else return h}else{return h}}}};jsworld.DateTimeFormatter=function(a){if(typeof a!="object"||a._className!="jsworld.Locale")throw"Constructor error: You must provide a valid jsworld.Locale instance.";this.lc=a;this.formatDate=function(a){var b=null;if(typeof a=="string"){try{b=jsworld.parseIsoDate(a)}catch(c){b=jsworld.parseIsoDateTime(a)}}else if(a!==null&&typeof a=="object"){b=a}else{throw"Error: Invalid date argument, must be a Date object or an ISO-8601 date/time string"}return this._applyFormatting(b,this.lc.d_fmt)};this.formatTime=function(a){var b=null;if(typeof a=="string"){try{b=jsworld.parseIsoTime(a)}catch(c){b=jsworld.parseIsoDateTime(a)}}else if(a!==null&&typeof a=="object"){b=a}else{throw"Error: Invalid date argument, must be a Date object or an ISO-8601 date/time string"}return this._applyFormatting(b,this.lc.t_fmt)};this.formatDateTime=function(a){var b=null;if(typeof a=="string"){b=jsworld.parseIsoDateTime(a)}else if(a!==null&&typeof a=="object"){b=a}else{throw"Error: Invalid date argument, must be a Date object or an ISO-8601 date/time string"}return this._applyFormatting(b,this.lc.d_t_fmt)};this._applyFormatting=function(a,b){b=b.replace(/%%/g,"%");b=b.replace(/%a/g,this.lc.abday[a.getDay()]);b=b.replace(/%A/g,this.lc.day[a.getDay()]);b=b.replace(/%b/g,this.lc.abmon[a.getMonth()]);b=b.replace(/%B/g,this.lc.mon[a.getMonth()]);b=b.replace(/%d/g,jsworld._zeroPad(a.getDate(),2));b=b.replace(/%e/g,jsworld._spacePad(a.getDate(),2));b=b.replace(/%F/g,a.getFullYear()+"-"+jsworld._zeroPad(a.getMonth()+1,2)+"-"+jsworld._zeroPad(a.getDate(),2));b=b.replace(/%h/g,this.lc.abmon[a.getMonth()]);b=b.replace(/%H/g,jsworld._zeroPad(a.getHours(),2));b=b.replace(/%I/g,jsworld._zeroPad(this._hours12(a.getHours()),2));b=b.replace(/%k/g,a.getHours());b=b.replace(/%l/g,this._hours12(a.getHours()));b=b.replace(/%m/g,jsworld._zeroPad(a.getMonth()+1,2));b=b.replace(/%n/g,"\n");b=b.replace(/%M/g,jsworld._zeroPad(a.getMinutes(),2));b=b.replace(/%p/g,this._getAmPm(a.getHours()));b=b.replace(/%P/g,this._getAmPm(a.getHours()).toLocaleLowerCase());b=b.replace(/%R/g,jsworld._zeroPad(a.getHours(),2)+":"+jsworld._zeroPad(a.getMinutes(),2));b=b.replace(/%S/g,jsworld._zeroPad(a.getSeconds(),2));b=b.replace(/%T/g,jsworld._zeroPad(a.getHours(),2)+":"+jsworld._zeroPad(a.getMinutes(),2)+":"+jsworld._zeroPad(a.getSeconds(),2));b=b.replace(/%w/g,this.lc.day[a.getDay()]);b=b.replace(/%y/g,(new String(a.getFullYear())).substring(2));b=b.replace(/%Y/g,a.getFullYear());b=b.replace(/%Z/g,"");b=b.replace(/%[a-zA-Z]/g,"");return b};this._hours12=function(a){if(a===0)return 12;else if(a>12)return a-12;else return a};this._getAmPm=function(a){if(a===0||a>12)return this.lc.pm;else return this.lc.am}};jsworld.MonetaryFormatter=function(a,b,c){if(typeof a!="object"||a._className!="jsworld.Locale")throw"Constructor error: You must provide a valid jsworld.Locale instance";this.lc=a;this.currencyFractionDigits={AFN:0,ALL:0,AMD:0,BHD:3,BIF:0,BYR:0,CLF:0,CLP:0,COP:0,CRC:0,DJF:0,GNF:0,GYD:0,HUF:0,IDR:0,IQD:0,IRR:0,ISK:0,JOD:3,JPY:0,KMF:0,KRW:0,KWD:3,LAK:0,LBP:0,LYD:3,MGA:0,MMK:0,MNT:0,MRO:0,MUR:0,OMR:3,PKR:0,PYG:0,RSD:0,RWF:0,SLL:0,SOS:0,STD:0,SYP:0,TND:3,TWD:0,TZS:0,UGX:0,UZS:0,VND:0,VUV:0,XAF:0,XOF:0,XPF:0,YER:0,ZMK:0};if(typeof b=="string"){this.currencyCode=b.toUpperCase();var d=this.currencyFractionDigits[this.currencyCode];if(typeof d!="number")d=2;this.lc.frac_digits=d;this.lc.int_frac_digits=d}else{this.currencyCode=this.lc.int_curr_symbol.substring(0,3).toUpperCase()}this.intSep=this.lc.int_curr_symbol.charAt(3);if(this.currencyCode==this.lc.int_curr_symbol.substring(0,3)){this.internationalFormatting=false;this.curSym=this.lc.currency_symbol}else{if(typeof c=="string"){this.curSym=c;this.internationalFormatting=false}else{this.internationalFormatting=true}}this.getCurrencySymbol=function(){return this.curSym};this.currencySymbolPrecedes=function(a){if(typeof a=="string"&&a=="i"){if(this.lc.int_p_cs_precedes==1)return true;else return false}else{if(this.internationalFormatting){if(this.lc.int_p_cs_precedes==1)return true;else return false}else{if(this.lc.p_cs_precedes==1)return true;else return false}}};this.getDecimalPoint=function(){return this.lc.mon_decimal_point};this.getFractionalDigits=function(a){if(typeof a=="string"&&a=="i"){return this.lc.int_frac_digits}else{if(this.internationalFormatting)return this.lc.int_frac_digits;else return this.lc.frac_digits}};this.format=function(a,b){var c;if(typeof a=="string"){a=jsworld._trim(a);c=parseFloat(a);if(typeof c!="number"||isNaN(c))throw"Error: Amount string not a number"}else if(typeof a=="number"){c=a}else{throw"Error: Amount not a number"}var d=jsworld._getPrecision(b);if(d==-1){if(this.internationalFormatting||jsworld._hasOption("i",b))d=this.lc.int_frac_digits;else d=this.lc.frac_digits}c=Math.round(c*Math.pow(10,d))/Math.pow(10,d);var e=jsworld._splitNumber(String(c));var f;if(c===0)f="0";else f=jsworld._hasOption("^",b)?e.integer:jsworld._formatIntegerPart(e.integer,this.lc.mon_grouping,this.lc.mon_thousands_sep);var g;if(d==-1){if(this.internationalFormatting||jsworld._hasOption("i",b))g=jsworld._formatFractionPart(e.fraction,this.lc.int_frac_digits);else g=jsworld._formatFractionPart(e.fraction,this.lc.frac_digits)}else{g=jsworld._formatFractionPart(e.fraction,d)}var h;if(this.lc.frac_digits>0||g.length)h=f+this.lc.mon_decimal_point+g;else h=f;if(jsworld._hasOption("~",b)){return h}else{var i=jsworld._hasOption("!",b)?true:false;var j=c<0?"-":"+";if(this.internationalFormatting||jsworld._hasOption("i",b)){if(i)return this._formatAsInternationalCurrencyWithNoSym(j,h);else return this._formatAsInternationalCurrency(j,h)}else{if(i)return this._formatAsLocalCurrencyWithNoSym(j,h);else return this._formatAsLocalCurrency(j,h)}}};this._formatAsLocalCurrency=function(a,b){if(a=="+"){if(this.lc.p_sign_posn===0&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===0){return"("+b+this.curSym+")"}else if(this.lc.p_sign_posn===0&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===1){return"("+this.curSym+b+")"}else if(this.lc.p_sign_posn===0&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===0){return"("+b+" "+this.curSym+")"}else if(this.lc.p_sign_posn===0&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===1){return"("+this.curSym+" "+b+")"}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===0){return this.lc.positive_sign+b+this.curSym}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+this.curSym+b}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===0){return this.lc.positive_sign+b+" "+this.curSym}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+this.curSym+" "+b}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===0){return this.lc.positive_sign+" "+b+this.curSym}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+" "+this.curSym+b}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===0){return b+this.curSym+this.lc.positive_sign}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===1){return this.curSym+b+this.lc.positive_sign}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===0){return b+" "+this.curSym+this.lc.positive_sign}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===1){return this.curSym+" "+b+this.lc.positive_sign}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===0){return b+this.curSym+" "+this.lc.positive_sign}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===1){return this.curSym+b+" "+this.lc.positive_sign}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===0){return b+this.lc.positive_sign+this.curSym}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+this.curSym+b}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===0){return b+" "+this.lc.positive_sign+this.curSym}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+this.curSym+" "+b}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===0){return b+this.lc.positive_sign+" "+this.curSym}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+" "+this.curSym+b}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===0){return b+this.curSym+this.lc.positive_sign}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===1){return this.curSym+this.lc.positive_sign+b}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===0){return b+" "+this.curSym+this.lc.positive_sign}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===1){return this.curSym+this.lc.positive_sign+" "+b}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===0){return b+this.curSym+" "+this.lc.positive_sign}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===1){return this.curSym+" "+this.lc.positive_sign+b}}else if(a=="-"){if(this.lc.n_sign_posn===0&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===0){return"("+b+this.curSym+")"}else if(this.lc.n_sign_posn===0&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===1){return"("+this.curSym+b+")"}else if(this.lc.n_sign_posn===0&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===0){return"("+b+" "+this.curSym+")"}else if(this.lc.n_sign_posn===0&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===1){return"("+this.curSym+" "+b+")"}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===0){return this.lc.negative_sign+b+this.curSym}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+this.curSym+b}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===0){return this.lc.negative_sign+b+" "+this.curSym}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+this.curSym+" "+b}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===0){return this.lc.negative_sign+" "+b+this.curSym}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+" "+this.curSym+b}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===0){return b+this.curSym+this.lc.negative_sign}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===1){return this.curSym+b+this.lc.negative_sign}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===0){return b+" "+this.curSym+this.lc.negative_sign}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===1){return this.curSym+" "+b+this.lc.negative_sign}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===0){return b+this.curSym+" "+this.lc.negative_sign}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===1){return this.curSym+b+" "+this.lc.negative_sign}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===0){return b+this.lc.negative_sign+this.curSym}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+this.curSym+b}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===0){return b+" "+this.lc.negative_sign+this.curSym}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+this.curSym+" "+b}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===0){return b+this.lc.negative_sign+" "+this.curSym}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+" "+this.curSym+b}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===0){return b+this.curSym+this.lc.negative_sign}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===1){return this.curSym+this.lc.negative_sign+b}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===0){return b+" "+this.curSym+this.lc.negative_sign}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===1){return this.curSym+this.lc.negative_sign+" "+b}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===0){return b+this.curSym+" "+this.lc.negative_sign}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===1){return this.curSym+" "+this.lc.negative_sign+b}}throw"Error: Invalid POSIX LC MONETARY definition"};this._formatAsInternationalCurrency=function(a,b){if(a=="+"){if(this.lc.int_p_sign_posn===0&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===0){return"("+b+this.currencyCode+")"}else if(this.lc.int_p_sign_posn===0&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===1){return"("+this.currencyCode+b+")"}else if(this.lc.int_p_sign_posn===0&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===0){return"("+b+this.intSep+this.currencyCode+")"}else if(this.lc.int_p_sign_posn===0&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===1){return"("+this.currencyCode+this.intSep+b+")"}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===0){return this.lc.positive_sign+b+this.currencyCode}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.currencyCode+b}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===0){return this.lc.positive_sign+b+this.intSep+this.currencyCode}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.currencyCode+this.intSep+b}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===0){return this.lc.positive_sign+this.intSep+b+this.currencyCode}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.intSep+this.currencyCode+b}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===0){return b+this.currencyCode+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===1){return this.currencyCode+b+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===0){return b+this.intSep+this.currencyCode+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===1){return this.currencyCode+this.intSep+b+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===0){return b+this.currencyCode+this.intSep+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===1){return this.currencyCode+b+this.intSep+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===0){return b+this.lc.positive_sign+this.currencyCode}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.currencyCode+b}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===0){return b+this.intSep+this.lc.positive_sign+this.currencyCode}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.currencyCode+this.intSep+b}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===0){return b+this.lc.positive_sign+this.intSep+this.currencyCode}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.intSep+this.currencyCode+b}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===0){return b+this.currencyCode+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===1){return this.currencyCode+this.lc.positive_sign+b}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===0){return b+this.intSep+this.currencyCode+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===1){return this.currencyCode+this.lc.positive_sign+this.intSep+b}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===0){return b+this.currencyCode+this.intSep+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===1){return this.currencyCode+this.intSep+this.lc.positive_sign+b}}else if(a=="-"){if(this.lc.int_n_sign_posn===0&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===0){return"("+b+this.currencyCode+")"}else if(this.lc.int_n_sign_posn===0&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===1){return"("+this.currencyCode+b+")"}else if(this.lc.int_n_sign_posn===0&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===0){return"("+b+this.intSep+this.currencyCode+")"}else if(this.lc.int_n_sign_posn===0&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===1){return"("+this.currencyCode+this.intSep+b+")"}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===0){return this.lc.negative_sign+b+this.currencyCode}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.currencyCode+b}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===0){return this.lc.negative_sign+b+this.intSep+this.currencyCode}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.currencyCode+this.intSep+b}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===0){return this.lc.negative_sign+this.intSep+b+this.currencyCode}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.intSep+this.currencyCode+b}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===0){return b+this.currencyCode+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===1){return this.currencyCode+b+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===0){return b+this.intSep+this.currencyCode+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===1){return this.currencyCode+this.intSep+b+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===0){return b+this.currencyCode+this.intSep+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===1){return this.currencyCode+b+this.intSep+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===0){return b+this.lc.negative_sign+this.currencyCode}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.currencyCode+b}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===0){return b+this.intSep+this.lc.negative_sign+this.currencyCode}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.currencyCode+this.intSep+b}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===0){return b+this.lc.negative_sign+this.intSep+this.currencyCode}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.intSep+this.currencyCode+b}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===0){return b+this.currencyCode+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===1){return this.currencyCode+this.lc.negative_sign+b}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===0){return b+this.intSep+this.currencyCode+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===1){return this.currencyCode+this.lc.negative_sign+this.intSep+b}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===0){return b+this.currencyCode+this.intSep+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===1){return this.currencyCode+this.intSep+this.lc.negative_sign+b}}throw"Error: Invalid POSIX LC MONETARY definition"};this._formatAsLocalCurrencyWithNoSym=function(a,b){if(a=="+"){if(this.lc.p_sign_posn===0){return"("+b+")"}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===0){return this.lc.positive_sign+b}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+b}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===0){return this.lc.positive_sign+b}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+b}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===0){return this.lc.positive_sign+" "+b}else if(this.lc.p_sign_posn===1&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+" "+b}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===0){return b+this.lc.positive_sign}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===1){return b+this.lc.positive_sign}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===0){return b+" "+this.lc.positive_sign}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===1){return b+this.lc.positive_sign}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===0){return b+this.lc.positive_sign}else if(this.lc.p_sign_posn===2&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===1){return b+" "+this.lc.positive_sign}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===0){return b+this.lc.positive_sign}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+b}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===0){return b+" "+this.lc.positive_sign}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+" "+b}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===0){return b+this.lc.positive_sign}else if(this.lc.p_sign_posn===3&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+" "+b}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===0){return b+this.lc.positive_sign}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===0&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+b}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===0){return b+" "+this.lc.positive_sign}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===1&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+" "+b}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===0){return b+" "+this.lc.positive_sign}else if(this.lc.p_sign_posn===4&&this.lc.p_sep_by_space===2&&this.lc.p_cs_precedes===1){return this.lc.positive_sign+b}}else if(a=="-"){if(this.lc.n_sign_posn===0){return"("+b+")"}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===0){return this.lc.negative_sign+b}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+b}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===0){return this.lc.negative_sign+b}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+" "+b}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===0){return this.lc.negative_sign+" "+b}else if(this.lc.n_sign_posn===1&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+" "+b}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===0){return b+this.lc.negative_sign}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===1){return b+this.lc.negative_sign}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===0){return b+" "+this.lc.negative_sign}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===1){return b+this.lc.negative_sign}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===0){return b+" "+this.lc.negative_sign}else if(this.lc.n_sign_posn===2&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===1){return b+" "+this.lc.negative_sign}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===0){return b+this.lc.negative_sign}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+b}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===0){return b+" "+this.lc.negative_sign}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+" "+b}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===0){return b+this.lc.negative_sign}else if(this.lc.n_sign_posn===3&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+" "+b}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===0){return b+this.lc.negative_sign}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===0&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+b}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===0){return b+" "+this.lc.negative_sign}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===1&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+" "+b}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===0){return b+" "+this.lc.negative_sign}else if(this.lc.n_sign_posn===4&&this.lc.n_sep_by_space===2&&this.lc.n_cs_precedes===1){return this.lc.negative_sign+b}}throw"Error: Invalid POSIX LC MONETARY definition"};this._formatAsInternationalCurrencyWithNoSym=function(a,b){if(a=="+"){if(this.lc.int_p_sign_posn===0){return"("+b+")"}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===0){return this.lc.positive_sign+b}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+b}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===0){return this.lc.positive_sign+b}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.intSep+b}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===0){return this.lc.positive_sign+this.intSep+b}else if(this.lc.int_p_sign_posn===1&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.intSep+b}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===0){return b+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===1){return b+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===0){return b+this.intSep+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===1){return b+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===0){return b+this.intSep+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===2&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===1){return b+this.intSep+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===0){return b+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+b}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===0){return b+this.intSep+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.intSep+b}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===0){return b+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===3&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.intSep+b}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===0){return b+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===0&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+b}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===0){return b+this.intSep+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===1&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+this.intSep+b}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===0){return b+this.intSep+this.lc.positive_sign}else if(this.lc.int_p_sign_posn===4&&this.lc.int_p_sep_by_space===2&&this.lc.int_p_cs_precedes===1){return this.lc.positive_sign+b}}else if(a=="-"){if(this.lc.int_n_sign_posn===0){return"("+b+")"}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===0){return this.lc.negative_sign+b}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+b}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===0){return this.lc.negative_sign+b}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.intSep+b}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===0){return this.lc.negative_sign+this.intSep+b}else if(this.lc.int_n_sign_posn===1&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.intSep+b}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===0){return b+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===1){return b+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===0){return b+this.intSep+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===1){return b+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===0){return b+this.intSep+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===2&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===1){return b+this.intSep+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===0){return b+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+b}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===0){return b+this.intSep+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.intSep+b}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===0){return b+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===3&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.intSep+b}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===0){return b+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===0&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+b}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===0){return b+this.intSep+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===1&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+this.intSep+b}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===0){return b+this.intSep+this.lc.negative_sign}else if(this.lc.int_n_sign_posn===4&&this.lc.int_n_sep_by_space===2&&this.lc.int_n_cs_precedes===1){return this.lc.negative_sign+b}}throw"Error: Invalid POSIX LC_MONETARY definition"}};jsworld.NumericParser=function(a){if(typeof a!="object"||a._className!="jsworld.Locale")throw"Constructor error: You must provide a valid jsworld.Locale instance";this.lc=a;this.parse=function(a){if(typeof a!="string")throw"Parse error: Argument must be a string";var b=jsworld._trim(a);b=jsworld._stringReplaceAll(a,this.lc.thousands_sep,"");b=jsworld._stringReplaceAll(b,this.lc.decimal_point,".");if(jsworld._isNumber(b))return parseFloat(b,10);else throw"Parse error: Invalid number string"}};jsworld.DateTimeParser=function(a){if(typeof a!="object"||a._className!="jsworld.Locale")throw"Constructor error: You must provide a valid jsworld.Locale instance.";this.lc=a;this.parseTime=function(a){if(typeof a!="string")throw"Parse error: Argument must be a string";var b=this._extractTokens(this.lc.t_fmt,a);var c=false;if(b.hour!==null&&b.minute!==null&&b.second!==null){c=true}else if(b.hourAmPm!==null&&b.am!==null&&b.minute!==null&&b.second!==null){if(b.am){b.hour=parseInt(b.hourAmPm,10)}else{if(b.hourAmPm==12)b.hour=0;else b.hour=parseInt(b.hourAmPm,10)+12}c=true}if(c)return jsworld._zeroPad(b.hour,2)+":"+jsworld._zeroPad(b.minute,2)+":"+jsworld._zeroPad(b.second,2);else throw"Parse error: Invalid/ambiguous time string"};this.parseDate=function(a){if(typeof a!="string")throw"Parse error: Argument must be a string";var b=this._extractTokens(this.lc.d_fmt,a);var c=false;if(b.year!==null&&b.month!==null&&b.day!==null){c=true}if(c)return jsworld._zeroPad(b.year,4)+"-"+jsworld._zeroPad(b.month,2)+"-"+jsworld._zeroPad(b.day,2);else throw"Parse error: Invalid date string"};this.parseDateTime=function(a){if(typeof a!="string")throw"Parse error: Argument must be a string";var b=this._extractTokens(this.lc.d_t_fmt,a);var c=false;var d=false;if(b.hour!==null&&b.minute!==null&&b.second!==null){c=true}else if(b.hourAmPm!==null&&b.am!==null&&b.minute!==null&&b.second!==null){if(b.am){b.hour=parseInt(b.hourAmPm,10)}else{if(b.hourAmPm==12)b.hour=0;else b.hour=parseInt(b.hourAmPm,10)+12}c=true}if(b.year!==null&&b.month!==null&&b.day!==null){d=true}if(d&&c)return jsworld._zeroPad(b.year,4)+"-"+jsworld._zeroPad(b.month,2)+"-"+jsworld._zeroPad(b.day,2)+" "+jsworld._zeroPad(b.hour,2)+":"+jsworld._zeroPad(b.minute,2)+":"+jsworld._zeroPad(b.second,2);else throw"Parse error: Invalid/ambiguous date/time string"};this._extractTokens=function(a,b){var c={year:null,month:null,day:null,hour:null,hourAmPm:null,am:null,minute:null,second:null,weekday:null};while(a.length>0){if(a.charAt(0)=="%"&&a.charAt(1)!=""){var d=a.substring(0,2);if(d=="%%"){b=b.substring(1)}else if(d=="%a"){for(var e=0;e31)throw"Parse error: Unrecognised day of the month (%e)";b=b.substring(f.length)}else if(d=="%F"){if(/^\d\d\d\d/.test(b)){c.year=parseInt(b.substring(0,4),10);b=b.substring(4)}else{throw"Parse error: Unrecognised date (%F)"}if(jsworld._stringStartsWith(b,"-"))b=b.substring(1);else throw"Parse error: Unrecognised date (%F)";if(/^0[1-9]|1[0-2]/.test(b)){c.month=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised date (%F)";if(jsworld._stringStartsWith(b,"-"))b=b.substring(1);else throw"Parse error: Unrecognised date (%F)";if(/^0[1-9]|[1-2][0-9]|3[0-1]/.test(b)){c.day=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised date (%F)"}else if(d=="%H"){if(/^[0-1][0-9]|2[0-3]/.test(b)){c.hour=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised hour (%H)"}else if(d=="%I"){if(/^0[1-9]|1[0-2]/.test(b)){c.hourAmPm=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised hour (%I)"}else if(d=="%k"){var g=b.match(/^(\d{1,2})/);c.hour=parseInt(g,10);if(isNaN(c.hour)||c.hour<0||c.hour>23)throw"Parse error: Unrecognised hour (%k)";b=b.substring(g.length)}else if(d=="%l"){var g=b.match(/^(\d{1,2})/);c.hourAmPm=parseInt(g,10);if(isNaN(c.hourAmPm)||c.hourAmPm<1||c.hourAmPm>12)throw"Parse error: Unrecognised hour (%l)";b=b.substring(g.length)}else if(d=="%m"){if(/^0[1-9]|1[0-2]/.test(b)){c.month=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised month (%m)"}else if(d=="%M"){if(/^[0-5][0-9]/.test(b)){c.minute=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised minute (%M)"}else if(d=="%n"){if(b.charAt(0)=="\n")b=b.substring(1);else throw"Parse error: Unrecognised new line (%n)"}else if(d=="%p"){if(jsworld._stringStartsWith(b,this.lc.am)){c.am=true;b=b.substring(this.lc.am.length)}else if(jsworld._stringStartsWith(b,this.lc.pm)){c.am=false;b=b.substring(this.lc.pm.length)}else throw"Parse error: Unrecognised AM/PM value (%p)"}else if(d=="%P"){if(jsworld._stringStartsWith(b,this.lc.am.toLowerCase())){c.am=true;b=b.substring(this.lc.am.length)}else if(jsworld._stringStartsWith(b,this.lc.pm.toLowerCase())){c.am=false;b=b.substring(this.lc.pm.length)}else throw"Parse error: Unrecognised AM/PM value (%P)"}else if(d=="%R"){if(/^[0-1][0-9]|2[0-3]/.test(b)){c.hour=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised time (%R)";if(jsworld._stringStartsWith(b,":"))b=b.substring(1);else throw"Parse error: Unrecognised time (%R)";if(/^[0-5][0-9]/.test(b)){c.minute=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised time (%R)"}else if(d=="%S"){if(/^[0-5][0-9]/.test(b)){c.second=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised second (%S)"}else if(d=="%T"){if(/^[0-1][0-9]|2[0-3]/.test(b)){c.hour=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised time (%T)";if(jsworld._stringStartsWith(b,":"))b=b.substring(1);else throw"Parse error: Unrecognised time (%T)";if(/^[0-5][0-9]/.test(b)){c.minute=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised time (%T)";if(jsworld._stringStartsWith(b,":"))b=b.substring(1);else throw"Parse error: Unrecognised time (%T)";if(/^[0-5][0-9]/.test(b)){c.second=parseInt(b.substring(0,2),10);b=b.substring(2)}else throw"Parse error: Unrecognised time (%T)"}else if(d=="%w"){if(/^\d/.test(b)){c.weekday=parseInt(b.substring(0,1),10);b=b.substring(1)}else throw"Parse error: Unrecognised weekday number (%w)"}else if(d=="%y"){if(/^\d\d/.test(b)){var h=parseInt(b.substring(0,2),10);if(h>50)c.year=1900+h;else c.year=2e3+h;b=b.substring(2)}else throw"Parse error: Unrecognised year (%y)"}else if(d=="%Y"){if(/^\d\d\d\d/.test(b)){c.year=parseInt(b.substring(0,4),10);b=b.substring(4)}else throw"Parse error: Unrecognised year (%Y)"}else if(d=="%Z"){if(a.length===0)break}a=a.substring(2)}else{if(a.charAt(0)!=b.charAt(0))throw'Parse error: Unexpected symbol "'+b.charAt(0)+'" in date/time string';a=a.substring(1);b=b.substring(1)}}return c}};jsworld.MonetaryParser=function(a){if(typeof a!="object"||a._className!="jsworld.Locale")throw"Constructor error: You must provide a valid jsworld.Locale instance";this.lc=a;this.parse=function(a){if(typeof a!="string")throw"Parse error: Argument must be a string";var b=this._detectCurrencySymbolType(a);var c,d;if(b=="local"){c="local";d=a.replace(this.lc.getCurrencySymbol(),"")}else if(b=="int"){c="int";d=a.replace(this.lc.getIntCurrencySymbol(),"")}else if(b=="none"){c="local";d=a}else throw"Parse error: Internal assert failure";d=jsworld._stringReplaceAll(d,this.lc.mon_thousands_sep,"");d=d.replace(this.lc.mon_decimal_point,".");d=d.replace(/\s*/g,"");d=this._removeLocalNonNegativeSign(d,c);d=this._normaliseNegativeSign(d,c);if(jsworld._isNumber(d))return parseFloat(d,10);else throw"Parse error: Invalid currency amount string"};this._detectCurrencySymbolType=function(a){if(this.lc.getCurrencySymbol().length>this.lc.getIntCurrencySymbol().length){if(a.indexOf(this.lc.getCurrencySymbol())!=-1)return"local";else if(a.indexOf(this.lc.getIntCurrencySymbol())!=-1)return"int";else return"none"}else{if(a.indexOf(this.lc.getIntCurrencySymbol())!=-1)return"int";else if(a.indexOf(this.lc.getCurrencySymbol())!=-1)return"local";else return"none"}};this._removeLocalNonNegativeSign=function(a,b){a=a.replace(this.lc.positive_sign,"");if((b=="local"&&this.lc.p_sign_posn===0||b=="int"&&this.lc.int_p_sign_posn===0)&&/\(\d+\.?\d*\)/.test(a)){a=a.replace("(","");a=a.replace(")","")}return a};this._normaliseNegativeSign=function(a,b){a=a.replace(this.lc.negative_sign,"-");if(b=="local"&&this.lc.n_sign_posn===0||b=="int"&&this.lc.int_n_sign_posn===0){if(/^\(\d+\.?\d*\)$/.test(a)){a=a.replace("(","");a=a.replace(")","");return"-"+a}}if(b=="local"&&this.lc.n_sign_posn==2||b=="int"&&this.lc.int_n_sign_posn==2){if(/^\d+\.?\d*-$/.test(a)){a=a.replace("-","");return"-"+a}}if(b=="local"&&this.lc.n_cs_precedes===0&&this.lc.n_sign_posn==3||b=="local"&&this.lc.n_cs_precedes===0&&this.lc.n_sign_posn==4||b=="int"&&this.lc.int_n_cs_precedes===0&&this.lc.int_n_sign_posn==3||b=="int"&&this.lc.int_n_cs_precedes===0&&this.lc.int_n_sign_posn==4){if(/^\d+\.?\d*-$/.test(a)){a=a.replace("-","");return"-"+a}}return a}} - - -if(typeof POSIX_LC == "undefined") var POSIX_LC = {}; - -POSIX_LC.en_US = { - "decimal_point" : ".", - "thousands_sep" : ",", - "grouping" : "3", - "abday" : ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"], - "day" : ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"], - "abmon" : ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"], - "mon" : ["January","February","March","April","May","June","July","August","September","October","November","December"], - "d_fmt" : "%m/%e/%y", - "t_fmt" : "%I:%M:%S %p", - "d_t_fmt" : "%B %e, %Y %I:%M:%S %p %Z", - "am_pm" : ["AM","PM"], - "int_curr_symbol" : "USD ", - "currency_symbol" : "\u0024", - "mon_decimal_point" : ".", - "mon_thousands_sep" : ",", - "mon_grouping" : "3", - "positive_sign" : "", - "negative_sign" : "-", - "int_frac_digits" : 2, - "frac_digits" : 2, - "p_cs_precedes" : 1, - "n_cs_precedes" : 1, - "p_sep_by_space" : 0, - "n_sep_by_space" : 0, - "p_sign_posn" : 1, - "n_sign_posn" : 1, - "int_p_cs_precedes" : 1, - "int_n_cs_precedes" : 1, - "int_p_sep_by_space" : 0, - "int_n_sep_by_space" : 0, - "int_p_sign_posn" : 1, - "int_n_sign_posn" : 1 -} - -if(typeof POSIX_LC == "undefined") var POSIX_LC = {}; - -POSIX_LC.fr_FR = { - "decimal_point" : ",", - "thousands_sep" : "\u00a0", - "grouping" : "3", - "abday" : ["dim.","lun.","mar.", - "mer.","jeu.","ven.", - "sam."], - "day" : ["dimanche","lundi","mardi", - "mercredi","jeudi","vendredi", - "samedi"], - "abmon" : ["janv.","f\u00e9vr.","mars", - "avr.","mai","juin", - "juil.","ao\u00fbt","sept.", - "oct.","nov.","d\u00e9c."], - "mon" : ["janvier","f\u00e9vrier","mars", - "avril","mai","juin", - "juillet","ao\u00fbt","septembre", - "octobre","novembre","d\u00e9cembre"], - "d_fmt" : "%d/%m/%y", - "t_fmt" : "%H:%M:%S", - "d_t_fmt" : "%e %B %Y %H:%M:%S %Z", - "am_pm" : ["AM","PM"], - "int_curr_symbol" : "EUR ", - "currency_symbol" : "\u20ac", - "mon_decimal_point" : ",", - "mon_thousands_sep" : "\u00a0", - "mon_grouping" : "3", - "positive_sign" : "", - "negative_sign" : "-", - "int_frac_digits" : 2, - "frac_digits" : 2, - "p_cs_precedes" : 0, - "n_cs_precedes" : 0, - "p_sep_by_space" : 1, - "n_sep_by_space" : 1, - "p_sign_posn" : 1, - "n_sign_posn" : 1, - "int_p_cs_precedes" : 0, - "int_n_cs_precedes" : 0, - "int_p_sep_by_space" : 1, - "int_n_sep_by_space" : 1, - "int_p_sign_posn" : 1, - "int_n_sign_posn" : 1 -}; - -/** https://github.com/csnover/js-iso8601 */(function(n,f){var u=n.parse,c=[1,4,5,6,7,10,11];n.parse=function(t){var i,o,a=0;if(o=/^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/.exec(t)){for(var v=0,r;r=c[v];++v)o[r]=+o[r]||0;o[2]=(+o[2]||1)-1,o[3]=+o[3]||1,o[8]!=="Z"&&o[9]!==f&&(a=o[10]*60+o[11],o[9]==="+"&&(a=0-a)),i=n.UTC(o[1],o[2],o[3],o[4],o[5]+a,o[6],o[7])}else i=u?u(t):NaN;return i}})(Date) - -/*! - * geo-location-javascript v0.4.3 - * http://code.google.com/p/geo-location-javascript/ - * - * Copyright (c) 2009 Stan Wiechers - * Licensed under the MIT licenses. - * - * Revision: $Rev: 68 $: - * Author: $Author: whoisstan $: - * Date: $Date: 2010-02-15 13:42:19 +0100 (Mon, 15 Feb 2010) $: - */ -var geo_position_js=function() { - - var pub = {}; - var provider=null; - - pub.getCurrentPosition = function(successCallback,errorCallback,options) - { - provider.getCurrentPosition(successCallback, errorCallback,options); - } - - pub.init = function() - { - try - { - if (typeof(geo_position_js_simulator)!="undefined") - { - provider=geo_position_js_simulator; - } - else if (typeof(bondi)!="undefined" && typeof(bondi.geolocation)!="undefined") - { - provider=bondi.geolocation; - } - else if (typeof(navigator.geolocation)!="undefined") - { - provider=navigator.geolocation; - pub.getCurrentPosition = function(successCallback, errorCallback, options) - { - function _successCallback(p) - { - //for mozilla geode,it returns the coordinates slightly differently - if(typeof(p.latitude)!="undefined") - { - successCallback({timestamp:p.timestamp, coords: {latitude:p.latitude,longitude:p.longitude}}); - } - else - { - successCallback(p); - } - } - provider.getCurrentPosition(_successCallback,errorCallback,options); - } - } - else if(typeof(window.google)!="undefined" && typeof(google.gears)!="undefined") - { - provider=google.gears.factory.create('beta.geolocation'); - } - else if ( typeof(Mojo) !="undefined" && typeof(Mojo.Service.Request)!="Mojo.Service.Request") - { - provider=true; - pub.getCurrentPosition = function(successCallback, errorCallback, options) - { - - parameters={}; - if(options) - { - //http://developer.palm.com/index.php?option=com_content&view=article&id=1673#GPS-getCurrentPosition - if (options.enableHighAccuracy && options.enableHighAccuracy==true) - { - parameters.accuracy=1; - } - if (options.maximumAge) - { - parameters.maximumAge=options.maximumAge; - } - if (options.responseTime) - { - if(options.responseTime<5) - { - parameters.responseTime=1; - } - else if (options.responseTime<20) - { - parameters.responseTime=2; - } - else - { - parameters.timeout=3; - } - } - } - - - r=new Mojo.Service.Request('palm://com.palm.location', { - method:"getCurrentPosition", - parameters:parameters, - onSuccess: function(p){successCallback({timestamp:p.timestamp, coords: {latitude:p.latitude, longitude:p.longitude,heading:p.heading}});}, - onFailure: function(e){ - if (e.errorCode==1) - { - errorCallback({code:3,message:"Timeout"}); - } - else if (e.errorCode==2) - { - errorCallback({code:2,message:"Position Unavailable"}); - } - else - { - errorCallback({code:0,message:"Unknown Error: webOS-code"+errorCode}); - } - } - }); - } - - } - else if (typeof(device)!="undefined" && typeof(device.getServiceObject)!="undefined") - { - provider=device.getServiceObject("Service.Location", "ILocation"); - - //override default method implementation - pub.getCurrentPosition = function(successCallback, errorCallback, options) - { - function callback(transId, eventCode, result) { - if (eventCode == 4) - { - errorCallback({message:"Position unavailable", code:2}); - } - else - { - //no timestamp of location given? - successCallback({timestamp:null, coords: {latitude:result.ReturnValue.Latitude, longitude:result.ReturnValue.Longitude, altitude:result.ReturnValue.Altitude,heading:result.ReturnValue.Heading}}); - } - } - //location criteria - var criteria = new Object(); - criteria.LocationInformationClass = "BasicLocationInformation"; - //make the call - provider.ILocation.GetLocation(criteria,callback); - } - } - } - catch (e){ - alert("error="+e); - if(typeof(console)!="undefined") - { - console.log(e); - } - return false; - } - return provider!=null; - } - - - return pub; -}(); -// Couldn't get unminified version to work , go here for docs => https://github.com/iamnoah/writeCapture -(function(E,a){var j=a.document;function A(Q){var Z=j.createElement("div");j.body.insertBefore(Z,null);E.replaceWith(Z,'\n \n
\n
\n \n\n
\n
\n \n
\n

'); - __out.push(__sanitize(t('Invite Link'))); - __out.push(' '); - __out.push(__sanitize(USER.referral_url)); - __out.push('

\n\n \n\n
\n\n'); - }).call(this); - - }).call(__obj); - __obj.safe = __objSafe, __obj.escape = __escape; - return __out.join(''); -}}, "templates/clients/login": function(exports, require, module) {module.exports = function(__obj) { - if (!__obj) __obj = {}; - var __out = [], __capture = function(callback) { - var out = __out, result; - __out = []; - callback.call(this); - result = __out.join(''); - __out = out; - return __safe(result); - }, __sanitize = function(value) { - if (value && value.ecoSafe) { - return value; - } else if (typeof value !== 'undefined' && value != null) { - return __escape(value); - } else { - return ''; - } - }, __safe, __objSafe = __obj.safe, __escape = __obj.escape; - __safe = __obj.safe = function(value) { - if (value && value.ecoSafe) { - return value; - } else { - if (!(typeof value !== 'undefined' && value != null)) value = ''; - var result = new String(value); - result.ecoSafe = true; - return result; - } - }; - if (!__escape) { - __escape = __obj.escape = function(value) { - return ('' + value) - .replace(/&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"'); - }; - } - (function() { - (function() { - __out.push('
\n\t

'); - __out.push(__sanitize(t('Sign In'))); - __out.push('

\n\t
\n\t\t
\n\n\t\t\t
\n\t\t\t\t\n\t\t\t
\n\t\t\t
\n\t\t\t\t\n\t\t\t
\n\n\t\t\t
\n\n\t\t\t
\n\t\t\t\t\n\t\t\t
\n\t\t\t
\n\t\t\t\t\n\t\t\t
\n\n\t\t\t
\n\n
\n\n

'); - __out.push(__sanitize(t('Forgot Password?'))); - __out.push('

\n\n\t\t
\n\t
\n
\n\n
\n
\n'); - }).call(this); - - }).call(__obj); - __obj.safe = __objSafe, __obj.escape = __escape; - return __out.join(''); -}}, "templates/clients/modules/credit_card": function(exports, require, module) {module.exports = function(__obj) { - if (!__obj) __obj = {}; - var __out = [], __capture = function(callback) { - var out = __out, result; - __out = []; - callback.call(this); - result = __out.join(''); - __out = out; - return __safe(result); - }, __sanitize = function(value) { - if (value && value.ecoSafe) { - return value; - } else if (typeof value !== 'undefined' && value != null) { - return __escape(value); - } else { - return ''; - } - }, __safe, __objSafe = __obj.safe, __escape = __obj.escape; - __safe = __obj.safe = function(value) { - if (value && value.ecoSafe) { - return value; - } else { - if (!(typeof value !== 'undefined' && value != null)) value = ''; - var result = new String(value); - result.ecoSafe = true; - return result; - } - }; - if (!__escape) { - __escape = __obj.escape = function(value) { - return ('' + value) - .replace(/&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"'); - }; - } - (function() { - (function() { - var printCard; - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; - if (this.cards === "new") { - __out.push('\n
\n
\n
\n
\n
\n
\n \n \n
\n
\n
\n
\n \n \n
\n
\n \n \n
\n
\n
\n
\n \n \n
\n
\n
\n \n \n
\n
\n
\n \n \n
\n
\n
\n \n
\n
\n
\n'); - } else { - __out.push('\n '); - printCard = __bind(function(card, index) { - var exp, style; - __out.push('\n
\n '); - style = "background-position:-173px"; - __out.push('\n '); - if (card.get("card_type") === "Visa") { - style = "background-position:0px"; - } - __out.push('\n '); - if (card.get("card_type") === "MasterCard") { - style = "background-position:-42px"; - } - __out.push('\n '); - if (card.get("card_type") === "American Express") { - style = "background-position:-130px"; - } - __out.push('\n '); - if (card.get("card_type") === "Discover Card") { - style = "background-position:-85px"; - } - __out.push('\n
\n
\n ****'); - __out.push(__sanitize(card.get("card_number"))); - __out.push('\n \n '); - if (card.get("card_expiration")) { - __out.push('\n '); - __out.push(__sanitize(t('Expiry'))); - __out.push('\n '); - exp = card.get('card_expiration').split('-'); - __out.push('\n '); - __out.push(__sanitize("" + exp[0] + "-" + exp[1])); - __out.push('\n '); - } - __out.push('\n \n \n \n '); - if (card.get("default")) { - __out.push('\n ('); - __out.push(__sanitize(t('default card'))); - __out.push(')\n '); - } - __out.push('\n '); - if (this.cards.length > 1 && !card.get("default")) { - __out.push('\n '); - __out.push(__sanitize(t('make default'))); - __out.push('\n '); - } - __out.push('\n \n '); - __out.push(__sanitize(t('Edit'))); - __out.push('\n \n '); - if (this.cards.length > 1) { - __out.push('\n '); - __out.push(__sanitize(t('Delete'))); - __out.push('\n '); - } - __out.push('\n
\n '); - _.each(this.cards.models, printCard); - __out.push('\n
\n
\n\n'); - } - __out.push('\n'); - }).call(this); - - }).call(__obj); - __obj.safe = __objSafe, __obj.escape = __escape; - return __out.join(''); -}}, "templates/clients/modules/sub_header": function(exports, require, module) {module.exports = function(__obj) { - if (!__obj) __obj = {}; - var __out = [], __capture = function(callback) { - var out = __out, result; - __out = []; - callback.call(this); - result = __out.join(''); - __out = out; - return __safe(result); - }, __sanitize = function(value) { - if (value && value.ecoSafe) { - return value; - } else if (typeof value !== 'undefined' && value != null) { - return __escape(value); - } else { - return ''; - } - }, __safe, __objSafe = __obj.safe, __escape = __obj.escape; - __safe = __obj.safe = function(value) { - if (value && value.ecoSafe) { - return value; - } else { - if (!(typeof value !== 'undefined' && value != null)) value = ''; - var result = new String(value); - result.ecoSafe = true; - return result; - } - }; - if (!__escape) { - __escape = __obj.escape = function(value) { - return ('' + value) - .replace(/&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"'); - }; - } - (function() { - (function() { - __out.push('
\n
'); - __out.push(__sanitize(this.heading)); - __out.push('
\n
\n '); - if (window.USER.first_name) { - __out.push('\n '); - __out.push(__sanitize(t('Hello Greeting', { - name: USER.first_name - }))); - __out.push('\n '); - } - __out.push('\n
\n
\n
\n'); - }).call(this); - - }).call(__obj); - __obj.safe = __objSafe, __obj.escape = __escape; - return __out.join(''); -}}, "templates/clients/promotions": function(exports, require, module) {module.exports = function(__obj) { - if (!__obj) __obj = {}; - var __out = [], __capture = function(callback) { - var out = __out, result; - __out = []; - callback.call(this); - result = __out.join(''); - __out = out; - return __safe(result); - }, __sanitize = function(value) { - if (value && value.ecoSafe) { - return value; - } else if (typeof value !== 'undefined' && value != null) { - return __escape(value); - } else { - return ''; - } - }, __safe, __objSafe = __obj.safe, __escape = __obj.escape; - __safe = __obj.safe = function(value) { - if (value && value.ecoSafe) { - return value; - } else { - if (!(typeof value !== 'undefined' && value != null)) value = ''; - var result = new String(value); - result.ecoSafe = true; - return result; - } - }; - if (!__escape) { - __escape = __obj.escape = function(value) { - return ('' + value) - .replace(/&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"'); - }; - } - (function() { - (function() { - var promo, _i, _len, _ref; - __out.push(require('templates/clients/modules/sub_header').call(this, { - heading: t("Promotions") - })); - __out.push('\n\n
\n
\n
\n \n \n
\n
\n \n \n\n \n
\n '); - if (this.promos.length > 0) { - __out.push('\n
\n

'); - __out.push(__sanitize(t('Your Available Promotions'))); - __out.push('

\n \n \n\n \n \n \n \n \n \n \n \n '); - _ref = this.promos; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - promo = _ref[_i]; - __out.push('\n \n \n \n \n \n \n '); - } - __out.push('\n \n
'); - __out.push(__sanitize(t('Code'))); - __out.push(''); - __out.push(__sanitize(t('Details'))); - __out.push(''); - __out.push(__sanitize(t('Starts'))); - __out.push(''); - __out.push(__sanitize(t('Expires'))); - __out.push('
'); - __out.push(__sanitize(promo.code)); - __out.push(''); - __out.push(__sanitize(promo.description)); - __out.push(''); - __out.push(__sanitize(app.helpers.formatDate(promo.starts_at, true, "America/Los_Angeles"))); - __out.push(''); - __out.push(__sanitize(app.helpers.formatDate(promo.ends_at, true, "America/Los_Angeles"))); - __out.push('
\n
\n '); - } else { - __out.push('\n\n

'); - __out.push(__sanitize(t('No Active Promotions'))); - __out.push('

\n '); - } - __out.push('\n\n
\n
\n
\n'); - }).call(this); - - }).call(__obj); - __obj.safe = __objSafe, __obj.escape = __escape; - return __out.join(''); -}}, "templates/clients/request": function(exports, require, module) {module.exports = function(__obj) { - if (!__obj) __obj = {}; - var __out = [], __capture = function(callback) { - var out = __out, result; - __out = []; - callback.call(this); - result = __out.join(''); - __out = out; - return __safe(result); - }, __sanitize = function(value) { - if (value && value.ecoSafe) { - return value; - } else if (typeof value !== 'undefined' && value != null) { - return __escape(value); - } else { - return ''; - } - }, __safe, __objSafe = __obj.safe, __escape = __obj.escape; - __safe = __obj.safe = function(value) { - if (value && value.ecoSafe) { - return value; - } else { - if (!(typeof value !== 'undefined' && value != null)) value = ''; - var result = new String(value); - result.ecoSafe = true; - return result; - } - }; - if (!__escape) { - __escape = __obj.escape = function(value) { - return ('' + value) - .replace(/&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"'); - }; - } - (function() { - (function() { - var showFavoriteLocation; - showFavoriteLocation = function(location, index) { - var alphabet; - __out.push('\n '); - alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - __out.push('\n
\n '); - __out.push(__sanitize(location.nickname)); - return __out.push('\n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n

'); - __out.push(__sanitize(t('Driver Name:'))); - __out.push('

\n

\n
\n

'); - __out.push(__sanitize(t('Driver #:'))); - __out.push('

\n

\n
\n

'); - __out.push(__sanitize(t('Pickup Address:'))); - __out.push('

\n

\n
\n ');
-      __out.push(__sanitize(t('Add to Favorite Locations')));
-      __out.push('\n
\n
\n

\n '); - __out.push(__sanitize(t('Nickname:'))); - __out.push('\n \n \n \n \n
\n
\n
\n
\n

'); - __out.push(__sanitize(t('Your last trip'))); - __out.push('

\n
\n \n ');
-      __out.push(__sanitize(t('Star')));
-      __out.push('\n ');
-      __out.push(__sanitize(t('Star')));
-      __out.push('\n ');
-      __out.push(__sanitize(t('Star')));
-      __out.push('\n ');
-      __out.push(__sanitize(t('Star')));
-      __out.push('\n ');
-      __out.push(__sanitize(t('Star')));
-      __out.push('\n \n \n
\n \n
\n \n
\n \n
\n \n\n
\n'); - }).call(this); - - }).call(__obj); - __obj.safe = __objSafe, __obj.escape = __escape; - return __out.join(''); -}}, "templates/shared/menu": function(exports, require, module) {module.exports = function(__obj) { - if (!__obj) __obj = {}; - var __out = [], __capture = function(callback) { - var out = __out, result; - __out = []; - callback.call(this); - result = __out.join(''); - __out = out; - return __safe(result); - }, __sanitize = function(value) { - if (value && value.ecoSafe) { - return value; - } else if (typeof value !== 'undefined' && value != null) { - return __escape(value); - } else { - return ''; - } - }, __safe, __objSafe = __obj.safe, __escape = __obj.escape; - __safe = __obj.safe = function(value) { - if (value && value.ecoSafe) { - return value; - } else { - if (!(typeof value !== 'undefined' && value != null)) value = ''; - var result = new String(value); - result.ecoSafe = true; - return result; - } - }; - if (!__escape) { - __escape = __obj.escape = function(value) { - return ('' + value) - .replace(/&/g, '&') - .replace(//g, '>') - .replace(/"/g, '"'); - }; - } - (function() { - (function() { - __out.push('\n'); - }).call(this); - - }).call(__obj); - __obj.safe = __objSafe, __obj.escape = __escape; - return __out.join(''); -}}, "translations/en": function(exports, require, module) {(function() { - exports.translations = { - "Uber": "Uber", - "Sign Up": "Sign Up", - "Ride Request": "Ride Request", - "Invite Friends": "Invite Friends", - "Promotions": "Promotions", - "Billing": "Billing", - "Settings": "Settings", - "Forgot Password?": "Forgot Password?", - "Password Recovery": "Password Recovery", - "Login": "Login", - "Trip Detail": "Trip Detail", - "Password Reset": "Password Reset", - "Confirm Email": "Confirm Email", - "Request Ride": "Request Ride", - "Credit Card Number": "Credit Card Number", - "month": "month", - "01-Jan": "01-Jan", - "02-Feb": "02-Feb", - "03-Mar": "03-Mar", - "04-Apr": "04-Apr", - "05-May": "05-May", - "06-Jun": "06-Jun", - "07-Jul": "07-Jul", - "08-Aug": "08-Aug", - "09-Sep": "09-Sep", - "10-Oct": "10-Oct", - "11-Nov": "11-Nov", - "12-Dec": "12-Dec", - "year": "year", - "CVV": "CVV", - "Category": "Category", - "personal": "personal", - "business": "business", - "Default Credit Card": "Default Credit Card", - "Add Credit Card": "Add Credit Card", - "Expiry": "Expiry", - "default card": "default card", - "make default": "make default", - "Edit": "Edit", - "Delete": "Delete", - "Expiry Month": "Expiry Month", - "Expiry Year": "Expiry Year", - "Unable to Verify Card": "Unable to verify card at this time. Please try again later.", - "Credit Card Update Succeeded": "Your card has been successfully updated!", - "Credit Card Update Failed": "We couldn't save your changes. Please try again in a few minutes.", - "Credit Card Delete Succeeded": "Your card has been deleted!", - "Credit Card Delete Failed": "We were unable to delete your card. Please try again later.", - "Credit Card Update Category Succeeded": "Successfully changed card category!", - "Credit Card Update Category Failed": "We couldn't change your card category. Please try again in a few minutes.", - "Credit Card Update Default Succeeded": "Successfully changed default card!", - "Credit Card Update Default Failed": "We couldn't change your default card. Please try again in a few minutes.", - "Hello Greeting": "Hello, <%= name %>", - "Card Ending in": "Card Ending in", - "Trip Map": "Trip Map", - "Amount": "Amount: <%= amount %>", - "Last Attempt to Bill": "Last Attempt to Bill: <%= date %>", - "Charge": "Charge", - "Uber Credit Balance Note": "Your account has an UberCredit balance of <%= amount %>. When billing for trips, we'll deplete your UberCredit balance before applying charges to your credit card.", - "Please Add Credit Card": "Please add a credit card to bill your outstanding charges.", - "Credit Cards": "Credit Cards", - "add a new credit card": "add a new credit card", - "Account Balance": "Account Balance", - "Arrears": "Arrears", - "Billing Succeeded": "Your card was successfully billed.", - "Confirm Email Succeeded": "Successfully confirmed email token, redirecting to log in page...", - "Confirm Email Failed": "Unable to confirm email. Please contact support@uber.com if this problem persists.", - "Email Already Confirmed": "Your email address has already been confirmed, redirecting to log in page...", - "Credit Card Added": "Credit Card Added", - "No Credit Card": "No Credit Card", - "Mobile Number Confirmed": "Mobile Number Confirmed", - "No Confirmed Mobile": "No Confirmed Mobile", - "E-mail Address Confirmed": "E-mail Address Confirmed", - "No Confirmed E-mail": "No Confirmed E-mail", - 'Reply to sign up text': 'Reply "GO" to the text message you received at sign up.', - "Resend text message": "Resend text message", - "Click sign up link": "Click the link in the email you received at sign up.", - "Resend email": "Resend email", - "Add a credit card to ride": "Add a credit card and you'll be ready to ride Uber.", - "Your Most Recent Trip": "Your Most Recent Trip", - "details": "details", - "Your Trip History ": "Your Trip History ", - "Status": "Status", - "Here's how it works:": "Here's how it works:", - "Show all trips": "Show all trips", - "Set your location:": "Set your location:", - "App search for address": "iPhone/Android app: fix the pin or search for an address", - "SMS text address": "SMS: text your address to UBRCAB (827222)", - "Confirm pickup request": "Confirm your pickup request", - "Uber sends ETA": "Uber will send you an ETA (usually within 5-10 minutes)", - "Car arrives": "When your car is arriving, Uber will inform you again.", - "Ride to destination": "Hop in the car and tell the driver your destination.", - "Thank your driver": "That’s it! Please thank your driver but remember that your tip is included and no cash is necessary.", - "Trip started here": "Trip started here", - "Trip ended here": "Trip ended here", - "Sending Email": "Sending email...", - "Resend Email Succeeded": "We just sent the email. Please click on the confirmation link you recieve.", - "Resend Email Failed": "There was an error sending the email. Please contact support if the problem persists.", - "Resend Text Succeeded": 'We just sent the text message. Please reply "GO" to the message you recieve. It may take a few minutes for the message to reach you phone.', - "Resend Text Failed": "There was an error sending the text message. Please contact support if the problem persists.", - "Password Reset Error": "There was an error processing your password reset request.", - "New Password": "New Password", - "Forgot Password": "Forgot Password", - "Forgot Password Error": "Your email address could not be found. Please make sure to use the same email address you used when you signed up.", - "Forgot Password Success": "Please check your email for a link to reset your password.", - "Forgot Password Enter Email": 'Enter your email address and Uber will send you a link to reset your password. If you remember your password, you can sign in here.', - "Invite friends": "Invite friends", - "Give $ Get $": "Give $10, Get $10", - "Give $ Get $ Description": "Every friend you invite to Uber gets $10 of Uber credit. After someone you’ve invited takes his/her first ride, you get $10 of Uber credits too!", - "What are you waiting for?": "So, what are you waiting for? Invite away!", - "Tweet": "Tweet", - "Invite Link": "Email or IM this link to your friends:", - "Email Address": "Email Address", - "Reset Password": "Reset Password", - "Enter Promotion Code": "If you have a promotion code, enter it here:", - "Your Active Promotions": "Your Active Promotions", - "Code": "Code", - "Details": "Details", - "Trips Remaining": "Trips Remaining", - "Expires": "Expires", - "No Active Promotions": "There are no active promotions on your account.", - "Your Available Promotions": "Your Available Promotions", - "Where do you want us to pick you up?": "Where do you want us to pick you up?", - "Address to search": "Address to search", - "Search": "Search", - "Driver Name:": "Driver Name:", - "Driver #:": "Driver #:", - "Pickup Address:": "Pickup Address:", - "Add to Favorite Locations": "Add to Favorite Locations", - "Star": "Star", - "Nickname:": "Nickname:", - "Add": "Add", - "Your last trip": "Your last trip", - "Please rate your driver:": "Please rate your driver:", - "Comments: (optional)": "Comments: (optional)", - "Rate Trip": "Rate Trip", - "Pickup time:": "Pickup time:", - "Miles:": "Miles:", - "Trip time:": "Trip time:", - "Fare:": "Fare:", - "Favorite Locations": "Favorite Locations", - "Search Results": "Search Results", - "You have no favorite locations saved.": "You have no favorite locations saved.", - "Loading...": "Loading...", - "Request Pickup": "Request Pickup", - "Cancel Pickup": "Cancel Pickup", - "Requesting Closest Driver": "Requesting the closest driver to pick you up...", - "En Route": "You are currently en route...", - "Rate Last Trip": "Please rate your trip to make another request", - "Rate Before Submitting": "Please rate your trip before submitting the form", - "Address too short": "Address too short", - "or did you mean": "or did you mean", - "Search Address Failed": "Unable to find the given address. Please enter another address close to your location.", - "Sending pickup request...": "Sending pickup request...", - "Cancel Request Prompt": "Are you sure you want to cancel your request?", - "Cancel Request Arrived Prompt": 'Are you sure you want to cancel your request? Your driver has arrived so there is a $10 cancellation fee. It may help to call your driver now', - "Favorite Location Nickname Length Error": "Nickname has to be atleast 3 characters", - "Favorite Location Save Succeeded": "Location Saved!", - "Favorite Location Save Failed": "Unable to save your location. Please try again later.", - "Favorite Location Title": "Favorite Location <%= id %>", - "Search Location Title": "Search Location <%= id %>", - "ETA Message": "ETA: Around <%= minutes %> Minutes", - "Nearest Cab Message": "The closest driver is approximately <%= minutes %> minute(s) away", - "Arrival ETA Message": "Your Uber will arrive in about <%= minutes %> minute(s)", - "Arriving Now Message": "Your Uber is arriving now...", - "Rating Driver Failed": "Unable to contact server. Please try again later or email support if this issue persists.", - "Account Information": "Account Information", - "Mobile Phone Information": "Mobile Phone Information", - "settings": "settings", - "Information": "Information", - "Picture": "Picture", - "Change password": "Change password", - "Your current Picture": "Your current Picture", - "Your Favorite Locations": "Your Favorite Locations", - "You have no favorite locations saved.": "You have no favorite locations saved.", - "Purpose of Mobile": "We send text messages to your mobile phone to tell you when your driver is arriving. You can also request trips using text messages.", - "Country": "Country", - "Mobile Number": "Mobile Number", - "Submit": "Submit", - "Favorite Location": "Favorite Location", - "No Approximate Address": "Could not find an approximate address", - "Address:": "Address:", - "Information Update Succeeded": "Your information has been updated!", - "Information Update Failed": "We couldn't update your information. Please try again in few minutes or contact support if the problem persists.", - "Location Delete Succeeded": "Location deleted!", - "Location Delete Failed": "We were unable to delete your favorite location. Please try again later or contact support of the issue persists.", - "Location Edit Succeeded": "Changes Saved!", - "Location Edit Failed": "We couldn't save your changes. Please try again in a few minutes.", - "Picture Update Succeeded": "Your picture has been updated!", - "Picture Update Failed": "We couldn't change your picture. Please try again in a few minutes.", - "Personal Information": "Personal Information", - "Mobile Phone Number": "Mobile Phone Number", - "Payment Information": "Payment Information", - "Purpose of Credit Card": "We keep your credit card on file so that your trip go as fast as possible. You will not be charged until you take a trip.", - "Your card will not be charged until you take a trip.": "Your card will not be charged until you take a trip.", - "Credit Card Number": "Credit Card Number", - "Expiration Date": "Expiration Date", - "Promotion Code": "Promotion Code", - "Enter Promo Here": "If you have a code for a promotion, invitation or group deal, you can enter it here.", - "Promotion Code Input Label": "Promotion, Invite or Groupon Code (optional)", - "Terms and Conditions": "Terms and Conditions", - "HELP": "HELP", - "STOP": "STOP", - "Legal Information": "Legal Information", - "Sign Up Agreement": "By signing up, I agree to the Uber <%= terms_link %> and <%= privacy_link %> and understand that Uber is a request tool, not a transportation carrier.", - "Sign Up Agreement Error": "You must agree to the Uber Terms and Conditions and Privacy Policy to continue.", - "Message and Data Rates Disclosure": "Message and Data Rates May Apply. Reply <%= help_string %> to 827-222 for help. Reply <%= stop_string %> to 827-222 to stop texts. For additional assistance, visit support.uber.com or call (866) 576-1039. Supported Carriers: AT&T, Sprint, Verizon, and T-Mobile.", - "I Agree": "I agree to the Terms & Conditions and Privacy Policy", - "Security Code": "Security Code", - "Type of Card": "Type of Card", - "Personal": "Personal", - "Business": "Business", - "Code": "Code", - "Zip or Postal Code": "Zip or Postal Code", - "Your Trip": "Your Trip", - "Trip Info": "Trip Info", - "Request a fare review": "Request a fare review", - "Fare Review Submitted": "Your fare review has been submitted. We'll get back to you soon about your request. Sorry for any inconvenience this may have caused!", - "Fair Price Consideration": "We're committed to delivering Uber service at a fair price. Before requesting a fare review, please consider:", - "Your Fare Calculation": "Your Fare Calculation", - "Charges": "Charges", - "Discounts": "Discounts", - "Total Charge": "Total Charge", - "Uber pricing information": "Uber pricing information", - "Uber Pricing Information Message": "<%= learn_link %> is published on our website.", - "GPS Point Capture Disclosure": "Due to a finite number of GPS point captures, corners on your trip map may appear cut off or rounded. These minor inaccuracies result in a shorter measured distance, which always results in a cheaper trip.", - "Fare Review Note": "Please elaborate on why this trip requires a fare review. Your comments below will help us better establish the correct price for your trip:", - "Fare Review Error": "There was an error submitting the review. Please ensure that you have a message.", - "Sign In": "Sign In" - }; -}).call(this); -}, "translations/fr": function(exports, require, module) {(function() { - exports.translations = { - "Uber": "Uber", - "Sign Up": "Inscription", - "Ride Request": "Passer une Commande", - "Invite Friends": "Inviter vos Amis", - "Promotions": "Promotions", - "Billing": "Paiement", - "Settings": "Paramètres", - "Forgot Password?": "Mot de passe oublié ?", - "Password Recovery": "Récupération du mot de passe", - "Login": "Connexion", - "Trip Detail": "Détail de la Course", - "Password Reset": "Réinitialisation du mot de passe", - "Confirm Email": "Confirmation de l’e-mail", - "Request Ride": "Passer une Commande", - "Credit Card Number": "Numéro de Carte de Crédit", - "month": "mois", - "01-Jan": "01-Jan", - "02-Feb": "02-Fév", - "03-Mar": "03-Mar", - "04-Apr": "04-Avr", - "05-May": "05-Mai", - "06-Jun": "06-Juin", - "07-Jul": "07-Jui", - "08-Aug": "08-Aoû", - "09-Sep": "09-Sep", - "10-Oct": "10-Oct", - "11-Nov": "11-Nov", - "12-Dec": "12-Déc", - "year": "année", - "CVV": "Code de Sécurité", - "Category": "Type", - "personal": "personnel", - "business": "entreprise", - "Default Credit Card": "Carte par Défaut", - "Add Credit Card": "Ajouter une Carte", - "Expiry": "Expire", - "default card": "carte par défaut", - "make default": "choisir par défaut", - "Edit": "Modifier", - "Delete": "Supprimer", - "Expiry Month": "Mois d’Expiration", - "Expiry Year": "Année d’Expiration", - "Unable to Verify Card": "Impossible de vérifier la carte pour le moment. Merci de réessayer un peu plus tard.", - "Credit Card Update Succeeded": "Votre carte a été mise à jour avec succès !", - "Credit Card Update Failed": "Nous ne pouvons enregistrer vos changements. Merci de réessayer dans quelques minutes.", - "Credit Card Delete Succeeded": "Votre carte a été supprimée !", - "Credit Card Delete Failed": "Nous n’avons pas été en mesure de supprimer votre carte. Merci de réessayer plus tard.", - "Credit Card Update Category Succeeded": "Changement de catégorie de carte réussi !", - "Credit Card Update Category Failed": "Nous ne pouvons pas changer la catégorie de votre carte. Merci de réessayer dans quelques minutes.", - "Credit Card Update Default Succeeded": "Carte par défaut changée avec succès !", - "Credit Card Update Default Failed": "Nous ne pouvons pas changer votre carte par défaut. Merci de réessayer dans quelques minutes.", - "Hello Greeting": "Bonjour, <%= name %>", - "Card Ending in": "La carte expire dans", - "Trip Map": "Carte des Courses", - "Amount": "Montant: <%= amount %>", - "Last Attempt to Bill": "Dernière tentative de prélèvement : <%= date %>", - "Charge": "Débit", - "Uber Credit Balance Note": "Votre compte a un solde de <%= amount %> UberCredits. Lorsque nous facturons des courses, nous réduirons votre solde d’UberCredits avant de prélever votre carte de crédit.", - "Please Add Credit Card": "Merci d’ajouter une carte de crédit pour que nous puissions vous facturer.", - "Credit Cards": "Cartes de crédit", - "add a new credit card": "Ajouter une nouvelle carte de crédit", - "Account Balance": "Solde du compte", - "Arrears": "Arriérés", - "Billing Succeeded": "Votre carte a été correctement débitée.", - "Confirm Email Succeeded": "L’adresse e-mail a bien été validée, vous êtes redirigé vers le tableau de bord...", - "Confirm Email Failed": "Impossible de confirmer l’adresse e-mail. Merci de contacter support@uber.com si le problème persiste.", - "Credit Card Added": "Carte de crédit ajoutée", - "No Credit Card": "Pas de carte de crédit", - "Mobile Number Confirmed": "Numéro de téléphone confirmé", - "No Confirmed Mobile": "Pas de numéro de téléphone confirmé", - "E-mail Address Confirmed": "Adresse e-mail confirmée", - "No Confirmed E-mail": "Pas d’adresse e-mail confirmée", - 'Reply to sign up text': 'Répondre "GO" au SMS que vous avez reçu à l’inscription.', - "Resend text message": "Renvoyer le SMS", - "Click sign up link": "Cliquez sur le lien contenu dans l’e-mail reçu à l’inscription.", - "Resend email": "Renvoyer l’e-mail", - "Add a credit card to ride": "Ajouter une carte de crédit et vous serez prêt à voyager avec Uber.", - "Your Most Recent Trip": "Votre course la plus récente", - "details": "détails", - "Your Trip History": "Historique de votre trajet", - "Status": "Statut", - "Here's how it works:": "Voici comment ça marche :", - "Show all trips": "Montrer toutes les courses", - "Set your location:": "Définir votre position :", - "App search for address": "Application iPhone/Android : positionner la punaise ou rechercher une adresse", - "SMS text address": "SMS : envoyez votre adresse à UBRCAB (827222)", - "Confirm pickup request": "Validez la commande", - "Uber sends ETA": "Uber envoie un temps d’attente estimé (habituellement entre 5 et 10 minutes)", - "Car arrives": "Lorsque votre voiture arrive, Uber vous en informera encore..", - "Ride to destination": "Montez dans la voiture et donnez votre destination au chauffeur.", - "Thank your driver": "C’est tout ! Remerciez le chauffeur mais souvenez-vous que les pourboires sont compris et qu’il n’est pas nécessaire d’avoir du liquide sur soi.", - "Trip started here": "La course a commencé ici.", - "Trip ended here": "La course s’est terminée ici.", - "Sending Email": "Envoi de l’e-mail...", - "Resend Email Succeeded": "Nous venons d’envoyer l’e-mail. Merci de cliquer sur le lien de confirmation que vous avez reçu.", - "Resend Email Failed": "Il y a eu un problème lors de l’envoi de l’email. Merci de contacter le support si le problème persiste.", - "Resend Text Succeeded": 'Nous venons d’envoyer le SMS. Merci de répondre "GO" au message que vous avez reçu. Il se peut que cela prenne quelques minutes pour que le message arrive sur votre téléphone.', - "Resend Text Failed": "Il y a eu un problème lors de l’envoi du SMS. Merci de contacter le support si le problème persiste.", - "Password Reset Error": "Il y a eu une error lors de la réinitialisation de votre mot de passe.", - "New Password:": "Nouveau mot de passe:", - "Forgot Password Error": "Votre nom d’utilisateur / adresse email ne peut être trouvé. Merci d’utiliser la même qu’à l’inscription.", - "Forgot Password Success": "Merci de consulter votre boîte mail pour suivre la demande de ‘réinitialisation de mot de passe.", - "Forgot Password Enter Email": "Merci de saisir votre adresse email et nous vous enverrons un lien vous permettant de réinitialiser votre mot de passe :", - "Invite friends": "Inviter vos amis", - "Give $ Get $": "Donnez $10, Recevez $10", - "Give $ Get $ Description": "Chaque ami que vous invitez à Uber recevra $10 de crédits Uber. Dès lors qu’une personne que vous aurez invité aura utilisé Uber pour la première, vous recevrez $10 de crédits Uber également !", - "What are you waiting for?": "N’attendez plus ! Lancez les invitations !", - "Tweet": "Tweeter", - "Invite Link": "Envoyez ce lien par email ou messagerie instantanée à vos amis :", - "Enter Promotion Code": "Si vous avez un code promo, saisissez-le ici:", - "Your Active Promotions": "Vos Codes Promos Actifs", - "Code": "Code", - "Details": "Détails", - "Trips Remaining": "Courses restantes", - "Expires": "Expire", - "No Active Promotions": "Vous n’avez pas de code promo actif.", - "Your Available Promotions": "Votres Promos Disponibles", - "Where do you want us to pick you up?": "Où souhaitez-vous que nous vous prenions en charge ?", - "Address to search": "Adresse à rechercher", - "Search": "Chercher", - "Driver Name:": "Nom du chauffeur:", - "Driver #:": "# Chauffeur:", - "Pickup Address:": "Lieu de prise en charge:", - "Add to Favorite Locations": "Ajoutez aux Lieux Favoris", - "Star": "Étoiles", - "Nickname:": "Pseudo", - "Add": "Ajouter", - "Your last trip": "Votre dernière course", - "Please rate your driver:": "Merci de noter votre chauffeur :", - "Comments: (optional)": "Commentaires: (optionnel)", - "Rate Trip": "Notez votre course", - "Pickup time:": "Heure de Prise en Charge :", - "Miles:": "Kilomètres :", - "Trip time:": "Temps de course :", - "Fare:": "Tarif :", - "Favorite Locations": "Lieux Favoris", - "Search Results": "Résultats", - "You have no favorite locations saved.": "Vous n’avez pas de lieux de prise en charge favoris.", - "Loading...": "Chargement...", - "Request Pickup": "Commander ici", - "Cancel Pickup": "Annuler", - "Requesting Closest Driver": "Nous demandons au chauffeur le plus proche de vous prendre en charge...", - "En Route": "Vous êtes actuellement en route...", - "Rate Last Trip": "Merci de noter votre précédent trajet pour faire une autre course.", - "Rate Before Submitting": "Merci de noter votre trajet avant de le valider.", - "Address too short": "L’adresse est trop courte", - "or did you mean": "ou vouliez-vous dire", - "Search Address Failed": "Impossible de trouver l’adresse spécifiée. Merci de saisir une autre adresse proche de l’endroit où vous vous trouvez.", - "Sending pickup request...": "Envoi de la demande de prise en charge...", - "Cancel Request Prompt": "Voulez-vous vraiment annuler votre demande ?", - "Cancel Request Arrived Prompt": 'Voulez-vous vraiment annuler votre demande ? Votre chauffeur est arrivé, vous serez donc facturé de $10 de frais d’annulation. Il pourrait être utile que vous appeliez votre chauffeur maintenant.', - "Favorite Location Nickname Length Error": "Le pseudo doit faire au moins 3 caractères de long", - "Favorite Location Save Succeeded": "Adresse enregistrée !", - "Favorite Location Save Failed": "Impossible d’enregistrer votre adresse. Merci de réessayer ultérieurement.", - "Favorite Location Title": "Adresse favorie <%= id %>", - "Search Location Title": "Recherche d’adresse <%= id %>", - "ETA Message": "Temps d’attente estimé: environ <%= minutes %> minutes", - "Nearest Cab Message": "Le chauffeur le plus proche sera là dans <%= minutes %> minute(s)", - "Arrival ETA Message": "Votre chauffeur arrivera dans <%= minutes %> minute(s)", - "Arriving Now Message": "Votre chauffeur est en approche...", - "Rating Driver Failed": "Impossible de contacter le serveur. Merci de réessayer ultérieurement ou de contacter le support si le problème persiste.", - "settings": "Paramètres", - "Information": "Information", - "Picture": "Photo", - "Change password": "Modifier votre mot de passe", - "Your current Picture": "Votre photo", - "Your Favorite Locations": "Vos lieux favoris", - "You have no favorite locations saved.": "Vous n’avez pas de lieu favori", - "Account Information": "Informations Personnelles", - "Mobile Phone Information": "Informations de Mobile", - "Change Your Password": "Changez votre mot de passe.", - "Country": "Pays", - "Language": "Langue", - "Favorite Location": "Lieu favori", - "No Approximate Address": "Impossible de trouver une adresse même approximative", - "Address:": "Adresse :", - "Information Update Succeeded": "Vos informations ont été mises à jour !", - "Information Update Failed": "Nous n’avons pas pu mettre à jour vos informations. Merci de réessayer dans quelques instants ou de contacter le support si le problème persiste.", - "Location Delete Succeeded": "Adresse supprimée !", - "Location Delete Failed": "Nous n’avons pas pu supprimée votre adresse favorie. Merci de réessayer plus tard ou de contacter le support si le problème persiste.", - "Location Edit Succeeded": "Modifications sauvegardées !", - "Location Edit Failed": "Nous n’avons pas pu sauvegarder vos modifications. Merci de réessayer dans quelques minutes.", - "Picture Update Succeeded": "Votre photo a été mise à jour !", - "Picture Update Failed": "Nous n’avons pas pu mettre à jour votre photo. Merci de réessayer dans quelques instants.", - "Personal Information": "Informations Personnelles", - "Mobile Phone Number": "Numéro de Téléphone Portable", - "Payment Information": "Informations de Facturation", - "Your card will not be charged until you take a trip.": "Votre carte ne sera pas débitée avant votre premier trajet.", - "Card Number": "Numéro de Carte", - "Promotion Code Input Label": "Code promo, code d’invitation ou “deal” acheté en ligne (optionnel)", - "Terms and Conditions": "Conditions Générales", - "HELP": "HELP", - "STOP": "STOP", - "Sign Up Agreement": "En souscrivant, j’accepte les <%= terms_link %> et <%= privacy_link %> et comprends qu’Uber est un outil de commande de chauffeur, et non un transporteur.", - "Sign Up Agreement Error": "Vous devez accepter les Conditions Générales d’utilisation d’Uber Terms and Conditions et la Politique de Confidentialité pour continuer.", - "Message and Data Rates Disclosure": "Les frais d’envoi de SMS et de consommation de données peuvent s’appliquer. Répondez <%= help_string %> au 827-222 pour obtenir de l’aide. Répondez <%= stop_string %> au 827-222 pour ne plus recevoir de SMS. Pour plus d’aide, visitez support.uber.com ou appelez le (866) 576-1039. Opérateurs supportés: AT&T, Sprint, Verizon, T-Mobile, Orange, SFR et Bouygues Telecom.", - "Zip/Postal Code": "Code Postal", - "Expiration Date": "Date D'expiration", - "Security Code": "Code de Sécurité", - "Type of Card": "Type", - "Personal": "Personnel", - "Business": "Entreprise", - "Promotion Code": "Code Promo", - "Legal Information": "Mentions Légales", - "I Agree": "J'accepte.", - "Your Trip": "Votre Course", - "Trip Info": "Informations de la Course", - "Request a fare review": "Demander un contrôle du tarif", - "Fare Review Submitted": "Votre demande de contrôle du tarif a été soumis. Nous reviendrons vers vous rapidement concernant cette demande. Nous nous excusons pour les dérangements éventuellement occasionnés !", - "Fair Price Consideration": "Nous nous engageons à proposer Uber à un tarif juste. Avant de demander un contrôle du tarif, merci de prendre en compte :", - "Your Fare Calculation": "Calcul du Prix", - "Charges": "Coûts", - "Discounts": "Réductions", - "Total Charge": "Coût total", - "Uber pricing information": "Information sur les prix d’Uber", - "Uber Pricing Information Message": "<%= learn_link %> est disponible sur notre site web.", - "GPS Point Capture Disclosure": "A cause d’un nombre limité de coordonnées GPS sauvegardées, les angles de votre trajet sur la carte peuvent apparaître coupés ou arrondis. Ces légères incohérences débouchent sur des distances mesurées plus courtes, ce qui implique toujours un prix du trajet moins élevé.", - "Fare Review Note": "Merci de nous expliquer pourquoi le tarif de cette course nécessite d’être contrôlé. Vos commentaires ci-dessous nous aideront à établir un prix plus juste si nécessaire :", - "Fare Review Error": "Il y a eu une erreur lors de l’envoi de la demande. Assurez-vous d’avoir bien ajouté une description à votre demande." - }; -}).call(this); -}, "views/clients/billing": function(exports, require, module) {(function() { - var clientsBillingTemplate; - var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { - for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } - function ctor() { this.constructor = child; } - ctor.prototype = parent.prototype; - child.prototype = new ctor; - child.__super__ = parent.prototype; - return child; - }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; - clientsBillingTemplate = require('templates/clients/billing'); - exports.ClientsBillingView = (function() { - __extends(ClientsBillingView, UberView); - function ClientsBillingView() { - ClientsBillingView.__super__.constructor.apply(this, arguments); - } - ClientsBillingView.prototype.id = 'billing_view'; - ClientsBillingView.prototype.className = 'view_container'; - ClientsBillingView.prototype.events = { - 'click a#add_card': 'addCard', - 'click .charge_arrear': 'chargeArrear' - }; - ClientsBillingView.prototype.render = function() { - this.RefreshUserInfo(__bind(function() { - var cards, newForm; - this.HideSpinner(); - $(this.el).html(clientsBillingTemplate()); - if (USER.payment_gateway.payment_profiles.length === 0) { - newForm = new app.views.clients.modules.creditcard; - $(this.el).find("#add_card_wrapper").html(newForm.render(0).el); - } else { - cards = new app.views.clients.modules.creditcard; - $("#cards").html(cards.render("all").el); - } - return this.delegateEvents(); - }, this)); - return this; - }; - ClientsBillingView.prototype.addCard = function(e) { - var newCard; - e.preventDefault(); - newCard = new app.views.clients.modules.creditcard; - $('#cards').append(newCard.render("new").el); - return $("a#add_card").hide(); - }; - ClientsBillingView.prototype.chargeArrear = function(e) { - var $el, arrearId, attrs, cardId, options, tryCharge; - e.preventDefault(); - $(".error_message").text(""); - $el = $(e.currentTarget); - arrearId = $el.attr('id'); - cardId = $el.parent().find('#card_to_charge').val(); - this.ShowSpinner('submit'); - tryCharge = new app.models.clientbills({ - id: arrearId - }); - attrs = { - payment_profile_id: cardId, - dataType: 'json' - }; - options = { - success: __bind(function(data, textStatus, jqXHR) { - $el.parent().find(".success_message").text(t("Billing Succeeded")); - $el.hide(); - return $el.parent().find('#card_to_charge').hide(); - }, this), - error: __bind(function(jqXHR, status, errorThrown) { - return $el.parent().find(".error_message").text(JSON.parse(status.responseText).error); - }, this), - complete: __bind(function() { - return this.HideSpinner(); - }, this) - }; - return tryCharge.save(attrs, options); - }; - return ClientsBillingView; - })(); -}).call(this); -}, "views/clients/confirm_email": function(exports, require, module) {(function() { - var clientsConfirmEmailTemplate; - var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { - for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } - function ctor() { this.constructor = child; } - ctor.prototype = parent.prototype; - child.prototype = new ctor; - child.__super__ = parent.prototype; - return child; - }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; - clientsConfirmEmailTemplate = require('templates/clients/confirm_email'); - exports.ClientsConfirmEmailView = (function() { - __extends(ClientsConfirmEmailView, UberView); - function ClientsConfirmEmailView() { - ClientsConfirmEmailView.__super__.constructor.apply(this, arguments); - } - ClientsConfirmEmailView.prototype.id = 'confirm_email_view'; - ClientsConfirmEmailView.prototype.className = 'view_container'; - ClientsConfirmEmailView.prototype.render = function(token) { - var attrs; - $(this.el).html(clientsConfirmEmailTemplate()); - attrs = { - data: { - email_token: token - }, - success: __bind(function(data, textStatus, jqXHR) { - var show_dashboard; - this.HideSpinner(); - show_dashboard = function() { - return app.routers.clients.navigate('!/dashboard', true); - }; - if (data.status === 'OK') { - $('.success_message').show(); - return _.delay(show_dashboard, 3000); - } else if (data.status === 'ALREADY_COMFIRMED') { - $('.already_confirmed_message').show(); - return _.delay(show_dashboard, 3000); - } else { - return $('.error_message').show(); - } - }, this), - error: __bind(function(e) { - this.HideSpinner(); - return $('.error_message').show(); - }, this), - complete: function(status) { - return $('#attempt_text').hide(); - }, - dataType: 'json', - type: 'PUT', - url: "" + API + "/users/self" - }; - $.ajax(attrs); - this.ShowSpinner('submit'); - return this; - }; - return ClientsConfirmEmailView; - })(); -}).call(this); -}, "views/clients/dashboard": function(exports, require, module) {(function() { - var clientsDashboardTemplate; - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { - for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } - function ctor() { this.constructor = child; } - ctor.prototype = parent.prototype; - child.prototype = new ctor; - child.__super__ = parent.prototype; - return child; - }; - clientsDashboardTemplate = require('templates/clients/dashboard'); - exports.ClientsDashboardView = (function() { - var displayFirstTrip; - __extends(ClientsDashboardView, UberView); - function ClientsDashboardView() { - this.showAllTrips = __bind(this.showAllTrips, this); - this.render = __bind(this.render, this); - ClientsDashboardView.__super__.constructor.apply(this, arguments); - } - ClientsDashboardView.prototype.id = 'dashboard_view'; - ClientsDashboardView.prototype.className = 'view_container'; - ClientsDashboardView.prototype.events = { - 'click a.confirmation': 'confirmationClick', - 'click #resend_email': 'resendEmail', - 'click #resend_mobile': 'resendMobile', - 'click #show_all_trips': 'showAllTrips' - }; - ClientsDashboardView.prototype.render = function() { - var displayPage, downloadTrips; - this.HideSpinner(); - displayPage = __bind(function() { - $(this.el).html(clientsDashboardTemplate()); - this.confirmationsSetup(); - return this.RequireMaps(__bind(function() { - if (USER.trips.models[0]) { - if (!USER.trips.models[0].get("points")) { - return USER.trips.models[0].fetch({ - data: { - relationships: 'points' - }, - success: __bind(function() { - this.CacheData("USERtrips", USER.trips); - return displayFirstTrip(); - }, this) - }); - } else { - return displayFirstTrip(); - } - } - }, this)); - }, this); - downloadTrips = __bind(function() { - return this.DownloadUserTrips(displayPage, false, 10); - }, this); - this.RefreshUserInfo(downloadTrips); - return this; - }; - displayFirstTrip = __bind(function() { - var bounds, endPos, map, myOptions, path, polyline, startPos; - myOptions = { - zoom: 12, - mapTypeId: google.maps.MapTypeId.ROADMAP, - zoomControl: false, - rotateControl: false, - panControl: false, - mapTypeControl: false, - scrollwheel: false - }; - if (USER.trips.length === 10) { - $("#show_all_trips").show(); - } - if (USER.trips.length > 0) { - map = new google.maps.Map(document.getElementById("trip_details_map"), myOptions); - bounds = new google.maps.LatLngBounds(); - path = []; - _.each(USER.trips.models[0].get('points'), __bind(function(point) { - path.push(new google.maps.LatLng(point.lat, point.lng)); - return bounds.extend(_.last(path)); - }, this)); - map.fitBounds(bounds); - startPos = new google.maps.Marker({ - position: _.first(path), - map: map, - title: t('Trip started here'), - icon: 'https://uber-static.s3.amazonaws.com/marker_start.png' - }); - endPos = new google.maps.Marker({ - position: _.last(path), - map: map, - title: t('Trip ended here'), - icon: 'https://uber-static.s3.amazonaws.com/marker_end.png' - }); - polyline = new google.maps.Polyline({ - path: path, - strokeColor: '#003F87', - strokeOpacity: 1, - strokeWeight: 5 - }); - return polyline.setMap(map); - } - }, ClientsDashboardView); - ClientsDashboardView.prototype.confirmationsSetup = function() { - var blink, cardForm, element, _ref, _ref2, _ref3, _ref4, _ref5; - blink = function(element) { - var opacity; - opacity = 0.5; - if (element.css('opacity') === "0.5") { - opacity = 1.0; - } - return element.fadeTo(2000, opacity, function() { - return blink(element); - }); - }; - if (((_ref = window.USER) != null ? (_ref2 = _ref.payment_gateway) != null ? (_ref3 = _ref2.payment_profiles) != null ? _ref3.length : void 0 : void 0 : void 0) === 0) { - element = $('#confirmed_credit_card'); - cardForm = new app.views.clients.modules.creditcard; - $('#card.info').append(cardForm.render().el); - blink(element); - } - if (((_ref4 = window.USER) != null ? _ref4.confirm_email : void 0) === false) { - element = $('#confirmed_email'); - blink(element); - } - if ((((_ref5 = window.USER) != null ? _ref5.confirm_mobile : void 0) != null) === false) { - element = $('#confirmed_mobile'); - return blink(element); - } - }; - ClientsDashboardView.prototype.confirmationClick = function(e) { - e.preventDefault(); - $('.info').hide(); - $('#more_info').show(); - switch (e.currentTarget.id) { - case "card": - return $('#card.info').slideToggle(); - case "mobile": - return $('#mobile.info').slideToggle(); - case "email": - return $('#email.info').slideToggle(); - } - }; - ClientsDashboardView.prototype.resendEmail = function(e) { - var $el; - e.preventDefault(); - $el = $(e.currentTarget); - $el.removeAttr('href').prop({ - disabled: true - }); - $el.html(t("Sending Email")); - return $.ajax({ - type: 'GET', - url: API + '/users/request_confirm_email', - data: { - token: USER.token - }, - dataType: 'json', - success: __bind(function(data, textStatus, jqXHR) { - return $el.html(t("Resend Email Succeeded")); - }, this), - error: __bind(function(jqXHR, textStatus, errorThrown) { - return $el.html(t("Resend Email Failed")); - }, this) - }); - }; - ClientsDashboardView.prototype.resendMobile = function(e) { - var $el; - e.preventDefault(); - $el = $(e.currentTarget); - $el.removeAttr('href').prop({ - disabled: true - }); - $el.html("Sending message..."); - return $.ajax({ - type: 'GET', - url: API + '/users/request_confirm_mobile', - data: { - token: USER.token - }, - dataType: 'json', - success: __bind(function(data, textStatus, jqXHR) { - return $el.html(t("Resend Text Succeeded")); - }, this), - error: __bind(function(jqXHR, textStatus, errorThrown) { - return $el.html(t("Resend Text Failed")); - }, this) - }); - }; - ClientsDashboardView.prototype.showAllTrips = function(e) { - e.preventDefault(); - $(e.currentTarget).hide(); - return this.DownloadUserTrips(this.render, true, 1000); - }; - return ClientsDashboardView; - }).call(this); -}).call(this); -}, "views/clients/forgot_password": function(exports, require, module) {(function() { - var clientsForgotPasswordTemplate; - var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { - for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } - function ctor() { this.constructor = child; } - ctor.prototype = parent.prototype; - child.prototype = new ctor; - child.__super__ = parent.prototype; - return child; - }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; - clientsForgotPasswordTemplate = require('templates/clients/forgot_password'); - exports.ClientsForgotPasswordView = (function() { - __extends(ClientsForgotPasswordView, UberView); - function ClientsForgotPasswordView() { - ClientsForgotPasswordView.__super__.constructor.apply(this, arguments); - } - ClientsForgotPasswordView.prototype.id = 'forgotpassword_view'; - ClientsForgotPasswordView.prototype.className = 'view_container modal_view_container'; - ClientsForgotPasswordView.prototype.events = { - "submit #password_reset": "passwordReset", - "click #password_reset_submit": "passwordReset", - "submit #forgot_password": "forgotPassword", - "click #forgot_password_submit": "forgotPassword" - }; - ClientsForgotPasswordView.prototype.render = function(token) { - this.HideSpinner(); - $(this.el).html(clientsForgotPasswordTemplate({ - token: token - })); - this.delegateEvents(); - return this; - }; - ClientsForgotPasswordView.prototype.forgotPassword = function(e) { - var attrs; - e.preventDefault(); - $('.success_message').hide(); - $(".error_message").hide(); - attrs = { - data: { - login: $("#login").val() - }, - success: __bind(function(data, textStatus, jqXHR) { - this.HideSpinner(); - $('.success_message').show(); - return $("#forgot_password").hide(); - }, this), - error: __bind(function(e) { - this.HideSpinner(); - return $('.error_message').show(); - }, this), - dataType: 'json', - type: 'PUT', - url: "" + API + "/users/forgot_password" - }; - $.ajax(attrs); - return this.ShowSpinner('submit'); - }; - ClientsForgotPasswordView.prototype.passwordReset = function(e) { - var attrs; - e.preventDefault(); - attrs = { - data: { - email_token: $("#token").val(), - password: $("#password").val() - }, - success: __bind(function(data, textStatus, jqXHR) { - this.HideSpinner(); - $.cookie('token', data.token); - amplify.store('USERjson', data); - app.refreshMenu(); - return location.hash = '!/dashboard'; - }, this), - error: __bind(function(e) { - this.HideSpinner(); - return $('#error_reset').show(); - }, this), - dataType: 'json', - type: 'PUT', - url: "" + API + "/users/self" - }; - $.ajax(attrs); - return this.ShowSpinner('submit'); - }; - return ClientsForgotPasswordView; - })(); -}).call(this); -}, "views/clients/invite": function(exports, require, module) {(function() { - var clientsInviteTemplate; - var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { - for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } - function ctor() { this.constructor = child; } - ctor.prototype = parent.prototype; - child.prototype = new ctor; - child.__super__ = parent.prototype; - return child; - }; - clientsInviteTemplate = require('templates/clients/invite'); - exports.ClientsInviteView = (function() { - __extends(ClientsInviteView, UberView); - function ClientsInviteView() { - ClientsInviteView.__super__.constructor.apply(this, arguments); - } - ClientsInviteView.prototype.id = 'invite_view'; - ClientsInviteView.prototype.className = 'view_container'; - ClientsInviteView.prototype.render = function() { - this.ReadUserInfo(); - this.HideSpinner(); - $(this.el).html(clientsInviteTemplate()); - console.log(screen); - return this; - }; - return ClientsInviteView; - })(); -}).call(this); -}, "views/clients/login": function(exports, require, module) {(function() { - var clientsLoginTemplate; - var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { - for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } - function ctor() { this.constructor = child; } - ctor.prototype = parent.prototype; - child.prototype = new ctor; - child.__super__ = parent.prototype; - return child; - }; - clientsLoginTemplate = require('templates/clients/login'); - exports.ClientsLoginView = (function() { - __extends(ClientsLoginView, UberView); - function ClientsLoginView() { - ClientsLoginView.__super__.constructor.apply(this, arguments); - } - ClientsLoginView.prototype.id = 'login_view'; - ClientsLoginView.prototype.className = 'view_container modal_view_container'; - ClientsLoginView.prototype.events = { - 'submit form': 'authenticate', - 'click button': 'authenticate' - }; - ClientsLoginView.prototype.initialize = function() { - _.bindAll(this, 'render'); - return this.render(); - }; - ClientsLoginView.prototype.render = function() { - this.HideSpinner(); - $(this.el).html(clientsLoginTemplate()); - this.delegateEvents(); - return this.place(); - }; - ClientsLoginView.prototype.authenticate = function(e) { - e.preventDefault(); - return $.ajax({ - type: 'POST', - url: API + '/auth/web_login/client', - data: { - login: $("#login").val(), - password: $("#password").val() - }, - dataType: 'json', - success: function(data, textStatus, jqXHR) { - $.cookie('user', JSON.stringify(data)); - $.cookie('token', data.token); - amplify.store('USERjson', data); - $('header').html(app.views.shared.menu.render().el); - return app.routers.clients.navigate('!/dashboard', true); - }, - error: function(jqXHR, textStatus, errorThrown) { - $.cookie('user', null); - $.cookie('token', null); - if (jqXHR.status === 403) { - $.cookie('redirected_user', JSON.stringify(JSON.parse(jqXHR.responseText).error_obj), { - domain: '.uber.com' - }); - window.location = 'http://partners.uber.com/'; - } - return $('.error_message').html(JSON.parse(jqXHR.responseText).error).hide().fadeIn(); - } - }); - }; - return ClientsLoginView; - })(); -}).call(this); -}, "views/clients/modules/credit_card": function(exports, require, module) {(function() { - var creditCardTemplate; - var __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { - for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } - function ctor() { this.constructor = child; } - ctor.prototype = parent.prototype; - child.prototype = new ctor; - child.__super__ = parent.prototype; - return child; - }, __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; - creditCardTemplate = require('templates/clients/modules/credit_card'); - exports.CreditCardView = (function() { - __extends(CreditCardView, UberView); - function CreditCardView() { - CreditCardView.__super__.constructor.apply(this, arguments); - } - CreditCardView.prototype.id = 'creditcard_view'; - CreditCardView.prototype.className = 'module_container'; - CreditCardView.prototype.events = { - 'submit #credit_card_form': 'processNewCard', - 'click #new_card': 'processNewCard', - 'change #card_number': 'showCardType', - 'click .edit_card_show': 'showEditCard', - 'click .edit_card': 'editCard', - 'click .delete_card': 'deleteCard', - 'click .make_default': 'makeDefault', - 'change .use_case': 'saveUseCase' - }; - CreditCardView.prototype.initialize = function() { - return app.collections.paymentprofiles.bind("refresh", __bind(function() { - return this.RefreshUserInfo(__bind(function() { - this.render("all"); - return this.HideSpinner(); - }, this)); - }, this)); - }; - CreditCardView.prototype.render = function(cards) { - if (cards == null) { - cards = "new"; - } - if (cards === "all") { - app.collections.paymentprofiles.reset(USER.payment_gateway.payment_profiles); - cards = app.collections.paymentprofiles; - } - $(this.el).html(creditCardTemplate({ - cards: cards - })); - return this; - }; - CreditCardView.prototype.processNewCard = function(e) { - var $el, attrs, model, options; - e.preventDefault(); - this.ClearGlobalStatus(); - $el = $("#credit_card_form"); - $el.find('.error_message').html(""); - attrs = { - card_number: $el.find('#card_number').val(), - card_code: $el.find('#card_code').val(), - card_expiration_month: $el.find('#card_expiration_month').val(), - card_expiration_year: $el.find('#card_expiration_year').val(), - use_case: $el.find('#use_case').val(), - "default": $el.find('#default_check').prop("checked") - }; - options = { - statusCode: { - 200: __bind(function(e) { - this.HideSpinner(); - $('#cc_form_wrapper').hide(); - app.collections.paymentprofiles.trigger("refresh"); - $(this.el).remove(); - $("a#add_card").show(); - return $('section').html(app.views.clients.billing.render().el); - }, this), - 406: __bind(function(e) { - var error, errors, _i, _len, _ref, _results; - this.HideSpinner(); - errors = JSON.parse(e.responseText); - _ref = _.keys(errors); - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - error = _ref[_i]; - _results.push(error === "top_of_form" ? $("#top_of_form").html(errors[error]) : $("#credit_card_form").find("#" + error).parent().find(".error_message").html(errors[error])); - } - return _results; - }, this), - 420: __bind(function(e) { - this.HideSpinner(); - return $("#top_of_form").html(t("Unable to Verify Card")); - }, this) - } - }; - this.ShowSpinner("submit"); - model = new app.models.paymentprofile; - model.save(attrs, options); - return app.collections.paymentprofiles.add(model); - }; - CreditCardView.prototype.showCardType = function(e) { - var $el, reAmerica, reDiscover, reMaster, reVisa, validCard; - reVisa = /^4\d{3}-?\d{4}-?\d{4}-?\d{4}$/; - reMaster = /^5[1-5]\d{2}-?\d{4}-?\d{4}-?\d{4}$/; - reAmerica = /^6011-?\d{4}-?\d{4}-?\d{4}$/; - reDiscover = /^3[4,7]\d{13}$/; - $el = $("#card_logos"); - validCard = false; - if (e.currentTarget.value.match(reVisa)) { - validCard = true; - } else if (e.currentTarget.value.match(reMaster)) { - $el.css('background-position', "-60px"); - validCard = true; - } else if (e.currentTarget.value.match(reAmerica)) { - $el.css('background-position', "-120px"); - validCard = true; - } else if (e.currentTarget.value.match(reDiscover)) { - $el.css('background-position', "-180px"); - validCard = true; - } - if (validCard) { - $el.css('width', "60px"); - return $el.css('margin-left', "180px"); - } else { - $el.css('width', "250px"); - return $el.css('margin-left', "80px"); - } - }; - CreditCardView.prototype.showEditCard = function(e) { - var $el, id; - e.preventDefault(); - $el = $(e.currentTarget); - if ($el.html() === t("Edit")) { - id = $el.html(t("Cancel")).parents("tr").attr("id").substring(1); - return $("#e" + id).show(); - } else { - id = $el.html(t("Edit")).parents("tr").attr("id").substring(1); - return $("#e" + id).hide(); - } - }; - CreditCardView.prototype.editCard = function(e) { - var $el, attrs, id, options; - e.preventDefault(); - this.ClearGlobalStatus(); - $el = $(e.currentTarget).parents("td"); - id = $el.parents("tr").attr("id").substring(1); - $el.attr('disabled', 'disabled'); - this.ShowSpinner('submit'); - attrs = { - card_expiration_month: $el.find('#card_expiration_month').val(), - card_expiration_year: $el.find('#card_expiration_year').val(), - card_code: $el.find('#card_code').val() - }; - options = { - success: __bind(function(response) { - this.HideSpinner(); - this.ShowSuccess(t("Credit Card Update Succeeded")); - $("#e" + id).hide(); - $("#d" + id).find(".edit_card_show").html(t("Edit")); - return app.collections.paymentprofiles.trigger("refresh"); - }, this), - error: __bind(function(e) { - this.HideSpinner(); - this.ShowError(t("Credit Card Update Failed")); - return $el.removeAttr('disabled'); - }, this) - }; - app.collections.paymentprofiles.models[id].set(attrs); - return app.collections.paymentprofiles.models[id].save({}, options); - }; - CreditCardView.prototype.deleteCard = function(e) { - var $el, id, options; - e.preventDefault(); - $el = $(e.currentTarget).parents("td"); - id = $el.parents("tr").attr("id").substring(1); - this.ClearGlobalStatus(); - this.ShowSpinner('submit'); - options = { - success: __bind(function(response) { - this.ShowSuccess(t("Credit Card Delete Succeeded")); - $("form").hide(); - app.collections.paymentprofiles.trigger("refresh"); - return $('section').html(app.views.clients.billing.render().el); - }, this), - error: __bind(function(xhr, e) { - this.HideSpinner(); - return this.ShowError(t("Credit Card Delete Failed")); - }, this) - }; - return app.collections.paymentprofiles.models[id].destroy(options); - }; - CreditCardView.prototype.saveUseCase = function(e) { - var $el, attrs, id, options, use_case; - this.ClearGlobalStatus(); - $el = $(e.currentTarget); - use_case = $el.val(); - id = $el.parents("tr").attr("id").substring(1); - attrs = { - use_case: use_case - }; - options = { - success: __bind(function(response) { - return this.ShowSuccess(t("Credit Card Update Category Succeeded")); - }, this), - error: __bind(function(e) { - return this.ShowError(t("Credit Card Update Category Failed")); - }, this) - }; - app.collections.paymentprofiles.models[id].set(attrs); - return app.collections.paymentprofiles.models[id].save({}, options); - }; - CreditCardView.prototype.makeDefault = function(e) { - var $el, attrs, id, options; - e.preventDefault(); - this.ClearGlobalStatus(); - $el = $(e.currentTarget).parents("td"); - id = $el.parents("tr").attr("id").substring(1); - attrs = { - "default": true - }; - options = { - success: __bind(function(response) { - this.ShowSuccess(t("Credit Card Update Default Succeeded")); - return app.collections.paymentprofiles.trigger("refresh"); - }, this), - error: __bind(function(e) { - return this.ShowError(t("Credit Card Update Default Failed")); - }, this) - }; - app.collections.paymentprofiles.models[id].set(attrs); - return app.collections.paymentprofiles.models[id].save({}, options); - }; - return CreditCardView; - })(); -}).call(this); -}, "views/clients/promotions": function(exports, require, module) {(function() { - var clientsPromotionsTemplate; - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { - for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } - function ctor() { this.constructor = child; } - ctor.prototype = parent.prototype; - child.prototype = new ctor; - child.__super__ = parent.prototype; - return child; - }; - clientsPromotionsTemplate = require('templates/clients/promotions'); - exports.ClientsPromotionsView = (function() { - __extends(ClientsPromotionsView, UberView); - function ClientsPromotionsView() { - this.render = __bind(this.render, this); - ClientsPromotionsView.__super__.constructor.apply(this, arguments); - } - ClientsPromotionsView.prototype.id = 'promotions_view'; - ClientsPromotionsView.prototype.className = 'view_container'; - ClientsPromotionsView.prototype.events = { - 'submit form': 'submitPromo', - 'click button': 'submitPromo' - }; - ClientsPromotionsView.prototype.initialize = function() { - if (this.model) { - return this.RefreshUserInfo(this.render); - } - }; - ClientsPromotionsView.prototype.render = function() { - var renderTemplate; - this.ReadUserInfo(); - renderTemplate = __bind(function() { - $(this.el).html(clientsPromotionsTemplate({ - promos: window.USER.unexpired_client_promotions || [] - })); - return this.HideSpinner(); - }, this); - this.DownloadUserPromotions(renderTemplate); - return this; - }; - ClientsPromotionsView.prototype.submitPromo = function(e) { - var attrs, model, options, refreshTable; - e.preventDefault(); - this.ClearGlobalStatus(); - refreshTable = __bind(function() { - $('section').html(this.render().el); - return this.HideSpinner(); - }, this); - attrs = { - code: $('#code').val() - }; - options = { - success: __bind(function(response) { - this.HideSpinner(); - if (response.get('first_name')) { - return this.ShowSuccess("Your promotion has been applied in the form of an account credit. Click here to check your balance."); - } else { - this.ShowSuccess("Your promotion has successfully been applied"); - return this.RefreshUserInfo(this.render, true); - } - }, this), - statusCode: { - 400: __bind(function(e) { - this.ShowError(JSON.parse(e.responseText).error); - return this.HideSpinner(); - }, this) - } - }; - this.ShowSpinner("submit"); - model = new app.models.promotions; - return model.save(attrs, options); - }; - return ClientsPromotionsView; - })(); -}).call(this); -}, "views/clients/request": function(exports, require, module) {(function() { - var clientsRequestTemplate; - var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = Object.prototype.hasOwnProperty, __extends = function(child, parent) { - for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } - function ctor() { this.constructor = child; } - ctor.prototype = parent.prototype; - child.prototype = new ctor; - child.__super__ = parent.prototype; - return child; - }; - clientsRequestTemplate = require('templates/clients/request'); - exports.ClientsRequestView = (function() { - __extends(ClientsRequestView, UberView); - function ClientsRequestView() { - this.AjaxCall = __bind(this.AjaxCall, this); - this.AskDispatch = __bind(this.AskDispatch, this); - this.removeMarkers = __bind(this.removeMarkers, this); - this.displaySearchLoc = __bind(this.displaySearchLoc, this); - this.displayFavLoc = __bind(this.displayFavLoc, this); - this.showFavLoc = __bind(this.showFavLoc, this); - this.addToFavLoc = __bind(this.addToFavLoc, this); - this.removeCabs = __bind(this.removeCabs, this); - this.requestRide = __bind(this.requestRide, this); - this.rateTrip = __bind(this.rateTrip, this); - this.locationChange = __bind(this.locationChange, this); - this.panToLocation = __bind(this.panToLocation, this); - this.clickLocation = __bind(this.clickLocation, this); - this.searchLocation = __bind(this.searchLocation, this); - this.mouseoutLocation = __bind(this.mouseoutLocation, this); - this.mouseoverLocation = __bind(this.mouseoverLocation, this); - this.fetchTripDetails = __bind(this.fetchTripDetails, this); - this.submitRating = __bind(this.submitRating, this); - this.setStatus = __bind(this.setStatus, this); - this.initialize = __bind(this.initialize, this); - ClientsRequestView.__super__.constructor.apply(this, arguments); - } - ClientsRequestView.prototype.id = 'request_view'; - ClientsRequestView.prototype.className = 'view_container'; - ClientsRequestView.prototype.pollInterval = 2 * 1000; - ClientsRequestView.prototype.events = { - "submit #search_form": "searchAddress", - "click .locations_link": "locationLinkHandle", - "mouseover .location_row": "mouseoverLocation", - "mouseout .location_row": "mouseoutLocation", - "click .location_row": "clickLocation", - "click #search_location": "searchLocation", - "click #pickupHandle": "pickupHandle", - "click .stars": "rateTrip", - "submit #rating_form": "submitRating", - "click #addToFavButton": "showFavLoc", - "click #favLocNickname": "selectInputText", - "submit #favLoc_form": "addToFavLoc" - }; - ClientsRequestView.prototype.status = ""; - ClientsRequestView.prototype.pickupMarker = "https://uber-static.s3.amazonaws.com/pickup_marker.png"; - ClientsRequestView.prototype.cabMarker = "https://uber-static.s3.amazonaws.com/cab_marker.png"; - ClientsRequestView.prototype.initialize = function() { - var displayCabs; - displayCabs = __bind(function() { - return this.AskDispatch("NearestCab"); - }, this); - this.showCabs = _.throttle(displayCabs, this.pollInterval); - return this.numSearchToDisplay = 1; - }; - ClientsRequestView.prototype.setStatus = function(status) { - var autocomplete; - if (this.status === status) { - return; - } - try { - google.maps.event.trigger(this.map, 'resize'); - } catch (_e) {} - switch (status) { - case "init": - this.AskDispatch("StatusClient"); - this.status = "init"; - return this.ShowSpinner("load"); - case "ready": - this.HideSpinner(); - $(".panel").hide(); - $("#top_bar").fadeIn(); - $("#location_panel").fadeIn(); - $("#location_panel_control").fadeIn(); - $("#pickupHandle").attr("class", "button_green").fadeIn().find("span").html(t("Request Pickup")); - this.pickup_icon.setDraggable(true); - this.map.panTo(this.pickup_icon.getPosition()); - this.showCabs(); - try { - this.pickup_icon.setMap(this.map); - this.displayFavLoc(); - autocomplete = new google.maps.places.Autocomplete(document.getElementById('address'), { - types: ['geocode'] - }); - autocomplete.bindTo('bounds', this.map); - } catch (_e) {} - return this.status = "ready"; - case "searching": - this.HideSpinner(); - this.removeMarkers(); - $(".panel").hide(); - $("#top_bar").fadeOut(); - $("#status_message").html(t("Requesting Closest Driver")); - $("#pickupHandle").attr("class", "button_red").fadeIn().find("span").html(t("Cancel Pickup")); - this.pickup_icon.setDraggable(false); - this.pickup_icon.setMap(this.map); - return this.status = "searching"; - case "waiting": - this.HideSpinner(); - this.removeMarkers(); - $(".panel").hide(); - $("#top_bar").fadeOut(); - $("#pickupHandle").attr("class", "button_red").fadeIn().find("span").html(t("Cancel Pickup")); - $("#waiting_riding").fadeIn(); - this.pickup_icon.setDraggable(false); - this.pickup_icon.setMap(this.map); - return this.status = "waiting"; - case "arriving": - this.HideSpinner(); - this.removeMarkers(); - $(".panel").hide(); - $("#top_bar").fadeOut(); - $("#pickupHandle").attr("class", "button_red").fadeIn().find("span").html(t("Cancel Pickup")); - $("#waiting_riding").fadeIn(); - this.pickup_icon.setDraggable(false); - this.pickup_icon.setMap(this.map); - return this.status = "arriving"; - case "riding": - this.HideSpinner(); - this.removeMarkers(); - $(".panel").hide(); - $("#top_bar").fadeOut(); - $("#pickupHandle").fadeIn().attr("class", "button_red").find("span").html(t("Cancel Pickup")); - $("#waiting_riding").fadeIn(); - this.pickup_icon.setDraggable(false); - this.status = "riding"; - return $("#status_message").html(t("En Route")); - case "rate": - this.HideSpinner(); - $(".panel").hide(); - $("#pickupHandle").fadeOut(); - $("#trip_completed_panel").fadeIn(); - $('#status_message').html(t("Rate Last Trip")); - return this.status = "rate"; - } - }; - ClientsRequestView.prototype.render = function() { - this.ReadUserInfo(); - this.HideSpinner(); - this.ShowSpinner("load"); - $(this.el).html(clientsRequestTemplate()); - this.cabs = []; - this.RequireMaps(__bind(function() { - var center, myOptions, streetViewPano; - center = new google.maps.LatLng(37.7749295, -122.4194155); - this.markers = []; - this.pickup_icon = new google.maps.Marker({ - position: center, - draggable: true, - clickable: true, - icon: this.pickupMarker - }); - this.geocoder = new google.maps.Geocoder(); - myOptions = { - zoom: 12, - center: center, - mapTypeId: google.maps.MapTypeId.ROADMAP, - rotateControl: false, - rotateControl: false, - panControl: false - }; - this.map = new google.maps.Map($(this.el).find("#map_wrapper_right")[0], myOptions); - if (this.status === "ready") { - this.pickup_icon.setMap(this.map); - } - if (geo_position_js.init()) { - geo_position_js.getCurrentPosition(__bind(function(data) { - var location; - location = new google.maps.LatLng(data.coords.latitude, data.coords.longitude); - this.pickup_icon.setPosition(location); - this.map.panTo(location); - return this.map.setZoom(16); - }, this)); - } - this.setStatus("init"); - streetViewPano = this.map.getStreetView(); - google.maps.event.addListener(streetViewPano, 'visible_changed', __bind(function() { - if (streetViewPano.getVisible()) { - this.pickupMarker = "https://uber-static.s3.amazonaws.com/pickup_marker_large.png"; - this.cabMarker = "https://uber-static.s3.amazonaws.com/cab_marker_large.png"; - } else { - this.pickupMarker = "https://uber-static.s3.amazonaws.com/pickup_marker.png"; - this.cabMarker = "https://uber-static.s3.amazonaws.com/cab_marker.png"; - } - this.pickup_icon.setIcon(this.pickupMarker); - return _.each(this.cabs, __bind(function(cab) { - return cab.setIcon(this.cabMarker); - }, this)); - }, this)); - if (this.status === "ready") { - return this.displayFavLoc(); - } - }, this)); - return this; - }; - ClientsRequestView.prototype.submitRating = function(e) { - var $el, message, rating; - e.preventDefault(); - $el = $(e.currentTarget); - rating = 0; - _(5).times(function(num) { - if ($el.find(".stars#" + (num + 1)).attr("src") === "/web/img/star_active.png") { - return rating = num + 1; - } - }); - if (rating === 0) { - $("#status_message").html("").html(t("Rate Before Submitting")); - } else { - this.ShowSpinner("submit"); - this.AskDispatch("RatingDriver", { - rating: rating - }); - } - message = $el.find("#comments").val().toString(); - if (message.length > 5) { - return this.AskDispatch("Feedback", { - message: message - }); - } - }; - ClientsRequestView.prototype.fetchTripDetails = function(id) { - var trip; - trip = new app.models.trip({ - id: id - }); - return trip.fetch({ - data: { - relationships: 'points,driver,city' - }, - dataType: 'json', - success: __bind(function() { - var bounds, endPos, path, polyline, startPos; - bounds = new google.maps.LatLngBounds(); - path = []; - _.each(trip.get('points'), __bind(function(point) { - path.push(new google.maps.LatLng(point.lat, point.lng)); - return bounds.extend(_.last(path)); - }, this)); - startPos = new google.maps.Marker({ - position: _.first(path), - map: this.map, - title: t("Trip started here"), - icon: 'https://uber-static.s3.amazonaws.com/carstart.png' - }); - endPos = new google.maps.Marker({ - position: _.last(path), - map: this.map, - title: t("Trip ended here"), - icon: 'https://uber-static.s3.amazonaws.com/carstop.png' - }); - polyline = new google.maps.Polyline({ - path: path, - strokeColor: '#003F87', - strokeOpacity: 1, - strokeWeight: 5 - }); - polyline.setMap(this.map); - this.map.fitBounds(bounds); - $("#tripTime").html(app.helpers.parseDateTime(trip.get('pickup_local_time'), trip.get('city.timezone'))); - $("#tripDist").html(app.helpers.RoundNumber(trip.get('distance'), 2)); - $("#tripDur").html(app.helpers.FormatSeconds(trip.get('duration'))); - return $("#tripFare").html(app.helpers.FormatCurrency(trip.get('fare'))); - }, this) - }); - }; - ClientsRequestView.prototype.searchAddress = function(e) { - var $locationsDiv, address, alphabet, bounds, showResults; - alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - try { - e.preventDefault(); - } catch (_e) {} - $('.error_message').html(""); - $locationsDiv = $("
"); - address = $('#address').val(); - bounds = new google.maps.LatLngBounds(); - if (address.length < 5) { - $('#status_message').html(t("Address too short")).fadeIn(); - return false; - } - showResults = __bind(function(address, index) { - var first_cell, row, second_cell; - if (index < this.numSearchToDisplay) { - first_cell = "
" + address.formatted_address + "
" + (t('or did you mean')) + "
" + address.formatted_address + "
- - - - - - -
Rod VaggGitHub/rvaggTwitter/@rvagg
Benjamin ByholmGitHub/kkoopa
Trevor NorrisGitHub/trevnorrisTwitter/@trevnorris
Nathan RajlichGitHub/TooTallNateTwitter/@TooTallNate
Brett LawsonGitHub/brett19Twitter/@brett19x
Ben NoordhuisGitHub/bnoordhuisTwitter/@bnoordhuis
- -Licence & copyright ------------------------ - -Copyright (c) 2014 NAN contributors (listed above). - -Native Abstractions for Node.js is licensed under an MIT +no-false-attribs license. All rights not explicitly granted in the MIT license are reserved. See the included LICENSE file for more details. diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/nan/build/config.gypi b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/nan/build/config.gypi deleted file mode 100644 index e085a5008e..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/nan/build/config.gypi +++ /dev/null @@ -1,38 +0,0 @@ -# Do not edit. File was generated by node-gyp's "configure" step -{ - "target_defaults": { - "cflags": [], - "default_configuration": "Release", - "defines": [], - "include_dirs": [], - "libraries": [] - }, - "variables": { - "clang": 0, - "gcc_version": 47, - "host_arch": "x64", - "node_install_npm": "true", - "node_prefix": "", - "node_shared_cares": "false", - "node_shared_http_parser": "false", - "node_shared_libuv": "false", - "node_shared_openssl": "false", - "node_shared_v8": "false", - "node_shared_zlib": "false", - "node_tag": "", - "node_unsafe_optimizations": 0, - "node_use_dtrace": "false", - "node_use_etw": "false", - "node_use_openssl": "true", - "node_use_perfctr": "false", - "node_use_systemtap": "false", - "python": "/usr/bin/python", - "target_arch": "x64", - "v8_enable_gdbjit": 0, - "v8_no_strict_aliasing": 1, - "v8_use_snapshot": "true", - "nodedir": "/home/rvagg/.node-gyp/0.10.21", - "copy_dev_lib": "true", - "standalone_static_library": 1 - } -} diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/nan/include_dirs.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/nan/include_dirs.js deleted file mode 100644 index 4f1dfb4166..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/nan/include_dirs.js +++ /dev/null @@ -1 +0,0 @@ -console.log(require('path').relative('.', __dirname)); diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/nan/nan.h b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/nan/nan.h deleted file mode 100644 index bc544f53c5..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/nan/nan.h +++ /dev/null @@ -1,1910 +0,0 @@ -/********************************************************************************** - * NAN - Native Abstractions for Node.js - * - * Copyright (c) 2014 NAN contributors: - * - Rod Vagg - * - Benjamin Byholm - * - Trevor Norris - * - Nathan Rajlich - * - Brett Lawson - * - Ben Noordhuis - * - * MIT +no-false-attribs License - * - * Version 1.0.0 (current Node unstable: 0.11.13, Node stable: 0.10.28) - * - * ChangeLog: - * * 1.0.0 May 4 2014 - * - Heavy API changes for V8 3.25 / Node 0.11.13 - * - Use cpplint.py - * - Removed NanInitPersistent - * - Removed NanPersistentToLocal - * - Removed NanFromV8String - * - Removed NanMakeWeak - * - Removed NanNewLocal - * - Removed NAN_WEAK_CALLBACK_OBJECT - * - Removed NAN_WEAK_CALLBACK_DATA - * - Introduce NanNew, replaces NanNewLocal, NanPersistentToLocal, adds many overloaded typed versions - * - Introduce NanUndefined, NanNull, NanTrue and NanFalse - * - Introduce NanEscapableScope and NanEscapeScope - * - Introduce NanMakeWeakPersistent (requires a special callback to work on both old and new node) - * - Introduce NanMakeCallback for node::MakeCallback - * - Introduce NanSetTemplate - * - Introduce NanGetCurrentContext - * - Introduce NanCompileScript and NanRunScript - * - Introduce NanAdjustExternalMemory - * - Introduce NanAddGCEpilogueCallback, NanAddGCPrologueCallback, NanRemoveGCEpilogueCallback, NanRemoveGCPrologueCallback - * - Introduce NanGetHeapStatistics - * - Rename NanAsyncWorker#SavePersistent() to SaveToPersistent() - * - * * 0.8.0 Jan 9 2014 - * - NanDispose -> NanDisposePersistent, deprecate NanDispose - * - Extract _NAN_*_RETURN_TYPE, pull up NAN_*() - * - * * 0.7.1 Jan 9 2014 - * - Fixes to work against debug builds of Node - * - Safer NanPersistentToLocal (avoid reinterpret_cast) - * - Speed up common NanRawString case by only extracting flattened string when necessary - * - * * 0.7.0 Dec 17 2013 - * - New no-arg form of NanCallback() constructor. - * - NanCallback#Call takes Handle rather than Local - * - Removed deprecated NanCallback#Run method, use NanCallback#Call instead - * - Split off _NAN_*_ARGS_TYPE from _NAN_*_ARGS - * - Restore (unofficial) Node 0.6 compatibility at NanCallback#Call() - * - Introduce NanRawString() for char* (or appropriate void*) from v8::String - * (replacement for NanFromV8String) - * - Introduce NanCString() for null-terminated char* from v8::String - * - * * 0.6.0 Nov 21 2013 - * - Introduce NanNewLocal(v8::Handle value) for use in place of - * v8::Local::New(...) since v8 started requiring isolate in Node 0.11.9 - * - * * 0.5.2 Nov 16 2013 - * - Convert SavePersistent and GetFromPersistent in NanAsyncWorker from protected and public - * - * * 0.5.1 Nov 12 2013 - * - Use node::MakeCallback() instead of direct v8::Function::Call() - * - * * 0.5.0 Nov 11 2013 - * - Added @TooTallNate as collaborator - * - New, much simpler, "include_dirs" for binding.gyp - * - Added full range of NAN_INDEX_* macros to match NAN_PROPERTY_* macros - * - * * 0.4.4 Nov 2 2013 - * - Isolate argument from v8::Persistent::MakeWeak removed for 0.11.8+ - * - * * 0.4.3 Nov 2 2013 - * - Include node_object_wrap.h, removed from node.h for Node 0.11.8. - * - * * 0.4.2 Nov 2 2013 - * - Handle deprecation of v8::Persistent::Dispose(v8::Isolate* isolate)) for - * Node 0.11.8 release. - * - * * 0.4.1 Sep 16 2013 - * - Added explicit `#include ` as it was removed from node.h for v0.11.8 - * - * * 0.4.0 Sep 2 2013 - * - Added NAN_INLINE and NAN_DEPRECATED and made use of them - * - Added NanError, NanTypeError and NanRangeError - * - Cleaned up code - * - * * 0.3.2 Aug 30 2013 - * - Fix missing scope declaration in GetFromPersistent() and SaveToPersistent - * in NanAsyncWorker - * - * * 0.3.1 Aug 20 2013 - * - fix "not all control paths return a value" compile warning on some platforms - * - * * 0.3.0 Aug 19 2013 - * - Made NAN work with NPM - * - Lots of fixes to NanFromV8String, pulling in features from new Node core - * - Changed node::encoding to Nan::Encoding in NanFromV8String to unify the API - * - Added optional error number argument for NanThrowError() - * - Added NanInitPersistent() - * - Added NanReturnNull() and NanReturnEmptyString() - * - Added NanLocker and NanUnlocker - * - Added missing scopes - * - Made sure to clear disposed Persistent handles - * - Changed NanAsyncWorker to allocate error messages on the heap - * - Changed NanThrowError(Local) to NanThrowError(Handle) - * - Fixed leak in NanAsyncWorker when errmsg is used - * - * * 0.2.2 Aug 5 2013 - * - Fixed usage of undefined variable with node::BASE64 in NanFromV8String() - * - * * 0.2.1 Aug 5 2013 - * - Fixed 0.8 breakage, node::BUFFER encoding type not available in 0.8 for - * NanFromV8String() - * - * * 0.2.0 Aug 5 2013 - * - Added NAN_PROPERTY_GETTER, NAN_PROPERTY_SETTER, NAN_PROPERTY_ENUMERATOR, - * NAN_PROPERTY_DELETER, NAN_PROPERTY_QUERY - * - Extracted _NAN_METHOD_ARGS, _NAN_GETTER_ARGS, _NAN_SETTER_ARGS, - * _NAN_PROPERTY_GETTER_ARGS, _NAN_PROPERTY_SETTER_ARGS, - * _NAN_PROPERTY_ENUMERATOR_ARGS, _NAN_PROPERTY_DELETER_ARGS, - * _NAN_PROPERTY_QUERY_ARGS - * - Added NanGetInternalFieldPointer, NanSetInternalFieldPointer - * - Added NAN_WEAK_CALLBACK, NAN_WEAK_CALLBACK_OBJECT, - * NAN_WEAK_CALLBACK_DATA, NanMakeWeak - * - Renamed THROW_ERROR to _NAN_THROW_ERROR - * - Added NanNewBufferHandle(char*, size_t, node::smalloc::FreeCallback, void*) - * - Added NanBufferUse(char*, uint32_t) - * - Added NanNewContextHandle(v8::ExtensionConfiguration*, - * v8::Handle, v8::Handle) - * - Fixed broken NanCallback#GetFunction() - * - Added optional encoding and size arguments to NanFromV8String() - * - Added NanGetPointerSafe() and NanSetPointerSafe() - * - Added initial test suite (to be expanded) - * - Allow NanUInt32OptionValue to convert any Number object - * - * * 0.1.0 Jul 21 2013 - * - Added `NAN_GETTER`, `NAN_SETTER` - * - Added `NanThrowError` with single Local argument - * - Added `NanNewBufferHandle` with single uint32_t argument - * - Added `NanHasInstance(Persistent&, Handle)` - * - Added `Local NanCallback#GetFunction()` - * - Added `NanCallback#Call(int, Local[])` - * - Deprecated `NanCallback#Run(int, Local[])` in favour of Call - * - * See https://github.com/rvagg/nan for the latest update to this file - **********************************************************************************/ - -#ifndef NAN_H_ -#define NAN_H_ - -#include -#include -#include -#include -#include -#include - -#if defined(__GNUC__) && !defined(DEBUG) -# define NAN_INLINE inline __attribute__((always_inline)) -#elif defined(_MSC_VER) && !defined(DEBUG) -# define NAN_INLINE __forceinline -#else -# define NAN_INLINE inline -#endif - -#if defined(__GNUC__) && !V8_DISABLE_DEPRECATIONS -# define NAN_DEPRECATED __attribute__((deprecated)) -#elif defined(_MSC_VER) && !V8_DISABLE_DEPRECATIONS -# define NAN_DEPRECATED __declspec(deprecated) -#else -# define NAN_DEPRECATED -#endif - -// some generic helpers - -template NAN_INLINE bool NanSetPointerSafe( - T *var - , T val -) { - if (var) { - *var = val; - return true; - } else { - return false; - } -} - -template NAN_INLINE T NanGetPointerSafe( - T *var - , T fallback = reinterpret_cast(0) -) { - if (var) { - return *var; - } else { - return fallback; - } -} - -NAN_INLINE bool NanBooleanOptionValue( - v8::Local optionsObj - , v8::Handle opt, bool def -) { - if (def) { - return optionsObj.IsEmpty() - || !optionsObj->Has(opt) - || optionsObj->Get(opt)->BooleanValue(); - } else { - return !optionsObj.IsEmpty() - && optionsObj->Has(opt) - && optionsObj->Get(opt)->BooleanValue(); - } -} - -NAN_INLINE bool NanBooleanOptionValue( - v8::Local optionsObj - , v8::Handle opt -) { - return NanBooleanOptionValue(optionsObj, opt, false); -} - -NAN_INLINE uint32_t NanUInt32OptionValue( - v8::Local optionsObj - , v8::Handle opt - , uint32_t def -) { - return !optionsObj.IsEmpty() - && optionsObj->Has(opt) - && optionsObj->Get(opt)->IsNumber() - ? optionsObj->Get(opt)->Uint32Value() - : def; -} - -#if (NODE_MODULE_VERSION > 0x000B) -// Node 0.11+ (0.11.3 and below won't compile with these) - -# define _NAN_METHOD_ARGS_TYPE const v8::FunctionCallbackInfo& -# define _NAN_METHOD_ARGS _NAN_METHOD_ARGS_TYPE args -# define _NAN_METHOD_RETURN_TYPE void - -# define _NAN_GETTER_ARGS_TYPE const v8::PropertyCallbackInfo& -# define _NAN_GETTER_ARGS _NAN_GETTER_ARGS_TYPE args -# define _NAN_GETTER_RETURN_TYPE void - -# define _NAN_SETTER_ARGS_TYPE const v8::PropertyCallbackInfo& -# define _NAN_SETTER_ARGS _NAN_SETTER_ARGS_TYPE args -# define _NAN_SETTER_RETURN_TYPE void - -# define _NAN_PROPERTY_GETTER_ARGS_TYPE \ - const v8::PropertyCallbackInfo& -# define _NAN_PROPERTY_GETTER_ARGS _NAN_PROPERTY_GETTER_ARGS_TYPE args -# define _NAN_PROPERTY_GETTER_RETURN_TYPE void - -# define _NAN_PROPERTY_SETTER_ARGS_TYPE \ - const v8::PropertyCallbackInfo& -# define _NAN_PROPERTY_SETTER_ARGS _NAN_PROPERTY_SETTER_ARGS_TYPE args -# define _NAN_PROPERTY_SETTER_RETURN_TYPE void - -# define _NAN_PROPERTY_ENUMERATOR_ARGS_TYPE \ - const v8::PropertyCallbackInfo& -# define _NAN_PROPERTY_ENUMERATOR_ARGS _NAN_PROPERTY_ENUMERATOR_ARGS_TYPE args -# define _NAN_PROPERTY_ENUMERATOR_RETURN_TYPE void - -# define _NAN_PROPERTY_DELETER_ARGS_TYPE \ - const v8::PropertyCallbackInfo& -# define _NAN_PROPERTY_DELETER_ARGS \ - _NAN_PROPERTY_DELETER_ARGS_TYPE args -# define _NAN_PROPERTY_DELETER_RETURN_TYPE void - -# define _NAN_PROPERTY_QUERY_ARGS_TYPE \ - const v8::PropertyCallbackInfo& -# define _NAN_PROPERTY_QUERY_ARGS _NAN_PROPERTY_QUERY_ARGS_TYPE args -# define _NAN_PROPERTY_QUERY_RETURN_TYPE void - -# define _NAN_INDEX_GETTER_ARGS_TYPE \ - const v8::PropertyCallbackInfo& -# define _NAN_INDEX_GETTER_ARGS _NAN_INDEX_GETTER_ARGS_TYPE args -# define _NAN_INDEX_GETTER_RETURN_TYPE void - -# define _NAN_INDEX_SETTER_ARGS_TYPE \ - const v8::PropertyCallbackInfo& -# define _NAN_INDEX_SETTER_ARGS _NAN_INDEX_SETTER_ARGS_TYPE args -# define _NAN_INDEX_SETTER_RETURN_TYPE void - -# define _NAN_INDEX_ENUMERATOR_ARGS_TYPE \ - const v8::PropertyCallbackInfo& -# define _NAN_INDEX_ENUMERATOR_ARGS _NAN_INDEX_ENUMERATOR_ARGS_TYPE args -# define _NAN_INDEX_ENUMERATOR_RETURN_TYPE void - -# define _NAN_INDEX_DELETER_ARGS_TYPE \ - const v8::PropertyCallbackInfo& -# define _NAN_INDEX_DELETER_ARGS _NAN_INDEX_DELETER_ARGS_TYPE args -# define _NAN_INDEX_DELETER_RETURN_TYPE void - -# define _NAN_INDEX_QUERY_ARGS_TYPE \ - const v8::PropertyCallbackInfo& -# define _NAN_INDEX_QUERY_ARGS _NAN_INDEX_QUERY_ARGS_TYPE args -# define _NAN_INDEX_QUERY_RETURN_TYPE void - -typedef v8::FunctionCallback NanFunctionCallback; -static v8::Isolate* nan_isolate = v8::Isolate::GetCurrent(); - -# define NanUndefined() v8::Undefined(nan_isolate) -# define NanNull() v8::Null(nan_isolate) -# define NanTrue() v8::True(nan_isolate) -# define NanFalse() v8::False(nan_isolate) -# define NanAdjustExternalMemory(amount) \ - nan_isolate->AdjustAmountOfExternalAllocatedMemory(amount) -# define NanSetTemplate(templ, name, value) templ->Set(nan_isolate, name, value) -# define NanGetCurrentContext() nan_isolate->GetCurrentContext() -# define NanMakeCallback(target, func, argc, argv) \ - node::MakeCallback(nan_isolate, target, func, argc, argv) -# define NanGetInternalFieldPointer(object, index) \ - object->GetAlignedPointerFromInternalField(index) -# define NanSetInternalFieldPointer(object, index, value) \ - object->SetAlignedPointerInInternalField(index, value) - - template - NAN_INLINE v8::Local NanNew() { - return T::New(nan_isolate); - } - - template - NAN_INLINE v8::Local NanNew(P arg1) { - return T::New(nan_isolate, arg1); - } - - template - NAN_INLINE v8::Local NanNew( - v8::Handle receiver - , int argc - , v8::Handle argv[] = 0) { - return v8::Signature::New(nan_isolate, receiver, argc, argv); - } - - template - NAN_INLINE v8::Local NanNew( - NanFunctionCallback callback - , v8::Handle data = v8::Handle() - , v8::Handle signature = v8::Handle()) { - return T::New(nan_isolate, callback, data, signature); - } - - template - NAN_INLINE v8::Local NanNew(v8::Handle arg1) { - return v8::Local::New(nan_isolate, arg1); - } - - template - NAN_INLINE v8::Local NanNew(const v8::Persistent &arg1) { - return v8::Local::New(nan_isolate, arg1); - } - - template - NAN_INLINE v8::Local NanNew(P arg1, int arg2) { - return T::New(nan_isolate, arg1, arg2); - } - - template<> - NAN_INLINE v8::Local NanNew() { - return v8::Array::New(nan_isolate); - } - - template<> - NAN_INLINE v8::Local NanNew(int length) { - return v8::Array::New(nan_isolate, length); - } - - template<> - NAN_INLINE v8::Local NanNew(double time) { - return v8::Date::New(nan_isolate, time).As(); - } - - template<> - NAN_INLINE v8::Local NanNew(int time) { - return v8::Date::New(nan_isolate, time).As(); - } - - typedef v8::UnboundScript NanUnboundScript; - typedef v8::Script NanBoundScript; - - template - NAN_INLINE v8::Local NanNew( - P s - , const v8::ScriptOrigin& origin - ) { - v8::ScriptCompiler::Source source(s, origin); - return v8::ScriptCompiler::CompileUnbound(nan_isolate, &source); - } - - template<> - NAN_INLINE v8::Local NanNew( - v8::Local s - ) { - v8::ScriptCompiler::Source source(s); - return v8::ScriptCompiler::CompileUnbound(nan_isolate, &source); - } - - NAN_INLINE v8::Local NanNew( - v8::String::ExternalStringResource *resource) { - return v8::String::NewExternal(nan_isolate, resource); - } - - NAN_INLINE v8::Local NanNew( - v8::String::ExternalAsciiStringResource *resource) { - return v8::String::NewExternal(nan_isolate, resource); - } - - template<> - NAN_INLINE v8::Local NanNew(bool value) { - return v8::BooleanObject::New(value).As(); - } - - template<> - NAN_INLINE v8::Local - NanNew >( - v8::Local value) { - return v8::StringObject::New(value).As(); - } - - template<> - NAN_INLINE v8::Local - NanNew >( - v8::Handle value) { - return v8::StringObject::New(value).As(); - } - - template<> - NAN_INLINE v8::Local NanNew(double val) { - return v8::NumberObject::New(nan_isolate, val).As(); - } - - template - NAN_INLINE v8::Local NanNew( - v8::Handle pattern, v8::RegExp::Flags flags) { - return v8::RegExp::New(pattern, flags); - } - - template - NAN_INLINE v8::Local NanNew( - v8::Local pattern, v8::RegExp::Flags flags) { - return v8::RegExp::New(pattern, flags); - } - - template - NAN_INLINE v8::Local NanNew( - v8::Handle pattern, v8::RegExp::Flags flags) { - return v8::RegExp::New(pattern, flags); - } - - template - NAN_INLINE v8::Local NanNew( - v8::Local pattern, v8::RegExp::Flags flags) { - return v8::RegExp::New(pattern, flags); - } - - template<> - NAN_INLINE v8::Local NanNew(int32_t val) { - return v8::Uint32::NewFromUnsigned(nan_isolate, val)->ToUint32(); - } - - template<> - NAN_INLINE v8::Local NanNew(uint32_t val) { - return v8::Uint32::NewFromUnsigned(nan_isolate, val)->ToUint32(); - } - - template<> - NAN_INLINE v8::Local NanNew(int32_t val) { - return v8::Int32::New(nan_isolate, val)->ToInt32(); - } - - template<> - NAN_INLINE v8::Local NanNew(uint32_t val) { - return v8::Int32::New(nan_isolate, val)->ToInt32(); - } - - template<> - NAN_INLINE v8::Local NanNew( - char *arg - , int length) { - return v8::String::NewFromUtf8( - nan_isolate - , arg - , v8::String::kNormalString - , length); - } - - template<> - NAN_INLINE v8::Local NanNew( - const char *arg - , int length) { - return v8::String::NewFromUtf8( - nan_isolate - , arg - , v8::String::kNormalString - , length); - } - - template<> - NAN_INLINE v8::Local NanNew(char *arg) { - return v8::String::NewFromUtf8(nan_isolate, arg); - } - - template<> - NAN_INLINE v8::Local NanNew( - const char *arg) { - return v8::String::NewFromUtf8(nan_isolate, arg); - } - - template<> - NAN_INLINE v8::Local NanNew( - uint8_t *arg - , int length) { - return v8::String::NewFromOneByte( - nan_isolate - , arg - , v8::String::kNormalString - , length); - } - - template<> - NAN_INLINE v8::Local NanNew( - const uint8_t *arg - , int length) { - return v8::String::NewFromOneByte( - nan_isolate - , arg - , v8::String::kNormalString - , length); - } - - template<> - NAN_INLINE v8::Local NanNew(uint8_t *arg) { - return v8::String::NewFromOneByte(nan_isolate, arg); - } - - template<> - NAN_INLINE v8::Local NanNew( - const uint8_t *arg) { - return v8::String::NewFromOneByte(nan_isolate, arg); - } - - template<> - NAN_INLINE v8::Local NanNew( - uint16_t *arg - , int length) { - return v8::String::NewFromTwoByte( - nan_isolate - , arg - , v8::String::kNormalString - , length); - } - - template<> - NAN_INLINE v8::Local NanNew( - const uint16_t *arg - , int length) { - return v8::String::NewFromTwoByte( - nan_isolate - , arg - , v8::String::kNormalString - , length); - } - template<> - NAN_INLINE v8::Local NanNew( - uint16_t *arg) { - return v8::String::NewFromTwoByte(nan_isolate, arg); - } - - template<> - NAN_INLINE v8::Local NanNew( - const uint16_t *arg) { - return v8::String::NewFromTwoByte(nan_isolate, arg); - } - - template<> - NAN_INLINE v8::Local NanNew() { - return v8::String::Empty(nan_isolate); - } - - NAN_INLINE void NanAddGCEpilogueCallback( - v8::Isolate::GCEpilogueCallback callback - , v8::GCType gc_type_filter = v8::kGCTypeAll) { - nan_isolate->AddGCEpilogueCallback(callback, gc_type_filter); - } - - NAN_INLINE void NanRemoveGCEpilogueCallback( - v8::Isolate::GCEpilogueCallback callback) { - nan_isolate->RemoveGCEpilogueCallback(callback); - } - - NAN_INLINE void NanAddGCPrologueCallback( - v8::Isolate::GCPrologueCallback callback - , v8::GCType gc_type_filter = v8::kGCTypeAll) { - nan_isolate->AddGCPrologueCallback(callback, gc_type_filter); - } - - NAN_INLINE void NanRemoveGCPrologueCallback( - v8::Isolate::GCPrologueCallback callback) { - nan_isolate->RemoveGCPrologueCallback(callback); - } - - NAN_INLINE void NanGetHeapStatistics( - v8::HeapStatistics *heap_statistics) { - nan_isolate->GetHeapStatistics(heap_statistics); - } - -# define NanSymbol(value) NanNew(value) - - template - NAN_INLINE void NanAssignPersistent( - v8::Persistent& handle - , v8::Handle obj) { - handle.Reset(nan_isolate, obj); - } - - template - NAN_INLINE void NanAssignPersistent( - v8::Persistent& handle - , const v8::Persistent& obj) { - handle.Reset(nan_isolate, obj); - } - - template - struct _NanWeakCallbackInfo { - typedef void (*Callback)( - const v8::WeakCallbackData >& data); - _NanWeakCallbackInfo(v8::Handle handle, P* param, Callback cb) - : parameter(param), callback(cb) { - NanAssignPersistent(persistent, handle); - } - - ~_NanWeakCallbackInfo() { - persistent.Reset(); - } - - P* const parameter; - Callback const callback; - v8::Persistent persistent; - }; - - template - class _NanWeakCallbackData { - public: - _NanWeakCallbackData(_NanWeakCallbackInfo *info) - : info_(info) { } - - NAN_INLINE v8::Local GetValue() const { - return NanNew(info_->persistent); - } - NAN_INLINE P* GetParameter() const { return info_->parameter; } - NAN_INLINE void Revive() const { - info_->persistent.SetWeak(info_, info_->callback); - } - - NAN_INLINE void Dispose() const { - delete info_; - } - - private: - _NanWeakCallbackInfo* info_; - }; - -// do not use for declaration -# define NAN_WEAK_CALLBACK(name) \ - template \ - static void name( \ - const v8::WeakCallbackData > &data) { \ - _NanWeakCallbackData wcbd( \ - data.GetParameter()); \ - _Nan_Weak_Callback_ ## name(wcbd); \ - } \ - \ - template \ - NAN_INLINE void _Nan_Weak_Callback_ ## name( \ - const _NanWeakCallbackData &data) - -# define NanScope() v8::HandleScope scope(nan_isolate) -# define NanEscapableScope() v8::EscapableHandleScope scope(nan_isolate) -# define NanEscapeScope(val) scope.Escape(val) -# define NanLocker() v8::Locker locker(nan_isolate) -# define NanUnlocker() v8::Unlocker unlocker(nan_isolate) -# define NanReturnValue(value) return args.GetReturnValue().Set(value) -# define NanReturnUndefined() return -# define NanReturnNull() return args.GetReturnValue().SetNull() -# define NanReturnEmptyString() return args.GetReturnValue().SetEmptyString() - -# define NanObjectWrapHandle(obj) obj->handle() - -template -void NAN_INLINE NanMakeWeakPersistent( - v8::Handle handle - , P* parameter - , typename _NanWeakCallbackInfo::Callback callback) { - _NanWeakCallbackInfo *cbinfo = - new _NanWeakCallbackInfo(handle, parameter, callback); - cbinfo->persistent.SetWeak(cbinfo, callback); -} - -# define _NAN_ERROR(fun, errmsg) fun(NanNew(errmsg)) - -# define _NAN_THROW_ERROR(fun, errmsg) \ - do { \ - NanScope(); \ - nan_isolate->ThrowException(_NAN_ERROR(fun, errmsg)); \ - } while (0); - - NAN_INLINE v8::Local NanError(const char* errmsg) { - return _NAN_ERROR(v8::Exception::Error, errmsg); - } - - NAN_INLINE void NanThrowError(const char* errmsg) { - _NAN_THROW_ERROR(v8::Exception::Error, errmsg); - } - - NAN_INLINE void NanThrowError(v8::Handle error) { - NanScope(); - nan_isolate->ThrowException(error); - } - - NAN_INLINE v8::Local NanError( - const char *msg - , const int errorNumber - ) { - v8::Local err = v8::Exception::Error(NanNew(msg)); - v8::Local obj = err.As(); - obj->Set(NanSymbol("code"), NanNew(errorNumber)); - return err; - } - - NAN_INLINE void NanThrowError( - const char *msg - , const int errorNumber - ) { - NanThrowError(NanError(msg, errorNumber)); - } - - NAN_INLINE v8::Local NanTypeError(const char* errmsg) { - return _NAN_ERROR(v8::Exception::TypeError, errmsg); - } - - NAN_INLINE void NanThrowTypeError(const char* errmsg) { - _NAN_THROW_ERROR(v8::Exception::TypeError, errmsg); - } - - NAN_INLINE v8::Local NanRangeError(const char* errmsg) { - return _NAN_ERROR(v8::Exception::RangeError, errmsg); - } - - NAN_INLINE void NanThrowRangeError(const char* errmsg) { - _NAN_THROW_ERROR(v8::Exception::RangeError, errmsg); - } - - template NAN_INLINE void NanDisposePersistent( - v8::Persistent &handle - ) { - handle.Reset(); - } - - NAN_INLINE v8::Local NanNewBufferHandle ( - char *data - , size_t length - , node::smalloc::FreeCallback callback - , void *hint - ) { - return node::Buffer::New(nan_isolate, data, length, callback, hint); - } - - NAN_INLINE v8::Local NanNewBufferHandle ( - const char *data - , uint32_t size - ) { - return node::Buffer::New(nan_isolate, data, size); - } - - NAN_INLINE v8::Local NanNewBufferHandle (uint32_t size) { - return node::Buffer::New(nan_isolate, size); - } - - NAN_INLINE v8::Local NanBufferUse( - char* data - , uint32_t size - ) { - return node::Buffer::Use(nan_isolate, data, size); - } - - NAN_INLINE bool NanHasInstance( - v8::Persistent& function_template - , v8::Handle value - ) { - return NanNew(function_template)->HasInstance(value); - } - - NAN_INLINE v8::Local NanNewContextHandle( - v8::ExtensionConfiguration* extensions = NULL - , v8::Handle tmpl = v8::Handle() - , v8::Handle obj = v8::Handle() - ) { - return v8::Local::New( - nan_isolate - , v8::Context::New(nan_isolate, extensions, tmpl, obj) - ); - } - - NAN_INLINE v8::Local NanCompileScript( - v8::Local s - , const v8::ScriptOrigin& origin - ) { - v8::ScriptCompiler::Source source(s, origin); - return v8::ScriptCompiler::Compile(nan_isolate, &source); - } - - NAN_INLINE v8::Local NanCompileScript( - v8::Local s - ) { - v8::ScriptCompiler::Source source(s); - return v8::ScriptCompiler::Compile(nan_isolate, &source); - } - - NAN_INLINE v8::Local NanRunScript( - v8::Local script - ) { - return script->BindToCurrentContext()->Run(); - } - - NAN_INLINE v8::Local NanRunScript( - v8::Local script - ) { - return script->Run(); - } - -#else -// Node 0.8 and 0.10 - -# define _NAN_METHOD_ARGS_TYPE const v8::Arguments& -# define _NAN_METHOD_ARGS _NAN_METHOD_ARGS_TYPE args -# define _NAN_METHOD_RETURN_TYPE v8::Handle - -# define _NAN_GETTER_ARGS_TYPE const v8::AccessorInfo & -# define _NAN_GETTER_ARGS _NAN_GETTER_ARGS_TYPE args -# define _NAN_GETTER_RETURN_TYPE v8::Handle - -# define _NAN_SETTER_ARGS_TYPE const v8::AccessorInfo & -# define _NAN_SETTER_ARGS _NAN_SETTER_ARGS_TYPE args -# define _NAN_SETTER_RETURN_TYPE void - -# define _NAN_PROPERTY_GETTER_ARGS_TYPE const v8::AccessorInfo& -# define _NAN_PROPERTY_GETTER_ARGS _NAN_PROPERTY_GETTER_ARGS_TYPE args -# define _NAN_PROPERTY_GETTER_RETURN_TYPE v8::Handle - -# define _NAN_PROPERTY_SETTER_ARGS_TYPE const v8::AccessorInfo& -# define _NAN_PROPERTY_SETTER_ARGS _NAN_PROPERTY_SETTER_ARGS_TYPE args -# define _NAN_PROPERTY_SETTER_RETURN_TYPE v8::Handle - -# define _NAN_PROPERTY_ENUMERATOR_ARGS_TYPE const v8::AccessorInfo& -# define _NAN_PROPERTY_ENUMERATOR_ARGS _NAN_PROPERTY_ENUMERATOR_ARGS_TYPE args -# define _NAN_PROPERTY_ENUMERATOR_RETURN_TYPE v8::Handle - -# define _NAN_PROPERTY_DELETER_ARGS_TYPE const v8::AccessorInfo& -# define _NAN_PROPERTY_DELETER_ARGS _NAN_PROPERTY_DELETER_ARGS_TYPE args -# define _NAN_PROPERTY_DELETER_RETURN_TYPE v8::Handle - -# define _NAN_PROPERTY_QUERY_ARGS_TYPE const v8::AccessorInfo& -# define _NAN_PROPERTY_QUERY_ARGS _NAN_PROPERTY_QUERY_ARGS_TYPE args -# define _NAN_PROPERTY_QUERY_RETURN_TYPE v8::Handle - -# define _NAN_INDEX_GETTER_ARGS_TYPE const v8::AccessorInfo& -# define _NAN_INDEX_GETTER_ARGS _NAN_INDEX_GETTER_ARGS_TYPE args -# define _NAN_INDEX_GETTER_RETURN_TYPE v8::Handle - -# define _NAN_INDEX_SETTER_ARGS_TYPE const v8::AccessorInfo& -# define _NAN_INDEX_SETTER_ARGS _NAN_INDEX_SETTER_ARGS_TYPE args -# define _NAN_INDEX_SETTER_RETURN_TYPE v8::Handle - -# define _NAN_INDEX_ENUMERATOR_ARGS_TYPE const v8::AccessorInfo& -# define _NAN_INDEX_ENUMERATOR_ARGS _NAN_INDEX_ENUMERATOR_ARGS_TYPE args -# define _NAN_INDEX_ENUMERATOR_RETURN_TYPE v8::Handle - -# define _NAN_INDEX_DELETER_ARGS_TYPE const v8::AccessorInfo& -# define _NAN_INDEX_DELETER_ARGS _NAN_INDEX_DELETER_ARGS_TYPE args -# define _NAN_INDEX_DELETER_RETURN_TYPE v8::Handle - -# define _NAN_INDEX_QUERY_ARGS_TYPE const v8::AccessorInfo& -# define _NAN_INDEX_QUERY_ARGS _NAN_INDEX_QUERY_ARGS_TYPE args -# define _NAN_INDEX_QUERY_RETURN_TYPE v8::Handle - -typedef v8::InvocationCallback NanFunctionCallback; - -# define NanUndefined() v8::Undefined() -# define NanNull() v8::Null() -# define NanTrue() v8::True() -# define NanFalse() v8::False() -# define NanAdjustExternalMemory(amount) \ - v8::V8::AdjustAmountOfExternalAllocatedMemory(amount) -# define NanSetTemplate(templ, name, value) templ->Set(name, value) -# define NanGetCurrentContext() v8::Context::GetCurrent() -# if NODE_VERSION_AT_LEAST(0, 8, 0) -# define NanMakeCallback(target, func, argc, argv) \ - node::MakeCallback(target, func, argc, argv) -# else -# define NanMakeCallback(target, func, argc, argv) \ - do { \ - v8::TryCatch try_catch; \ - func->Call(target, argc, argv); \ - if (try_catch.HasCaught()) { \ - v8::FatalException(try_catch); \ - } \ - } while (0) -# endif - -# define NanSymbol(value) v8::String::NewSymbol(value) - - template - NAN_INLINE v8::Local NanNew() { - return v8::Local::New(T::New()); - } - - template - NAN_INLINE v8::Local NanNew(v8::Handle arg) { - return v8::Local::New(arg); - } - - template - NAN_INLINE v8::Local NanNew( - v8::Handle receiver - , int argc - , v8::Handle argv[] = 0) { - return v8::Signature::New(receiver, argc, argv); - } - - template - NAN_INLINE v8::Local NanNew( - NanFunctionCallback callback - , v8::Handle data = v8::Handle() - , v8::Handle signature = v8::Handle()) { - return T::New(callback, data, signature); - } - - template - NAN_INLINE v8::Local NanNew(const v8::Persistent &arg) { - return v8::Local::New(arg); - } - - template - NAN_INLINE v8::Local NanNew(P arg) { - return v8::Local::New(T::New(arg)); - } - - template - NAN_INLINE v8::Local NanNew(P arg, int length) { - return v8::Local::New(T::New(arg, length)); - } - - template - NAN_INLINE v8::Local NanNew( - v8::Handle pattern, v8::RegExp::Flags flags) { - return v8::RegExp::New(pattern, flags); - } - - template - NAN_INLINE v8::Local NanNew( - v8::Local pattern, v8::RegExp::Flags flags) { - return v8::RegExp::New(pattern, flags); - } - - template - NAN_INLINE v8::Local NanNew( - v8::Handle pattern, v8::RegExp::Flags flags) { - return v8::RegExp::New(pattern, flags); - } - - template - NAN_INLINE v8::Local NanNew( - v8::Local pattern, v8::RegExp::Flags flags) { - return v8::RegExp::New(pattern, flags); - } - - template<> - NAN_INLINE v8::Local NanNew() { - return v8::Array::New(); - } - - template<> - NAN_INLINE v8::Local NanNew(int length) { - return v8::Array::New(length); - } - - - template<> - NAN_INLINE v8::Local NanNew(double time) { - return v8::Date::New(time).As(); - } - - template<> - NAN_INLINE v8::Local NanNew(int time) { - return v8::Date::New(time).As(); - } - - typedef v8::Script NanUnboundScript; - typedef v8::Script NanBoundScript; - - template - NAN_INLINE v8::Local NanNew( - P s - , const v8::ScriptOrigin& origin - ) { - return v8::Script::New(s, const_cast(&origin)); - } - - template<> - NAN_INLINE v8::Local NanNew( - v8::Local s - ) { - return v8::Script::New(s); - } - - NAN_INLINE v8::Local NanNew( - v8::String::ExternalStringResource *resource) { - return v8::String::NewExternal(resource); - } - - NAN_INLINE v8::Local NanNew( - v8::String::ExternalAsciiStringResource *resource) { - return v8::String::NewExternal(resource); - } - - template<> - NAN_INLINE v8::Local NanNew(bool value) { - return v8::BooleanObject::New(value).As(); - } - - template<> - NAN_INLINE v8::Local - NanNew >( - v8::Local value) { - return v8::StringObject::New(value).As(); - } - - template<> - NAN_INLINE v8::Local - NanNew >( - v8::Handle value) { - return v8::StringObject::New(value).As(); - } - - template<> - NAN_INLINE v8::Local NanNew(double val) { - return v8::NumberObject::New(val).As(); - } - - template<> - NAN_INLINE v8::Local NanNew(int32_t val) { - return v8::Uint32::NewFromUnsigned(val)->ToUint32(); - } - - template<> - NAN_INLINE v8::Local NanNew(uint32_t val) { - return v8::Uint32::NewFromUnsigned(val)->ToUint32(); - } - - template<> - NAN_INLINE v8::Local NanNew(int32_t val) { - return v8::Int32::New(val)->ToInt32(); - } - - template<> - NAN_INLINE v8::Local NanNew(uint32_t val) { - return v8::Int32::New(val)->ToInt32(); - } - - template<> - NAN_INLINE v8::Local NanNew( - uint8_t *arg - , int length) { - uint16_t *warg = new uint16_t[length]; - for (int i = 0; i < length; i++) { - warg[i] = arg[i]; - } - v8::Local retval = v8::String::New(warg, length); - delete[] warg; - return retval; - } - - template<> - NAN_INLINE v8::Local NanNew( - const uint8_t *arg - , int length) { - uint16_t *warg = new uint16_t[length]; - for (int i = 0; i < length; i++) { - warg[i] = arg[i]; - } - v8::Local retval = v8::String::New(warg, length); - delete[] warg; - return retval; - } - - template<> - NAN_INLINE v8::Local NanNew(uint8_t *arg) { - int length = strlen(reinterpret_cast(arg)); - uint16_t *warg = new uint16_t[length]; - for (int i = 0; i < length; i++) { - warg[i] = arg[i]; - } - - v8::Local retval = v8::String::New(warg, length); - delete[] warg; - return retval; - } - - template<> - NAN_INLINE v8::Local NanNew( - const uint8_t *arg) { - int length = strlen(reinterpret_cast(arg)); - uint16_t *warg = new uint16_t[length]; - for (int i = 0; i < length; i++) { - warg[i] = arg[i]; - } - v8::Local retval = v8::String::New(warg, length); - delete[] warg; - return retval; - } - - template<> - NAN_INLINE v8::Local NanNew() { - return v8::String::Empty(); - } - - NAN_INLINE void NanAddGCEpilogueCallback( - v8::GCEpilogueCallback callback - , v8::GCType gc_type_filter = v8::kGCTypeAll) { - v8::V8::AddGCEpilogueCallback(callback, gc_type_filter); - } - NAN_INLINE void NanRemoveGCEpilogueCallback( - v8::GCEpilogueCallback callback) { - v8::V8::RemoveGCEpilogueCallback(callback); - } - NAN_INLINE void NanAddGCPrologueCallback( - v8::GCPrologueCallback callback - , v8::GCType gc_type_filter = v8::kGCTypeAll) { - v8::V8::AddGCPrologueCallback(callback, gc_type_filter); - } - NAN_INLINE void NanRemoveGCPrologueCallback( - v8::GCPrologueCallback callback) { - v8::V8::RemoveGCPrologueCallback(callback); - } - NAN_INLINE void NanGetHeapStatistics( - v8::HeapStatistics *heap_statistics) { - v8::V8::GetHeapStatistics(heap_statistics); - } - - template - NAN_INLINE void NanAssignPersistent( - v8::Persistent& handle - , v8::Handle obj) { - handle.Dispose(); - handle = v8::Persistent::New(obj); - } - - template - struct _NanWeakCallbackInfo { - typedef void (*Callback)(v8::Persistent object, void* parameter); - _NanWeakCallbackInfo(v8::Handle handle, P* param, Callback cb) : - parameter(param) - , callback(cb) - , persistent(v8::Persistent::New(handle)) { } - - ~_NanWeakCallbackInfo() { - persistent.Dispose(); - persistent.Clear(); - } - - P* const parameter; - Callback const callback; - v8::Persistent persistent; - }; - - template - class _NanWeakCallbackData { - public: - _NanWeakCallbackData(_NanWeakCallbackInfo *info) - : info_(info) { } - - NAN_INLINE v8::Local GetValue() const { - return NanNew(info_->persistent); - } - NAN_INLINE P* GetParameter() const { return info_->parameter; } - NAN_INLINE void Revive() const { - info_->persistent.MakeWeak(info_, info_->callback); - } - NAN_INLINE void Dispose() const { - delete info_; - } - - private: - _NanWeakCallbackInfo* info_; - }; - -# define NanGetInternalFieldPointer(object, index) \ - object->GetPointerFromInternalField(index) -# define NanSetInternalFieldPointer(object, index, value) \ - object->SetPointerInInternalField(index, value) - -// do not use for declaration -# define NAN_WEAK_CALLBACK(name) \ - template \ - static void name( \ - v8::Persistent object, void *data) { \ - _NanWeakCallbackData wcbd( \ - static_cast<_NanWeakCallbackInfo*>(data)); \ - _Nan_Weak_Callback_ ## name(wcbd); \ - } \ - \ - template \ - NAN_INLINE void _Nan_Weak_Callback_ ## name( \ - const _NanWeakCallbackData &data) - - template - NAN_INLINE void NanMakeWeakPersistent( - v8::Handle handle - , P* parameter - , typename _NanWeakCallbackInfo::Callback callback) { - _NanWeakCallbackInfo *cbinfo = - new _NanWeakCallbackInfo(handle, parameter, callback); - cbinfo->persistent.MakeWeak(cbinfo, callback); - } - -# define NanScope() v8::HandleScope scope -# define NanEscapableScope() v8::HandleScope scope -# define NanEscapeScope(val) scope.Close(val) -# define NanLocker() v8::Locker locker -# define NanUnlocker() v8::Unlocker unlocker -# define NanReturnValue(value) return scope.Close(value) -# define NanReturnUndefined() return v8::Undefined() -# define NanReturnNull() return v8::Null() -# define NanReturnEmptyString() return v8::String::Empty() -# define NanObjectWrapHandle(obj) v8::Local::New(obj->handle_) - -# define _NAN_ERROR(fun, errmsg) \ - fun(v8::String::New(errmsg)) - -# define _NAN_THROW_ERROR(fun, errmsg) \ - do { \ - NanScope(); \ - return v8::Local::New( \ - v8::ThrowException(_NAN_ERROR(fun, errmsg))); \ - } while (0); - - NAN_INLINE v8::Local NanError(const char* errmsg) { - return _NAN_ERROR(v8::Exception::Error, errmsg); - } - - NAN_INLINE v8::Local NanThrowError(const char* errmsg) { - _NAN_THROW_ERROR(v8::Exception::Error, errmsg); - } - - NAN_INLINE v8::Local NanThrowError( - v8::Handle error - ) { - NanScope(); - return v8::Local::New(v8::ThrowException(error)); - } - - NAN_INLINE v8::Local NanError( - const char *msg - , const int errorNumber - ) { - v8::Local err = v8::Exception::Error(v8::String::New(msg)); - v8::Local obj = err.As(); - obj->Set(v8::String::New("code"), v8::Int32::New(errorNumber)); - return err; - } - - NAN_INLINE v8::Local NanThrowError( - const char *msg - , const int errorNumber - ) { - return NanThrowError(NanError(msg, errorNumber)); - } - - NAN_INLINE v8::Local NanTypeError(const char* errmsg) { - return _NAN_ERROR(v8::Exception::TypeError, errmsg); - } - - NAN_INLINE v8::Local NanThrowTypeError( - const char* errmsg - ) { - _NAN_THROW_ERROR(v8::Exception::TypeError, errmsg); - } - - NAN_INLINE v8::Local NanRangeError( - const char* errmsg - ) { - return _NAN_ERROR(v8::Exception::RangeError, errmsg); - } - - NAN_INLINE v8::Local NanThrowRangeError( - const char* errmsg - ) { - _NAN_THROW_ERROR(v8::Exception::RangeError, errmsg); - } - - template - NAN_INLINE void NanDisposePersistent( - v8::Persistent &handle) { // NOLINT(runtime/references) - handle.Dispose(); - handle.Clear(); - } - - NAN_INLINE v8::Local NanNewBufferHandle ( - char *data - , size_t length - , node::Buffer::free_callback callback - , void *hint - ) { - return NanNew( - node::Buffer::New(data, length, callback, hint)->handle_); - } - - NAN_INLINE v8::Local NanNewBufferHandle ( - const char *data - , uint32_t size - ) { -#if NODE_MODULE_VERSION >= 0x000B - return NanNew(node::Buffer::New(data, size)->handle_); -#else - return NanNew( - node::Buffer::New(const_cast(data), size)->handle_); -#endif - } - - NAN_INLINE v8::Local NanNewBufferHandle (uint32_t size) { - return NanNew(node::Buffer::New(size)->handle_); - } - - NAN_INLINE void FreeData(char *data, void *hint) { - delete[] data; - } - - NAN_INLINE v8::Local NanBufferUse( - char* data - , uint32_t size - ) { - return NanNew( - node::Buffer::New(data, size, FreeData, NULL)->handle_); - } - - NAN_INLINE bool NanHasInstance( - v8::Persistent& function_template - , v8::Handle value - ) { - return function_template->HasInstance(value); - } - - NAN_INLINE v8::Local NanNewContextHandle( - v8::ExtensionConfiguration* extensions = NULL - , v8::Handle tmpl = v8::Handle() - , v8::Handle obj = v8::Handle() - ) { - v8::Persistent ctx = v8::Context::New(extensions, tmpl, obj); - v8::Local lctx = NanNew(ctx); - ctx.Dispose(); - return lctx; - } - - NAN_INLINE v8::Local NanCompileScript( - v8::Local s - , const v8::ScriptOrigin& origin - ) { - return v8::Script::Compile(s, const_cast(&origin)); - } - - NAN_INLINE v8::Local NanCompileScript( - v8::Local s - ) { - return v8::Script::Compile(s); - } - - NAN_INLINE v8::Local NanRunScript(v8::Local script) { - return script->Run(); - } - -#endif // NODE_MODULE_VERSION - -typedef void (*NanFreeCallback)(char *data, void *hint); - -#define NAN_METHOD(name) _NAN_METHOD_RETURN_TYPE name(_NAN_METHOD_ARGS) -#define NAN_GETTER(name) \ - _NAN_GETTER_RETURN_TYPE name( \ - v8::Local property \ - , _NAN_GETTER_ARGS) -#define NAN_SETTER(name) \ - _NAN_SETTER_RETURN_TYPE name( \ - v8::Local property \ - , v8::Local value \ - , _NAN_SETTER_ARGS) -#define NAN_PROPERTY_GETTER(name) \ - _NAN_PROPERTY_GETTER_RETURN_TYPE name( \ - v8::Local property \ - , _NAN_PROPERTY_GETTER_ARGS) -#define NAN_PROPERTY_SETTER(name) \ - _NAN_PROPERTY_SETTER_RETURN_TYPE name( \ - v8::Local property \ - , v8::Local value \ - , _NAN_PROPERTY_SETTER_ARGS) -#define NAN_PROPERTY_ENUMERATOR(name) \ - _NAN_PROPERTY_ENUMERATOR_RETURN_TYPE name(_NAN_PROPERTY_ENUMERATOR_ARGS) -#define NAN_PROPERTY_DELETER(name) \ - _NAN_PROPERTY_DELETER_RETURN_TYPE name( \ - v8::Local property \ - , _NAN_PROPERTY_DELETER_ARGS) -#define NAN_PROPERTY_QUERY(name) \ - _NAN_PROPERTY_QUERY_RETURN_TYPE name( \ - v8::Local property \ - , _NAN_PROPERTY_QUERY_ARGS) -# define NAN_INDEX_GETTER(name) \ - _NAN_INDEX_GETTER_RETURN_TYPE name(uint32_t index, _NAN_INDEX_GETTER_ARGS) -#define NAN_INDEX_SETTER(name) \ - _NAN_INDEX_SETTER_RETURN_TYPE name( \ - uint32_t index \ - , v8::Local value \ - , _NAN_INDEX_SETTER_ARGS) -#define NAN_INDEX_ENUMERATOR(name) \ - _NAN_INDEX_ENUMERATOR_RETURN_TYPE name(_NAN_INDEX_ENUMERATOR_ARGS) -#define NAN_INDEX_DELETER(name) \ - _NAN_INDEX_DELETER_RETURN_TYPE name( \ - uint32_t index \ - , _NAN_INDEX_DELETER_ARGS) -#define NAN_INDEX_QUERY(name) \ - _NAN_INDEX_QUERY_RETURN_TYPE name(uint32_t index, _NAN_INDEX_QUERY_ARGS) - -class NanCallback { - public: - NanCallback() { - NanScope(); - v8::Local obj = NanNew(); - NanAssignPersistent(handle, obj); - } - - explicit NanCallback(const v8::Handle &fn) { - NanScope(); - v8::Local obj = NanNew(); - NanAssignPersistent(handle, obj); - SetFunction(fn); - } - - ~NanCallback() { - if (handle.IsEmpty()) return; - NanDisposePersistent(handle); - } - - NAN_INLINE void SetFunction(const v8::Handle &fn) { - NanScope(); - NanNew(handle)->Set(NanSymbol("callback"), fn); - } - - NAN_INLINE v8::Local GetFunction () { - return NanNew(handle)->Get(NanSymbol("callback")) - .As(); - } - - void Call(int argc, v8::Handle argv[]) { - NanScope(); -#if (NODE_MODULE_VERSION > 0x000B) // 0.11.12+ - v8::Local callback = NanNew(handle)-> - Get(NanSymbol("callback")).As(); - node::MakeCallback( - nan_isolate - , nan_isolate->GetCurrentContext()->Global() - , callback - , argc - , argv - ); -#else -#if NODE_VERSION_AT_LEAST(0, 8, 0) - v8::Local callback = NanNew(handle)-> - Get(NanSymbol("callback")).As(); - node::MakeCallback( - v8::Context::GetCurrent()->Global() - , callback - , argc - , argv - ); -#else - node::MakeCallback(handle, "callback", argc, argv); -#endif -#endif - } - - private: - v8::Persistent handle; -}; - -/* abstract */ class NanAsyncWorker { - public: - explicit NanAsyncWorker(NanCallback *callback) : callback(callback) { - request.data = this; - errmsg = NULL; - - NanScope(); - v8::Local obj = NanNew(); - NanAssignPersistent(persistentHandle, obj); - } - - virtual ~NanAsyncWorker() { - NanScope(); - - if (!persistentHandle.IsEmpty()) - NanDisposePersistent(persistentHandle); - if (callback) - delete callback; - if (errmsg) - delete errmsg; - } - - virtual void WorkComplete() { - NanScope(); - - if (errmsg == NULL) - HandleOKCallback(); - else - HandleErrorCallback(); - delete callback; - callback = NULL; - } - - NAN_INLINE void SaveToPersistent(const char *key, v8::Local &obj) { - v8::Local handle = NanNew(persistentHandle); - handle->Set(NanSymbol(key), obj); - } - - v8::Local GetFromPersistent(const char *key) { - NanEscapableScope(); - v8::Local handle = NanNew(persistentHandle); - return NanEscapeScope(handle->Get(NanSymbol(key)).As()); - } - - virtual void Execute() = 0; - - uv_work_t request; - - protected: - v8::Persistent persistentHandle; - NanCallback *callback; - const char *errmsg; - - virtual void HandleOKCallback() { - NanScope(); - - callback->Call(0, NULL); - } - - virtual void HandleErrorCallback() { - NanScope(); - - v8::Local argv[] = { - v8::Exception::Error(NanNew(errmsg)) - }; - callback->Call(1, argv); - } -}; - -NAN_INLINE void NanAsyncExecute (uv_work_t* req) { - NanAsyncWorker *worker = static_cast(req->data); - worker->Execute(); -} - -NAN_INLINE void NanAsyncExecuteComplete (uv_work_t* req) { - NanAsyncWorker* worker = static_cast(req->data); - worker->WorkComplete(); - delete worker; -} - -NAN_INLINE void NanAsyncQueueWorker (NanAsyncWorker* worker) { - uv_queue_work( - uv_default_loop() - , &worker->request - , NanAsyncExecute - , (uv_after_work_cb)NanAsyncExecuteComplete - ); -} - -//// Base 64 //// - -#define _nan_base64_encoded_size(size) ((size + 2 - ((size + 2) % 3)) / 3 * 4) - -// Doesn't check for padding at the end. Can be 1-2 bytes over. -NAN_INLINE size_t _nan_base64_decoded_size_fast(size_t size) { - size_t remainder = size % 4; - - size = (size / 4) * 3; - if (remainder) { - if (size == 0 && remainder == 1) { - // special case: 1-byte input cannot be decoded - size = 0; - } else { - // non-padded input, add 1 or 2 extra bytes - size += 1 + (remainder == 3); - } - } - - return size; -} - -template -NAN_INLINE size_t _nan_base64_decoded_size( - const T* src - , size_t size -) { - if (size == 0) - return 0; - - if (src[size - 1] == '=') - size--; - if (size > 0 && src[size - 1] == '=') - size--; - - return _nan_base64_decoded_size_fast(size); -} - -// supports regular and URL-safe base64 -static const int _nan_unbase64_table[] = { - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -1, -1, -2, -1, -1 - , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 - , -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 62, -1, 63 - , 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1 - , -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 - , 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, 63 - , -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 - , 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1 - , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 - , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 - , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 - , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 - , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 - , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 - , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 - , -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 -}; - -#define _nan_unbase64(x) _nan_unbase64_table[(uint8_t)(x)] - -template static size_t _nan_base64_decode( - char* buf - , size_t len - , const T* src - , const size_t srcLen -) { - char* dst = buf; - char* dstEnd = buf + len; - const T* srcEnd = src + srcLen; - - while (src < srcEnd && dst < dstEnd) { - ptrdiff_t remaining = srcEnd - src; - char a, b, c, d; - - while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--; - if (remaining == 0 || *src == '=') break; - a = _nan_unbase64(*src++); - - while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--; - if (remaining <= 1 || *src == '=') break; - b = _nan_unbase64(*src++); - - *dst++ = (a << 2) | ((b & 0x30) >> 4); - if (dst == dstEnd) break; - - while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--; - if (remaining <= 2 || *src == '=') break; - c = _nan_unbase64(*src++); - - *dst++ = ((b & 0x0F) << 4) | ((c & 0x3C) >> 2); - if (dst == dstEnd) break; - - while (_nan_unbase64(*src) < 0 && src < srcEnd) src++, remaining--; - if (remaining <= 3 || *src == '=') break; - d = _nan_unbase64(*src++); - - *dst++ = ((c & 0x03) << 6) | (d & 0x3F); - } - - return dst - buf; -} - -//// HEX //// - -template unsigned _nan_hex2bin(T c) { - if (c >= '0' && c <= '9') return c - '0'; - if (c >= 'A' && c <= 'F') return 10 + (c - 'A'); - if (c >= 'a' && c <= 'f') return 10 + (c - 'a'); - return static_cast(-1); -} - -template static size_t _nan_hex_decode( - char* buf - , size_t len - , const T* src - , const size_t srcLen -) { - size_t i; - for (i = 0; i < len && i * 2 + 1 < srcLen; ++i) { - unsigned a = _nan_hex2bin(src[i * 2 + 0]); - unsigned b = _nan_hex2bin(src[i * 2 + 1]); - if (!~a || !~b) return i; - buf[i] = a * 16 + b; - } - - return i; -} - -static bool _NanGetExternalParts( - v8::Handle val - , const char** data - , size_t* len -) { - if (node::Buffer::HasInstance(val)) { - *data = node::Buffer::Data(val.As()); - *len = node::Buffer::Length(val.As()); - return true; - } - - assert(val->IsString()); - v8::Local str = NanNew(val.As()); - - if (str->IsExternalAscii()) { - const v8::String::ExternalAsciiStringResource* ext; - ext = str->GetExternalAsciiStringResource(); - *data = ext->data(); - *len = ext->length(); - return true; - - } else if (str->IsExternal()) { - const v8::String::ExternalStringResource* ext; - ext = str->GetExternalStringResource(); - *data = reinterpret_cast(ext->data()); - *len = ext->length(); - return true; - } - - return false; -} - -namespace Nan { - enum Encoding {ASCII, UTF8, BASE64, UCS2, BINARY, HEX, BUFFER}; -} - -NAN_INLINE void* NanRawString( - v8::Handle from - , enum Nan::Encoding encoding - , size_t *datalen - , void *buf - , size_t buflen - , int flags -) { - NanScope(); - - size_t sz_; - size_t term_len = !(flags & v8::String::NO_NULL_TERMINATION); - char *data = NULL; - size_t len; - bool is_extern = _NanGetExternalParts( - from - , const_cast(&data) - , &len); - - if (is_extern && !term_len) { - NanSetPointerSafe(datalen, len); - return data; - } - - v8::Local toStr = from->ToString(); - - char *to = static_cast(buf); - - switch (encoding) { - case Nan::ASCII: -#if NODE_MODULE_VERSION < 0x000C - sz_ = toStr->Length(); - if (to == NULL) { - to = new char[sz_ + term_len]; - } else { - assert(buflen >= sz_ + term_len && "too small buffer"); - } - NanSetPointerSafe( - datalen - , toStr->WriteAscii(to, 0, static_cast(sz_ + term_len), flags)); - return to; -#endif - case Nan::BINARY: - case Nan::BUFFER: - sz_ = toStr->Length(); - if (to == NULL) { - to = new char[sz_ + term_len]; - } else { - assert(buflen >= sz_ + term_len && "too small buffer"); - } -#if NODE_MODULE_VERSION < 0x000C - { - uint16_t* twobytebuf = new uint16_t[sz_ + term_len]; - - size_t len = toStr->Write(twobytebuf, 0, - static_cast(sz_ + term_len), flags); - - for (size_t i = 0; i < sz_ + term_len && i < len + term_len; i++) { - unsigned char *b = reinterpret_cast(&twobytebuf[i]); - to[i] = *b; - } - - NanSetPointerSafe(datalen, len); - - delete[] twobytebuf; - return to; - } -#else - NanSetPointerSafe( - datalen, - toStr->WriteOneByte( - reinterpret_cast(to) - , 0 - , static_cast(sz_ + term_len) - , flags)); - return to; -#endif - case Nan::UTF8: - sz_ = toStr->Utf8Length(); - if (to == NULL) { - to = new char[sz_ + term_len]; - } else { - assert(buflen >= sz_ + term_len && "too small buffer"); - } - NanSetPointerSafe( - datalen - , toStr->WriteUtf8(to, static_cast(sz_ + term_len) - , NULL, flags) - - term_len); - return to; - case Nan::BASE64: - { - v8::String::Value value(toStr); - sz_ = _nan_base64_decoded_size(*value, value.length()); - if (to == NULL) { - to = new char[sz_ + term_len]; - } else { - assert(buflen >= sz_ + term_len); - } - NanSetPointerSafe( - datalen - , _nan_base64_decode(to, sz_, *value, value.length())); - if (term_len) { - to[sz_] = '\0'; - } - return to; - } - case Nan::UCS2: - { - sz_ = toStr->Length(); - if (to == NULL) { - to = new char[(sz_ + term_len) * 2]; - } else { - assert(buflen >= (sz_ + term_len) * 2 && "too small buffer"); - } - - int bc = 2 * toStr->Write( - reinterpret_cast(to) - , 0 - , static_cast(sz_ + term_len) - , flags); - NanSetPointerSafe(datalen, bc); - return to; - } - case Nan::HEX: - { - v8::String::Value value(toStr); - sz_ = value.length(); - assert(!(sz_ & 1) && "bad hex data"); - if (to == NULL) { - to = new char[sz_ / 2 + term_len]; - } else { - assert(buflen >= sz_ / 2 + term_len && "too small buffer"); - } - NanSetPointerSafe( - datalen - , _nan_hex_decode(to, sz_ / 2, *value, value.length())); - } - if (term_len) { - to[sz_ / 2] = '\0'; - } - return to; - default: - assert(0 && "unknown encoding"); - } - return to; -} - -NAN_INLINE char* NanCString( - v8::Handle from - , size_t *datalen - , char *buf = NULL - , size_t buflen = 0 - , int flags = v8::String::NO_OPTIONS -) { - return static_cast( - NanRawString(from, Nan::UTF8, datalen, buf, buflen, flags) - ); -} - -#endif // NAN_H_ diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/nan/package.json b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/nan/package.json deleted file mode 100644 index ef8e9060b3..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/nan/package.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "name": "nan", - "version": "1.0.0", - "description": "Native Abstractions for Node.js: C++ header for Node 0.8->0.12 compatibility", - "main": "include_dirs.js", - "repository": { - "type": "git", - "url": "git://github.com/rvagg/nan.git" - }, - "contributors": [ - { - "name": "Rod Vagg", - "email": "r@va.gg", - "url": "https://github.com/rvagg" - }, - { - "name": "Benjamin Byholm", - "email": "bbyholm@abo.fi", - "url": "https://github.com/kkoopa/" - }, - { - "name": "Trevor Norris", - "email": "trev.norris@gmail.com", - "url": "https://github.com/trevnorris" - }, - { - "name": "Nathan Rajlich", - "email": "nathan@tootallnate.net", - "url": "https://github.com/TooTallNate" - }, - { - "name": "Brett Lawson", - "email": "brett19@gmail.com", - "url": "https://github.com/brett19" - }, - { - "name": "Ben Noordhuis", - "email": "info@bnoordhuis.nl", - "url": "https://github.com/bnoordhuis" - } - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/rvagg/nan/issues" - }, - "homepage": "https://github.com/rvagg/nan", - "_id": "nan@1.0.0", - "dist": { - "shasum": "ae24f8850818d662fcab5acf7f3b95bfaa2ccf38", - "tarball": "http://registry.npmjs.org/nan/-/nan-1.0.0.tgz" - }, - "_from": "nan@~1.0.0", - "_npmVersion": "1.4.3", - "_npmUser": { - "name": "rvagg", - "email": "rod@vagg.org" - }, - "maintainers": [ - { - "name": "rvagg", - "email": "rod@vagg.org" - } - ], - "directories": {}, - "_shasum": "ae24f8850818d662fcab5acf7f3b95bfaa2ccf38", - "_resolved": "https://registry.npmjs.org/nan/-/nan-1.0.0.tgz", - "readme": "ERROR: No README data found!" -} diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/options/.npmignore b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/options/.npmignore deleted file mode 100644 index 1b18fb395a..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/options/.npmignore +++ /dev/null @@ -1,7 +0,0 @@ -npm-debug.log -node_modules -.*.swp -.lock-* -build/ - -test diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/options/Makefile b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/options/Makefile deleted file mode 100644 index 7496b6fcc5..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/options/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -ALL_TESTS = $(shell find test/ -name '*.test.js') - -run-tests: - @./node_modules/.bin/mocha \ - -t 2000 \ - $(TESTFLAGS) \ - $(TESTS) - -test: - @$(MAKE) NODE_PATH=lib TESTS="$(ALL_TESTS)" run-tests - -.PHONY: test diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/options/README.md b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/options/README.md deleted file mode 100644 index 0dabc7551c..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/options/README.md +++ /dev/null @@ -1,69 +0,0 @@ -# options.js # - -A very light-weight in-code option parsers for node.js. - -## Usage ## - -``` js -var Options = require("options"); - -// Create an Options object -function foo(options) { - var default_options = { - foo : "bar" - }; - - // Create an option object with default value - var opts = new Options(default_options); - - // Merge options - opts = opts.merge(options); - - // Reset to default value - opts.reset(); - - // Copy selected attributes out - var seled_att = opts.copy("foo"); - - // Read json options from a file. - opts.read("options.file"); // Sync - opts.read("options.file", function(err){ // Async - if(err){ // If error occurs - console.log("File error."); - }else{ - // No error - } - }); - - // Attributes defined or not - opts.isDefinedAndNonNull("foobar"); - opts.isDefined("foobar"); -} - -``` - - -## License ## - -(The MIT License) - -Copyright (c) 2012 Einar Otto Stangvik <einaros@gmail.com> - -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. diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/options/lib/options.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/options/lib/options.js deleted file mode 100644 index 4fc45e90a8..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/options/lib/options.js +++ /dev/null @@ -1,86 +0,0 @@ -/*! - * Copyright(c) 2011 Einar Otto Stangvik - * MIT Licensed - */ - -var fs = require('fs'); - -function Options(defaults) { - var internalValues = {}; - var values = this.value = {}; - Object.keys(defaults).forEach(function(key) { - internalValues[key] = defaults[key]; - Object.defineProperty(values, key, { - get: function() { return internalValues[key]; }, - configurable: false, - enumerable: true - }); - }); - this.reset = function() { - Object.keys(defaults).forEach(function(key) { - internalValues[key] = defaults[key]; - }); - return this; - }; - this.merge = function(options, required) { - options = options || {}; - if (Object.prototype.toString.call(required) === '[object Array]') { - var missing = []; - for (var i = 0, l = required.length; i < l; ++i) { - var key = required[i]; - if (!(key in options)) { - missing.push(key); - } - } - if (missing.length > 0) { - if (missing.length > 1) { - throw new Error('options ' + - missing.slice(0, missing.length - 1).join(', ') + ' and ' + - missing[missing.length - 1] + ' must be defined'); - } - else throw new Error('option ' + missing[0] + ' must be defined'); - } - } - Object.keys(options).forEach(function(key) { - if (key in internalValues) { - internalValues[key] = options[key]; - } - }); - return this; - }; - this.copy = function(keys) { - var obj = {}; - Object.keys(defaults).forEach(function(key) { - if (keys.indexOf(key) !== -1) { - obj[key] = values[key]; - } - }); - return obj; - }; - this.read = function(filename, cb) { - if (typeof cb == 'function') { - var self = this; - fs.readFile(filename, function(error, data) { - if (error) return cb(error); - var conf = JSON.parse(data); - self.merge(conf); - cb(); - }); - } - else { - var conf = JSON.parse(fs.readFileSync(filename)); - this.merge(conf); - } - return this; - }; - this.isDefined = function(key) { - return typeof values[key] != 'undefined'; - }; - this.isDefinedAndNonNull = function(key) { - return typeof values[key] != 'undefined' && values[key] !== null; - }; - Object.freeze(values); - Object.freeze(this); -} - -module.exports = Options; diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/options/package.json b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/options/package.json deleted file mode 100644 index 7a62d8e3c5..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/options/package.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "author": { - "name": "Einar Otto Stangvik", - "email": "einaros@gmail.com", - "url": "http://2x.io" - }, - "name": "options", - "description": "A very light-weight in-code option parsers for node.js.", - "version": "0.0.6", - "repository": { - "type": "git", - "url": "git://github.com/einaros/options.js.git" - }, - "main": "lib/options", - "scripts": { - "test": "make test" - }, - "engines": { - "node": ">=0.4.0" - }, - "dependencies": {}, - "devDependencies": { - "mocha": "latest" - }, - "gitHead": "ff53d0a092c897cb95964232a96fe17da65c11af", - "bugs": { - "url": "https://github.com/einaros/options.js/issues" - }, - "homepage": "https://github.com/einaros/options.js", - "_id": "options@0.0.6", - "_shasum": "ec22d312806bb53e731773e7cdaefcf1c643128f", - "_from": "options@>=0.0.5", - "_npmVersion": "1.4.21", - "_npmUser": { - "name": "einaros", - "email": "einaros@gmail.com" - }, - "maintainers": [ - { - "name": "einaros", - "email": "einaros@gmail.com" - } - ], - "dist": { - "shasum": "ec22d312806bb53e731773e7cdaefcf1c643128f", - "tarball": "http://registry.npmjs.org/options/-/options-0.0.6.tgz" - }, - "directories": {}, - "_resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", - "readme": "ERROR: No README data found!" -} diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/tinycolor/.gitignore b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/tinycolor/.gitignore deleted file mode 100644 index 6bfffbb79b..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/tinycolor/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -npm-debug.log -node_modules -.*.swp -.lock-* -build/ diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/tinycolor/README.md b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/tinycolor/README.md deleted file mode 100644 index 55eb3c110a..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/tinycolor/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# tinycolor # - -This is a no-fuzz, barebone, zero muppetry color module for node.js. \ No newline at end of file diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/tinycolor/example.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/tinycolor/example.js deleted file mode 100644 index f754046854..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/tinycolor/example.js +++ /dev/null @@ -1,3 +0,0 @@ -require('./tinycolor'); -console.log('this should be red and have an underline!'.grey.underline); -console.log('this should have a blue background!'.bgBlue); \ No newline at end of file diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/tinycolor/package.json b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/tinycolor/package.json deleted file mode 100644 index de79f18307..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/tinycolor/package.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "author": { - "name": "Einar Otto Stangvik", - "email": "einaros@gmail.com", - "url": "http://2x.io" - }, - "name": "tinycolor", - "description": "a to-the-point color module for node", - "version": "0.0.1", - "repository": { - "type": "git", - "url": "git://github.com/einaros/tinycolor.git" - }, - "engines": { - "node": ">=0.4.0" - }, - "dependencies": {}, - "devDependencies": {}, - "main": "tinycolor", - "_npmUser": { - "name": "einaros", - "email": "einaros@gmail.com" - }, - "_id": "tinycolor@0.0.1", - "_engineSupported": true, - "_npmVersion": "1.1.0-alpha-6", - "_nodeVersion": "v0.6.5", - "_defaultsLoaded": true, - "dist": { - "shasum": "320b5a52d83abb5978d81a3e887d4aefb15a6164", - "tarball": "http://registry.npmjs.org/tinycolor/-/tinycolor-0.0.1.tgz" - }, - "maintainers": [ - { - "name": "einaros", - "email": "einaros@gmail.com" - } - ], - "directories": {}, - "_shasum": "320b5a52d83abb5978d81a3e887d4aefb15a6164", - "_from": "tinycolor@0.x", - "_resolved": "https://registry.npmjs.org/tinycolor/-/tinycolor-0.0.1.tgz", - "bugs": { - "url": "https://github.com/einaros/tinycolor/issues" - }, - "readme": "ERROR: No README data found!", - "homepage": "https://github.com/einaros/tinycolor", - "scripts": {} -} diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/tinycolor/tinycolor.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/tinycolor/tinycolor.js deleted file mode 100644 index 36e552c4cc..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/node_modules/tinycolor/tinycolor.js +++ /dev/null @@ -1,31 +0,0 @@ -var styles = { - 'bold': ['\033[1m', '\033[22m'], - 'italic': ['\033[3m', '\033[23m'], - 'underline': ['\033[4m', '\033[24m'], - 'inverse': ['\033[7m', '\033[27m'], - 'black': ['\033[30m', '\033[39m'], - 'red': ['\033[31m', '\033[39m'], - 'green': ['\033[32m', '\033[39m'], - 'yellow': ['\033[33m', '\033[39m'], - 'blue': ['\033[34m', '\033[39m'], - 'magenta': ['\033[35m', '\033[39m'], - 'cyan': ['\033[36m', '\033[39m'], - 'white': ['\033[37m', '\033[39m'], - 'default': ['\033[39m', '\033[39m'], - 'grey': ['\033[90m', '\033[39m'], - 'bgBlack': ['\033[40m', '\033[49m'], - 'bgRed': ['\033[41m', '\033[49m'], - 'bgGreen': ['\033[42m', '\033[49m'], - 'bgYellow': ['\033[43m', '\033[49m'], - 'bgBlue': ['\033[44m', '\033[49m'], - 'bgMagenta': ['\033[45m', '\033[49m'], - 'bgCyan': ['\033[46m', '\033[49m'], - 'bgWhite': ['\033[47m', '\033[49m'], - 'bgDefault': ['\033[49m', '\033[49m'] -} -Object.keys(styles).forEach(function(style) { - Object.defineProperty(String.prototype, style, { - get: function() { return styles[style][0] + this + styles[style][1]; }, - enumerable: false - }); -}); diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/package.json b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/package.json deleted file mode 100644 index 63c4b393ce..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/package.json +++ /dev/null @@ -1,82 +0,0 @@ -{ - "author": { - "name": "Einar Otto Stangvik", - "email": "einaros@gmail.com", - "url": "http://2x.io" - }, - "name": "ws", - "description": "simple to use, blazing fast and thoroughly tested websocket client, server and console for node.js, up-to-date against RFC-6455", - "version": "0.4.32", - "keywords": [ - "Hixie", - "HyBi", - "Push", - "RFC-6455", - "WebSocket", - "WebSockets", - "real-time" - ], - "repository": { - "type": "git", - "url": "git://github.com/einaros/ws.git" - }, - "bin": { - "wscat": "./bin/wscat" - }, - "scripts": { - "test": "make test", - "install": "(node-gyp rebuild 2> builderror.log) || (exit 0)" - }, - "engines": { - "node": ">=0.4.0" - }, - "dependencies": { - "commander": "~2.1.0", - "nan": "~1.0.0", - "tinycolor": "0.x", - "options": ">=0.0.5" - }, - "devDependencies": { - "mocha": "1.12.0", - "should": "1.2.x", - "expect.js": "0.2.x", - "benchmark": "0.3.x", - "ansi": "latest" - }, - "browser": "./lib/browser.js", - "component": { - "scripts": { - "ws/index.js": "./lib/browser.js" - } - }, - "gypfile": true, - "bugs": { - "url": "https://github.com/einaros/ws/issues" - }, - "homepage": "https://github.com/einaros/ws", - "_id": "ws@0.4.32", - "_shasum": "787a6154414f3c99ed83c5772153b20feb0cec32", - "_from": "ws@0.4.x", - "_npmVersion": "1.4.10", - "_npmUser": { - "name": "V1", - "email": "info@3rd-Eden.com" - }, - "maintainers": [ - { - "name": "einaros", - "email": "einaros@gmail.com" - }, - { - "name": "V1", - "email": "info@3rd-Eden.com" - } - ], - "dist": { - "shasum": "787a6154414f3c99ed83c5772153b20feb0cec32", - "tarball": "http://registry.npmjs.org/ws/-/ws-0.4.32.tgz" - }, - "directories": {}, - "_resolved": "https://registry.npmjs.org/ws/-/ws-0.4.32.tgz", - "readme": "ERROR: No README data found!" -} diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/src/bufferutil.cc b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/src/bufferutil.cc deleted file mode 100644 index 7f99bd6b26..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/src/bufferutil.cc +++ /dev/null @@ -1,117 +0,0 @@ -/*! - * ws: a node.js websocket client - * Copyright(c) 2011 Einar Otto Stangvik - * MIT Licensed - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include "nan.h" - -using namespace v8; -using namespace node; - -class BufferUtil : public ObjectWrap -{ -public: - - static void Initialize(v8::Handle target) - { - NanScope(); - Local t = NanNew(New); - t->InstanceTemplate()->SetInternalFieldCount(1); - NODE_SET_METHOD(t, "unmask", BufferUtil::Unmask); - NODE_SET_METHOD(t, "mask", BufferUtil::Mask); - NODE_SET_METHOD(t, "merge", BufferUtil::Merge); - target->Set(NanSymbol("BufferUtil"), t->GetFunction()); - } - -protected: - - static NAN_METHOD(New) - { - NanScope(); - BufferUtil* bufferUtil = new BufferUtil(); - bufferUtil->Wrap(args.This()); - NanReturnValue(args.This()); - } - - static NAN_METHOD(Merge) - { - NanScope(); - Local bufferObj = args[0]->ToObject(); - char* buffer = Buffer::Data(bufferObj); - Local array = Local::Cast(args[1]); - unsigned int arrayLength = array->Length(); - size_t offset = 0; - unsigned int i; - for (i = 0; i < arrayLength; ++i) { - Local src = array->Get(i)->ToObject(); - size_t length = Buffer::Length(src); - memcpy(buffer + offset, Buffer::Data(src), length); - offset += length; - } - NanReturnValue(NanTrue()); - } - - static NAN_METHOD(Unmask) - { - NanScope(); - Local buffer_obj = args[0]->ToObject(); - size_t length = Buffer::Length(buffer_obj); - Local mask_obj = args[1]->ToObject(); - unsigned int *mask = (unsigned int*)Buffer::Data(mask_obj); - unsigned int* from = (unsigned int*)Buffer::Data(buffer_obj); - size_t len32 = length / 4; - unsigned int i; - for (i = 0; i < len32; ++i) *(from + i) ^= *mask; - from += i; - switch (length % 4) { - case 3: *((unsigned char*)from+2) = *((unsigned char*)from+2) ^ ((unsigned char*)mask)[2]; - case 2: *((unsigned char*)from+1) = *((unsigned char*)from+1) ^ ((unsigned char*)mask)[1]; - case 1: *((unsigned char*)from ) = *((unsigned char*)from ) ^ ((unsigned char*)mask)[0]; - case 0:; - } - NanReturnValue(NanTrue()); - } - - static NAN_METHOD(Mask) - { - NanScope(); - Local buffer_obj = args[0]->ToObject(); - Local mask_obj = args[1]->ToObject(); - unsigned int *mask = (unsigned int*)Buffer::Data(mask_obj); - Local output_obj = args[2]->ToObject(); - unsigned int dataOffset = args[3]->Int32Value(); - unsigned int length = args[4]->Int32Value(); - unsigned int* to = (unsigned int*)(Buffer::Data(output_obj) + dataOffset); - unsigned int* from = (unsigned int*)Buffer::Data(buffer_obj); - unsigned int len32 = length / 4; - unsigned int i; - for (i = 0; i < len32; ++i) *(to + i) = *(from + i) ^ *mask; - to += i; - from += i; - switch (length % 4) { - case 3: *((unsigned char*)to+2) = *((unsigned char*)from+2) ^ *((unsigned char*)mask+2); - case 2: *((unsigned char*)to+1) = *((unsigned char*)from+1) ^ *((unsigned char*)mask+1); - case 1: *((unsigned char*)to ) = *((unsigned char*)from ) ^ *((unsigned char*)mask); - case 0:; - } - NanReturnValue(NanTrue()); - } -}; - -extern "C" void init (Handle target) -{ - NanScope(); - BufferUtil::Initialize(target); -} - -NODE_MODULE(bufferutil, init) - diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/src/validation.cc b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/src/validation.cc deleted file mode 100644 index 0d9e242ad6..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/ws/src/validation.cc +++ /dev/null @@ -1,145 +0,0 @@ -/*! - * ws: a node.js websocket client - * Copyright(c) 2011 Einar Otto Stangvik - * MIT Licensed - */ - -#include -#include -#include -#include -#include -#include -#include -#include "nan.h" - -using namespace v8; -using namespace node; - -#define UNI_SUR_HIGH_START (uint32_t) 0xD800 -#define UNI_SUR_LOW_END (uint32_t) 0xDFFF -#define UNI_REPLACEMENT_CHAR (uint32_t) 0x0000FFFD -#define UNI_MAX_LEGAL_UTF32 (uint32_t) 0x0010FFFF - -static const uint8_t trailingBytesForUTF8[256] = { - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, 3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 -}; - -static const uint32_t offsetsFromUTF8[6] = { - 0x00000000, 0x00003080, 0x000E2080, - 0x03C82080, 0xFA082080, 0x82082080 -}; - -static int isLegalUTF8(const uint8_t *source, const int length) -{ - uint8_t a; - const uint8_t *srcptr = source+length; - switch (length) { - default: return 0; - /* Everything else falls through when "true"... */ - /* RFC3629 makes 5 & 6 bytes UTF-8 illegal - case 6: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0; - case 5: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0; */ - case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0; - case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return 0; - case 2: if ((a = (*--srcptr)) > 0xBF) return 0; - switch (*source) { - /* no fall-through in this inner switch */ - case 0xE0: if (a < 0xA0) return 0; break; - case 0xED: if (a > 0x9F) return 0; break; - case 0xF0: if (a < 0x90) return 0; break; - case 0xF4: if (a > 0x8F) return 0; break; - default: if (a < 0x80) return 0; - } - - case 1: if (*source >= 0x80 && *source < 0xC2) return 0; - } - if (*source > 0xF4) return 0; - return 1; -} - -int is_valid_utf8 (size_t len, char *value) -{ - /* is the string valid UTF-8? */ - for (unsigned int i = 0; i < len; i++) { - uint32_t ch = 0; - uint8_t extrabytes = trailingBytesForUTF8[(uint8_t) value[i]]; - - if (extrabytes + i >= len) - return 0; - - if (isLegalUTF8 ((uint8_t *) (value + i), extrabytes + 1) == 0) return 0; - - switch (extrabytes) { - case 5 : ch += (uint8_t) value[i++]; ch <<= 6; - case 4 : ch += (uint8_t) value[i++]; ch <<= 6; - case 3 : ch += (uint8_t) value[i++]; ch <<= 6; - case 2 : ch += (uint8_t) value[i++]; ch <<= 6; - case 1 : ch += (uint8_t) value[i++]; ch <<= 6; - case 0 : ch += (uint8_t) value[i]; - } - - ch -= offsetsFromUTF8[extrabytes]; - - if (ch <= UNI_MAX_LEGAL_UTF32) { - if (ch >= UNI_SUR_HIGH_START && ch <= UNI_SUR_LOW_END) - return 0; - } else { - return 0; - } - } - - return 1; -} - -class Validation : public ObjectWrap -{ -public: - - static void Initialize(v8::Handle target) - { - NanScope(); - Local t = NanNew(New); - t->InstanceTemplate()->SetInternalFieldCount(1); - NODE_SET_METHOD(t, "isValidUTF8", Validation::IsValidUTF8); - target->Set(NanSymbol("Validation"), t->GetFunction()); - } - -protected: - - static NAN_METHOD(New) - { - NanScope(); - Validation* validation = new Validation(); - validation->Wrap(args.This()); - NanReturnValue(args.This()); - } - - static NAN_METHOD(IsValidUTF8) - { - NanScope(); - if (!Buffer::HasInstance(args[0])) { - return NanThrowTypeError("First argument needs to be a buffer"); - } - Local buffer_obj = args[0]->ToObject(); - char *buffer_data = Buffer::Data(buffer_obj); - size_t buffer_length = Buffer::Length(buffer_obj); - NanReturnValue(is_valid_utf8(buffer_length, buffer_data) == 1 ? NanTrue() : NanFalse()); - } -}; - -extern "C" void init (Handle target) -{ - NanScope(); - Validation::Initialize(target); -} - -NODE_MODULE(validation, init) - diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/README.md b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/README.md deleted file mode 100644 index 22aab8bdc9..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# node-XMLHttpRequest # - -node-XMLHttpRequest is a wrapper for the built-in http client to emulate the -browser XMLHttpRequest object. - -This can be used with JS designed for browsers to improve reuse of code and -allow the use of existing libraries. - -Note: This library currently conforms to [XMLHttpRequest 1](http://www.w3.org/TR/XMLHttpRequest/). Version 2.0 will target [XMLHttpRequest Level 2](http://www.w3.org/TR/XMLHttpRequest2/). - -## Usage ## - -Here's how to include the module in your project and use as the browser-based -XHR object. - - var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest; - var xhr = new XMLHttpRequest(); - -Note: use the lowercase string "xmlhttprequest" in your require(). On -case-sensitive systems (eg Linux) using uppercase letters won't work. - -## Versions ## - -Prior to 1.4.0 version numbers were arbitrary. From 1.4.0 on they conform to -the standard major.minor.bugfix. 1.x shouldn't necessarily be considered -stable just because it's above 0.x. - -Since the XMLHttpRequest API is stable this library's API is stable as -well. Major version numbers indicate significant core code changes. -Minor versions indicate minor core code changes or better conformity to -the W3C spec. - -## Supports ## - -* Async and synchronous requests -* GET, POST, PUT, and DELETE requests -* All spec methods (open, send, abort, getRequestHeader, - getAllRequestHeaders, event methods) -* Requests to all domains - -## Known Issues / Missing Features ## - -For a list of open issues or to report your own visit the [github issues -page](https://github.com/driverdan/node-XMLHttpRequest/issues). - -* Local file access may have unexpected results for non-UTF8 files -* Synchronous requests don't set headers properly -* Synchronous requests freeze node while waiting for response (But that's what you want, right? Stick with async!). -* Some events are missing, such as abort -* getRequestHeader is case-sensitive -* Cookies aren't persisted between requests -* Missing XML support -* Missing basic auth diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/autotest.watchr b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/autotest.watchr deleted file mode 100644 index 5324db6cdd..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/autotest.watchr +++ /dev/null @@ -1,8 +0,0 @@ -def run_all_tests - puts `clear` - puts `node tests/test-constants.js` - puts `node tests/test-headers.js` - puts `node tests/test-request.js` -end -watch('.*.js') { run_all_tests } -run_all_tests diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/example/demo.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/example/demo.js deleted file mode 100644 index 4f333de934..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/example/demo.js +++ /dev/null @@ -1,16 +0,0 @@ -var sys = require('util'); -var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest; - -var xhr = new XMLHttpRequest(); - -xhr.onreadystatechange = function() { - sys.puts("State: " + this.readyState); - - if (this.readyState == 4) { - sys.puts("Complete.\nBody length: " + this.responseText.length); - sys.puts("Body:\n" + this.responseText); - } -}; - -xhr.open("GET", "http://driverdan.com"); -xhr.send(); diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/lib/XMLHttpRequest.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/lib/XMLHttpRequest.js deleted file mode 100644 index 214a2e3b5b..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/lib/XMLHttpRequest.js +++ /dev/null @@ -1,548 +0,0 @@ -/** - * Wrapper for built-in http.js to emulate the browser XMLHttpRequest object. - * - * This can be used with JS designed for browsers to improve reuse of code and - * allow the use of existing libraries. - * - * Usage: include("XMLHttpRequest.js") and use XMLHttpRequest per W3C specs. - * - * @author Dan DeFelippi - * @contributor David Ellis - * @license MIT - */ - -var Url = require("url") - , spawn = require("child_process").spawn - , fs = require('fs'); - -exports.XMLHttpRequest = function() { - /** - * Private variables - */ - var self = this; - var http = require('http'); - var https = require('https'); - - // Holds http.js objects - var client; - var request; - var response; - - // Request settings - var settings = {}; - - // Set some default headers - var defaultHeaders = { - "User-Agent": "node-XMLHttpRequest", - "Accept": "*/*", - }; - - var headers = defaultHeaders; - - // These headers are not user setable. - // The following are allowed but banned in the spec: - // * user-agent - var forbiddenRequestHeaders = [ - "accept-charset", - "accept-encoding", - "access-control-request-headers", - "access-control-request-method", - "connection", - "content-length", - "content-transfer-encoding", - "cookie", - "cookie2", - "date", - "expect", - "host", - "keep-alive", - "origin", - "referer", - "te", - "trailer", - "transfer-encoding", - "upgrade", - "via" - ]; - - // These request methods are not allowed - var forbiddenRequestMethods = [ - "TRACE", - "TRACK", - "CONNECT" - ]; - - // Send flag - var sendFlag = false; - // Error flag, used when errors occur or abort is called - var errorFlag = false; - - // Event listeners - var listeners = {}; - - /** - * Constants - */ - - this.UNSENT = 0; - this.OPENED = 1; - this.HEADERS_RECEIVED = 2; - this.LOADING = 3; - this.DONE = 4; - - /** - * Public vars - */ - - // Current state - this.readyState = this.UNSENT; - - // default ready state change handler in case one is not set or is set late - this.onreadystatechange = null; - - // Result & response - this.responseText = ""; - this.responseXML = ""; - this.status = null; - this.statusText = null; - - /** - * Private methods - */ - - /** - * Check if the specified header is allowed. - * - * @param string header Header to validate - * @return boolean False if not allowed, otherwise true - */ - var isAllowedHttpHeader = function(header) { - return (header && forbiddenRequestHeaders.indexOf(header.toLowerCase()) === -1); - }; - - /** - * Check if the specified method is allowed. - * - * @param string method Request method to validate - * @return boolean False if not allowed, otherwise true - */ - var isAllowedHttpMethod = function(method) { - return (method && forbiddenRequestMethods.indexOf(method) === -1); - }; - - /** - * Public methods - */ - - /** - * Open the connection. Currently supports local server requests. - * - * @param string method Connection method (eg GET, POST) - * @param string url URL for the connection. - * @param boolean async Asynchronous connection. Default is true. - * @param string user Username for basic authentication (optional) - * @param string password Password for basic authentication (optional) - */ - this.open = function(method, url, async, user, password) { - this.abort(); - errorFlag = false; - - // Check for valid request method - if (!isAllowedHttpMethod(method)) { - throw "SecurityError: Request method not allowed"; - return; - } - - settings = { - "method": method, - "url": url.toString(), - "async": (typeof async !== "boolean" ? true : async), - "user": user || null, - "password": password || null - }; - - setState(this.OPENED); - }; - - /** - * Sets a header for the request. - * - * @param string header Header name - * @param string value Header value - */ - this.setRequestHeader = function(header, value) { - if (this.readyState != this.OPENED) { - throw "INVALID_STATE_ERR: setRequestHeader can only be called when state is OPEN"; - } - if (!isAllowedHttpHeader(header)) { - console.warn('Refused to set unsafe header "' + header + '"'); - return; - } - if (sendFlag) { - throw "INVALID_STATE_ERR: send flag is true"; - } - headers[header] = value; - }; - - /** - * Gets a header from the server response. - * - * @param string header Name of header to get. - * @return string Text of the header or null if it doesn't exist. - */ - this.getResponseHeader = function(header) { - if (typeof header === "string" - && this.readyState > this.OPENED - && response.headers[header.toLowerCase()] - && !errorFlag - ) { - return response.headers[header.toLowerCase()]; - } - - return null; - }; - - /** - * Gets all the response headers. - * - * @return string A string with all response headers separated by CR+LF - */ - this.getAllResponseHeaders = function() { - if (this.readyState < this.HEADERS_RECEIVED || errorFlag) { - return ""; - } - var result = ""; - - for (var i in response.headers) { - // Cookie headers are excluded - if (i !== "set-cookie" && i !== "set-cookie2") { - result += i + ": " + response.headers[i] + "\r\n"; - } - } - return result.substr(0, result.length - 2); - }; - - /** - * Gets a request header - * - * @param string name Name of header to get - * @return string Returns the request header or empty string if not set - */ - this.getRequestHeader = function(name) { - // @TODO Make this case insensitive - if (typeof name === "string" && headers[name]) { - return headers[name]; - } - - return ""; - } - - /** - * Sends the request to the server. - * - * @param string data Optional data to send as request body. - */ - this.send = function(data) { - if (this.readyState != this.OPENED) { - throw "INVALID_STATE_ERR: connection must be opened before send() is called"; - } - - if (sendFlag) { - throw "INVALID_STATE_ERR: send has already been called"; - } - - var ssl = false, local = false; - var url = Url.parse(settings.url); - - // Determine the server - switch (url.protocol) { - case 'https:': - ssl = true; - // SSL & non-SSL both need host, no break here. - case 'http:': - var host = url.hostname; - break; - - case 'file:': - local = true; - break; - - case undefined: - case '': - var host = "localhost"; - break; - - default: - throw "Protocol not supported."; - } - - // Load files off the local filesystem (file://) - if (local) { - if (settings.method !== "GET") { - throw "XMLHttpRequest: Only GET method is supported"; - } - - if (settings.async) { - fs.readFile(url.pathname, 'utf8', function(error, data) { - if (error) { - self.handleError(error); - } else { - self.status = 200; - self.responseText = data; - setState(self.DONE); - } - }); - } else { - try { - this.responseText = fs.readFileSync(url.pathname, 'utf8'); - this.status = 200; - setState(self.DONE); - } catch(e) { - this.handleError(e); - } - } - - return; - } - - // Default to port 80. If accessing localhost on another port be sure - // to use http://localhost:port/path - var port = url.port || (ssl ? 443 : 80); - // Add query string if one is used - var uri = url.pathname + (url.search ? url.search : ''); - - // Set the Host header or the server may reject the request - headers["Host"] = host; - if (!((ssl && port === 443) || port === 80)) { - headers["Host"] += ':' + url.port; - } - - // Set Basic Auth if necessary - if (settings.user) { - if (typeof settings.password == "undefined") { - settings.password = ""; - } - var authBuf = new Buffer(settings.user + ":" + settings.password); - headers["Authorization"] = "Basic " + authBuf.toString("base64"); - } - - // Set content length header - if (settings.method === "GET" || settings.method === "HEAD") { - data = null; - } else if (data) { - headers["Content-Length"] = Buffer.byteLength(data); - - if (!headers["Content-Type"]) { - headers["Content-Type"] = "text/plain;charset=UTF-8"; - } - } else if (settings.method === "POST") { - // For a post with no data set Content-Length: 0. - // This is required by buggy servers that don't meet the specs. - headers["Content-Length"] = 0; - } - - var options = { - host: host, - port: port, - path: uri, - method: settings.method, - headers: headers - }; - - // Reset error flag - errorFlag = false; - - // Handle async requests - if (settings.async) { - // Use the proper protocol - var doRequest = ssl ? https.request : http.request; - - // Request is being sent, set send flag - sendFlag = true; - - // As per spec, this is called here for historical reasons. - self.dispatchEvent("readystatechange"); - - // Create the request - request = doRequest(options, function(resp) { - response = resp; - response.setEncoding("utf8"); - - setState(self.HEADERS_RECEIVED); - self.status = response.statusCode; - - response.on('data', function(chunk) { - // Make sure there's some data - if (chunk) { - self.responseText += chunk; - } - // Don't emit state changes if the connection has been aborted. - if (sendFlag) { - setState(self.LOADING); - } - }); - - response.on('end', function() { - if (sendFlag) { - // Discard the 'end' event if the connection has been aborted - setState(self.DONE); - sendFlag = false; - } - }); - - response.on('error', function(error) { - self.handleError(error); - }); - }).on('error', function(error) { - self.handleError(error); - }); - - // Node 0.4 and later won't accept empty data. Make sure it's needed. - if (data) { - request.write(data); - } - - request.end(); - - self.dispatchEvent("loadstart"); - } else { // Synchronous - // Create a temporary file for communication with the other Node process - var syncFile = ".node-xmlhttprequest-sync-" + process.pid; - fs.writeFileSync(syncFile, "", "utf8"); - // The async request the other Node process executes - var execString = "var http = require('http'), https = require('https'), fs = require('fs');" - + "var doRequest = http" + (ssl ? "s" : "") + ".request;" - + "var options = " + JSON.stringify(options) + ";" - + "var responseText = '';" - + "var req = doRequest(options, function(response) {" - + "response.setEncoding('utf8');" - + "response.on('data', function(chunk) {" - + "responseText += chunk;" - + "});" - + "response.on('end', function() {" - + "fs.writeFileSync('" + syncFile + "', 'NODE-XMLHTTPREQUEST-STATUS:' + response.statusCode + ',' + responseText, 'utf8');" - + "});" - + "response.on('error', function(error) {" - + "fs.writeFileSync('" + syncFile + "', 'NODE-XMLHTTPREQUEST-ERROR:' + JSON.stringify(error), 'utf8');" - + "});" - + "}).on('error', function(error) {" - + "fs.writeFileSync('" + syncFile + "', 'NODE-XMLHTTPREQUEST-ERROR:' + JSON.stringify(error), 'utf8');" - + "});" - + (data ? "req.write('" + data.replace(/'/g, "\\'") + "');":"") - + "req.end();"; - // Start the other Node Process, executing this string - syncProc = spawn(process.argv[0], ["-e", execString]); - while((self.responseText = fs.readFileSync(syncFile, 'utf8')) == "") { - // Wait while the file is empty - } - // Kill the child process once the file has data - syncProc.stdin.end(); - // Remove the temporary file - fs.unlinkSync(syncFile); - if (self.responseText.match(/^NODE-XMLHTTPREQUEST-ERROR:/)) { - // If the file returned an error, handle it - var errorObj = self.responseText.replace(/^NODE-XMLHTTPREQUEST-ERROR:/, ""); - self.handleError(errorObj); - } else { - // If the file returned okay, parse its data and move to the DONE state - self.status = self.responseText.replace(/^NODE-XMLHTTPREQUEST-STATUS:([0-9]*),.*/, "$1"); - self.responseText = self.responseText.replace(/^NODE-XMLHTTPREQUEST-STATUS:[0-9]*,(.*)/, "$1"); - setState(self.DONE); - } - } - }; - - /** - * Called when an error is encountered to deal with it. - */ - this.handleError = function(error) { - this.status = 503; - this.statusText = error; - this.responseText = error.stack; - errorFlag = true; - setState(this.DONE); - }; - - /** - * Aborts a request. - */ - this.abort = function() { - if (request) { - request.abort(); - request = null; - } - - headers = defaultHeaders; - this.responseText = ""; - this.responseXML = ""; - - errorFlag = true; - - if (this.readyState !== this.UNSENT - && (this.readyState !== this.OPENED || sendFlag) - && this.readyState !== this.DONE) { - sendFlag = false; - setState(this.DONE); - } - this.readyState = this.UNSENT; - }; - - /** - * Adds an event listener. Preferred method of binding to events. - */ - this.addEventListener = function(event, callback) { - if (!(event in listeners)) { - listeners[event] = []; - } - // Currently allows duplicate callbacks. Should it? - listeners[event].push(callback); - }; - - /** - * Remove an event callback that has already been bound. - * Only works on the matching funciton, cannot be a copy. - */ - this.removeEventListener = function(event, callback) { - if (event in listeners) { - // Filter will return a new array with the callback removed - listeners[event] = listeners[event].filter(function(ev) { - return ev !== callback; - }); - } - }; - - /** - * Dispatch any events, including both "on" methods and events attached using addEventListener. - */ - this.dispatchEvent = function(event) { - if (typeof self["on" + event] === "function") { - self["on" + event](); - } - if (event in listeners) { - for (var i = 0, len = listeners[event].length; i < len; i++) { - listeners[event][i].call(self); - } - } - }; - - /** - * Changes readyState and calls onreadystatechange. - * - * @param int state New state - */ - var setState = function(state) { - if (self.readyState !== state) { - self.readyState = state; - - if (settings.async || self.readyState < self.OPENED || self.readyState === self.DONE) { - self.dispatchEvent("readystatechange"); - } - - if (self.readyState === self.DONE && !errorFlag) { - self.dispatchEvent("load"); - // @TODO figure out InspectorInstrumentation::didLoadXHR(cookie) - self.dispatchEvent("loadend"); - } - } - }; -}; diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/package.json b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/package.json deleted file mode 100644 index cf4f09af11..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/package.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "name": "xmlhttprequest", - "description": "XMLHttpRequest for Node", - "version": "1.4.2", - "author": { - "name": "Dan DeFelippi", - "url": "http://driverdan.com" - }, - "keywords": [ - "xhr", - "ajax" - ], - "licenses": [ - { - "type": "MIT", - "url": "http://creativecommons.org/licenses/MIT/" - } - ], - "repository": { - "type": "git", - "url": "git://github.com/driverdan/node-XMLHttpRequest.git" - }, - "bugs": { - "name": "http://github.com/driverdan/node-XMLHttpRequest/issues" - }, - "engines": { - "node": ">=0.4.0" - }, - "directories": { - "lib": "./lib", - "example": "./example" - }, - "main": "./lib/XMLHttpRequest.js", - "_npmUser": { - "name": "driverdan", - "email": "dan@driverdan.com" - }, - "_id": "xmlhttprequest@1.4.2", - "dependencies": {}, - "devDependencies": {}, - "optionalDependencies": {}, - "_engineSupported": true, - "_npmVersion": "1.1.24", - "_nodeVersion": "v0.6.19", - "_defaultsLoaded": true, - "dist": { - "shasum": "01453a1d9bed1e8f172f6495bbf4c8c426321500", - "tarball": "http://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.4.2.tgz" - }, - "maintainers": [ - { - "name": "driverdan", - "email": "dan@driverdan.com" - } - ], - "_shasum": "01453a1d9bed1e8f172f6495bbf4c8c426321500", - "_from": "xmlhttprequest@1.4.2", - "_resolved": "https://registry.npmjs.org/xmlhttprequest/-/xmlhttprequest-1.4.2.tgz" -} diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/tests/test-constants.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/tests/test-constants.js deleted file mode 100644 index 372e46cc65..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/tests/test-constants.js +++ /dev/null @@ -1,13 +0,0 @@ -var sys = require("util") - , assert = require("assert") - , XMLHttpRequest = require("../lib/XMLHttpRequest").XMLHttpRequest - , xhr = new XMLHttpRequest(); - -// Test constant values -assert.equal(0, xhr.UNSENT); -assert.equal(1, xhr.OPENED); -assert.equal(2, xhr.HEADERS_RECEIVED); -assert.equal(3, xhr.LOADING); -assert.equal(4, xhr.DONE); - -sys.puts("done"); diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/tests/test-events.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/tests/test-events.js deleted file mode 100644 index c72f001d20..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/tests/test-events.js +++ /dev/null @@ -1,50 +0,0 @@ -var sys = require("util") - , assert = require("assert") - , http = require("http") - , XMLHttpRequest = require("../lib/XMLHttpRequest").XMLHttpRequest - , xhr; - -// Test server -var server = http.createServer(function (req, res) { - var body = (req.method != "HEAD" ? "Hello World" : ""); - - res.writeHead(200, { - "Content-Type": "text/plain", - "Content-Length": Buffer.byteLength(body) - }); - // HEAD has no body - if (req.method != "HEAD") { - res.write(body); - } - res.end(); - assert.equal(onreadystatechange, true); - assert.equal(readystatechange, true); - assert.equal(removed, true); - sys.puts("done"); - this.close(); -}).listen(8000); - -xhr = new XMLHttpRequest(); - -// Track event calls -var onreadystatechange = false; -var readystatechange = false; -var removed = true; -var removedEvent = function() { - removed = false; -}; - -xhr.onreadystatechange = function() { - onreadystatechange = true; -}; - -xhr.addEventListener("readystatechange", function() { - readystatechange = true; -}); - -// This isn't perfect, won't guarantee it was added in the first place -xhr.addEventListener("readystatechange", removedEvent); -xhr.removeEventListener("readystatechange", removedEvent); - -xhr.open("GET", "http://localhost:8000"); -xhr.send(); diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/tests/test-exceptions.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/tests/test-exceptions.js deleted file mode 100644 index f1edd71f62..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/tests/test-exceptions.js +++ /dev/null @@ -1,62 +0,0 @@ -var sys = require("util") - , assert = require("assert") - , XMLHttpRequest = require("../lib/XMLHttpRequest").XMLHttpRequest - , xhr = new XMLHttpRequest(); - -// Test request methods that aren't allowed -try { - xhr.open("TRACK", "http://localhost:8000/"); - console.log("ERROR: TRACK should have thrown exception"); -} catch(e) {} -try { - xhr.open("TRACE", "http://localhost:8000/"); - console.log("ERROR: TRACE should have thrown exception"); -} catch(e) {} -try { - xhr.open("CONNECT", "http://localhost:8000/"); - console.log("ERROR: CONNECT should have thrown exception"); -} catch(e) {} -// Test valid request method -try { - xhr.open("GET", "http://localhost:8000/"); -} catch(e) { - console.log("ERROR: Invalid exception for GET", e); -} - -// Test forbidden headers -var forbiddenRequestHeaders = [ - "accept-charset", - "accept-encoding", - "access-control-request-headers", - "access-control-request-method", - "connection", - "content-length", - "content-transfer-encoding", - "cookie", - "cookie2", - "date", - "expect", - "host", - "keep-alive", - "origin", - "referer", - "te", - "trailer", - "transfer-encoding", - "upgrade", - "user-agent", - "via" -]; - -for (var i in forbiddenRequestHeaders) { - try { - xhr.setRequestHeader(forbiddenRequestHeaders[i], "Test"); - console.log("ERROR: " + forbiddenRequestHeaders[i] + " should have thrown exception"); - } catch(e) { - } -} - -// Try valid header -xhr.setRequestHeader("X-Foobar", "Test"); - -console.log("Done"); diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/tests/test-headers.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/tests/test-headers.js deleted file mode 100644 index 2ecb045dfc..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/tests/test-headers.js +++ /dev/null @@ -1,61 +0,0 @@ -var sys = require("util") - , assert = require("assert") - , XMLHttpRequest = require("../lib/XMLHttpRequest").XMLHttpRequest - , xhr = new XMLHttpRequest() - , http = require("http"); - -// Test server -var server = http.createServer(function (req, res) { - // Test setRequestHeader - assert.equal("Foobar", req.headers["x-test"]); - - var body = "Hello World"; - res.writeHead(200, { - "Content-Type": "text/plain", - "Content-Length": Buffer.byteLength(body), - // Set cookie headers to see if they're correctly suppressed - // Actual values don't matter - "Set-Cookie": "foo=bar", - "Set-Cookie2": "bar=baz", - "Connection": "close" - }); - res.write("Hello World"); - res.end(); - - this.close(); -}).listen(8000); - -xhr.onreadystatechange = function() { - if (this.readyState == 4) { - // Test getAllResponseHeaders() - var headers = "content-type: text/plain\r\ncontent-length: 11\r\nconnection: close"; - assert.equal(headers, this.getAllResponseHeaders()); - - // Test case insensitivity - assert.equal('text/plain', this.getResponseHeader('Content-Type')); - assert.equal('text/plain', this.getResponseHeader('Content-type')); - assert.equal('text/plain', this.getResponseHeader('content-Type')); - assert.equal('text/plain', this.getResponseHeader('content-type')); - - // Test aborted getAllResponseHeaders - this.abort(); - assert.equal("", this.getAllResponseHeaders()); - assert.equal(null, this.getResponseHeader("Connection")); - - sys.puts("done"); - } -}; - -assert.equal(null, xhr.getResponseHeader("Content-Type")); -try { - xhr.open("GET", "http://localhost:8000/"); - // Valid header - xhr.setRequestHeader("X-Test", "Foobar"); - // Invalid header - xhr.setRequestHeader("Content-Length", 0); - // Test getRequestHeader - assert.equal("Foobar", xhr.getRequestHeader("X-Test")); - xhr.send(); -} catch(e) { - console.log("ERROR: Exception raised", e); -} diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/tests/test-request-methods.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/tests/test-request-methods.js deleted file mode 100644 index fa1b1bed33..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/tests/test-request-methods.js +++ /dev/null @@ -1,62 +0,0 @@ -var sys = require("util") - , assert = require("assert") - , XMLHttpRequest = require("../lib/XMLHttpRequest").XMLHttpRequest - , http = require("http") - , xhr; - -// Test server -var server = http.createServer(function (req, res) { - // Check request method and URL - assert.equal(methods[curMethod], req.method); - assert.equal("/" + methods[curMethod], req.url); - - var body = (req.method != "HEAD" ? "Hello World" : ""); - - res.writeHead(200, { - "Content-Type": "text/plain", - "Content-Length": Buffer.byteLength(body) - }); - // HEAD has no body - if (req.method != "HEAD") { - res.write(body); - } - res.end(); - - if (curMethod == methods.length - 1) { - this.close(); - sys.puts("done"); - } -}).listen(8000); - -// Test standard methods -var methods = ["GET", "POST", "HEAD", "PUT", "DELETE"]; -var curMethod = 0; - -function start(method) { - // Reset each time - xhr = new XMLHttpRequest(); - - xhr.onreadystatechange = function() { - if (this.readyState == 4) { - if (method == "HEAD") { - assert.equal("", this.responseText); - } else { - assert.equal("Hello World", this.responseText); - } - - curMethod++; - - if (curMethod < methods.length) { - sys.puts("Testing " + methods[curMethod]); - start(methods[curMethod]); - } - } - }; - - var url = "http://localhost:8000/" + method; - xhr.open(method, url); - xhr.send(); -} - -sys.puts("Testing " + methods[curMethod]); -start(methods[curMethod]); diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/tests/test-request-protocols.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/tests/test-request-protocols.js deleted file mode 100644 index cd4e174571..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/tests/test-request-protocols.js +++ /dev/null @@ -1,34 +0,0 @@ -var sys = require("util") - , assert = require("assert") - , XMLHttpRequest = require("../lib/XMLHttpRequest").XMLHttpRequest - , xhr; - -xhr = new XMLHttpRequest(); - -xhr.onreadystatechange = function() { - if (this.readyState == 4) { - assert.equal("Hello World", this.responseText); - this.close(); - runSync(); - } -}; - -// Async -var url = "file://" + __dirname + "/testdata.txt"; -xhr.open("GET", url); -xhr.send(); - -// Sync -var runSync = function() { - xhr = new XMLHttpRequest(); - - xhr.onreadystatechange = function() { - if (this.readyState == 4) { - assert.equal("Hello World", this.responseText); - this.close(); - sys.puts("done"); - } - }; - xhr.open("GET", url, false); - xhr.send(); -} diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/tests/testdata.txt b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/tests/testdata.txt deleted file mode 100644 index 557db03de9..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/node_modules/xmlhttprequest/tests/testdata.txt +++ /dev/null @@ -1 +0,0 @@ -Hello World diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/package.json b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/package.json deleted file mode 100644 index e0e16d527a..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/package.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "name": "socket.io-client", - "description": "Socket.IO client for the browser and node.js", - "version": "0.9.16", - "main": "./lib/io.js", - "browserify": "./dist/socket.io.js", - "homepage": "http://socket.io", - "keywords": [ - "websocket", - "socket", - "realtime", - "socket.io", - "comet", - "ajax" - ], - "author": { - "name": "Guillermo Rauch", - "email": "guillermo@learnboost.com" - }, - "contributors": [ - { - "name": "Guillermo Rauch", - "email": "rauchg@gmail.com" - }, - { - "name": "Arnout Kazemier", - "email": "info@3rd-eden.com" - }, - { - "name": "Vladimir Dronnikov", - "email": "dronnikov@gmail.com" - }, - { - "name": "Einar Otto Stangvik", - "email": "einaros@gmail.com" - } - ], - "repository": { - "type": "git", - "url": "https://github.com/LearnBoost/socket.io-client.git" - }, - "dependencies": { - "uglify-js": "1.2.5", - "ws": "0.4.x", - "xmlhttprequest": "1.4.2", - "active-x-obfuscator": "0.0.1" - }, - "devDependencies": { - "expresso": "*", - "express": "2.5.x", - "jade": "*", - "stylus": "*", - "socket.io": "0.9.16", - "socket.io-client": "0.9.16", - "should": "*" - }, - "engines": { - "node": ">= 0.4.0" - }, - "_id": "socket.io-client@0.9.16", - "dist": { - "shasum": "4da7515c5e773041d1b423970415bcc430f35fc6", - "tarball": "http://registry.npmjs.org/socket.io-client/-/socket.io-client-0.9.16.tgz" - }, - "_from": "socket.io-client@0.9.16", - "_npmVersion": "1.2.18", - "_npmUser": { - "name": "rauchg", - "email": "rauchg@gmail.com" - }, - "maintainers": [ - { - "name": "rauchg", - "email": "rauchg@gmail.com" - } - ], - "directories": {}, - "_shasum": "4da7515c5e773041d1b423970415bcc430f35fc6", - "_resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-0.9.16.tgz", - "bugs": { - "url": "https://github.com/LearnBoost/socket.io-client/issues" - }, - "readme": "ERROR: No README data found!" -} diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/events.test.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/events.test.js deleted file mode 100644 index 365c422315..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/events.test.js +++ /dev/null @@ -1,120 +0,0 @@ - -/*! - * socket.io-node - * Copyright(c) 2011 LearnBoost - * MIT Licensed - */ - -(function (module, io, should) { - - module.exports = { - - 'add listeners': function () { - var event = new io.EventEmitter - , calls = 0; - - event.on('test', function (a, b) { - ++calls; - a.should().eql('a'); - b.should().eql('b'); - }); - - event.emit('test', 'a', 'b'); - calls.should().eql(1); - event.on.should().eql(event.addListener); - }, - - 'remove listener': function () { - var event = new io.EventEmitter; - function empty () { } - - event.on('test', empty); - event.on('test:more', empty); - event.removeAllListeners('test'); - - event.listeners('test').should().eql([]); - event.listeners('test:more').should().eql([empty]); - }, - - 'remove all listeners with no arguments': function () { - var event = new io.EventEmitter; - function empty () { } - - event.on('test', empty); - event.on('test:more', empty); - event.removeAllListeners(); - - event.listeners('test').should().eql([]); - event.listeners('test:more').should().eql([]); - }, - - 'remove listeners functions': function () { - var event = new io.EventEmitter - , calls = 0; - - function one () { ++calls } - function two () { ++calls } - function three () { ++calls } - - event.on('one', one); - event.removeListener('one', one); - event.listeners('one').should().eql([]); - - event.on('two', two); - event.removeListener('two', one); - event.listeners('two').should().eql([two]); - - event.on('three', three); - event.on('three', two); - event.removeListener('three', three); - event.listeners('three').should().eql([two]); - }, - - 'number of arguments': function () { - var event = new io.EventEmitter - , number = []; - - event.on('test', function () { - number.push(arguments.length); - }); - - event.emit('test'); - event.emit('test', null); - event.emit('test', null, null); - event.emit('test', null, null, null); - event.emit('test', null, null, null, null); - event.emit('test', null, null, null, null, null); - - [0, 1, 2, 3, 4, 5].should().eql(number); - }, - - 'once': function () { - var event = new io.EventEmitter - , calls = 0; - - event.once('test', function (a, b) { - ++calls; - }); - - event.emit('test', 'a', 'b'); - event.emit('test', 'a', 'b'); - event.emit('test', 'a', 'b'); - - function removed () { - should().fail('not removed'); - }; - - event.once('test:removed', removed); - event.removeListener('test:removed', removed); - event.emit('test:removed'); - - calls.should().eql(1); - } - - }; - -})( - 'undefined' == typeof module ? module = {} : module - , 'undefined' == typeof io ? require('socket.io-client') : io - , 'undefined' == typeof should || !should.fail ? require('should') : should -); diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/io.test.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/io.test.js deleted file mode 100644 index d9f0b09ed6..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/io.test.js +++ /dev/null @@ -1,31 +0,0 @@ - -/*! - * socket.io-node - * Copyright(c) 2011 LearnBoost - * MIT Licensed - */ - -(function (module, io, should) { - - module.exports = { - - 'client version number': function () { - io.version.should().match(/([0-9]+)\.([0-9]+)\.([0-9]+)/); - }, - - 'socket.io protocol version': function () { - io.protocol.should().be.a('number'); - io.protocol.toString().should().match(/^\d+$/); - }, - - 'socket.io available transports': function () { - (io.transports.length > 0).should().be_true; - } - - }; - -})( - 'undefined' == typeof module ? module = {} : module - , 'undefined' == typeof io ? require('socket.io-client') : io - , 'undefined' == typeof should ? require('should') : should -); diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/node/builder.common.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/node/builder.common.js deleted file mode 100644 index fa8d46eda1..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/node/builder.common.js +++ /dev/null @@ -1,102 +0,0 @@ - -/*! - * socket.io-node - * Copyright(c) 2011 LearnBoost - * MIT Licensed - */ - -var vm = require('vm') - , should = require('should'); - -/** - * Generates evn variables for the vm so we can `emulate` a browser. - * @returns {Object} evn variables - */ - -exports.env = function env () { - var details = { - location: { - port: 8080 - , host: 'www.example.org' - , hostname: 'www.example.org' - , href: 'http://www.example.org/example/' - , pathname: '/example/' - , protocol: 'http:' - , search: '' - , hash: '' - } - , console: { - log: function(){}, - info: function(){}, - warn: function(){}, - error: function(){} - } - , navigator: { - userAgent: 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_7) AppleWebKit' - + '/534.27 (KHTML, like Gecko) Chrome/12.0.716.0 Safari/534.27' - , appName: 'socket.io' - , platform: process.platform - , appVersion: process.version - , } - , name: 'socket.io' - , innerWidth: 1024 - , innerHeight: 768 - , length: 1 - , outerWidth: 1024 - , outerHeight: 768 - , pageXOffset: 0 - , pageYOffset: 0 - , screenX: 0 - , screenY: 0 - , screenLeft: 0 - , screenTop: 0 - , scrollX: 0 - , scrollY: 0 - , scrollTop: 0 - , scrollLeft: 0 - , screen: { - width: 0 - , height: 0 - } - }; - - // circular references - details.window = details.self = details.contentWindow = details; - - // callable methods - details.Image = details.scrollTo = details.scrollBy = details.scroll = - details.resizeTo = details.resizeBy = details.prompt = details.print = - details.open = details.moveTo = details.moveBy = details.focus = - details.createPopup = details.confirm = details.close = details.blur = - details.alert = details.clearTimeout = details.clearInterval = - details.setInterval = details.setTimeout = details.XMLHttpRequest = - details.getComputedStyle = details.trigger = details.dispatchEvent = - details.removeEventListener = details.addEventListener = function(){}; - - // frames - details.frames = [details]; - - // document - details.document = details; - details.document.domain = details.location.href; - - return details; -}; - -/** - * Executes a script in a browser like env and returns - * the result - * - * @param {String} contents The script content - * @returns {Object} The evaluated script. - */ - -exports.execute = function execute (contents) { - var env = exports.env() - , script = vm.createScript(contents); - - // run the script with `browser like` globals - script.runInNewContext(env); - - return env; -}; diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/node/builder.test.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/node/builder.test.js deleted file mode 100644 index 989e2bc562..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/node/builder.test.js +++ /dev/null @@ -1,131 +0,0 @@ -/*! - * socket.io-node - * Copyright(c) 2011 LearnBoost - * MIT Licensed - */ - -/** - * Test dependencies. - */ - -var builder = require('../../bin/builder') - , common = require('./builder.common') - , should = require('should'); - -/** - * Tests. - */ - -module.exports = { - - 'version number': function () { - builder.version.should().match(/([0-9]+)\.([0-9]+)\.([0-9]+)/); - builder.version.should().equal(require('../../lib/io').version); - }, - - 'production build LOC': function () { - builder(function (err, result) { - should.strictEqual(err, null) - - var lines = result.split('\n'); - lines.length.should().be.below(5); - lines[0].should().match(/production/gi); - Buffer.byteLength(result).should().be.below(43000); - }); - }, - - 'development build LOC': function () { - builder({ minify: false }, function (err, result) { - should.strictEqual(err, null) - - var lines = result.split('\n'); - lines.length.should().be.above(5); - lines[0].should().match(/development/gi); - Buffer.byteLength(result).should().be.above(35000); - }); - }, - - 'default builds': function () { - builder(function (err, result) { - should.strictEqual(err, null); - - var io = common.execute(result).io - , transports = Object.keys(io.Transport) - , defaults = Object.keys(builder.transports); - - /* XHR transport is private, but still available */ - transports.length.should().be.equal(defaults.length + 1); - - defaults.forEach(function (transport) { - transports.indexOf(transport).should().be.above(-1); - }) - }); - }, - - 'custom build': function () { - builder(['websocket'], function (err, result) { - should.strictEqual(err, null); - - var io = common.execute(result).io - , transports = Object.keys(io.Transport); - - transports.should().have.length(1); - transports[0].should().eql('websocket'); - }); - }, - - 'custom code': function () { - var custom = 'var hello = "world";'; - builder({ custom: [custom], minify: false }, function (err, result) { - should.strictEqual(err, null); - - result.should().include.string(custom); - }); - }, - - 'node if': function () { - var custom = '// if node \nvar hello = "world";\n' - + '// end node\nvar pew = "pew";'; - - builder({ custom: [custom], minify: false }, function (err, result) { - should.strictEqual(err, null); - - result.should().not.include.string(custom); - result.should().not.include.string('// if node'); - result.should().not.include.string('// end node'); - result.should().not.include.string('"world"'); - - result.should().include.string('var pew = "pew"'); - }); - }, - - 'preserve the encoding during minification': function () { - builder(function (err, result) { - should.strictEqual(err, null); - - result.should().match(/(\\ufffd)/g); - }) - }, - - 'globals': function () { - builder(function (err, result) { - should.strictEqual(err, null); - - var io = common.execute(result) - , env = common.env() - , allowed = ['io', 'swfobject', 'WEB_SOCKET_DISABLE_AUTO_INITIALIZATION']; - - Array.prototype.push.apply(allowed, Object.keys(env)); - - Object.keys(io).forEach(function (global) { - var index = allowed.indexOf(global); - - // the global is not allowed! - if (!~index) { - throw new Error('Global leak: ' + global); - } - }); - }) - } - -}; diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/parser.test.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/parser.test.js deleted file mode 100644 index 0022afb235..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/parser.test.js +++ /dev/null @@ -1,360 +0,0 @@ - -/*! - * socket.io-node - * Copyright(c) 2011 LearnBoost - * MIT Licensed - */ - -(function (module, io, should) { - - var parser = io.parser; - - module.exports = { - - 'decoding error packet': function () { - parser.decodePacket('7:::').should().eql({ - type: 'error' - , reason: '' - , advice: '' - , endpoint: '' - }); - }, - - 'decoding error packet with reason': function () { - parser.decodePacket('7:::0').should().eql({ - type: 'error' - , reason: 'transport not supported' - , advice: '' - , endpoint: '' - }); - }, - - 'decoding error packet with reason and advice': function () { - parser.decodePacket('7:::2+0').should().eql({ - type: 'error' - , reason: 'unauthorized' - , advice: 'reconnect' - , endpoint: '' - }); - }, - - 'decoding error packet with endpoint': function () { - parser.decodePacket('7::/woot').should().eql({ - type: 'error' - , reason: '' - , advice: '' - , endpoint: '/woot' - }); - }, - - 'decoding ack packet': function () { - parser.decodePacket('6:::140').should().eql({ - type: 'ack' - , ackId: '140' - , endpoint: '' - , args: [] - }); - }, - - 'decoding ack packet with args': function () { - parser.decodePacket('6:::12+["woot","wa"]').should().eql({ - type: 'ack' - , ackId: '12' - , endpoint: '' - , args: ['woot', 'wa'] - }); - }, - - 'decoding ack packet with bad json': function () { - var thrown = false; - - try { - parser.decodePacket('6:::1+{"++]').should().eql({ - type: 'ack' - , ackId: '1' - , endpoint: '' - , args: [] - }); - } catch (e) { - thrown = true; - } - - thrown.should().be_false; - }, - - 'decoding json packet': function () { - parser.decodePacket('4:::"2"').should().eql({ - type: 'json' - , endpoint: '' - , data: '2' - }); - }, - - 'decoding json packet with message id and ack data': function () { - parser.decodePacket('4:1+::{"a":"b"}').should().eql({ - type: 'json' - , id: 1 - , ack: 'data' - , endpoint: '' - , data: { a: 'b' } - }); - }, - - 'decoding an event packet': function () { - parser.decodePacket('5:::{"name":"woot"}').should().eql({ - type: 'event' - , name: 'woot' - , endpoint: '' - , args: [] - }); - }, - - 'decoding an event packet with message id and ack': function () { - parser.decodePacket('5:1+::{"name":"tobi"}').should().eql({ - type: 'event' - , id: 1 - , ack: 'data' - , endpoint: '' - , name: 'tobi' - , args: [] - }); - }, - - 'decoding an event packet with data': function () { - parser.decodePacket('5:::{"name":"edwald","args":[{"a": "b"},2,"3"]}') - .should().eql({ - type: 'event' - , name: 'edwald' - , endpoint: '' - , args: [{a: 'b'}, 2, '3'] - }); - }, - - 'decoding a message packet': function () { - parser.decodePacket('3:::woot').should().eql({ - type: 'message' - , endpoint: '' - , data: 'woot' - }); - }, - - 'decoding a message packet with id and endpoint': function () { - parser.decodePacket('3:5:/tobi').should().eql({ - type: 'message' - , id: 5 - , ack: true - , endpoint: '/tobi' - , data: '' - }); - }, - - 'decoding a heartbeat packet': function () { - parser.decodePacket('2:::').should().eql({ - type: 'heartbeat' - , endpoint: '' - }); - }, - - 'decoding a connection packet': function () { - parser.decodePacket('1::/tobi').should().eql({ - type: 'connect' - , endpoint: '/tobi' - , qs: '' - }); - }, - - 'decoding a connection packet with query string': function () { - parser.decodePacket('1::/test:?test=1').should().eql({ - type: 'connect' - , endpoint: '/test' - , qs: '?test=1' - }); - }, - - 'decoding a disconnection packet': function () { - parser.decodePacket('0::/woot').should().eql({ - type: 'disconnect' - , endpoint: '/woot' - }); - }, - - 'encoding error packet': function () { - parser.encodePacket({ - type: 'error' - , reason: '' - , advice: '' - , endpoint: '' - }).should().eql('7::'); - }, - - 'encoding error packet with reason': function () { - parser.encodePacket({ - type: 'error' - , reason: 'transport not supported' - , advice: '' - , endpoint: '' - }).should().eql('7:::0'); - }, - - 'encoding error packet with reason and advice': function () { - parser.encodePacket({ - type: 'error' - , reason: 'unauthorized' - , advice: 'reconnect' - , endpoint: '' - }).should().eql('7:::2+0'); - }, - - 'encoding error packet with endpoint': function () { - parser.encodePacket({ - type: 'error' - , reason: '' - , advice: '' - , endpoint: '/woot' - }).should().eql('7::/woot'); - }, - - 'encoding ack packet': function () { - parser.encodePacket({ - type: 'ack' - , ackId: '140' - , endpoint: '' - , args: [] - }).should().eql('6:::140'); - }, - - 'encoding ack packet with args': function () { - parser.encodePacket({ - type: 'ack' - , ackId: '12' - , endpoint: '' - , args: ['woot', 'wa'] - }).should().eql('6:::12+["woot","wa"]'); - }, - - 'encoding json packet': function () { - parser.encodePacket({ - type: 'json' - , endpoint: '' - , data: '2' - }).should().eql('4:::"2"'); - }, - - 'encoding json packet with message id and ack data': function () { - parser.encodePacket({ - type: 'json' - , id: 1 - , ack: 'data' - , endpoint: '' - , data: { a: 'b' } - }).should().eql('4:1+::{"a":"b"}'); - }, - - 'encoding an event packet': function () { - parser.encodePacket({ - type: 'event' - , name: 'woot' - , endpoint: '' - , args: [] - }).should().eql('5:::{"name":"woot"}'); - }, - - 'encoding an event packet with message id and ack': function () { - parser.encodePacket({ - type: 'event' - , id: 1 - , ack: 'data' - , endpoint: '' - , name: 'tobi' - , args: [] - }).should().eql('5:1+::{"name":"tobi"}'); - }, - - 'encoding an event packet with data': function () { - parser.encodePacket({ - type: 'event' - , name: 'edwald' - , endpoint: '' - , args: [{a: 'b'}, 2, '3'] - }).should().eql('5:::{"name":"edwald","args":[{"a":"b"},2,"3"]}'); - }, - - 'encoding a message packet': function () { - parser.encodePacket({ - type: 'message' - , endpoint: '' - , data: 'woot' - }).should().eql('3:::woot'); - }, - - 'encoding a message packet with id and endpoint': function () { - parser.encodePacket({ - type: 'message' - , id: 5 - , ack: true - , endpoint: '/tobi' - , data: '' - }).should().eql('3:5:/tobi'); - }, - - 'encoding a heartbeat packet': function () { - parser.encodePacket({ - type: 'heartbeat' - , endpoint: '' - }).should().eql('2::'); - }, - - 'encoding a connection packet': function () { - parser.encodePacket({ - type: 'connect' - , endpoint: '/tobi' - , qs: '' - }).should().eql('1::/tobi'); - }, - - 'encoding a connection packet with query string': function () { - parser.encodePacket({ - type: 'connect' - , endpoint: '/test' - , qs: '?test=1' - }).should().eql('1::/test:?test=1'); - }, - - 'encoding a disconnection packet': function () { - parser.encodePacket({ - type: 'disconnect' - , endpoint: '/woot' - }).should().eql('0::/woot'); - }, - - 'test decoding a payload': function () { - parser.decodePayload('\ufffd5\ufffd3:::5\ufffd7\ufffd3:::53d' - + '\ufffd3\ufffd0::').should().eql([ - { type: 'message', data: '5', endpoint: '' } - , { type: 'message', data: '53d', endpoint: '' } - , { type: 'disconnect', endpoint: '' } - ]); - }, - - 'test encoding a payload': function () { - parser.encodePayload([ - parser.encodePacket({ type: 'message', data: '5', endpoint: '' }) - , parser.encodePacket({ type: 'message', data: '53d', endpoint: '' }) - ]).should().eql('\ufffd5\ufffd3:::5\ufffd7\ufffd3:::53d') - }, - - 'test decoding newline': function () { - parser.decodePacket('3:::\n').should().eql({ - type: 'message' - , endpoint: '' - , data: '\n' - }); - } - - }; - -})( - 'undefined' == typeof module ? module = {} : module - , 'undefined' == typeof io ? require('socket.io-client') : io - , 'undefined' == typeof should ? require('should') : should -); diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/socket.test.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/socket.test.js deleted file mode 100644 index eae4956494..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/socket.test.js +++ /dev/null @@ -1,422 +0,0 @@ - -/*! - * socket.io-node - * Copyright(c) 2011 LearnBoost - * MIT Licensed - */ - -(function (module, io, should) { - - if ('object' == typeof global) { - return module.exports = { '': function () {} }; - } - - module.exports = { - - 'test connecting the socket and disconnecting': function (next) { - var socket = create(); - - socket.on('error', function (msg) { - throw new Error(msg || 'Received an error'); - }); - - socket.on('connect', function () { - socket.disconnect(); - next(); - }); - }, - - 'test receiving messages': function (next) { - var socket = create() - , connected = false - , messages = 0; - - socket.on('error', function (msg) { - throw new Error(msg || 'Received an error'); - }); - - socket.on('connect', function () { - connected = true; - }); - - socket.on('message', function (i) { - String(++messages).should().equal(i); - }); - - socket.on('disconnect', function (reason) { - connected.should().be_true; - messages.should().equal(3); - reason.should().eql('booted'); - next(); - }); - }, - - 'test sending messages': function (next) { - var socket = create(); - - socket.on('error', function (msg) { - throw new Error(msg || 'Received an error'); - }); - - socket.on('connect', function () { - socket.send('echo'); - - socket.on('message', function (msg) { - msg.should().equal('echo'); - socket.disconnect(); - next(); - }); - }); - }, - - 'test manual buffer flushing': function (next) { - var socket = create(); - - socket.socket.options['manualFlush'] = true; - - socket.on('error', function (msg) { - throw new Error(msg || 'Received an error'); - }); - - socket.on('connect', function () { - socket.socket.connected = false; - socket.send('buffered'); - socket.socket.onConnect(); - socket.socket.flushBuffer(); - - socket.on('message', function (msg) { - msg.should().equal('buffered'); - socket.disconnect(); - next(); - }); - }); - }, - - 'test automatic buffer flushing': function (next) { - var socket = create(); - - socket.on('error', function (msg) { - throw new Error(msg || 'Received an error'); - }); - - socket.on('connect', function () { - socket.socket.connected = false; - socket.send('buffered'); - socket.socket.onConnect(); - - socket.on('message', function (msg) { - msg.should().equal('buffered'); - socket.disconnect(); - next(); - }); - }); - }, - - 'test acks sent from client': function (next) { - var socket = create(); - - socket.on('error', function (msg) { - throw new Error(msg || 'Received an error'); - }); - - socket.on('connect', function () { - socket.on('message', function (msg) { - if ('tobi 2' == msg) { - socket.disconnect(); - next(); - } - }); - }); - }, - - 'test acks sent from server': function (next) { - var socket = create(); - - socket.on('error', function (msg) { - throw new Error(msg || 'Received an error'); - }); - - socket.on('connect', function () { - socket.send('ooo', function () { - socket.disconnect(); - next(); - }); - }); - }, - - 'test connecting to namespaces': function (next) { - var io = create() - , socket = io.socket - , namespaces = 2 - , connect = 0; - - function finish () { - socket.of('').disconnect(); - connect.should().equal(3); - next(); - } - - socket.on('connect', function(){ - connect++; - }); - - socket.of('/woot').on('connect', function () { - connect++; - }).on('message', function (msg) { - msg.should().equal('connected to woot'); - --namespaces || finish(); - }).on('error', function (msg) { - throw new Error(msg || 'Received an error'); - }); - - socket.of('/chat').on('connect', function () { - connect++; - }).on('message', function (msg) { - msg.should().equal('connected to chat'); - --namespaces || finish(); - }).on('error', function (msg) { - throw new Error(msg || 'Received an error'); - }); - }, - - 'test disconnecting from namespaces': function (next) { - var socket = create().socket - , namespaces = 2 - , disconnections = 0; - - function finish () { - socket.of('').disconnect(); - next(); - }; - - socket.of('/a').on('error', function (msg) { - throw new Error(msg || 'Received an error'); - }); - - socket.of('/a').on('connect', function () { - socket.of('/a').disconnect(); - }); - - socket.of('/a').on('disconnect', function () { - --namespaces || finish(); - }); - - socket.of('/b').on('error', function (msg) { - throw new Error(msg || 'Received an error'); - }); - - socket.of('/b').on('connect', function () { - socket.of('/b').disconnect(); - }); - - socket.of('/b').on('disconnect', function () { - --namespaces || finish(); - }); - }, - - 'test authorizing for namespaces': function (next) { - var socket = create().socket - - function finish () { - socket.of('').disconnect(); - next(); - }; - - socket.of('/a') - .on('connect_failed', function (msg) { - next(); - }) - .on('error', function (msg) { - throw new Error(msg || 'Received an error'); - }); - }, - - 'test sending json from server': function (next) { - var socket = create(); - - socket.on('error', function (msg) { - throw new Error(msg || 'Received an error'); - }); - - socket.on('message', function (msg) { - msg.should().eql(3141592); - socket.disconnect(); - next(); - }); - }, - - 'test sending json from client': function (next) { - var socket = create(); - - socket.on('error', function (msg) { - throw new Error(msg || 'Received an error'); - }); - - socket.json.send([1, 2, 3]); - socket.on('message', function (msg) { - msg.should().equal('echo'); - socket.disconnect(); - next(); - }); - }, - - 'test emitting an event from server': function (next) { - var socket = create(); - - socket.on('error', function (msg) { - throw new Error(msg || 'Received an error'); - }); - - socket.on('woot', function () { - socket.disconnect(); - next(); - }); - }, - - 'test emitting an event to server': function (next) { - var socket = create(); - - socket.on('error', function (msg) { - throw new Error(msg || 'Received an error'); - }); - - socket.emit('woot'); - socket.on('echo', function () { - socket.disconnect(); - next(); - }) - }, - - 'test emitting multiple events at once to the server': function (next) { - var socket = create(); - - socket.on('connect', function () { - socket.emit('print', 'foo'); - socket.emit('print', 'bar'); - }); - - socket.on('done', function () { - socket.disconnect(); - next(); - }); - }, - - 'test emitting an event from server and sending back data': function (next) { - var socket = create(); - - socket.on('error', function (msg) { - throw new Error(msg || 'Received an error'); - }); - - socket.on('woot', function (a, fn) { - a.should().eql(1); - fn('test'); - - socket.on('done', function () { - socket.disconnect(); - next(); - }); - }); - }, - - 'test emitting an event to server and sending back data': function (next) { - var socket = create(); - - socket.on('error', function (msg) { - throw new Error(msg || 'Received an error'); - }); - - socket.emit('tobi', 1, 2, function (a) { - a.should().eql({ hello: 'world' }); - socket.disconnect(); - next(); - }); - }, - - 'test encoding a payload': function (next) { - var socket = create('/woot'); - - socket.on('error', function (msg) { - throw new Error(msg || 'Received an error'); - }); - - socket.on('connect', function () { - socket.socket.setBuffer(true); - socket.send('ñ'); - socket.send('ñ'); - socket.send('ñ'); - socket.send('ñ'); - socket.socket.setBuffer(false); - }); - - socket.on('done', function () { - socket.disconnect(); - next(); - }); - }, - - 'test sending query strings to the server': function (next) { - var socket = create('?foo=bar'); - - socket.on('error', function (msg) { - throw new Error(msg || 'Received an error'); - }); - - socket.on('message', function (data) { - data.query.foo.should().eql('bar'); - - socket.disconnect(); - next(); - }); - }, - - 'test sending newline': function (next) { - var socket = create(); - - socket.on('error', function (msg) { - throw new Error(msg || 'Received an error'); - }); - - socket.send('\n'); - - socket.on('done', function () { - socket.disconnect(); - next(); - }); - }, - - 'test sending unicode': function (next) { - var socket = create(); - - socket.on('error', function (msg) { - throw new Error(msg || 'Received an error'); - }); - - socket.json.send({ test: "☃" }); - - socket.on('done', function () { - socket.disconnect(); - next(); - }); - }, - - 'test webworker connection': function (next) { - if (!window.Worker) { - return next(); - } - - var worker = new Worker('/test/worker.js'); - worker.postMessage(uri()); - worker.onmessage = function (ev) { - if ('done!' == ev.data) return next(); - throw new Error('Unexpected message: ' + ev.data); - } - } - - }; - -})( - 'undefined' == typeof module ? module = {} : module - , 'undefined' == typeof io ? require('socket.io-client') : io - , 'undefined' == typeof should ? require('should-browser') : should -); diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/util.test.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/util.test.js deleted file mode 100644 index 30db5a63c7..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/util.test.js +++ /dev/null @@ -1,156 +0,0 @@ - -/*! - * socket.io-node - * Copyright(c) 2011 LearnBoost - * MIT Licensed - */ - -(function (module, io, should) { - - module.exports = { - - 'parse uri': function () { - var http = io.util.parseUri('http://google.com') - , https = io.util.parseUri('https://www.google.com:80') - , query = io.util.parseUri('google.com:8080/foo/bar?foo=bar'); - - http.protocol.should().eql('http'); - http.port.should().eql(''); - http.host.should().eql('google.com'); - https.protocol.should().eql('https'); - https.port.should().eql('80'); - https.host.should().eql('www.google.com'); - query.port.should().eql('8080'); - query.query.should().eql('foo=bar'); - query.path.should().eql('/foo/bar'); - query.relative.should().eql('/foo/bar?foo=bar'); - }, - - 'unique uri': function () { - var protocol = io.util.parseUri('http://google.com') - , noprotocol = io.util.parseUri('google.com') - , https = io.util.parseUri('https://google.com') - , path = io.util.parseUri('https://google.com/google.com/com/?foo=bar'); - - if ('object' == typeof window) { - io.util.uniqueUri(protocol).should().eql('http://google.com:3000'); - io.util.uniqueUri(noprotocol).should().eql('http://google.com:3000'); - } else { - io.util.uniqueUri(protocol).should().eql('http://google.com:80'); - io.util.uniqueUri(noprotocol).should().eql('http://google.com:80'); - } - - io.util.uniqueUri(https).should().eql('https://google.com:443'); - io.util.uniqueUri(path).should().eql('https://google.com:443'); - }, - - 'chunk query string': function () { - io.util.chunkQuery('foo=bar').should().be.a('object'); - io.util.chunkQuery('foo=bar').foo.should().eql('bar'); - }, - - 'merge query strings': function () { - var base = io.util.query('foo=bar', 'foo=baz') - , add = io.util.query('foo=bar', 'bar=foo') - - base.should().eql('?foo=baz'); - add.should().eql('?foo=bar&bar=foo'); - - io.util.query('','').should().eql(''); - io.util.query('foo=bar', '').should().eql('?foo=bar'); - io.util.query('', 'foo=bar').should().eql('?foo=bar'); - }, - - 'request': function () { - var type = typeof io.util.request(); - type.should().eql('object'); - }, - - 'is array': function () { - io.util.isArray([]).should().be_true; - io.util.isArray({}).should().be_false; - io.util.isArray('str').should().be_false; - io.util.isArray(new Date).should().be_false; - io.util.isArray(true).should().be_false; - io.util.isArray(arguments).should().be_false; - }, - - 'merge, deep merge': function () { - var start = { - foo: 'bar' - , bar: 'baz' - } - , duplicate = { - foo: 'foo' - , bar: 'bar' - } - , extra = { - ping: 'pong' - } - , deep = { - level1:{ - foo: 'bar' - , level2: { - foo: 'bar' - , level3:{ - foo: 'bar' - , rescursive: deep - } - } - } - } - // same structure, but changed names - , deeper = { - foo: 'bar' - , level1:{ - foo: 'baz' - , level2: { - foo: 'foo' - , level3:{ - foo: 'pewpew' - , rescursive: deep - } - } - } - }; - - io.util.merge(start, duplicate); - - start.foo.should().eql('foo'); - start.bar.should().eql('bar'); - - io.util.merge(start, extra); - start.ping.should().eql('pong'); - start.foo.should().eql('foo'); - - io.util.merge(deep, deeper); - - deep.foo.should().eql('bar'); - deep.level1.foo.should().eql('baz'); - deep.level1.level2.foo.should().eql('foo'); - deep.level1.level2.level3.foo.should().eql('pewpew'); - }, - - 'defer': function (next) { - var now = +new Date; - - io.util.defer(function () { - ((new Date - now) >= ( io.util.webkit ? 100 : 0 )).should().be_true(); - next(); - }) - }, - - 'indexOf': function () { - var data = ['socket', 2, 3, 4, 'socket', 5, 6, 7, 'io']; - io.util.indexOf(data, 'socket', 1).should().eql(4); - io.util.indexOf(data, 'socket').should().eql(0); - io.util.indexOf(data, 'waffles').should().eql(-1); - } - - }; - -})( - 'undefined' == typeof module ? module = {} : module - , 'undefined' == typeof io ? require('socket.io-client') : io - , 'undefined' == typeof should ? require('should') : should -); diff --git a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/worker.js b/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/worker.js deleted file mode 100644 index c5426326b1..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/node_modules/socket.io-client/test/worker.js +++ /dev/null @@ -1,20 +0,0 @@ -importScripts('/socket.io/socket.io.js'); - -self.onmessage = function (ev) { - var url = ev.data - , socket = io.connect(url); - - socket.on('done', function () { - self.postMessage('done!'); - }); - - socket.on('connect_failed', function () { - self.postMessage('connect failed'); - }); - - socket.on('error', function () { - self.postMessage('error'); - }); - - socket.send('woot'); -} diff --git a/messenger/js/easyrtc/node_modules/socket.io/package.json b/messenger/js/easyrtc/node_modules/socket.io/package.json deleted file mode 100644 index 0a2f9c6c45..0000000000 --- a/messenger/js/easyrtc/node_modules/socket.io/package.json +++ /dev/null @@ -1,87 +0,0 @@ -{ - "name": "socket.io", - "version": "0.9.17", - "description": "Real-time apps made cross-browser & easy with a WebSocket-like API", - "homepage": "http://socket.io", - "keywords": [ - "websocket", - "socket", - "realtime", - "socket.io", - "comet", - "ajax" - ], - "author": { - "name": "Guillermo Rauch", - "email": "guillermo@learnboost.com" - }, - "contributors": [ - { - "name": "Guillermo Rauch", - "email": "rauchg@gmail.com" - }, - { - "name": "Arnout Kazemier", - "email": "info@3rd-eden.com" - }, - { - "name": "Vladimir Dronnikov", - "email": "dronnikov@gmail.com" - }, - { - "name": "Einar Otto Stangvik", - "email": "einaros@gmail.com" - } - ], - "repository": { - "type": "git", - "url": "https://github.com/LearnBoost/socket.io.git" - }, - "dependencies": { - "socket.io-client": "0.9.16", - "policyfile": "0.0.4", - "base64id": "0.1.0", - "redis": "0.7.3" - }, - "devDependencies": { - "expresso": "0.9.2", - "should": "*", - "benchmark": "0.2.2", - "microtime": "0.1.3-1", - "colors": "0.5.1" - }, - "optionalDependencies": { - "redis": "0.7.3" - }, - "main": "index", - "engines": { - "node": ">= 0.4.0" - }, - "scripts": { - "test": "make test" - }, - "bugs": { - "url": "https://github.com/LearnBoost/socket.io/issues" - }, - "_id": "socket.io@0.9.17", - "_shasum": "ca389268fb2cd5df4b59218490a08c907581c9ec", - "_from": "socket.io@0.9.x", - "_npmVersion": "1.4.7", - "_npmUser": { - "name": "rauchg", - "email": "rauchg@gmail.com" - }, - "maintainers": [ - { - "name": "rauchg", - "email": "rauchg@gmail.com" - } - ], - "dist": { - "shasum": "ca389268fb2cd5df4b59218490a08c907581c9ec", - "tarball": "http://registry.npmjs.org/socket.io/-/socket.io-0.9.17.tgz" - }, - "directories": {}, - "_resolved": "https://registry.npmjs.org/socket.io/-/socket.io-0.9.17.tgz", - "readme": "ERROR: No README data found!" -} diff --git a/messenger/js/easyrtc/package.json b/messenger/js/easyrtc/package.json deleted file mode 100755 index 2cec280cac..0000000000 --- a/messenger/js/easyrtc/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name" : "easyrtc_server_example", - "version" : "0.1.6", - "author" : "Priologic Software Inc. (http://priologic.com/)", - "description" : "Simple EasyRTC server example which includes EasyRTC, Express, and Socket.io", - - "private" : true, - - "scripts": { - "start" : "node server.js" - }, - - "dependencies" : { - "easyrtc" : "1.0.x", - "express" : "*", - "socket.io" : "0.9.x" - }, - - "license" : "BSD2", - - "engines": { - "node" : ">=0.8" - } -} diff --git a/messenger/js/easyrtc/server.js b/messenger/js/easyrtc/server.js deleted file mode 100755 index 3c478e35ad..0000000000 --- a/messenger/js/easyrtc/server.js +++ /dev/null @@ -1,18 +0,0 @@ -// Load required modules -var http = require("http"); // http server core module -var express = require("express"); // web framework external module -var io = require("socket.io"); // web socket external module -var easyrtc = require("easyrtc"); // EasyRTC external module - -// Setup and configure Express http server. Expect a subfolder called "static" to be the web root. -var httpApp = express(); -httpApp.use(express.static(__dirname + "/static/")); - -// Start Express http server on port 8080 -var webServer = http.createServer(httpApp).listen(8010); - -// Start Socket.io so it attaches itself to Express server -var socketServer = io.listen(webServer, {"log level":1}); - -// Start EasyRTC server -var rtc = easyrtc.listen(httpApp , socketServer); diff --git a/messenger/js/easyrtc/static/index.html b/messenger/js/easyrtc/static/index.html deleted file mode 100644 index 9ffeb38a05..0000000000 --- a/messenger/js/easyrtc/static/index.html +++ /dev/null @@ -1,20 +0,0 @@ - - - - EasyRTC - Server Root - - - -

You have installed EasyRTC!

- -

This is your server's Web Root

- -

This is the easiest location to put your own static html files for developing WebRTC applications.

- -

In the meantime we'll forward you to the EasyRTC Demo page...

- - Powered by EasyRTC - - \ No newline at end of file diff --git a/messenger/setup/setup.inc.php b/messenger/setup/setup.inc.php deleted file mode 100644 index a9ecd1f7f7..0000000000 --- a/messenger/setup/setup.inc.php +++ /dev/null @@ -1,47 +0,0 @@ - - * @package messenger - * @subpackage setup - * @copyright (c) 2014 by Stylite AG - * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License - * @version $Id: $ - */ - -$setup_info['messenger']['name'] = 'messenger'; -$setup_info['messenger']['version'] = '15.1'; -$setup_info['messenger']['app_order'] = 5; -$setup_info['messenger']['enable'] = 1; -$setup_info['messenger']['index'] = 'messenger.messenger_ui.index&ajax=true'; - - -/* The hooks this app includes, needed for hooks registration */ -$setup_info['messenger']['hooks']['search_link'] = 'messenger_hooks::search_link'; -$setup_info['messenger']['hooks']['sidebox_menu'] = 'messenger_hooks::sidebox_menu'; - -$setup_info['messenger']['author'] = -$setup_info['messenger']['maintainer'] = array( - 'name' => 'Hadi Nategh', - 'email' => 'hn@stylite.de' -); -$setup_info['messenger']['license'] = 'GPL'; -$setup_info['messenger']['description'] = -'Collaboration Media for egroupware'; -$setup_info['messenger']['note'] = -'The messenger application is sponsored by:'; - -/* Dependencies for this app to work */ -$setup_info['messenger']['depends'][] = array( - 'appname' => 'phpgwapi', - 'versions' => Array('14.1') -); -$setup_info['messenger']['depends'][] = array( - 'appname' => 'etemplate', - 'versions' => Array('14.1') -); diff --git a/messenger/templates/default/app.css b/messenger/templates/default/app.css deleted file mode 100644 index 0333eaa83c..0000000000 --- a/messenger/templates/default/app.css +++ /dev/null @@ -1,41 +0,0 @@ -.messenger_remote_media { - position:relative; -} -.messenger_local_media { - -} -#messenger-dialog_chatbox { - overflow-x: hidden; -} -.messenger_textboxes { - border:1px solid gray; - margin-left: 1px; - overflow-y: auto; - resize: none; -} -div.dialogSplitter { - background: white; - border: 2px solid; - border-radius: 20px 20px 20px 20px; - border-color: rgba(90, 90, 90, 0.68); - /* border-style: outset; */ - margin-left: -6px; - box-shadow: 2px 9px 15px 6px gray; - margin-top: 0px; - border-style: solid; -} -table.messageBox { - border-left: 1px solid rgba(141, 141, 141, 1); -} -.writeMessageBox { - border-top: 3px solid rgba(141, 141, 141, 1); -} -.writeMessageBox #messenger-index_msg_message { - max-height: 70%; - background: rgb(231, 241, 251); - margin-right: 10px; - resize: vertical; -} -.phoneRingingTune { - URI: -} \ No newline at end of file diff --git a/messenger/templates/default/dialog.xet b/messenger/templates/default/dialog.xet deleted file mode 100644 index dcd62eeb4a..0000000000 --- a/messenger/templates/default/dialog.xet +++ /dev/null @@ -1,38 +0,0 @@ - - - - - \ No newline at end of file diff --git a/messenger/templates/default/index.xet b/messenger/templates/default/index.xet deleted file mode 100644 index 00245116a4..0000000000 --- a/messenger/templates/default/index.xet +++ /dev/null @@ -1,51 +0,0 @@ - - - - - - - \ No newline at end of file