Comparar commits
301 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 9153a45933 | |||
| bda4267def | |||
| 49ecac9f7b | |||
| 736119b375 | |||
| d8733e73d3 | |||
| 7f73c45af0 | |||
| f8c4bf1d3b | |||
| 3c5ff959e5 | |||
| 49cf0eebca | |||
| 4efa02e4ae | |||
| 3b51e7d7a5 | |||
| c46e9fc534 | |||
| 03e423f439 | |||
| 2f432667e9 | |||
| 087e5c819c | |||
| fab9257282 | |||
| 3feb97b119 | |||
| 25667db4be | |||
| c8bf94971b | |||
| 4ce384d9b1 | |||
| fc586cff7e | |||
| adb4afc8f5 | |||
| 7888f5ed09 | |||
| b50933b263 | |||
| d203f633f2 | |||
| 22b7b71204 | |||
| a48f7e6992 | |||
| ec33ace031 | |||
| a428903a00 | |||
| 6bb5a152d7 | |||
| b49d898c9c | |||
| e45aa6ccec | |||
| e16ab27416 | |||
| 3ba25a08f6 | |||
| 87b3b1db32 | |||
| 3343044e95 | |||
| 835fa8227c | |||
| 82a28d6aba | |||
| 7c3e4119dd | |||
| 20e9f108e8 | |||
| dad49f59fb | |||
| 455484e524 | |||
| e70904b99d | |||
| fef58dee3b | |||
| 995505fc43 | |||
| c10c9453e9 | |||
| ae23b508da | |||
| aedb263d2b | |||
| 6a93988d15 | |||
| 6fc12af3d9 | |||
| d7daff286b | |||
| d8623963fe | |||
| e8da8085a1 | |||
| 04e85ee881 | |||
| efcff4f0be | |||
| ed19a6a323 | |||
| 54a65ca132 | |||
| 1c10198bb9 | |||
| f02eea99dd | |||
| e8a6b664c1 | |||
| 597c6e6346 | |||
| d4d8c335e7 | |||
| 6b2b5991fc | |||
| 869c3d1fc0 | |||
| fc1b2f4641 | |||
| 72a67f034a | |||
| ce344f6bba | |||
| c3f1ff141c | |||
| a3eee043b3 | |||
| 0c5f405503 | |||
| 499804d53b | |||
| 49a6782244 | |||
| 2c9efba0bd | |||
| b73aeafb5c | |||
| 616085d2a5 | |||
| 42c7939474 | |||
| 3538a0ad62 | |||
| 6925034cf3 | |||
| 50d5356ee4 | |||
| c242f05afe | |||
| 3b23f20268 | |||
| 3fba657d40 | |||
| 3c1ef25e2c | |||
| 569ab66016 | |||
| 84aab421a0 | |||
| 86ad16ef4b | |||
| 2fe742f169 | |||
| d7e32cc638 | |||
| 63e271e5e4 | |||
| ee93f36a4c | |||
| bdd4236d1a | |||
| c2c35b303a | |||
| b9ef5b1a69 | |||
| 3e0c752a13 | |||
| cafbd71c74 | |||
| 423cea6d41 | |||
| 850febf328 | |||
| 5d1719b92e | |||
| d998e4cacb | |||
| eda9ab60de | |||
| 13a02fa692 | |||
| 36c0727828 | |||
| e1ffa79236 | |||
| e33e3b4853 | |||
| 62eacdc5ff | |||
| 40b5ff344b | |||
| d8ae158d24 | |||
| 5fdb292690 | |||
| a0a116901d | |||
| 5a34a0fd2e | |||
| 5435326fb9 | |||
| ff453821bf | |||
| 03ac47a264 | |||
| a17f046a92 | |||
| 1b0db86edf | |||
| 77863d7a27 | |||
| 03435fce9c | |||
| f9598604e2 | |||
| edd715b993 | |||
| a8b777e5b7 | |||
| 3282285b3c | |||
| 564aa7cd8a | |||
| 81047222c6 | |||
| 329f55978f | |||
| 01b14279b3 | |||
| 630bb45eb1 | |||
| 779103ed32 | |||
| fbd0511a76 | |||
| da0a7d7b5d | |||
| da020726ec | |||
| 79f05a0799 | |||
| 2d832d1752 | |||
| 550485c07c | |||
| 3566972527 | |||
| ca21753d73 | |||
| 70abb7121c | |||
| 4e9c802da9 | |||
| 651c138b97 | |||
| 318bd7ee7d | |||
| 7929b20516 | |||
| 20c8d0e2f6 | |||
| 3628cd751a | |||
| 996ae30df8 | |||
| 7b32d598e4 | |||
| 5edf4c2368 | |||
| 9bec4084d8 | |||
| 700e62c9d4 | |||
| 9fa16fca40 | |||
| 5f0b2c8a35 | |||
| f41faaf9af | |||
| 3dd2b14e5a | |||
| 3d2fa05b1f | |||
| f8888fdbb2 | |||
| 8e5e90032c | |||
| 86df085723 | |||
| b57ab86b8f | |||
| 79c1a76427 | |||
| 7acca71a45 | |||
| 925ff098d0 | |||
| 4edcc578aa | |||
| 153f045b00 | |||
| ba03261f1e | |||
| 50fe563e1a | |||
| 31c9b29521 | |||
| b1ce729ec9 | |||
| ffc3678cb9 | |||
| 5772868738 | |||
| 4529f71896 | |||
| 8b53842bcd | |||
| 5c2bc52b55 | |||
| e704f4d05a | |||
| fa3febf0b6 | |||
| 2814cfb36e | |||
| 8aa2736e4a | |||
| a2b216443a | |||
| 487e32a7b9 | |||
| 2950c747c9 | |||
| f39cc79dff | |||
| b62eb995d8 | |||
| e45aa41ae8 | |||
| ee1d70a1db | |||
| 66b5ebda32 | |||
| 08beae250b | |||
| 3de204d857 | |||
| a2fe0b9383 | |||
| e655247a01 | |||
| 27eefde3b3 | |||
| 708648e414 | |||
| 6e9fcf2518 | |||
| d7316e895a | |||
| 01c34f46dd | |||
| 65305f3609 | |||
| 2cd5b5764a | |||
| a52fe9884b | |||
| c95e117857 | |||
| 5f2d4ce7a6 | |||
| d988621b4d | |||
| 9d40ed8086 | |||
| 9750a558f2 | |||
| feb0c634a4 | |||
| 89c6e28970 | |||
| 5224cdf30c | |||
| c85ef77c21 | |||
| cebcc61496 | |||
| 7cf71a7c8b | |||
| 4bffcd665c | |||
| 4fb9938049 | |||
| 419eb17f65 | |||
| 20cc517457 | |||
| a30bcffeec | |||
| e1f4d1d811 | |||
| dea3a30149 | |||
| 2c2e13d966 | |||
| 65c0b7a57a | |||
| 2b6dd690f4 | |||
| 292e7646b6 | |||
| 9c137be6ae | |||
| c711167d3f | |||
| 4c388212eb | |||
| b843aa2f03 | |||
| 8d1fba000a | |||
| e9f0634d29 | |||
| a69b70af1e | |||
| 341db9e625 | |||
| 67d2c12640 | |||
| c0fae24dcd | |||
| 05d9aaa01d | |||
| 8cd97ec3e1 | |||
| 58e2fccf95 | |||
| 4b541d462a | |||
| 310ac4e0a6 | |||
| 53b44961ea | |||
| 8271e64cf7 | |||
| 27438984e1 | |||
| 0fb7de74ce | |||
| 3db02b0560 | |||
| e2dfb6bc94 | |||
| 55dbbdb636 | |||
| 308ccc1426 | |||
| 7f1a011b1b | |||
| d102d41f6b | |||
| 91def2febc | |||
| 7ea444276b | |||
| f810a8a28f | |||
| 2acf47a872 | |||
| 906136245a | |||
| a053753e10 | |||
| e996296b7f | |||
| d4a31dc8fc | |||
| c8ca2734e0 | |||
| 03e8ae8d1d | |||
| d626eb355f | |||
| 862c124366 | |||
| 3c2cf893be | |||
| ac8f014377 | |||
| d0e16c0a2a | |||
| cb926a1dec | |||
| 7aac1d6c28 | |||
| 25a982f9c3 | |||
| 76da9c0fd1 | |||
| a9d167acda | |||
| 32960f39b0 | |||
| 3e1c1ded67 | |||
| e19da058f6 | |||
| 80b5a4a350 | |||
| 5c10a738cb | |||
| 855b776ca2 | |||
| 735016e676 | |||
| 46897f0e66 | |||
| f1918e06cb | |||
| 3405d0e3c2 | |||
| c280251e3c | |||
| 0954c245c3 | |||
| 1aa44434b3 | |||
| c1bd08b3e4 | |||
| f298364a37 | |||
| e061670880 | |||
| 6680283cea | |||
| cb6b1345e0 | |||
| 09a83236ab | |||
| a68bae3288 | |||
| a7f4073f0b | |||
| 8248854ce7 | |||
| 88f225f564 | |||
| 8c1ba13449 | |||
| eb7cef099b | |||
| 8ae8d2f7bf | |||
| 33d41e2a84 | |||
| ca816760c8 | |||
| 31d6121273 | |||
| 8bc299739d | |||
| 263cb2ecb7 | |||
| c7e37147a7 | |||
| 34c880aa5c | |||
| 165dba73a4 | |||
| f2770d7a44 | |||
| b7c4cac550 | |||
| 656a82cf17 | |||
| 3d4ece2561 | |||
| 52b16e9ef0 | |||
| a07347cc22 |
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"directory": "lib/",
|
||||
"analytics": false
|
||||
}
|
||||
@@ -1 +1,13 @@
|
||||
node_modules
|
||||
*.zip
|
||||
*.zip.sig
|
||||
bower_components
|
||||
archives/
|
||||
/css/
|
||||
dev/
|
||||
.wti
|
||||
*~
|
||||
/tmp/
|
||||
lib/favico.js/
|
||||
lib/strophe.bookmarks/
|
||||
lib/strophe.x/
|
||||
|
||||
@@ -1,6 +1,15 @@
|
||||
[submodule "lib/strophe.jingle"]
|
||||
path = lib/strophe.jingle
|
||||
url = https://github.com/sualko/strophe.jingle.git
|
||||
[submodule "lib/otr"]
|
||||
path = lib/otr
|
||||
url = https://github.com/sualko/otr.git
|
||||
[submodule "lib/i18next"]
|
||||
path = lib/i18next
|
||||
url = https://github.com/i18next/i18next.git
|
||||
[submodule "lib/bootstrap"]
|
||||
path = lib/bootstrap
|
||||
url = https://github.com/twbs/bootstrap-sass/
|
||||
[submodule "lib/magnific-popup"]
|
||||
path = lib/magnific-popup
|
||||
url = https://github.com/dimsemenov/Magnific-Popup
|
||||
[submodule "lib/strophe.jinglejs"]
|
||||
path = lib/strophe.jinglejs
|
||||
url = https://github.com/sualko/strophe.jinglejs
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"indent_size": 3,
|
||||
"indent_char": " ",
|
||||
"end_with_newline": true
|
||||
}
|
||||
@@ -14,11 +14,15 @@
|
||||
"multistr": true,
|
||||
"devel": true,
|
||||
"globals": {
|
||||
"t":true,
|
||||
"i18n":true,
|
||||
"I18next":true,
|
||||
"OTR":true,
|
||||
"DSA":true,
|
||||
"Worker":true,
|
||||
"BigInt":true,
|
||||
"Notification":true,
|
||||
"$": true,
|
||||
"jQuery":true,
|
||||
"Strophe":true,
|
||||
"localStorage":true,
|
||||
@@ -29,6 +33,7 @@
|
||||
"jsxc":true,
|
||||
"getUserMediaWithConstraints":true,
|
||||
"setupRTC":true,
|
||||
"SDPUtil":true
|
||||
"SDPUtil":true,
|
||||
"getSelection":true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,162 @@
|
||||
v2.1.4 / 2015-09-10
|
||||
===
|
||||
- remove leading at sign from comments in build file
|
||||
|
||||
v2.1.3 / 2015-09-08
|
||||
===
|
||||
- fix bookmark loading
|
||||
- show unread notifications only if the chat window has no focus
|
||||
|
||||
v2.1.2 / 2015-08-12
|
||||
===
|
||||
- update grunt-sass (fix invalid css)
|
||||
|
||||
v2.1.1 / 2015-08-10
|
||||
===
|
||||
- update strophe.jingle (fix login with safari and older versions of ie, ff, chrome)
|
||||
- update favico.js
|
||||
- fix undefined error variable in ie
|
||||
- fix handling of escaped jids (e.g. used in transports)
|
||||
- fix placeholder replacement
|
||||
- rearrange bootstrap import
|
||||
- add option for custom online user manual
|
||||
|
||||
v2.1.0 / 2015-07-31
|
||||
===
|
||||
- add bookmark feature for rooms (XEP-0048)
|
||||
- add reserved room feature for muc (XEP-0045#10.1.3)
|
||||
- add counter of unread messages to roster, window and favicon
|
||||
- add join as URI query type
|
||||
- add ru language
|
||||
- add roster resize hint
|
||||
- make dialog responsive
|
||||
- allow messages to persons without valid friendship
|
||||
- replace video library for more stable connection
|
||||
- fix dsa key generation in chrome > 42
|
||||
- fix minor roster ui issues
|
||||
|
||||
- add jsbeautifier and prettysass
|
||||
- improve example
|
||||
- extract templates to single files
|
||||
- replace colorbox with magnific popup
|
||||
- use parts of bootstrap
|
||||
- replace strophe.jingle with strophe.jinglejs (jingle.js)
|
||||
- concatenate strings for better translatability
|
||||
- add new option attach if login form was found
|
||||
- add new option loginForm.startMinimized
|
||||
- add new option loginForm.enable (deprecates xmpp.onlogin)
|
||||
- add new option RTCPeerConfig.url (deprecates turnCredentialsPath)
|
||||
- ICE servers can now be passed as init option
|
||||
- loadSettings option is no longer required and supports now async requests
|
||||
|
||||
v2.0.1 / 2015-05-23
|
||||
===
|
||||
- improve login box
|
||||
- fix browsers without CSPRNG generator
|
||||
- fix ajax login after credential failure
|
||||
- fix some webrtc issues
|
||||
- fix login with different username after dirty logout
|
||||
- remove ie (<11) gradient
|
||||
- remove broken mitm detection
|
||||
- fix temporary template 404
|
||||
- fix login option
|
||||
- add connecting event
|
||||
|
||||
v2.0.0 / 2015-05-08
|
||||
===
|
||||
- add multi-user chat (XEP-0045)
|
||||
- add window resize handle
|
||||
- add username autocomplete
|
||||
- add offline state
|
||||
- add Italian, French, Polish, Portuguese/Brazil
|
||||
- use user avatar as notification icon
|
||||
- show notifications if tabs has no focus
|
||||
- split files into namespaces
|
||||
- sass improvements
|
||||
- replace own translation engine with i18next
|
||||
- fix login from login box
|
||||
- fix selection of chat messages
|
||||
- fix video calls
|
||||
- fix emoticons
|
||||
- fix duplicated roster items
|
||||
- fix notification request
|
||||
- fix logout
|
||||
|
||||
v1.1.0a / 2015-02-25
|
||||
===
|
||||
- fix css url path
|
||||
|
||||
v1.1.0 / 2015-01-08
|
||||
===
|
||||
- move from plain css to sass
|
||||
- show avatar also by EXTVAL (url), not only by BINVAL
|
||||
- add XEP-0280 (Message Carbons)
|
||||
- add XEP-0297 (Stanza Forwarding)
|
||||
- add option to disable otr
|
||||
- add timestamp to messages
|
||||
- add ajax/prebind login
|
||||
- fix offline subscription request
|
||||
- fix hide offline contacts
|
||||
- fix error with multiple own resources
|
||||
- fix avatars with newlines
|
||||
|
||||
v1.0.0 / 2014-11-06
|
||||
===
|
||||
- add unread flag to roster and scroll to target window
|
||||
- add XEP-0147 URI Scheme Query support
|
||||
- add has-come-online notification
|
||||
- add silent notification request
|
||||
- add more information in vCard view
|
||||
- add resizable function to chat window
|
||||
- add vertical scrollbar to window list
|
||||
- add call information to chat window
|
||||
- add concatinated and uglified files
|
||||
- add translations
|
||||
- minor video call improvements
|
||||
- minor style improvements
|
||||
- generate dsa key complete in background
|
||||
- update caps node property to jsxc.org
|
||||
- update strophe.jingle
|
||||
- update otr
|
||||
- fix wrong avatars
|
||||
- fix minor message delivery errors
|
||||
- fix ff snapshot security error
|
||||
- fix case sensitive resource handling
|
||||
- fix non-square avatars
|
||||
- fix several video issues
|
||||
- fix messages from unknown (not in roster) jid
|
||||
- fix vcard retrieval from unknown (not in roster) jid
|
||||
- fix vcard in second tab
|
||||
- fix jids with non-word characters (replace user identifier)
|
||||
- improve video window design
|
||||
- improve user info
|
||||
- improve login box
|
||||
- improve smp user interaction
|
||||
- improve notifications (sync sound/message, icon)
|
||||
- minor chat window improvements
|
||||
- detect email in message
|
||||
- detect uri scheme in message
|
||||
- end all private conversations on logout
|
||||
- remove email pattern from contact dialog
|
||||
- disable video on second tab
|
||||
- add/require disco dtls feature for webrtc
|
||||
- move emoticons to css
|
||||
- handle loadSettings failure
|
||||
- change cursor for some elements
|
||||
- prevent event bubbling for dialog
|
||||
|
||||
v0.8.2 / 2014-08-20
|
||||
===
|
||||
- fix use of custom username
|
||||
- write to console only if debug flag is set
|
||||
- allow string|boolean as config param
|
||||
- add translations
|
||||
|
||||
v0.8.1 / 2014-08-12
|
||||
===
|
||||
- add user-defined xmpp options
|
||||
- fix login form without id submit
|
||||
|
||||
v0.8.0 / 2014-07-02
|
||||
===
|
||||
- add spanish translation
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
You find all information in our [contributor guide](https://github.com/jsxc/jsxc/wiki/Contributor-Guide).
|
||||
@@ -1,12 +1,20 @@
|
||||
/* global module:false */
|
||||
module.exports = function(grunt) {
|
||||
|
||||
var dep = grunt.file.readJSON('dep.json');
|
||||
var dep_files = dep.map(function(el) {
|
||||
return '<%= target %>/' + el.file;
|
||||
});
|
||||
|
||||
var git_cached = [];
|
||||
|
||||
// Project configuration.
|
||||
grunt.initConfig({
|
||||
app: grunt.file.readJSON('package.json'),
|
||||
meta: {
|
||||
banner: grunt.file.read('banner.js')
|
||||
},
|
||||
target: 'dev',
|
||||
jshint: {
|
||||
options: {
|
||||
jshintrc: '.jshintrc'
|
||||
@@ -14,18 +22,28 @@ module.exports = function(grunt) {
|
||||
gruntfile: {
|
||||
src: 'Gruntfile.js'
|
||||
},
|
||||
files: [ 'jsxc.lib.webrtc.js', 'jsxc.lib.js' ]
|
||||
files: ['src/jsxc.lib.*.js']
|
||||
},
|
||||
copy: {
|
||||
main: {
|
||||
files: [ {
|
||||
files: [{
|
||||
expand: true,
|
||||
src: [ 'lib/strophe.jingle/*.js', 'lib/otr/build/**', 'lib/otr/lib/dsa-webworker.js', 'lib/otr/lib/sm-webworker.js', 'lib/otr/lib/const.js', 'lib/otr/lib/helpers.js', 'lib/otr/lib/dsa.js', 'lib/otr/vendor/*.js', 'lib/*.js', 'jsxc.lib.js', 'jsxc.lib.webrtc.js', '*.css', 'LICENSE', 'img/**', 'sound/**' ],
|
||||
dest: 'build/'
|
||||
} ]
|
||||
src: ['lib/i18next/release/i18next-latest.min.js', 'lib/magnific-popup/dist/*.js', 'lib/favico.js/favico.js', 'lib/strophe.x/*.js', 'lib/strophe.bookmarks/*.js', 'lib/strophe.jinglejs/*-bundle.js', 'lib/otr/build/**', 'lib/otr/lib/dsa-webworker.js', 'lib/otr/lib/sm-webworker.js', 'lib/otr/lib/const.js', 'lib/otr/lib/helpers.js', 'lib/otr/lib/dsa.js', 'lib/otr/vendor/*.js', 'lib/*.js', 'LICENSE', 'img/**', 'sound/**'],
|
||||
dest: '<%= target %>/'
|
||||
}, {
|
||||
expand: true,
|
||||
cwd: 'lib/',
|
||||
src: ['*.css'],
|
||||
dest: '<%= target %>/css/'
|
||||
}, {
|
||||
expand: true,
|
||||
cwd: 'lib/magnific-popup/dist/',
|
||||
src: ['*.css'],
|
||||
dest: '<%= target %>/css/'
|
||||
}]
|
||||
}
|
||||
},
|
||||
clean: [ 'build/' ],
|
||||
clean: ['<%= target %>/'],
|
||||
usebanner: {
|
||||
dist: {
|
||||
options: {
|
||||
@@ -33,18 +51,293 @@ module.exports = function(grunt) {
|
||||
banner: '<%= meta.banner %>'
|
||||
},
|
||||
files: {
|
||||
src: [ 'build/*.js' ]
|
||||
src: ['<%= target %>/*.js']
|
||||
}
|
||||
}
|
||||
},
|
||||
replace: {
|
||||
version: {
|
||||
src: [ 'build/jsxc.lib.js' ],
|
||||
src: ['<%= target %>/jsxc.js'],
|
||||
overwrite: true,
|
||||
replacements: [ {
|
||||
replacements: [{
|
||||
from: '< $ app.version $ >',
|
||||
to: "<%= app.version %>"
|
||||
} ]
|
||||
}]
|
||||
},
|
||||
libraries: {
|
||||
src: ['<%= target %>/jsxc.js'],
|
||||
overwrite: true,
|
||||
replacements: [{
|
||||
from: '<$ dep.libraries $>',
|
||||
to: function() {
|
||||
var i, d, libraries = '';
|
||||
|
||||
for (i = 0; i < dep.length; i++) {
|
||||
d = dep[i];
|
||||
if (typeof d.name === 'string') {
|
||||
libraries += '<a href="' + d.url + '">' + d.name + '</a> (' + d.license + '), ';
|
||||
}
|
||||
}
|
||||
|
||||
return libraries.replace(/, $/, '');
|
||||
}
|
||||
}]
|
||||
},
|
||||
locales: {
|
||||
src: ['<%= target %>/lib/translation.js'],
|
||||
overwrite: true,
|
||||
replacements: [{
|
||||
from: /^{/g,
|
||||
to: 'var I18next = {'
|
||||
}, {
|
||||
from: /}$/g,
|
||||
to: '};'
|
||||
}]
|
||||
},
|
||||
template: {
|
||||
src: ['tmp/template.js'],
|
||||
overwrite: true,
|
||||
replacements: [{
|
||||
from: 'var jsxc.gui.template = {};',
|
||||
to: ''
|
||||
}]
|
||||
},
|
||||
imageUrl: {
|
||||
src: ['<%= target %>/css/*.css'],
|
||||
overwrite: true,
|
||||
replacements: [{
|
||||
from: /image-url\(["'](.+)["']\)/g,
|
||||
to: 'url(\'../img/$1\')'
|
||||
}]
|
||||
},
|
||||
// IE 10 does not like comments starting with @
|
||||
todo: {
|
||||
src: ['build/jsxc.js'],
|
||||
overwrite: true,
|
||||
replacements: [{
|
||||
from: /\/\/@(.*)/g,
|
||||
to: '//$1'
|
||||
}]
|
||||
}
|
||||
},
|
||||
merge_data: {
|
||||
target: {
|
||||
src: ['locales/*.{json,y{,a}ml}'],
|
||||
dest: '<%= target %>/lib/translation.js'
|
||||
}
|
||||
},
|
||||
concat: {
|
||||
dep: {
|
||||
options: {
|
||||
banner: '/*!\n' +
|
||||
' * <%= app.name %> v<%= app.version %> - <%= grunt.template.today("yyyy-mm-dd") %>\n' +
|
||||
' * \n' +
|
||||
' * This file concatenates all dependencies of <%= app.name %>.\n' +
|
||||
' * \n' +
|
||||
' */\n\n',
|
||||
process: function(src, filepath) {
|
||||
filepath = filepath.replace(/^[a-z]+\//i, '');
|
||||
|
||||
if (filepath === 'lib/otr/build/dep/crypto.js') {
|
||||
src += ';';
|
||||
}
|
||||
|
||||
var data = dep[dep_files.indexOf('<%= target %>/' + filepath)];
|
||||
|
||||
if (data) {
|
||||
return '\n/*!\n * Source: ' + filepath + ', license: ' + data.license + ', url: ' + data.url + '\n */\n' + src;
|
||||
} else {
|
||||
return src;
|
||||
}
|
||||
}
|
||||
},
|
||||
src: dep_files,
|
||||
dest: '<%= target %>/lib/jsxc.dep.js'
|
||||
},
|
||||
jsxc: {
|
||||
options: {
|
||||
banner: '/*! This file is concatenated for the browser. */\n\n'
|
||||
},
|
||||
src: ['src/jsxc.intro.js', 'src/jsxc.lib.js', 'src/jsxc.lib.xmpp.js', 'src/jsxc.lib.*.js', 'tmp/template.js', 'src/jsxc.outro.js'],
|
||||
dest: '<%= target %>/jsxc.js'
|
||||
}
|
||||
},
|
||||
uglify: {
|
||||
jsxc: {
|
||||
options: {
|
||||
mangle: false,
|
||||
sourceMap: true,
|
||||
preserveComments: 'some'
|
||||
},
|
||||
files: {
|
||||
'<%= target %>/lib/jsxc.dep.min.js': ['<%= target %>/lib/jsxc.dep.js'],
|
||||
'<%= target %>/jsxc.min.js': ['<%= target %>/jsxc.js']
|
||||
}
|
||||
}
|
||||
},
|
||||
search: {
|
||||
console: {
|
||||
files: {
|
||||
src: ['src/*.js']
|
||||
},
|
||||
options: {
|
||||
searchString: /console\.log\((?!'[<>]|msg)/g,
|
||||
logFormat: 'console',
|
||||
failOnMatch: true
|
||||
}
|
||||
},
|
||||
changelog: {
|
||||
files: {
|
||||
src: ['CHANGELOG.md']
|
||||
},
|
||||
options: {
|
||||
searchString: "<%= app.version %>",
|
||||
logFormat: 'console',
|
||||
onComplete: function(m) {
|
||||
if (m.numMatches === 0) {
|
||||
grunt.fail.fatal("No entry in CHANGELOG.md for current version found.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
compress: {
|
||||
main: {
|
||||
options: {
|
||||
archive: "archives/jsxc-<%= app.version %>.zip"
|
||||
},
|
||||
files: [{
|
||||
src: ['**'],
|
||||
expand: true,
|
||||
dest: 'jsxc/',
|
||||
cwd: 'build/'
|
||||
}]
|
||||
}
|
||||
},
|
||||
dataUri: {
|
||||
dist: {
|
||||
src: '<%= target %>/css/*.css',
|
||||
dest: '<%= target %>/css/',
|
||||
options: {
|
||||
target: ['<%= target %>/img/*.*', '<%= target %>/img/**/*.*'],
|
||||
fixDirLevel: false,
|
||||
maxBytes: 2048
|
||||
}
|
||||
}
|
||||
},
|
||||
jsdoc: {
|
||||
dist: {
|
||||
src: ['src/jsxc.lib.*'],
|
||||
dest: 'doc'
|
||||
}
|
||||
},
|
||||
autoprefixer: {
|
||||
no_dest: {
|
||||
src: '<%= target %>/css/*.css'
|
||||
}
|
||||
},
|
||||
csslint: {
|
||||
strict: {
|
||||
options: {
|
||||
import: 2
|
||||
},
|
||||
src: ['<%= target %>/css/*.css']
|
||||
},
|
||||
},
|
||||
sass: {
|
||||
dist: {
|
||||
files: {
|
||||
'<%= target %>/css/jsxc.css': 'scss/jsxc.scss',
|
||||
'<%= target %>/css/jsxc.webrtc.css': 'scss/jsxc.webrtc.scss'
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
locales: {
|
||||
files: ['locales/*'],
|
||||
tasks: ['merge_data', 'replace:locales', 'concat:dep']
|
||||
},
|
||||
css: {
|
||||
files: ['scss/*'],
|
||||
tasks: ['sass', 'autoprefixer']
|
||||
},
|
||||
js: {
|
||||
files: ['src/jsxc.lib.*'],
|
||||
tasks: ['concat:jsxc']
|
||||
},
|
||||
template: {
|
||||
files: ['template/*.html'],
|
||||
tasks: ['htmlConvert', 'replace:template', 'concat:jsxc']
|
||||
}
|
||||
},
|
||||
jsbeautifier: {
|
||||
files: ['Gruntfile.js', 'src/jsxc.lib.*', 'template/*.html', 'example/*.html', 'example/js/dev.js', 'example/js/example.js', 'example/css/example.css'],
|
||||
options: {
|
||||
config: '.jsbeautifyrc'
|
||||
}
|
||||
},
|
||||
prettysass: {
|
||||
options: {
|
||||
alphabetize: false,
|
||||
indent: 4
|
||||
},
|
||||
jsxc: {
|
||||
src: ['scss/*.scss']
|
||||
}
|
||||
},
|
||||
htmlConvert: {
|
||||
options: {
|
||||
target: 'js',
|
||||
rename: function(name) {
|
||||
return name.match(/([-_0-9a-z]+)\.html$/i)[1];
|
||||
},
|
||||
quoteChar: '\'',
|
||||
indentString: '',
|
||||
indentGlobal: ''
|
||||
},
|
||||
'jsxc.gui.template': {
|
||||
src: 'template/*.html',
|
||||
dest: 'tmp/template.js'
|
||||
}
|
||||
},
|
||||
shell: {
|
||||
'precommit-before': {
|
||||
command: 'git diff --cached --name-only',
|
||||
options: {
|
||||
callback: function(err, stdout, stderr, cb) {
|
||||
git_cached = stdout.trim().split(/\n/);
|
||||
|
||||
cb();
|
||||
}
|
||||
}
|
||||
},
|
||||
'precommit-after': {
|
||||
command: 'git diff --name-only',
|
||||
options: {
|
||||
callback: function(err, stdout, stderr, cb) {
|
||||
var git_diff = stdout.trim().split(/\n/);
|
||||
var intersection = [];
|
||||
var i;
|
||||
|
||||
for (i = 0; i < git_diff.length; i++) {
|
||||
if (git_cached.indexOf(git_diff[i]) >= 0) {
|
||||
intersection.push(git_diff[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (intersection.length > 0) {
|
||||
grunt.log.writeln();
|
||||
|
||||
for (i = 0; i < intersection.length; i++) {
|
||||
grunt.log.writeln('> ' + intersection[i]);
|
||||
}
|
||||
|
||||
grunt.fail.warn('Some files changed during pre-commit hook!');
|
||||
}
|
||||
|
||||
cb();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -53,10 +346,44 @@ module.exports = function(grunt) {
|
||||
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||
grunt.loadNpmTasks('grunt-contrib-copy');
|
||||
grunt.loadNpmTasks('grunt-contrib-clean');
|
||||
grunt.loadNpmTasks('grunt-contrib-concat');
|
||||
grunt.loadNpmTasks('grunt-contrib-uglify');
|
||||
grunt.loadNpmTasks('grunt-banner');
|
||||
grunt.loadNpmTasks('grunt-text-replace');
|
||||
grunt.loadNpmTasks('grunt-search');
|
||||
grunt.loadNpmTasks('grunt-contrib-compress');
|
||||
grunt.loadNpmTasks('grunt-jsdoc');
|
||||
grunt.loadNpmTasks('grunt-data-uri');
|
||||
grunt.loadNpmTasks('grunt-merge-data');
|
||||
grunt.loadNpmTasks('grunt-contrib-csslint');
|
||||
grunt.loadNpmTasks('grunt-sass');
|
||||
grunt.loadNpmTasks('grunt-autoprefixer');
|
||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||
grunt.loadNpmTasks('grunt-jsbeautifier');
|
||||
grunt.loadNpmTasks('grunt-prettysass');
|
||||
grunt.loadNpmTasks('grunt-html-convert');
|
||||
grunt.loadNpmTasks('grunt-shell');
|
||||
|
||||
// Default task.
|
||||
grunt.registerTask('default', [ 'jshint', 'clean', 'copy', 'usebanner', 'replace' ]);
|
||||
//Default task
|
||||
grunt.registerTask('default', ['build', 'watch']);
|
||||
|
||||
grunt.registerTask('build', ['jshint', 'clean', 'sass', 'replace:imageUrl', 'autoprefixer', 'copy', 'merge_data', 'replace:locales', 'htmlConvert', 'replace:template', 'concat']);
|
||||
|
||||
grunt.registerTask('build:prerelease', 'Build a new pre-release', function() {
|
||||
grunt.config.set('target', 'build');
|
||||
|
||||
grunt.task.run(['search:console', 'build', 'dataUri', 'usebanner', 'replace:version', 'replace:libraries', 'replace:todo', 'uglify', 'compress']);
|
||||
});
|
||||
|
||||
grunt.registerTask('build:release', 'Build a new release', function() {
|
||||
grunt.config.set('target', 'build');
|
||||
|
||||
grunt.task.run(['search:changelog', 'build:prerelease', 'jsdoc']);
|
||||
});
|
||||
|
||||
// Create alpha/beta build @deprecated
|
||||
grunt.registerTask('pre', ['build:prerelease']);
|
||||
|
||||
// before commit
|
||||
grunt.registerTask('commit', ['shell:precommit-before', 'search:console', 'jsbeautifier', 'prettysass', 'jshint', 'shell:precommit-after']);
|
||||
};
|
||||
|
||||
@@ -4,21 +4,4 @@ Real-time chat app. This app requires an external XMPP server (openfire, ejabber
|
||||
|
||||
You find a list of features, supported protocols and browsers at the homepage of __[Javascript XMPP Client](http://www.jsxc.org)__.
|
||||
|
||||
## Developer notes
|
||||
|
||||
Please execute the following commands to get a copy of the code:
|
||||
|
||||
```
|
||||
git clone https://github.com/sualko/jsxc/
|
||||
git submodule update --init
|
||||
```
|
||||
|
||||
### Libaries
|
||||
- jQuery (http://jquery.com/)
|
||||
- Strophe.js (http://strophe.im/strophejs/)
|
||||
- Strophe.js Plugins (https://github.com/strophe/strophejs-plugins)
|
||||
- OTR (https://github.com/arlolra/otr)
|
||||
- strophe.jingle (https://github.com/ESTOS/strophe.jingle)
|
||||
|
||||
### Events
|
||||
coming soon...
|
||||
If you are looking for install instructions or developer notes, please also checkout our [wiki](https://github.com/jsxc/jsxc/wiki/).
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/**
|
||||
/*!
|
||||
* <%= app.name %> v<%= app.version %> - <%= grunt.template.today("yyyy-mm-dd") %>
|
||||
*
|
||||
* Copyright (c) <%= grunt.template.today("yyyy") %> <%= app.author %> <br>
|
||||
@@ -8,4 +8,5 @@
|
||||
*
|
||||
* @author <%= app.author %>
|
||||
* @version <%= app.version %>
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"name": "jsxc",
|
||||
"version": "2.1.2",
|
||||
"homepage": "https://www.jsxc.org",
|
||||
"authors": [
|
||||
"sualko <klaus@jsxc.org>"
|
||||
],
|
||||
"description": "Real-time chat app",
|
||||
"keywords": [
|
||||
"javascript",
|
||||
"xmpp",
|
||||
"webrtc",
|
||||
"otr",
|
||||
"chat",
|
||||
"realtime"
|
||||
],
|
||||
"license": "MIT",
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"bower_components",
|
||||
"lib/",
|
||||
"test",
|
||||
"tests"
|
||||
],
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"favico.js": "~0.3.9",
|
||||
"strophe.bookmarks": "https://raw.githubusercontent.com/sualko/strophejs-plugins/bookmarks/bookmarks/strophe.bookmarks.js",
|
||||
"strophe.x": "https://raw.githubusercontent.com/strophe/strophejs-plugins/master/dataforms/src/strophe.x.js"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
/* Remove close button from firstrunwizard */
|
||||
#closeWizard {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/*
|
||||
Colorbox Core Style:
|
||||
The following CSS is consistent between example themes and should not be altered.
|
||||
*/
|
||||
#colorbox,#cboxOverlay,#cboxWrapper {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9999;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#cboxWrapper {
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
#cboxOverlay {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#cboxMiddleLeft,#cboxBottomLeft {
|
||||
clear: left;
|
||||
}
|
||||
|
||||
#cboxContent {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#cboxLoadedContent {
|
||||
overflow: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
||||
#cboxTitle {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#cboxLoadingOverlay,#cboxLoadingGraphic {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#cboxPrevious,#cboxNext,#cboxClose,#cboxSlideshow {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.cboxPhoto {
|
||||
float: left;
|
||||
margin: auto;
|
||||
border: 0;
|
||||
display: block;
|
||||
max-width: none;
|
||||
-ms-interpolation-mode: bicubic;
|
||||
}
|
||||
|
||||
.cboxIframe {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: block;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
#colorbox,#cboxContent,#cboxLoadedContent {
|
||||
box-sizing: content-box;
|
||||
-moz-box-sizing: content-box;
|
||||
-webkit-box-sizing: content-box;
|
||||
}
|
||||
|
||||
/*
|
||||
User Style:
|
||||
Change the following styles to modify the appearance of Colorbox. They are
|
||||
ordered & tabbed in a way that represents the nesting of the generated HTML.
|
||||
*/
|
||||
#cboxOverlay {
|
||||
background: #000;
|
||||
}
|
||||
|
||||
#colorbox {
|
||||
|
||||
}
|
||||
|
||||
#cboxContent {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.cboxIframe {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
#cboxError {
|
||||
padding: 50px;
|
||||
border: 0px solid #ccc;
|
||||
}
|
||||
|
||||
#cboxLoadedContent {
|
||||
border: 0px solid #555;
|
||||
background: #fff;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
#cboxTitle {
|
||||
position: absolute;
|
||||
top: -20px;
|
||||
left: 0;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
#cboxCurrent {
|
||||
position: absolute;
|
||||
top: -20px;
|
||||
right: 0px;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
#cboxSlideshow {
|
||||
position: absolute;
|
||||
top: -20px;
|
||||
right: 90px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#cboxPrevious:hover {
|
||||
background-position: bottom left;
|
||||
}
|
||||
|
||||
#cboxNext:hover {
|
||||
background-position: bottom right;
|
||||
}
|
||||
|
||||
#cboxLoadingOverlay {
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
#cboxClose {
|
||||
position: absolute;
|
||||
top: 5px;
|
||||
right: 5px;
|
||||
display: block;
|
||||
opacity: 0.5;
|
||||
width: 19px !important;
|
||||
height: 19px;
|
||||
border: 0px;
|
||||
text-indent: -9999px;
|
||||
background-color: #fff;
|
||||
}
|
||||
#cboxClose:before {
|
||||
content: '×';
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
display: block;
|
||||
width: 19px;
|
||||
height: 19px;
|
||||
opacity: 0.5;
|
||||
text-indent: 0;
|
||||
text-align: center;
|
||||
line-height: 19px;
|
||||
font-size: 19px;
|
||||
}
|
||||
|
||||
#cboxClose:before:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#cboxClose:hover {
|
||||
background-position: right center !important;
|
||||
opacity: 1.0;
|
||||
}
|
||||
|
||||
/*
|
||||
The following fixes a problem where IE7 and IE8 replace a PNG's alpha transparency with a black fill
|
||||
when an alpha filter (opacity change) is set on the element or ancestor element. This style is not applied to or needed in IE9.
|
||||
See: http://jacklmoore.com/notes/ie-transparency-problems/
|
||||
*/
|
||||
.cboxIE #cboxTopLeft,.cboxIE #cboxTopCenter,.cboxIE #cboxTopRight,.cboxIE #cboxBottomLeft,.cboxIE #cboxBottomCenter,.cboxIE #cboxBottomRight,.cboxIE #cboxMiddleLeft,.cboxIE #cboxMiddleRight
|
||||
{
|
||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#00FFFFFF,
|
||||
endColorstr=#00FFFFFF);
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
.jsxc_remotevideo, .jsxc_noRemoteVideo {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 9000;
|
||||
background-color: #999999; }
|
||||
|
||||
.jsxc_webrtc {
|
||||
width: 900px; }
|
||||
.jsxc_webrtc .jsxc_status {
|
||||
z-index: 9999;
|
||||
border-radius: 20px;
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
left: 50%;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
color: #fff;
|
||||
padding: 15px;
|
||||
font-weight: bold;
|
||||
text-align: center; }
|
||||
.jsxc_webrtc .slimScrollDiv {
|
||||
opacity: 1 !important; }
|
||||
.jsxc_webrtc li .jsxc_name {
|
||||
cursor: auto; }
|
||||
.jsxc_webrtc li .jsxc_name:hover {
|
||||
color: gray; }
|
||||
|
||||
.jsxc_videoContainer {
|
||||
width: 640px;
|
||||
height: 480px;
|
||||
position: relative;
|
||||
background-color: #999999; }
|
||||
.jsxc_videoContainer video {
|
||||
display: none; }
|
||||
.jsxc_videoContainer .jsxc_noRemoteVideo {
|
||||
display: none; }
|
||||
|
||||
.jsxc_noRemoteVideo p {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
width: 100%;
|
||||
z-index: 100; }
|
||||
|
||||
.jsxc_noRemoteVideo > div {
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
margin-top: -100px;
|
||||
left: 50%;
|
||||
margin-left: -100px; }
|
||||
.jsxc_noRemoteVideo > div > div {
|
||||
background-color: #4d4d4d; }
|
||||
.jsxc_noRemoteVideo > div > div:first-child {
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
border-radius: 50%;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
margin-left: -25%;
|
||||
top: 10%; }
|
||||
.jsxc_noRemoteVideo > div > div:last-child {
|
||||
position: absolute;
|
||||
bottom: -50%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%; }
|
||||
|
||||
.jsxc_localvideo {
|
||||
width: 160px;
|
||||
height: 120px;
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
bottom: 10px;
|
||||
z-index: 9990;
|
||||
background-color: #000;
|
||||
cursor: pointer; }
|
||||
|
||||
div:full-screen {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #000; }
|
||||
div:full-screen.jsxc_localvideo {
|
||||
border: 1px solid #fff; }
|
||||
|
||||
div:-webkit-full-screen {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #000; }
|
||||
|
||||
div:-moz-full-screen {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #000; }
|
||||
|
||||
div:-ms-fullscreen {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #000; }
|
||||
|
||||
div:fullscreen {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: #000; }
|
||||
div:-webkit-full-screen.jsxc_localvideo {
|
||||
border: 1px solid #fff; }
|
||||
div:-moz-full-screen.jsxc_localvideo {
|
||||
border: 1px solid #fff; }
|
||||
div:-ms-fullscreen.jsxc_localvideo {
|
||||
border: 1px solid #fff; }
|
||||
div:fullscreen.jsxc_localvideo {
|
||||
border: 1px solid #fff; }
|
||||
|
||||
div.jsxc_video {
|
||||
background-image: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgeG1sbnM6ZGM9Imh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvIgogICB4bWxuczpjYz0iaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjIgogICB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiCiAgIHhtbG5zOnN2Zz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciCiAgIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKICAgdmVyc2lvbj0iMS4xIgogICBpZD0ic3ZnMiIKICAgd2lkdGg9IjIwIgogICBoZWlnaHQ9IjIwIj4KICA8bWV0YWRhdGEKICAgICBpZD0ibWV0YWRhdGExMCI+CiAgICA8cmRmOlJERj4KICAgICAgPGNjOldvcmsKICAgICAgICAgcmRmOmFib3V0PSIiPgogICAgICAgIDxkYzpmb3JtYXQ+aW1hZ2Uvc3ZnK3htbDwvZGM6Zm9ybWF0PgogICAgICAgIDxkYzp0eXBlCiAgICAgICAgICAgcmRmOnJlc291cmNlPSJodHRwOi8vcHVybC5vcmcvZGMvZGNtaXR5cGUvU3RpbGxJbWFnZSIgLz4KICAgICAgICA8ZGM6dGl0bGU+PC9kYzp0aXRsZT4KICAgICAgPC9jYzpXb3JrPgogICAgPC9yZGY6UkRGPgogIDwvbWV0YWRhdGE+CiAgPGRlZnMKICAgICBpZD0iZGVmczgiIC8+CiAgPGcKICAgICBpZD0ibGF5ZXIxIgogICAgIHRyYW5zZm9ybT0ibWF0cml4KDAuMDM3ODg1OTQsMCwwLDAuMDM3ODg1OTQsLTAuNDEzNDA3OTMsLTIuNjMxMDcxNikiPgogICAgPHBhdGgKICAgICAgIGlkPSJwYXRoMzkwNiIKICAgICAgIHN0eWxlPSJmaWxsOiM4MDgwODA7c3Ryb2tlOm5vbmUiCiAgICAgICBkPSJtIDM2MS42NTE0OCwzMTMuNTE3NjggMTc3LjE2MDc0LC0xMzEuNzg1MTYgMCwzMDIuMjI5OTkgTCAzNTguOTczMzgsMzUwLjE4NTE3IFogTSAxMC45MTE5MjIsMTgyLjQwNjM0IGwgMzc4LjM3MjY3OCwwIDAsMzAyLjY1NTgyIC0zNzguMzcyNjc4LDAgeiIgLz4KICA8L2c+Cjwvc3ZnPgo=');
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
background-size: 15px 15px; }
|
||||
div.jsxc_video:not(.jsxc_disabled):hover {
|
||||
background-image: url('../img/camera_icon_white.svg'); }
|
||||
|
||||
.jsxc_controlbar {
|
||||
width: 640px;
|
||||
margin-top: 10px; }
|
||||
.jsxc_controlbar .jsxc_showchat {
|
||||
float: right; }
|
||||
|
||||
.jsxc_multi > div {
|
||||
display: none; }
|
||||
|
||||
.jsxc_snapshotbar {
|
||||
width: 100%;
|
||||
display: none; }
|
||||
.jsxc_snapshotbar img {
|
||||
height: 50px; }
|
||||
|
||||
.jsxc_buttongroup {
|
||||
display: inline; }
|
||||
.jsxc_buttongroup button:first-child {
|
||||
border-top-right-radius: 0;
|
||||
border-bottom-right-radius: 0;
|
||||
margin-right: 0; }
|
||||
.jsxc_buttongroup button:last-child {
|
||||
border-top-left-radius: 0;
|
||||
border-bottom-left-radius: 0;
|
||||
margin-left: 0; }
|
||||
|
||||
.jsxc_chatarea {
|
||||
position: relative;
|
||||
float: right;
|
||||
height: 480px;
|
||||
width: 250px;
|
||||
background-color: #999999; }
|
||||
.jsxc_chatarea .jsxc_settings {
|
||||
display: none !important; }
|
||||
.jsxc_chatarea .jsxc_close {
|
||||
display: none !important; }
|
||||
.jsxc_chatarea .jsxc_video {
|
||||
display: none !important; }
|
||||
.jsxc_chatarea .jsxc_window {
|
||||
bottom: 0;
|
||||
box-shadow: none; }
|
||||
.jsxc_chatarea > ul {
|
||||
width: 250px;
|
||||
height: 480px;
|
||||
list-style: none;
|
||||
padding: 0; }
|
||||
|
||||
.bubblingG {
|
||||
text-align: center;
|
||||
width: 129px;
|
||||
height: 80px;
|
||||
position: absolute;
|
||||
top: 40%;
|
||||
left: 50%;
|
||||
margin-left: -64px; }
|
||||
.bubblingG span {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin: 40px auto;
|
||||
background: #000;
|
||||
border-radius: 81px;
|
||||
-webkit-animation: bubblingG 1.3s infinite alternate;
|
||||
animation: bubblingG 1.3s infinite alternate; }
|
||||
|
||||
#bubblingG_1 {
|
||||
-webkit-animation-delay: 0s;
|
||||
animation-delay: 0s; }
|
||||
|
||||
#bubblingG_2 {
|
||||
-webkit-animation-delay: 0.39s;
|
||||
animation-delay: 0.39s; }
|
||||
|
||||
#bubblingG_3 {
|
||||
-webkit-animation-delay: 0.78s;
|
||||
animation-delay: 0.78s; }
|
||||
|
||||
@-webkit-keyframes bubblingG {
|
||||
|
||||
0% {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-color: #000;
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0); }
|
||||
|
||||
100% {
|
||||
width: 39px;
|
||||
height: 39px;
|
||||
background-color: #fff;
|
||||
-webkit-transform: translateY(-34px);
|
||||
transform: translateY(-34px); } }
|
||||
|
||||
@keyframes bubblingG {
|
||||
0% {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-color: #000;
|
||||
-webkit-transform: translateY(0);
|
||||
transform: translateY(0); }
|
||||
100% {
|
||||
width: 39px;
|
||||
height: 39px;
|
||||
background-color: #fff;
|
||||
-webkit-transform: translateY(-34px);
|
||||
transform: translateY(-34px); } }
|
||||
|
||||
.jsxc_fullscreen.jsxc_localvideo {
|
||||
border: 1px solid #fff; }
|
||||
|
||||
.jsxc_videoSuitable .jsxc_name {
|
||||
font-style: italic; }
|
||||
|
||||
#jsxc_buddylist .jsxc_options .jsxc_video {
|
||||
background-image: url('../img/camera_icon_white.svg'); }
|
||||
#jsxc_buddylist .jsxc_options .jsxc_video.jsxc_disabled {
|
||||
opacity: 0.2; }
|
||||
@@ -0,0 +1,374 @@
|
||||
/* Magnific Popup CSS */
|
||||
.mfp-bg {
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 1042;
|
||||
overflow: hidden;
|
||||
position: fixed;
|
||||
background: #0b0b0b;
|
||||
opacity: 0.8;
|
||||
filter: alpha(opacity=80); }
|
||||
|
||||
.mfp-wrap {
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 1043;
|
||||
position: fixed;
|
||||
outline: none !important;
|
||||
-webkit-backface-visibility: hidden; }
|
||||
|
||||
.mfp-container {
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
padding: 0 8px;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box; }
|
||||
|
||||
.mfp-container:before {
|
||||
content: '';
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
vertical-align: middle; }
|
||||
|
||||
.mfp-align-top .mfp-container:before {
|
||||
display: none; }
|
||||
|
||||
.mfp-content {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
margin: 0 auto;
|
||||
text-align: left;
|
||||
z-index: 1045; }
|
||||
|
||||
.mfp-inline-holder .mfp-content, .mfp-ajax-holder .mfp-content {
|
||||
width: 100%;
|
||||
cursor: auto; }
|
||||
|
||||
.mfp-ajax-cur {
|
||||
cursor: progress; }
|
||||
|
||||
.mfp-zoom-out-cur, .mfp-zoom-out-cur .mfp-image-holder .mfp-close {
|
||||
cursor: -moz-zoom-out;
|
||||
cursor: -webkit-zoom-out;
|
||||
cursor: zoom-out; }
|
||||
|
||||
.mfp-zoom {
|
||||
cursor: pointer;
|
||||
cursor: -webkit-zoom-in;
|
||||
cursor: -moz-zoom-in;
|
||||
cursor: zoom-in; }
|
||||
|
||||
.mfp-auto-cursor .mfp-content {
|
||||
cursor: auto; }
|
||||
|
||||
.mfp-close, .mfp-arrow, .mfp-preloader, .mfp-counter {
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none; }
|
||||
|
||||
.mfp-loading.mfp-figure {
|
||||
display: none; }
|
||||
|
||||
.mfp-hide {
|
||||
display: none !important; }
|
||||
|
||||
.mfp-preloader {
|
||||
color: #CCC;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
width: auto;
|
||||
text-align: center;
|
||||
margin-top: -0.8em;
|
||||
left: 8px;
|
||||
right: 8px;
|
||||
z-index: 1044; }
|
||||
.mfp-preloader a {
|
||||
color: #CCC; }
|
||||
.mfp-preloader a:hover {
|
||||
color: #FFF; }
|
||||
|
||||
.mfp-s-ready .mfp-preloader {
|
||||
display: none; }
|
||||
|
||||
.mfp-s-error .mfp-content {
|
||||
display: none; }
|
||||
|
||||
button.mfp-close, button.mfp-arrow {
|
||||
overflow: visible;
|
||||
cursor: pointer;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
-webkit-appearance: none;
|
||||
display: block;
|
||||
outline: none;
|
||||
padding: 0;
|
||||
z-index: 1046;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none; }
|
||||
button::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border: 0; }
|
||||
|
||||
.mfp-close {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
line-height: 44px;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
opacity: 0.65;
|
||||
filter: alpha(opacity=65);
|
||||
padding: 0 0 18px 10px;
|
||||
color: #FFF;
|
||||
font-style: normal;
|
||||
font-size: 28px;
|
||||
font-family: Arial, Baskerville, monospace; }
|
||||
.mfp-close:hover, .mfp-close:focus {
|
||||
opacity: 1;
|
||||
filter: alpha(opacity=100); }
|
||||
.mfp-close:active {
|
||||
top: 1px; }
|
||||
|
||||
.mfp-close-btn-in .mfp-close {
|
||||
color: #333; }
|
||||
|
||||
.mfp-image-holder .mfp-close, .mfp-iframe-holder .mfp-close {
|
||||
color: #FFF;
|
||||
right: -6px;
|
||||
text-align: right;
|
||||
padding-right: 6px;
|
||||
width: 100%; }
|
||||
|
||||
.mfp-counter {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
color: #CCC;
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
white-space: nowrap; }
|
||||
|
||||
.mfp-arrow {
|
||||
position: absolute;
|
||||
opacity: 0.65;
|
||||
filter: alpha(opacity=65);
|
||||
margin: 0;
|
||||
top: 50%;
|
||||
margin-top: -55px;
|
||||
padding: 0;
|
||||
width: 90px;
|
||||
height: 110px;
|
||||
-webkit-tap-highlight-color: rgba(0, 0, 0, 0); }
|
||||
.mfp-arrow:active {
|
||||
margin-top: -54px; }
|
||||
.mfp-arrow:hover, .mfp-arrow:focus {
|
||||
opacity: 1;
|
||||
filter: alpha(opacity=100); }
|
||||
.mfp-arrow:before, .mfp-arrow:after, .mfp-arrow .mfp-b, .mfp-arrow .mfp-a {
|
||||
content: '';
|
||||
display: block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
margin-top: 35px;
|
||||
margin-left: 35px;
|
||||
border: medium inset transparent; }
|
||||
.mfp-arrow:after, .mfp-arrow .mfp-a {
|
||||
border-top-width: 13px;
|
||||
border-bottom-width: 13px;
|
||||
top: 8px; }
|
||||
.mfp-arrow:before, .mfp-arrow .mfp-b {
|
||||
border-top-width: 21px;
|
||||
border-bottom-width: 21px;
|
||||
opacity: 0.7; }
|
||||
|
||||
.mfp-arrow-left {
|
||||
left: 0; }
|
||||
.mfp-arrow-left:after, .mfp-arrow-left .mfp-a {
|
||||
border-right: 17px solid #FFF;
|
||||
margin-left: 31px; }
|
||||
.mfp-arrow-left:before, .mfp-arrow-left .mfp-b {
|
||||
margin-left: 25px;
|
||||
border-right: 27px solid #3F3F3F; }
|
||||
|
||||
.mfp-arrow-right {
|
||||
right: 0; }
|
||||
.mfp-arrow-right:after, .mfp-arrow-right .mfp-a {
|
||||
border-left: 17px solid #FFF;
|
||||
margin-left: 39px; }
|
||||
.mfp-arrow-right:before, .mfp-arrow-right .mfp-b {
|
||||
border-left: 27px solid #3F3F3F; }
|
||||
|
||||
.mfp-iframe-holder {
|
||||
padding-top: 40px;
|
||||
padding-bottom: 40px; }
|
||||
.mfp-iframe-holder .mfp-content {
|
||||
line-height: 0;
|
||||
width: 100%;
|
||||
max-width: 900px; }
|
||||
.mfp-iframe-holder .mfp-close {
|
||||
top: -40px; }
|
||||
|
||||
.mfp-iframe-scaler {
|
||||
width: 100%;
|
||||
height: 0;
|
||||
overflow: hidden;
|
||||
padding-top: 56.25%; }
|
||||
.mfp-iframe-scaler iframe {
|
||||
position: absolute;
|
||||
display: block;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
box-shadow: 0 0 8px rgba(0, 0, 0, 0.6);
|
||||
background: #000; }
|
||||
|
||||
/* Main image in popup */
|
||||
img.mfp-img {
|
||||
width: auto;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
display: block;
|
||||
line-height: 0;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
padding: 40px 0 40px;
|
||||
margin: 0 auto; }
|
||||
|
||||
/* The shadow behind the image */
|
||||
.mfp-figure {
|
||||
line-height: 0; }
|
||||
.mfp-figure:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 40px;
|
||||
bottom: 40px;
|
||||
display: block;
|
||||
right: 0;
|
||||
width: auto;
|
||||
height: auto;
|
||||
z-index: -1;
|
||||
box-shadow: 0 0 8px rgba(0, 0, 0, 0.6);
|
||||
background: #444; }
|
||||
.mfp-figure small {
|
||||
color: #BDBDBD;
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
line-height: 14px; }
|
||||
.mfp-figure figure {
|
||||
margin: 0; }
|
||||
|
||||
.mfp-bottom-bar {
|
||||
margin-top: -36px;
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
cursor: auto; }
|
||||
|
||||
.mfp-title {
|
||||
text-align: left;
|
||||
line-height: 18px;
|
||||
color: #F3F3F3;
|
||||
word-wrap: break-word;
|
||||
padding-right: 36px; }
|
||||
|
||||
.mfp-image-holder .mfp-content {
|
||||
max-width: 100%; }
|
||||
|
||||
.mfp-gallery .mfp-image-holder .mfp-figure {
|
||||
cursor: pointer; }
|
||||
|
||||
@media screen and (max-width: 800px) and (orientation: landscape), screen and (max-height: 300px) {
|
||||
/**
|
||||
* Remove all paddings around the image on small screen
|
||||
*/
|
||||
.mfp-img-mobile .mfp-image-holder {
|
||||
padding-left: 0;
|
||||
padding-right: 0; }
|
||||
.mfp-img-mobile img.mfp-img {
|
||||
padding: 0; }
|
||||
.mfp-img-mobile .mfp-figure:after {
|
||||
top: 0;
|
||||
bottom: 0; }
|
||||
.mfp-img-mobile .mfp-figure small {
|
||||
display: inline;
|
||||
margin-left: 5px; }
|
||||
.mfp-img-mobile .mfp-bottom-bar {
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
bottom: 0;
|
||||
margin: 0;
|
||||
top: auto;
|
||||
padding: 3px 5px;
|
||||
position: fixed;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box; }
|
||||
.mfp-img-mobile .mfp-bottom-bar:empty {
|
||||
padding: 0; }
|
||||
.mfp-img-mobile .mfp-counter {
|
||||
right: 5px;
|
||||
top: 3px; }
|
||||
.mfp-img-mobile .mfp-close {
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 35px;
|
||||
height: 35px;
|
||||
line-height: 35px;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
position: fixed;
|
||||
text-align: center;
|
||||
padding: 0; }
|
||||
}
|
||||
|
||||
@media all and (max-width: 900px) {
|
||||
.mfp-arrow {
|
||||
-webkit-transform: scale(0.75);
|
||||
transform: scale(0.75); }
|
||||
|
||||
.mfp-arrow-left {
|
||||
-webkit-transform-origin: 0;
|
||||
transform-origin: 0; }
|
||||
|
||||
.mfp-arrow-right {
|
||||
-webkit-transform-origin: 100%;
|
||||
transform-origin: 100%; }
|
||||
|
||||
.mfp-container {
|
||||
padding-left: 6px;
|
||||
padding-right: 6px; }
|
||||
}
|
||||
|
||||
.mfp-ie7 .mfp-img {
|
||||
padding: 0; }
|
||||
.mfp-ie7 .mfp-bottom-bar {
|
||||
width: 600px;
|
||||
left: 50%;
|
||||
margin-left: -300px;
|
||||
margin-top: 5px;
|
||||
padding-bottom: 5px; }
|
||||
.mfp-ie7 .mfp-container {
|
||||
padding: 0; }
|
||||
.mfp-ie7 .mfp-content {
|
||||
padding-top: 44px; }
|
||||
.mfp-ie7 .mfp-close {
|
||||
top: 0;
|
||||
right: 0;
|
||||
padding-top: 0; }
|
||||
|
Depois Largura: | Altura: | Tamanho: 9.3 KiB |
@@ -0,0 +1,105 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Generator: Adobe Illustrator 13.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 14948) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
id="Layer_1"
|
||||
xml:space="preserve"
|
||||
height="147.22015"
|
||||
viewBox="0 0 192.89149 147.21771"
|
||||
width="192.89587"
|
||||
version="1.1"
|
||||
y="0px"
|
||||
x="0px"
|
||||
enable-background="new 0 0 176.486 181.437"
|
||||
inkscape:version="0.91pre2 r"
|
||||
sodipodi:docname="XMPP_logo.svg"><metadata
|
||||
id="metadata41"><rdf:RDF><cc:Work
|
||||
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||
id="defs39" /><sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="640"
|
||||
inkscape:window-height="480"
|
||||
id="namedview37"
|
||||
showgrid="false"
|
||||
fit-margin-top="10"
|
||||
fit-margin-left="10"
|
||||
fit-margin-right="10"
|
||||
fit-margin-bottom="10"
|
||||
inkscape:zoom="1.3007054"
|
||||
inkscape:cx="71.332001"
|
||||
inkscape:cy="72.501142"
|
||||
inkscape:window-x="75"
|
||||
inkscape:window-y="34"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="Layer_1" /><linearGradient
|
||||
id="SVGID_1_"
|
||||
y2="0.00048828"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x2="-1807.2"
|
||||
gradientTransform="translate(1925.9953,9.9988343)"
|
||||
y1="125.86"
|
||||
x1="-1807.2"><stop
|
||||
stop-color="#1b3967"
|
||||
offset=".011"
|
||||
id="stop4" /><stop
|
||||
stop-color="#13b5ea"
|
||||
offset=".467"
|
||||
id="stop6" /><stop
|
||||
stop-color="#002b5c"
|
||||
offset=".9945"
|
||||
id="stop8" /></linearGradient><path
|
||||
d="m 146.28531,24.187835 c 0.077,1.313 -1.786,0.968 -1.786,2.293 0,38.551 -44.720002,96.831035 -89.847002,108.190035 l 0,1.182 C 114.60931,130.34287 181.38231,69.052835 182.89231,10.002834 l -36.6,14.189001 z"
|
||||
id="path10"
|
||||
style="fill:url(#SVGID_1_)"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="m 130.22531,27.958835 c 0.077,1.313 0.121,2.633 0.121,3.958 0,38.551 -30.700002,90.497035 -75.827002,101.860035 l 0,1.637 c 59.065002,-3.823 105.810002,-63.023035 105.810002,-109.200035 0,-2.375 -0.125,-4.729 -0.371,-7.056 l -29.73,8.796 z"
|
||||
id="path12"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#e96d1f" /><linearGradient
|
||||
id="SVGID_2_"
|
||||
y2="1.279e-13"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x2="-1073.2"
|
||||
gradientTransform="matrix(-1,0,0,1,-998.20465,9.9988343)"
|
||||
y1="126.85"
|
||||
x1="-1073.2"><stop
|
||||
stop-color="#1b3967"
|
||||
offset=".011"
|
||||
id="stop15" /><stop
|
||||
stop-color="#13b5ea"
|
||||
offset=".467"
|
||||
id="stop17" /><stop
|
||||
stop-color="#002b5c"
|
||||
offset=".9945"
|
||||
id="stop19" /></linearGradient><path
|
||||
d="m 46.594308,24.187835 c -0.077,1.313 1.787,0.968 1.787,2.293 0,38.551 46.558,97.366035 91.688002,108.730035 l 0,1.639 C 80.116308,131.32987 11.509308,69.049835 9.9993079,9.9998343 L 46.598308,24.188835 Z"
|
||||
id="path21"
|
||||
style="fill:url(#SVGID_2_)"
|
||||
inkscape:connector-curvature="0" /><path
|
||||
d="m 64.726308,28.930835 c -0.076,1.313 -0.12,2.63 -0.12,3.957 0,38.551 30.699,90.497035 75.827002,101.860035 l 0,1.639 C 81.389308,133.59687 34.623308,73.362835 34.623308,27.186835 c 0,-2.375 0.128,-4.729 0.371,-7.056 l 29.73,8.798 z"
|
||||
id="path23"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#a0ce67" /><path
|
||||
d="m 34.708308,19.581835 7.617,2.722 c -0.041,0.962 -0.066,2.254 -0.066,3.225 0,41.219 37.271,98.204035 87.272002,107.120035 3.245,1.088 7.538,2.077 10.932,2.931 l 0,1.638 C 75.209308,131.65787 29.363308,65.351835 34.703308,19.577835 Z"
|
||||
id="path25"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#439639" /><path
|
||||
d="m 160.33531,18.758835 -7.833,2.625 c 0.041,0.963 0.191,2.203 0.191,3.173 0,41.219 -37.272,98.205035 -87.274002,107.120035 -3.243,1.089 -7.538,2.077 -10.93,2.932 l 0,1.639 C 122.83331,127.58787 165.66931,64.528835 160.32931,18.757835 Z"
|
||||
id="path27"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:#d9541e" /></svg>
|
||||
|
Depois Largura: | Altura: | Tamanho: 4.5 KiB |
@@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="12.923695"
|
||||
height="19.551229"
|
||||
viewBox="0 0 3.4193941 5.1729296"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91+devel r"
|
||||
sodipodi:docname="bookmark_red.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="22.4"
|
||||
inkscape:cx="-1.621067"
|
||||
inkscape:cy="11.999492"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
units="px"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:window-width="1855"
|
||||
inkscape:window-height="1056"
|
||||
inkscape:window-x="65"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-0.88782864,-291.84497)">
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#800000;stroke-width:0.26458332;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 1.0201203,291.84497 0,4.85355 1.5774055,-1.5774 1.5774053,1.5774 0,-4.83839"
|
||||
id="path4141"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4162"
|
||||
d="m 1.0201203,291.84497 0,4.85355 1.5774055,-1.5774 1.5774053,1.5774 0,-4.83839"
|
||||
style="fill:#ff0000;fill-rule:evenodd;stroke:none;stroke-width:0.26458332;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Depois Largura: | Altura: | Tamanho: 2.5 KiB |
@@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
viewBox="0 0 1000 1000"
|
||||
preserveAspectRatio="xMinYMin meet"
|
||||
width="100%"
|
||||
height="100%"
|
||||
style="width: 512px; height: 512px;"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91+devel r"
|
||||
sodipodi:docname="group_grey.svg">
|
||||
<metadata
|
||||
id="metadata10">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs8" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="980"
|
||||
inkscape:window-height="888"
|
||||
id="namedview6"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.6675088"
|
||||
inkscape:cx="512.17823"
|
||||
inkscape:cy="480.21903"
|
||||
inkscape:window-x="889"
|
||||
inkscape:window-y="85"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg2" />
|
||||
<path
|
||||
d="m 0.94630456,763.0963 c 0,22.21203 9.08673644,33.31804 27.26020844,33.31804 l 112.069747,0 0,-142.35887 c 0,-18.17347 4.54363,-34.83222 13.63088,-49.97627 9.08724,-15.14405 21.70797,-26.75512 37.86216,-34.83326 l 115.09866,-54.52042 c 10.09637,-6.05782 18.17347,-13.12528 24.23129,-21.20238 -12.11564,-18.17347 -22.21202,-39.37586 -30.28912,-63.60715 -8.0771,-24.2313 -12.11564,-49.47223 -12.11564,-75.7228 0,-16.1542 2.01927,-32.3084 6.05782,-48.46259 4.03855,-16.1542 9.08674,-31.29876 15.14456,-45.43368 -20.19275,-14.13493 -41.39513,-21.20239 -63.60715,-21.20239 -38.36622,2.01928 -68.65534,17.66839 -90.86736,46.94736 -22.21201,29.27897 -33.31803,62.09244 -33.31803,98.44042 2.01928,62.59751 24.2313,107.02155 66.63606,133.27212 L 16.092416,596.50615 C 5.9960421,602.56397 0.94785546,612.66034 0.94785546,626.79527 l 0,136.30103 z M 191.76775,796.41434 c -2.01927,42.40476 10.09637,64.61678 36.34695,66.63606 l 542.17524,0 c 12.11565,-4.03855 20.69783,-10.09637 25.74653,-18.17347 5.04869,-8.0771 7.57305,-14.63948 7.57305,-19.68716 l 0,-171.13275 c 0,-18.17347 -7.06746,-30.28912 -21.20238,-36.34694 L 637.01936,545.01619 573.41221,514.72707 c 38.36622,-22.21202 63.60715,-60.57824 75.7228,-115.09865 8.0771,-30.28912 8.0771,-61.58788 0,-93.89627 -10.09637,-36.34695 -28.7744,-67.14115 -56.0341,-92.38259 -27.25969,-25.24145 -59.06352,-38.87182 -95.4115,-40.89109 -36.34694,2.01927 -67.6457,15.64964 -93.89627,40.89109 -26.25057,25.24144 -44.42404,55.02601 -54.52042,89.35368 -12.11564,46.44331 -8.07709,93.89627 12.11565,142.35886 16.1542,30.28912 37.35658,54.52041 63.60715,72.69389 l -57.54932,27.2602 -151.4456,69.66498 c -16.1542,8.0771 -24.2313,21.20238 -24.2313,39.37585 l 0,142.35887 z m 475.53918,-302.8912 c 8.0771,8.0771 18.17347,16.1542 30.28912,24.23129 12.11565,8.0771 23.22166,14.13493 33.31803,18.17348 10.09638,4.03855 23.22166,9.59181 39.37586,16.65979 16.1542,7.06797 28.26984,12.62124 36.34694,16.65979 16.1542,8.0771 28.77493,19.68819 37.86218,34.83326 9.08724,15.14507 13.63088,31.80384 13.63088,49.97627 l 0,142.35887 115.09865,0 c 18.17347,-2.01928 27.26021,-13.12529 27.26021,-33.31803 l 0,-136.30104 c 0,-14.13493 -5.04819,-24.2313 -15.14456,-30.28912 L 815.72517,514.72707 c 42.40477,-30.28912 63.60715,-73.70352 63.60715,-130.24321 0,-38.36622 -12.11565,-72.18881 -36.34694,-101.46778 -24.2313,-29.27897 -53.51078,-43.91896 -87.83845,-43.92 -22.21202,0 -44.42404,7.06747 -66.63606,21.20239 12.11564,30.28912 18.17347,61.58787 18.17347,93.89627 0,50.48187 -13.12529,96.92518 -39.37586,139.32995 z"
|
||||
id="path4"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cscsscccsssccscccscccccssscccccscscccccscccssssssccssccssccscc"
|
||||
style="fill:#999999;stroke-width:1.55090213;fill-opacity:1" />
|
||||
</svg>
|
||||
|
Depois Largura: | Altura: | Tamanho: 4.2 KiB |
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
viewBox="0 0 1000 1000"
|
||||
preserveAspectRatio="xMinYMin meet"
|
||||
width="100%"
|
||||
height="100%"
|
||||
style="width: 512px; height: 512px;"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91+devel r"
|
||||
sodipodi:docname="group_white.svg">
|
||||
<metadata
|
||||
id="metadata10">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs8" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1855"
|
||||
inkscape:window-height="1056"
|
||||
id="namedview6"
|
||||
showgrid="false"
|
||||
inkscape:zoom="0.6675088"
|
||||
inkscape:cx="538.39511"
|
||||
inkscape:cy="480.21903"
|
||||
inkscape:window-x="65"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg2" />
|
||||
<path
|
||||
d="m 0.94630456,763.0963 c 0,22.21203 9.08673644,33.31804 27.26020844,33.31804 l 112.069747,0 0,-142.35887 c 0,-18.17347 4.54363,-34.83222 13.63088,-49.97627 9.08724,-15.14405 21.70797,-26.75512 37.86216,-34.83326 l 115.09866,-54.52042 c 10.09637,-6.05782 18.17347,-13.12528 24.23129,-21.20238 -12.11564,-18.17347 -22.21202,-39.37586 -30.28912,-63.60715 -8.0771,-24.2313 -12.11564,-49.47223 -12.11564,-75.7228 0,-16.1542 2.01927,-32.3084 6.05782,-48.46259 4.03855,-16.1542 9.08674,-31.29876 15.14456,-45.43368 -20.19275,-14.13493 -41.39513,-21.20239 -63.60715,-21.20239 -38.36622,2.01928 -68.65534,17.66839 -90.86736,46.94736 -22.21201,29.27897 -33.31803,62.09244 -33.31803,98.44042 2.01928,62.59751 24.2313,107.02155 66.63606,133.27212 L 16.092416,596.50615 C 5.9960421,602.56397 0.94785546,612.66034 0.94785546,626.79527 l 0,136.30103 z M 191.76775,796.41434 c -2.01927,42.40476 10.09637,64.61678 36.34695,66.63606 l 542.17524,0 c 12.11565,-4.03855 20.69783,-10.09637 25.74653,-18.17347 5.04869,-8.0771 7.57305,-14.63948 7.57305,-19.68716 l 0,-171.13275 c 0,-18.17347 -7.06746,-30.28912 -21.20238,-36.34694 L 637.01936,545.01619 573.41221,514.72707 c 38.36622,-22.21202 63.60715,-60.57824 75.7228,-115.09865 8.0771,-30.28912 8.0771,-61.58788 0,-93.89627 -10.09637,-36.34695 -28.7744,-67.14115 -56.0341,-92.38259 -27.25969,-25.24145 -59.06352,-38.87182 -95.4115,-40.89109 -36.34694,2.01927 -67.6457,15.64964 -93.89627,40.89109 -26.25057,25.24144 -44.42404,55.02601 -54.52042,89.35368 -12.11564,46.44331 -8.07709,93.89627 12.11565,142.35886 16.1542,30.28912 37.35658,54.52041 63.60715,72.69389 l -57.54932,27.2602 -151.4456,69.66498 c -16.1542,8.0771 -24.2313,21.20238 -24.2313,39.37585 l 0,142.35887 z m 475.53918,-302.8912 c 8.0771,8.0771 18.17347,16.1542 30.28912,24.23129 12.11565,8.0771 23.22166,14.13493 33.31803,18.17348 10.09638,4.03855 23.22166,9.59181 39.37586,16.65979 16.1542,7.06797 28.26984,12.62124 36.34694,16.65979 16.1542,8.0771 28.77493,19.68819 37.86218,34.83326 9.08724,15.14507 13.63088,31.80384 13.63088,49.97627 l 0,142.35887 115.09865,0 c 18.17347,-2.01928 27.26021,-13.12529 27.26021,-33.31803 l 0,-136.30104 c 0,-14.13493 -5.04819,-24.2313 -15.14456,-30.28912 L 815.72517,514.72707 c 42.40477,-30.28912 63.60715,-73.70352 63.60715,-130.24321 0,-38.36622 -12.11565,-72.18881 -36.34694,-101.46778 -24.2313,-29.27897 -53.51078,-43.91896 -87.83845,-43.92 -22.21202,0 -44.42404,7.06747 -66.63606,21.20239 12.11564,30.28912 18.17347,61.58787 18.17347,93.89627 0,50.48187 -13.12529,96.92518 -39.37586,139.32995 z"
|
||||
id="path4"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cscsscccsssccscccscccccssscccccscscccccscccssssssccssccssccscc"
|
||||
style="fill:#ffffff;stroke-width:1.55090213" />
|
||||
</svg>
|
||||
|
Depois Largura: | Altura: | Tamanho: 4.2 KiB |
|
Antes Largura: | Altura: | Tamanho: 783 B |
@@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="15"
|
||||
height="15"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="resize_gray.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<clipPath
|
||||
clipPathUnits="userSpaceOnUse"
|
||||
id="clipPath3803">
|
||||
<rect
|
||||
style="stroke:none"
|
||||
id="rect3805"
|
||||
width="16.09375"
|
||||
height="14.71875"
|
||||
x="0.84375"
|
||||
y="1038.1434" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="32"
|
||||
inkscape:cx="6.9909088"
|
||||
inkscape:cy="6.5564812"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1865"
|
||||
inkscape:window-height="1056"
|
||||
inkscape:window-x="55"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1037.3622)">
|
||||
<path
|
||||
style="fill:none;stroke:#bfbfbf;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 10.46875,1032.1747 -14.5,14.2813 z m 3.5,1.2501 -17.3125,17.3124 z"
|
||||
id="path2985"
|
||||
inkscape:connector-curvature="0"
|
||||
clip-path="url(#clipPath3803)"
|
||||
transform="translate(0.8125,0.6875)"
|
||||
sodipodi:nodetypes="cccccc" />
|
||||
</g>
|
||||
</svg>
|
||||
|
Depois Largura: | Altura: | Tamanho: 2.2 KiB |
@@ -1,973 +0,0 @@
|
||||
.jsxc_online,.jsxc_chat {
|
||||
border-left: 4px solid #00BFFF !important;
|
||||
}
|
||||
|
||||
.jsxc_away,.jsxc_xa {
|
||||
border-left: 4px solid orange !important;
|
||||
}
|
||||
|
||||
.jsxc_dnd {
|
||||
border-left: 4px solid red !important;
|
||||
}
|
||||
|
||||
.jsxc_offline {
|
||||
border-left: 4px solid #A4A4A4 !important;
|
||||
}
|
||||
|
||||
.jsxc_hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.jsxc_invalid {
|
||||
border: 2px solid red !important;
|
||||
}
|
||||
|
||||
p.jsxc_right {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
p.jsxc_center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/*############################
|
||||
*########## Dialog ##########
|
||||
*############################*/
|
||||
#jsxc_dialog {
|
||||
padding: 10px;
|
||||
min-width: 300px;
|
||||
}
|
||||
|
||||
#jsxc_dialog p {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
#jsxc_dialog h3 {
|
||||
font-size: 120%;
|
||||
font-weight: bold;
|
||||
margin-bottom: 10px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
#jsxc_dialog p input {
|
||||
margin-bottom: 5px;
|
||||
width: 60%;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
#jsxc_dialog p input[type="submit"] {
|
||||
width: auto;
|
||||
}
|
||||
|
||||
#jsxc_dialog p label {
|
||||
display: block;
|
||||
width: 30%;
|
||||
float: left;
|
||||
padding: 6px 0px;
|
||||
}
|
||||
|
||||
#jsxc_dialog .jsxc_right {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
#jsxc_dialog p.jsxc_maxWidth {
|
||||
max-width: 500px;
|
||||
}
|
||||
|
||||
#jsxc_dialog fieldset {
|
||||
border: 2px solid #ccc;
|
||||
}
|
||||
|
||||
#jsxc_dialog legend {
|
||||
padding: 0px 10px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#jsxc_dialog input {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
#jsxc_dialog input:invalid {
|
||||
border:1px solid red;
|
||||
}
|
||||
|
||||
#jsxc_dialog .jsxc_fieldsetPriority {
|
||||
width: 200px;
|
||||
padding: 10px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
#jsxc_dialog .jsxc_fieldsetPriority label {
|
||||
display: inline-block;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
#jsxc_dialog .jsxc_fieldsetPriority input[type="Number"] {
|
||||
display: inline-block;
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
/*############################
|
||||
*########## Overall #########
|
||||
*############################*/
|
||||
li .jsxc_name {
|
||||
overflow: hidden;
|
||||
height: 30px;
|
||||
cursor: pointer;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
li .jsxc_name:hover {
|
||||
color: #FAFAFA;
|
||||
}
|
||||
|
||||
.jsxc_avatar,ul#jsxc_buddylist li:hover .jsxc_avatar {
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
line-height: 25px;
|
||||
margin-top: 2px;
|
||||
margin-right: 4px;
|
||||
background-color: #a3a3a3;
|
||||
border-radius: 2px;
|
||||
float: left;
|
||||
text-align: center;
|
||||
font-weight: bold;
|
||||
font-size: 30px;
|
||||
color: #b1b1b1;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
font-family: Arial;
|
||||
}
|
||||
|
||||
.jsxc_avatar img {
|
||||
display: block;
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
}
|
||||
|
||||
/*############################
|
||||
*########## Roster ##########
|
||||
*############################*/
|
||||
div#jsxc_roster {
|
||||
position: fixed;
|
||||
top: 0px;
|
||||
bottom: 0px;
|
||||
right: 0px;
|
||||
width: 200px;
|
||||
overflow: visible;
|
||||
border-left: 4px solid #A4A4A4;
|
||||
z-index: 80;
|
||||
margin-left: 10px;
|
||||
box-shadow: 0px 0px 7px #000000;
|
||||
}
|
||||
|
||||
div#jsxc_roster .slimScrollDiv {
|
||||
left: -4px;
|
||||
margin-bottom: 30px;
|
||||
z-index: 40;
|
||||
}
|
||||
|
||||
div#jsxc_roster .jsxc_wait {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
bottom: 0px;
|
||||
width: 160px;
|
||||
padding: 20px;
|
||||
background-color: #fff;
|
||||
z-index: 60;
|
||||
}
|
||||
|
||||
div#jsxc_roster .jsxc_wait img {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
div#jsxc_roster .jsxc_wait h3 {
|
||||
margin-bottom: 5px;
|
||||
font-size: 1.13em;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/** Input field for alias renaming */
|
||||
#jsxc_roster input {
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 31px;
|
||||
width: 157px;
|
||||
height: 18px;
|
||||
margin-top: -11px;
|
||||
padding: 2px;
|
||||
border: 0px;
|
||||
background-image: none;
|
||||
background-color: #fff;
|
||||
border-radius: 3px;
|
||||
-moz-box-shadow: inset 0 0 5px #888;
|
||||
-webkit-box-shadow: inset 0 0 5px #888;
|
||||
box-shadow: inner 0 0 5px #888;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
#jsxc_roster .jsxc_expand input {
|
||||
left: 51px;
|
||||
width: 137px;
|
||||
}
|
||||
|
||||
div#jsxc_roster p {
|
||||
color: #939393;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
div#jsxc_roster p a {
|
||||
color: #b1b1b1;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
div#jsxc_roster>.jsxc_bottom {
|
||||
position: absolute;
|
||||
left: -4px;
|
||||
bottom: 0px;
|
||||
height: 30px;
|
||||
width: 200px;
|
||||
border-left: 4px solid #A4A4A4;
|
||||
border-top: 1px solid #939393;
|
||||
padding-left: 0px;
|
||||
background-color: #282323;
|
||||
color: #939393;
|
||||
cursor: pointer;
|
||||
line-height: 30px;
|
||||
z-index: 50;
|
||||
}
|
||||
|
||||
div#jsxc_roster>.jsxc_bottom>div:hover {
|
||||
color: #FAFAFA;
|
||||
}
|
||||
|
||||
div#jsxc_roster>.jsxc_bottom>div>span {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
div#jsxc_roster>.jsxc_bottom ul {
|
||||
width: 190px;
|
||||
position: absolute;
|
||||
bottom: 30px;
|
||||
left: 0px;
|
||||
display: none;
|
||||
border-top: 1px solid #939393;
|
||||
padding-left: 10px;
|
||||
background-color: #282323;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
div#jsxc_roster>.jsxc_bottom li {
|
||||
height: 30px;
|
||||
background-color: #282323;
|
||||
color: #939393;
|
||||
cursor: pointer;
|
||||
width: 180px;
|
||||
padding-left: 10px;
|
||||
line-height: 30px;
|
||||
text-align: left;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
div#jsxc_roster>.jsxc_bottom li:hover:not(.jsxc_disabled ) {
|
||||
color: #fff;
|
||||
background-color: #3F8FBA;
|
||||
}
|
||||
|
||||
div#jsxc_roster>.jsxc_bottom li.jsxc_disabled {
|
||||
color: #595959;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
div#jsxc_roster>.jsxc_bottom ul li:last-child {
|
||||
border-bottom: 1px solid #939393;
|
||||
}
|
||||
|
||||
#jsxc_menu,#jsxc_avatar,#jsxc_notice {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
/** own avatar */
|
||||
#jsxc_avatar {
|
||||
float: left;
|
||||
margin: 0px 2px;
|
||||
width: 25px;
|
||||
}
|
||||
|
||||
#jsxc_menu {
|
||||
cursor: pointer;
|
||||
float: right;
|
||||
text-align: center;
|
||||
width: 25px;
|
||||
}
|
||||
|
||||
#jsxc_menu>span {
|
||||
opacity: 0.5;
|
||||
display: block;
|
||||
width: 25px;
|
||||
height: 30px;
|
||||
background-image: url('img/gear_white.svg');
|
||||
background-size: 18px 18px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
}
|
||||
|
||||
#jsxc_menu:hover>span {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
#jsxc_notice {
|
||||
float: right;
|
||||
text-align: center;
|
||||
line-height: 30px;
|
||||
}
|
||||
|
||||
#jsxc_notice>span:empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#jsxc_notice span {
|
||||
background-color: #fbc14c;
|
||||
border-radius: 11px;
|
||||
color: black;
|
||||
font-size: 80%;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
#jsxc_presence {
|
||||
cursor: pointer;
|
||||
padding-left: 2px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/** List of all buddies inside the roster */
|
||||
ul#jsxc_buddylist {
|
||||
list-style: none;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
width: 204px;
|
||||
}
|
||||
|
||||
ul#jsxc_buddylist li {
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
height: 30px;
|
||||
border-bottom: 1px solid #939393;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
position: relative;
|
||||
color: #939393;
|
||||
font-family: Arial;
|
||||
line-height: 30px;
|
||||
padding-left: 3px;
|
||||
z-index: 85;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
ul#jsxc_buddylist .jsxc_name {
|
||||
padding-right: 30px;
|
||||
}
|
||||
|
||||
ul#jsxc_buddylist li.jsxc_expand {
|
||||
height: 54px;
|
||||
}
|
||||
|
||||
ul#jsxc_buddylist li.jsxc_expand .jsxc_avatar, ul#jsxc_buddylist li.jsxc_expand .jsxc_avatar img {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
#jsxc_buddylist .jsxc_control {
|
||||
position:absolute;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#jsxc_buddylist .jsxc_control:after {
|
||||
content: '▾';
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 15px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
line-height: 16px;
|
||||
text-align: center;
|
||||
margin-left: -8px;
|
||||
margin-top: -8px;
|
||||
border-radius: 8px;
|
||||
color: #c1c1c1;
|
||||
background-color: rgba(150, 150, 150, 0.5);
|
||||
opacity: 0.6;
|
||||
-webkit-transition: -webkit-transform 0.5s;
|
||||
transition: transform 0.5s;
|
||||
}
|
||||
|
||||
#jsxc_buddylist .jsxc_control:hover:after {
|
||||
color: #fff;
|
||||
opacity: 1.0;
|
||||
}
|
||||
|
||||
#jsxc_buddylist li.jsxc_expand .jsxc_control:after {
|
||||
/* content: '▴'; */
|
||||
-ms-transform:rotate(180deg); /* IE 9 */
|
||||
-webkit-transform:rotate(180deg);
|
||||
transform:rotate(180deg);
|
||||
}
|
||||
|
||||
#jsxc_buddylist .jsxc_options {
|
||||
height: 20px;
|
||||
float: left;
|
||||
border-radius:2px;
|
||||
background-color: rgba(150, 150, 150, 0.5);
|
||||
}
|
||||
#jsxc_buddylist .jsxc_options > div {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
float: left;
|
||||
margin-right:0px 1px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
opacity: 0.6;
|
||||
cursor: pointer;
|
||||
}
|
||||
#jsxc_buddylist .jsxc_options > div:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
#jsxc_buddylist .jsxc_chaticon {
|
||||
background-image: url('img/speech_balloon_white.svg');
|
||||
background-size: 15px 15px;
|
||||
}
|
||||
#jsxc_buddylist .jsxc_videoicon {
|
||||
background-image: url('img/camera_icon_white.svg');
|
||||
background-size: 13px 13px;
|
||||
}
|
||||
#jsxc_buddylist .jsxc_vcardicon {
|
||||
font-size: 15px;
|
||||
line-height: 20px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
font-weight: bold;
|
||||
font-family: serif;
|
||||
}
|
||||
|
||||
ul#jsxc_buddylist li:hover {
|
||||
|
||||
}
|
||||
|
||||
ul#jsxc_buddylist .jsxc_oneway {
|
||||
opacity: 0.7;
|
||||
}
|
||||
.jsxc_oneway .jsxc_avatar {
|
||||
-webkit-filter: grayscale(100%);
|
||||
-moz-filter: grayscale(100%);
|
||||
-ms-filter: grayscale(100%);
|
||||
-o-filter: grayscale(100%);
|
||||
filter: grayscale(100%);
|
||||
}
|
||||
ul#jsxc_buddylist .jsxc_right {
|
||||
float:left;
|
||||
}
|
||||
ul#jsxc_buddylist .jsxc_right {
|
||||
float: right;
|
||||
margin-right: 6px;
|
||||
}
|
||||
|
||||
ul#jsxc_buddylist .jsxc_right div {
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
font-size: 13px;
|
||||
line-height: 20px;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
ul#jsxc_buddylist li[data-type!="chat"] .jsxc_right {
|
||||
display: none;
|
||||
}
|
||||
|
||||
ul#jsxc_buddylist .jsxc_right div:hover {
|
||||
opacity: 1.0;
|
||||
}
|
||||
|
||||
ul#jsxc_buddylist .jsxc_rename {
|
||||
|
||||
}
|
||||
|
||||
ul#jsxc_buddylist .jsxc_delete {
|
||||
|
||||
}
|
||||
|
||||
#jsxc_roster .jsxc_avatar {
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
}
|
||||
#jsxc_roster .jsxc_avatar img {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
div#jsxc_toggleRoster {
|
||||
width: 14px;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
left: -14px !important;
|
||||
top: 0px;
|
||||
z-index: 110;
|
||||
background-color: transparent;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#jsxc_toggleRoster:hover {
|
||||
background-color: #a4a4a4;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
/*############################
|
||||
*###### Window List #########
|
||||
*############################*/
|
||||
div#jsxc_windowList {
|
||||
position: fixed;
|
||||
bottom: 0px;
|
||||
right: 0px;
|
||||
width: 100%;
|
||||
z-index: 50;
|
||||
}
|
||||
|
||||
div#jsxc_windowList>ul {
|
||||
list-style: none;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
padding-right: 210px;
|
||||
height: 30px;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
div#jsxc_windowList>ul>li {
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
display: block;
|
||||
float: right;
|
||||
width: 250px;
|
||||
background-color: #282323;
|
||||
height: 30px;
|
||||
position: relative;
|
||||
overflow: visible;
|
||||
margin-right: 5px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
div#jsxc_windowList>ul>li.jsxc_min {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
/*############################
|
||||
*######### Window ###########
|
||||
*############################*/
|
||||
div.jsxc_bar {
|
||||
background-color: #282323;
|
||||
cursor: pointer;
|
||||
height: 30px;
|
||||
line-height: 26px;
|
||||
padding: 2px;
|
||||
color: #939393;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
div.jsxc_cycle {
|
||||
position: absolute;
|
||||
bottom: 9px;
|
||||
right: 5px;
|
||||
height: 12px;
|
||||
width: 12px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
div#jsxc_windowList>ul>li.jsxc_unreadMsg .jsxc_name {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
div#jsxc_windowList>ul>li.jsxc_unreadMsg .jsxc_cycle {
|
||||
background-color: orange;
|
||||
}
|
||||
|
||||
/** Contains text area */
|
||||
div.jsxc_window {
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
height: auto;
|
||||
background-color: #A4A4A4;
|
||||
z-index: 80;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
div.jsxc_window .jsxc_emoticons {
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
position: absolute;
|
||||
top: 240px;
|
||||
right: 0px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
div.jsxc_window .jsxc_emoticons:after {
|
||||
content: ' ';
|
||||
background-image: url('img/smiley.png');
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
opacity: 0.3;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
}
|
||||
|
||||
div.jsxc_window .jsxc_emoticons:hover:after {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
div.jsxc_window .jsxc_emoticons ul {
|
||||
display: none;
|
||||
position: absolute;
|
||||
bottom: 33px;
|
||||
right: 3px;
|
||||
width: 210px;
|
||||
background-color: rgba(40, 35, 35, 0.8);
|
||||
padding: 3px;
|
||||
border-radius: 3px;
|
||||
z-index: 200;
|
||||
}
|
||||
|
||||
div.jsxc_window .jsxc_emoticons ul:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
border-left: 5px solid transparent;
|
||||
border-right: 5px solid transparent;
|
||||
border-top: 6px solid rgba(40, 35, 35, 0.8);
|
||||
display: block;
|
||||
width: 0;
|
||||
z-index: 1;
|
||||
right: 6px;
|
||||
bottom: -6px;
|
||||
}
|
||||
|
||||
div.jsxc_window .jsxc_emoticons li {
|
||||
float: right;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
div.jsxc_window .jsxc_emoticons img {
|
||||
cursor: pointer;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
div.jsxc_window .jsxc_emoticons img:hover {
|
||||
background-color: rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
/** groups elements, which will be hidden, if the window is minimized. */
|
||||
.jsxc_window .jsxc_fade {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.jsxc_window .jsxc_gradient {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
right: 0px;
|
||||
height: 15px;
|
||||
z-index: 100;
|
||||
background: -moz-linear-gradient(top, rgba(164, 164, 164, 1) 0%,
|
||||
rgba(40, 35, 35, 0) 100%); /* FF3.6+ */
|
||||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(164,
|
||||
164, 164, 1)), color-stop(100%, rgba(40, 35, 35, 0)));
|
||||
/* Chrome,Safari4+ */
|
||||
background: -webkit-linear-gradient(top, rgba(164, 164, 164, 1) 0%,
|
||||
rgba(40, 35, 35, 0) 100%); /* Chrome10+,Safari5.1+ */
|
||||
background: -o-linear-gradient(top, rgba(164, 164, 164, 1) 0%,
|
||||
rgba(40, 35, 35, 0) 100%); /* Opera 11.10+ */
|
||||
background: -ms-linear-gradient(top, rgba(164, 164, 164, 1) 0%,
|
||||
rgba(40, 35, 35, 0) 100%); /* IE10+ */
|
||||
background: linear-gradient(to bottom, #a4a4a4 0%, rgba(40, 35, 35, 0)
|
||||
100%); /* W3C */
|
||||
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#a4a4a4',
|
||||
endColorstr='#00282323', GradientType=0); /* IE6-9 */
|
||||
}
|
||||
|
||||
div.jsxc_window .jsxc_avatar {
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
div.jsxc_window .jsxc_textarea {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
padding: 3px;
|
||||
}
|
||||
|
||||
div.jsxc_window .slimScrollDiv {
|
||||
margin: 0px 0px 6px 0px;
|
||||
}
|
||||
|
||||
div.jsxc_chatmessage {
|
||||
margin: 3px;
|
||||
padding: 4px;
|
||||
padding-right: 10px;
|
||||
max-width: 76%;
|
||||
word-wrap: break-word;
|
||||
background-color: #fff;
|
||||
position: relative;
|
||||
outline: none;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
div.jsxc_chatmessage a {
|
||||
color: blue;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
div.jsxc_chatmessage img {
|
||||
width: 19px;
|
||||
height: 19px;
|
||||
}
|
||||
|
||||
/** incoming message */
|
||||
div.jsxc_in {
|
||||
float: left;
|
||||
position: relative;
|
||||
margin-left: 10px;
|
||||
background: #f1f7fd;
|
||||
border: solid 1px #a6b8c9;
|
||||
-webkit-border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
div.jsxc_in:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
border-style: solid;
|
||||
border-width: 5px 6px 5px 0;
|
||||
border-color: transparent #f1f7fd;
|
||||
display: block;
|
||||
width: 0;
|
||||
z-index: 1;
|
||||
left: -6px;
|
||||
bottom: 10px;
|
||||
}
|
||||
|
||||
div.jsxc_out.jsxc_received:before {
|
||||
content: '✓';
|
||||
position: absolute;
|
||||
bottom: 2px;
|
||||
right: 2px;
|
||||
font-size: 12px;
|
||||
line-height: 12px;
|
||||
color: green;
|
||||
}
|
||||
|
||||
/** outgoing message */
|
||||
div.jsxc_out {
|
||||
float: right;
|
||||
position: relative;
|
||||
margin-right: 10px;
|
||||
background: #e6ffd1;
|
||||
border: solid 1px #b4d89f;
|
||||
-webkit-border-radius: 3px;
|
||||
-moz-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
div.jsxc_out:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
border-style: solid;
|
||||
border-width: 5px 0 5px 6px;
|
||||
border-color: transparent #e6ffd1;
|
||||
display: block;
|
||||
width: 0;
|
||||
z-index: 1;
|
||||
right: -6px;
|
||||
bottom: 10px;
|
||||
}
|
||||
|
||||
/** system message */
|
||||
div.jsxc_sys {
|
||||
width: auto;
|
||||
max-width: none;
|
||||
padding-right: 4px;
|
||||
box-sizing: border-box;
|
||||
margin-right: 3px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.jsxc_window input.jsxc_textinput {
|
||||
width: 100%;
|
||||
height: 30px;
|
||||
margin: 0px;
|
||||
padding: 3px;
|
||||
padding-right: 40px;
|
||||
outline: none;
|
||||
border-radius: 0px;
|
||||
box-sizing: border-box;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.jsxc_window ::-webkit-input-placeholder {
|
||||
color: #000;
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
.jsxc_window ::-moz-placeholder {
|
||||
color: #000;
|
||||
opacity: 0.3;
|
||||
} /* firefox 19+ */
|
||||
.jsxc_window :-ms-input-placeholder {
|
||||
color: rgba(0, 0, 0, 0.4);
|
||||
} /* ie */
|
||||
.jsxc_window input:-moz-placeholder {
|
||||
color: #000;
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
||||
div.jsxc_window .jsxc_tools {
|
||||
height: 26px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.jsxc_min .jsxc_tools {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.jsxc_window .jsxc_tools > div {
|
||||
width: 17px;
|
||||
height: 26px;
|
||||
display: block;
|
||||
float: left;
|
||||
color: #939393;
|
||||
font-family: Arial;
|
||||
line-height: 26px;
|
||||
cursor: pointer;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
div.jsxc_settings {
|
||||
background-image: url('img/gear_grey.svg');
|
||||
background-size: 15px 15px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
div.jsxc_settings:hover,div.jsxc_settings.hover {
|
||||
background-image: url('img/gear_white.svg');
|
||||
}
|
||||
|
||||
div.jsxc_settings ul {
|
||||
list-style: none;
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
left: 0px;
|
||||
box-shadow: 0px 5px 5px -5px #000;
|
||||
z-index: 110;
|
||||
overflow: visible;
|
||||
background-color: #282323;
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.jsxc_settings li {
|
||||
width: 170px;
|
||||
margin-left: 20px;
|
||||
padding-left: 10px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
div.jsxc_settings li:first-child {
|
||||
border-top: 1px solid #ccc;
|
||||
}
|
||||
|
||||
div.jsxc_settings li:hover:not(.jsxc_disabled ){
|
||||
color: #fff;
|
||||
background-color: #3F8FBA;
|
||||
}
|
||||
|
||||
div.jsxc_settings li.jsxc_disabled {
|
||||
color: #595959;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
div.jsxc_transfer {
|
||||
background-image: url('img/padlock_open_grey.svg');
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
background-size: 12px 12px;
|
||||
}
|
||||
|
||||
div.jsxc_transfer:hover {
|
||||
background-image: url('img/padlock_open_white.svg');
|
||||
}
|
||||
|
||||
div.jsxc_transfer.jsxc_fin {
|
||||
background-image: url('img/padlock_close_grey.svg');
|
||||
}
|
||||
|
||||
div.jsxc_transfer.jsxc_enc {
|
||||
background-image: url('img/padlock_close_orange.svg');
|
||||
}
|
||||
|
||||
div.jsxc_transfer.jsxc_enc.jsxc_trust {
|
||||
background-image: url('img/padlock_close_green.svg');
|
||||
}
|
||||
|
||||
.jsxc_window .jsxc_close {
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.jsxc_window .jsxc_close:hover {
|
||||
color: #FAFAFA;
|
||||
}
|
||||
|
||||
#colorbox,#cboxWrapper {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/*############################
|
||||
*######### Other ############
|
||||
*############################*/
|
||||
ul.jsxc_vCard {
|
||||
min-width: 400px;
|
||||
}
|
||||
|
||||
ul.jsxc_vCard ul {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
ul.jsxc_vCard li {
|
||||
cursor: default !important;
|
||||
}
|
||||
|
||||
ul.jsxc_vCard strong {
|
||||
|
||||
}
|
||||
|
||||
img.jsxc_vCard {
|
||||
float: right;
|
||||
max-width: 200px;
|
||||
max-height: 200px;
|
||||
}
|
||||
@@ -1,892 +0,0 @@
|
||||
/**
|
||||
* jsxc v0.8.0 - 2014-07-02
|
||||
*
|
||||
* Copyright (c) 2014 Klaus Herberth <klaus@jsxc.org> <br>
|
||||
* Released under the MIT license
|
||||
*
|
||||
* Please see http://www.jsxc.org/
|
||||
*
|
||||
* @author Klaus Herberth <klaus@jsxc.org>
|
||||
* @version 0.8.0
|
||||
*/
|
||||
|
||||
/* jsxc, Strophe, SDPUtil, getUserMediaWithConstraints, setupRTC, jQuery */
|
||||
|
||||
var RTC = null, RTCPeerconnection = null;
|
||||
|
||||
jsxc.gui.template.incomingCall = '<h3>%%Incoming_call%%</h3>\
|
||||
<p>%%Do_you_want_to_accept_the_call_from%% {{cid_name}}?</p>\
|
||||
<p class="jsxc_right">\
|
||||
<a href="#" class="button jsxc_reject">%%Reject%%</a> <a href="#" class="button creation jsxc_accept">%%Accept%%</a>\
|
||||
</p>';
|
||||
|
||||
jsxc.gui.template.allowMediaAccess = '<p>%%Please_allow_access_to_microphone_and_camera%%</p>';
|
||||
|
||||
jsxc.gui.template.videoWindow = '<div class="jsxc_webrtc">\
|
||||
<div class="jsxc_videoContainer">\
|
||||
<video class="jsxc_localvideo" autoplay></video>\
|
||||
<video class="jsxc_remotevideo" autoplay></video>\
|
||||
<div class="jsxc_status"></div>\
|
||||
</div>\
|
||||
<div class="jsxc_controlbar">\
|
||||
<button type="button" class="jsxc_hangUp">%%hang_up%%</button>\
|
||||
<input type="range" class="jsxc_volume" min="0.0" max="1.0" step="0.05" value="0.5" />\
|
||||
<div class="jsxc_buttongroup">\
|
||||
<button type="button" class="jsxc_snapshot">%%snapshot%%</button><button type="button" class="jsxc_snapshots">▼</button>\
|
||||
</div>\
|
||||
<!-- <button type="button" class="jsxc_mute_local">%%mute_my_audio%%</button>\
|
||||
<button type="button" class="jsxc_pause_local">%%pause_my_video%%</button> --> \
|
||||
<button type="button" class="jsxc_showchat">%%chat%%</button>\
|
||||
<button type="button" class="jsxc_fullscreen">%%fullscreen%%</button>\
|
||||
<button type="button" class="jsxc_info">%%Info%%</button>\
|
||||
</div>\
|
||||
<div class="jsxc_multi">\
|
||||
<div class="jsxc_snapshotbar">\
|
||||
<p>No pictures yet!</p>\
|
||||
</div>\n\
|
||||
<div class="jsxc_chatarea">\
|
||||
<ul></ul>\
|
||||
</div>\
|
||||
<div class="jsxc_infobar"></div>\
|
||||
</div>\
|
||||
</div>';
|
||||
|
||||
(function($) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* WebRTC namespace for jsxc.
|
||||
*
|
||||
* @namespace jsxc.webrtc
|
||||
*/
|
||||
jsxc.webrtc = {
|
||||
/** strophe connection */
|
||||
conn: null,
|
||||
|
||||
/** local video stream */
|
||||
localStream: null,
|
||||
|
||||
/** remote video stream */
|
||||
remoteStream: null,
|
||||
|
||||
/** jid of the last caller */
|
||||
last_caller: null,
|
||||
|
||||
/** should we auto accept incoming calls? */
|
||||
AUTO_ACCEPT: false,
|
||||
|
||||
/** required disco features */
|
||||
reqVideoFeatures: [ 'urn:xmpp:jingle:apps:rtp:video', 'urn:xmpp:jingle:apps:rtp:audio', 'urn:xmpp:jingle:transports:ice-udp:1' ],
|
||||
|
||||
/** bare jid to current jid mapping */
|
||||
chatJids: {},
|
||||
|
||||
/**
|
||||
* Initialize webrtc plugin.
|
||||
*
|
||||
* @private
|
||||
* @memberOf jsxc.webrtc
|
||||
*/
|
||||
init: function() {
|
||||
var self = jsxc.webrtc;
|
||||
|
||||
// shortcut
|
||||
self.conn = jsxc.xmpp.conn;
|
||||
|
||||
if (RTC.browser === 'firefox') {
|
||||
self.conn.jingle.media_constraints.mandatory.MozDontOfferDataChannel = true;
|
||||
}
|
||||
|
||||
if (!self.conn.jingle) {
|
||||
jsxc.error('No jingle plugin found!');
|
||||
return;
|
||||
}
|
||||
|
||||
// jingle configuration
|
||||
self.conn.jingle.PRANSWER = false;
|
||||
self.conn.jingle.AUTOACCEPT = false;
|
||||
self.conn.jingle.ice_config = jsxc.storage.getUserItem('iceConfig');
|
||||
self.conn.jingle.MULTIPARTY = false;
|
||||
self.conn.jingle.pc_constraints = RTC.pc_constraints;
|
||||
|
||||
$(document).on('message.jsxc', $.proxy(self.onMessage, self));
|
||||
|
||||
$(document).on('mediaready.jingle', $.proxy(self.onMediaReady, self));
|
||||
$(document).on('mediafailure.jingle', $.proxy(self.onMediaFailure, self));
|
||||
$(document).on('callincoming.jingle', $.proxy(self.onCallIncoming, self));
|
||||
$(document).on('callterminated.jingle', $.proxy(self.onCallTerminated, self));
|
||||
$(document).on('ringing.jingle', $.proxy(self.onCallRinging, self));
|
||||
|
||||
$(document).on('remotestreamadded.jingle', $.proxy(self.onRemoteStreamAdded, self));
|
||||
$(document).on('remotestreamremoved.jingle', $.proxy(self.onRemoteStreamRemoved, self));
|
||||
$(document).on('iceconnectionstatechange.jingle', $.proxy(self.onIceConnectionStateChanged, self));
|
||||
$(document).on('nostuncandidates.jingle', $.proxy(self.noStunCandidates, self));
|
||||
|
||||
$(document).on('error.jingle', function(ev, sid, error) {
|
||||
jsxc.error('[JINGLE]', error);
|
||||
});
|
||||
|
||||
if (self.conn.caps) {
|
||||
$(document).on('caps.strophe', $.proxy(self.onCaps, self));
|
||||
}
|
||||
|
||||
self.getTurnCrendentials();
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if cached configuration is valid and if necessary update it.
|
||||
*
|
||||
* @memberOf jsxc.webrtc
|
||||
*/
|
||||
getTurnCrendentials: function() {
|
||||
|
||||
if (!jsxc.options.turnCredentialsPath) {
|
||||
jsxc.debug('No path for TURN credentials defined!');
|
||||
return;
|
||||
}
|
||||
|
||||
var ttl = (jsxc.storage.getUserItem('iceValidity') || 0) - (new Date()).getTime();
|
||||
if (ttl > 0) {
|
||||
// credentials valid
|
||||
|
||||
window.setTimeout(jsxc.webrtc.getTurnCrendentials, ttl + 500);
|
||||
return;
|
||||
}
|
||||
|
||||
$.ajax(jsxc.options.turnCredentialsPath, {
|
||||
async: true,
|
||||
success: function(data) {
|
||||
var iceConfig = {
|
||||
iceServers: [ {
|
||||
url: 'turn:' + data.url,
|
||||
credential: data.credential,
|
||||
username: data.username
|
||||
} ]
|
||||
};
|
||||
|
||||
jsxc.webrtc.conn.jingle.ice_config = iceConfig;
|
||||
jsxc.storage.setUserItem('iceConfig', iceConfig);
|
||||
jsxc.storage.setUserItem('iceValidity', (new Date()).getTime() + 1000 * data.ttl);
|
||||
},
|
||||
dataType: 'json'
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Add "video" button to roster
|
||||
*
|
||||
* @private
|
||||
* @memberOf jsxc.webrtc
|
||||
* @param event
|
||||
* @param cid cid of roster item
|
||||
* @param data data wich belongs to cid
|
||||
* @param el the roster item
|
||||
*/
|
||||
onAddRosterItem: function(event, cid, data, el) {
|
||||
var self = jsxc.webrtc;
|
||||
var videoIcon = $('<div class="jsxc_video jsxc_disabled" title="' + jsxc.l.Start_video_call + '"></div>');
|
||||
console.log(data);
|
||||
videoIcon.click(function() {
|
||||
self.startCall(data.jid);
|
||||
return false;
|
||||
});
|
||||
|
||||
el.find('.jsxc_options.jsxc_left').append(videoIcon);
|
||||
|
||||
el.on('extra.jsxc', function() {
|
||||
self.updateIcon(cid);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Add "video" button to window menu.
|
||||
*
|
||||
* @private
|
||||
* @memberOf jsxc.webrtc
|
||||
* @param event
|
||||
* @param win jQuery window object
|
||||
*/
|
||||
initWindow: function(event, win) {
|
||||
var self = jsxc.webrtc;
|
||||
|
||||
if (!self.conn) {
|
||||
$(document).one('connectionReady.jsxc', function() {
|
||||
self.initWindow(null, win);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
var div = $('<div>').addClass('jsxc_video');
|
||||
win.find('.jsxc_transfer:eq(1)').after(div);
|
||||
|
||||
self.updateIcon(jsxc.jidToCid(win.data('jid')));
|
||||
},
|
||||
|
||||
/**
|
||||
* Enable or disable "video" icon and assign full jid.
|
||||
*
|
||||
* @memberOf jsxc.webrtc
|
||||
* @param cid CSS conform jid
|
||||
*/
|
||||
updateIcon: function(cid) {
|
||||
|
||||
var self = jsxc.webrtc;
|
||||
var win = jsxc.gui.getWindow(cid);
|
||||
var jid = win.data('jid') || jsxc.storage.getUserItem('buddy_' + cid).jid;
|
||||
|
||||
var el = win.find('.jsxc_video').add('#' + cid + ' .jsxc_video');
|
||||
|
||||
// only start video call to a full jid
|
||||
if (Strophe.getResourceFromJid(jid) === null) {
|
||||
|
||||
var res = jsxc.storage.getUserItem('buddy_' + cid).res;
|
||||
|
||||
if (Array.isArray(res) && res.length === 1) {
|
||||
jid += '/' + res[0];
|
||||
}
|
||||
}
|
||||
|
||||
el.off('click');
|
||||
|
||||
if (self.conn.caps.hasFeatureByJid(jid, self.reqVideoFeatures)) {
|
||||
el.click(function() {
|
||||
self.startCall(jid);
|
||||
});
|
||||
el.removeClass('jsxc_disabled');
|
||||
|
||||
el.attr('title', jsxc.translate('%%Start video call%%'));
|
||||
} else {
|
||||
el.addClass('jsxc_disabled');
|
||||
|
||||
el.attr('title', jsxc.translate('%%Video call not possible.%%'));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if full jid changed.
|
||||
*
|
||||
* @private
|
||||
* @memberOf jsxc.webrtc
|
||||
* @param e
|
||||
* @param from full jid
|
||||
*/
|
||||
onMessage: function(e, from) {
|
||||
var self = jsxc.webrtc;
|
||||
var bJid = Strophe.getBareJidFromJid(from);
|
||||
|
||||
if (self.chatJids[bJid] !== from) {
|
||||
self.updateIcon(jsxc.jidToCid(bJid));
|
||||
self.chatJids[bJid] = from;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Display status message to user.
|
||||
*
|
||||
* @memberOf jsxc.webrtc
|
||||
* @param txt message
|
||||
* @param d duration in ms
|
||||
*/
|
||||
setStatus: function(txt, d) {
|
||||
var status = $('.jsxc_webrtc .jsxc_status');
|
||||
var duration = (typeof d === 'undefined' || d === null) ? 4000 : d;
|
||||
|
||||
jsxc.debug('[Webrtc]', txt);
|
||||
|
||||
if (status.html()) {
|
||||
// attach old messages
|
||||
txt = status.html() + '<br />' + txt;
|
||||
}
|
||||
|
||||
status.html(txt);
|
||||
|
||||
status.css({
|
||||
'margin-left': '-' + (status.width() / 2) + 'px',
|
||||
opacity: 0,
|
||||
display: 'block'
|
||||
});
|
||||
|
||||
status.stop().animate({
|
||||
opacity: 1
|
||||
});
|
||||
|
||||
clearTimeout(status.data('timeout'));
|
||||
|
||||
if (duration === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var to = setTimeout(function() {
|
||||
status.stop().animate({
|
||||
opacity: 0
|
||||
}, function() {
|
||||
status.html('');
|
||||
});
|
||||
}, duration);
|
||||
|
||||
status.data('timeout', to);
|
||||
},
|
||||
|
||||
/**
|
||||
* Update "video" button if we receive cap information.
|
||||
*
|
||||
* @private
|
||||
* @memberOf jsxc.webrtc
|
||||
* @param event
|
||||
* @param jid
|
||||
*/
|
||||
onCaps: function(event, jid) {
|
||||
var self = jsxc.webrtc;
|
||||
|
||||
self.updateIcon(jsxc.jidToCid(jid));
|
||||
},
|
||||
|
||||
/**
|
||||
* Called if video/audio is ready. Open window and display some messages.
|
||||
*
|
||||
* @private
|
||||
* @memberOf jsxc.webrtc
|
||||
* @param event
|
||||
* @param stream
|
||||
*/
|
||||
onMediaReady: function(event, stream) {
|
||||
jsxc.debug('media ready');
|
||||
|
||||
var self = jsxc.webrtc;
|
||||
|
||||
self.localStream = stream;
|
||||
self.conn.jingle.localStream = stream;
|
||||
|
||||
jsxc.gui.showVideoWindow(self.last_caller);
|
||||
|
||||
var i;
|
||||
for (i = 0; i < stream.getAudioTracks().length; i++) {
|
||||
self.setStatus((stream.getAudioTracks().length > 0) ? 'Use local audio device.' : 'No local audio device.');
|
||||
|
||||
jsxc.debug('using audio device "' + stream.getAudioTracks()[i].label + '"');
|
||||
}
|
||||
for (i = 0; i < stream.getVideoTracks().length; i++) {
|
||||
self.setStatus((stream.getVideoTracks().length > 0) ? 'Use local video device.' : 'No local video device.');
|
||||
|
||||
jsxc.debug('using video device "' + stream.getVideoTracks()[i].label + '"');
|
||||
}
|
||||
|
||||
$(document).one('cleanup.dialog.jsxc', $.proxy(self.hangUp, self));
|
||||
$(document).trigger('finish.mediaready.jsxc');
|
||||
},
|
||||
|
||||
/**
|
||||
* Called if media failes.
|
||||
*
|
||||
* @private
|
||||
* @memberOf jsxc.webrtc
|
||||
*/
|
||||
onMediaFailure: function() {
|
||||
this.setStatus('media failure');
|
||||
},
|
||||
|
||||
/**
|
||||
* Called on incoming call.
|
||||
*
|
||||
* @private
|
||||
* @memberOf jsxc.webrtc
|
||||
* @param event
|
||||
* @param sid Session id
|
||||
*/
|
||||
onCallIncoming: function(event, sid) {
|
||||
jsxc.debug('incoming call' + sid);
|
||||
|
||||
var self = this;
|
||||
var sess = this.conn.jingle.sessions[sid];
|
||||
var jid = jsxc.jidToCid(sess.peerjid);
|
||||
|
||||
// display notification
|
||||
jsxc.notification.notify(jsxc.translate('%%Incoming call%%'), jsxc.translate('%%from%% ' + jid));
|
||||
|
||||
// send signal to partner
|
||||
sess.sendRinging();
|
||||
|
||||
jsxc.webrtc.last_caller = sess.peerjid;
|
||||
|
||||
jsxc.switchEvents({
|
||||
'mediaready.jingle': function(event, stream) {
|
||||
self.setStatus('Accept call');
|
||||
|
||||
sess.localStream = stream;
|
||||
sess.peerconnection.addStream(stream);
|
||||
|
||||
sess.sendAnswer();
|
||||
sess.accept();
|
||||
},
|
||||
'mediafailure.jingle': function() {
|
||||
sess.sendTerminate('decline');
|
||||
sess.terminate();
|
||||
}
|
||||
});
|
||||
|
||||
if (jsxc.webrtc.AUTO_ACCEPT) {
|
||||
self.reqUserMedia();
|
||||
return;
|
||||
}
|
||||
|
||||
var dialog = jsxc.gui.dialog.open(jsxc.gui.template.get('incomingCall', jsxc.jidToCid(jid)));
|
||||
|
||||
dialog.find('.jsxc_accept').click(function() {
|
||||
$(document).trigger('accept.call.jsxc');
|
||||
|
||||
self.reqUserMedia();
|
||||
});
|
||||
|
||||
dialog.find('.jsxc_reject').click(function() {
|
||||
jsxc.gui.dialog.close();
|
||||
$(document).trigger('reject.call.jsxc');
|
||||
|
||||
sess.sendTerminate('decline');
|
||||
sess.terminate();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Called if call is terminated.
|
||||
*
|
||||
* @private
|
||||
* @memberOf jsxc.webrtc
|
||||
* @param event
|
||||
* @param sid Session id
|
||||
* @param reason Reason for termination
|
||||
* @param [text] Optional explanation
|
||||
*/
|
||||
onCallTerminated: function(event, sid, reason, text) {
|
||||
this.setStatus('call terminated ' + sid + (reason ? (': ' + reason + ' ' + text) : ''));
|
||||
|
||||
if (this.localStream) {
|
||||
this.localStream.stop();
|
||||
}
|
||||
|
||||
$('.jsxc_remotevideo')[0].src = "";
|
||||
$('.jsxc_localvideo')[0].src = "";
|
||||
|
||||
this.conn.jingle.localStream = null;
|
||||
this.localStream = null;
|
||||
this.remoteStream = null;
|
||||
|
||||
$('#jsxc_windowList > ul').prepend($('#jsxc_dialog .jsxc_chatarea > ul > li').detach());
|
||||
|
||||
$(document).off('cleanup.dialog.jsxc');
|
||||
$(document).off('error.jingle');
|
||||
jsxc.gui.dialog.close();
|
||||
},
|
||||
|
||||
/**
|
||||
* Remote station is ringing.
|
||||
*
|
||||
* @private
|
||||
* @memberOf jsxc.webrtc
|
||||
*/
|
||||
onCallRinging: function() {
|
||||
this.setStatus('ringing...', 0);
|
||||
},
|
||||
|
||||
/**
|
||||
* Called if we receive a remote stream.
|
||||
*
|
||||
* @private
|
||||
* @memberOf jsxc.webrtc
|
||||
* @param event
|
||||
* @param data
|
||||
* @param sid Session id
|
||||
*/
|
||||
onRemoteStreamAdded: function(event, data, sid) {
|
||||
this.setStatus('Remote stream for session ' + sid + ' added.');
|
||||
|
||||
var stream = data.stream;
|
||||
this.remoteStream = stream;
|
||||
|
||||
var sess = this.conn.jingle.sessions[sid];
|
||||
|
||||
var isVideoDevice = stream.getVideoTracks().length > 0;
|
||||
var isAudioDevice = stream.getAudioTracks().length > 0;
|
||||
|
||||
sess.remoteDevices = {
|
||||
video: isVideoDevice,
|
||||
audio: isAudioDevice
|
||||
};
|
||||
|
||||
this.setStatus(isVideoDevice ? 'Use remote video device.' : 'No remote video device');
|
||||
this.setStatus(isAudioDevice ? 'Use remote audio device.' : 'No remote audio device');
|
||||
|
||||
if ($('.jsxc_remotevideo').length) {
|
||||
RTC.attachMediaStream($('.jsxc_remotevideo'), stream);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Called if the remote stream was removed.
|
||||
*
|
||||
* @private
|
||||
* @meberOf jsxc.webrtc
|
||||
* @param event
|
||||
* @param data
|
||||
* @param sid Session id
|
||||
*/
|
||||
onRemoteStreamRemoved: function(event, data, sid) {
|
||||
this.setStatus('Remote stream for session ' + sid + ' removed.');
|
||||
},
|
||||
|
||||
/**
|
||||
* Extracts local and remote ip and display it to the user.
|
||||
*
|
||||
* @private
|
||||
* @memberOf jsxc.webrtc
|
||||
* @param event
|
||||
* @param sid session id
|
||||
* @param sess
|
||||
*/
|
||||
onIceConnectionStateChanged: function(event, sid, sess) {
|
||||
var sigState = sess.peerconnection.signalingState;
|
||||
var iceCon = sess.peerconnection.iceConnectionState;
|
||||
|
||||
jsxc.debug('iceGat state for ' + sid, sess.peerconnection.iceGatheringState);
|
||||
jsxc.debug('iceCon state for ' + sid, iceCon);
|
||||
jsxc.debug('sig state for ' + sid, sigState);
|
||||
|
||||
if (sigState === 'stable' && iceCon === 'connected') {
|
||||
var localSDP = sess.peerconnection.localDescription.sdp;
|
||||
var remoteSDP = sess.peerconnection.remoteDescription.sdp;
|
||||
|
||||
sess.local_fp = SDPUtil.parse_fingerprint(SDPUtil.find_line(localSDP, 'a=fingerprint:')).fingerprint;
|
||||
sess.remote_fp = SDPUtil.parse_fingerprint(SDPUtil.find_line(remoteSDP, 'a=fingerprint:')).fingerprint;
|
||||
|
||||
var ip_regex = "(\\d{1,3}\\.\\d{1,3}.\\d{1,3}\\.\\d{1,3}) \\d+ typ host";
|
||||
|
||||
sess.remote_ip = remoteSDP.match(new RegExp(ip_regex))[1];
|
||||
sess.local_ip = localSDP.match(new RegExp(ip_regex))[1];
|
||||
|
||||
var regex = new RegExp(ip_regex, 'g');
|
||||
var match;
|
||||
while ((match = regex.exec(remoteSDP)) !== null) {
|
||||
if (match[1] !== sess.remote_ip) {
|
||||
alert('!!! WARNING !!!\n\nPossible Man-in-the-middle attack detected!\n\nYou should close the connection.');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var text = '<p>';
|
||||
text += '<b>' + jsxc.translate('%%Local IP%%: ') + '</b>' + sess.local_ip + '<br />';
|
||||
text += '<b>' + jsxc.translate('%%Remote IP%%: ') + '</b>' + sess.remote_ip + '<br />';
|
||||
text += '<b>' + jsxc.translate('%%Local Fingerprint%%: ') + '</b>' + sess.local_fp + '<br />';
|
||||
text += '<b>' + jsxc.translate('%%Remote Fingerprint%%: ') + '</b>' + sess.remote_fp;
|
||||
text += '</p>';
|
||||
|
||||
$('#jsxc_dialog .jsxc_infobar').html(text);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* No STUN candidates found
|
||||
*
|
||||
* @private
|
||||
* @memberOf jsxc.webrtc
|
||||
*/
|
||||
noStunCandidates: function() {
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* Start a call to the specified jid.
|
||||
*
|
||||
* @memberOf jsxc.webrtc
|
||||
* @param jid full jid
|
||||
*/
|
||||
startCall: function(jid) {
|
||||
var self = this;
|
||||
|
||||
if (Strophe.getResourceFromJid(jid) === null) {
|
||||
jsxc.debug('We need a full jid');
|
||||
return;
|
||||
}
|
||||
|
||||
self.last_caller = jid;
|
||||
|
||||
jsxc.switchEvents({
|
||||
'finish.mediaready.jsxc': function() {
|
||||
self.setStatus('Initiate call');
|
||||
|
||||
$(document).one('error.jingle', function(e, sid, error) {
|
||||
if (error.source !== 'offer') {
|
||||
return;
|
||||
}
|
||||
|
||||
$(document).off('cleanup.dialog.jsxc');
|
||||
setTimeout(function() {
|
||||
jsxc.gui.showAlert("Sorry, we couldn't establish a connection. Maybe your buddy is offline.");
|
||||
}, 500);
|
||||
});
|
||||
|
||||
self.conn.jingle.initiate(jid, self.conn.jid.toLowerCase());
|
||||
},
|
||||
'mediafailure.jingle': function() {
|
||||
jsxc.gui.dialog.close();
|
||||
}
|
||||
});
|
||||
|
||||
this.reqUserMedia();
|
||||
},
|
||||
|
||||
/**
|
||||
* Hang up the current call.
|
||||
*
|
||||
* @memberOf jsxc.webrtc
|
||||
*/
|
||||
hangUp: function() {
|
||||
$(document).off('cleanup.dialog.jsxc');
|
||||
|
||||
jsxc.webrtc.conn.jingle.terminate(null);
|
||||
$(document).trigger('callterminated.jingle');
|
||||
},
|
||||
|
||||
/**
|
||||
* Request video and audio from local user.
|
||||
*
|
||||
* @memberOf jsxc.webrtc
|
||||
*/
|
||||
reqUserMedia: function() {
|
||||
if (this.localStream) {
|
||||
$(document).trigger('mediaready.jingle', [ this.localStream ]);
|
||||
return;
|
||||
}
|
||||
|
||||
jsxc.gui.dialog.open(jsxc.gui.template.get('allowMediaAccess'), {
|
||||
noClose: true
|
||||
});
|
||||
this.setStatus('please allow access to microphone and camera');
|
||||
|
||||
getUserMediaWithConstraints([ 'video', 'audio' ]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Make a snapshot from a video stream and display it.
|
||||
*
|
||||
* @memberOf
|
||||
* @param video Video stream
|
||||
*/
|
||||
snapshot: function(video) {
|
||||
if (!video) {
|
||||
jsxc.debug('Missing video element');
|
||||
}
|
||||
|
||||
$('.jsxc_snapshotbar p').remove();
|
||||
|
||||
var canvas = $('<canvas/>').css('display', 'none').appendTo('body').attr({
|
||||
width: video.width(),
|
||||
height: video.height()
|
||||
}).get(0);
|
||||
var ctx = canvas.getContext('2d');
|
||||
|
||||
ctx.drawImage(video[0], 0, 0);
|
||||
var img = $('<img/>');
|
||||
var url = canvas.toDataURL('image/jpeg');
|
||||
img[0].src = url;
|
||||
var link = $('<a/>').attr({
|
||||
target: '_blank',
|
||||
href: url
|
||||
});
|
||||
link.append(img);
|
||||
$('.jsxc_snapshotbar').append(link);
|
||||
|
||||
canvas.remove();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Display window for video call.
|
||||
*
|
||||
* @memberOf jsxc.gui
|
||||
*/
|
||||
jsxc.gui.showVideoWindow = function(jid) {
|
||||
var self = jsxc.webrtc;
|
||||
|
||||
$(document).one('complete.dialog.jsxc', function() {
|
||||
|
||||
// mute own video element to avoid echoes
|
||||
$('#jsxc_dialog .jsxc_localvideo')[0].muted = true;
|
||||
$('#jsxc_dialog .jsxc_localvideo')[0].volume = 0;
|
||||
|
||||
var rv = $('#jsxc_dialog .jsxc_remotevideo');
|
||||
var lv = $('#jsxc_dialog .jsxc_localvideo');
|
||||
|
||||
lv.draggable({
|
||||
containment: "parent"
|
||||
});
|
||||
|
||||
RTC.attachMediaStream(lv, self.localStream);
|
||||
|
||||
var w_dialog = $('#jsxc_dialog').width();
|
||||
var w_remote = rv.width();
|
||||
|
||||
// fit in video
|
||||
if (w_remote > w_dialog) {
|
||||
var scale = w_dialog / w_remote;
|
||||
var new_h = rv.height() * scale;
|
||||
var new_w = w_dialog;
|
||||
var vc = $('#jsxc_dialog .jsxc_videoContainer');
|
||||
|
||||
rv.height(new_h);
|
||||
rv.width(new_w);
|
||||
|
||||
vc.height(new_h);
|
||||
vc.width(new_w);
|
||||
|
||||
lv.height(lv.height() * scale);
|
||||
lv.width(lv.width() * scale);
|
||||
}
|
||||
|
||||
if (self.remoteStream) {
|
||||
RTC.attachMediaStream(rv, self.remoteStream);
|
||||
}
|
||||
|
||||
var toggleMulti = function(elem, open) {
|
||||
$('#jsxc_dialog .jsxc_multi > div').not(elem).slideUp();
|
||||
|
||||
var opt = {
|
||||
complete: jsxc.gui.dialog.resize
|
||||
};
|
||||
|
||||
if (open) {
|
||||
elem.slideDown(opt);
|
||||
} else {
|
||||
elem.slideToggle(opt);
|
||||
}
|
||||
};
|
||||
|
||||
var win = jsxc.gui.window.open(jsxc.jidToCid(jid));
|
||||
|
||||
$('#jsxc_dialog .jsxc_chatarea ul').append(win.detach());
|
||||
|
||||
$('#jsxc_dialog .jsxc_hangUp').click(function() {
|
||||
jsxc.webrtc.hangUp();
|
||||
});
|
||||
|
||||
$('#jsxc_dialog .jsxc_snapshot').click(function() {
|
||||
jsxc.webrtc.snapshot(rv);
|
||||
toggleMulti($('#jsxc_dialog .jsxc_snapshotbar'), true);
|
||||
});
|
||||
|
||||
$('#jsxc_dialog .jsxc_snapshots').click(function() {
|
||||
toggleMulti($('#jsxc_dialog .jsxc_snapshotbar'));
|
||||
});
|
||||
|
||||
$('#jsxc_dialog .jsxc_showchat').click(function() {
|
||||
toggleMulti($('#jsxc_dialog .jsxc_chatarea'));
|
||||
});
|
||||
|
||||
$('#jsxc_dialog .jsxc_info').click(function() {
|
||||
toggleMulti($('#jsxc_dialog .jsxc_infobar'));
|
||||
});
|
||||
|
||||
$('#jsxc_dialog .jsxc_fullscreen').click(function() {
|
||||
|
||||
if ($.support.fullscreen) {
|
||||
// Reset position of localvideo
|
||||
$(document).one('disabled.fullscreen', function() {
|
||||
lv.removeAttr('style');
|
||||
});
|
||||
|
||||
$('#jsxc_dialog .jsxc_videoContainer').fullscreen();
|
||||
}
|
||||
});
|
||||
|
||||
$('#jsxc_dialog .jsxc_volume').change(function() {
|
||||
rv[0].volume = $(this).val();
|
||||
});
|
||||
|
||||
$('#jsxc_dialog .jsxc_volume').dblclick(function() {
|
||||
$(this).val(0.5);
|
||||
});
|
||||
});
|
||||
|
||||
jsxc.gui.dialog.open(jsxc.gui.template.get('videoWindow'), {
|
||||
noClose: true
|
||||
});
|
||||
};
|
||||
|
||||
$.extend(jsxc.CONST, {
|
||||
KEYCODE_ENTER: 13,
|
||||
KEYCODE_ESC: 27
|
||||
});
|
||||
|
||||
$(document).ready(function() {
|
||||
RTC = setupRTC();
|
||||
|
||||
if (RTC !== null) {
|
||||
RTCPeerconnection = RTC.peerconnection;
|
||||
|
||||
$(document).on('add.roster.jsxc', jsxc.webrtc.onAddRosterItem);
|
||||
$(document).on('init.window.jsxc', jsxc.webrtc.initWindow);
|
||||
$(document).on('attached.jsxc', jsxc.webrtc.init);
|
||||
}
|
||||
});
|
||||
|
||||
$.extend(jsxc.l10n.en, {
|
||||
Please_allow_access_to_microphone_and_camera: 'Please click the "Allow" button at the top, to allow access to microphone and camera.',
|
||||
Incoming_call: 'Incoming call',
|
||||
from: 'from',
|
||||
Do_you_want_to_accept_the_call_from: 'Do you want to accept the call from',
|
||||
Reject: 'Reject',
|
||||
Accept: 'Accept',
|
||||
hang_up: 'hang up',
|
||||
snapshot: 'snapshot',
|
||||
mute_my_audio: 'mute my audio',
|
||||
pause_my_video: 'pause my video',
|
||||
fullscreen: 'fullscreen',
|
||||
Info: 'Info',
|
||||
Local_IP: 'Local IP',
|
||||
Remote_IP: 'Remote IP',
|
||||
Local_Fingerprint: 'Local fingerprint',
|
||||
Remote_Fingerprint: 'Remote fingerprint',
|
||||
Video_call_not_possible: 'Video call not possible',
|
||||
Start_video_call: 'Start video call'
|
||||
});
|
||||
|
||||
$.extend(jsxc.l10n.de, {
|
||||
Please_allow_access_to_microphone_and_camera: 'Bitte klick auf den "Zulassen" Button oben, um den Zugriff auf Kamera und Mikrofon zu erlauben.',
|
||||
Incoming_call: 'Eingehender Anruf',
|
||||
from: 'von',
|
||||
Do_you_want_to_accept_the_call_from: 'Möchtest Du den Anruf annehmen von',
|
||||
Reject: 'Ablehnen',
|
||||
Accept: 'Annehmen',
|
||||
hang_up: 'Auflegen',
|
||||
snapshot: 'Schnappschuss',
|
||||
mute_my_audio: 'Mein Ton aus',
|
||||
pause_my_video: 'Mein Video pausieren',
|
||||
fullscreen: 'Vollbild',
|
||||
Info: 'Info',
|
||||
Local_IP: 'Lokale IP',
|
||||
Remote_IP: 'Remote IP',
|
||||
Local_Fingerprint: 'Lokaler Fingerprint',
|
||||
Remote_Fingerprint: 'Remote Fingerprint',
|
||||
Video_call_not_possible: 'Videoanruf nicht verfügbar',
|
||||
Start_video_call: 'Starte Videoanruf'
|
||||
});
|
||||
|
||||
$.extend(jsxc.l10n.es, {
|
||||
Please_allow_access_to_microphone_and_camera: 'Por favor, permitir el acceso al micrófono y la cámara.',
|
||||
Incoming_call: 'Llamada entrante',
|
||||
from: 'de',
|
||||
Do_you_want_to_accept_the_call_from: 'Desea aceptar la llamada de',
|
||||
Reject: 'Rechazar',
|
||||
Accept: 'Aceptar',
|
||||
hang_up: 'colgar',
|
||||
snapshot: 'instantánea',
|
||||
mute_my_audio: 'silenciar mi audio',
|
||||
pause_my_video: 'pausar mi vídeo',
|
||||
fullscreen: 'pantalla completa',
|
||||
Info: 'Info',
|
||||
Local_IP: 'IP local',
|
||||
Remote_IP: 'IP remota',
|
||||
Local_Fingerprint: 'Firma digital local',
|
||||
Remote_Fingerprint: 'Firma digital remota',
|
||||
Video_call_not_possible: 'Llamada de vídeo no es posible',
|
||||
Start_video_call: 'Iniciar llamada de vídeo'
|
||||
});
|
||||
}(jQuery));
|
||||
@@ -1,173 +0,0 @@
|
||||
.jsxc_videoContainer {
|
||||
width: 640px;
|
||||
height: 480px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.jsxc_remotevideo {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
z-index: 9000;
|
||||
background-color: grey;
|
||||
}
|
||||
|
||||
.jsxc_localvideo {
|
||||
width: 160px;
|
||||
height: 120px;
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
bottom: 10px;
|
||||
z-index: 9990;
|
||||
background-color: black;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.jsxc_webrtc .jsxc_status {
|
||||
z-index: 9999;
|
||||
border-radius: 20px;
|
||||
display: none;
|
||||
position: absolute;
|
||||
top: 30px;
|
||||
left: 50%;
|
||||
background-color: lightgrey;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
color: white;
|
||||
padding: 15px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
div:-moz-full-screen {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
div:-ms-full-screen {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
div:-webkit-full-screen {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
div:fullscreen {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: black;
|
||||
}
|
||||
|
||||
div:-moz-full-screen.jsxc_localvideo {
|
||||
border: 1px solid white;
|
||||
}
|
||||
|
||||
div:-webkit-full-screen.jsxc_localvideo {
|
||||
border: 1px solid white;
|
||||
}
|
||||
|
||||
div:-ms-full-screen.jsxc_localvideo {
|
||||
border: 1px solid white;
|
||||
}
|
||||
|
||||
div:fullscreen.jsxc_localvideo {
|
||||
border: 1px solid white;
|
||||
}
|
||||
|
||||
.jsxc_fullscreen.jsxc_localvideo {
|
||||
border: 1px solid white;
|
||||
}
|
||||
|
||||
.jsxc_multi>div {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.jsxc_snapshotbar {
|
||||
width: 100%;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.jsxc_snapshotbar img {
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.jsxc_buttongroup {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.jsxc_buttongroup button:first-child {
|
||||
border-top-right-radius: 0px;
|
||||
border-bottom-right-radius: 0px;
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
.jsxc_buttongroup button:last-child {
|
||||
border-top-left-radius: 0px;
|
||||
border-bottom-left-radius: 0px;
|
||||
margin-left: 0px;
|
||||
}
|
||||
|
||||
.jsxc_chatarea {
|
||||
position: relative;
|
||||
height: 270px;
|
||||
display: none;
|
||||
background-color: #A4A4A4;
|
||||
}
|
||||
|
||||
.jsxc_chatarea > ul {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 0px;
|
||||
width: 250px;
|
||||
height: 270px;
|
||||
list-style: none;
|
||||
padding: 0px;
|
||||
margin: 0px 0px 0px -100px;
|
||||
}
|
||||
|
||||
.jsxc_chatarea .jsxc_settings {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.jsxc_chatarea .jsxc_close {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.jsxc_chatarea .jsxc_bar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.jsxc_chatarea .jsxc_window {
|
||||
bottom: 0px;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.jsxc_videoSuitable .jsxc_name {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
div.jsxc_video {
|
||||
background-image: url('img/camera_icon_grey.svg');
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
background-size: 15px 15px;
|
||||
}
|
||||
|
||||
div.jsxc_video:not(.jsxc_disabled):hover, #jsxc_buddylist .jsxc_options .jsxc_video {
|
||||
background-image: url('img/camera_icon_white.svg');
|
||||
}
|
||||
|
||||
div.jsxc_video.jsxc_disabled {
|
||||
opacity: 0.5;
|
||||
cursor: default !important;
|
||||
}
|
||||
|
||||
#jsxc_buddylist .jsxc_options .jsxc_video.jsxc_disabled {
|
||||
opacity: 0.2;
|
||||
}
|
||||
@@ -0,0 +1,851 @@
|
||||
/**
|
||||
* @license MIT
|
||||
* @fileOverview Favico animations
|
||||
* @author Miroslav Magda, http://blog.ejci.net
|
||||
* @version 0.3.9
|
||||
*/
|
||||
|
||||
/**
|
||||
* Create new favico instance
|
||||
* @param {Object} Options
|
||||
* @return {Object} Favico object
|
||||
* @example
|
||||
* var favico = new Favico({
|
||||
* bgColor : '#d00',
|
||||
* textColor : '#fff',
|
||||
* fontFamily : 'sans-serif',
|
||||
* fontStyle : 'bold',
|
||||
* position : 'down',
|
||||
* type : 'circle',
|
||||
* animation : 'slide',
|
||||
* dataUrl: function(url){},
|
||||
* win: top
|
||||
* });
|
||||
*/
|
||||
(function() {
|
||||
|
||||
var Favico = (function(opt) {
|
||||
'use strict';
|
||||
opt = (opt) ? opt : {};
|
||||
var _def = {
|
||||
bgColor : '#d00',
|
||||
textColor : '#fff',
|
||||
fontFamily : 'sans-serif', //Arial,Verdana,Times New Roman,serif,sans-serif,...
|
||||
fontStyle : 'bold', //normal,italic,oblique,bold,bolder,lighter,100,200,300,400,500,600,700,800,900
|
||||
type : 'circle',
|
||||
position : 'down', // down, up, left, leftup (upleft)
|
||||
animation : 'slide',
|
||||
elementId : false,
|
||||
dataUrl : false,
|
||||
win: window
|
||||
};
|
||||
var _opt, _orig, _h, _w, _canvas, _context, _img, _ready, _lastBadge, _running, _readyCb, _stop, _browser, _animTimeout, _drawTimeout, _doc;
|
||||
|
||||
_browser = {};
|
||||
_browser.ff = typeof InstallTrigger != 'undefined';
|
||||
_browser.chrome = !!window.chrome;
|
||||
_browser.opera = !!window.opera || navigator.userAgent.indexOf('Opera') >= 0;
|
||||
_browser.ie = /*@cc_on!@*/false;
|
||||
_browser.safari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;
|
||||
_browser.supported = (_browser.chrome || _browser.ff || _browser.opera);
|
||||
|
||||
var _queue = [];
|
||||
_readyCb = function() {
|
||||
};
|
||||
_ready = _stop = false;
|
||||
/**
|
||||
* Initialize favico
|
||||
*/
|
||||
var init = function() {
|
||||
//merge initial options
|
||||
_opt = merge(_def, opt);
|
||||
_opt.bgColor = hexToRgb(_opt.bgColor);
|
||||
_opt.textColor = hexToRgb(_opt.textColor);
|
||||
_opt.position = _opt.position.toLowerCase();
|
||||
_opt.animation = (animation.types['' + _opt.animation]) ? _opt.animation : _def.animation;
|
||||
|
||||
_doc = _opt.win.document;
|
||||
|
||||
var isUp = _opt.position.indexOf('up') > -1;
|
||||
var isLeft = _opt.position.indexOf('left') > -1;
|
||||
|
||||
//transform animation
|
||||
if (isUp || isLeft) {
|
||||
for (var i = 0; i < animation.types['' + _opt.animation].length; i++) {
|
||||
var step = animation.types['' + _opt.animation][i];
|
||||
|
||||
if (isUp) {
|
||||
if (step.y < 0.6) {
|
||||
step.y = step.y - 0.4;
|
||||
} else {
|
||||
step.y = step.y - 2 * step.y + (1 - step.w);
|
||||
}
|
||||
}
|
||||
|
||||
if (isLeft) {
|
||||
if (step.x < 0.6) {
|
||||
step.x = step.x - 0.4;
|
||||
} else {
|
||||
step.x = step.x - 2 * step.x + (1 - step.h);
|
||||
}
|
||||
}
|
||||
|
||||
animation.types['' + _opt.animation][i] = step;
|
||||
}
|
||||
}
|
||||
_opt.type = (type['' + _opt.type]) ? _opt.type : _def.type;
|
||||
|
||||
_orig = link.getIcon();
|
||||
//create temp canvas
|
||||
_canvas = document.createElement('canvas');
|
||||
//create temp image
|
||||
_img = document.createElement('img');
|
||||
if (_orig.hasAttribute('href')) {
|
||||
_img.setAttribute('crossOrigin', 'anonymous');
|
||||
_img.setAttribute('src', _orig.getAttribute('href'));
|
||||
//get width/height
|
||||
_img.onload = function() {
|
||||
_h = (_img.height > 0) ? _img.height : 32;
|
||||
_w = (_img.width > 0) ? _img.width : 32;
|
||||
_canvas.height = _h;
|
||||
_canvas.width = _w;
|
||||
_context = _canvas.getContext('2d');
|
||||
icon.ready();
|
||||
};
|
||||
} else {
|
||||
_img.setAttribute('src', '');
|
||||
_h = 32;
|
||||
_w = 32;
|
||||
_img.height = _h;
|
||||
_img.width = _w;
|
||||
_canvas.height = _h;
|
||||
_canvas.width = _w;
|
||||
_context = _canvas.getContext('2d');
|
||||
icon.ready();
|
||||
}
|
||||
|
||||
};
|
||||
/**
|
||||
* Icon namespace
|
||||
*/
|
||||
var icon = {};
|
||||
/**
|
||||
* Icon is ready (reset icon) and start animation (if ther is any)
|
||||
*/
|
||||
icon.ready = function() {
|
||||
_ready = true;
|
||||
icon.reset();
|
||||
_readyCb();
|
||||
};
|
||||
/**
|
||||
* Reset icon to default state
|
||||
*/
|
||||
icon.reset = function() {
|
||||
//reset
|
||||
if (!_ready) {
|
||||
return;
|
||||
}
|
||||
_queue = [];
|
||||
_lastBadge = false;
|
||||
_running = false;
|
||||
_context.clearRect(0, 0, _w, _h);
|
||||
_context.drawImage(_img, 0, 0, _w, _h);
|
||||
//_stop=true;
|
||||
link.setIcon(_canvas);
|
||||
//webcam('stop');
|
||||
//video('stop');
|
||||
window.clearTimeout(_animTimeout);
|
||||
window.clearTimeout(_drawTimeout);
|
||||
};
|
||||
/**
|
||||
* Start animation
|
||||
*/
|
||||
icon.start = function() {
|
||||
if (!_ready || _running) {
|
||||
return;
|
||||
}
|
||||
var finished = function() {
|
||||
_lastBadge = _queue[0];
|
||||
_running = false;
|
||||
if (_queue.length > 0) {
|
||||
_queue.shift();
|
||||
icon.start();
|
||||
} else {
|
||||
|
||||
}
|
||||
};
|
||||
if (_queue.length > 0) {
|
||||
_running = true;
|
||||
var run = function() {
|
||||
// apply options for this animation
|
||||
['type', 'animation', 'bgColor', 'textColor', 'fontFamily', 'fontStyle'].forEach(function(a) {
|
||||
if ( a in _queue[0].options) {
|
||||
_opt[a] = _queue[0].options[a];
|
||||
}
|
||||
});
|
||||
animation.run(_queue[0].options, function() {
|
||||
finished();
|
||||
}, false);
|
||||
};
|
||||
if (_lastBadge) {
|
||||
animation.run(_lastBadge.options, function() {
|
||||
run();
|
||||
}, true);
|
||||
} else {
|
||||
run();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Badge types
|
||||
*/
|
||||
var type = {};
|
||||
var options = function(opt) {
|
||||
opt.n = (( typeof opt.n) === 'number') ? Math.abs(opt.n | 0) : opt.n;
|
||||
opt.x = _w * opt.x;
|
||||
opt.y = _h * opt.y;
|
||||
opt.w = _w * opt.w;
|
||||
opt.h = _h * opt.h;
|
||||
opt.len = ("" + opt.n).length;
|
||||
return opt;
|
||||
};
|
||||
/**
|
||||
* Generate circle
|
||||
* @param {Object} opt Badge options
|
||||
*/
|
||||
type.circle = function(opt) {
|
||||
opt = options(opt);
|
||||
var more = false;
|
||||
if (opt.len === 2) {
|
||||
opt.x = opt.x - opt.w * 0.4;
|
||||
opt.w = opt.w * 1.4;
|
||||
more = true;
|
||||
} else if (opt.len >= 3) {
|
||||
opt.x = opt.x - opt.w * 0.65;
|
||||
opt.w = opt.w * 1.65;
|
||||
more = true;
|
||||
}
|
||||
_context.clearRect(0, 0, _w, _h);
|
||||
_context.drawImage(_img, 0, 0, _w, _h);
|
||||
_context.beginPath();
|
||||
_context.font = _opt.fontStyle + " " + Math.floor(opt.h * (opt.n > 99 ? 0.85 : 1)) + "px " + _opt.fontFamily;
|
||||
_context.textAlign = 'center';
|
||||
if (more) {
|
||||
_context.moveTo(opt.x + opt.w / 2, opt.y);
|
||||
_context.lineTo(opt.x + opt.w - opt.h / 2, opt.y);
|
||||
_context.quadraticCurveTo(opt.x + opt.w, opt.y, opt.x + opt.w, opt.y + opt.h / 2);
|
||||
_context.lineTo(opt.x + opt.w, opt.y + opt.h - opt.h / 2);
|
||||
_context.quadraticCurveTo(opt.x + opt.w, opt.y + opt.h, opt.x + opt.w - opt.h / 2, opt.y + opt.h);
|
||||
_context.lineTo(opt.x + opt.h / 2, opt.y + opt.h);
|
||||
_context.quadraticCurveTo(opt.x, opt.y + opt.h, opt.x, opt.y + opt.h - opt.h / 2);
|
||||
_context.lineTo(opt.x, opt.y + opt.h / 2);
|
||||
_context.quadraticCurveTo(opt.x, opt.y, opt.x + opt.h / 2, opt.y);
|
||||
} else {
|
||||
_context.arc(opt.x + opt.w / 2, opt.y + opt.h / 2, opt.h / 2, 0, 2 * Math.PI);
|
||||
}
|
||||
_context.fillStyle = 'rgba(' + _opt.bgColor.r + ',' + _opt.bgColor.g + ',' + _opt.bgColor.b + ',' + opt.o + ')';
|
||||
_context.fill();
|
||||
_context.closePath();
|
||||
_context.beginPath();
|
||||
_context.stroke();
|
||||
_context.fillStyle = 'rgba(' + _opt.textColor.r + ',' + _opt.textColor.g + ',' + _opt.textColor.b + ',' + opt.o + ')';
|
||||
//_context.fillText((more) ? '9+' : opt.n, Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.15));
|
||||
if (( typeof opt.n) === 'number' && opt.n > 999) {
|
||||
_context.fillText(((opt.n > 9999) ? 9 : Math.floor(opt.n / 1000) ) + 'k+', Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.2));
|
||||
} else {
|
||||
_context.fillText(opt.n, Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.15));
|
||||
}
|
||||
_context.closePath();
|
||||
};
|
||||
/**
|
||||
* Generate rectangle
|
||||
* @param {Object} opt Badge options
|
||||
*/
|
||||
type.rectangle = function(opt) {
|
||||
opt = options(opt);
|
||||
var more = false;
|
||||
if (opt.len === 2) {
|
||||
opt.x = opt.x - opt.w * 0.4;
|
||||
opt.w = opt.w * 1.4;
|
||||
more = true;
|
||||
} else if (opt.len >= 3) {
|
||||
opt.x = opt.x - opt.w * 0.65;
|
||||
opt.w = opt.w * 1.65;
|
||||
more = true;
|
||||
}
|
||||
_context.clearRect(0, 0, _w, _h);
|
||||
_context.drawImage(_img, 0, 0, _w, _h);
|
||||
_context.beginPath();
|
||||
_context.font = _opt.fontStyle + " " + Math.floor(opt.h * (opt.n > 99 ? 0.9 : 1)) + "px " + _opt.fontFamily;
|
||||
_context.textAlign = 'center';
|
||||
_context.fillStyle = 'rgba(' + _opt.bgColor.r + ',' + _opt.bgColor.g + ',' + _opt.bgColor.b + ',' + opt.o + ')';
|
||||
_context.fillRect(opt.x, opt.y, opt.w, opt.h);
|
||||
_context.fillStyle = 'rgba(' + _opt.textColor.r + ',' + _opt.textColor.g + ',' + _opt.textColor.b + ',' + opt.o + ')';
|
||||
//_context.fillText((more) ? '9+' : opt.n, Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.15));
|
||||
if (( typeof opt.n) === 'number' && opt.n > 999) {
|
||||
_context.fillText(((opt.n > 9999) ? 9 : Math.floor(opt.n / 1000) ) + 'k+', Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.2));
|
||||
} else {
|
||||
_context.fillText(opt.n, Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.15));
|
||||
}
|
||||
_context.closePath();
|
||||
};
|
||||
|
||||
/**
|
||||
* Set badge
|
||||
*/
|
||||
var badge = function(number, opts) {
|
||||
opts = (( typeof opts) === 'string' ? {
|
||||
animation : opts
|
||||
} : opts) || {};
|
||||
_readyCb = function() {
|
||||
try {
|
||||
if ( typeof (number) === 'number' ? (number > 0) : (number !== '')) {
|
||||
var q = {
|
||||
type : 'badge',
|
||||
options : {
|
||||
n : number
|
||||
}
|
||||
};
|
||||
if ('animation' in opts && animation.types['' + opts.animation]) {
|
||||
q.options.animation = '' + opts.animation;
|
||||
}
|
||||
if ('type' in opts && type['' + opts.type]) {
|
||||
q.options.type = '' + opts.type;
|
||||
}
|
||||
['bgColor', 'textColor'].forEach(function(o) {
|
||||
if ( o in opts) {
|
||||
q.options[o] = hexToRgb(opts[o]);
|
||||
}
|
||||
});
|
||||
['fontStyle', 'fontFamily'].forEach(function(o) {
|
||||
if ( o in opts) {
|
||||
q.options[o] = opts[o];
|
||||
}
|
||||
});
|
||||
_queue.push(q);
|
||||
if (_queue.length > 100) {
|
||||
throw new Error('Too many badges requests in queue.');
|
||||
}
|
||||
icon.start();
|
||||
} else {
|
||||
icon.reset();
|
||||
}
|
||||
} catch(e) {
|
||||
throw new Error('Error setting badge. Message: ' + e.message);
|
||||
}
|
||||
};
|
||||
if (_ready) {
|
||||
_readyCb();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Set image as icon
|
||||
*/
|
||||
var image = function(imageElement) {
|
||||
_readyCb = function() {
|
||||
try {
|
||||
var w = imageElement.width;
|
||||
var h = imageElement.height;
|
||||
var newImg = document.createElement('img');
|
||||
var ratio = (w / _w < h / _h) ? (w / _w) : (h / _h);
|
||||
newImg.setAttribute('crossOrigin', 'anonymous');
|
||||
newImg.setAttribute('src', imageElement.getAttribute('src'));
|
||||
newImg.height = (h / ratio);
|
||||
newImg.width = (w / ratio);
|
||||
_context.clearRect(0, 0, _w, _h);
|
||||
_context.drawImage(newImg, 0, 0, _w, _h);
|
||||
link.setIcon(_canvas);
|
||||
} catch(e) {
|
||||
throw new Error('Error setting image. Message: ' + e.message);
|
||||
}
|
||||
};
|
||||
if (_ready) {
|
||||
_readyCb();
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Set video as icon
|
||||
*/
|
||||
var video = function(videoElement) {
|
||||
_readyCb = function() {
|
||||
try {
|
||||
if (videoElement === 'stop') {
|
||||
_stop = true;
|
||||
icon.reset();
|
||||
_stop = false;
|
||||
return;
|
||||
}
|
||||
//var w = videoElement.width;
|
||||
//var h = videoElement.height;
|
||||
//var ratio = (w / _w < h / _h) ? (w / _w) : (h / _h);
|
||||
videoElement.addEventListener('play', function() {
|
||||
drawVideo(this);
|
||||
}, false);
|
||||
|
||||
} catch(e) {
|
||||
throw new Error('Error setting video. Message: ' + e.message);
|
||||
}
|
||||
};
|
||||
if (_ready) {
|
||||
_readyCb();
|
||||
}
|
||||
};
|
||||
/**
|
||||
* Set video as icon
|
||||
*/
|
||||
var webcam = function(action) {
|
||||
//UR
|
||||
if (!window.URL || !window.URL.createObjectURL) {
|
||||
window.URL = window.URL || {};
|
||||
window.URL.createObjectURL = function(obj) {
|
||||
return obj;
|
||||
};
|
||||
}
|
||||
if (_browser.supported) {
|
||||
var newVideo = false;
|
||||
navigator.getUserMedia = navigator.getUserMedia || navigator.oGetUserMedia || navigator.msGetUserMedia || navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
|
||||
_readyCb = function() {
|
||||
try {
|
||||
if (action === 'stop') {
|
||||
_stop = true;
|
||||
icon.reset();
|
||||
_stop = false;
|
||||
return;
|
||||
}
|
||||
newVideo = document.createElement('video');
|
||||
newVideo.width = _w;
|
||||
newVideo.height = _h;
|
||||
navigator.getUserMedia({
|
||||
video : true,
|
||||
audio : false
|
||||
}, function(stream) {
|
||||
newVideo.src = URL.createObjectURL(stream);
|
||||
newVideo.play();
|
||||
drawVideo(newVideo);
|
||||
}, function() {
|
||||
});
|
||||
} catch(e) {
|
||||
throw new Error('Error setting webcam. Message: ' + e.message);
|
||||
}
|
||||
};
|
||||
if (_ready) {
|
||||
_readyCb();
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* Draw video to context and repeat :)
|
||||
*/
|
||||
function drawVideo(video) {
|
||||
if (video.paused || video.ended || _stop) {
|
||||
return false;
|
||||
}
|
||||
//nasty hack for FF webcam (Thanks to Julian Ćwirko, kontakt@redsunmedia.pl)
|
||||
try {
|
||||
_context.clearRect(0, 0, _w, _h);
|
||||
_context.drawImage(video, 0, 0, _w, _h);
|
||||
} catch(e) {
|
||||
|
||||
}
|
||||
_drawTimeout = setTimeout(drawVideo, animation.duration, video);
|
||||
link.setIcon(_canvas);
|
||||
}
|
||||
|
||||
var link = {};
|
||||
/**
|
||||
* Get icon from HEAD tag or create a new <link> element
|
||||
*/
|
||||
link.getIcon = function() {
|
||||
var elm = false;
|
||||
//get link element
|
||||
var getLink = function() {
|
||||
var link = _doc.getElementsByTagName('head')[0].getElementsByTagName('link');
|
||||
for (var l = link.length, i = (l - 1); i >= 0; i--) {
|
||||
if ((/(^|\s)icon(\s|$)/i).test(link[i].getAttribute('rel'))) {
|
||||
return link[i];
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
if (_opt.element) {
|
||||
elm = _opt.element;
|
||||
} else if (_opt.elementId) {
|
||||
//if img element identified by elementId
|
||||
elm = _doc.getElementById(_opt.elementId);
|
||||
elm.setAttribute('href', elm.getAttribute('src'));
|
||||
} else {
|
||||
//if link element
|
||||
elm = getLink();
|
||||
if (elm === false) {
|
||||
elm = _doc.createElement('link');
|
||||
elm.setAttribute('rel', 'icon');
|
||||
_doc.getElementsByTagName('head')[0].appendChild(elm);
|
||||
}
|
||||
}
|
||||
elm.setAttribute('type', 'image/png');
|
||||
return elm;
|
||||
};
|
||||
link.setIcon = function(canvas) {
|
||||
var url = canvas.toDataURL('image/png');
|
||||
if (_opt.dataUrl) {
|
||||
//if using custom exporter
|
||||
_opt.dataUrl(url);
|
||||
}
|
||||
if (_opt.element) {
|
||||
_opt.element.setAttribute('href', url);
|
||||
_opt.element.setAttribute('src', url);
|
||||
} else if (_opt.elementId) {
|
||||
//if is attached to element (image)
|
||||
var elm = _doc.getElementById(_opt.elementId);
|
||||
elm.setAttribute('href', url);
|
||||
elm.setAttribute('src', url);
|
||||
} else {
|
||||
//if is attached to fav icon
|
||||
if (_browser.ff || _browser.opera) {
|
||||
//for FF we need to "recreate" element, atach to dom and remove old <link>
|
||||
//var originalType = _orig.getAttribute('rel');
|
||||
var old = _orig;
|
||||
_orig = _doc.createElement('link');
|
||||
//_orig.setAttribute('rel', originalType);
|
||||
if (_browser.opera) {
|
||||
_orig.setAttribute('rel', 'icon');
|
||||
}
|
||||
_orig.setAttribute('rel', 'icon');
|
||||
_orig.setAttribute('type', 'image/png');
|
||||
_doc.getElementsByTagName('head')[0].appendChild(_orig);
|
||||
_orig.setAttribute('href', url);
|
||||
if (old.parentNode) {
|
||||
old.parentNode.removeChild(old);
|
||||
}
|
||||
} else {
|
||||
_orig.setAttribute('href', url);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb#answer-5624139
|
||||
//HEX to RGB convertor
|
||||
function hexToRgb(hex) {
|
||||
var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
|
||||
hex = hex.replace(shorthandRegex, function(m, r, g, b) {
|
||||
return r + r + g + g + b + b;
|
||||
});
|
||||
var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
||||
return result ? {
|
||||
r : parseInt(result[1], 16),
|
||||
g : parseInt(result[2], 16),
|
||||
b : parseInt(result[3], 16)
|
||||
} : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge options
|
||||
*/
|
||||
function merge(def, opt) {
|
||||
var mergedOpt = {};
|
||||
var attrname;
|
||||
for (attrname in def) {
|
||||
mergedOpt[attrname] = def[attrname];
|
||||
}
|
||||
for (attrname in opt) {
|
||||
mergedOpt[attrname] = opt[attrname];
|
||||
}
|
||||
return mergedOpt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cross-browser page visibility shim
|
||||
* http://stackoverflow.com/questions/12536562/detect-whether-a-window-is-visible
|
||||
*/
|
||||
function isPageHidden() {
|
||||
return _doc.hidden || _doc.msHidden || _doc.webkitHidden || _doc.mozHidden;
|
||||
}
|
||||
|
||||
/**
|
||||
* @namespace animation
|
||||
*/
|
||||
var animation = {};
|
||||
/**
|
||||
* Animation "frame" duration
|
||||
*/
|
||||
animation.duration = 40;
|
||||
/**
|
||||
* Animation types (none,fade,pop,slide)
|
||||
*/
|
||||
animation.types = {};
|
||||
animation.types.fade = [{
|
||||
x : 0.4,
|
||||
y : 0.4,
|
||||
w : 0.6,
|
||||
h : 0.6,
|
||||
o : 0.0
|
||||
}, {
|
||||
x : 0.4,
|
||||
y : 0.4,
|
||||
w : 0.6,
|
||||
h : 0.6,
|
||||
o : 0.1
|
||||
}, {
|
||||
x : 0.4,
|
||||
y : 0.4,
|
||||
w : 0.6,
|
||||
h : 0.6,
|
||||
o : 0.2
|
||||
}, {
|
||||
x : 0.4,
|
||||
y : 0.4,
|
||||
w : 0.6,
|
||||
h : 0.6,
|
||||
o : 0.3
|
||||
}, {
|
||||
x : 0.4,
|
||||
y : 0.4,
|
||||
w : 0.6,
|
||||
h : 0.6,
|
||||
o : 0.4
|
||||
}, {
|
||||
x : 0.4,
|
||||
y : 0.4,
|
||||
w : 0.6,
|
||||
h : 0.6,
|
||||
o : 0.5
|
||||
}, {
|
||||
x : 0.4,
|
||||
y : 0.4,
|
||||
w : 0.6,
|
||||
h : 0.6,
|
||||
o : 0.6
|
||||
}, {
|
||||
x : 0.4,
|
||||
y : 0.4,
|
||||
w : 0.6,
|
||||
h : 0.6,
|
||||
o : 0.7
|
||||
}, {
|
||||
x : 0.4,
|
||||
y : 0.4,
|
||||
w : 0.6,
|
||||
h : 0.6,
|
||||
o : 0.8
|
||||
}, {
|
||||
x : 0.4,
|
||||
y : 0.4,
|
||||
w : 0.6,
|
||||
h : 0.6,
|
||||
o : 0.9
|
||||
}, {
|
||||
x : 0.4,
|
||||
y : 0.4,
|
||||
w : 0.6,
|
||||
h : 0.6,
|
||||
o : 1.0
|
||||
}];
|
||||
animation.types.none = [{
|
||||
x : 0.4,
|
||||
y : 0.4,
|
||||
w : 0.6,
|
||||
h : 0.6,
|
||||
o : 1
|
||||
}];
|
||||
animation.types.pop = [{
|
||||
x : 1,
|
||||
y : 1,
|
||||
w : 0,
|
||||
h : 0,
|
||||
o : 1
|
||||
}, {
|
||||
x : 0.9,
|
||||
y : 0.9,
|
||||
w : 0.1,
|
||||
h : 0.1,
|
||||
o : 1
|
||||
}, {
|
||||
x : 0.8,
|
||||
y : 0.8,
|
||||
w : 0.2,
|
||||
h : 0.2,
|
||||
o : 1
|
||||
}, {
|
||||
x : 0.7,
|
||||
y : 0.7,
|
||||
w : 0.3,
|
||||
h : 0.3,
|
||||
o : 1
|
||||
}, {
|
||||
x : 0.6,
|
||||
y : 0.6,
|
||||
w : 0.4,
|
||||
h : 0.4,
|
||||
o : 1
|
||||
}, {
|
||||
x : 0.5,
|
||||
y : 0.5,
|
||||
w : 0.5,
|
||||
h : 0.5,
|
||||
o : 1
|
||||
}, {
|
||||
x : 0.4,
|
||||
y : 0.4,
|
||||
w : 0.6,
|
||||
h : 0.6,
|
||||
o : 1
|
||||
}];
|
||||
animation.types.popFade = [{
|
||||
x : 0.75,
|
||||
y : 0.75,
|
||||
w : 0,
|
||||
h : 0,
|
||||
o : 0
|
||||
}, {
|
||||
x : 0.65,
|
||||
y : 0.65,
|
||||
w : 0.1,
|
||||
h : 0.1,
|
||||
o : 0.2
|
||||
}, {
|
||||
x : 0.6,
|
||||
y : 0.6,
|
||||
w : 0.2,
|
||||
h : 0.2,
|
||||
o : 0.4
|
||||
}, {
|
||||
x : 0.55,
|
||||
y : 0.55,
|
||||
w : 0.3,
|
||||
h : 0.3,
|
||||
o : 0.6
|
||||
}, {
|
||||
x : 0.50,
|
||||
y : 0.50,
|
||||
w : 0.4,
|
||||
h : 0.4,
|
||||
o : 0.8
|
||||
}, {
|
||||
x : 0.45,
|
||||
y : 0.45,
|
||||
w : 0.5,
|
||||
h : 0.5,
|
||||
o : 0.9
|
||||
}, {
|
||||
x : 0.4,
|
||||
y : 0.4,
|
||||
w : 0.6,
|
||||
h : 0.6,
|
||||
o : 1
|
||||
}];
|
||||
animation.types.slide = [{
|
||||
x : 0.4,
|
||||
y : 1,
|
||||
w : 0.6,
|
||||
h : 0.6,
|
||||
o : 1
|
||||
}, {
|
||||
x : 0.4,
|
||||
y : 0.9,
|
||||
w : 0.6,
|
||||
h : 0.6,
|
||||
o : 1
|
||||
}, {
|
||||
x : 0.4,
|
||||
y : 0.9,
|
||||
w : 0.6,
|
||||
h : 0.6,
|
||||
o : 1
|
||||
}, {
|
||||
x : 0.4,
|
||||
y : 0.8,
|
||||
w : 0.6,
|
||||
h : 0.6,
|
||||
o : 1
|
||||
}, {
|
||||
x : 0.4,
|
||||
y : 0.7,
|
||||
w : 0.6,
|
||||
h : 0.6,
|
||||
o : 1
|
||||
}, {
|
||||
x : 0.4,
|
||||
y : 0.6,
|
||||
w : 0.6,
|
||||
h : 0.6,
|
||||
o : 1
|
||||
}, {
|
||||
x : 0.4,
|
||||
y : 0.5,
|
||||
w : 0.6,
|
||||
h : 0.6,
|
||||
o : 1
|
||||
}, {
|
||||
x : 0.4,
|
||||
y : 0.4,
|
||||
w : 0.6,
|
||||
h : 0.6,
|
||||
o : 1
|
||||
}];
|
||||
/**
|
||||
* Run animation
|
||||
* @param {Object} opt Animation options
|
||||
* @param {Object} cb Callabak after all steps are done
|
||||
* @param {Object} revert Reverse order? true|false
|
||||
* @param {Object} step Optional step number (frame bumber)
|
||||
*/
|
||||
animation.run = function(opt, cb, revert, step) {
|
||||
var animationType = animation.types[isPageHidden() ? 'none' : _opt.animation];
|
||||
if (revert === true) {
|
||||
step = ( typeof step !== 'undefined') ? step : animationType.length - 1;
|
||||
} else {
|
||||
step = ( typeof step !== 'undefined') ? step : 0;
|
||||
}
|
||||
cb = (cb) ? cb : function() {
|
||||
};
|
||||
if ((step < animationType.length) && (step >= 0)) {
|
||||
type[_opt.type](merge(opt, animationType[step]));
|
||||
_animTimeout = setTimeout(function() {
|
||||
if (revert) {
|
||||
step = step - 1;
|
||||
} else {
|
||||
step = step + 1;
|
||||
}
|
||||
animation.run(opt, cb, revert, step);
|
||||
}, animation.duration);
|
||||
|
||||
link.setIcon(_canvas);
|
||||
} else {
|
||||
cb();
|
||||
return;
|
||||
}
|
||||
};
|
||||
//auto init
|
||||
init();
|
||||
return {
|
||||
badge : badge,
|
||||
video : video,
|
||||
image : image,
|
||||
webcam : webcam,
|
||||
reset : icon.reset,
|
||||
browser : {
|
||||
supported : _browser.supported
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
// AMD / RequireJS
|
||||
if ( typeof define !== 'undefined' && define.amd) {
|
||||
define([], function() {
|
||||
return Favico;
|
||||
});
|
||||
}
|
||||
// CommonJS
|
||||
else if ( typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = Favico;
|
||||
}
|
||||
// included directly via <script> tag
|
||||
else {
|
||||
this.Favico = Favico;
|
||||
}
|
||||
|
||||
})();
|
||||
@@ -2,35 +2,81 @@
|
||||
* Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
|
||||
* and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
|
||||
*
|
||||
* Version: 1.0.0
|
||||
*
|
||||
* Version: 1.3.3 + pr#94
|
||||
*
|
||||
*/
|
||||
(function($) {
|
||||
|
||||
jQuery.fn.extend({
|
||||
$.fn.extend({
|
||||
slimScroll: function(options) {
|
||||
|
||||
var defaults = {
|
||||
wheelStep : 20,
|
||||
|
||||
// width in pixels of the visible scroll area
|
||||
width : 'auto',
|
||||
|
||||
// height in pixels of the visible scroll area
|
||||
height : '250px',
|
||||
|
||||
// width in pixels of the scrollbar and rail
|
||||
size : '7px',
|
||||
|
||||
// scrollbar color, accepts any hex/color value
|
||||
color: '#000',
|
||||
|
||||
// scrollbar position - left/right
|
||||
position : 'right',
|
||||
|
||||
// distance in pixels between the side edge and the scrollbar
|
||||
distance : '1px',
|
||||
|
||||
// default scroll position on load - top / bottom / $('selector')
|
||||
start : 'top',
|
||||
|
||||
// sets scrollbar opacity
|
||||
opacity : .4,
|
||||
|
||||
// enables always-on mode for the scrollbar
|
||||
alwaysVisible : false,
|
||||
disableFadeOut: false,
|
||||
|
||||
// check if we should hide the scrollbar when user is hovering over
|
||||
disableFadeOut : false,
|
||||
|
||||
// sets visibility of the rail
|
||||
railVisible : false,
|
||||
|
||||
// sets rail color
|
||||
railColor : '#333',
|
||||
railOpacity : '0.2',
|
||||
|
||||
// sets rail opacity
|
||||
railOpacity : .2,
|
||||
|
||||
// whether we should use jQuery UI Draggable to enable bar dragging
|
||||
railDraggable : true,
|
||||
|
||||
// defautlt CSS class of the slimscroll rail
|
||||
railClass : 'slimScrollRail',
|
||||
|
||||
// defautlt CSS class of the slimscroll bar
|
||||
barClass : 'slimScrollBar',
|
||||
|
||||
// defautlt CSS class of the slimscroll wrapper
|
||||
wrapperClass : 'slimScrollDiv',
|
||||
|
||||
// check if mousewheel should scroll the window if we reach top/bottom
|
||||
allowPageScroll : false,
|
||||
scroll : 0,
|
||||
touchScrollStep : 200
|
||||
|
||||
// scroll amount applied to each mouse wheel step
|
||||
wheelStep : 20,
|
||||
|
||||
// scroll amount applied when user is using gestures
|
||||
touchScrollStep : 200,
|
||||
|
||||
// sets border radius
|
||||
borderRadius: '7px',
|
||||
|
||||
// sets border radius of the rail
|
||||
railBorderRadius : '7px'
|
||||
};
|
||||
|
||||
var o = $.extend(defaults, options);
|
||||
@@ -38,7 +84,7 @@
|
||||
// do it for every element that matches selector
|
||||
this.each(function(){
|
||||
|
||||
var isOverPanel, isOverBar, isDragg, queueHide, touchDif,
|
||||
var isOverPanel, isOverBar, isDragg, queueHide, touchDif,
|
||||
barHeight, percentScroll, lastScroll,
|
||||
divS = '<div></div>',
|
||||
minBarHeight = 30,
|
||||
@@ -48,20 +94,33 @@
|
||||
var me = $(this);
|
||||
|
||||
// ensure we are not binding it again
|
||||
if (me.parent().hasClass('slimScrollDiv'))
|
||||
{
|
||||
if (me.parent().hasClass(o.wrapperClass))
|
||||
{
|
||||
// start from last bar position
|
||||
var offset = me.scrollTop();
|
||||
|
||||
// find bar and rail
|
||||
bar = me.parent().find('.slimScrollBar');
|
||||
rail = me.parent().find('.slimScrollRail');
|
||||
|
||||
bar = me.parent().find('.' + o.barClass);
|
||||
rail = me.parent().find('.' + o.railClass);
|
||||
|
||||
getBarHeight();
|
||||
|
||||
// check if we should scroll existing instance
|
||||
if (options)
|
||||
if ($.isPlainObject(options))
|
||||
{
|
||||
// Pass height: auto to an existing slimscroll object to force a resize after contents have changed
|
||||
if ( 'height' in options && options.height == 'auto' ) {
|
||||
me.parent().css('height', 'auto');
|
||||
me.css('height', 'auto');
|
||||
var height = me.parent().parent().height();
|
||||
me.parent().css('height', height);
|
||||
me.css('height', height);
|
||||
} else if ('height' in options) {
|
||||
var h = options.height;
|
||||
me.parent().css('height', h);
|
||||
me.css('height', h);
|
||||
}
|
||||
|
||||
if ('scrollTo' in options)
|
||||
{
|
||||
// jump to a static point
|
||||
@@ -72,6 +131,14 @@
|
||||
// jump by value pixels
|
||||
offset += parseInt(o.scrollBy);
|
||||
}
|
||||
else if ('destroy' in options)
|
||||
{
|
||||
// remove slimscroll elements
|
||||
bar.remove();
|
||||
rail.remove();
|
||||
me.unwrap();
|
||||
return;
|
||||
}
|
||||
|
||||
// scroll content by the given offset
|
||||
scrollContent(offset, false, true);
|
||||
@@ -79,9 +146,16 @@
|
||||
|
||||
return;
|
||||
}
|
||||
else if ($.isPlainObject(options))
|
||||
{
|
||||
if ('destroy' in options)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// optionally set height to the parent's height
|
||||
o.height = (o.height == 'auto') ? me.parent().innerHeight() : o.height;
|
||||
o.height = (o.height == 'auto') ? me.parent().height() : o.height;
|
||||
|
||||
// wrap content
|
||||
var wrapper = $(divS)
|
||||
@@ -101,7 +175,7 @@
|
||||
});
|
||||
|
||||
// create scrollbar rail
|
||||
var rail = $(divS)
|
||||
var rail = $(divS)
|
||||
.addClass(o.railClass)
|
||||
.css({
|
||||
width: o.size,
|
||||
@@ -109,7 +183,7 @@
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
display: (o.alwaysVisible && o.railVisible) ? 'block' : 'none',
|
||||
'border-radius': o.size,
|
||||
'border-radius': o.railBorderRadius,
|
||||
background: o.railColor,
|
||||
opacity: o.railOpacity,
|
||||
zIndex: 90
|
||||
@@ -125,10 +199,10 @@
|
||||
top: 0,
|
||||
opacity: o.opacity,
|
||||
display: o.alwaysVisible ? 'block' : 'none',
|
||||
'border-radius' : o.size,
|
||||
BorderRadius: o.size,
|
||||
MozBorderRadius: o.size,
|
||||
WebkitBorderRadius: o.size,
|
||||
'border-radius' : o.borderRadius,
|
||||
BorderRadius: o.borderRadius,
|
||||
MozBorderRadius: o.borderRadius,
|
||||
WebkitBorderRadius: o.borderRadius,
|
||||
zIndex: 99
|
||||
});
|
||||
|
||||
@@ -144,18 +218,31 @@
|
||||
me.parent().append(bar);
|
||||
me.parent().append(rail);
|
||||
|
||||
// make it draggable
|
||||
bar.draggable({
|
||||
axis: 'y',
|
||||
containment: 'parent',
|
||||
start: function() { isDragg = true; },
|
||||
stop: function() { isDragg = false; hideBar(); },
|
||||
drag: function(e)
|
||||
{
|
||||
// scroll content
|
||||
scrollContent(0, $(this).position().top, false);
|
||||
}
|
||||
});
|
||||
// make it draggable and no longer dependent on the jqueryUI
|
||||
if (o.railDraggable){
|
||||
bar.bind("mousedown", function(e) {
|
||||
var $doc = $(document);
|
||||
isDragg = true;
|
||||
t = parseFloat(bar.css('top'));
|
||||
pageY = e.pageY;
|
||||
|
||||
$doc.bind("mousemove.slimscroll", function(e){
|
||||
currTop = t + e.pageY - pageY;
|
||||
bar.css('top', currTop);
|
||||
scrollContent(0, bar.position().top, false);// scroll content
|
||||
});
|
||||
|
||||
$doc.bind("mouseup.slimscroll", function(e) {
|
||||
isDragg = false;hideBar();
|
||||
$doc.unbind('.slimscroll');
|
||||
});
|
||||
return false;
|
||||
}).bind("selectstart.slimscroll", function(e){
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
// on rail over
|
||||
rail.hover(function(){
|
||||
@@ -191,18 +278,44 @@
|
||||
});
|
||||
|
||||
me.bind('touchmove', function(e){
|
||||
// prevent scrolling the page
|
||||
e.originalEvent.preventDefault();
|
||||
// prevent scrolling the page if necessary
|
||||
if(!releaseScroll)
|
||||
{
|
||||
e.originalEvent.preventDefault();
|
||||
}
|
||||
if (e.originalEvent.touches.length)
|
||||
{
|
||||
// see how far user swiped
|
||||
var diff = (touchDif - e.originalEvent.touches[0].pageY) / o.touchScrollStep;
|
||||
// scroll content
|
||||
scrollContent(diff, true);
|
||||
touchDif = e.originalEvent.touches[0].pageY;
|
||||
}
|
||||
});
|
||||
|
||||
var _onWheel = function(e)
|
||||
// set up initial height
|
||||
getBarHeight();
|
||||
|
||||
// check start position
|
||||
if (o.start === 'bottom')
|
||||
{
|
||||
// scroll content to bottom
|
||||
bar.css({ top: me.outerHeight() - bar.outerHeight() });
|
||||
scrollContent(0, true);
|
||||
}
|
||||
else if (o.start !== 'top')
|
||||
{
|
||||
// assume jQuery selector
|
||||
scrollContent($(o.start).position().top, null, true);
|
||||
|
||||
// make sure bar stays hidden
|
||||
if (!o.alwaysVisible) { bar.hide(); }
|
||||
}
|
||||
|
||||
// attach scroll events
|
||||
attachWheel();
|
||||
|
||||
function _onWheel(e)
|
||||
{
|
||||
// use mouse wheel only when mouse is over
|
||||
if (!isOverPanel) { return; }
|
||||
@@ -213,8 +326,11 @@
|
||||
if (e.wheelDelta) { delta = -e.wheelDelta/120; }
|
||||
if (e.detail) { delta = e.detail / 3; }
|
||||
|
||||
// scroll content
|
||||
scrollContent(delta, true);
|
||||
var target = e.target || e.srcTarget || e.srcElement;
|
||||
if ($(target).closest('.' + o.wrapperClass).is(me.parent())) {
|
||||
// scroll content
|
||||
scrollContent(delta, true);
|
||||
}
|
||||
|
||||
// stop window scroll
|
||||
if (e.preventDefault && !releaseScroll) { e.preventDefault(); }
|
||||
@@ -223,16 +339,24 @@
|
||||
|
||||
function scrollContent(y, isWheel, isJump)
|
||||
{
|
||||
releaseScroll = false;
|
||||
var delta = y;
|
||||
var maxTop = me.outerHeight() - bar.outerHeight();
|
||||
|
||||
|
||||
if (isWheel)
|
||||
{
|
||||
// move bar with mouse wheel
|
||||
delta = parseInt(bar.css('top')) + y * parseInt(o.wheelStep) / 100 * bar.outerHeight();
|
||||
|
||||
// move bar, make sure it doesn't go out
|
||||
// move bar, make sure it doesn't go out
|
||||
delta = Math.min(Math.max(delta, 0), maxTop);
|
||||
|
||||
// if scrolling down, make sure a fractional change to the
|
||||
// scroll position isn't rounded away when the scrollbar's CSS is set
|
||||
// this flooring of delta would happened automatically when
|
||||
// bar.css is set below, but we floor here for clarity
|
||||
delta = (y > 0) ? Math.ceil(delta) : Math.floor(delta);
|
||||
|
||||
// scroll the scrollbar
|
||||
bar.css({ top: delta + 'px' });
|
||||
}
|
||||
@@ -245,7 +369,6 @@
|
||||
{
|
||||
delta = y;
|
||||
var offsetTop = delta / me[0].scrollHeight * me.outerHeight();
|
||||
|
||||
offsetTop = Math.min(Math.max(offsetTop, 0), maxTop);
|
||||
bar.css({ top: offsetTop + 'px' });
|
||||
}
|
||||
@@ -253,6 +376,9 @@
|
||||
// scroll content
|
||||
me.scrollTop(delta);
|
||||
|
||||
// fire scrolling event
|
||||
me.trigger('slimscrolling', ~~delta);
|
||||
|
||||
// ensure bar is visible
|
||||
showBar();
|
||||
|
||||
@@ -260,31 +386,29 @@
|
||||
hideBar();
|
||||
}
|
||||
|
||||
var attachWheel = function()
|
||||
function attachWheel()
|
||||
{
|
||||
if (window.addEventListener)
|
||||
{
|
||||
this.addEventListener('DOMMouseScroll', _onWheel, false );
|
||||
this.addEventListener('mousewheel', _onWheel, false );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
document.attachEvent("onmousewheel", _onWheel)
|
||||
}
|
||||
}
|
||||
|
||||
// attach scroll events
|
||||
attachWheel();
|
||||
|
||||
function getBarHeight()
|
||||
{
|
||||
// calculate scrollbar height and make sure it is not too small
|
||||
barHeight = Math.max((me.outerHeight() / me[0].scrollHeight) * me.outerHeight(), minBarHeight);
|
||||
bar.css({ height: barHeight + 'px' });
|
||||
}
|
||||
|
||||
// set up initial height
|
||||
getBarHeight();
|
||||
// hide scrollbar if content is not long enough
|
||||
var display = barHeight == me.outerHeight() ? 'none' : 'block';
|
||||
bar.css({ display: display });
|
||||
}
|
||||
|
||||
function showBar()
|
||||
{
|
||||
@@ -293,18 +417,22 @@
|
||||
clearTimeout(queueHide);
|
||||
|
||||
// when bar reached top or bottom
|
||||
if (percentScroll == ~~ percentScroll)
|
||||
if (percentScroll == ~~percentScroll)
|
||||
{
|
||||
//release wheel
|
||||
//release wheel
|
||||
releaseScroll = o.allowPageScroll;
|
||||
|
||||
|
||||
// publish approporiate event
|
||||
if (lastScroll != percentScroll)
|
||||
{
|
||||
var msg = (~~percentScroll == 0) ? 'top' : 'bottom';
|
||||
var msg = (~~percentScroll == 0) ? 'top' : 'bottom';
|
||||
me.trigger('slimscroll', msg);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
releaseScroll = false;
|
||||
}
|
||||
lastScroll = percentScroll;
|
||||
|
||||
// show only when required
|
||||
@@ -324,7 +452,7 @@
|
||||
{
|
||||
queueHide = setTimeout(function(){
|
||||
if (!(o.disableFadeOut && isOverPanel) && !isOverBar && !isDragg)
|
||||
{
|
||||
{
|
||||
bar.fadeOut('slow');
|
||||
rail.fadeOut('slow');
|
||||
}
|
||||
@@ -332,30 +460,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
// check start position
|
||||
if (o.start == 'bottom')
|
||||
{
|
||||
// scroll content to bottom
|
||||
bar.css({ top: me.outerHeight() - bar.outerHeight() });
|
||||
scrollContent(0, true);
|
||||
}
|
||||
else if (typeof o.start == 'object')
|
||||
{
|
||||
// scroll content
|
||||
scrollContent($(o.start).position().top, null, true);
|
||||
|
||||
// make sure bar stays hidden
|
||||
if (!o.alwaysVisible) { bar.hide(); }
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// maintain chainability
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
jQuery.fn.extend({
|
||||
slimscroll: jQuery.fn.slimScroll
|
||||
$.fn.extend({
|
||||
slimscroll: $.fn.slimScroll
|
||||
});
|
||||
|
||||
})(jQuery);
|
||||
@@ -5,7 +5,11 @@
|
||||
} else if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = factory(require('crypto'))
|
||||
} else {
|
||||
root.BigInt = factory(root.crypto || root.msCrypto)
|
||||
try {
|
||||
root.BigInt = factory(root.crypto || root.msCrypto)
|
||||
} catch(e) {
|
||||
console.warn(e.message);
|
||||
}
|
||||
}
|
||||
|
||||
}(this, function (crypto) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*!
|
||||
|
||||
otr.js v0.2.11 - 2014-03-24
|
||||
(c) 2014 - Arlo Breault <arlolra@gmail.com>
|
||||
otr.js v0.2.15 - 2015-05-04
|
||||
(c) 2015 - Arlo Breault <arlolra@gmail.com>
|
||||
Freely distributed under the MPL v2.0 license.
|
||||
|
||||
This file is concatenated for the browser.
|
||||
@@ -29,7 +29,9 @@
|
||||
} else {
|
||||
root.OTR = {}
|
||||
root.DSA = {}
|
||||
factory.call(root)
|
||||
if (typeof root.BigInt !== 'undefined') {
|
||||
factory.call(root)
|
||||
}
|
||||
}
|
||||
|
||||
}(this, function () {
|
||||
@@ -141,6 +143,17 @@
|
||||
child.__super__ = parent.prototype
|
||||
}
|
||||
|
||||
// assumes 32-bit
|
||||
function intCompare(x, y) {
|
||||
var z = ~(x ^ y)
|
||||
z &= z >> 16
|
||||
z &= z >> 8
|
||||
z &= z >> 4
|
||||
z &= z >> 2
|
||||
z &= z >> 1
|
||||
return z & 1
|
||||
}
|
||||
|
||||
// constant-time string comparison
|
||||
HLP.compare = function (str1, str2) {
|
||||
if (str1.length !== str2.length)
|
||||
@@ -148,7 +161,7 @@
|
||||
var i = 0, result = 0
|
||||
for (; i < str1.length; i++)
|
||||
result |= str1[i].charCodeAt(0) ^ str2[i].charCodeAt(0)
|
||||
return result === 0
|
||||
return intCompare(result, 0)
|
||||
}
|
||||
|
||||
HLP.randomExponent = function () {
|
||||
@@ -1160,7 +1173,7 @@
|
||||
HLP.debug.call(this.otr, 'success')
|
||||
|
||||
if (BigInt.equals(this.their_y, this.our_dh.publicKey))
|
||||
return this.otr.error('equal keys - we have a problem.', true)
|
||||
return this.otr.error('equal keys - we have a problem.')
|
||||
|
||||
this.otr.our_old_dh = this.our_dh
|
||||
this.otr.their_priv_pk = this.their_priv_pk
|
||||
@@ -1267,7 +1280,7 @@
|
||||
|
||||
// verify gy is legal 2 <= gy <= N-2
|
||||
if (!HLP.checkGroup(this.their_y, N_MINUS_2))
|
||||
return this.otr.error('Illegal g^y.', true)
|
||||
return this.otr.error('Illegal g^y.')
|
||||
|
||||
this.createKeys(this.their_y)
|
||||
|
||||
@@ -1303,11 +1316,11 @@
|
||||
var hash = CryptoJS.SHA256(CryptoJS.enc.Latin1.parse(gxmpi))
|
||||
|
||||
if (!HLP.compare(this.hashed, hash.toString(CryptoJS.enc.Latin1)))
|
||||
return this.otr.error('Hashed g^x does not match.', true)
|
||||
return this.otr.error('Hashed g^x does not match.')
|
||||
|
||||
// verify gx is legal 2 <= g^x <= N-2
|
||||
if (!HLP.checkGroup(this.their_y, N_MINUS_2))
|
||||
return this.otr.error('Illegal g^x.', true)
|
||||
return this.otr.error('Illegal g^x.')
|
||||
|
||||
this.createKeys(this.their_y)
|
||||
|
||||
@@ -1321,7 +1334,7 @@
|
||||
, this.m1
|
||||
, HLP.packCtr(0)
|
||||
)
|
||||
if (vsm[0]) return this.otr.error(vsm[0], true)
|
||||
if (vsm[0]) return this.otr.error(vsm[0])
|
||||
|
||||
// store their key
|
||||
this.their_keyid = vsm[1]
|
||||
@@ -1363,7 +1376,7 @@
|
||||
, this.m1_prime
|
||||
, HLP.packCtr(0)
|
||||
)
|
||||
if (vsm[0]) return this.otr.error(vsm[0], true)
|
||||
if (vsm[0]) return this.otr.error(vsm[0])
|
||||
|
||||
// store their key
|
||||
this.their_keyid = vsm[1]
|
||||
@@ -1609,10 +1622,12 @@
|
||||
|
||||
this.smpstate = CONST.SMPSTATE_EXPECT0
|
||||
|
||||
// assume utf8 question
|
||||
question = CryptoJS.enc.Latin1
|
||||
.parse(question)
|
||||
.toString(CryptoJS.enc.Utf8)
|
||||
if (question) {
|
||||
// assume utf8 question
|
||||
question = CryptoJS.enc.Latin1
|
||||
.parse(question)
|
||||
.toString(CryptoJS.enc.Utf8)
|
||||
}
|
||||
|
||||
// invoke question
|
||||
this.trigger('question', [question])
|
||||
@@ -1920,6 +1935,11 @@
|
||||
var MAX_INT = Math.pow(2, 53) - 1 // doubles
|
||||
var MAX_UINT = Math.pow(2, 31) - 1 // bitwise operators
|
||||
|
||||
// an internal callback
|
||||
function OTRCB(cb) {
|
||||
this.cb = cb
|
||||
}
|
||||
|
||||
// OTR contructor
|
||||
function OTR(options) {
|
||||
if (!(this instanceof OTR)) return new OTR(options)
|
||||
@@ -2090,17 +2110,22 @@
|
||||
})
|
||||
})
|
||||
this.sm.on('send', function (ssid, send) {
|
||||
if (self.ssid === ssid)
|
||||
if (self.ssid === ssid) {
|
||||
send = self.prepareMsg(send)
|
||||
self.io(send)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
OTR.prototype.io = function (msg, meta) {
|
||||
|
||||
// buffer
|
||||
msg = ([].concat(msg)).map(function(m){
|
||||
return { msg: m, meta: meta }
|
||||
msg = ([].concat(msg)).map(function(m, i, arr) {
|
||||
var obj = { msg: m }
|
||||
if (!(meta instanceof OTRCB) ||
|
||||
i === (arr.length - 1) // only cb after last fragment is sent
|
||||
) obj.meta = meta
|
||||
return obj
|
||||
})
|
||||
this.outgoing = this.outgoing.concat(msg)
|
||||
|
||||
@@ -2108,8 +2133,13 @@
|
||||
;(function send(first) {
|
||||
if (!first) {
|
||||
if (!self.outgoing.length) return
|
||||
var elem = self.outgoing.shift()
|
||||
var elem = self.outgoing.shift(), cb = null
|
||||
if (elem.meta instanceof OTRCB) {
|
||||
cb = elem.meta.cb
|
||||
elem.meta = null
|
||||
}
|
||||
self.trigger('io', [elem.msg, elem.meta])
|
||||
if (cb) cb()
|
||||
}
|
||||
setTimeout(send, first ? 0 : self.send_interval)
|
||||
}(true))
|
||||
@@ -2142,7 +2172,7 @@
|
||||
this.sendenc = HLP.mask(HLP.h1(sendbyte, secbytes), 0, 128) // f16 bytes
|
||||
this.sendmac = CryptoJS.SHA1(CryptoJS.enc.Latin1.parse(this.sendenc))
|
||||
this.sendmac = this.sendmac.toString(CryptoJS.enc.Latin1)
|
||||
this.sendmacused = false
|
||||
|
||||
this.rcvenc = HLP.mask(HLP.h1(rcvbyte, secbytes), 0, 128)
|
||||
this.rcvmac = CryptoJS.SHA1(CryptoJS.enc.Latin1.parse(this.rcvenc))
|
||||
this.rcvmac = this.rcvmac.toString(CryptoJS.enc.Latin1)
|
||||
@@ -2161,7 +2191,6 @@
|
||||
// reveal old mac keys
|
||||
var self = this
|
||||
this.sessKeys[1].forEach(function (sk) {
|
||||
if (sk && sk.sendmacused) self.oldMacKeys.push(sk.sendmac)
|
||||
if (sk && sk.rcvmacused) self.oldMacKeys.push(sk.rcvmac)
|
||||
})
|
||||
|
||||
@@ -2189,7 +2218,6 @@
|
||||
// reveal old mac keys
|
||||
var self = this
|
||||
this.sessKeys.forEach(function (sk) {
|
||||
if (sk[1] && sk[1].sendmacused) self.oldMacKeys.push(sk[1].sendmac)
|
||||
if (sk[1] && sk[1].rcvmacused) self.oldMacKeys.push(sk[1].rcvmac)
|
||||
})
|
||||
|
||||
@@ -2207,12 +2235,12 @@
|
||||
|
||||
OTR.prototype.prepareMsg = function (msg, esk) {
|
||||
if (this.msgstate !== CONST.MSGSTATE_ENCRYPTED || this.their_keyid === 0)
|
||||
return this.error('Not ready to encrypt.')
|
||||
return this.notify('Not ready to encrypt.')
|
||||
|
||||
var sessKeys = this.sessKeys[1][0]
|
||||
|
||||
if (sessKeys.send_counter >= MAX_INT)
|
||||
return this.error('Should have rekeyed by now.')
|
||||
return this.notify('Should have rekeyed by now.')
|
||||
|
||||
sessKeys.send_counter += 1
|
||||
|
||||
@@ -2233,7 +2261,7 @@
|
||||
send += ctr.substring(0, 8)
|
||||
|
||||
if (Math.ceil(msg.length / 8) >= MAX_UINT) // * 16 / 128
|
||||
return this.error('Message is too long.')
|
||||
return this.notify('Message is too long.')
|
||||
|
||||
var aes = HLP.encryptAes(
|
||||
CryptoJS.enc.Latin1.parse(msg)
|
||||
@@ -2245,8 +2273,6 @@
|
||||
send += HLP.make1Mac(send, sessKeys.sendmac)
|
||||
send += HLP.packData(this.oldMacKeys.splice(0).join(''))
|
||||
|
||||
sessKeys.sendmacused = true
|
||||
|
||||
send = HLP.wrapMsg(
|
||||
send
|
||||
, this.fragment_size
|
||||
@@ -2254,7 +2280,7 @@
|
||||
, this.our_instance_tag
|
||||
, this.their_instance_tag
|
||||
)
|
||||
if (send[0]) return this.error(send[0])
|
||||
if (send[0]) return this.notify(send[0])
|
||||
|
||||
// emit extra symmetric key
|
||||
if (esk) this.trigger('file', ['send', sessKeys.extra_symkey, esk])
|
||||
@@ -2275,7 +2301,7 @@
|
||||
var ign = (msg[0] === '\x01')
|
||||
|
||||
if (this.msgstate !== CONST.MSGSTATE_ENCRYPTED || msg.length !== 8) {
|
||||
if (!ign) this.error('Received an unreadable encrypted message.', true)
|
||||
if (!ign) this.error('Received an unreadable encrypted message.')
|
||||
return
|
||||
}
|
||||
|
||||
@@ -2283,12 +2309,12 @@
|
||||
var their_keyid = this.their_keyid - HLP.readLen(msg[1])
|
||||
|
||||
if (our_keyid < 0 || our_keyid > 1) {
|
||||
if (!ign) this.error('Not of our latest keys.', true)
|
||||
if (!ign) this.error('Not of our latest keys.')
|
||||
return
|
||||
}
|
||||
|
||||
if (their_keyid < 0 || their_keyid > 1) {
|
||||
if (!ign) this.error('Not of your latest keys.', true)
|
||||
if (!ign) this.error('Not of your latest keys.')
|
||||
return
|
||||
}
|
||||
|
||||
@@ -2383,16 +2409,17 @@
|
||||
|
||||
OTR.prototype.smpSecret = function (secret, question) {
|
||||
if (this.msgstate !== CONST.MSGSTATE_ENCRYPTED)
|
||||
return this.error('Must be encrypted for SMP.')
|
||||
return this.notify('Must be encrypted for SMP.')
|
||||
|
||||
if (typeof secret !== 'string' || secret.length < 1)
|
||||
return this.error('Secret is required.')
|
||||
return this.notify('Secret is required.')
|
||||
|
||||
if (!this.sm) this._smInit()
|
||||
|
||||
// utf8 inputs
|
||||
secret = CryptoJS.enc.Utf8.parse(secret).toString(CryptoJS.enc.Latin1)
|
||||
question = CryptoJS.enc.Utf8.parse(question).toString(CryptoJS.enc.Latin1)
|
||||
if (question)
|
||||
question = CryptoJS.enc.Utf8.parse(question).toString(CryptoJS.enc.Latin1)
|
||||
|
||||
this.sm.rcvSecret(secret, question)
|
||||
}
|
||||
@@ -2443,7 +2470,7 @@
|
||||
break
|
||||
case CONST.MSGSTATE_FINISHED:
|
||||
this.storedMgs.push({msg: msg, meta: meta})
|
||||
this.error('Message cannot be sent at this time.')
|
||||
this.notify('Message cannot be sent at this time.', 'warn')
|
||||
return
|
||||
case CONST.MSGSTATE_ENCRYPTED:
|
||||
msg = this.prepareMsg(msg)
|
||||
@@ -2455,7 +2482,7 @@
|
||||
if (msg) this.io(msg, meta)
|
||||
}
|
||||
|
||||
OTR.prototype.receiveMsg = function (msg) {
|
||||
OTR.prototype.receiveMsg = function (msg, meta) {
|
||||
|
||||
// parse type
|
||||
msg = Parse.parseMsg(this, msg)
|
||||
@@ -2464,18 +2491,26 @@
|
||||
|
||||
switch (msg.cls) {
|
||||
case 'error':
|
||||
this.error(msg.msg)
|
||||
this.notify(msg.msg)
|
||||
return
|
||||
case 'ake':
|
||||
if ( msg.version === CONST.OTR_VERSION_3 &&
|
||||
this.checkInstanceTags(msg.instance_tags)
|
||||
) return // ignore
|
||||
) {
|
||||
this.notify(
|
||||
'Received a message intended for a different session.', 'warn')
|
||||
return // ignore
|
||||
}
|
||||
this.ake.handleAKE(msg)
|
||||
return
|
||||
case 'data':
|
||||
if ( msg.version === CONST.OTR_VERSION_3 &&
|
||||
this.checkInstanceTags(msg.instance_tags)
|
||||
) return // ignore
|
||||
) {
|
||||
this.notify(
|
||||
'Received a message intended for a different session.', 'warn')
|
||||
return // ignore
|
||||
}
|
||||
msg.msg = this.handleDataMsg(msg)
|
||||
msg.encrypted = true
|
||||
break
|
||||
@@ -2487,7 +2522,7 @@
|
||||
// check for encrypted
|
||||
if ( this.REQUIRE_ENCRYPTION ||
|
||||
this.msgstate !== CONST.MSGSTATE_PLAINTEXT
|
||||
) this.error('Received an unencrypted message.')
|
||||
) this.notify('Received an unencrypted message.', 'warn')
|
||||
|
||||
// received a plaintext message
|
||||
// stop sending the whitespace tag
|
||||
@@ -2498,7 +2533,7 @@
|
||||
this.doAKE(msg)
|
||||
}
|
||||
|
||||
if (msg.msg) this.trigger('ui', [msg.msg, !!msg.encrypted])
|
||||
if (msg.msg) this.trigger('ui', [msg.msg, !!msg.encrypted, meta])
|
||||
}
|
||||
|
||||
OTR.prototype.checkInstanceTags = function (it) {
|
||||
@@ -2522,20 +2557,19 @@
|
||||
} else if (this.ALLOW_V2 && ~msg.ver.indexOf(CONST.OTR_VERSION_2)) {
|
||||
this.ake.initiateAKE(CONST.OTR_VERSION_2)
|
||||
} else {
|
||||
// is this an error?
|
||||
this.error('OTR conversation requested, ' +
|
||||
'but no compatible protocol version found.')
|
||||
this.notify('OTR conversation requested, ' +
|
||||
'but no compatible protocol version found.', 'warn')
|
||||
}
|
||||
}
|
||||
|
||||
OTR.prototype.error = function (err, send) {
|
||||
if (send) {
|
||||
if (!this.debug) err = "An OTR error has occurred."
|
||||
err = '?OTR Error:' + err
|
||||
this.io(err)
|
||||
return
|
||||
}
|
||||
this.trigger('error', [err])
|
||||
OTR.prototype.error = function (err) {
|
||||
if (!this.debug) err = 'An OTR error has occurred.'
|
||||
this.io('?OTR Error:' + err)
|
||||
this.notify(err)
|
||||
}
|
||||
|
||||
OTR.prototype.notify = function (err, severity) {
|
||||
this.trigger('error', [err, severity || 'error'])
|
||||
}
|
||||
|
||||
OTR.prototype.sendStored = function () {
|
||||
@@ -2548,18 +2582,18 @@
|
||||
|
||||
OTR.prototype.sendFile = function (filename) {
|
||||
if (this.msgstate !== CONST.MSGSTATE_ENCRYPTED)
|
||||
return this.error('Not ready to encrypt.')
|
||||
return this.notify('Not ready to encrypt.')
|
||||
|
||||
if (this.ake.otr_version !== CONST.OTR_VERSION_3)
|
||||
return this.error('Protocol v3 required.')
|
||||
return this.notify('Protocol v3 required.')
|
||||
|
||||
if (!filename) return this.error('Please specify a filename.')
|
||||
if (!filename) return this.notify('Please specify a filename.')
|
||||
|
||||
// utf8 filenames
|
||||
var l1name = CryptoJS.enc.Utf8.parse(filename)
|
||||
l1name = l1name.toString(CryptoJS.enc.Latin1)
|
||||
|
||||
if (l1name.length >= 65532) return this.error('filename is too long.')
|
||||
if (l1name.length >= 65532) return this.notify('Filename is too long.')
|
||||
|
||||
var msg = '\x00' // null byte
|
||||
msg += '\x00\x08' // type 8 tlv
|
||||
@@ -2571,14 +2605,18 @@
|
||||
this.io(msg)
|
||||
}
|
||||
|
||||
OTR.prototype.endOtr = function () {
|
||||
OTR.prototype.endOtr = function (cb) {
|
||||
if (this.msgstate === CONST.MSGSTATE_ENCRYPTED) {
|
||||
this.sendMsg('\x00\x00\x01\x00\x00')
|
||||
if (typeof cb === 'function')
|
||||
cb = new OTRCB(cb)
|
||||
this.sendMsg('\x00\x00\x01\x00\x00', cb)
|
||||
if (this.sm) {
|
||||
if (this.smw) this.sm.worker.terminate() // destroy webworker
|
||||
this.sm = null
|
||||
}
|
||||
}
|
||||
} else if (typeof cb === 'function')
|
||||
setTimeout(cb, 0)
|
||||
|
||||
this.msgstate = CONST.MSGSTATE_PLAINTEXT
|
||||
this.receivedPlaintext = false
|
||||
this.trigger('status', [CONST.STATUS_END_OTR])
|
||||
|
||||
@@ -3,11 +3,16 @@
|
||||
|
||||
root.OTR = {}
|
||||
root.DSA = {}
|
||||
root.crypto = {
|
||||
randomBytes: function () {
|
||||
throw new Error("Haven't seeded yet.")
|
||||
|
||||
var hasCrypto = false
|
||||
if (root.crypto)
|
||||
hasCrypto = true
|
||||
else
|
||||
root.crypto = {
|
||||
randomBytes: function () {
|
||||
throw new Error("Haven't seeded yet.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// default imports
|
||||
var imports = [
|
||||
@@ -30,10 +35,12 @@
|
||||
if (data.imports) imports = data.imports
|
||||
importScripts.apply(root, imports);
|
||||
|
||||
// use salsa20 since there's no prng in webworkers
|
||||
var state = new root.Salsa20(data.seed.slice(0, 32), data.seed.slice(32))
|
||||
root.crypto.randomBytes = function (n) {
|
||||
return state.getBytes(n)
|
||||
if (!hasCrypto) {
|
||||
// use salsa20 when there's no prng in webworkers
|
||||
var state = new root.Salsa20(data.seed.slice(0, 32), data.seed.slice(32))
|
||||
root.crypto.randomBytes = function (n) {
|
||||
return state.getBytes(n)
|
||||
}
|
||||
}
|
||||
|
||||
if (data.debug) sendMsg('debug', 'DSA key creation started')
|
||||
|
||||
@@ -50,6 +50,17 @@
|
||||
child.__super__ = parent.prototype
|
||||
}
|
||||
|
||||
// assumes 32-bit
|
||||
function intCompare(x, y) {
|
||||
var z = ~(x ^ y)
|
||||
z &= z >> 16
|
||||
z &= z >> 8
|
||||
z &= z >> 4
|
||||
z &= z >> 2
|
||||
z &= z >> 1
|
||||
return z & 1
|
||||
}
|
||||
|
||||
// constant-time string comparison
|
||||
HLP.compare = function (str1, str2) {
|
||||
if (str1.length !== str2.length)
|
||||
@@ -57,7 +68,7 @@
|
||||
var i = 0, result = 0
|
||||
for (; i < str1.length; i++)
|
||||
result |= str1[i].charCodeAt(0) ^ str2[i].charCodeAt(0)
|
||||
return result === 0
|
||||
return intCompare(result, 0)
|
||||
}
|
||||
|
||||
HLP.randomExponent = function () {
|
||||
|
||||
@@ -2,11 +2,16 @@
|
||||
"use strict";
|
||||
|
||||
root.OTR = {}
|
||||
root.crypto = {
|
||||
randomBytes: function () {
|
||||
throw new Error("Haven't seeded yet.")
|
||||
|
||||
var hasCrypto = false
|
||||
if (root.crypto)
|
||||
hasCrypto = true
|
||||
else
|
||||
root.crypto = {
|
||||
randomBytes: function () {
|
||||
throw new Error("Haven't seeded yet.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// default imports
|
||||
var imports = [
|
||||
@@ -36,7 +41,10 @@
|
||||
if (data.imports) imports = data.imports
|
||||
importScripts.apply(root, imports)
|
||||
|
||||
// use salsa20 since there's no prng in webworkers
|
||||
if (hasCrypto)
|
||||
break
|
||||
|
||||
// use salsa20 when there's no prng in webworkers
|
||||
var state = new root.Salsa20(
|
||||
data.seed.slice(0, 32),
|
||||
data.seed.slice(32)
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
Strophe.addConnectionPlugin('bookmarks', {
|
||||
init : function(connection) {
|
||||
this.connection = connection;
|
||||
Strophe.addNamespace('PRIVATE', 'jabber:iq:private');
|
||||
Strophe.addNamespace('BOOKMARKS', 'storage:bookmarks');
|
||||
Strophe.addNamespace('PRIVACY', 'jabber:iq:privacy');
|
||||
Strophe.addNamespace('DELAY', 'jabber:x:delay');
|
||||
Strophe.addNamespace('PUBSUB', 'http://jabber.org/protocol/pubsub');
|
||||
|
||||
},
|
||||
/**
|
||||
* Create private bookmark node.
|
||||
*
|
||||
* @param {function} [success] - Callback after success
|
||||
* @param {function} [error] - Callback after error
|
||||
*/
|
||||
createBookmarksNode : function(success, error) {
|
||||
// We do this instead of using publish-options because this is not
|
||||
// mandatory to implement according to XEP-0060
|
||||
this.connection.sendIQ($iq({
|
||||
type : 'set'
|
||||
}).c('pubsub', {
|
||||
xmlns : Strophe.NS.PUBSUB
|
||||
}).c('create', {
|
||||
node : 'storage:bookmarks'
|
||||
}).up().c('configure').c('x', {
|
||||
xmlns : 'jabber:x:data',
|
||||
type : 'submit'
|
||||
}).c('field', {
|
||||
'var' : 'FORM_TYPE',
|
||||
type : 'hidden'
|
||||
}).c('value').t('http://jabber.org/protocol/pubsub#node_config').up()
|
||||
.up().c('field', {
|
||||
'var' : 'pubsub#persist_items'
|
||||
}).c('value').t('1').up().up().c('field', {
|
||||
'var' : 'pubsub#access_model'
|
||||
}).c('value').t('whitelist'), success, error);
|
||||
|
||||
return true;
|
||||
},
|
||||
/**
|
||||
* Add bookmark to storage.
|
||||
*
|
||||
* @param {string} roomJid - The JabberID of the chat roomJid
|
||||
* @param {string} [alias] - A friendly name for the bookmark
|
||||
* @param {string} [nick] - The users's preferred roomnick for the chatroom
|
||||
* @param {boolean} [autojoin=false] - Whether the client should automatically join
|
||||
* the conference room on login.
|
||||
* @param {function} [success] - Callback after success
|
||||
* @param {function} [error] - Callback after error
|
||||
*/
|
||||
add : function(roomJid, alias, nick, autojoin, success, error) {
|
||||
var conferenceAttr = {
|
||||
jid: roomJid,
|
||||
autojoin: autojoin || false
|
||||
};
|
||||
|
||||
if (alias) {
|
||||
conferenceAttr.name = alias;
|
||||
}
|
||||
|
||||
var stanza = $iq({
|
||||
type : 'set'
|
||||
}).c('pubsub', {
|
||||
xmlns : Strophe.NS.PUBSUB
|
||||
}).c('publish', {
|
||||
node : Strophe.NS.BOOKMARKS
|
||||
}).c('item', {
|
||||
id : roomJid
|
||||
}).c('storage', {
|
||||
xmlns : Strophe.NS.BOOKMARKS
|
||||
}).c('conference', conferenceAttr);
|
||||
|
||||
if (nick) {
|
||||
stanza.c('nick').t(nick);
|
||||
}
|
||||
|
||||
this.connection.sendIQ(stanza, success, error);
|
||||
},
|
||||
/**
|
||||
* Retrieve all stored bookmarks.
|
||||
*
|
||||
* @param {function} [success] - Callback after success
|
||||
* @param {function} [error] - Callback after error
|
||||
*/
|
||||
get: function(success, error) {
|
||||
this.connection.sendIQ($iq({
|
||||
type : 'get'
|
||||
}).c('pubsub', {
|
||||
xmlns : Strophe.NS.PUBSUB
|
||||
}).c('items', {
|
||||
node : Strophe.NS.BOOKMARKS
|
||||
}), success, error);
|
||||
},
|
||||
/**
|
||||
* Delete the given entry for roomJid.
|
||||
*
|
||||
* @param {string} roomJid - The JabberID of the chat roomJid you want to remove
|
||||
* @param {function} [success] - Callback after success
|
||||
* @param {function} [error] - Callback after error
|
||||
* @param {boolean} [notify=false] - True: notify all subscribers
|
||||
*/
|
||||
delete: function(roomJid, success, error, notify) {
|
||||
this.connection.sendIQ($iq({
|
||||
type : 'set'
|
||||
}).c('pubsub', {
|
||||
xmlns : Strophe.NS.PUBSUB
|
||||
}).c('retract', {
|
||||
node : Strophe.NS.BOOKMARKS,
|
||||
notify: notify || false
|
||||
}).c('item', {
|
||||
id: roomJid
|
||||
}), success, error);
|
||||
}
|
||||
|
||||
});
|
||||
@@ -7,6 +7,8 @@
|
||||
*
|
||||
* Authors: - Michael Weibel <michael.weibel@gmail.com> - Klaus Herberth <klaus@jsxc.org>
|
||||
* Copyright: - Michael Weibel <michael.weibel@gmail.com>
|
||||
*
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
(function($) {
|
||||
@@ -122,12 +124,17 @@
|
||||
if (this._jidVerIndex[jid] && feature !== null && typeof feature !== 'undefined') {
|
||||
if(!$.isArray(feature)){
|
||||
feature = $.makeArray(feature);
|
||||
};
|
||||
}
|
||||
|
||||
var i;
|
||||
var i, knownCapabilities;
|
||||
knownCapabilities = this._knownCapabilities[this._jidVerIndex[jid]];
|
||||
if (!knownCapabilities) {
|
||||
return null;
|
||||
}
|
||||
for (i = 0; i < feature.length; i++) {
|
||||
if (this._knownCapabilities[this._jidVerIndex[jid]]['features'].indexOf(feature[i]) < 0)
|
||||
if (knownCapabilities['features'].indexOf(feature[i]) < 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -154,7 +161,7 @@
|
||||
}
|
||||
|
||||
localStorage.setItem('strophe.caps._jidVerIndex', JSON.stringify(this._jidVerIndex));
|
||||
$(document).trigger('caps.strophe', [ from ]);
|
||||
$(document).trigger('caps.strophe', [ from, this._knownCapabilities[ver], ver]);
|
||||
|
||||
return true;
|
||||
},
|
||||
@@ -189,13 +196,18 @@
|
||||
* Returns: (Boolean) - false, to automatically remove the handler.
|
||||
*/
|
||||
_handleDiscoInfoReply: function(stanza) {
|
||||
var query = stanza.querySelector('query'), node = query.getAttribute('node').split('#'), ver = node[1], from = stanza.getAttribute('from');
|
||||
var query = stanza.querySelector('query');
|
||||
var from = stanza.getAttribute('from');
|
||||
var node = query.getAttribute('node');
|
||||
var ver = (node)? node.split('#')[1] : this._jidVerIndex[from]; //fix open prosody issue
|
||||
|
||||
if (!this._knownCapabilities[ver]) {
|
||||
var childNodes = query.childNodes, childNodesLen = childNodes.length;
|
||||
this._knownCapabilities[ver] = {
|
||||
features: [],
|
||||
identities: []
|
||||
};
|
||||
|
||||
for (var i = 0; i < childNodesLen; i++) {
|
||||
var node = childNodes[i];
|
||||
if (node.nodeName == 'feature') {
|
||||
@@ -203,10 +215,11 @@
|
||||
} else if (node.nodeName == 'identity') {
|
||||
this._knownCapabilities[ver]['identities'].push(this._attributesToJsObject(node.attributes));
|
||||
} else {
|
||||
if (_knownCapabilities[ver][node.nodeName])
|
||||
_knownCapabilities[ver][node.nodeName] = [];
|
||||
if (typeof this._knownCapabilities[ver][node.nodeName] === 'undefined')
|
||||
this._knownCapabilities[ver][node.nodeName] = [];
|
||||
this._knownCapabilities[ver][node.nodeName].push(this._attributesToJsObject(node.attributes));
|
||||
}
|
||||
|
||||
}
|
||||
this._jidVerIndex[from] = ver;
|
||||
} else if (!this._jidVerIndex[from] || !this._jidVerIndex[from] !== ver) {
|
||||
@@ -215,7 +228,7 @@
|
||||
|
||||
localStorage.setItem('strophe.caps._jidVerIndex', JSON.stringify(this._jidVerIndex));
|
||||
localStorage.setItem('strophe.caps._knownCapabilities', JSON.stringify(this._knownCapabilities));
|
||||
$(document).trigger('caps.strophe', [ from ]);
|
||||
$(document).trigger('caps.strophe', [ from, this._knownCapabilities[ver], ver ]);
|
||||
|
||||
return false;
|
||||
},
|
||||
@@ -259,4 +272,4 @@
|
||||
return 0;
|
||||
}
|
||||
});
|
||||
}(jQuery));
|
||||
}(jQuery));
|
||||
|
||||
@@ -1,330 +0,0 @@
|
||||
/* jshint -W117 */
|
||||
var setupRTC, getUserMediaWithConstraints, TraceablePeerConnection;
|
||||
|
||||
(function($){
|
||||
TraceablePeerConnection = function(ice_config, constraints) {
|
||||
var self = this;
|
||||
var RTCPeerconnection = navigator.mozGetUserMedia ? mozRTCPeerConnection : webkitRTCPeerConnection;
|
||||
this.peerconnection = new RTCPeerconnection(ice_config, constraints);
|
||||
this.updateLog = [];
|
||||
|
||||
// override as desired
|
||||
this.trace = function(what, info) {
|
||||
//console.warn('WTRACE', what, info);
|
||||
self.updateLog.push({
|
||||
time: new Date(),
|
||||
type: what,
|
||||
value: info
|
||||
});
|
||||
};
|
||||
this.onicecandidate = null;
|
||||
this.peerconnection.onicecandidate = function (event) {
|
||||
self.trace('onicecandidate', event.candidate);
|
||||
if (self.onicecandidate !== null) {
|
||||
self.onicecandidate(event);
|
||||
}
|
||||
};
|
||||
this.onaddstream = null;
|
||||
this.peerconnection.onaddstream = function (event) {
|
||||
self.trace('onaddstream', event.stream);
|
||||
if (self.onaddstream !== null) {
|
||||
self.onaddstream(event);
|
||||
}
|
||||
};
|
||||
this.onremovestream = null;
|
||||
this.peerconnection.onremovestream = function (event) {
|
||||
self.trace('onremovestream', event.stream);
|
||||
if (self.onremovestream !== null) {
|
||||
self.onremovestream(event);
|
||||
}
|
||||
};
|
||||
this.onsignalingstatechange = null;
|
||||
this.peerconnection.onsignalingstatechange = function (event) {
|
||||
self.trace('onsignalingstatechange', event);
|
||||
if (self.onsignalingstatechange !== null) {
|
||||
self.onsignalingstatechange(event);
|
||||
}
|
||||
};
|
||||
this.oniceconnectionstatechange = null;
|
||||
this.peerconnection.oniceconnectionstatechange = function (event) {
|
||||
self.trace('oniceconnectionstatechange', event);
|
||||
if (self.oniceconnectionstatechange !== null) {
|
||||
self.oniceconnectionstatechange(event);
|
||||
}
|
||||
};
|
||||
this.onnegotiationneeded = null;
|
||||
this.peerconnection.onnegotiationneeded = function (event) {
|
||||
self.trace('onnegotiationneeded', event);
|
||||
if (self.onnegotiationneeded !== null) {
|
||||
self.onnegotiationneeded(event);
|
||||
}
|
||||
};
|
||||
self.ondatachannel = null;
|
||||
this.peerconnection.ondatachannel = function (event) {
|
||||
self.trace('ondatachannel', event);
|
||||
if (self.ondatachannel !== null) {
|
||||
self.ondatachannel(event);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
TraceablePeerConnection.prototype.__defineGetter__('signalingState', function() { return this.peerconnection.signalingState; });
|
||||
TraceablePeerConnection.prototype.__defineGetter__('iceConnectionState', function() { return this.peerconnection.iceConnectionState; });
|
||||
TraceablePeerConnection.prototype.__defineGetter__('localDescription', function() { return this.peerconnection.localDescription; });
|
||||
TraceablePeerConnection.prototype.__defineGetter__('remoteDescription', function() { return this.peerconnection.remoteDescription; });
|
||||
|
||||
TraceablePeerConnection.prototype.addStream = function (stream) {
|
||||
this.trace('addStream', stream);
|
||||
this.peerconnection.addStream(stream);
|
||||
};
|
||||
|
||||
TraceablePeerConnection.prototype.removeStream = function (stream) {
|
||||
this.trace('removeStream', stream);
|
||||
this.peerconnection.removeStream(stream);
|
||||
};
|
||||
|
||||
TraceablePeerConnection.prototype.createDataChannel = function (label, opts) {
|
||||
this.trace('createDataChannel', label, opts);
|
||||
this.peerconnection.createDataChannel(label, opts);
|
||||
}
|
||||
|
||||
TraceablePeerConnection.prototype.setLocalDescription = function (description, successCallback, failureCallback) {
|
||||
var self = this;
|
||||
this.trace('setLocalDescription', description);
|
||||
this.peerconnection.setLocalDescription(description,
|
||||
function () {
|
||||
self.trace('setLocalDescriptionOnSuccess');
|
||||
successCallback();
|
||||
},
|
||||
function (err) {
|
||||
self.trace('setLocalDescriptionOnFailure', err);
|
||||
failureCallback(err);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
TraceablePeerConnection.prototype.setRemoteDescription = function (description, successCallback, failureCallback) {
|
||||
var self = this;
|
||||
this.trace('setRemoteDescription', description);
|
||||
this.peerconnection.setRemoteDescription(description,
|
||||
function () {
|
||||
self.trace('setRemoteDescriptionOnSuccess');
|
||||
successCallback();
|
||||
},
|
||||
function (err) {
|
||||
self.trace('setRemoteDescriptionOnFailure', err);
|
||||
failureCallback(err);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
TraceablePeerConnection.prototype.close = function () {
|
||||
this.trace('stop');
|
||||
this.peerconnection.close();
|
||||
};
|
||||
|
||||
TraceablePeerConnection.prototype.createOffer = function (successCallback, failureCallback, constraints) {
|
||||
var self = this;
|
||||
this.trace('createOffer', constraints);
|
||||
this.peerconnection.createOffer(
|
||||
function (sdp) {
|
||||
self.trace('createOfferOnSuccess', sdp);
|
||||
successCallback(sdp);
|
||||
},
|
||||
function(err) {
|
||||
self.trace('createOfferOnFailure', err);
|
||||
failureCallback(err);
|
||||
},
|
||||
constraints
|
||||
);
|
||||
};
|
||||
|
||||
TraceablePeerConnection.prototype.createAnswer = function (successCallback, failureCallback, constraints) {
|
||||
var self = this;
|
||||
this.trace('createAnswer', constraints);
|
||||
this.peerconnection.createAnswer(
|
||||
function (sdp) {
|
||||
self.trace('createAnswerOnSuccess', sdp);
|
||||
successCallback(sdp);
|
||||
},
|
||||
function(err) {
|
||||
self.trace('createAnswerOnFailure', err);
|
||||
failureCallback(err);
|
||||
},
|
||||
constraints
|
||||
);
|
||||
};
|
||||
|
||||
TraceablePeerConnection.prototype.addIceCandidate = function (candidate, successCallback, failureCallback) {
|
||||
var self = this;
|
||||
this.trace('addIceCandidate', candidate);
|
||||
this.peerconnection.addIceCandidate(candidate);
|
||||
/* maybe later
|
||||
this.peerconnection.addIceCandidate(candidate,
|
||||
function () {
|
||||
self.trace('addIceCandidateOnSuccess');
|
||||
successCallback();
|
||||
},
|
||||
function (err) {
|
||||
self.trace('addIceCandidateOnFailure', err);
|
||||
failureCallback(err);
|
||||
}
|
||||
);
|
||||
*/
|
||||
};
|
||||
|
||||
TraceablePeerConnection.prototype.getStats = function(callback) {
|
||||
this.peerconnection.getStats(callback);
|
||||
};
|
||||
|
||||
|
||||
// mozilla chrome compat layer -- very similar to adapter.js
|
||||
setupRTC = function (){
|
||||
var RTC = null;
|
||||
if (navigator.mozGetUserMedia) {
|
||||
console.log('This appears to be Firefox');
|
||||
var version = parseInt(navigator.userAgent.match(/Firefox\/([0-9]+)\./)[1], 10);
|
||||
if (version >= 22) {
|
||||
RTC = {
|
||||
peerconnection: mozRTCPeerConnection,
|
||||
browser: 'firefox',
|
||||
getUserMedia: navigator.mozGetUserMedia.bind(navigator),
|
||||
attachMediaStream: function (element, stream) {
|
||||
element[0].mozSrcObject = stream;
|
||||
element[0].play();
|
||||
},
|
||||
pc_constraints: {}
|
||||
};
|
||||
if (!MediaStream.prototype.getVideoTracks)
|
||||
MediaStream.prototype.getVideoTracks = function () { return []; };
|
||||
if (!MediaStream.prototype.getAudioTracks)
|
||||
MediaStream.prototype.getAudioTracks = function () { return []; };
|
||||
RTCSessionDescription = mozRTCSessionDescription;
|
||||
RTCIceCandidate = mozRTCIceCandidate;
|
||||
}
|
||||
} else if (navigator.webkitGetUserMedia) {
|
||||
console.log('This appears to be Chrome');
|
||||
RTC = {
|
||||
peerconnection: webkitRTCPeerConnection,
|
||||
browser: 'chrome',
|
||||
getUserMedia: navigator.webkitGetUserMedia.bind(navigator),
|
||||
attachMediaStream: function (element, stream) {
|
||||
element.attr('src', webkitURL.createObjectURL(stream));
|
||||
},
|
||||
// DTLS should now be enabled by default but..
|
||||
pc_constraints: {'optional': [{'DtlsSrtpKeyAgreement': 'true'}]}
|
||||
};
|
||||
if (navigator.userAgent.indexOf('Android') != -1) {
|
||||
RTC.pc_constraints = {}; // disable DTLS on Android
|
||||
}
|
||||
if (!webkitMediaStream.prototype.getVideoTracks) {
|
||||
webkitMediaStream.prototype.getVideoTracks = function () {
|
||||
return this.videoTracks;
|
||||
};
|
||||
}
|
||||
if (!webkitMediaStream.prototype.getAudioTracks) {
|
||||
webkitMediaStream.prototype.getAudioTracks = function () {
|
||||
return this.audioTracks;
|
||||
};
|
||||
}
|
||||
}
|
||||
if (RTC === null) {
|
||||
try { console.log('Browser does not appear to be WebRTC-capable'); } catch (e) { }
|
||||
}
|
||||
return RTC;
|
||||
};
|
||||
|
||||
getUserMediaWithConstraints = function(um, resolution, bandwidth, fps) {
|
||||
var constraints = {audio: false, video: false};
|
||||
|
||||
if (um.indexOf('video') >= 0) {
|
||||
constraints.video = {mandatory: {}};// same behaviour as true
|
||||
}
|
||||
if (um.indexOf('audio') >= 0) {
|
||||
constraints.audio = {};// same behaviour as true
|
||||
}
|
||||
if (um.indexOf('screen') >= 0) {
|
||||
constraints.video = {
|
||||
"mandatory": {
|
||||
"chromeMediaSource": "screen"
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (resolution && !constraints.video) {
|
||||
constraints.video = {mandatory: {}};// same behaviour as true
|
||||
}
|
||||
// see https://code.google.com/p/chromium/issues/detail?id=143631#c9 for list of supported resolutions
|
||||
switch (resolution) {
|
||||
// 16:9 first
|
||||
case '1080':
|
||||
case 'fullhd':
|
||||
constraints.video.mandatory.minWidth = 1920;
|
||||
constraints.video.mandatory.minHeight = 1080;
|
||||
constraints.video.mandatory.minAspectRatio = 1.77;
|
||||
break;
|
||||
case '720':
|
||||
case 'hd':
|
||||
constraints.video.mandatory.minWidth = 1280;
|
||||
constraints.video.mandatory.minHeight = 720;
|
||||
constraints.video.mandatory.minAspectRatio = 1.77;
|
||||
break;
|
||||
case '360':
|
||||
constraints.video.mandatory.minWidth = 640;
|
||||
constraints.video.mandatory.minHeight = 360;
|
||||
constraints.video.mandatory.minAspectRatio = 1.77;
|
||||
break;
|
||||
case '180':
|
||||
constraints.video.mandatory.minWidth = 320;
|
||||
constraints.video.mandatory.minHeight = 180;
|
||||
constraints.video.mandatory.minAspectRatio = 1.77;
|
||||
break;
|
||||
// 4:3
|
||||
case '960':
|
||||
constraints.video.mandatory.minWidth = 960;
|
||||
constraints.video.mandatory.minHeight = 720;
|
||||
break;
|
||||
case '640':
|
||||
case 'vga':
|
||||
constraints.video.mandatory.minWidth = 640;
|
||||
constraints.video.mandatory.minHeight = 480;
|
||||
break;
|
||||
case '320':
|
||||
constraints.video.mandatory.minWidth = 320;
|
||||
constraints.video.mandatory.minHeight = 240;
|
||||
break;
|
||||
default:
|
||||
if (navigator.userAgent.indexOf('Android') != -1) {
|
||||
constraints.video.mandatory.minWidth = 320;
|
||||
constraints.video.mandatory.minHeight = 240;
|
||||
constraints.video.mandatory.maxFrameRate = 15;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (bandwidth) { // doesn't work currently, see webrtc issue 1846
|
||||
if (!constraints.video) constraints.video = {mandatory: {}};//same behaviour as true
|
||||
constraints.video.optional = [{bandwidth: bandwidth}];
|
||||
}
|
||||
if (fps) { // for some cameras it might be necessary to request 30fps
|
||||
// so they choose 30fps mjpg over 10fps yuy2
|
||||
if (!constraints.video) constraints.video = {mandatory: {}};// same behaviour as tru;
|
||||
constraints.video.mandatory.minFrameRate = fps;
|
||||
}
|
||||
|
||||
try {
|
||||
RTC.getUserMedia(constraints,
|
||||
function (stream) {
|
||||
console.log('onUserMediaSuccess');
|
||||
$(document).trigger('mediaready.jingle', [stream]);
|
||||
},
|
||||
function (error) {
|
||||
console.warn('Failed to get access to local media. Error ', error);
|
||||
$(document).trigger('mediafailure.jingle');
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('GUM failed: ', e);
|
||||
$(document).trigger('mediafailure.jingle');
|
||||
}
|
||||
}
|
||||
}(jQuery));
|
||||
@@ -1,261 +0,0 @@
|
||||
/* jshint -W117 */
|
||||
(function($){
|
||||
Strophe.addConnectionPlugin('jingle', {
|
||||
connection: null,
|
||||
sessions: {},
|
||||
jid2session: {},
|
||||
ice_config: {iceServers: []},
|
||||
pc_constraints: {},
|
||||
media_constraints: {
|
||||
mandatory: {
|
||||
'OfferToReceiveAudio': true,
|
||||
'OfferToReceiveVideo': true
|
||||
}
|
||||
// MozDontOfferDataChannel: true when this is firefox
|
||||
},
|
||||
localStream: null,
|
||||
|
||||
init: function (conn) {
|
||||
this.connection = conn;
|
||||
if (this.connection.disco) {
|
||||
// http://xmpp.org/extensions/xep-0167.html#support
|
||||
// http://xmpp.org/extensions/xep-0176.html#support
|
||||
this.connection.disco.addFeature('urn:xmpp:jingle:1');
|
||||
this.connection.disco.addFeature('urn:xmpp:jingle:apps:rtp:1');
|
||||
this.connection.disco.addFeature('urn:xmpp:jingle:transports:ice-udp:1');
|
||||
this.connection.disco.addFeature('urn:xmpp:jingle:apps:rtp:audio');
|
||||
this.connection.disco.addFeature('urn:xmpp:jingle:apps:rtp:video');
|
||||
|
||||
|
||||
// this is dealt with by SDP O/A so we don't need to annouce this
|
||||
//this.connection.disco.addFeature('urn:xmpp:jingle:apps:rtp:rtcp-fb:0'); // XEP-0293
|
||||
//this.connection.disco.addFeature('urn:xmpp:jingle:apps:rtp:rtp-hdrext:0'); // XEP-0294
|
||||
this.connection.disco.addFeature('urn:ietf:rfc:5761'); // rtcp-mux
|
||||
//this.connection.disco.addFeature('urn:ietf:rfc:5888'); // a=group, e.g. bundle
|
||||
//this.connection.disco.addFeature('urn:ietf:rfc:5576'); // a=ssrc
|
||||
}
|
||||
this.connection.addHandler(this.onJingle.bind(this), 'urn:xmpp:jingle:1', 'iq', 'set', null, null);
|
||||
},
|
||||
onJingle: function (iq) {
|
||||
var sid = $(iq).find('jingle').attr('sid');
|
||||
var action = $(iq).find('jingle').attr('action');
|
||||
// send ack first
|
||||
var ack = $iq({type: 'result',
|
||||
to: iq.getAttribute('from'),
|
||||
id: iq.getAttribute('id')
|
||||
});
|
||||
console.log('on jingle ' + action);
|
||||
var sess = this.sessions[sid];
|
||||
if ('session-initiate' != action) {
|
||||
if (sess === null) {
|
||||
ack.type = 'error';
|
||||
ack.c('error', {type: 'cancel'})
|
||||
.c('item-not-found', {xmlns: 'urn:ietf:params:xml:ns:xmpp-stanzas'}).up()
|
||||
.c('unknown-session', {xmlns: 'urn:xmpp:jingle:errors:1'});
|
||||
this.connection.send(ack);
|
||||
return true;
|
||||
}
|
||||
// compare from to sess.peerjid (bare jid comparison for later compat with message-mode)
|
||||
// local jid is not checked
|
||||
if (Strophe.getBareJidFromJid(iq.getAttribute('from')) != Strophe.getBareJidFromJid(sess.peerjid)) {
|
||||
console.warn('jid mismatch for session id', sid, iq.getAttribute('from'), sess.peerjid);
|
||||
ack.type = 'error';
|
||||
ack.c('error', {type: 'cancel'})
|
||||
.c('item-not-found', {xmlns: 'urn:ietf:params:xml:ns:xmpp-stanzas'}).up()
|
||||
.c('unknown-session', {xmlns: 'urn:xmpp:jingle:errors:1'});
|
||||
this.connection.send(ack);
|
||||
return true;
|
||||
}
|
||||
} else if (sess !== undefined) {
|
||||
// existing session with same session id
|
||||
// this might be out-of-order if the sess.peerjid is the same as from
|
||||
ack.type = 'error';
|
||||
ack.c('error', {type: 'cancel'})
|
||||
.c('service-unavailable', {xmlns: 'urn:ietf:params:xml:ns:xmpp-stanzas'}).up();
|
||||
console.warn('duplicate session id', sid);
|
||||
this.connection.send(ack);
|
||||
return true;
|
||||
}
|
||||
// FIXME: check for a defined action
|
||||
this.connection.send(ack);
|
||||
// see http://xmpp.org/extensions/xep-0166.html#concepts-session
|
||||
switch (action) {
|
||||
case 'session-initiate':
|
||||
sess = new JingleSession($(iq).attr('to'), $(iq).find('jingle').attr('sid'), this.connection);
|
||||
// configure session
|
||||
if (this.localStream) {
|
||||
sess.localStreams.push(this.localStream);
|
||||
}
|
||||
sess.media_constraints = this.media_constraints;
|
||||
sess.pc_constraints = this.pc_constraints;
|
||||
sess.ice_config = this.ice_config;
|
||||
|
||||
sess.initiate($(iq).attr('from'), false);
|
||||
// FIXME: setRemoteDescription should only be done when this call is to be accepted
|
||||
sess.setRemoteDescription($(iq).find('>jingle'), 'offer');
|
||||
|
||||
this.sessions[sess.sid] = sess;
|
||||
this.jid2session[sess.peerjid] = sess;
|
||||
|
||||
// the callback should either
|
||||
// .sendAnswer and .accept
|
||||
// or .sendTerminate -- not necessarily synchronus
|
||||
$(document).trigger('callincoming.jingle', [sess.sid]);
|
||||
break;
|
||||
case 'session-accept':
|
||||
sess.setRemoteDescription($(iq).find('>jingle'), 'answer');
|
||||
sess.accept();
|
||||
$(document).trigger('callaccepted.jingle', [sess.sid]);
|
||||
break;
|
||||
case 'session-terminate':
|
||||
console.log('terminating...');
|
||||
sess.terminate();
|
||||
this.terminate(sess.sid);
|
||||
if ($(iq).find('>jingle>reason').length) {
|
||||
$(document).trigger('callterminated.jingle', [
|
||||
sess.sid,
|
||||
$(iq).find('>jingle>reason>:first')[0].tagName,
|
||||
$(iq).find('>jingle>reason>text').text()
|
||||
]);
|
||||
} else {
|
||||
$(document).trigger('callterminated.jingle', [sess.sid]);
|
||||
}
|
||||
break;
|
||||
case 'transport-info':
|
||||
sess.addIceCandidate($(iq).find('>jingle>content'));
|
||||
break;
|
||||
case 'session-info':
|
||||
var affected;
|
||||
if ($(iq).find('>jingle>ringing[xmlns="urn:xmpp:jingle:apps:rtp:info:1"]').length) {
|
||||
$(document).trigger('ringing.jingle', [sess.sid]);
|
||||
} else if ($(iq).find('>jingle>mute[xmlns="urn:xmpp:jingle:apps:rtp:info:1"]').length) {
|
||||
affected = $(iq).find('>jingle>mute[xmlns="urn:xmpp:jingle:apps:rtp:info:1"]').attr('name');
|
||||
$(document).trigger('mute.jingle', [sess.sid, affected]);
|
||||
} else if ($(iq).find('>jingle>unmute[xmlns="urn:xmpp:jingle:apps:rtp:info:1"]').length) {
|
||||
affected = $(iq).find('>jingle>unmute[xmlns="urn:xmpp:jingle:apps:rtp:info:1"]').attr('name');
|
||||
$(document).trigger('unmute.jingle', [sess.sid, affected]);
|
||||
}
|
||||
break;
|
||||
case 'addsource': // FIXME: proprietary
|
||||
sess.addSource($(iq).find('>jingle>content'));
|
||||
break;
|
||||
case 'removesource': // FIXME: proprietary
|
||||
sess.removeSource($(iq).find('>jingle>content'));
|
||||
break;
|
||||
default:
|
||||
console.warn('jingle action not implemented', action);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
initiate: function (peerjid, myjid) { // initiate a new jinglesession to peerjid
|
||||
var sess = new JingleSession(myjid || this.connection.jid,
|
||||
Math.random().toString(36).substr(2, 12), // random string
|
||||
this.connection);
|
||||
// configure session
|
||||
if (this.localStream) {
|
||||
sess.localStreams.push(this.localStream);
|
||||
}
|
||||
sess.media_constraints = this.media_constraints;
|
||||
sess.pc_constraints = this.pc_constraints;
|
||||
sess.ice_config = this.ice_config;
|
||||
|
||||
sess.initiate(peerjid, true);
|
||||
this.sessions[sess.sid] = sess;
|
||||
this.jid2session[sess.peerjid] = sess;
|
||||
sess.sendOffer();
|
||||
return sess;
|
||||
},
|
||||
terminate: function (sid, reason, text) { // terminate by sessionid (or all sessions)
|
||||
if (sid === null || sid === undefined) {
|
||||
for (sid in this.sessions) {
|
||||
if (this.sessions[sid].state != 'ended') {
|
||||
this.sessions[sid].sendTerminate(reason || (!this.sessions[sid].active()) ? 'cancel' : null, text);
|
||||
this.sessions[sid].terminate();
|
||||
}
|
||||
delete this.jid2session[this.sessions[sid].peerjid];
|
||||
delete this.sessions[sid];
|
||||
}
|
||||
} else if (this.sessions.hasOwnProperty(sid)) {
|
||||
if (this.sessions[sid].state != 'ended') {
|
||||
this.sessions[sid].sendTerminate(reason || (!this.sessions[sid].active()) ? 'cancel' : null, text);
|
||||
this.sessions[sid].terminate();
|
||||
}
|
||||
delete this.jid2session[this.sessions[sid].peerjid];
|
||||
delete this.sessions[sid];
|
||||
}
|
||||
},
|
||||
terminateByJid: function (jid) {
|
||||
if (this.jid2session.hasOwnProperty(jid)) {
|
||||
var sess = this.jid2session[jid];
|
||||
if (sess) {
|
||||
sess.terminate();
|
||||
console.log('peer went away silently', jid);
|
||||
delete this.sessions[sess.sid];
|
||||
delete this.jid2session[jid];
|
||||
$(document).trigger('callterminated.jingle', [sess.sid, 'gone']);
|
||||
}
|
||||
}
|
||||
},
|
||||
getStunAndTurnCredentials: function () {
|
||||
// get stun and turn configuration from server via xep-0215
|
||||
// uses time-limited credentials as described in
|
||||
// http://tools.ietf.org/html/draft-uberti-behave-turn-rest-00
|
||||
//
|
||||
// see https://code.google.com/p/prosody-modules/source/browse/mod_turncredentials/mod_turncredentials.lua
|
||||
// for a prosody module which implements this
|
||||
//
|
||||
// currently, this doesn't work with updateIce and therefore credentials with a long
|
||||
// validity have to be fetched before creating the peerconnection
|
||||
// TODO: implement refresh via updateIce as described in
|
||||
// https://code.google.com/p/webrtc/issues/detail?id=1650
|
||||
this.connection.sendIQ(
|
||||
$iq({type: 'get', to: this.connection.domain})
|
||||
.c('services', {xmlns: 'urn:xmpp:extdisco:1'}).c('service', {host: 'turn.' + this.connection.domain}),
|
||||
function (res) {
|
||||
var iceservers = [];
|
||||
$(res).find('>services>service').each(function (idx, el) {
|
||||
el = $(el);
|
||||
var dict = {};
|
||||
switch (el.attr('type')) {
|
||||
case 'stun':
|
||||
dict.url = 'stun:' + el.attr('host');
|
||||
if (el.attr('port')) {
|
||||
dict.url += ':' + el.attr('port');
|
||||
}
|
||||
iceservers.push(dict);
|
||||
break;
|
||||
case 'turn':
|
||||
dict.url = 'turn:';
|
||||
if (el.attr('username')) { // https://code.google.com/p/webrtc/issues/detail?id=1508
|
||||
if (navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./) && parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2], 10) < 28) {
|
||||
dict.url += el.attr('username') + '@';
|
||||
} else {
|
||||
dict.username = el.attr('username'); // only works in M28
|
||||
}
|
||||
}
|
||||
dict.url += el.attr('host');
|
||||
if (el.attr('port') && el.attr('port') != '3478') {
|
||||
dict.url += ':' + el.attr('port');
|
||||
}
|
||||
if (el.attr('transport') && el.attr('transport') != 'udp') {
|
||||
dict.url += '?transport=' + el.attr('transport');
|
||||
}
|
||||
if (el.attr('password')) {
|
||||
dict.credential = el.attr('password');
|
||||
}
|
||||
iceservers.push(dict);
|
||||
break;
|
||||
}
|
||||
});
|
||||
this.ice_config.iceServers = iceservers;
|
||||
},
|
||||
function (err) {
|
||||
console.warn('getting turn credentials failed', err);
|
||||
console.warn('is mod_turncredentials or similar installed?');
|
||||
}
|
||||
);
|
||||
// implement push?
|
||||
}
|
||||
});
|
||||
}(jQuery));
|
||||
@@ -1,813 +0,0 @@
|
||||
/* jshint -W117 */
|
||||
var SDP;
|
||||
|
||||
(function($){
|
||||
// SDP STUFF
|
||||
SDP = function(sdp) {
|
||||
this.media = sdp.split('\r\nm=');
|
||||
for (var i = 1; i < this.media.length; i++) {
|
||||
this.media[i] = 'm=' + this.media[i];
|
||||
if (i != this.media.length - 1) {
|
||||
this.media[i] += '\r\n';
|
||||
}
|
||||
}
|
||||
this.session = this.media.shift() + '\r\n';
|
||||
this.raw = this.session + this.media.join('');
|
||||
}
|
||||
|
||||
// remove iSAC and CN from SDP
|
||||
SDP.prototype.mangle = function () {
|
||||
var i, j, mline, lines, rtpmap, newdesc;
|
||||
for (i = 0; i < this.media.length; i++) {
|
||||
lines = this.media[i].split('\r\n');
|
||||
lines.pop(); // remove empty last element
|
||||
mline = SDPUtil.parse_mline(lines.shift());
|
||||
if (mline.media != 'audio')
|
||||
continue;
|
||||
newdesc = '';
|
||||
mline.fmt.length = 0;
|
||||
for (j = 0; j < lines.length; j++) {
|
||||
if (lines[j].substr(0, 9) == 'a=rtpmap:') {
|
||||
rtpmap = SDPUtil.parse_rtpmap(lines[j]);
|
||||
if (rtpmap.name == 'CN' || rtpmap.name == 'ISAC')
|
||||
continue;
|
||||
mline.fmt.push(rtpmap.id);
|
||||
newdesc += lines[j] + '\r\n';
|
||||
} else {
|
||||
newdesc += lines[j] + '\r\n';
|
||||
}
|
||||
}
|
||||
this.media[i] = SDPUtil.build_mline(mline) + '\r\n';
|
||||
this.media[i] += newdesc;
|
||||
}
|
||||
this.raw = this.session + this.media.join('');
|
||||
};
|
||||
|
||||
// remove lines matching prefix from session section
|
||||
SDP.prototype.removeSessionLines = function(prefix) {
|
||||
var self = this;
|
||||
var lines = SDPUtil.find_lines(this.session, prefix);
|
||||
lines.forEach(function(line) {
|
||||
self.session = self.session.replace(line + '\r\n', '');
|
||||
});
|
||||
this.raw = this.session + this.media.join('');
|
||||
return lines;
|
||||
}
|
||||
// remove lines matching prefix from a media section specified by mediaindex
|
||||
// TODO: non-numeric mediaindex could match mid
|
||||
SDP.prototype.removeMediaLines = function(mediaindex, prefix) {
|
||||
var self = this;
|
||||
var lines = SDPUtil.find_lines(this.media[mediaindex], prefix);
|
||||
lines.forEach(function(line) {
|
||||
self.media[mediaindex] = self.media[mediaindex].replace(line + '\r\n', '');
|
||||
});
|
||||
this.raw = this.session + this.media.join('');
|
||||
return lines;
|
||||
}
|
||||
|
||||
// add content's to a jingle element
|
||||
SDP.prototype.toJingle = function (elem, thecreator) {
|
||||
var i, j, k, mline, ssrc, rtpmap, tmp, line, lines;
|
||||
var self = this;
|
||||
// new bundle plan
|
||||
if (SDPUtil.find_line(this.session, 'a=group:')) {
|
||||
lines = SDPUtil.find_lines(this.session, 'a=group:');
|
||||
for (i = 0; i < lines.length; i++) {
|
||||
tmp = lines[i].split(' ');
|
||||
var semantics = tmp.shift().substr(8);
|
||||
// new plan
|
||||
elem.c('group', {xmlns: 'urn:xmpp:jingle:apps:grouping:0', type: semantics, semantics:semantics});
|
||||
for (j = 0; j < tmp.length; j++) {
|
||||
elem.c('content', {name: tmp[j]}).up();
|
||||
}
|
||||
elem.up();
|
||||
|
||||
// temporary plan, to be removed
|
||||
elem.c('group', {xmlns: 'urn:ietf:rfc:5888', type: semantics});
|
||||
for (j = 0; j < tmp.length; j++) {
|
||||
elem.c('content', {name: tmp[j]}).up();
|
||||
}
|
||||
elem.up();
|
||||
}
|
||||
}
|
||||
// old bundle plan, to be removed
|
||||
var bundle = [];
|
||||
if (SDPUtil.find_line(this.session, 'a=group:BUNDLE')) {
|
||||
bundle = SDPUtil.find_line(this.session, 'a=group:BUNDLE ').split(' ');
|
||||
bundle.shift();
|
||||
}
|
||||
for (i = 0; i < this.media.length; i++) {
|
||||
mline = SDPUtil.parse_mline(this.media[i].split('\r\n')[0]);
|
||||
if (!(mline.media == 'audio' || mline.media == 'video')) {
|
||||
continue;
|
||||
}
|
||||
if (SDPUtil.find_line(this.media[i], 'a=ssrc:')) {
|
||||
ssrc = SDPUtil.find_line(this.media[i], 'a=ssrc:').substring(7).split(' ')[0]; // take the first
|
||||
} else {
|
||||
ssrc = false;
|
||||
}
|
||||
|
||||
elem.c('content', {creator: thecreator, name: mline.media});
|
||||
if (SDPUtil.find_line(this.media[i], 'a=mid:')) {
|
||||
// prefer identifier from a=mid if present
|
||||
var mid = SDPUtil.parse_mid(SDPUtil.find_line(this.media[i], 'a=mid:'));
|
||||
elem.attrs({ name: mid });
|
||||
|
||||
// old BUNDLE plan, to be removed
|
||||
if (bundle.indexOf(mid) != -1) {
|
||||
elem.c('bundle', {xmlns: 'http://estos.de/ns/bundle'}).up();
|
||||
bundle.splice(bundle.indexOf(mid), 1);
|
||||
}
|
||||
}
|
||||
if (SDPUtil.find_line(this.media[i], 'a=rtpmap:').length) {
|
||||
elem.c('description',
|
||||
{xmlns: 'urn:xmpp:jingle:apps:rtp:1',
|
||||
media: mline.media });
|
||||
if (ssrc) {
|
||||
elem.attrs({ssrc: ssrc});
|
||||
}
|
||||
for (j = 0; j < mline.fmt.length; j++) {
|
||||
rtpmap = SDPUtil.find_line(this.media[i], 'a=rtpmap:' + mline.fmt[j]);
|
||||
elem.c('payload-type', SDPUtil.parse_rtpmap(rtpmap));
|
||||
// put any 'a=fmtp:' + mline.fmt[j] lines into <param name=foo value=bar/>
|
||||
if (SDPUtil.find_line(this.media[i], 'a=fmtp:' + mline.fmt[j])) {
|
||||
tmp = SDPUtil.parse_fmtp(SDPUtil.find_line(this.media[i], 'a=fmtp:' + mline.fmt[j]));
|
||||
for (k = 0; k < tmp.length; k++) {
|
||||
elem.c('parameter', tmp[k]).up();
|
||||
}
|
||||
}
|
||||
this.RtcpFbToJingle(i, elem, mline.fmt[j]); // XEP-0293 -- map a=rtcp-fb
|
||||
|
||||
elem.up();
|
||||
}
|
||||
if (SDPUtil.find_line(this.media[i], 'a=crypto:', this.session)) {
|
||||
elem.c('encryption', {required: 1});
|
||||
var crypto = SDPUtil.find_lines(this.media[i], 'a=crypto:', this.session);
|
||||
crypto.forEach(function(line) {
|
||||
elem.c('crypto', SDPUtil.parse_crypto(line)).up();
|
||||
});
|
||||
elem.up(); // end of encryption
|
||||
}
|
||||
|
||||
if (ssrc) {
|
||||
// new style mapping
|
||||
elem.c('source', { ssrc: ssrc, xmlns: 'urn:xmpp:jingle:apps:rtp:ssma:0' });
|
||||
// FIXME: group by ssrc and support multiple different ssrcs
|
||||
var ssrclines = SDPUtil.find_lines(this.media[i], 'a=ssrc:');
|
||||
ssrclines.forEach(function(line) {
|
||||
idx = line.indexOf(' ');
|
||||
var linessrc = line.substr(0, idx).substr(7);
|
||||
if (linessrc != ssrc) {
|
||||
elem.up();
|
||||
ssrc = linessrc;
|
||||
elem.c('source', { ssrc: ssrc, xmlns: 'urn:xmpp:jingle:apps:rtp:ssma:0' });
|
||||
}
|
||||
var kv = line.substr(idx + 1);
|
||||
elem.c('parameter');
|
||||
if (kv.indexOf(':') == -1) {
|
||||
elem.attrs({ name: kv });
|
||||
} else {
|
||||
elem.attrs({ name: kv.split(':', 2)[0] });
|
||||
elem.attrs({ value: kv.split(':', 2)[1] });
|
||||
}
|
||||
elem.up();
|
||||
});
|
||||
elem.up();
|
||||
|
||||
// old proprietary mapping, to be removed at some point
|
||||
tmp = SDPUtil.parse_ssrc(this.media[i]);
|
||||
tmp.xmlns = 'http://estos.de/ns/ssrc';
|
||||
tmp.ssrc = ssrc;
|
||||
elem.c('ssrc', tmp).up(); // ssrc is part of description
|
||||
}
|
||||
|
||||
if (SDPUtil.find_line(this.media[i], 'a=rtcp-mux')) {
|
||||
elem.c('rtcp-mux').up();
|
||||
}
|
||||
|
||||
// XEP-0293 -- map a=rtcp-fb:*
|
||||
this.RtcpFbToJingle(i, elem, '*');
|
||||
|
||||
// XEP-0294
|
||||
if (SDPUtil.find_line(this.media[i], 'a=extmap:')) {
|
||||
lines = SDPUtil.find_lines(this.media[i], 'a=extmap:');
|
||||
for (j = 0; j < lines.length; j++) {
|
||||
tmp = SDPUtil.parse_extmap(lines[j]);
|
||||
elem.c('rtp-hdrext', { xmlns: 'urn:xmpp:jingle:apps:rtp:rtp-hdrext:0',
|
||||
uri: tmp.uri,
|
||||
id: tmp.value });
|
||||
if (tmp.hasOwnProperty('direction')) {
|
||||
switch (tmp.direction) {
|
||||
case 'sendonly':
|
||||
elem.attrs({senders: 'responder'});
|
||||
break;
|
||||
case 'recvonly':
|
||||
elem.attrs({senders: 'initiator'});
|
||||
break;
|
||||
case 'sendrecv':
|
||||
elem.attrs({senders: 'both'});
|
||||
break;
|
||||
case 'inactive':
|
||||
elem.attrs({senders: 'none'});
|
||||
break;
|
||||
}
|
||||
}
|
||||
// TODO: handle params
|
||||
elem.up();
|
||||
}
|
||||
}
|
||||
elem.up(); // end of description
|
||||
}
|
||||
|
||||
// map ice-ufrag/pwd, dtls fingerprint, candidates
|
||||
this.TransportToJingle(i, elem);
|
||||
|
||||
if (SDPUtil.find_line(this.media[i], 'a=sendrecv', this.session)) {
|
||||
elem.attrs({senders: 'both'});
|
||||
} else if (SDPUtil.find_line(this.media[i], 'a=sendonly', this.session)) {
|
||||
elem.attrs({senders: 'initiator'});
|
||||
} else if (SDPUtil.find_line(this.media[i], 'a=recvonly', this.session)) {
|
||||
elem.attrs({senders: 'responder'});
|
||||
} else if (SDPUtil.find_line(this.media[i], 'a=inactive', this.session)) {
|
||||
elem.attrs({senders: 'none'});
|
||||
}
|
||||
if (mline.port == '0') {
|
||||
// estos hack to reject an m-line
|
||||
elem.attrs({senders: 'rejected'});
|
||||
}
|
||||
elem.up(); // end of content
|
||||
}
|
||||
elem.up();
|
||||
return elem;
|
||||
};
|
||||
|
||||
SDP.prototype.TransportToJingle = function (mediaindex, elem) {
|
||||
var i = mediaindex;
|
||||
var tmp;
|
||||
var self = this;
|
||||
elem.c('transport');
|
||||
|
||||
// XEP-0320
|
||||
var fingerprints = SDPUtil.find_lines(this.media[mediaindex], 'a=fingerprint:', this.session);
|
||||
fingerprints.forEach(function(line) {
|
||||
tmp = SDPUtil.parse_fingerprint(line);
|
||||
tmp.xmlns = 'urn:xmpp:tmp:jingle:apps:dtls:0';
|
||||
// tmp.xmlns = 'urn:xmpp:jingle:apps:dtls:0'; -- FIXME: update receivers first
|
||||
elem.c('fingerprint').t(tmp.fingerprint);
|
||||
delete tmp.fingerprint;
|
||||
line = SDPUtil.find_line(self.media[mediaindex], 'a=setup:', self.session);
|
||||
if (line) {
|
||||
tmp.setup = line.substr(8);
|
||||
}
|
||||
elem.attrs(tmp);
|
||||
elem.up(); // end of fingerprint
|
||||
});
|
||||
tmp = SDPUtil.iceparams(this.media[mediaindex], this.session);
|
||||
if (tmp) {
|
||||
tmp.xmlns = 'urn:xmpp:jingle:transports:ice-udp:1';
|
||||
elem.attrs(tmp);
|
||||
// XEP-0176
|
||||
if (SDPUtil.find_line(this.media[mediaindex], 'a=candidate:', this.session)) { // add any a=candidate lines
|
||||
var lines = SDPUtil.find_lines(this.media[mediaindex], 'a=candidate:', this.session);
|
||||
lines.forEach(function (line) {
|
||||
elem.c('candidate', SDPUtil.candidateToJingle(line)).up();
|
||||
});
|
||||
}
|
||||
}
|
||||
elem.up(); // end of transport
|
||||
}
|
||||
|
||||
SDP.prototype.RtcpFbToJingle = function (mediaindex, elem, payloadtype) { // XEP-0293
|
||||
var lines = SDPUtil.find_lines(this.media[mediaindex], 'a=rtcp-fb:' + payloadtype);
|
||||
lines.forEach(function (line) {
|
||||
var tmp = SDPUtil.parse_rtcpfb(line);
|
||||
if (tmp.type == 'trr-int') {
|
||||
elem.c('rtcp-fb-trr-int', {xmlns: 'urn:xmpp:jingle:apps:rtp:rtcp-fb:0', value: tmp.params[0]});
|
||||
elem.up();
|
||||
} else {
|
||||
elem.c('rtcp-fb', {xmlns: 'urn:xmpp:jingle:apps:rtp:rtcp-fb:0', type: tmp.type});
|
||||
if (tmp.params.length > 0) {
|
||||
elem.attrs({'subtype': tmp.params[0]});
|
||||
}
|
||||
elem.up();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
SDP.prototype.RtcpFbFromJingle = function (elem, payloadtype) { // XEP-0293
|
||||
var media = '';
|
||||
var tmp = elem.find('>rtcp-fb-trr-int[xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0"]');
|
||||
if (tmp.length) {
|
||||
media += 'a=rtcp-fb:' + '*' + ' ' + 'trr-int' + ' ';
|
||||
if (tmp.attr('value')) {
|
||||
media += tmp.attr('value');
|
||||
} else {
|
||||
media += '0';
|
||||
}
|
||||
media += '\r\n';
|
||||
}
|
||||
tmp = elem.find('>rtcp-fb[xmlns="urn:xmpp:jingle:apps:rtp:rtcp-fb:0"]');
|
||||
tmp.each(function () {
|
||||
media += 'a=rtcp-fb:' + payloadtype + ' ' + $(this).attr('type');
|
||||
if ($(this).attr('subtype')) {
|
||||
media += ' ' + $(this).attr('subtype');
|
||||
}
|
||||
media += '\r\n';
|
||||
});
|
||||
return media;
|
||||
};
|
||||
|
||||
// construct an SDP from a jingle stanza
|
||||
SDP.prototype.fromJingle = function (jingle) {
|
||||
var self = this;
|
||||
this.raw = 'v=0\r\n' +
|
||||
'o=- ' + '1923518516' + ' 2 IN IP4 0.0.0.0\r\n' +// FIXME
|
||||
's=-\r\n' +
|
||||
't=0 0\r\n';
|
||||
// http://tools.ietf.org/html/draft-ietf-mmusic-sdp-bundle-negotiation-04#section-8
|
||||
if ($(jingle).find('>group[xmlns="urn:xmpp:jingle:apps:grouping:0"]').length) {
|
||||
$(jingle).find('>group[xmlns="urn:xmpp:jingle:apps:grouping:0"]').each(function (idx, group) {
|
||||
var contents = $(group).find('>content').map(function (idx, content) {
|
||||
return content.getAttribute('name');
|
||||
}).get();
|
||||
if (contents.length > 0) {
|
||||
self.raw += 'a=group:' + (group.getAttribute('semantics') || group.getAttribute('type')) + ' ' + contents.join(' ') + '\r\n';
|
||||
}
|
||||
});
|
||||
} else if ($(jingle).find('>group[xmlns="urn:ietf:rfc:5888"]').length) {
|
||||
// temporary namespace, not to be used. to be removed soon.
|
||||
$(jingle).find('>group[xmlns="urn:ietf:rfc:5888"]').each(function (idx, group) {
|
||||
var contents = $(group).find('>content').map(function (idx, content) {
|
||||
return content.getAttribute('name');
|
||||
}).get();
|
||||
if (group.getAttribute('type') !== null && contents.length > 0) {
|
||||
self.raw += 'a=group:' + group.getAttribute('type') + ' ' + contents.join(' ') + '\r\n';
|
||||
}
|
||||
});
|
||||
} else {
|
||||
// for backward compability, to be removed soon
|
||||
// assume all contents are in the same bundle group, can be improved upon later
|
||||
var bundle = $(jingle).find('>content').filter(function (idx, content) {
|
||||
//elem.c('bundle', {xmlns:'http://estos.de/ns/bundle'});
|
||||
return $(content).find('>bundle').length > 0;
|
||||
}).map(function (idx, content) {
|
||||
return content.getAttribute('name');
|
||||
}).get();
|
||||
if (bundle.length) {
|
||||
this.raw += 'a=group:BUNDLE ' + bundle.join(' ') + '\r\n';
|
||||
}
|
||||
}
|
||||
|
||||
this.session = this.raw;
|
||||
jingle.find('>content').each(function () {
|
||||
var m = self.jingle2media($(this));
|
||||
self.media.push(m);
|
||||
});
|
||||
|
||||
// reconstruct msid-semantic -- apparently not necessary
|
||||
/*
|
||||
var msid = SDPUtil.parse_ssrc(this.raw);
|
||||
if (msid.hasOwnProperty('mslabel')) {
|
||||
this.session += "a=msid-semantic: WMS " + msid.mslabel + "\r\n";
|
||||
}
|
||||
*/
|
||||
|
||||
this.raw = this.session + this.media.join('');
|
||||
};
|
||||
|
||||
// translate a jingle content element into an an SDP media part
|
||||
SDP.prototype.jingle2media = function (content) {
|
||||
var media = '',
|
||||
desc = content.find('description'),
|
||||
ssrc = desc.attr('ssrc'),
|
||||
self = this,
|
||||
tmp;
|
||||
|
||||
tmp = { media: desc.attr('media') };
|
||||
tmp.port = '1';
|
||||
if (content.attr('senders') == 'rejected') {
|
||||
// estos hack to reject an m-line.
|
||||
tmp.port = '0';
|
||||
}
|
||||
if (content.find('>transport>fingerprint').length || desc.find('encryption').length) {
|
||||
tmp.proto = 'RTP/SAVPF';
|
||||
} else {
|
||||
tmp.proto = 'RTP/AVPF';
|
||||
}
|
||||
tmp.fmt = desc.find('payload-type').map(function () { return this.getAttribute('id'); }).get();
|
||||
media += SDPUtil.build_mline(tmp) + '\r\n';
|
||||
media += 'c=IN IP4 0.0.0.0\r\n';
|
||||
media += 'a=rtcp:1 IN IP4 0.0.0.0\r\n';
|
||||
tmp = content.find('>transport[xmlns="urn:xmpp:jingle:transports:ice-udp:1"]');
|
||||
if (tmp.length) {
|
||||
if (tmp.attr('ufrag')) {
|
||||
media += SDPUtil.build_iceufrag(tmp.attr('ufrag')) + '\r\n';
|
||||
}
|
||||
if (tmp.attr('pwd')) {
|
||||
media += SDPUtil.build_icepwd(tmp.attr('pwd')) + '\r\n';
|
||||
}
|
||||
tmp.find('>fingerprint').each(function () {
|
||||
// FIXME: check namespace at some point
|
||||
media += 'a=fingerprint:' + this.getAttribute('hash');
|
||||
media += ' ' + $(this).text();
|
||||
media += '\r\n';
|
||||
if (this.getAttribute('setup')) {
|
||||
media += 'a=setup:' + this.getAttribute('setup') + '\r\n';
|
||||
}
|
||||
});
|
||||
}
|
||||
switch (content.attr('senders')) {
|
||||
case 'initiator':
|
||||
media += 'a=sendonly\r\n';
|
||||
break;
|
||||
case 'responder':
|
||||
media += 'a=recvonly\r\n';
|
||||
break;
|
||||
case 'none':
|
||||
media += 'a=inactive\r\n';
|
||||
break;
|
||||
case 'both':
|
||||
media += 'a=sendrecv\r\n';
|
||||
break;
|
||||
}
|
||||
media += 'a=mid:' + content.attr('name') + '\r\n';
|
||||
|
||||
// <description><rtcp-mux/></description>
|
||||
// see http://code.google.com/p/libjingle/issues/detail?id=309 -- no spec though
|
||||
// and http://mail.jabber.org/pipermail/jingle/2011-December/001761.html
|
||||
if (desc.find('rtcp-mux').length) {
|
||||
media += 'a=rtcp-mux\r\n';
|
||||
}
|
||||
|
||||
if (desc.find('encryption').length) {
|
||||
desc.find('encryption>crypto').each(function () {
|
||||
media += 'a=crypto:' + this.getAttribute('tag');
|
||||
media += ' ' + this.getAttribute('crypto-suite');
|
||||
media += ' ' + this.getAttribute('key-params');
|
||||
if (this.getAttribute('session-params')) {
|
||||
media += ' ' + this.getAttribute('session-params');
|
||||
}
|
||||
media += '\r\n';
|
||||
});
|
||||
}
|
||||
desc.find('payload-type').each(function () {
|
||||
media += SDPUtil.build_rtpmap(this) + '\r\n';
|
||||
if ($(this).find('>parameter').length) {
|
||||
media += 'a=fmtp:' + this.getAttribute('id') + ' ';
|
||||
media += $(this).find('parameter').map(function () { return (this.getAttribute('name') ? (this.getAttribute('name') + '=') : '') + this.getAttribute('value'); }).get().join(';');
|
||||
media += '\r\n';
|
||||
}
|
||||
// xep-0293
|
||||
media += self.RtcpFbFromJingle($(this), this.getAttribute('id'));
|
||||
});
|
||||
|
||||
// xep-0293
|
||||
media += self.RtcpFbFromJingle(desc, '*');
|
||||
|
||||
// xep-0294
|
||||
tmp = desc.find('>rtp-hdrext[xmlns="urn:xmpp:jingle:apps:rtp:rtp-hdrext:0"]');
|
||||
tmp.each(function () {
|
||||
media += 'a=extmap:' + this.getAttribute('id') + ' ' + this.getAttribute('uri') + '\r\n';
|
||||
});
|
||||
|
||||
content.find('>transport[xmlns="urn:xmpp:jingle:transports:ice-udp:1"]>candidate').each(function () {
|
||||
media += SDPUtil.candidateFromJingle(this);
|
||||
});
|
||||
|
||||
tmp = content.find('description>source[xmlns="urn:xmpp:jingle:apps:rtp:ssma:0"]');
|
||||
tmp.each(function () {
|
||||
var ssrc = this.getAttribute('ssrc');
|
||||
$(this).find('>parameter').each(function () {
|
||||
media += 'a=ssrc:' + ssrc + ' ' + this.getAttribute('name');
|
||||
if (this.getAttribute('value') && this.getAttribute('value').length)
|
||||
media += ':' + this.getAttribute('value');
|
||||
media += '\r\n';
|
||||
});
|
||||
});
|
||||
|
||||
if (tmp.length === 0) {
|
||||
// fallback to proprietary mapping of a=ssrc lines
|
||||
tmp = content.find('description>ssrc[xmlns="http://estos.de/ns/ssrc"]');
|
||||
if (tmp.length) {
|
||||
media += 'a=ssrc:' + ssrc + ' cname:' + tmp.attr('cname') + '\r\n';
|
||||
media += 'a=ssrc:' + ssrc + ' msid:' + tmp.attr('msid') + '\r\n';
|
||||
media += 'a=ssrc:' + ssrc + ' mslabel:' + tmp.attr('mslabel') + '\r\n';
|
||||
media += 'a=ssrc:' + ssrc + ' label:' + tmp.attr('label') + '\r\n';
|
||||
}
|
||||
}
|
||||
return media;
|
||||
};
|
||||
|
||||
SDPUtil = {
|
||||
iceparams: function (mediadesc, sessiondesc) {
|
||||
var data = null;
|
||||
if (SDPUtil.find_line(mediadesc, 'a=ice-ufrag:', sessiondesc) &&
|
||||
SDPUtil.find_line(mediadesc, 'a=ice-pwd:', sessiondesc)) {
|
||||
data = {
|
||||
ufrag: SDPUtil.parse_iceufrag(SDPUtil.find_line(mediadesc, 'a=ice-ufrag:', sessiondesc)),
|
||||
pwd: SDPUtil.parse_icepwd(SDPUtil.find_line(mediadesc, 'a=ice-pwd:', sessiondesc))
|
||||
};
|
||||
}
|
||||
return data;
|
||||
},
|
||||
parse_iceufrag: function (line) {
|
||||
return line.substring(12);
|
||||
},
|
||||
build_iceufrag: function (frag) {
|
||||
return 'a=ice-ufrag:' + frag;
|
||||
},
|
||||
parse_icepwd: function (line) {
|
||||
return line.substring(10);
|
||||
},
|
||||
build_icepwd: function (pwd) {
|
||||
return 'a=ice-pwd:' + pwd;
|
||||
},
|
||||
parse_mid: function (line) {
|
||||
return line.substring(6);
|
||||
},
|
||||
parse_mline: function (line) {
|
||||
var parts = line.substring(2).split(' '),
|
||||
data = {};
|
||||
data.media = parts.shift();
|
||||
data.port = parts.shift();
|
||||
data.proto = parts.shift();
|
||||
if (parts[parts.length - 1] === '') { // trailing whitespace
|
||||
parts.pop();
|
||||
}
|
||||
data.fmt = parts;
|
||||
return data;
|
||||
},
|
||||
build_mline: function (mline) {
|
||||
return 'm=' + mline.media + ' ' + mline.port + ' ' + mline.proto + ' ' + mline.fmt.join(' ');
|
||||
},
|
||||
parse_rtpmap: function (line) {
|
||||
var parts = line.substring(9).split(' '),
|
||||
data = {};
|
||||
data.id = parts.shift();
|
||||
parts = parts[0].split('/');
|
||||
data.name = parts.shift();
|
||||
data.clockrate = parts.shift();
|
||||
data.channels = parts.length ? parts.shift() : '1';
|
||||
return data;
|
||||
},
|
||||
build_rtpmap: function (el) {
|
||||
var line = 'a=rtpmap:' + el.getAttribute('id') + ' ' + el.getAttribute('name') + '/' + el.getAttribute('clockrate');
|
||||
if (el.getAttribute('channels') && el.getAttribute('channels') != '1') {
|
||||
line += '/' + el.getAttribute('channels');
|
||||
}
|
||||
return line;
|
||||
},
|
||||
parse_crypto: function (line) {
|
||||
var parts = line.substring(9).split(' '),
|
||||
data = {};
|
||||
data.tag = parts.shift();
|
||||
data['crypto-suite'] = parts.shift();
|
||||
data['key-params'] = parts.shift();
|
||||
if (parts.length) {
|
||||
data['session-params'] = parts.join(' ');
|
||||
}
|
||||
return data;
|
||||
},
|
||||
parse_fingerprint: function (line) { // RFC 4572
|
||||
var parts = line.substring(14).split(' '),
|
||||
data = {};
|
||||
data.hash = parts.shift();
|
||||
data.fingerprint = parts.shift();
|
||||
// TODO assert that fingerprint satisfies 2UHEX *(":" 2UHEX) ?
|
||||
return data;
|
||||
},
|
||||
parse_fmtp: function (line) {
|
||||
var parts = line.split(' '),
|
||||
i, key, value,
|
||||
data = [];
|
||||
parts.shift();
|
||||
parts = parts.join(' ').split(';');
|
||||
for (i = 0; i < parts.length; i++) {
|
||||
key = parts[i].split('=')[0];
|
||||
while (key.length && key[0] == ' ') {
|
||||
key = key.substring(1);
|
||||
}
|
||||
value = parts[i].split('=')[1];
|
||||
if (key && value) {
|
||||
data.push({name: key, value: value});
|
||||
} else if (key) {
|
||||
// rfc 4733 (DTMF) style stuff
|
||||
data.push({name: '', value: key});
|
||||
}
|
||||
}
|
||||
return data;
|
||||
},
|
||||
parse_icecandidate: function (line) {
|
||||
var candidate = {},
|
||||
elems = line.split(' ');
|
||||
candidate.foundation = elems[0].substring(12);
|
||||
candidate.component = elems[1];
|
||||
candidate.protocol = elems[2].toLowerCase();
|
||||
candidate.priority = elems[3];
|
||||
candidate.ip = elems[4];
|
||||
candidate.port = elems[5];
|
||||
// elems[6] => "typ"
|
||||
candidate.type = elems[7];
|
||||
candidate.generation = 0; // default value, may be overwritten below
|
||||
for (var i = 8; i < elems.length; i += 2) {
|
||||
switch (elems[i]) {
|
||||
case 'raddr':
|
||||
candidate['rel-addr'] = elems[i + 1];
|
||||
break;
|
||||
case 'rport':
|
||||
candidate['rel-port'] = elems[i + 1];
|
||||
break;
|
||||
case 'generation':
|
||||
candidate.generation = elems[i + 1];
|
||||
break;
|
||||
default: // TODO
|
||||
console.log('parse_icecandidate not translating "' + elems[i] + '" = "' + elems[i + 1] + '"');
|
||||
}
|
||||
}
|
||||
candidate.network = '1';
|
||||
candidate.id = Math.random().toString(36).substr(2, 10); // not applicable to SDP -- FIXME: should be unique, not just random
|
||||
return candidate;
|
||||
},
|
||||
build_icecandidate: function (cand) {
|
||||
var line = ['a=candidate:' + cand.foundation, cand.component, cand.protocol, cand.priority, cand.ip, cand.port, 'typ', cand.type].join(' ');
|
||||
line += ' ';
|
||||
switch (cand.type) {
|
||||
case 'srflx':
|
||||
case 'prflx':
|
||||
case 'relay':
|
||||
if (cand.hasOwnAttribute('rel-addr') && cand.hasOwnAttribute('rel-port')) {
|
||||
line += 'raddr';
|
||||
line += ' ';
|
||||
line += cand['rel-addr'];
|
||||
line += ' ';
|
||||
line += 'rport';
|
||||
line += ' ';
|
||||
line += cand['rel-port'];
|
||||
line += ' ';
|
||||
}
|
||||
break;
|
||||
}
|
||||
line += 'generation';
|
||||
line += ' ';
|
||||
line += cand.hasOwnAttribute('generation') ? cand.generation : '0';
|
||||
return line;
|
||||
},
|
||||
parse_ssrc: function (desc) {
|
||||
// proprietary mapping of a=ssrc lines
|
||||
// TODO: see "Jingle RTP Source Description" by Juberti and P. Thatcher on google docs
|
||||
// and parse according to that
|
||||
var lines = desc.split('\r\n'),
|
||||
data = {};
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
if (lines[i].substring(0, 7) == 'a=ssrc:') {
|
||||
var idx = lines[i].indexOf(' ');
|
||||
data[lines[i].substr(idx + 1).split(':', 2)[0]] = lines[i].substr(idx + 1).split(':', 2)[1];
|
||||
}
|
||||
}
|
||||
return data;
|
||||
},
|
||||
parse_rtcpfb: function (line) {
|
||||
var parts = line.substr(10).split(' ');
|
||||
var data = {};
|
||||
data.pt = parts.shift();
|
||||
data.type = parts.shift();
|
||||
data.params = parts;
|
||||
return data;
|
||||
},
|
||||
parse_extmap: function (line) {
|
||||
var parts = line.substr(9).split(' ');
|
||||
var data = {};
|
||||
data.value = parts.shift();
|
||||
if (data.value.indexOf('/') != -1) {
|
||||
data.direction = data.value.substr(data.value.indexOf('/') + 1);
|
||||
data.value = data.value.substr(0, data.value.indexOf('/'));
|
||||
} else {
|
||||
data.direction = 'both';
|
||||
}
|
||||
data.uri = parts.shift();
|
||||
data.params = parts;
|
||||
return data;
|
||||
},
|
||||
find_line: function (haystack, needle, sessionpart) {
|
||||
var lines = haystack.split('\r\n');
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
if (lines[i].substring(0, needle.length) == needle) {
|
||||
return lines[i];
|
||||
}
|
||||
}
|
||||
if (!sessionpart) {
|
||||
return false;
|
||||
}
|
||||
// search session part
|
||||
lines = sessionpart.split('\r\n');
|
||||
for (var j = 0; j < lines.length; j++) {
|
||||
if (lines[j].substring(0, needle.length) == needle) {
|
||||
return lines[j];
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
find_lines: function (haystack, needle, sessionpart) {
|
||||
var lines = haystack.split('\r\n'),
|
||||
needles = [];
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
if (lines[i].substring(0, needle.length) == needle)
|
||||
needles.push(lines[i]);
|
||||
}
|
||||
if (needles.length || !sessionpart) {
|
||||
return needles;
|
||||
}
|
||||
// search session part
|
||||
lines = sessionpart.split('\r\n');
|
||||
for (var j = 0; j < lines.length; j++) {
|
||||
if (lines[j].substring(0, needle.length) == needle) {
|
||||
needles.push(lines[j]);
|
||||
}
|
||||
}
|
||||
return needles;
|
||||
},
|
||||
candidateToJingle: function (line) {
|
||||
// a=candidate:2979166662 1 udp 2113937151 192.168.2.100 57698 typ host generation 0
|
||||
// <candidate component=... foundation=... generation=... id=... ip=... network=... port=... priority=... protocol=... type=.../>
|
||||
if (line.substring(0, 12) != 'a=candidate:') {
|
||||
console.log('parseCandidate called with a line that is not a candidate line');
|
||||
console.log(line);
|
||||
return null;
|
||||
}
|
||||
if (line.substring(line.length - 2) == '\r\n') // chomp it
|
||||
line = line.substring(0, line.length - 2);
|
||||
var candidate = {},
|
||||
elems = line.split(' '),
|
||||
i;
|
||||
if (elems[6] != 'typ') {
|
||||
console.log('did not find typ in the right place');
|
||||
console.log(line);
|
||||
return null;
|
||||
}
|
||||
candidate.foundation = elems[0].substring(12);
|
||||
candidate.component = elems[1];
|
||||
candidate.protocol = elems[2].toLowerCase();
|
||||
candidate.priority = elems[3];
|
||||
candidate.ip = elems[4];
|
||||
candidate.port = elems[5];
|
||||
// elems[6] => "typ"
|
||||
candidate.type = elems[7];
|
||||
for (i = 8; i < elems.length; i += 2) {
|
||||
switch (elems[i]) {
|
||||
case 'raddr':
|
||||
candidate['rel-addr'] = elems[i + 1];
|
||||
break;
|
||||
case 'rport':
|
||||
candidate['rel-port'] = elems[i + 1];
|
||||
break;
|
||||
case 'generation':
|
||||
candidate.generation = elems[i + 1];
|
||||
break;
|
||||
default: // TODO
|
||||
console.log('not translating "' + elems[i] + '" = "' + elems[i + 1] + '"');
|
||||
}
|
||||
}
|
||||
candidate.network = '1';
|
||||
candidate.id = Math.random().toString(36).substr(2, 10); // not applicable to SDP -- FIXME: should be unique, not just random
|
||||
return candidate;
|
||||
},
|
||||
candidateFromJingle: function (cand) {
|
||||
var line = 'a=candidate:';
|
||||
line += cand.getAttribute('foundation');
|
||||
line += ' ';
|
||||
line += cand.getAttribute('component');
|
||||
line += ' ';
|
||||
line += cand.getAttribute('protocol'); //.toUpperCase(); // chrome M23 doesn't like this
|
||||
line += ' ';
|
||||
line += cand.getAttribute('priority');
|
||||
line += ' ';
|
||||
line += cand.getAttribute('ip');
|
||||
line += ' ';
|
||||
line += cand.getAttribute('port');
|
||||
line += ' ';
|
||||
line += 'typ';
|
||||
line += ' ' + cand.getAttribute('type');
|
||||
line += ' ';
|
||||
switch (cand.getAttribute('type')) {
|
||||
case 'srflx':
|
||||
case 'prflx':
|
||||
case 'relay':
|
||||
if (cand.getAttribute('rel-addr') && cand.getAttribute('rel-port')) {
|
||||
line += 'raddr';
|
||||
line += ' ';
|
||||
line += cand.getAttribute('rel-addr');
|
||||
line += ' ';
|
||||
line += 'rport';
|
||||
line += ' ';
|
||||
line += cand.getAttribute('rel-port');
|
||||
line += ' ';
|
||||
}
|
||||
break;
|
||||
}
|
||||
line += 'generation';
|
||||
line += ' ';
|
||||
line += cand.getAttribute('generation') || '0';
|
||||
return line + '\r\n';
|
||||
}
|
||||
};
|
||||
}(jQuery));
|
||||
@@ -1,859 +0,0 @@
|
||||
/* jshint -W117 */
|
||||
// Jingle stuff
|
||||
var JingleSession;
|
||||
|
||||
(function($){
|
||||
JingleSession = function(me, sid, connection) {
|
||||
this.me = me;
|
||||
this.sid = sid;
|
||||
this.connection = connection;
|
||||
this.initiator = null;
|
||||
this.responder = null;
|
||||
this.isInitiator = null;
|
||||
this.peerjid = null;
|
||||
this.state = null;
|
||||
this.peerconnection = null;
|
||||
this.remoteStream = null;
|
||||
this.localSDP = null;
|
||||
this.remoteSDP = null;
|
||||
this.localStreams = [];
|
||||
this.relayedStreams = [];
|
||||
this.remoteStreams = [];
|
||||
this.startTime = null;
|
||||
this.stopTime = null;
|
||||
this.media_constraints = null;
|
||||
this.pc_constraints = null;
|
||||
this.ice_config = {},
|
||||
this.drip_container = [];
|
||||
|
||||
this.usetrickle = true;
|
||||
this.usepranswer = false; // early transport warmup -- mind you, this might fail. depends on webrtc issue 1718
|
||||
this.usedrip = false; // dripping is sending trickle candidates not one-by-one
|
||||
|
||||
this.hadstuncandidate = false;
|
||||
this.hadturncandidate = false;
|
||||
this.lasticecandidate = false;
|
||||
|
||||
this.statsinterval = null;
|
||||
|
||||
this.reason = null;
|
||||
|
||||
this.addssrc = [];
|
||||
this.removessrc = [];
|
||||
|
||||
this.wait = true;
|
||||
}
|
||||
|
||||
JingleSession.prototype.initiate = function (peerjid, isInitiator) {
|
||||
var self = this;
|
||||
if (this.state !== null) {
|
||||
console.error('attempt to initiate on session ' + this.sid +
|
||||
'in state ' + this.state);
|
||||
return;
|
||||
}
|
||||
this.isInitiator = isInitiator;
|
||||
this.state = 'pending';
|
||||
this.initiator = isInitiator ? this.me : peerjid;
|
||||
this.responder = !isInitiator ? this.me : peerjid;
|
||||
this.peerjid = peerjid;
|
||||
//console.log('create PeerConnection ' + JSON.stringify(this.ice_config));
|
||||
try {
|
||||
this.peerconnection = new RTCPeerconnection(this.ice_config,
|
||||
this.pc_constraints);
|
||||
} catch (e) {
|
||||
console.error('Failed to create PeerConnection, exception: ',
|
||||
e.message);
|
||||
console.error(e);
|
||||
return;
|
||||
}
|
||||
this.hadstuncandidate = false;
|
||||
this.hadturncandidate = false;
|
||||
this.lasticecandidate = false;
|
||||
this.peerconnection.onicecandidate = function (event) {
|
||||
self.sendIceCandidate(event.candidate);
|
||||
};
|
||||
this.peerconnection.onaddstream = function (event) {
|
||||
self.remoteStream = event.stream;
|
||||
self.remoteStreams.push(event.stream);
|
||||
$(document).trigger('remotestreamadded.jingle', [event, self.sid]);
|
||||
};
|
||||
this.peerconnection.onremovestream = function (event) {
|
||||
self.remoteStream = null;
|
||||
// FIXME: remove from this.remoteStreams
|
||||
$(document).trigger('remotestreamremoved.jingle', [event, self.sid]);
|
||||
};
|
||||
this.peerconnection.onsignalingstatechange = function (event) {
|
||||
if (!(self && self.peerconnection)) return;
|
||||
};
|
||||
this.peerconnection.oniceconnectionstatechange = function (event) {
|
||||
if (!(self && self.peerconnection)) return;
|
||||
switch (self.peerconnection.iceConnectionState) {
|
||||
case 'connected':
|
||||
this.startTime = new Date();
|
||||
break;
|
||||
case 'disconnected':
|
||||
this.stopTime = new Date();
|
||||
break;
|
||||
}
|
||||
$(document).trigger('iceconnectionstatechange.jingle', [self.sid, self]);
|
||||
};
|
||||
// add any local and relayed stream
|
||||
this.localStreams.forEach(function(stream) {
|
||||
self.peerconnection.addStream(stream);
|
||||
});
|
||||
this.relayedStreams.forEach(function(stream) {
|
||||
self.peerconnection.addStream(stream);
|
||||
});
|
||||
};
|
||||
|
||||
JingleSession.prototype.accept = function () {
|
||||
var self = this;
|
||||
this.state = 'active';
|
||||
|
||||
var pranswer = this.peerconnection.localDescription;
|
||||
if (!pranswer || pranswer.type != 'pranswer') {
|
||||
return;
|
||||
}
|
||||
console.log('going from pranswer to answer');
|
||||
if (this.usetrickle) {
|
||||
// remove candidates already sent from session-accept
|
||||
var lines = SDPUtil.find_lines(pranswer.sdp, 'a=candidate:');
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
pranswer.sdp = pranswer.sdp.replace(lines[i] + '\r\n', '');
|
||||
}
|
||||
}
|
||||
while (SDPUtil.find_line(pranswer.sdp, 'a=inactive')) {
|
||||
// FIXME: change any inactive to sendrecv or whatever they were originally
|
||||
pranswer.sdp = pranswer.sdp.replace('a=inactive', 'a=sendrecv');
|
||||
}
|
||||
var prsdp = new SDP(pranswer.sdp);
|
||||
var accept = $iq({to: this.peerjid,
|
||||
type: 'set'})
|
||||
.c('jingle', {xmlns: 'urn:xmpp:jingle:1',
|
||||
action: 'session-accept',
|
||||
initiator: this.initiator,
|
||||
responder: this.responder,
|
||||
sid: this.sid });
|
||||
prsdp.toJingle(accept, this.initiator == this.me ? 'initiator' : 'responder');
|
||||
this.connection.sendIQ(accept,
|
||||
function () {
|
||||
var ack = {};
|
||||
ack.source = 'answer';
|
||||
$(document).trigger('ack.jingle', [self.sid, ack]);
|
||||
},
|
||||
function (stanza) {
|
||||
var error = ($(stanza).find('error').length) ? {
|
||||
code: $(stanza).find('error').attr('code'),
|
||||
reason: $(stanza).find('error :first')[0].tagName,
|
||||
}:{};
|
||||
error.source = 'answer';
|
||||
$(document).trigger('error.jingle', [self.sid, error]);
|
||||
},
|
||||
10000);
|
||||
|
||||
var sdp = this.peerconnection.localDescription.sdp;
|
||||
while (SDPUtil.find_line(sdp, 'a=inactive')) {
|
||||
// FIXME: change any inactive to sendrecv or whatever they were originally
|
||||
sdp = sdp.replace('a=inactive', 'a=sendrecv');
|
||||
}
|
||||
this.peerconnection.setLocalDescription(new RTCSessionDescription({type: 'answer', sdp: sdp}),
|
||||
function () {
|
||||
//console.log('setLocalDescription success');
|
||||
},
|
||||
function (e) {
|
||||
console.error('setLocalDescription failed', e);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
JingleSession.prototype.terminate = function (reason) {
|
||||
this.state = 'ended';
|
||||
this.reason = reason;
|
||||
this.peerconnection.close();
|
||||
if (this.statsinterval !== null) {
|
||||
window.clearInterval(this.statsinterval);
|
||||
this.statsinterval = null;
|
||||
}
|
||||
};
|
||||
|
||||
JingleSession.prototype.active = function () {
|
||||
return this.state == 'active';
|
||||
};
|
||||
|
||||
JingleSession.prototype.sendIceCandidate = function (candidate) {
|
||||
var self = this;
|
||||
if (candidate && !this.lasticecandidate) {
|
||||
var ice = SDPUtil.iceparams(this.localSDP.media[candidate.sdpMLineIndex], this.localSDP.session);
|
||||
var jcand = SDPUtil.candidateToJingle(candidate.candidate);
|
||||
if (!(ice && jcand)) {
|
||||
console.error('failed to get ice && jcand');
|
||||
return;
|
||||
}
|
||||
ice.xmlns = 'urn:xmpp:jingle:transports:ice-udp:1';
|
||||
|
||||
if (jcand.type === 'srflx') {
|
||||
this.hadstuncandidate = true;
|
||||
} else if (jcand.type === 'relay') {
|
||||
this.hadturncandidate = true;
|
||||
}
|
||||
|
||||
if (this.usetrickle) {
|
||||
if (this.usedrip) {
|
||||
if (this.drip_container.length === 0) {
|
||||
// start 10ms callout
|
||||
window.setTimeout(function () {
|
||||
if (self.drip_container.length === 0) return;
|
||||
var allcands = self.drip_container;
|
||||
self.drip_container = [];
|
||||
var cand = $iq({to: self.peerjid, type: 'set'})
|
||||
.c('jingle', {xmlns: 'urn:xmpp:jingle:1',
|
||||
action: 'transport-info',
|
||||
initiator: self.initiator,
|
||||
sid: self.sid});
|
||||
for (var mid = 0; mid < self.localSDP.media.length; mid++) {
|
||||
var cands = allcands.filter(function (el) { return el.sdpMLineIndex == mid; });
|
||||
if (cands.length > 0) {
|
||||
var ice = SDPUtil.iceparams(self.localSDP.media[mid], self.localSDP.session);
|
||||
ice.xmlns = 'urn:xmpp:jingle:transports:ice-udp:1';
|
||||
cand.c('content', {creator: self.initiator == self.me ? 'initiator' : 'responder',
|
||||
name: cands[0].sdpMid
|
||||
}).c('transport', ice);
|
||||
for (var i = 0; i < cands.length; i++) {
|
||||
cand.c('candidate', SDPUtil.candidateToJingle(cands[i].candidate)).up();
|
||||
}
|
||||
// add fingerprint
|
||||
if (SDPUtil.find_line(self.localSDP.media[mid], 'a=fingerprint:', self.localSDP.session)) {
|
||||
var tmp = SDPUtil.parse_fingerprint(SDPUtil.find_line(self.localSDP.media[mid], 'a=fingerprint:', self.localSDP.session));
|
||||
tmp.required = true;
|
||||
cand.c('fingerprint').t(tmp.fingerprint);
|
||||
delete tmp.fingerprint;
|
||||
cand.attrs(tmp);
|
||||
cand.up();
|
||||
}
|
||||
cand.up(); // transport
|
||||
cand.up(); // content
|
||||
}
|
||||
}
|
||||
// might merge last-candidate notification into this, but it is called alot later. See webrtc issue #2340
|
||||
//console.log('was this the last candidate', self.lasticecandidate);
|
||||
self.connection.sendIQ(cand,
|
||||
function () {
|
||||
var ack = {};
|
||||
ack.source = 'transportinfo';
|
||||
$(document).trigger('ack.jingle', [self.sid, ack]);
|
||||
},
|
||||
function (stanza) {
|
||||
var error = ($(stanza).find('error').length) ? {
|
||||
code: $(stanza).find('error').attr('code'),
|
||||
reason: $(stanza).find('error :first')[0].tagName,
|
||||
}:{};
|
||||
error.source = 'transportinfo';
|
||||
$(document).trigger('error.jingle', [self.sid, error]);
|
||||
},
|
||||
10000);
|
||||
}, 10);
|
||||
}
|
||||
this.drip_container.push(event.candidate);
|
||||
return;
|
||||
}
|
||||
// map to transport-info
|
||||
var cand = $iq({to: this.peerjid, type: 'set'})
|
||||
.c('jingle', {xmlns: 'urn:xmpp:jingle:1',
|
||||
action: 'transport-info',
|
||||
initiator: this.initiator,
|
||||
sid: this.sid})
|
||||
.c('content', {creator: this.initiator == this.me ? 'initiator' : 'responder',
|
||||
name: candidate.sdpMid
|
||||
})
|
||||
.c('transport', ice)
|
||||
.c('candidate', jcand);
|
||||
cand.up();
|
||||
// add fingerprint
|
||||
if (SDPUtil.find_line(this.localSDP.media[candidate.sdpMLineIndex], 'a=fingerprint:', this.localSDP.session)) {
|
||||
var tmp = SDPUtil.parse_fingerprint(SDPUtil.find_line(this.localSDP.media[candidate.sdpMLineIndex], 'a=fingerprint:', this.localSDP.session));
|
||||
tmp.required = true;
|
||||
cand.c('fingerprint').t(tmp.fingerprint);
|
||||
delete tmp.fingerprint;
|
||||
cand.attrs(tmp);
|
||||
cand.up();
|
||||
}
|
||||
this.connection.sendIQ(cand,
|
||||
function () {
|
||||
var ack = {};
|
||||
ack.source = 'transportinfo';
|
||||
$(document).trigger('ack.jingle', [self.sid, ack]);
|
||||
},
|
||||
function (stanza) {
|
||||
console.error('transport info error');
|
||||
var error = ($(stanza).find('error').length) ? {
|
||||
code: $(stanza).find('error').attr('code'),
|
||||
reason: $(stanza).find('error :first')[0].tagName,
|
||||
}:{};
|
||||
error.source = 'transportinfo';
|
||||
$(document).trigger('error.jingle', [self.sid, error]);
|
||||
},
|
||||
10000);
|
||||
}
|
||||
} else {
|
||||
//console.log('sendIceCandidate: last candidate.');
|
||||
if (!this.usetrickle) {
|
||||
//console.log('should send full offer now...');
|
||||
var init = $iq({to: this.peerjid,
|
||||
type: 'set'})
|
||||
.c('jingle', {xmlns: 'urn:xmpp:jingle:1',
|
||||
action: this.peerconnection.localDescription.type == 'offer' ? 'session-initiate' : 'session-accept',
|
||||
initiator: this.initiator,
|
||||
sid: this.sid});
|
||||
this.localSDP = new SDP(this.peerconnection.localDescription.sdp);
|
||||
this.localSDP.toJingle(init, this.initiator == this.me ? 'initiator' : 'responder');
|
||||
this.connection.sendIQ(init,
|
||||
function () {
|
||||
//console.log('session initiate ack');
|
||||
var ack = {};
|
||||
ack.source = 'offer';
|
||||
$(document).trigger('ack.jingle', [self.sid, ack]);
|
||||
},
|
||||
function (stanza) {
|
||||
self.state = 'error';
|
||||
self.peerconnection.close();
|
||||
var error = ($(stanza).find('error').length) ? {
|
||||
code: $(stanza).find('error').attr('code'),
|
||||
reason: $(stanza).find('error :first')[0].tagName,
|
||||
}:{};
|
||||
error.source = 'offer';
|
||||
$(document).trigger('error.jingle', [self.sid, error]);
|
||||
},
|
||||
10000);
|
||||
}
|
||||
this.lasticecandidate = true;
|
||||
console.log('Have we encountered any srflx candidates? ' + this.hadstuncandidate);
|
||||
console.log('Have we encountered any relay candidates? ' + this.hadturncandidate);
|
||||
|
||||
if (!(this.hadstuncandidate || this.hadturncandidate) && this.peerconnection.signalingState != 'closed') {
|
||||
$(document).trigger('nostuncandidates.jingle', [this.sid]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
JingleSession.prototype.sendOffer = function () {
|
||||
//console.log('sendOffer...');
|
||||
var self = this;
|
||||
this.peerconnection.createOffer(function (sdp) {
|
||||
self.createdOffer(sdp);
|
||||
},
|
||||
function (e) {
|
||||
console.error('createOffer failed', e);
|
||||
},
|
||||
this.media_constraints
|
||||
);
|
||||
};
|
||||
|
||||
JingleSession.prototype.createdOffer = function (sdp) {
|
||||
//console.log('createdOffer', sdp);
|
||||
var self = this;
|
||||
this.localSDP = new SDP(sdp.sdp);
|
||||
//this.localSDP.mangle();
|
||||
if (this.usetrickle) {
|
||||
var init = $iq({to: this.peerjid,
|
||||
type: 'set'})
|
||||
.c('jingle', {xmlns: 'urn:xmpp:jingle:1',
|
||||
action: 'session-initiate',
|
||||
initiator: this.initiator,
|
||||
sid: this.sid});
|
||||
this.localSDP.toJingle(init, this.initiator == this.me ? 'initiator' : 'responder');
|
||||
this.connection.sendIQ(init,
|
||||
function () {
|
||||
var ack = {};
|
||||
ack.source = 'offer';
|
||||
$(document).trigger('ack.jingle', [self.sid, ack]);
|
||||
},
|
||||
function (stanza) {
|
||||
self.state = 'error';
|
||||
self.peerconnection.close();
|
||||
var error = ($(stanza).find('error').length) ? {
|
||||
code: $(stanza).find('error').attr('code'),
|
||||
reason: $(stanza).find('error :first')[0].tagName,
|
||||
}:{};
|
||||
error.source = 'offer';
|
||||
$(document).trigger('error.jingle', [self.sid, error]);
|
||||
},
|
||||
10000);
|
||||
}
|
||||
sdp.sdp = this.localSDP.raw;
|
||||
this.peerconnection.setLocalDescription(sdp,
|
||||
function () {
|
||||
//console.log('setLocalDescription success');
|
||||
},
|
||||
function (e) {
|
||||
console.error('setLocalDescription failed', e);
|
||||
}
|
||||
);
|
||||
var cands = SDPUtil.find_lines(this.localSDP.raw, 'a=candidate:');
|
||||
for (var i = 0; i < cands.length; i++) {
|
||||
var cand = SDPUtil.parse_icecandidate(cands[i]);
|
||||
if (cand.type == 'srflx') {
|
||||
this.hadstuncandidate = true;
|
||||
} else if (cand.type == 'relay') {
|
||||
this.hadturncandidate = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
JingleSession.prototype.setRemoteDescription = function (elem, desctype) {
|
||||
//console.log('setting remote description... ', desctype);
|
||||
this.remoteSDP = new SDP('');
|
||||
this.remoteSDP.fromJingle(elem);
|
||||
if (this.peerconnection.remoteDescription !== null) {
|
||||
console.log('setRemoteDescription when remote description is not null, should be pranswer', this.peerconnection.remoteDescription);
|
||||
if (this.peerconnection.remoteDescription.type == 'pranswer') {
|
||||
var pranswer = new SDP(this.peerconnection.remoteDescription.sdp);
|
||||
for (var i = 0; i < pranswer.media.length; i++) {
|
||||
// make sure we have ice ufrag and pwd
|
||||
if (!SDPUtil.find_line(this.remoteSDP.media[i], 'a=ice-ufrag:', this.remoteSDP.session)) {
|
||||
if (SDPUtil.find_line(pranswer.media[i], 'a=ice-ufrag:', pranswer.session)) {
|
||||
this.remoteSDP.media[i] += SDPUtil.find_line(pranswer.media[i], 'a=ice-ufrag:', pranswer.session) + '\r\n';
|
||||
} else {
|
||||
console.warn('no ice ufrag?');
|
||||
}
|
||||
if (SDPUtil.find_line(pranswer.media[i], 'a=ice-pwd:', pranswer.session)) {
|
||||
this.remoteSDP.media[i] += SDPUtil.find_line(pranswer.media[i], 'a=ice-pwd:', pranswer.session) + '\r\n';
|
||||
} else {
|
||||
console.warn('no ice pwd?');
|
||||
}
|
||||
}
|
||||
// copy over candidates
|
||||
var lines = SDPUtil.find_lines(pranswer.media[i], 'a=candidate:');
|
||||
for (var j = 0; j < lines.length; j++) {
|
||||
this.remoteSDP.media[i] += lines[j] + '\r\n';
|
||||
}
|
||||
}
|
||||
this.remoteSDP.raw = this.remoteSDP.session + this.remoteSDP.media.join('');
|
||||
}
|
||||
}
|
||||
var remotedesc = new RTCSessionDescription({type: desctype, sdp: this.remoteSDP.raw});
|
||||
|
||||
this.peerconnection.setRemoteDescription(remotedesc,
|
||||
function () {
|
||||
//console.log('setRemoteDescription success');
|
||||
},
|
||||
function (e) {
|
||||
console.error('setRemoteDescription error', e);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
JingleSession.prototype.addIceCandidate = function (elem) {
|
||||
var self = this;
|
||||
if (this.peerconnection.signalingState == 'closed') {
|
||||
return;
|
||||
}
|
||||
if (!this.peerconnection.remoteDescription && this.peerconnection.signalingState == 'have-local-offer') {
|
||||
console.log('trickle ice candidate arriving before session accept...');
|
||||
// create a PRANSWER for setRemoteDescription
|
||||
if (!this.remoteSDP) {
|
||||
var cobbled = 'v=0\r\n' +
|
||||
'o=- ' + '1923518516' + ' 2 IN IP4 0.0.0.0\r\n' +// FIXME
|
||||
's=-\r\n' +
|
||||
't=0 0\r\n';
|
||||
// first, take some things from the local description
|
||||
for (var i = 0; i < this.localSDP.media.length; i++) {
|
||||
cobbled += SDPUtil.find_line(this.localSDP.media[i], 'm=') + '\r\n';
|
||||
cobbled += SDPUtil.find_lines(this.localSDP.media[i], 'a=rtpmap:').join('\r\n') + '\r\n';
|
||||
if (SDPUtil.find_line(this.localSDP.media[i], 'a=mid:')) {
|
||||
cobbled += SDPUtil.find_line(this.localSDP.media[i], 'a=mid:') + '\r\n';
|
||||
}
|
||||
cobbled += 'a=inactive\r\n';
|
||||
}
|
||||
this.remoteSDP = new SDP(cobbled);
|
||||
}
|
||||
// then add things like ice and dtls from remote candidate
|
||||
elem.each(function () {
|
||||
for (var i = 0; i < self.remoteSDP.media.length; i++) {
|
||||
if (SDPUtil.find_line(self.remoteSDP.media[i], 'a=mid:' + $(this).attr('name')) ||
|
||||
self.remoteSDP.media[i].indexOf('m=' + $(this).attr('name')) === 0) {
|
||||
if (!SDPUtil.find_line(self.remoteSDP.media[i], 'a=ice-ufrag:')) {
|
||||
var tmp = $(this).find('transport');
|
||||
self.remoteSDP.media[i] += 'a=ice-ufrag:' + tmp.attr('ufrag') + '\r\n';
|
||||
self.remoteSDP.media[i] += 'a=ice-pwd:' + tmp.attr('pwd') + '\r\n';
|
||||
tmp = $(this).find('transport>fingerprint');
|
||||
if (tmp.length) {
|
||||
self.remoteSDP.media[i] += 'a=fingerprint:' + tmp.attr('hash') + ' ' + tmp.text() + '\r\n';
|
||||
} else {
|
||||
console.log('no dtls fingerprint (webrtc issue #1718?)');
|
||||
self.remoteSDP.media[i] += 'a=crypto:1 AES_CM_128_HMAC_SHA1_80 inline:BAADBAADBAADBAADBAADBAADBAADBAADBAADBAAD\r\n';
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
this.remoteSDP.raw = this.remoteSDP.session + this.remoteSDP.media.join('');
|
||||
|
||||
// we need a complete SDP with ice-ufrag/ice-pwd in all parts
|
||||
// this makes the assumption that the PRANSWER is constructed such that the ice-ufrag is in all mediaparts
|
||||
// but it could be in the session part as well. since the code above constructs this sdp this can't happen however
|
||||
var iscomplete = this.remoteSDP.media.filter(function (mediapart) {
|
||||
return SDPUtil.find_line(mediapart, 'a=ice-ufrag:');
|
||||
}).length == this.remoteSDP.media.length;
|
||||
|
||||
if (iscomplete) {
|
||||
console.log('setting pranswer');
|
||||
try {
|
||||
this.peerconnection.setRemoteDescription(new RTCSessionDescription({type: 'pranswer', sdp: this.remoteSDP.raw }),
|
||||
function() {
|
||||
},
|
||||
function(e) {
|
||||
console.log('setRemoteDescription pranswer failed', e.toString());
|
||||
});
|
||||
} catch (e) {
|
||||
console.error('setting pranswer failed', e);
|
||||
}
|
||||
} else {
|
||||
//console.log('not yet setting pranswer');
|
||||
}
|
||||
}
|
||||
// operate on each content element
|
||||
elem.each(function () {
|
||||
// would love to deactivate this, but firefox still requires it
|
||||
var idx = -1;
|
||||
var i;
|
||||
for (i = 0; i < self.remoteSDP.media.length; i++) {
|
||||
if (SDPUtil.find_line(self.remoteSDP.media[i], 'a=mid:' + $(this).attr('name')) ||
|
||||
self.remoteSDP.media[i].indexOf('m=' + $(this).attr('name')) === 0) {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (idx == -1) { // fall back to localdescription
|
||||
for (i = 0; i < self.localSDP.media.length; i++) {
|
||||
if (SDPUtil.find_line(self.localSDP.media[i], 'a=mid:' + $(this).attr('name')) ||
|
||||
self.localSDP.media[i].indexOf('m=' + $(this).attr('name')) === 0) {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
var name = $(this).attr('name');
|
||||
// TODO: check ice-pwd and ice-ufrag?
|
||||
$(this).find('transport>candidate').each(function () {
|
||||
var line, candidate;
|
||||
line = SDPUtil.candidateFromJingle(this);
|
||||
candidate = new RTCIceCandidate({sdpMLineIndex: idx,
|
||||
sdpMid: name,
|
||||
candidate: line});
|
||||
try {
|
||||
self.peerconnection.addIceCandidate(candidate);
|
||||
} catch (e) {
|
||||
console.error('addIceCandidate failed', e.toString(), line);
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
JingleSession.prototype.sendAnswer = function (provisional) {
|
||||
//console.log('createAnswer', provisional);
|
||||
var self = this;
|
||||
this.peerconnection.createAnswer(
|
||||
function (sdp) {
|
||||
self.createdAnswer(sdp, provisional);
|
||||
},
|
||||
function (e) {
|
||||
console.error('createAnswer failed', e);
|
||||
},
|
||||
this.media_constraints
|
||||
);
|
||||
};
|
||||
|
||||
JingleSession.prototype.createdAnswer = function (sdp, provisional) {
|
||||
//console.log('createAnswer callback');
|
||||
console.log(sdp);
|
||||
var self = this;
|
||||
this.localSDP = new SDP(sdp.sdp);
|
||||
//this.localSDP.mangle();
|
||||
this.usepranswer = provisional === true;
|
||||
if (this.usetrickle) {
|
||||
if (!this.usepranswer) {
|
||||
var accept = $iq({to: this.peerjid,
|
||||
type: 'set'})
|
||||
.c('jingle', {xmlns: 'urn:xmpp:jingle:1',
|
||||
action: 'session-accept',
|
||||
initiator: this.initiator,
|
||||
responder: this.responder,
|
||||
sid: this.sid });
|
||||
this.localSDP.toJingle(accept, this.initiator == this.me ? 'initiator' : 'responder');
|
||||
this.connection.sendIQ(accept,
|
||||
function () {
|
||||
var ack = {};
|
||||
ack.source = 'answer';
|
||||
$(document).trigger('ack.jingle', [self.sid, ack]);
|
||||
},
|
||||
function (stanza) {
|
||||
var error = ($(stanza).find('error').length) ? {
|
||||
code: $(stanza).find('error').attr('code'),
|
||||
reason: $(stanza).find('error :first')[0].tagName,
|
||||
}:{};
|
||||
error.source = 'answer';
|
||||
$(document).trigger('error.jingle', [self.sid, error]);
|
||||
},
|
||||
10000);
|
||||
} else {
|
||||
sdp.type = 'pranswer';
|
||||
for (var i = 0; i < this.localSDP.media.length; i++) {
|
||||
this.localSDP.media[i] = this.localSDP.media[i].replace('a=sendrecv\r\n', 'a=inactive\r\n');
|
||||
}
|
||||
this.localSDP.raw = this.localSDP.session + '\r\n' + this.localSDP.media.join('');
|
||||
}
|
||||
}
|
||||
sdp.sdp = this.localSDP.raw;
|
||||
this.peerconnection.setLocalDescription(sdp,
|
||||
function () {
|
||||
//console.log('setLocalDescription success');
|
||||
},
|
||||
function (e) {
|
||||
console.error('setLocalDescription failed', e);
|
||||
}
|
||||
);
|
||||
var cands = SDPUtil.find_lines(this.localSDP.raw, 'a=candidate:');
|
||||
for (var j = 0; j < cands.length; j++) {
|
||||
var cand = SDPUtil.parse_icecandidate(cands[j]);
|
||||
if (cand.type == 'srflx') {
|
||||
this.hadstuncandidate = true;
|
||||
} else if (cand.type == 'relay') {
|
||||
this.hadturncandidate = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
JingleSession.prototype.sendTerminate = function (reason, text) {
|
||||
var self = this,
|
||||
term = $iq({to: this.peerjid,
|
||||
type: 'set'})
|
||||
.c('jingle', {xmlns: 'urn:xmpp:jingle:1',
|
||||
action: 'session-terminate',
|
||||
initiator: this.initiator,
|
||||
sid: this.sid})
|
||||
.c('reason')
|
||||
.c(reason || 'success');
|
||||
|
||||
if (text) {
|
||||
term.up().c('text').t(text);
|
||||
}
|
||||
|
||||
this.connection.sendIQ(term,
|
||||
function () {
|
||||
self.peerconnection.close();
|
||||
self.peerconnection = null;
|
||||
self.terminate();
|
||||
var ack = {};
|
||||
ack.source = 'terminate';
|
||||
$(document).trigger('ack.jingle', [self.sid, ack]);
|
||||
},
|
||||
function (stanza) {
|
||||
var error = ($(stanza).find('error').length) ? {
|
||||
code: $(stanza).find('error').attr('code'),
|
||||
reason: $(stanza).find('error :first')[0].tagName,
|
||||
}:{};
|
||||
$(document).trigger('ack.jingle', [self.sid, error]);
|
||||
},
|
||||
10000);
|
||||
if (this.statsinterval !== null) {
|
||||
window.clearInterval(this.statsinterval);
|
||||
this.statsinterval = null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
JingleSession.prototype.addSource = function (elem) {
|
||||
console.log('addssrc', new Date().getTime());
|
||||
console.log('ice', this.peerconnection.iceConnectionState);
|
||||
var sdp = new SDP(this.peerconnection.remoteDescription.sdp);
|
||||
|
||||
var self = this;
|
||||
$(elem).each(function (idx, content) {
|
||||
var name = $(content).attr('name');
|
||||
var lines = '';
|
||||
tmp = $(content).find('>source[xmlns="urn:xmpp:jingle:apps:rtp:ssma:0"]');
|
||||
tmp.each(function () {
|
||||
var ssrc = $(this).attr('ssrc');
|
||||
$(this).find('>parameter').each(function () {
|
||||
lines += 'a=ssrc:' + ssrc + ' ' + $(this).attr('name');
|
||||
if ($(this).attr('value') && $(this).attr('value').length)
|
||||
lines += ':' + $(this).attr('value');
|
||||
lines += '\r\n';
|
||||
});
|
||||
});
|
||||
sdp.media.forEach(function(media, idx) {
|
||||
if (!SDPUtil.find_line(media, 'a=mid:' + name))
|
||||
return;
|
||||
sdp.media[idx] += lines;
|
||||
if (!self.addssrc[idx]) self.addssrc[idx] = '';
|
||||
self.addssrc[idx] += lines;
|
||||
});
|
||||
sdp.raw = sdp.session + sdp.media.join('');
|
||||
});
|
||||
this.modifySources();
|
||||
};
|
||||
|
||||
JingleSession.prototype.removeSource = function (elem) {
|
||||
console.log('removessrc', new Date().getTime());
|
||||
console.log('ice', this.peerconnection.iceConnectionState);
|
||||
var sdp = new SDP(this.peerconnection.remoteDescription.sdp);
|
||||
|
||||
var self = this;
|
||||
$(elem).each(function (idx, content) {
|
||||
var name = $(content).attr('name');
|
||||
var lines = '';
|
||||
tmp = $(content).find('>source[xmlns="urn:xmpp:jingle:apps:rtp:ssma:0"]');
|
||||
tmp.each(function () {
|
||||
var ssrc = $(this).attr('ssrc');
|
||||
$(this).find('>parameter').each(function () {
|
||||
lines += 'a=ssrc:' + ssrc + ' ' + $(this).attr('name');
|
||||
if ($(this).attr('value') && $(this).attr('value').length)
|
||||
lines += ':' + $(this).attr('value');
|
||||
lines += '\r\n';
|
||||
});
|
||||
});
|
||||
sdp.media.forEach(function(media, idx) {
|
||||
if (!SDPUtil.find_line(media, 'a=mid:' + name))
|
||||
return;
|
||||
sdp.media[idx] += lines;
|
||||
if (!self.addssrc[idx]) self.removessrc[idx] = '';
|
||||
self.removessrc[idx] += lines;
|
||||
});
|
||||
sdp.raw = sdp.session + sdp.media.join('');
|
||||
});
|
||||
this.modifySources();
|
||||
};
|
||||
|
||||
JingleSession.prototype.modifySources = function() {
|
||||
var self = this;
|
||||
if (!(this.addssrc.length || this.removessrc.length)) return;
|
||||
if (this.peerconnection.signalingState == 'closed') return;
|
||||
if (!(this.peerconnection.signalingState == 'stable' && this.peerconnection.iceConnectionState == 'connected')) {
|
||||
console.warn('modifySources not yet', this.peerconnection.signalingState, this.peerconnection.iceConnectionState);
|
||||
this.wait = true;
|
||||
window.setTimeout(function() { self.modifySources(); }, 250);
|
||||
return;
|
||||
}
|
||||
if (this.wait) {
|
||||
window.setTimeout(function() { self.modifySources(); }, 2500);
|
||||
this.wait = false;
|
||||
return;
|
||||
}
|
||||
|
||||
var sdp = new SDP(this.peerconnection.remoteDescription.sdp);
|
||||
|
||||
// add sources
|
||||
this.addssrc.forEach(function(lines, idx) {
|
||||
sdp.media[idx] += lines;
|
||||
});
|
||||
this.addssrc = [];
|
||||
|
||||
// remove sources
|
||||
this.removessrc.forEach(function(lines, idx) {
|
||||
lines = lines.split('\r\n');
|
||||
lines.pop(); // remove empty last element;
|
||||
lines.forEach(function(line) {
|
||||
sdp.media[idx] = sdp.media[idx].replace(line + '\r\n', '');
|
||||
});
|
||||
});
|
||||
this.removessrc = [];
|
||||
|
||||
sdp.raw = sdp.session + sdp.media.join('');
|
||||
this.peerconnection.setRemoteDescription(new RTCSessionDescription({type: 'offer', sdp: sdp.raw}),
|
||||
function() {
|
||||
self.peerconnection.createAnswer(
|
||||
function(modifiedAnswer) {
|
||||
self.peerconnection.setLocalDescription(modifiedAnswer,
|
||||
function() {
|
||||
//console.log('modified setLocalDescription ok');
|
||||
},
|
||||
function(error) {
|
||||
console.log('modified setLocalDescription failed');
|
||||
}
|
||||
);
|
||||
},
|
||||
function(error) {
|
||||
console.log('modified answer failed');
|
||||
}
|
||||
);
|
||||
},
|
||||
function(error) {
|
||||
console.log('modify failed');
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
JingleSession.prototype.sendMute = function (muted, content) {
|
||||
var info = $iq({to: this.peerjid,
|
||||
type: 'set'})
|
||||
.c('jingle', {xmlns: 'urn:xmpp:jingle:1',
|
||||
action: 'session-info',
|
||||
initiator: this.initiator,
|
||||
sid: this.sid });
|
||||
info.c(muted ? 'mute' : 'unmute', {xmlns: 'urn:xmpp:jingle:apps:rtp:info:1'});
|
||||
info.attrs({'creator': this.me == this.initiator ? 'creator' : 'responder'});
|
||||
if (content) {
|
||||
info.attrs({'name': content});
|
||||
}
|
||||
this.connection.send(info);
|
||||
};
|
||||
|
||||
JingleSession.prototype.sendRinging = function () {
|
||||
var info = $iq({to: this.peerjid,
|
||||
type: 'set'})
|
||||
.c('jingle', {xmlns: 'urn:xmpp:jingle:1',
|
||||
action: 'session-info',
|
||||
initiator: this.initiator,
|
||||
sid: this.sid });
|
||||
info.c('ringing', {xmlns: 'urn:xmpp:jingle:apps:rtp:info:1'});
|
||||
this.connection.send(info);
|
||||
};
|
||||
|
||||
JingleSession.prototype.getStats = function (interval) {
|
||||
var self = this;
|
||||
var recv = {audio: 0, video: 0};
|
||||
var lost = {audio: 0, video: 0};
|
||||
var lastrecv = {audio: 0, video: 0};
|
||||
var lastlost = {audio: 0, video: 0};
|
||||
var loss = {audio: 0, video: 0};
|
||||
var delta = {audio: 0, video: 0};
|
||||
this.statsinterval = window.setInterval(function () {
|
||||
if (self && self.peerconnection && self.peerconnection.getStats) {
|
||||
self.peerconnection.getStats(function (stats) {
|
||||
var results = stats.result();
|
||||
// TODO: there are so much statistics you can get from this..
|
||||
for (var i = 0; i < results.length; ++i) {
|
||||
if (results[i].type == 'ssrc') {
|
||||
var packetsrecv = results[i].stat('packetsReceived');
|
||||
var packetslost = results[i].stat('packetsLost');
|
||||
if (packetsrecv && packetslost) {
|
||||
packetsrecv = parseInt(packetsrecv, 10);
|
||||
packetslost = parseInt(packetslost, 10);
|
||||
|
||||
if (results[i].stat('googFrameRateReceived')) {
|
||||
lastlost.video = lost.video;
|
||||
lastrecv.video = recv.video;
|
||||
recv.video = packetsrecv;
|
||||
lost.video = packetslost;
|
||||
} else {
|
||||
lastlost.audio = lost.audio;
|
||||
lastrecv.audio = recv.audio;
|
||||
recv.audio = packetsrecv;
|
||||
lost.audio = packetslost;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
delta.audio = recv.audio - lastrecv.audio;
|
||||
delta.video = recv.video - lastrecv.video;
|
||||
loss.audio = (delta.audio > 0) ? Math.ceil(100 * (lost.audio - lastlost.audio) / delta.audio) : 0;
|
||||
loss.video = (delta.video > 0) ? Math.ceil(100 * (lost.video - lastlost.video) / delta.video) : 0;
|
||||
$(document).trigger('packetloss.jingle', [self.sid, loss]);
|
||||
});
|
||||
}
|
||||
}, interval || 3000);
|
||||
return this.statsinterval;
|
||||
};
|
||||
|
||||
}(jQuery));
|
||||
@@ -3,9 +3,10 @@
|
||||
* Klaus Herberth, 2014
|
||||
*/
|
||||
|
||||
// This code was written by Tyler Akins and has been placed in the
|
||||
// public domain. It would be nice if you left this header intact.
|
||||
// Base64 code from Tyler Akins -- http://rumkin.com
|
||||
/*! This code was written by Tyler Akins and has been placed in the
|
||||
public domain. It would be nice if you left this header intact.
|
||||
Base64 code from Tyler Akins -- http://rumkin.com
|
||||
*/
|
||||
|
||||
var Base64 = (function () {
|
||||
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
||||
@@ -84,7 +85,7 @@ var Base64 = (function () {
|
||||
return obj;
|
||||
})();
|
||||
|
||||
/*
|
||||
/*!
|
||||
* A JavaScript implementation of the Secure Hash Algorithm, SHA-1, as defined
|
||||
* in FIPS PUB 180-1
|
||||
* Version 2.1a Copyright Paul Johnston 2000 - 2002.
|
||||
@@ -261,7 +262,7 @@ function binb2b64(binarray)
|
||||
return str;
|
||||
}
|
||||
|
||||
/*
|
||||
/*!
|
||||
* A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
|
||||
* Digest Algorithm, as defined in RFC 1321.
|
||||
* Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
|
||||
@@ -469,7 +470,7 @@ var MD5 = (function () {
|
||||
return obj;
|
||||
})();
|
||||
|
||||
/*
|
||||
/*!
|
||||
This program is distributed under the terms of the MIT license.
|
||||
Please see the LICENSE file for details.
|
||||
|
||||
|
||||
@@ -353,7 +353,7 @@ Strophe.addConnectionPlugin('muc', {
|
||||
}).c("query", {
|
||||
xmlns: Strophe.NS.MUC_OWNER
|
||||
});
|
||||
if (config instanceof Form) {
|
||||
if (Strophe.x && config instanceof Strophe.x.Form) {
|
||||
config.type = "submit";
|
||||
iq.cnode(config.toXML());
|
||||
} else {
|
||||
@@ -1017,4 +1017,4 @@ Occupant = (function() {
|
||||
|
||||
return Occupant;
|
||||
|
||||
})();
|
||||
})();
|
||||
|
||||
@@ -0,0 +1,845 @@
|
||||
// Generated by CoffeeScript 1.8.0
|
||||
(function() {
|
||||
var $field, $form, $item, $opt, Field, Form, Item, Option, helper,
|
||||
__slice = [].slice,
|
||||
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },
|
||||
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };
|
||||
|
||||
helper = {
|
||||
fill: function(src, target, klass) {
|
||||
var f, _i, _len, _results;
|
||||
_results = [];
|
||||
for (_i = 0, _len = src.length; _i < _len; _i++) {
|
||||
f = src[_i];
|
||||
_results.push(target.push(f instanceof klass ? f : new klass(f)));
|
||||
}
|
||||
return _results;
|
||||
},
|
||||
createHtmlFieldCouple: function(f) {
|
||||
var div, id;
|
||||
div = $("<div>");
|
||||
id = "Strophe.x.Field-" + f.type + "-" + f["var"];
|
||||
div.append("<label for='" + id + "'>" + (f.label || '') + "</label>").append($(f.toHTML()).attr("id", id)).append("<br />");
|
||||
return div.children();
|
||||
},
|
||||
getHtmlFields: function(html) {
|
||||
html = $(html);
|
||||
return __slice.call(html.find("input")).concat(__slice.call(html.find("select")), __slice.call(html.find("textarea")));
|
||||
}
|
||||
};
|
||||
|
||||
Form = (function() {
|
||||
Form._types = ["form", "submit", "cancel", "result"];
|
||||
|
||||
function Form(opt) {
|
||||
this.toHTML = __bind(this.toHTML, this);
|
||||
this.toJSON = __bind(this.toJSON, this);
|
||||
this.toXML = __bind(this.toXML, this);
|
||||
var f, i, _i, _j, _len, _len1, _ref, _ref1, _ref2, _ref3;
|
||||
this.fields = [];
|
||||
this.items = [];
|
||||
this.reported = [];
|
||||
if (opt) {
|
||||
if (_ref = opt.type, __indexOf.call(Form._types, _ref) >= 0) {
|
||||
this.type = opt.type;
|
||||
}
|
||||
this.title = opt.title;
|
||||
this.instructions = opt.instructions;
|
||||
helper.fill = function(src, target, klass) {
|
||||
var f, _i, _len, _results;
|
||||
_results = [];
|
||||
for (_i = 0, _len = src.length; _i < _len; _i++) {
|
||||
f = src[_i];
|
||||
_results.push(target.push(f instanceof klass ? f : new klass(f)));
|
||||
}
|
||||
return _results;
|
||||
};
|
||||
if (opt.fields) {
|
||||
if (opt.fields) {
|
||||
helper.fill(opt.fields, this.fields, Field);
|
||||
}
|
||||
} else if (opt.items) {
|
||||
if (opt.items) {
|
||||
helper.fill(opt.items, this.items, Item);
|
||||
}
|
||||
_ref1 = this.items;
|
||||
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
|
||||
i = _ref1[_i];
|
||||
_ref2 = i.fields;
|
||||
for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
|
||||
f = _ref2[_j];
|
||||
if (!(_ref3 = f["var"], __indexOf.call(this.reported, _ref3) >= 0)) {
|
||||
this.reported.push(f["var"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Form.prototype.type = "form";
|
||||
|
||||
Form.prototype.title = null;
|
||||
|
||||
Form.prototype.instructions = null;
|
||||
|
||||
Form.prototype.toXML = function() {
|
||||
var f, i, r, xml, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2;
|
||||
xml = $build("x", {
|
||||
xmlns: "jabber:x:data",
|
||||
type: this.type
|
||||
});
|
||||
if (this.title) {
|
||||
xml.c("title").t(this.title.toString()).up();
|
||||
}
|
||||
if (this.instructions) {
|
||||
xml.c("instructions").t(this.instructions.toString()).up();
|
||||
}
|
||||
if (this.fields.length > 0) {
|
||||
_ref = this.fields;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
f = _ref[_i];
|
||||
xml.cnode(f.toXML()).up();
|
||||
}
|
||||
} else if (this.items.length > 0) {
|
||||
xml.c("reported");
|
||||
_ref1 = this.reported;
|
||||
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
|
||||
r = _ref1[_j];
|
||||
xml.c("field", {
|
||||
"var": r
|
||||
}).up();
|
||||
}
|
||||
xml.up();
|
||||
_ref2 = this.items;
|
||||
for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
|
||||
i = _ref2[_k];
|
||||
xml.cnode(i.toXML()).up();
|
||||
}
|
||||
}
|
||||
return xml.tree();
|
||||
};
|
||||
|
||||
Form.prototype.toJSON = function() {
|
||||
var f, i, json, _i, _j, _len, _len1, _ref, _ref1;
|
||||
json = {
|
||||
type: this.type
|
||||
};
|
||||
if (this.title) {
|
||||
json.title = this.title;
|
||||
}
|
||||
if (this.instructions) {
|
||||
json.instructions = this.instructions;
|
||||
}
|
||||
if (this.fields.length > 0) {
|
||||
json.fields = [];
|
||||
_ref = this.fields;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
f = _ref[_i];
|
||||
json.fields.push(f.toJSON());
|
||||
}
|
||||
} else if (this.items.length > 0) {
|
||||
json.items = [];
|
||||
json.reported = this.reported;
|
||||
_ref1 = this.items;
|
||||
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
|
||||
i = _ref1[_j];
|
||||
json.items.push(i.toJSON());
|
||||
}
|
||||
}
|
||||
return json;
|
||||
};
|
||||
|
||||
Form.prototype.toHTML = function() {
|
||||
var f, form, i, _i, _j, _len, _len1, _ref, _ref1;
|
||||
form = $("<form data-type='" + this.type + "'>");
|
||||
if (this.title) {
|
||||
form.append("<h1>" + this.title + "</h1>");
|
||||
}
|
||||
if (this.instructions) {
|
||||
form.append("<p>" + this.instructions + "</p>");
|
||||
}
|
||||
if (this.fields.length > 0) {
|
||||
_ref = this.fields;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
f = _ref[_i];
|
||||
(helper.createHtmlFieldCouple(f)).appendTo(form);
|
||||
}
|
||||
} else if (this.items.length > 0) {
|
||||
_ref1 = this.items;
|
||||
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
|
||||
i = _ref1[_j];
|
||||
($(i.toHTML())).appendTo(form);
|
||||
}
|
||||
}
|
||||
return form[0];
|
||||
};
|
||||
|
||||
Form.fromXML = function(xml) {
|
||||
var f, fields, i, instr, items, j, r, reported, title;
|
||||
xml = $(xml);
|
||||
f = new Form({
|
||||
type: xml.attr("type")
|
||||
});
|
||||
title = xml.find("title");
|
||||
if (title.length === 1) {
|
||||
f.title = title.text();
|
||||
}
|
||||
instr = xml.find("instructions");
|
||||
if (instr.length === 1) {
|
||||
f.instructions = instr.text();
|
||||
}
|
||||
fields = xml.find("field");
|
||||
items = xml.find("item");
|
||||
if (items.length > 0) {
|
||||
f.items = (function() {
|
||||
var _i, _len, _results;
|
||||
_results = [];
|
||||
for (_i = 0, _len = items.length; _i < _len; _i++) {
|
||||
i = items[_i];
|
||||
_results.push(Item.fromXML(i));
|
||||
}
|
||||
return _results;
|
||||
})();
|
||||
} else if (fields.length > 0) {
|
||||
f.fields = (function() {
|
||||
var _i, _len, _results;
|
||||
_results = [];
|
||||
for (_i = 0, _len = fields.length; _i < _len; _i++) {
|
||||
j = fields[_i];
|
||||
_results.push(Field.fromXML(j));
|
||||
}
|
||||
return _results;
|
||||
})();
|
||||
}
|
||||
reported = xml.find("reported");
|
||||
if (reported.length === 1) {
|
||||
fields = reported.find("field");
|
||||
f.reported = (function() {
|
||||
var _i, _len, _results;
|
||||
_results = [];
|
||||
for (_i = 0, _len = fields.length; _i < _len; _i++) {
|
||||
r = fields[_i];
|
||||
_results.push(($(r)).attr("var"));
|
||||
}
|
||||
return _results;
|
||||
})();
|
||||
}
|
||||
return f;
|
||||
};
|
||||
|
||||
Form.fromHTML = function(html) {
|
||||
var f, field, fields, i, instructions, item, items, j, title, _i, _j, _len, _len1, _ref, _ref1, _ref2;
|
||||
html = $(html);
|
||||
f = new Form({
|
||||
type: html.attr("data-type")
|
||||
});
|
||||
title = html.find("h1").text();
|
||||
if (title) {
|
||||
f.title = title;
|
||||
}
|
||||
instructions = html.find("p").text();
|
||||
if (instructions) {
|
||||
f.instructions = instructions;
|
||||
}
|
||||
items = html.find("fieldset");
|
||||
fields = helper.getHtmlFields(html);
|
||||
if (items.length > 0) {
|
||||
f.items = (function() {
|
||||
var _i, _len, _results;
|
||||
_results = [];
|
||||
for (_i = 0, _len = items.length; _i < _len; _i++) {
|
||||
i = items[_i];
|
||||
_results.push(Item.fromHTML(i));
|
||||
}
|
||||
return _results;
|
||||
})();
|
||||
_ref = f.items;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
item = _ref[_i];
|
||||
_ref1 = item.fields;
|
||||
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
|
||||
field = _ref1[_j];
|
||||
if (!(_ref2 = field["var"], __indexOf.call(f.reported, _ref2) >= 0)) {
|
||||
f.reported.push(field["var"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (fields.length > 0) {
|
||||
f.fields = (function() {
|
||||
var _k, _len2, _results;
|
||||
_results = [];
|
||||
for (_k = 0, _len2 = fields.length; _k < _len2; _k++) {
|
||||
j = fields[_k];
|
||||
_results.push(Field.fromHTML(j));
|
||||
}
|
||||
return _results;
|
||||
})();
|
||||
}
|
||||
return f;
|
||||
};
|
||||
|
||||
return Form;
|
||||
|
||||
})();
|
||||
|
||||
Field = (function() {
|
||||
Field._types = ["boolean", "fixed", "hidden", "jid-multi", "jid-single", "list-multi", "list-single", "text-multi", "text-private", "text-single"];
|
||||
|
||||
Field._multiTypes = ["list-multi", "jid-multi", "text-multi", "hidden"];
|
||||
|
||||
function Field(opt) {
|
||||
this.toHTML = __bind(this.toHTML, this);
|
||||
this.toXML = __bind(this.toXML, this);
|
||||
this.toJSON = __bind(this.toJSON, this);
|
||||
this.addOptions = __bind(this.addOptions, this);
|
||||
this.addOption = __bind(this.addOption, this);
|
||||
this.addValues = __bind(this.addValues, this);
|
||||
this.addValue = __bind(this.addValue, this);
|
||||
var _ref, _ref1;
|
||||
this.options = [];
|
||||
this.values = [];
|
||||
if (opt) {
|
||||
if (_ref = opt.type, __indexOf.call(Field._types, _ref) >= 0) {
|
||||
this.type = opt.type.toString();
|
||||
}
|
||||
if (opt.desc) {
|
||||
this.desc = opt.desc.toString();
|
||||
}
|
||||
if (opt.label) {
|
||||
this.label = opt.label.toString();
|
||||
}
|
||||
this["var"] = ((_ref1 = opt["var"]) != null ? _ref1.toString() : void 0) || "_no_var_was_defined_";
|
||||
this.required = opt.required === true || opt.required === "true";
|
||||
if (opt.options) {
|
||||
this.addOptions(opt.options);
|
||||
}
|
||||
if (opt.value) {
|
||||
opt.values = [opt.value];
|
||||
}
|
||||
if (opt.values) {
|
||||
this.addValues(opt.values);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Field.prototype.type = "text-single";
|
||||
|
||||
Field.prototype.desc = null;
|
||||
|
||||
Field.prototype.label = null;
|
||||
|
||||
Field.prototype["var"] = "_no_var_was_defined_";
|
||||
|
||||
Field.prototype.required = false;
|
||||
|
||||
Field.prototype.addValue = function(val) {
|
||||
return this.addValues([val]);
|
||||
};
|
||||
|
||||
Field.prototype.addValues = function(vals) {
|
||||
var multi, v, _ref;
|
||||
multi = (_ref = this.type, __indexOf.call(Field._multiTypes, _ref) >= 0);
|
||||
if (multi || (!multi && vals.length === 1)) {
|
||||
this.values = __slice.call(this.values).concat(__slice.call((function() {
|
||||
var _i, _len, _results;
|
||||
_results = [];
|
||||
for (_i = 0, _len = vals.length; _i < _len; _i++) {
|
||||
v = vals[_i];
|
||||
_results.push(v.toString());
|
||||
}
|
||||
return _results;
|
||||
})()));
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
Field.prototype.addOption = function(opt) {
|
||||
return this.addOptions([opt]);
|
||||
};
|
||||
|
||||
Field.prototype.addOptions = function(opts) {
|
||||
var o;
|
||||
if (this.type === "list-single" || this.type === "list-multi") {
|
||||
if (typeof opts[0] !== "object") {
|
||||
opts = (function() {
|
||||
var _i, _len, _results;
|
||||
_results = [];
|
||||
for (_i = 0, _len = opts.length; _i < _len; _i++) {
|
||||
o = opts[_i];
|
||||
_results.push(new Option({
|
||||
value: o.toString()
|
||||
}));
|
||||
}
|
||||
return _results;
|
||||
})();
|
||||
}
|
||||
helper.fill(opts, this.options, Option);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
Field.prototype.toJSON = function() {
|
||||
var json, o, _i, _len, _ref;
|
||||
json = {
|
||||
type: this.type,
|
||||
"var": this["var"],
|
||||
required: this.required
|
||||
};
|
||||
if (this.desc) {
|
||||
json.desc = this.desc;
|
||||
}
|
||||
if (this.label) {
|
||||
json.label = this.label;
|
||||
}
|
||||
if (this.values) {
|
||||
json.values = this.values;
|
||||
}
|
||||
if (this.options) {
|
||||
json.options = [];
|
||||
_ref = this.options;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
o = _ref[_i];
|
||||
json.options.push(o.toJSON());
|
||||
}
|
||||
}
|
||||
return json;
|
||||
};
|
||||
|
||||
Field.prototype.toXML = function() {
|
||||
var attrs, o, v, xml, _i, _j, _len, _len1, _ref, _ref1;
|
||||
attrs = {
|
||||
type: this.type,
|
||||
"var": this["var"]
|
||||
};
|
||||
if (this.label) {
|
||||
attrs.label = this.label;
|
||||
}
|
||||
xml = $build("field", attrs);
|
||||
if (this.desc) {
|
||||
xml.c("desc").t(this.desc).up();
|
||||
}
|
||||
if (this.required) {
|
||||
xml.c("required").up();
|
||||
}
|
||||
if (this.values) {
|
||||
_ref = this.values;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
v = _ref[_i];
|
||||
xml.c("value").t(v.toString()).up();
|
||||
}
|
||||
}
|
||||
if (this.options) {
|
||||
_ref1 = this.options;
|
||||
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
|
||||
o = _ref1[_j];
|
||||
xml.cnode(o.toXML()).up();
|
||||
}
|
||||
}
|
||||
return xml.tree();
|
||||
};
|
||||
|
||||
Field.prototype.toHTML = function() {
|
||||
var el, k, line, o, opt, txt, val, _i, _j, _len, _len1, _ref, _ref1, _ref2;
|
||||
switch (this.type.toLowerCase()) {
|
||||
case 'list-single':
|
||||
case 'list-multi':
|
||||
el = $("<select>");
|
||||
if (this.type === 'list-multi') {
|
||||
el.attr('multiple', 'multiple');
|
||||
}
|
||||
if (this.options.length > 0) {
|
||||
_ref = this.options;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
opt = _ref[_i];
|
||||
if (!(opt)) {
|
||||
continue;
|
||||
}
|
||||
o = $(opt.toHTML());
|
||||
_ref1 = this.values;
|
||||
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
|
||||
k = _ref1[_j];
|
||||
if (k.toString() === opt.value.toString()) {
|
||||
o.attr('selected', 'selected');
|
||||
}
|
||||
}
|
||||
o.appendTo(el);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'text-multi':
|
||||
case 'jid-multi':
|
||||
el = $("<textarea>");
|
||||
txt = ((function() {
|
||||
var _k, _len2, _ref2, _results;
|
||||
_ref2 = this.values;
|
||||
_results = [];
|
||||
for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
|
||||
line = _ref2[_k];
|
||||
_results.push(line);
|
||||
}
|
||||
return _results;
|
||||
}).call(this)).join('\n');
|
||||
if (txt) {
|
||||
el.text(txt);
|
||||
}
|
||||
break;
|
||||
case 'text-single':
|
||||
case 'boolean':
|
||||
case 'text-private':
|
||||
case 'hidden':
|
||||
case 'fixed':
|
||||
case 'jid-single':
|
||||
el = $("<input>");
|
||||
if (this.values) {
|
||||
el.val(this.values[0]);
|
||||
}
|
||||
switch (this.type.toLowerCase()) {
|
||||
case 'text-single':
|
||||
el.attr('type', 'text');
|
||||
el.attr('placeholder', this.desc);
|
||||
break;
|
||||
case 'boolean':
|
||||
el.attr('type', 'checkbox');
|
||||
val = (_ref2 = this.values[0]) != null ? typeof _ref2.toString === "function" ? _ref2.toString() : void 0 : void 0;
|
||||
if (val && (val === "true" || val === "1")) {
|
||||
el.attr('checked', 'checked');
|
||||
}
|
||||
break;
|
||||
case 'text-private':
|
||||
el.attr('type', 'password');
|
||||
break;
|
||||
case 'hidden':
|
||||
el.attr('type', 'hidden');
|
||||
break;
|
||||
case 'fixed':
|
||||
el.attr('type', 'text').attr('readonly', 'readonly');
|
||||
break;
|
||||
case 'jid-single':
|
||||
el.attr('type', 'email');
|
||||
}
|
||||
break;
|
||||
default:
|
||||
el = $("<input type='text'>");
|
||||
}
|
||||
el.attr('name', this["var"]);
|
||||
if (this.required) {
|
||||
el.attr('required', this.required);
|
||||
}
|
||||
return el[0];
|
||||
};
|
||||
|
||||
Field.fromXML = function(xml) {
|
||||
var o, v;
|
||||
xml = $(xml);
|
||||
return new Field({
|
||||
type: xml.attr("type"),
|
||||
"var": xml.attr("var"),
|
||||
label: xml.attr("label"),
|
||||
desc: xml.find("desc").text(),
|
||||
required: xml.find("required").length === 1,
|
||||
values: (function() {
|
||||
var _i, _len, _ref, _results;
|
||||
_ref = xml.find(">value");
|
||||
_results = [];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
v = _ref[_i];
|
||||
_results.push(($(v)).text());
|
||||
}
|
||||
return _results;
|
||||
})(),
|
||||
options: (function() {
|
||||
var _i, _len, _ref, _results;
|
||||
_ref = xml.find("option");
|
||||
_results = [];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
o = _ref[_i];
|
||||
_results.push(Option.fromXML(o));
|
||||
}
|
||||
return _results;
|
||||
})()
|
||||
});
|
||||
};
|
||||
|
||||
Field._htmlElementToFieldType = function(el) {
|
||||
var r, type;
|
||||
el = $(el);
|
||||
switch (el[0].nodeName.toLowerCase()) {
|
||||
case "textarea":
|
||||
type = "text-multi";
|
||||
break;
|
||||
case "select":
|
||||
if (el.attr("multiple") === "multiple") {
|
||||
type = "list-multi";
|
||||
} else {
|
||||
type = "list-single";
|
||||
}
|
||||
break;
|
||||
case "input":
|
||||
switch (el.attr("type")) {
|
||||
case "checkbox":
|
||||
type = "boolean";
|
||||
break;
|
||||
case "email":
|
||||
type = "jid-single";
|
||||
break;
|
||||
case "hidden":
|
||||
type = "hidden";
|
||||
break;
|
||||
case "password":
|
||||
type = "text-private";
|
||||
break;
|
||||
case "text":
|
||||
r = el.attr("readonly") === "readonly";
|
||||
if (r) {
|
||||
type = "fixed";
|
||||
} else {
|
||||
type = "text-single";
|
||||
}
|
||||
}
|
||||
}
|
||||
return type;
|
||||
};
|
||||
|
||||
Field.fromHTML = function(html) {
|
||||
var el, f, txt, type;
|
||||
html = $(html);
|
||||
type = Field._htmlElementToFieldType(html);
|
||||
f = new Field({
|
||||
type: type,
|
||||
"var": html.attr("name"),
|
||||
required: html.attr("required") === "required"
|
||||
});
|
||||
switch (type) {
|
||||
case "list-multi":
|
||||
case "list-single":
|
||||
f.values = (function() {
|
||||
var _i, _len, _ref, _results;
|
||||
_ref = html.find("option:selected");
|
||||
_results = [];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
el = _ref[_i];
|
||||
_results.push(($(el)).val());
|
||||
}
|
||||
return _results;
|
||||
})();
|
||||
f.options = (function() {
|
||||
var _i, _len, _ref, _results;
|
||||
_ref = html.find("option");
|
||||
_results = [];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
el = _ref[_i];
|
||||
_results.push(Option.fromHTML(el));
|
||||
}
|
||||
return _results;
|
||||
})();
|
||||
break;
|
||||
case "text-multi":
|
||||
case "jid-multi":
|
||||
txt = html.text();
|
||||
if (txt.trim() !== "") {
|
||||
f.values = txt.split('\n');
|
||||
}
|
||||
break;
|
||||
case 'text-single':
|
||||
case 'boolean':
|
||||
case 'text-private':
|
||||
case 'hidden':
|
||||
case 'fixed':
|
||||
case 'jid-single':
|
||||
if (html.val().trim() !== "") {
|
||||
f.values = [html.val()];
|
||||
}
|
||||
}
|
||||
return f;
|
||||
};
|
||||
|
||||
return Field;
|
||||
|
||||
})();
|
||||
|
||||
Option = (function() {
|
||||
function Option(opt) {
|
||||
this.toHTML = __bind(this.toHTML, this);
|
||||
this.toJSON = __bind(this.toJSON, this);
|
||||
this.toXML = __bind(this.toXML, this);
|
||||
if (opt) {
|
||||
if (opt.label) {
|
||||
this.label = opt.label.toString();
|
||||
}
|
||||
if (opt.value) {
|
||||
this.value = opt.value.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Option.prototype.label = "";
|
||||
|
||||
Option.prototype.value = "";
|
||||
|
||||
Option.prototype.toXML = function() {
|
||||
return $build("option", {
|
||||
label: this.label
|
||||
}).c("value").t(this.value.toString()).tree();
|
||||
};
|
||||
|
||||
Option.prototype.toJSON = function() {
|
||||
return {
|
||||
label: this.label,
|
||||
value: this.value
|
||||
};
|
||||
};
|
||||
|
||||
Option.prototype.toHTML = function() {
|
||||
return ($("<option>")).attr('value', this.value).text(this.label || this.value)[0];
|
||||
};
|
||||
|
||||
Option.fromXML = function(xml) {
|
||||
return new Option({
|
||||
label: ($(xml)).attr("label"),
|
||||
value: ($(xml)).text()
|
||||
});
|
||||
};
|
||||
|
||||
Option.fromHTML = function(html) {
|
||||
return new Option({
|
||||
value: ($(html)).attr("value"),
|
||||
label: ($(html)).text()
|
||||
});
|
||||
};
|
||||
|
||||
return Option;
|
||||
|
||||
})();
|
||||
|
||||
Item = (function() {
|
||||
function Item(opts) {
|
||||
this.toHTML = __bind(this.toHTML, this);
|
||||
this.toJSON = __bind(this.toJSON, this);
|
||||
this.toXML = __bind(this.toXML, this);
|
||||
this.fields = [];
|
||||
if (opts != null ? opts.fields : void 0) {
|
||||
helper.fill(opts.fields, this.fields, Field);
|
||||
}
|
||||
}
|
||||
|
||||
Item.prototype.toXML = function() {
|
||||
var f, xml, _i, _len, _ref;
|
||||
xml = $build("item");
|
||||
_ref = this.fields;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
f = _ref[_i];
|
||||
xml.cnode(f.toXML()).up();
|
||||
}
|
||||
return xml.tree();
|
||||
};
|
||||
|
||||
Item.prototype.toJSON = function() {
|
||||
var f, json, _i, _len, _ref;
|
||||
json = {};
|
||||
if (this.fields) {
|
||||
json.fields = [];
|
||||
_ref = this.fields;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
f = _ref[_i];
|
||||
json.fields.push(f.toJSON());
|
||||
}
|
||||
}
|
||||
return json;
|
||||
};
|
||||
|
||||
Item.prototype.toHTML = function() {
|
||||
var f, fieldset, _i, _len, _ref;
|
||||
fieldset = $("<fieldset>");
|
||||
_ref = this.fields;
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
f = _ref[_i];
|
||||
(helper.createHtmlFieldCouple(f)).appendTo(fieldset);
|
||||
}
|
||||
return fieldset[0];
|
||||
};
|
||||
|
||||
Item.fromXML = function(xml) {
|
||||
var f, fields;
|
||||
xml = $(xml);
|
||||
fields = xml.find("field");
|
||||
return new Item({
|
||||
fields: (function() {
|
||||
var _i, _len, _results;
|
||||
_results = [];
|
||||
for (_i = 0, _len = fields.length; _i < _len; _i++) {
|
||||
f = fields[_i];
|
||||
_results.push(Field.fromXML(f));
|
||||
}
|
||||
return _results;
|
||||
})()
|
||||
});
|
||||
};
|
||||
|
||||
Item.fromHTML = function(html) {
|
||||
var f;
|
||||
return new Item({
|
||||
fields: (function() {
|
||||
var _i, _len, _ref, _results;
|
||||
_ref = helper.getHtmlFields(html);
|
||||
_results = [];
|
||||
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
|
||||
f = _ref[_i];
|
||||
_results.push(Field.fromHTML(f));
|
||||
}
|
||||
return _results;
|
||||
})()
|
||||
});
|
||||
};
|
||||
|
||||
return Item;
|
||||
|
||||
})();
|
||||
|
||||
Strophe.x = {
|
||||
Form: Form,
|
||||
Field: Field,
|
||||
Option: Option,
|
||||
Item: Item
|
||||
};
|
||||
|
||||
$form = function(opt) {
|
||||
return new Strophe.x.Form(opt);
|
||||
};
|
||||
|
||||
$field = function(opt) {
|
||||
return new Strophe.x.Field(opt);
|
||||
};
|
||||
|
||||
$opt = function(opt) {
|
||||
return new Strophe.x.Option(opt);
|
||||
};
|
||||
|
||||
$item = function(opts) {
|
||||
return new Strophe.x.Item(opts);
|
||||
};
|
||||
|
||||
Strophe.addConnectionPlugin('x', {
|
||||
init: function(conn) {
|
||||
var _ref, _ref1;
|
||||
Strophe.addNamespace('DATA', 'jabber:x:data');
|
||||
if (((_ref = conn.disco) != null ? _ref.addFeature : void 0) != null) {
|
||||
conn.disco.addFeature(Strophe.NS.DATA);
|
||||
}
|
||||
if (((_ref1 = conn.disco) != null ? _ref1.addNode : void 0) != null) {
|
||||
return conn.disco.addNode(Strophe.NS.DATA, {
|
||||
items: []
|
||||
});
|
||||
}
|
||||
},
|
||||
parseFromResult: function(result) {
|
||||
var _ref;
|
||||
if (result.nodeName.toLowerCase() === "x") {
|
||||
return Form.fromXML(result);
|
||||
} else {
|
||||
return Form.fromXML((_ref = ($(result)).find("x")) != null ? _ref[0] : void 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}).call(this);
|
||||
@@ -0,0 +1,104 @@
|
||||
[
|
||||
{
|
||||
"name": "strophe.js",
|
||||
"file": "lib/strophe.js",
|
||||
"license": "multiple",
|
||||
"url": "http://strophe.im/strophejs/"
|
||||
},
|
||||
{
|
||||
"name": "strophe.js/muc",
|
||||
"file": "lib/strophe.muc.js",
|
||||
"license": "MIT",
|
||||
"url": "https://github.com/strophe/strophejs-plugins"
|
||||
},
|
||||
{
|
||||
"name": "strophe.js/disco",
|
||||
"file": "lib/strophe.disco.js",
|
||||
"license": "MIT",
|
||||
"url": "https://github.com/strophe/strophejs-plugins"
|
||||
},
|
||||
{
|
||||
"name": "strophe.js/caps",
|
||||
"file": "lib/strophe.caps.js",
|
||||
"license": "MIT",
|
||||
"url": "https://github.com/strophe/strophejs-plugins"
|
||||
},
|
||||
{
|
||||
"name": "strophe.js/vcard",
|
||||
"file": "lib/strophe.vcard.js",
|
||||
"license": "MIT",
|
||||
"url": "https://github.com/strophe/strophejs-plugins"
|
||||
},
|
||||
{
|
||||
"name": "strophe.js/bookmarks",
|
||||
"file": "lib/strophe.bookmarks/index.js",
|
||||
"license": "MIT",
|
||||
"url": "https://github.com/strophe/strophejs-plugins/tree/master/bookmarks"
|
||||
},
|
||||
{
|
||||
"name": "strophe.js/x",
|
||||
"file": "lib/strophe.x/index.js",
|
||||
"license": "MIT",
|
||||
"url": "https://github.com/strophe/strophejs-plugins/tree/master/dataforms"
|
||||
},
|
||||
{
|
||||
"name": "strophe.jinglejs",
|
||||
"file": "lib/strophe.jinglejs/strophe.jinglejs-bundle.js",
|
||||
"license": "MIT",
|
||||
"url": "https://github.com/sualko/strophe.jinglejs"
|
||||
},
|
||||
{
|
||||
"name": "Salsa20",
|
||||
"file": "lib/otr/build/dep/salsa20.js",
|
||||
"license": "AGPL3",
|
||||
"url": "https://github.com/neoatlantis/node-salsa20"
|
||||
},
|
||||
{
|
||||
"name": "bigint",
|
||||
"file": "lib/otr/build/dep/bigint.js",
|
||||
"license": "public domain",
|
||||
"url": "www.leemon.com"
|
||||
},
|
||||
{
|
||||
"name": "cryptojs",
|
||||
"file": "lib/otr/build/dep/crypto.js",
|
||||
"license": "code.google.com/p/crypto-js/wiki/license",
|
||||
"url": "code.google.com/p/crypto-js"
|
||||
},
|
||||
{
|
||||
"name": "eventemitter",
|
||||
"file": "lib/otr/build/dep/eventemitter.js",
|
||||
"license": "MIT",
|
||||
"url": "http://git.io/ee"
|
||||
},
|
||||
{
|
||||
"name": "otr.js",
|
||||
"file": "lib/otr/build/otr.js",
|
||||
"license": "MPL v2.0",
|
||||
"url": "https://arlolra.github.io/otr/"
|
||||
},
|
||||
{
|
||||
"name": "i18next",
|
||||
"file": "lib/i18next/release/i18next-latest.min.js",
|
||||
"license": "MIT",
|
||||
"url": "http://i18next.com/"
|
||||
},
|
||||
{
|
||||
"name": "Magnific Popup",
|
||||
"file": "lib/magnific-popup/dist/jquery.magnific-popup.min.js",
|
||||
"license": "MIT",
|
||||
"url": "http://dimsemenov.com/plugins/magnific-popup/"
|
||||
},
|
||||
{
|
||||
"name": null,
|
||||
"file": "lib/translation.js",
|
||||
"license": "MIT",
|
||||
"url": "https://webtranslateit.com/en/projects/10365-JSXC"
|
||||
},
|
||||
{
|
||||
"name": "favico.js",
|
||||
"file": "lib/favico.js/favico.js",
|
||||
"license": "MIT",
|
||||
"url": "https://github.com/ejci/favico.js"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,353 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>JSDoc: Global</title>
|
||||
|
||||
<script src="scripts/prettify/prettify.js"> </script>
|
||||
<script src="scripts/prettify/lang-css.js"> </script>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
|
||||
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="main">
|
||||
|
||||
<h1 class="page-title">Global</h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<section>
|
||||
|
||||
<header>
|
||||
<h2>
|
||||
|
||||
</h2>
|
||||
|
||||
</header>
|
||||
|
||||
<article>
|
||||
<div class="container-overview">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dl class="details">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3 class="subsection-title">Type Definitions</h3>
|
||||
|
||||
<dl>
|
||||
|
||||
<dt>
|
||||
<h4 class="name" id="getUsers-cb"><span class="type-signature"></span>getUsers-cb<span class="signature">(list)</span><span class="type-signature"></span></h4>
|
||||
|
||||
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
<div class="description">
|
||||
Processes user list.
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h5>Parameters:</h5>
|
||||
|
||||
|
||||
<table class="params">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
<th>Name</th>
|
||||
|
||||
|
||||
<th>Type</th>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<th class="last">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="name"><code>list</code></td>
|
||||
|
||||
|
||||
<td class="type">
|
||||
|
||||
|
||||
<span class="param-type">object</span>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<td class="description last">List of users, key: username, value: alias</td>
|
||||
</tr>
|
||||
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
<dl class="details">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="jsxc.lib.options.js.html">jsxc.lib.options.js</a>, <a href="jsxc.lib.options.js.html#line187">line 187</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
|
||||
|
||||
|
||||
<dt>
|
||||
<h4 class="name" id="loadSettingsCallback"><span class="type-signature"></span>loadSettingsCallback<span class="signature">(settings)</span><span class="type-signature"></span></h4>
|
||||
|
||||
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
<div class="description">
|
||||
This callback processes all settings.
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h5>Parameters:</h5>
|
||||
|
||||
|
||||
<table class="params">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
<th>Name</th>
|
||||
|
||||
|
||||
<th>Type</th>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<th class="last">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="name"><code>settings</code></td>
|
||||
|
||||
|
||||
<td class="type">
|
||||
|
||||
|
||||
<span class="param-type">object</span>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<td class="description last">could be every jsxc option</td>
|
||||
</tr>
|
||||
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
<dl class="details">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="jsxc.lib.options.js.html">jsxc.lib.options.js</a>, <a href="jsxc.lib.options.js.html#line154">line 154</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
</article>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<nav>
|
||||
<h2><a href="index.html">Index</a></h2><h3>Namespaces</h3><ul><li><a href="jsxc.html">jsxc</a></li><li><a href="jsxc.gui.html">gui</a></li><li><a href="jsxc.gui.dialog.html">dialog</a></li><li><a href="jsxc.gui.queryActions.html">queryActions</a></li><li><a href="jsxc.gui.roster.html">roster</a></li><li><a href="jsxc.gui.window.html">window</a></li><li><a href="jsxc.muc.html">muc</a></li><li><a href="jsxc.notification.html">notification</a></li><li><a href="jsxc.options.html">options</a></li><li><a href="jsxc.otr.html">otr</a></li><li><a href="jsxc.storage.html">storage</a></li><li><a href="jsxc.webrtc.html">webrtc</a></li><li><a href="jsxc.xmpp.html">xmpp</a></li><li><a href="jsxc.xmpp.bookmarks.html">bookmarks</a></li><li><a href="jsxc.xmpp.carbons.html">carbons</a></li></ul><h3><a href="global.html">Global</a></h3>
|
||||
</nav>
|
||||
|
||||
<br clear="both">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.2.2</a> on Thu Sep 10 2015 11:03:21 GMT+0200 (CEST)
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
<script src="scripts/linenumber.js"> </script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,63 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>JSDoc: Index</title>
|
||||
|
||||
<script src="scripts/prettify/prettify.js"> </script>
|
||||
<script src="scripts/prettify/lang-css.js"> </script>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
|
||||
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="main">
|
||||
|
||||
<h1 class="page-title">Index</h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3> </h3>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<nav>
|
||||
<h2><a href="index.html">Index</a></h2><h3>Namespaces</h3><ul><li><a href="jsxc.html">jsxc</a></li><li><a href="jsxc.gui.html">gui</a></li><li><a href="jsxc.gui.dialog.html">dialog</a></li><li><a href="jsxc.gui.queryActions.html">queryActions</a></li><li><a href="jsxc.gui.roster.html">roster</a></li><li><a href="jsxc.gui.window.html">window</a></li><li><a href="jsxc.muc.html">muc</a></li><li><a href="jsxc.notification.html">notification</a></li><li><a href="jsxc.options.html">options</a></li><li><a href="jsxc.otr.html">otr</a></li><li><a href="jsxc.storage.html">storage</a></li><li><a href="jsxc.webrtc.html">webrtc</a></li><li><a href="jsxc.xmpp.html">xmpp</a></li><li><a href="jsxc.xmpp.bookmarks.html">bookmarks</a></li><li><a href="jsxc.xmpp.carbons.html">carbons</a></li></ul><h3><a href="global.html">Global</a></h3>
|
||||
</nav>
|
||||
|
||||
<br clear="both">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.2.2</a> on Thu Sep 10 2015 11:03:21 GMT+0200 (CEST)
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
<script src="scripts/linenumber.js"> </script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,556 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>JSDoc: Namespace: dialog</title>
|
||||
|
||||
<script src="scripts/prettify/prettify.js"> </script>
|
||||
<script src="scripts/prettify/lang-css.js"> </script>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
|
||||
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="main">
|
||||
|
||||
<h1 class="page-title">Namespace: dialog</h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<section>
|
||||
|
||||
<header>
|
||||
<h2>
|
||||
<span class="ancestors"><a href="jsxc.html">jsxc</a><a href="jsxc.gui.html">.gui</a>.</span>
|
||||
|
||||
dialog
|
||||
</h2>
|
||||
|
||||
</header>
|
||||
|
||||
<article>
|
||||
<div class="container-overview">
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="description">Wrapper for dialog</div>
|
||||
|
||||
|
||||
|
||||
<dl class="details">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="jsxc.lib.gui.js.html">jsxc.lib.gui.js</a>, <a href="jsxc.lib.gui.js.html#line1765">line 1765</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3 class="subsection-title">Methods</h3>
|
||||
|
||||
<dl>
|
||||
|
||||
<dt>
|
||||
<h4 class="name" id="close"><span class="type-signature"><static> </span>close<span class="signature">()</span><span class="type-signature"></span></h4>
|
||||
|
||||
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
<div class="description">
|
||||
Close current dialog.
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dl class="details">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="jsxc.lib.gui.js.html">jsxc.lib.gui.js</a>, <a href="jsxc.lib.gui.js.html#line1843">line 1843</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
|
||||
|
||||
|
||||
<dt>
|
||||
<h4 class="name" id="open"><span class="type-signature"><static> </span>open<span class="signature">(data, <span class="optional">o</span>)</span><span class="type-signature"> → {jQuery}</span></h4>
|
||||
|
||||
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
<div class="description">
|
||||
Open a Dialog.
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h5>Parameters:</h5>
|
||||
|
||||
|
||||
<table class="params">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
<th>Name</th>
|
||||
|
||||
|
||||
<th>Type</th>
|
||||
|
||||
|
||||
<th>Argument</th>
|
||||
|
||||
|
||||
|
||||
|
||||
<th class="last">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="name"><code>data</code></td>
|
||||
|
||||
|
||||
<td class="type">
|
||||
|
||||
|
||||
<span class="param-type">String</span>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
<td class="attributes">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
<td class="description last">Data of the dialog</td>
|
||||
</tr>
|
||||
|
||||
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="name"><code>o</code></td>
|
||||
|
||||
|
||||
<td class="type">
|
||||
|
||||
|
||||
<span class="param-type">Object</span>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
<td class="attributes">
|
||||
|
||||
<optional><br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
<td class="description last">Options for the dialog
|
||||
<h6>Properties</h6>
|
||||
|
||||
|
||||
<table class="params">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
<th>Name</th>
|
||||
|
||||
|
||||
<th>Type</th>
|
||||
|
||||
|
||||
<th>Argument</th>
|
||||
|
||||
|
||||
|
||||
|
||||
<th class="last">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="name"><code>noClose</code></td>
|
||||
|
||||
|
||||
<td class="type">
|
||||
|
||||
|
||||
<span class="param-type">Boolean</span>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
<td class="attributes">
|
||||
|
||||
<optional><br>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
<td class="description last">If true, hide all default close options</td>
|
||||
</tr>
|
||||
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
<dl class="details">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="jsxc.lib.gui.js.html">jsxc.lib.gui.js</a>, <a href="jsxc.lib.gui.js.html#line1780">line 1780</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h5>Returns:</h5>
|
||||
|
||||
|
||||
<div class="param-desc">
|
||||
Dialog object
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<dl>
|
||||
<dt>
|
||||
Type
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
<span class="param-type">jQuery</span>
|
||||
|
||||
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
|
||||
|
||||
|
||||
<dt>
|
||||
<h4 class="name" id="resize"><span class="type-signature"><static> </span>resize<span class="signature">(options)</span><span class="type-signature"></span></h4>
|
||||
|
||||
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
<div class="description">
|
||||
Resizes current dialog.
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h5>Parameters:</h5>
|
||||
|
||||
|
||||
<table class="params">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
<th>Name</th>
|
||||
|
||||
|
||||
<th>Type</th>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<th class="last">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="name"><code>options</code></td>
|
||||
|
||||
|
||||
<td class="type">
|
||||
|
||||
|
||||
<span class="param-type">Object</span>
|
||||
|
||||
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<td class="description last">e.g. width and height</td>
|
||||
</tr>
|
||||
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
<dl class="details">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="jsxc.lib.gui.js.html">jsxc.lib.gui.js</a>, <a href="jsxc.lib.gui.js.html#line1854">line 1854</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</article>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<nav>
|
||||
<h2><a href="index.html">Index</a></h2><h3>Namespaces</h3><ul><li><a href="jsxc.html">jsxc</a></li><li><a href="jsxc.gui.html">gui</a></li><li><a href="jsxc.gui.dialog.html">dialog</a></li><li><a href="jsxc.gui.queryActions.html">queryActions</a></li><li><a href="jsxc.gui.roster.html">roster</a></li><li><a href="jsxc.gui.window.html">window</a></li><li><a href="jsxc.muc.html">muc</a></li><li><a href="jsxc.notification.html">notification</a></li><li><a href="jsxc.options.html">options</a></li><li><a href="jsxc.otr.html">otr</a></li><li><a href="jsxc.storage.html">storage</a></li><li><a href="jsxc.webrtc.html">webrtc</a></li><li><a href="jsxc.xmpp.html">xmpp</a></li><li><a href="jsxc.xmpp.bookmarks.html">bookmarks</a></li><li><a href="jsxc.xmpp.carbons.html">carbons</a></li></ul><h3><a href="global.html">Global</a></h3>
|
||||
</nav>
|
||||
|
||||
<br clear="both">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.2.2</a> on Thu Sep 10 2015 11:03:22 GMT+0200 (CEST)
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
<script src="scripts/linenumber.js"> </script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,473 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>JSDoc: Namespace: queryActions</title>
|
||||
|
||||
<script src="scripts/prettify/prettify.js"> </script>
|
||||
<script src="scripts/prettify/lang-css.js"> </script>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
|
||||
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="main">
|
||||
|
||||
<h1 class="page-title">Namespace: queryActions</h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<section>
|
||||
|
||||
<header>
|
||||
<h2>
|
||||
<span class="ancestors"><a href="jsxc.html">jsxc</a><a href="jsxc.gui.html">.gui</a>.</span>
|
||||
|
||||
queryActions
|
||||
</h2>
|
||||
|
||||
</header>
|
||||
|
||||
<article>
|
||||
<div class="container-overview">
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="description">Different uri query actions as defined in XEP-0147.</div>
|
||||
|
||||
|
||||
|
||||
<dl class="details">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="jsxc.lib.gui.js.html">jsxc.lib.gui.js</a>, <a href="jsxc.lib.gui.js.html#line36">line 36</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3 class="subsection-title">Methods</h3>
|
||||
|
||||
<dl>
|
||||
|
||||
<dt>
|
||||
<h4 class="name" id="join"><span class="type-signature"><static> </span>join<span class="signature">()</span><span class="type-signature"></span></h4>
|
||||
|
||||
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
<div class="description">
|
||||
xmpp:JID?join[;password=TEXT]
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dl class="details">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="jsxc.lib.gui.js.html">jsxc.lib.gui.js</a>, <a href="jsxc.lib.gui.js.html#line71">line 71</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
|
||||
|
||||
|
||||
<dt>
|
||||
<h4 class="name" id="message"><span class="type-signature"><static> </span>message<span class="signature">()</span><span class="type-signature"></span></h4>
|
||||
|
||||
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
<div class="description">
|
||||
xmpp:JID?message[;body=TEXT]
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dl class="details">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="jsxc.lib.gui.js.html">jsxc.lib.gui.js</a>, <a href="jsxc.lib.gui.js.html#line43">line 43</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
|
||||
|
||||
|
||||
<dt>
|
||||
<h4 class="name" id="remove"><span class="type-signature"><static> </span>remove<span class="signature">()</span><span class="type-signature"></span></h4>
|
||||
|
||||
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
<div class="description">
|
||||
xmpp:JID?remove
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dl class="details">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="jsxc.lib.gui.js.html">jsxc.lib.gui.js</a>, <a href="jsxc.lib.gui.js.html#line52">line 52</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
|
||||
|
||||
|
||||
<dt>
|
||||
<h4 class="name" id="subscribe"><span class="type-signature"><static> </span>subscribe<span class="signature">()</span><span class="type-signature"></span></h4>
|
||||
|
||||
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
<div class="description">
|
||||
xmpp:JID?subscribe[;name=NAME]
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dl class="details">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="jsxc.lib.gui.js.html">jsxc.lib.gui.js</a>, <a href="jsxc.lib.gui.js.html#line57">line 57</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
|
||||
|
||||
|
||||
<dt>
|
||||
<h4 class="name" id="vcard"><span class="type-signature"><static> </span>vcard<span class="signature">()</span><span class="type-signature"></span></h4>
|
||||
|
||||
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
<div class="description">
|
||||
xmpp:JID?vcard
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dl class="details">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="jsxc.lib.gui.js.html">jsxc.lib.gui.js</a>, <a href="jsxc.lib.gui.js.html#line66">line 66</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</article>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<nav>
|
||||
<h2><a href="index.html">Index</a></h2><h3>Namespaces</h3><ul><li><a href="jsxc.html">jsxc</a></li><li><a href="jsxc.gui.html">gui</a></li><li><a href="jsxc.gui.dialog.html">dialog</a></li><li><a href="jsxc.gui.queryActions.html">queryActions</a></li><li><a href="jsxc.gui.roster.html">roster</a></li><li><a href="jsxc.gui.window.html">window</a></li><li><a href="jsxc.muc.html">muc</a></li><li><a href="jsxc.notification.html">notification</a></li><li><a href="jsxc.options.html">options</a></li><li><a href="jsxc.otr.html">otr</a></li><li><a href="jsxc.storage.html">storage</a></li><li><a href="jsxc.webrtc.html">webrtc</a></li><li><a href="jsxc.xmpp.html">xmpp</a></li><li><a href="jsxc.xmpp.bookmarks.html">bookmarks</a></li><li><a href="jsxc.xmpp.carbons.html">carbons</a></li></ul><h3><a href="global.html">Global</a></h3>
|
||||
</nav>
|
||||
|
||||
<br clear="both">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.2.2</a> on Thu Sep 10 2015 11:03:22 GMT+0200 (CEST)
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
<script src="scripts/linenumber.js"> </script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,124 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>JSDoc: Namespace: template</title>
|
||||
|
||||
<script src="scripts/prettify/prettify.js"> </script>
|
||||
<script src="scripts/prettify/lang-css.js"> </script>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
|
||||
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="main">
|
||||
|
||||
<h1 class="page-title">Namespace: template</h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<section>
|
||||
|
||||
<header>
|
||||
<h2>
|
||||
<span class="ancestors"><a href="jsxc.html">jsxc</a><a href="jsxc.gui.html">.gui</a>.</span>
|
||||
|
||||
template
|
||||
</h2>
|
||||
|
||||
</header>
|
||||
|
||||
<article>
|
||||
<div class="container-overview">
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="description">Hold all HTML templates.</div>
|
||||
|
||||
|
||||
|
||||
<dl class="details">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="jsxc.lib.gui.js.html">jsxc.lib.gui.js</a>, <a href="jsxc.lib.gui.js.html#line2288">line 2288</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</article>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<nav>
|
||||
<h2><a href="index.html">Index</a></h2><h3>Namespaces</h3><ul><li><a href="jsxc.html">jsxc</a></li><li><a href="jsxc.gui.html">gui</a></li><li><a href="jsxc.gui.dialog.html">dialog</a></li><li><a href="jsxc.gui.queryActions.html">queryActions</a></li><li><a href="jsxc.gui.roster.html">roster</a></li><li><a href="jsxc.gui.template.html">template</a></li><li><a href="jsxc.gui.window.html">window</a></li><li><a href="jsxc.muc.html">muc</a></li><li><a href="jsxc.notification.html">notification</a></li><li><a href="jsxc.options.html">options</a></li><li><a href="jsxc.otr.html">otr</a></li><li><a href="jsxc.storage.html">storage</a></li><li><a href="jsxc.webrtc.html">webrtc</a></li><li><a href="jsxc.xmpp.html">xmpp</a></li><li><a href="jsxc.xmpp.carbons.html">carbons</a></li></ul><h3><a href="global.html">Global</a></h3>
|
||||
</nav>
|
||||
|
||||
<br clear="both">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.2.2</a> on Sat May 23 2015 16:03:19 GMT+0200 (CEST)
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
<script src="scripts/linenumber.js"> </script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,124 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>JSDoc: Namespace: l10n</title>
|
||||
|
||||
<script src="scripts/prettify/prettify.js"> </script>
|
||||
<script src="scripts/prettify/lang-css.js"> </script>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
|
||||
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="main">
|
||||
|
||||
<h1 class="page-title">Namespace: l10n</h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<section>
|
||||
|
||||
<header>
|
||||
<h2>
|
||||
<span class="ancestors"><a href="jsxc.html">jsxc</a>.</span>
|
||||
|
||||
l10n
|
||||
</h2>
|
||||
|
||||
</header>
|
||||
|
||||
<article>
|
||||
<div class="container-overview">
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="description">Contains all available translations</div>
|
||||
|
||||
|
||||
|
||||
<dl class="details">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="jsxc.lib.js.html">jsxc.lib.js</a>, <a href="jsxc.lib.js.html#line5777">line 5777</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</article>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<nav>
|
||||
<h2><a href="index.html">Index</a></h2><h3>Namespaces</h3><ul><li><a href="jsxc.html">jsxc</a></li><li><a href="jsxc.gui.html">gui</a></li><li><a href="jsxc.gui.dialog.html">dialog</a></li><li><a href="jsxc.gui.queryActions.html">queryActions</a></li><li><a href="jsxc.gui.roster.html">roster</a></li><li><a href="jsxc.gui.template.html">template</a></li><li><a href="jsxc.gui.window.html">window</a></li><li><a href="jsxc.l10n.html">l10n</a></li><li><a href="jsxc.notification.html">notification</a></li><li><a href="jsxc.options.html">options</a></li><li><a href="jsxc.otr.html">otr</a></li><li><a href="jsxc.storage.html">storage</a></li><li><a href="jsxc.webrtc.html">webrtc</a></li><li><a href="jsxc.xmpp.html">xmpp</a></li><li><a href="jsxc.xmpp.carbons.html">carbons</a></li></ul>
|
||||
</nav>
|
||||
|
||||
<br clear="both">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.2.2</a> on Wed Feb 25 2015 19:15:14 GMT+0100 (CET)
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
<script src="scripts/linenumber.js"> </script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,889 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>JSDoc: Source: jsxc.lib.js</title>
|
||||
|
||||
<script src="scripts/prettify/prettify.js"> </script>
|
||||
<script src="scripts/prettify/lang-css.js"> </script>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
|
||||
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="main">
|
||||
|
||||
<h1 class="page-title">Source: jsxc.lib.js</h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<section>
|
||||
<article>
|
||||
<pre class="prettyprint source"><code>/**
|
||||
* JavaScript Xmpp Chat namespace
|
||||
*
|
||||
* @namespace jsxc
|
||||
*/
|
||||
jsxc = {
|
||||
/** Version of jsxc */
|
||||
version: '< $ app.version $ >',
|
||||
|
||||
/** True if i'm the master */
|
||||
master: false,
|
||||
|
||||
/** True if the role allocation is finished */
|
||||
role_allocation: false,
|
||||
|
||||
/** Timeout for keepalive */
|
||||
to: null,
|
||||
|
||||
/** Timeout after normal keepalive starts */
|
||||
toBusy: null,
|
||||
|
||||
/** Timeout for notification */
|
||||
toNotification: null,
|
||||
|
||||
/** Timeout delay for notification */
|
||||
toNotificationDelay: 500,
|
||||
|
||||
/** Interval for keep-alive */
|
||||
keepalive: null,
|
||||
|
||||
/** True if last activity was up to 10 min ago */
|
||||
restore: false,
|
||||
|
||||
/** True if restore is complete */
|
||||
restoreCompleted: false,
|
||||
|
||||
/** True if login through box */
|
||||
triggeredFromBox: false,
|
||||
|
||||
/** True if logout through element click */
|
||||
triggeredFromElement: false,
|
||||
|
||||
/** True if logout through logout click */
|
||||
triggeredFromLogout: false,
|
||||
|
||||
/** last values which we wrote into localstorage (IE workaround) */
|
||||
ls: [],
|
||||
|
||||
/**
|
||||
* storage event is even fired if I write something into storage (IE
|
||||
* workaround) 0: conform, 1: not conform, 2: not shure
|
||||
*/
|
||||
storageNotConform: null,
|
||||
|
||||
/** Timeout for storageNotConform test */
|
||||
toSNC: null,
|
||||
|
||||
/** My bar id */
|
||||
bid: null,
|
||||
|
||||
/** Some constants */
|
||||
CONST: {
|
||||
NOTIFICATION_DEFAULT: 'default',
|
||||
NOTIFICATION_GRANTED: 'granted',
|
||||
NOTIFICATION_DENIED: 'denied',
|
||||
STATUS: ['offline', 'dnd', 'xa', 'away', 'chat', 'online'],
|
||||
SOUNDS: {
|
||||
MSG: 'incomingMessage.wav',
|
||||
CALL: 'Rotary-Phone6.mp3',
|
||||
NOTICE: 'Ping1.mp3'
|
||||
},
|
||||
REGEX: {
|
||||
JID: new RegExp('\\b[^"&\'\\/:<>@\\s]+@[\\w-_.]+\\b', 'ig'),
|
||||
URL: new RegExp(/((?:https?:\/\/|www\.|([\w\-]+\.[a-zA-Z]{2,3})(?=\b))(?:(?:[\-A-Za-z0-9+&@#\/%?=~_|!:,.;]*\([\-A-Za-z0-9+&@#\/%?=~_|!:,.;]*\)([\-A-Za-z0-9+&@#\/%?=~_|!:,.;]*[\-A-Za-z0-9+&@#\/%=~_|])?)|(?:[\-A-Za-z0-9+&@#\/%?=~_|!:,.;]*[\-A-Za-z0-9+&@#\/%=~_|]))?)/gi)
|
||||
},
|
||||
NS: {
|
||||
CARBONS: 'urn:xmpp:carbons:2',
|
||||
FORWARD: 'urn:xmpp:forward:0'
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Parse a unix timestamp and return a formatted time string
|
||||
*
|
||||
* @memberOf jsxc
|
||||
* @param {Object} unixtime
|
||||
* @returns time of day and/or date
|
||||
*/
|
||||
getFormattedTime: function(unixtime) {
|
||||
var msgDate = new Date(parseInt(unixtime));
|
||||
var date = ('0' + msgDate.getDate()).slice(-2);
|
||||
var month = ('0' + (msgDate.getMonth() + 1)).slice(-2);
|
||||
var year = msgDate.getFullYear();
|
||||
var hours = ('0' + msgDate.getHours()).slice(-2);
|
||||
var minutes = ('0' + msgDate.getMinutes()).slice(-2);
|
||||
var dateNow = new Date(),
|
||||
time = hours + ':' + minutes;
|
||||
|
||||
// compare dates only
|
||||
dateNow.setHours(0, 0, 0, 0);
|
||||
msgDate.setHours(0, 0, 0, 0);
|
||||
|
||||
if (dateNow.getTime() !== msgDate.getTime()) {
|
||||
return date + '.' + month + '.' + year + ' ' + time;
|
||||
}
|
||||
return time;
|
||||
},
|
||||
|
||||
/**
|
||||
* Write debug message to console and to log.
|
||||
*
|
||||
* @memberOf jsxc
|
||||
* @param {String} msg Debug message
|
||||
* @param {Object} data
|
||||
* @param {String} Could be warn|error|null
|
||||
*/
|
||||
debug: function(msg, data, level) {
|
||||
if (level) {
|
||||
msg = '[' + level + '] ' + msg;
|
||||
}
|
||||
|
||||
if (data) {
|
||||
if (jsxc.storage.getItem('debug') === true) {
|
||||
console.log(msg, data);
|
||||
}
|
||||
|
||||
// try to convert data to string
|
||||
var d;
|
||||
try {
|
||||
// clone html snippet
|
||||
d = $("<span>").prepend($(data).clone()).html();
|
||||
} catch (err) {
|
||||
try {
|
||||
d = JSON.stringify(data);
|
||||
} catch (err2) {
|
||||
d = 'see js console';
|
||||
}
|
||||
}
|
||||
|
||||
jsxc.log = jsxc.log + msg + ': ' + d + '\n';
|
||||
} else {
|
||||
console.log(msg);
|
||||
jsxc.log = jsxc.log + msg + '\n';
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Write warn message.
|
||||
*
|
||||
* @memberOf jsxc
|
||||
* @param {String} msg Warn message
|
||||
* @param {Object} data
|
||||
*/
|
||||
warn: function(msg, data) {
|
||||
jsxc.debug(msg, data, 'WARN');
|
||||
},
|
||||
|
||||
/**
|
||||
* Write error message.
|
||||
*
|
||||
* @memberOf jsxc
|
||||
* @param {String} msg Error message
|
||||
* @param {Object} data
|
||||
*/
|
||||
error: function(msg, data) {
|
||||
jsxc.debug(msg, data, 'ERROR');
|
||||
},
|
||||
|
||||
/** debug log */
|
||||
log: '',
|
||||
|
||||
/**
|
||||
* Starts the action
|
||||
*
|
||||
* @memberOf jsxc
|
||||
* @param {object} options
|
||||
*/
|
||||
init: function(options) {
|
||||
|
||||
if (options) {
|
||||
// override default options
|
||||
$.extend(true, jsxc.options, options);
|
||||
}
|
||||
|
||||
// Check localStorage
|
||||
if (typeof(localStorage) === 'undefined') {
|
||||
jsxc.warn("Browser doesn't support localStorage.");
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter method for options. Saved options will override default one.
|
||||
*
|
||||
* @param {string} key option key
|
||||
* @returns default or saved option value
|
||||
*/
|
||||
jsxc.options.get = function(key) {
|
||||
var local = jsxc.storage.getUserItem('options') || {};
|
||||
|
||||
return local[key] || jsxc.options[key];
|
||||
};
|
||||
|
||||
/**
|
||||
* Setter method for options. Will write into localstorage.
|
||||
*
|
||||
* @param {string} key option key
|
||||
* @param {object} value option value
|
||||
*/
|
||||
jsxc.options.set = function(key, value) {
|
||||
jsxc.storage.updateItem('options', key, value, true);
|
||||
};
|
||||
|
||||
jsxc.storageNotConform = jsxc.storage.getItem('storageNotConform');
|
||||
if (jsxc.storageNotConform === null) {
|
||||
jsxc.storageNotConform = 2;
|
||||
}
|
||||
|
||||
// detect language
|
||||
var lang;
|
||||
if (jsxc.storage.getItem('lang') !== null) {
|
||||
lang = jsxc.storage.getItem('lang');
|
||||
} else if (jsxc.options.autoLang && navigator.language) {
|
||||
lang = navigator.language.substr(0, 2);
|
||||
} else {
|
||||
lang = jsxc.options.defaultLang;
|
||||
}
|
||||
|
||||
// initialize i18n translator
|
||||
$.i18n.init({
|
||||
lng: lang,
|
||||
fallbackLng: 'en',
|
||||
resStore: I18next,
|
||||
// use localStorage and set expiration to a day
|
||||
useLocalStorage: true,
|
||||
localStorageExpirationTime: 60 * 60 * 24 * 1000,
|
||||
});
|
||||
|
||||
if (jsxc.storage.getItem('debug') === true) {
|
||||
jsxc.options.otr.debug = true;
|
||||
}
|
||||
|
||||
// Register event listener for the storage event
|
||||
window.addEventListener('storage', jsxc.storage.onStorage, false);
|
||||
|
||||
var lastActivity = jsxc.storage.getItem('lastActivity') || 0;
|
||||
|
||||
if ((new Date()).getTime() - lastActivity < jsxc.options.loginTimeout) {
|
||||
jsxc.restore = true;
|
||||
}
|
||||
|
||||
$(document).on('connectionReady.jsxc', function() {
|
||||
// Looking for logout element
|
||||
if (jsxc.options.logoutElement !== null && jsxc.options.logoutElement.length > 0) {
|
||||
var logout = function() {
|
||||
jsxc.options.logoutElement = $(this);
|
||||
jsxc.triggeredFromLogout = true;
|
||||
return jsxc.xmpp.logout();
|
||||
};
|
||||
|
||||
jsxc.options.logoutElement.off('click', null, logout).one('click', logout);
|
||||
}
|
||||
});
|
||||
|
||||
// Check if we have to establish a new connection
|
||||
if (!jsxc.storage.getItem('rid') || !jsxc.storage.getItem('sid') || !jsxc.restore) {
|
||||
|
||||
// clean up rid and sid
|
||||
jsxc.storage.removeItem('rid');
|
||||
jsxc.storage.removeItem('sid');
|
||||
|
||||
// Looking for a login form
|
||||
if (!jsxc.isLoginForm()) {
|
||||
|
||||
if (jsxc.options.displayRosterMinimized()) {
|
||||
// Show minimized roster
|
||||
jsxc.storage.setUserItem('roster', 'hidden');
|
||||
jsxc.gui.roster.init();
|
||||
jsxc.gui.roster.noConnection();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof jsxc.options.formFound === 'function') {
|
||||
jsxc.options.formFound.call();
|
||||
}
|
||||
|
||||
// create jquery object
|
||||
var form = jsxc.options.loginForm.form = $(jsxc.options.loginForm.form);
|
||||
var events = form.data('events') || {
|
||||
submit: []
|
||||
};
|
||||
var submits = [];
|
||||
|
||||
// save attached submit events and remove them. Will be reattached
|
||||
// in jsxc.submitLoginForm
|
||||
$.each(events.submit, function(index, val) {
|
||||
submits.push(val.handler);
|
||||
});
|
||||
|
||||
form.data('submits', submits);
|
||||
form.off('submit');
|
||||
|
||||
// Add jsxc login action to form
|
||||
form.submit(function() {
|
||||
jsxc.prepareLogin(function(settings) {
|
||||
if (settings !== false) {
|
||||
// settings.xmpp.onlogin is deprecated since v2.1.0
|
||||
var enabled = (settings.loginForm && settings.loginForm.enable) || (settings.xmpp && settings.xmpp.onlogin);
|
||||
enabled = enabled === "true" || enabled === true;
|
||||
|
||||
if (enabled) {
|
||||
jsxc.options.loginForm.triggered = true;
|
||||
|
||||
jsxc.xmpp.login();
|
||||
}
|
||||
} else {
|
||||
jsxc.submitLoginForm();
|
||||
}
|
||||
});
|
||||
|
||||
// Trigger submit in jsxc.xmpp.connected()
|
||||
return false;
|
||||
});
|
||||
|
||||
} else if (!jsxc.isLoginForm() || (jsxc.options.loginForm && jsxc.options.loginForm.attachIfFound)) {
|
||||
|
||||
// Restore old connection
|
||||
|
||||
jsxc.bid = jsxc.jidToBid(jsxc.storage.getItem('jid'));
|
||||
|
||||
jsxc.gui.init();
|
||||
|
||||
if (typeof(jsxc.storage.getItem('alive')) === 'undefined' || !jsxc.restore) {
|
||||
jsxc.onMaster();
|
||||
} else {
|
||||
jsxc.checkMaster();
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if login form is found.
|
||||
*
|
||||
* @memberOf jsxc
|
||||
* @returns {boolean} True if login form was found.
|
||||
*/
|
||||
isLoginForm: function() {
|
||||
return jsxc.options.loginForm.form && jsxc.el_exists(jsxc.options.loginForm.form) && jsxc.el_exists(jsxc.options.loginForm.jid) && jsxc.el_exists(jsxc.options.loginForm.pass);
|
||||
},
|
||||
|
||||
/**
|
||||
* Load settings and prepare jid.
|
||||
*
|
||||
* @memberOf jsxc
|
||||
* @param {string} username
|
||||
* @param {string} password
|
||||
* @param {function} cb Called after login is prepared with result as param
|
||||
*/
|
||||
prepareLogin: function(username, password, cb) {
|
||||
if (typeof username === 'function') {
|
||||
cb = username;
|
||||
username = null;
|
||||
}
|
||||
username = username || $(jsxc.options.loginForm.jid).val();
|
||||
password = password || $(jsxc.options.loginForm.pass).val();
|
||||
|
||||
if (!jsxc.triggeredFromBox && (jsxc.options.loginForm.onConnecting === 'dialog' || typeof jsxc.options.loginForm.onConnecting === 'undefined')) {
|
||||
jsxc.gui.showWaitAlert($.t('Logging_in'));
|
||||
}
|
||||
|
||||
var settings;
|
||||
|
||||
if (typeof jsxc.options.loadSettings === 'function') {
|
||||
settings = jsxc.options.loadSettings.call(this, username, password, function(s) {
|
||||
jsxc._prepareLogin(username, password, cb, s);
|
||||
});
|
||||
|
||||
if (typeof settings !== 'undefined') {
|
||||
jsxc._prepareLogin(username, password, cb, settings);
|
||||
}
|
||||
} else {
|
||||
jsxc._prepareLogin(username, password, cb);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Process xmpp settings and save loaded settings.
|
||||
*
|
||||
* @private
|
||||
* @memberOf jsxc
|
||||
* @param {string} username
|
||||
* @param {string} password
|
||||
* @param {function} cb Called after login is prepared with result as param
|
||||
* @param {object} [loadedSettings] additonal options
|
||||
*/
|
||||
_prepareLogin: function(username, password, cb, loadedSettings) {
|
||||
if (loadedSettings === false) {
|
||||
jsxc.warn('No settings provided');
|
||||
|
||||
cb(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// prevent to modify the original object
|
||||
var settings = $.extend(true, {}, jsxc.options);
|
||||
|
||||
if (loadedSettings) {
|
||||
// overwrite current options with loaded settings;
|
||||
settings = $.extend(true, settings, loadedSettings);
|
||||
} else {
|
||||
loadedSettings = {};
|
||||
}
|
||||
|
||||
if (typeof settings.xmpp.username === 'string') {
|
||||
username = settings.xmpp.username;
|
||||
}
|
||||
|
||||
var resource = (settings.xmpp.resource) ? '/' + settings.xmpp.resource : '';
|
||||
var domain = settings.xmpp.domain;
|
||||
var jid;
|
||||
|
||||
if (username.match(/@(.*)$/)) {
|
||||
jid = (username.match(/\/(.*)$/)) ? username : username + resource;
|
||||
} else {
|
||||
jid = username + '@' + domain + resource;
|
||||
}
|
||||
|
||||
if (typeof jsxc.options.loginForm.preJid === 'function') {
|
||||
jid = jsxc.options.loginForm.preJid(jid);
|
||||
}
|
||||
|
||||
jsxc.bid = jsxc.jidToBid(jid);
|
||||
|
||||
settings.xmpp.username = jid.split('@')[0];
|
||||
settings.xmpp.domain = jid.split('@')[1].split('/')[0];
|
||||
settings.xmpp.resource = jid.split('@')[1].split('/')[1] || "";
|
||||
|
||||
if (!loadedSettings.xmpp) {
|
||||
// force xmpp settings to be saved to storage
|
||||
loadedSettings.xmpp = {};
|
||||
}
|
||||
|
||||
// save loaded settings to storage
|
||||
$.each(loadedSettings, function(key) {
|
||||
var old = jsxc.options.get(key);
|
||||
var val = settings[key];
|
||||
val = $.extend(true, old, val);
|
||||
|
||||
jsxc.options.set(key, val);
|
||||
});
|
||||
|
||||
jsxc.options.xmpp.jid = jid;
|
||||
jsxc.options.xmpp.password = password;
|
||||
|
||||
cb(settings);
|
||||
},
|
||||
|
||||
/**
|
||||
* Called if the script is a slave
|
||||
*/
|
||||
onSlave: function() {
|
||||
jsxc.debug('I am the slave.');
|
||||
|
||||
jsxc.role_allocation = true;
|
||||
|
||||
jsxc.restoreRoster();
|
||||
jsxc.restoreWindows();
|
||||
jsxc.restoreCompleted = true;
|
||||
|
||||
$(document).trigger('restoreCompleted.jsxc');
|
||||
},
|
||||
|
||||
/**
|
||||
* Called if the script is the master
|
||||
*/
|
||||
onMaster: function() {
|
||||
jsxc.debug('I am master.');
|
||||
|
||||
jsxc.master = true;
|
||||
|
||||
// Init local storage
|
||||
jsxc.storage.setItem('alive', 0);
|
||||
jsxc.storage.setItem('alive_busy', 0);
|
||||
if (!jsxc.storage.getUserItem('windowlist')) {
|
||||
jsxc.storage.setUserItem('windowlist', []);
|
||||
}
|
||||
|
||||
// Sending keepalive signal
|
||||
jsxc.startKeepAlive();
|
||||
|
||||
if (jsxc.options.get('otr').enable) {
|
||||
// create or load DSA key and call _onMaster
|
||||
jsxc.otr.createDSA();
|
||||
} else {
|
||||
jsxc._onMaster();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Second half of the onMaster routine
|
||||
*/
|
||||
_onMaster: function() {
|
||||
|
||||
// create otr objects, if we lost the master
|
||||
if (jsxc.role_allocation) {
|
||||
$.each(jsxc.storage.getUserItem('windowlist'), function(index, val) {
|
||||
jsxc.otr.create(val);
|
||||
});
|
||||
}
|
||||
|
||||
jsxc.role_allocation = true;
|
||||
|
||||
if (jsxc.restore && !jsxc.restoreCompleted) {
|
||||
jsxc.restoreRoster();
|
||||
jsxc.restoreWindows();
|
||||
jsxc.restoreCompleted = true;
|
||||
|
||||
$(document).trigger('restoreCompleted.jsxc');
|
||||
}
|
||||
|
||||
// Prepare notifications
|
||||
if (jsxc.restore) {
|
||||
var noti = jsxc.storage.getUserItem('notification');
|
||||
noti = (typeof noti === 'number') ? noti : 2;
|
||||
if (jsxc.options.notification && noti > 0 && jsxc.notification.hasSupport()) {
|
||||
if (jsxc.notification.hasPermission()) {
|
||||
jsxc.notification.init();
|
||||
} else {
|
||||
jsxc.notification.prepareRequest();
|
||||
}
|
||||
} else {
|
||||
// No support => disable
|
||||
jsxc.options.notification = false;
|
||||
}
|
||||
}
|
||||
|
||||
$(document).on('connectionReady.jsxc', function() {
|
||||
jsxc.gui.updateAvatar($('#jsxc_avatar'), jsxc.jidToBid(jsxc.storage.getItem('jid')), 'own');
|
||||
});
|
||||
|
||||
jsxc.xmpp.login();
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if there is a master
|
||||
*/
|
||||
checkMaster: function() {
|
||||
jsxc.debug('check master');
|
||||
|
||||
jsxc.to = window.setTimeout(jsxc.onMaster, 1000);
|
||||
jsxc.storage.ink('alive');
|
||||
},
|
||||
|
||||
/**
|
||||
* Start sending keep-alive signal
|
||||
*/
|
||||
startKeepAlive: function() {
|
||||
jsxc.keepalive = window.setInterval(jsxc.keepAlive, jsxc.options.timeout - 1000);
|
||||
},
|
||||
|
||||
/**
|
||||
* Sends the keep-alive signal to signal that the master is still there.
|
||||
*/
|
||||
keepAlive: function() {
|
||||
jsxc.storage.ink('alive');
|
||||
|
||||
if (jsxc.role_allocation) {
|
||||
jsxc.storage.setItem('lastActivity', (new Date()).getTime());
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Send one keep-alive signal with higher timeout, and than resume with
|
||||
* normal signal
|
||||
*/
|
||||
keepBusyAlive: function() {
|
||||
if (jsxc.toBusy) {
|
||||
window.clearTimeout(jsxc.toBusy);
|
||||
}
|
||||
|
||||
if (jsxc.keepalive) {
|
||||
window.clearInterval(jsxc.keepalive);
|
||||
}
|
||||
|
||||
jsxc.storage.ink('alive_busy');
|
||||
jsxc.toBusy = window.setTimeout(jsxc.startKeepAlive, jsxc.options.busyTimeout - 1000);
|
||||
},
|
||||
|
||||
/**
|
||||
* Generates a random integer number between 0 and max
|
||||
*
|
||||
* @param {Integer} max
|
||||
* @return {Integer} random integer between 0 and max
|
||||
*/
|
||||
random: function(max) {
|
||||
return Math.floor(Math.random() * max);
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if there is a element with the given selector
|
||||
*
|
||||
* @param {String} selector jQuery selector
|
||||
* @return {Boolean}
|
||||
*/
|
||||
el_exists: function(selector) {
|
||||
return $(selector).length > 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a CSS compatible string from a JID
|
||||
*
|
||||
* @param {type} jid Valid Jabber ID
|
||||
* @returns {String} css Compatible string
|
||||
*/
|
||||
jidToCid: function(jid) {
|
||||
jsxc.warn('jsxc.jidToCid is deprecated!');
|
||||
|
||||
var cid = Strophe.getBareJidFromJid(jid).replace('@', '-').replace(/\./g, '-').toLowerCase();
|
||||
|
||||
return cid;
|
||||
},
|
||||
|
||||
/**
|
||||
* Create comparable bar jid.
|
||||
*
|
||||
* @memberOf jsxc
|
||||
* @param jid
|
||||
* @returns comparable bar jid
|
||||
*/
|
||||
jidToBid: function(jid) {
|
||||
return Strophe.unescapeNode(Strophe.getBareJidFromJid(jid).toLowerCase());
|
||||
},
|
||||
|
||||
/**
|
||||
* Restore roster
|
||||
*/
|
||||
restoreRoster: function() {
|
||||
var buddies = jsxc.storage.getUserItem('buddylist');
|
||||
|
||||
if (!buddies || buddies.length === 0) {
|
||||
jsxc.debug('No saved buddylist.');
|
||||
|
||||
jsxc.gui.roster.empty();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$.each(buddies, function(index, value) {
|
||||
jsxc.gui.roster.add(value);
|
||||
});
|
||||
|
||||
jsxc.gui.roster.loaded = true;
|
||||
$(document).trigger('cloaded.roster.jsxc');
|
||||
},
|
||||
|
||||
/**
|
||||
* Restore all windows
|
||||
*/
|
||||
restoreWindows: function() {
|
||||
var windows = jsxc.storage.getUserItem('windowlist');
|
||||
|
||||
if (windows === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
$.each(windows, function(index, bid) {
|
||||
var window = jsxc.storage.getUserItem('window', bid);
|
||||
|
||||
if (!window) {
|
||||
jsxc.debug('Associated window-element is missing: ' + bid);
|
||||
return true;
|
||||
}
|
||||
|
||||
jsxc.gui.window.init(bid);
|
||||
|
||||
if (!window.minimize) {
|
||||
jsxc.gui.window.show(bid);
|
||||
} else {
|
||||
jsxc.gui.window.hide(bid);
|
||||
}
|
||||
|
||||
jsxc.gui.window.setText(bid, window.text);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* This method submits the specified login form.
|
||||
*/
|
||||
submitLoginForm: function() {
|
||||
var form = jsxc.options.loginForm.form.off('submit');
|
||||
|
||||
// Attach original events
|
||||
var submits = form.data('submits') || [];
|
||||
$.each(submits, function(index, val) {
|
||||
form.submit(val);
|
||||
});
|
||||
|
||||
if (form.find('#submit').length > 0) {
|
||||
form.find('#submit').click();
|
||||
} else {
|
||||
form.submit();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Escapes some characters to HTML character
|
||||
*/
|
||||
escapeHTML: function(text) {
|
||||
text = text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
||||
return text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes all html tags.
|
||||
*
|
||||
* @memberOf jsxc
|
||||
* @param text
|
||||
* @returns stripped text
|
||||
*/
|
||||
removeHTML: function(text) {
|
||||
return $('<span>').html(text).text();
|
||||
},
|
||||
|
||||
/**
|
||||
* Executes only one of the given events
|
||||
*
|
||||
* @param {string} obj.key event name
|
||||
* @param {function} obj.value function to execute
|
||||
* @returns {string} namespace of all events
|
||||
*/
|
||||
switchEvents: function(obj) {
|
||||
var ns = Math.random().toString(36).substr(2, 12);
|
||||
var self = this;
|
||||
|
||||
$.each(obj, function(key, val) {
|
||||
$(document).one(key + '.' + ns, function() {
|
||||
$(document).off('.' + ns);
|
||||
|
||||
val.apply(self, arguments);
|
||||
});
|
||||
});
|
||||
|
||||
return ns;
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if tab is hidden.
|
||||
*
|
||||
* @returns {boolean} True if tab is hidden
|
||||
*/
|
||||
isHidden: function() {
|
||||
var hidden = false;
|
||||
|
||||
if (typeof document.hidden !== 'undefined') {
|
||||
hidden = document.hidden;
|
||||
} else if (typeof document.webkitHidden !== 'undefined') {
|
||||
hidden = document.webkitHidden;
|
||||
} else if (typeof document.mozHidden !== 'undefined') {
|
||||
hidden = document.mozHidden;
|
||||
} else if (typeof document.msHidden !== 'undefined') {
|
||||
hidden = document.msHidden;
|
||||
}
|
||||
|
||||
// handle multiple tabs
|
||||
if (hidden && jsxc.master) {
|
||||
jsxc.storage.ink('hidden', 0);
|
||||
} else if (!hidden && !jsxc.master) {
|
||||
jsxc.storage.ink('hidden');
|
||||
}
|
||||
|
||||
return hidden;
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if tab has focus.
|
||||
*
|
||||
* @returns {boolean} True if tabs has focus
|
||||
*/
|
||||
hasFocus: function() {
|
||||
var focus = true;
|
||||
|
||||
if (typeof document.hasFocus === 'function') {
|
||||
focus = document.hasFocus();
|
||||
}
|
||||
|
||||
if (!focus && jsxc.master) {
|
||||
jsxc.storage.ink('focus', 0);
|
||||
} else if (focus && !jsxc.master) {
|
||||
jsxc.storage.ink('focus');
|
||||
}
|
||||
|
||||
return focus;
|
||||
},
|
||||
|
||||
/**
|
||||
* Executes the given function in jsxc namespace.
|
||||
*
|
||||
* @memberOf jsxc
|
||||
* @param {string} fnName Function name
|
||||
* @param {array} fnParams Function parameters
|
||||
* @returns Function return value
|
||||
*/
|
||||
exec: function(fnName, fnParams) {
|
||||
var fnList = fnName.split('.');
|
||||
var fn = jsxc[fnList[0]];
|
||||
var i;
|
||||
for (i = 1; i < fnList.length; i++) {
|
||||
fn = fn[fnList[i]];
|
||||
}
|
||||
|
||||
if (typeof fn === 'function') {
|
||||
return fn.apply(null, fnParams);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Hash string into 32-bit signed integer.
|
||||
*
|
||||
* @memberOf jsxc
|
||||
* @param {string} str input string
|
||||
* @returns {integer} 32-bit signed integer
|
||||
*/
|
||||
hashStr: function(str) {
|
||||
var hash = 0,
|
||||
i;
|
||||
|
||||
if (str.length === 0) {
|
||||
return hash;
|
||||
}
|
||||
|
||||
for (i = 0; i < str.length; i++) {
|
||||
hash = ((hash << 5) - hash) + str.charCodeAt(i);
|
||||
hash |= 0; // Convert to 32bit integer
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
};
|
||||
</code></pre>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<nav>
|
||||
<h2><a href="index.html">Index</a></h2><h3>Namespaces</h3><ul><li><a href="jsxc.html">jsxc</a></li><li><a href="jsxc.gui.html">gui</a></li><li><a href="jsxc.gui.dialog.html">dialog</a></li><li><a href="jsxc.gui.queryActions.html">queryActions</a></li><li><a href="jsxc.gui.roster.html">roster</a></li><li><a href="jsxc.gui.window.html">window</a></li><li><a href="jsxc.muc.html">muc</a></li><li><a href="jsxc.notification.html">notification</a></li><li><a href="jsxc.options.html">options</a></li><li><a href="jsxc.otr.html">otr</a></li><li><a href="jsxc.storage.html">storage</a></li><li><a href="jsxc.webrtc.html">webrtc</a></li><li><a href="jsxc.xmpp.html">xmpp</a></li><li><a href="jsxc.xmpp.bookmarks.html">bookmarks</a></li><li><a href="jsxc.xmpp.carbons.html">carbons</a></li></ul><h3><a href="global.html">Global</a></h3>
|
||||
</nav>
|
||||
|
||||
<br clear="both">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.2.2</a> on Thu Sep 10 2015 11:03:21 GMT+0200 (CEST)
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
<script src="scripts/linenumber.js"> </script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,166 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>JSDoc: Source: jsxc.lib.notice.js</title>
|
||||
|
||||
<script src="scripts/prettify/prettify.js"> </script>
|
||||
<script src="scripts/prettify/lang-css.js"> </script>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
|
||||
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="main">
|
||||
|
||||
<h1 class="page-title">Source: jsxc.lib.notice.js</h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<section>
|
||||
<article>
|
||||
<pre class="prettyprint source"><code>/**
|
||||
* This namespace handle the notice system.
|
||||
*
|
||||
* @namspace jsxc.notice
|
||||
* @memberOf jsxc
|
||||
*/
|
||||
jsxc.notice = {
|
||||
/** Number of notices. */
|
||||
_num: 0,
|
||||
|
||||
/**
|
||||
* Loads the saved notices.
|
||||
*
|
||||
* @memberOf jsxc.notice
|
||||
*/
|
||||
load: function() {
|
||||
// reset list
|
||||
$('#jsxc_notice ul li').remove();
|
||||
$('#jsxc_notice > span').text('');
|
||||
jsxc.notice._num = 0;
|
||||
|
||||
var saved = jsxc.storage.getUserItem('notices') || [];
|
||||
var key = null;
|
||||
|
||||
for (key in saved) {
|
||||
if (saved.hasOwnProperty(key)) {
|
||||
var val = saved[key];
|
||||
|
||||
jsxc.notice.add(val.msg, val.description, val.fnName, val.fnParams, key);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Add a new notice to the stack;
|
||||
*
|
||||
* @memberOf jsxc.notice
|
||||
* @param msg Header message
|
||||
* @param description Notice description
|
||||
* @param fnName Function name to be called if you open the notice
|
||||
* @param fnParams Array of params for function
|
||||
* @param id Notice id
|
||||
*/
|
||||
add: function(msg, description, fnName, fnParams, id) {
|
||||
var nid = id || Date.now();
|
||||
var list = $('#jsxc_notice ul');
|
||||
var notice = $('<li/>');
|
||||
|
||||
notice.click(function() {
|
||||
jsxc.notice.remove(nid);
|
||||
|
||||
jsxc.exec(fnName, fnParams);
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
notice.text(msg);
|
||||
notice.attr('title', description || '');
|
||||
notice.attr('data-nid', nid);
|
||||
list.append(notice);
|
||||
|
||||
$('#jsxc_notice > span').text(++jsxc.notice._num);
|
||||
|
||||
if (!id) {
|
||||
var saved = jsxc.storage.getUserItem('notices') || {};
|
||||
saved[nid] = {
|
||||
msg: msg,
|
||||
description: description,
|
||||
fnName: fnName,
|
||||
fnParams: fnParams
|
||||
};
|
||||
jsxc.storage.setUserItem('notices', saved);
|
||||
|
||||
jsxc.notification.notify(msg, description || '', null, true, jsxc.CONST.SOUNDS.NOTICE);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes notice from stack
|
||||
*
|
||||
* @memberOf jsxc.notice
|
||||
* @param nid The notice id
|
||||
*/
|
||||
remove: function(nid) {
|
||||
var el = $('#jsxc_notice li[data-nid=' + nid + ']');
|
||||
|
||||
el.remove();
|
||||
$('#jsxc_notice > span').text(--jsxc.notice._num || '');
|
||||
|
||||
var s = jsxc.storage.getUserItem('notices');
|
||||
delete s[nid];
|
||||
jsxc.storage.setUserItem('notices', s);
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if there is already a notice for the given function name.
|
||||
*
|
||||
* @memberOf jsxc.notice
|
||||
* @param {string} fnName Function name
|
||||
* @returns {boolean} True if there is >0 functions with the given name
|
||||
*/
|
||||
has: function(fnName) {
|
||||
var saved = jsxc.storage.getUserItem('notices') || [];
|
||||
var has = false;
|
||||
|
||||
$.each(saved, function(index, val) {
|
||||
if (val.fnName === fnName) {
|
||||
has = true;
|
||||
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
return has;
|
||||
}
|
||||
};
|
||||
</code></pre>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<nav>
|
||||
<h2><a href="index.html">Index</a></h2><h3>Namespaces</h3><ul><li><a href="jsxc.html">jsxc</a></li><li><a href="jsxc.gui.html">gui</a></li><li><a href="jsxc.gui.dialog.html">dialog</a></li><li><a href="jsxc.gui.queryActions.html">queryActions</a></li><li><a href="jsxc.gui.roster.html">roster</a></li><li><a href="jsxc.gui.window.html">window</a></li><li><a href="jsxc.muc.html">muc</a></li><li><a href="jsxc.notification.html">notification</a></li><li><a href="jsxc.options.html">options</a></li><li><a href="jsxc.otr.html">otr</a></li><li><a href="jsxc.storage.html">storage</a></li><li><a href="jsxc.webrtc.html">webrtc</a></li><li><a href="jsxc.xmpp.html">xmpp</a></li><li><a href="jsxc.xmpp.bookmarks.html">bookmarks</a></li><li><a href="jsxc.xmpp.carbons.html">carbons</a></li></ul><h3><a href="global.html">Global</a></h3>
|
||||
</nav>
|
||||
|
||||
<br clear="both">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.2.2</a> on Thu Sep 10 2015 11:03:21 GMT+0200 (CEST)
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
<script src="scripts/linenumber.js"> </script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,324 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>JSDoc: Source: jsxc.lib.notification.js</title>
|
||||
|
||||
<script src="scripts/prettify/prettify.js"> </script>
|
||||
<script src="scripts/prettify/lang-css.js"> </script>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
|
||||
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="main">
|
||||
|
||||
<h1 class="page-title">Source: jsxc.lib.notification.js</h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<section>
|
||||
<article>
|
||||
<pre class="prettyprint source"><code>/**
|
||||
* This namespace handles the Notification API.
|
||||
*
|
||||
* @namespace jsxc.notification
|
||||
*/
|
||||
jsxc.notification = {
|
||||
|
||||
/** Current audio file. */
|
||||
audio: null,
|
||||
|
||||
/**
|
||||
* Register notification on incoming messages.
|
||||
*
|
||||
* @memberOf jsxc.notification
|
||||
*/
|
||||
init: function() {
|
||||
$(document).on('postmessagein.jsxc', function(event, bid, msg) {
|
||||
msg = (msg.match(/^\?OTR/)) ? $.t('Encrypted_message') : msg;
|
||||
var data = jsxc.storage.getUserItem('buddy', bid);
|
||||
|
||||
jsxc.notification.notify({
|
||||
title: $.t('New_message_from', {
|
||||
name: data.name
|
||||
}),
|
||||
msg: msg,
|
||||
soundFile: jsxc.CONST.SOUNDS.MSG,
|
||||
source: bid
|
||||
});
|
||||
});
|
||||
|
||||
$(document).on('callincoming.jingle', function() {
|
||||
jsxc.notification.playSound(jsxc.CONST.SOUNDS.CALL, true, true);
|
||||
});
|
||||
|
||||
$(document).on('accept.call.jsxc reject.call.jsxc', function() {
|
||||
jsxc.notification.stopSound();
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Shows a pop up notification and optional play sound.
|
||||
*
|
||||
* @param title Title
|
||||
* @param msg Message
|
||||
* @param d Duration
|
||||
* @param force Should message also shown, if tab is visible?
|
||||
* @param soundFile Playing given sound file
|
||||
* @param loop Loop sound file?
|
||||
* @param source Bid which triggered this notification
|
||||
*/
|
||||
notify: function(title, msg, d, force, soundFile, loop, source) {
|
||||
if (!jsxc.options.notification || !jsxc.notification.hasPermission()) {
|
||||
return; // notifications disabled
|
||||
}
|
||||
|
||||
var o;
|
||||
|
||||
if (title !== null && typeof title === 'object') {
|
||||
o = title;
|
||||
} else {
|
||||
o = {
|
||||
title: title,
|
||||
msg: msg,
|
||||
duration: d,
|
||||
force: force,
|
||||
soundFile: soundFile,
|
||||
loop: loop,
|
||||
source: source
|
||||
};
|
||||
}
|
||||
|
||||
if (jsxc.hasFocus() && !o.force) {
|
||||
return; // Tab is visible
|
||||
}
|
||||
|
||||
var icon = o.icon || jsxc.options.root + '/img/XMPP_logo.png';
|
||||
|
||||
if (typeof o.source === 'string') {
|
||||
var data = jsxc.storage.getUserItem('buddy', o.source);
|
||||
var src = jsxc.storage.getUserItem('avatar', data.avatar);
|
||||
|
||||
if (typeof src === 'string' && src !== '0') {
|
||||
icon = src;
|
||||
}
|
||||
}
|
||||
|
||||
jsxc.toNotification = setTimeout(function() {
|
||||
|
||||
if (typeof o.soundFile === 'string') {
|
||||
jsxc.notification.playSound(o.soundFile, o.loop, o.force);
|
||||
}
|
||||
|
||||
var popup = new Notification($.t(o.title), {
|
||||
body: $.t(o.msg),
|
||||
icon: icon
|
||||
});
|
||||
|
||||
var duration = o.duration || jsxc.options.popupDuration;
|
||||
|
||||
if (duration > 0) {
|
||||
setTimeout(function() {
|
||||
popup.close();
|
||||
}, duration);
|
||||
}
|
||||
}, jsxc.toNotificationDelay);
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks if browser has support for notifications and add on chrome to the
|
||||
* default api.
|
||||
*
|
||||
* @returns {Boolean} True if the browser has support.
|
||||
*/
|
||||
hasSupport: function() {
|
||||
if (window.webkitNotifications) {
|
||||
// prepare chrome
|
||||
|
||||
window.Notification = function(title, opt) {
|
||||
var popup = window.webkitNotifications.createNotification(null, title, opt.body);
|
||||
popup.show();
|
||||
|
||||
popup.close = function() {
|
||||
popup.cancel();
|
||||
};
|
||||
|
||||
return popup;
|
||||
};
|
||||
|
||||
var permission;
|
||||
switch (window.webkitNotifications.checkPermission()) {
|
||||
case 0:
|
||||
permission = jsxc.CONST.NOTIFICATION_GRANTED;
|
||||
break;
|
||||
case 2:
|
||||
permission = jsxc.CONST.NOTIFICATION_DENIED;
|
||||
break;
|
||||
default: // 1
|
||||
permission = jsxc.CONST.NOTIFICATION_DEFAULT;
|
||||
}
|
||||
window.Notification.permission = permission;
|
||||
|
||||
window.Notification.requestPermission = function(func) {
|
||||
window.webkitNotifications.requestPermission(func);
|
||||
};
|
||||
|
||||
return true;
|
||||
} else if (window.Notification) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Ask user on first incoming message if we should inform him about new
|
||||
* messages.
|
||||
*/
|
||||
prepareRequest: function() {
|
||||
|
||||
if (jsxc.notice.has('gui.showRequestNotification')) {
|
||||
return;
|
||||
}
|
||||
|
||||
$(document).one('postmessagein.jsxc', function() {
|
||||
setTimeout(function() {
|
||||
jsxc.notice.add($.t('Notifications') + '?', $.t('Should_we_notify_you_'), 'gui.showRequestNotification');
|
||||
}, 1000);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Request notification permission.
|
||||
*/
|
||||
requestPermission: function() {
|
||||
window.Notification.requestPermission(function(status) {
|
||||
if (window.Notification.permission !== status) {
|
||||
window.Notification.permission = status;
|
||||
}
|
||||
|
||||
if (jsxc.notification.hasPermission()) {
|
||||
$(document).trigger('notificationready.jsxc');
|
||||
} else {
|
||||
$(document).trigger('notificationfailure.jsxc');
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Check permission.
|
||||
*
|
||||
* @returns {Boolean} True if we have the permission
|
||||
*/
|
||||
hasPermission: function() {
|
||||
return window.Notification.permission === jsxc.CONST.NOTIFICATION_GRANTED;
|
||||
},
|
||||
|
||||
/**
|
||||
* Plays the given file.
|
||||
*
|
||||
* @memberOf jsxc.notification
|
||||
* @param {string} soundFile File relative to the sound directory
|
||||
* @param {boolean} loop True for loop
|
||||
* @param {boolean} force Play even if a tab is visible. Default: false.
|
||||
*/
|
||||
playSound: function(soundFile, loop, force) {
|
||||
if (!jsxc.master) {
|
||||
// only master plays sound
|
||||
return;
|
||||
}
|
||||
|
||||
if (jsxc.options.get('muteNotification') || jsxc.storage.getUserItem('presence') === 'dnd') {
|
||||
// sound mute or own presence is dnd
|
||||
return;
|
||||
}
|
||||
|
||||
if (jsxc.hasFocus() && !force) {
|
||||
// tab is visible
|
||||
return;
|
||||
}
|
||||
|
||||
// stop current audio file
|
||||
jsxc.notification.stopSound();
|
||||
|
||||
var audio = new Audio(jsxc.options.root + '/sound/' + soundFile);
|
||||
audio.loop = loop || false;
|
||||
audio.play();
|
||||
|
||||
jsxc.notification.audio = audio;
|
||||
},
|
||||
|
||||
/**
|
||||
* Stop/remove current sound.
|
||||
*
|
||||
* @memberOf jsxc.notification
|
||||
*/
|
||||
stopSound: function() {
|
||||
var audio = jsxc.notification.audio;
|
||||
|
||||
if (typeof audio !== 'undefined' && audio !== null) {
|
||||
audio.pause();
|
||||
jsxc.notification.audio = null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Mute sound.
|
||||
*
|
||||
* @memberOf jsxc.notification
|
||||
* @param {boolean} external True if triggered from external tab. Default:
|
||||
* false.
|
||||
*/
|
||||
muteSound: function(external) {
|
||||
$('#jsxc_menu .jsxc_muteNotification').text($.t('Unmute'));
|
||||
|
||||
if (external !== true) {
|
||||
jsxc.options.set('muteNotification', true);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Unmute sound.
|
||||
*
|
||||
* @memberOf jsxc.notification
|
||||
* @param {boolean} external True if triggered from external tab. Default:
|
||||
* false.
|
||||
*/
|
||||
unmuteSound: function(external) {
|
||||
$('#jsxc_menu .jsxc_muteNotification').text($.t('Mute'));
|
||||
|
||||
if (external !== true) {
|
||||
jsxc.options.set('muteNotification', false);
|
||||
}
|
||||
}
|
||||
};
|
||||
</code></pre>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<nav>
|
||||
<h2><a href="index.html">Index</a></h2><h3>Namespaces</h3><ul><li><a href="jsxc.html">jsxc</a></li><li><a href="jsxc.gui.html">gui</a></li><li><a href="jsxc.gui.dialog.html">dialog</a></li><li><a href="jsxc.gui.queryActions.html">queryActions</a></li><li><a href="jsxc.gui.roster.html">roster</a></li><li><a href="jsxc.gui.window.html">window</a></li><li><a href="jsxc.muc.html">muc</a></li><li><a href="jsxc.notification.html">notification</a></li><li><a href="jsxc.options.html">options</a></li><li><a href="jsxc.otr.html">otr</a></li><li><a href="jsxc.storage.html">storage</a></li><li><a href="jsxc.webrtc.html">webrtc</a></li><li><a href="jsxc.xmpp.html">xmpp</a></li><li><a href="jsxc.xmpp.bookmarks.html">bookmarks</a></li><li><a href="jsxc.xmpp.carbons.html">carbons</a></li></ul><h3><a href="global.html">Global</a></h3>
|
||||
</nav>
|
||||
|
||||
<br clear="both">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.2.2</a> on Thu Sep 10 2015 11:03:21 GMT+0200 (CEST)
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
<script src="scripts/linenumber.js"> </script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,284 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>JSDoc: Source: jsxc.lib.options.js</title>
|
||||
|
||||
<script src="scripts/prettify/prettify.js"> </script>
|
||||
<script src="scripts/prettify/lang-css.js"> </script>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
|
||||
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="main">
|
||||
|
||||
<h1 class="page-title">Source: jsxc.lib.options.js</h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<section>
|
||||
<article>
|
||||
<pre class="prettyprint source"><code>/**
|
||||
* Set some options for the chat.
|
||||
*
|
||||
* @namespace jsxc.options
|
||||
*/
|
||||
jsxc.options = {
|
||||
|
||||
/** name of container application (e.g. owncloud or SOGo) */
|
||||
app_name: 'web applications',
|
||||
|
||||
/** Timeout for the keepalive signal */
|
||||
timeout: 3000,
|
||||
|
||||
/** Timeout for the keepalive signal if the master is busy */
|
||||
busyTimeout: 15000,
|
||||
|
||||
/** OTR options */
|
||||
otr: {
|
||||
enable: true,
|
||||
ERROR_START_AKE: false,
|
||||
debug: false,
|
||||
SEND_WHITESPACE_TAG: true,
|
||||
WHITESPACE_START_AKE: true
|
||||
},
|
||||
|
||||
/** xmpp options */
|
||||
xmpp: {
|
||||
/** BOSH url */
|
||||
url: null,
|
||||
|
||||
/** XMPP JID*/
|
||||
jid: null,
|
||||
|
||||
/** XMPP domain */
|
||||
domain: null,
|
||||
|
||||
/** XMPP password */
|
||||
password: null,
|
||||
|
||||
/** True: Allow user to overwrite xmpp settings */
|
||||
overwrite: false,
|
||||
|
||||
/** @deprecated since v2.1.0. Use now loginForm.enable. */
|
||||
onlogin: null
|
||||
},
|
||||
|
||||
/** default xmpp priorities */
|
||||
priority: {
|
||||
online: 0,
|
||||
chat: 0,
|
||||
away: 0,
|
||||
xa: 0,
|
||||
dnd: 0
|
||||
},
|
||||
|
||||
/** If all 3 properties are set and enable is true, the login form is used */
|
||||
loginForm: {
|
||||
/** False, disables login through login form */
|
||||
enable: true,
|
||||
|
||||
/** jquery object from form */
|
||||
form: null,
|
||||
|
||||
/** jquery object from input element which contains the jid */
|
||||
jid: null,
|
||||
|
||||
/** jquery object from input element which contains the password */
|
||||
pass: null,
|
||||
|
||||
/** manipulate JID from input element */
|
||||
preJid: function(jid) {
|
||||
return jid;
|
||||
},
|
||||
|
||||
/**
|
||||
* Action after login was called: dialog [String] Show wait dialog, false [boolean] |
|
||||
* quiet [String] Do nothing
|
||||
*/
|
||||
onConnecting: 'dialog',
|
||||
|
||||
/**
|
||||
* Action after connected: submit [String] Submit form, false [boolean] Do
|
||||
* nothing, continue [String] Start chat
|
||||
*/
|
||||
onConnected: 'submit',
|
||||
|
||||
/**
|
||||
* Action after auth fail: submit [String] Submit form, false [boolean] | quiet [String] Do
|
||||
* nothing, ask [String] Show auth fail dialog
|
||||
*/
|
||||
onAuthFail: 'submit',
|
||||
|
||||
/** True: Attach connection even is login form was found */
|
||||
attachIfFound: true,
|
||||
|
||||
/**
|
||||
* True: Display roster minimized after first login. Afterwards the last
|
||||
* roster state will be used.
|
||||
*/
|
||||
startMinimized: false
|
||||
},
|
||||
|
||||
/** jquery object from logout element */
|
||||
logoutElement: null,
|
||||
|
||||
/** How many messages should be logged? */
|
||||
numberOfMsg: 10,
|
||||
|
||||
/** Default language */
|
||||
defaultLang: 'en',
|
||||
|
||||
/** auto language detection */
|
||||
autoLang: true,
|
||||
|
||||
/** Place for roster */
|
||||
rosterAppend: 'body',
|
||||
|
||||
/** Should we use the HTML5 notification API? */
|
||||
notification: true,
|
||||
|
||||
/** duration for notification */
|
||||
popupDuration: 6000,
|
||||
|
||||
/** Absolute path root of JSXC installation */
|
||||
root: '',
|
||||
|
||||
/** Timeout for restore in ms */
|
||||
loginTimeout: 1000 * 60 * 10,
|
||||
|
||||
/**
|
||||
* This function decides wether the roster will be displayed or not if no
|
||||
* connection is found.
|
||||
*/
|
||||
displayRosterMinimized: function() {
|
||||
return false;
|
||||
},
|
||||
|
||||
/** Set to true if you want to hide offline buddies. */
|
||||
hideOffline: false,
|
||||
|
||||
/** Mute notification sound? */
|
||||
muteNotification: false,
|
||||
|
||||
/**
|
||||
* If no avatar is found, this function is called.
|
||||
*
|
||||
* @param jid Jid of that user.
|
||||
* @this {jQuery} Elements to update with probable .jsxc_avatar elements
|
||||
*/
|
||||
defaultAvatar: function(jid) {
|
||||
jsxc.gui.avatarPlaceholder($(this).find('.jsxc_avatar'), jid);
|
||||
},
|
||||
|
||||
/**
|
||||
* This callback processes all settings.
|
||||
* @callback loadSettingsCallback
|
||||
* @param settings {object} could be every jsxc option
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns permanent saved settings and overwrite default jsxc.options.
|
||||
*
|
||||
* @memberOf jsxc.options
|
||||
* @function
|
||||
* @param username {string} username
|
||||
* @param password {string} password
|
||||
* @param cb {loadSettingsCallback} Callback that handles the result
|
||||
*/
|
||||
loadSettings: null,
|
||||
|
||||
/**
|
||||
* Call this function to save user settings permanent.
|
||||
*
|
||||
* @memberOf jsxc.options
|
||||
* @param data Holds all data as key/value
|
||||
* @returns {boolean} false if function failes
|
||||
*/
|
||||
saveSettinsPermanent: function() {
|
||||
|
||||
},
|
||||
|
||||
carbons: {
|
||||
/** Enable carbon copies? */
|
||||
enable: false
|
||||
},
|
||||
|
||||
/**
|
||||
* Processes user list.
|
||||
*
|
||||
* @callback getUsers-cb
|
||||
* @param {object} list List of users, key: username, value: alias
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns a list of usernames and aliases
|
||||
*
|
||||
* @function getUsers
|
||||
* @memberOf jsxc.options
|
||||
* @param {string} search Search token (start with)
|
||||
* @param {getUsers-cb} cb Called with list of users
|
||||
*/
|
||||
getUsers: null,
|
||||
|
||||
/** Options for info in favicon */
|
||||
favicon: {
|
||||
enable: true,
|
||||
|
||||
/** Favicon info background color */
|
||||
bgColor: '#E59400',
|
||||
|
||||
/** Favicon info text color */
|
||||
textColor: '#fff'
|
||||
},
|
||||
|
||||
/** @deprecated since v2.1.0. Use now RTCPeerConfig.url. */
|
||||
turnCredentialsPath: null,
|
||||
|
||||
/** RTCPeerConfiguration used for audio/video calls. */
|
||||
RTCPeerConfig: {
|
||||
/** Time-to-live for config from url */
|
||||
ttl: 3600,
|
||||
|
||||
/** [optional] If set, jsxc requests and uses RTCPeerConfig from this url */
|
||||
url: null,
|
||||
|
||||
/** ICE servers like defined in http://www.w3.org/TR/webrtc/#idl-def-RTCIceServer */
|
||||
iceServers: [{
|
||||
urls: 'stun:stun.stunprotocol.org'
|
||||
}]
|
||||
},
|
||||
|
||||
/** Link to an online user manual */
|
||||
onlineHelp: 'http://www.jsxc.org/manual.html'
|
||||
};
|
||||
</code></pre>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<nav>
|
||||
<h2><a href="index.html">Index</a></h2><h3>Namespaces</h3><ul><li><a href="jsxc.html">jsxc</a></li><li><a href="jsxc.gui.html">gui</a></li><li><a href="jsxc.gui.dialog.html">dialog</a></li><li><a href="jsxc.gui.queryActions.html">queryActions</a></li><li><a href="jsxc.gui.roster.html">roster</a></li><li><a href="jsxc.gui.window.html">window</a></li><li><a href="jsxc.muc.html">muc</a></li><li><a href="jsxc.notification.html">notification</a></li><li><a href="jsxc.options.html">options</a></li><li><a href="jsxc.otr.html">otr</a></li><li><a href="jsxc.storage.html">storage</a></li><li><a href="jsxc.webrtc.html">webrtc</a></li><li><a href="jsxc.xmpp.html">xmpp</a></li><li><a href="jsxc.xmpp.bookmarks.html">bookmarks</a></li><li><a href="jsxc.xmpp.carbons.html">carbons</a></li></ul><h3><a href="global.html">Global</a></h3>
|
||||
</nav>
|
||||
|
||||
<br clear="both">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.2.2</a> on Thu Sep 10 2015 11:03:21 GMT+0200 (CEST)
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
<script src="scripts/linenumber.js"> </script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,536 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>JSDoc: Source: jsxc.lib.otr.js</title>
|
||||
|
||||
<script src="scripts/prettify/prettify.js"> </script>
|
||||
<script src="scripts/prettify/lang-css.js"> </script>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
|
||||
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="main">
|
||||
|
||||
<h1 class="page-title">Source: jsxc.lib.otr.js</h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<section>
|
||||
<article>
|
||||
<pre class="prettyprint source"><code>/**
|
||||
* @namespace jsxc.otr
|
||||
*/
|
||||
jsxc.otr = {
|
||||
/** list of otr objects */
|
||||
objects: {},
|
||||
|
||||
dsaFallback: null,
|
||||
/**
|
||||
* Handler for otr receive event
|
||||
*
|
||||
* @memberOf jsxc.otr
|
||||
* @param {Object} d
|
||||
* @param {string} d.bid
|
||||
* @param {string} d.msg received message
|
||||
* @param {boolean} d.encrypted True, if msg was encrypted.
|
||||
* @param {boolean} d.forwarded
|
||||
* @param {string} d.stamp timestamp
|
||||
*/
|
||||
receiveMessage: function(d) {
|
||||
var bid = d.bid;
|
||||
|
||||
if (jsxc.otr.objects[bid].msgstate !== OTR.CONST.MSGSTATE_PLAINTEXT) {
|
||||
jsxc.otr.backup(bid);
|
||||
}
|
||||
|
||||
if (jsxc.otr.objects[bid].msgstate !== OTR.CONST.MSGSTATE_PLAINTEXT && !d.encrypted) {
|
||||
jsxc.gui.window.postMessage(bid, 'sys', $.t('Received_an_unencrypted_message') + '. [' + d.msg + ']', d.encrypted, d.forwarded, d.stamp);
|
||||
} else {
|
||||
jsxc.gui.window.postMessage(bid, 'in', d.msg, d.encrypted, d.forwarded, d.stamp);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Handler for otr send event
|
||||
*
|
||||
* @param {string} jid
|
||||
* @param {string} msg message to be send
|
||||
*/
|
||||
sendMessage: function(jid, msg, uid) {
|
||||
if (jsxc.otr.objects[jsxc.jidToBid(jid)].msgstate !== 0) {
|
||||
jsxc.otr.backup(jsxc.jidToBid(jid));
|
||||
}
|
||||
|
||||
jsxc.xmpp._sendMessage(jid, msg, uid);
|
||||
},
|
||||
|
||||
/**
|
||||
* Create new otr instance
|
||||
*
|
||||
* @param {type} bid
|
||||
* @returns {undefined}
|
||||
*/
|
||||
create: function(bid) {
|
||||
|
||||
if (jsxc.otr.objects.hasOwnProperty(bid)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!jsxc.options.otr.priv) {
|
||||
return;
|
||||
}
|
||||
|
||||
// save list of otr objects
|
||||
var ol = jsxc.storage.getUserItem('otrlist') || [];
|
||||
if (ol.indexOf(bid) < 0) {
|
||||
ol.push(bid);
|
||||
jsxc.storage.setUserItem('otrlist', ol);
|
||||
}
|
||||
|
||||
jsxc.otr.objects[bid] = new OTR(jsxc.options.otr);
|
||||
|
||||
if (jsxc.options.otr.SEND_WHITESPACE_TAG) {
|
||||
jsxc.otr.objects[bid].SEND_WHITESPACE_TAG = true;
|
||||
}
|
||||
|
||||
if (jsxc.options.otr.WHITESPACE_START_AKE) {
|
||||
jsxc.otr.objects[bid].WHITESPACE_START_AKE = true;
|
||||
}
|
||||
|
||||
jsxc.otr.objects[bid].on('status', function(status) {
|
||||
var data = jsxc.storage.getUserItem('buddy', bid);
|
||||
|
||||
if (data === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (status) {
|
||||
case OTR.CONST.STATUS_SEND_QUERY:
|
||||
jsxc.gui.window.postMessage(bid, 'sys', $.t('trying_to_start_private_conversation'));
|
||||
break;
|
||||
case OTR.CONST.STATUS_AKE_SUCCESS:
|
||||
data.fingerprint = jsxc.otr.objects[bid].their_priv_pk.fingerprint();
|
||||
data.msgstate = OTR.CONST.MSGSTATE_ENCRYPTED;
|
||||
|
||||
var msg_state = jsxc.otr.objects[bid].trust ? 'Verified' : 'Unverified';
|
||||
var msg = $.t(msg_state + '_private_conversation_started');
|
||||
|
||||
jsxc.gui.window.postMessage(bid, 'sys', msg);
|
||||
break;
|
||||
case OTR.CONST.STATUS_END_OTR:
|
||||
data.fingerprint = null;
|
||||
|
||||
if (jsxc.otr.objects[bid].msgstate === OTR.CONST.MSGSTATE_PLAINTEXT) {
|
||||
// we abort the private conversation
|
||||
|
||||
data.msgstate = OTR.CONST.MSGSTATE_PLAINTEXT;
|
||||
jsxc.gui.window.postMessage(bid, 'sys', $.t('private_conversation_aborted'));
|
||||
|
||||
} else {
|
||||
// the buddy abort the private conversation
|
||||
|
||||
data.msgstate = OTR.CONST.MSGSTATE_FINISHED;
|
||||
jsxc.gui.window.postMessage(bid, 'sys', $.t('your_buddy_closed_the_private_conversation_you_should_do_the_same'));
|
||||
}
|
||||
break;
|
||||
case OTR.CONST.STATUS_SMP_HANDLE:
|
||||
jsxc.keepBusyAlive();
|
||||
break;
|
||||
}
|
||||
|
||||
jsxc.storage.setUserItem('buddy', bid, data);
|
||||
|
||||
// for encryption and verification state
|
||||
jsxc.gui.update(bid);
|
||||
});
|
||||
|
||||
jsxc.otr.objects[bid].on('smp', function(type, data) {
|
||||
switch (type) {
|
||||
case 'question': // verification request received
|
||||
jsxc.gui.window.postMessage(bid, 'sys', $.t('Authentication_request_received'));
|
||||
|
||||
if ($('#jsxc_dialog').length > 0) {
|
||||
jsxc.otr.objects[bid].sm.abort();
|
||||
break;
|
||||
}
|
||||
|
||||
jsxc.otr.onSmpQuestion(bid, data);
|
||||
jsxc.storage.setUserItem('smp_' + bid, {
|
||||
data: data || null
|
||||
});
|
||||
|
||||
break;
|
||||
case 'trust': // verification completed
|
||||
jsxc.otr.objects[bid].trust = data;
|
||||
jsxc.storage.updateUserItem('buddy', bid, 'trust', data);
|
||||
jsxc.otr.backup(bid);
|
||||
jsxc.gui.update(bid);
|
||||
|
||||
if (data) {
|
||||
jsxc.gui.window.postMessage(bid, 'sys', $.t('conversation_is_now_verified'));
|
||||
} else {
|
||||
jsxc.gui.window.postMessage(bid, 'sys', $.t('authentication_failed'));
|
||||
}
|
||||
jsxc.storage.removeUserItem('smp_' + bid);
|
||||
jsxc.gui.dialog.close();
|
||||
break;
|
||||
case 'abort':
|
||||
jsxc.gui.window.postMessage(bid, 'sys', $.t('Authentication_aborted'));
|
||||
break;
|
||||
default:
|
||||
jsxc.debug('[OTR] sm callback: Unknown type: ' + type);
|
||||
}
|
||||
});
|
||||
|
||||
// Receive message
|
||||
jsxc.otr.objects[bid].on('ui', function(msg, encrypted, meta) {
|
||||
jsxc.otr.receiveMessage({
|
||||
bid: bid,
|
||||
msg: msg,
|
||||
encrypted: encrypted === true,
|
||||
stamp: meta.stamp,
|
||||
forwarded: meta.forwarded
|
||||
});
|
||||
});
|
||||
|
||||
// Send message
|
||||
jsxc.otr.objects[bid].on('io', function(msg, uid) {
|
||||
var jid = jsxc.gui.window.get(bid).data('jid') || jsxc.otr.objects[bid].jid;
|
||||
|
||||
jsxc.otr.objects[bid].jid = jid;
|
||||
|
||||
jsxc.otr.sendMessage(jid, msg, uid);
|
||||
});
|
||||
|
||||
jsxc.otr.objects[bid].on('error', function(err) {
|
||||
// Handle this case in jsxc.otr.receiveMessage
|
||||
if (err !== 'Received an unencrypted message.') {
|
||||
jsxc.gui.window.postMessage(bid, 'sys', '[OTR] ' + $.t(err));
|
||||
}
|
||||
|
||||
jsxc.error('[OTR] ' + err);
|
||||
});
|
||||
|
||||
jsxc.otr.restore(bid);
|
||||
},
|
||||
|
||||
/**
|
||||
* show verification dialog with related part (secret or question)
|
||||
*
|
||||
* @param {type} bid
|
||||
* @param {string} [data]
|
||||
* @returns {undefined}
|
||||
*/
|
||||
onSmpQuestion: function(bid, data) {
|
||||
jsxc.gui.showVerification(bid);
|
||||
|
||||
$('#jsxc_dialog select').prop('selectedIndex', (data ? 2 : 3)).change();
|
||||
$('#jsxc_dialog > div:eq(0)').hide();
|
||||
|
||||
if (data) {
|
||||
$('#jsxc_dialog > div:eq(2)').find('#jsxc_quest').val(data).prop('disabled', true);
|
||||
$('#jsxc_dialog > div:eq(2)').find('.jsxc_submit').text($('Answer'));
|
||||
$('#jsxc_dialog > div:eq(2)').find('.jsxc_explanation').text($.t('onsmp_explanation_question'));
|
||||
} else {
|
||||
$('#jsxc_dialog > div:eq(3)').find('.jsxc_explanation').text($.t('onsmp_explanation_secret'));
|
||||
}
|
||||
|
||||
$('#jsxc_dialog .jsxc_close').click(function() {
|
||||
jsxc.storage.removeUserItem('smp_' + bid);
|
||||
|
||||
if (jsxc.master) {
|
||||
jsxc.otr.objects[bid].sm.abort();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Send verification request to buddy
|
||||
*
|
||||
* @param {string} bid
|
||||
* @param {string} sec secret
|
||||
* @param {string} [quest] question
|
||||
* @returns {undefined}
|
||||
*/
|
||||
sendSmpReq: function(bid, sec, quest) {
|
||||
jsxc.keepBusyAlive();
|
||||
|
||||
jsxc.otr.objects[bid].smpSecret(sec, quest || '');
|
||||
},
|
||||
|
||||
/**
|
||||
* Toggle encryption state
|
||||
*
|
||||
* @param {type} bid
|
||||
* @returns {undefined}
|
||||
*/
|
||||
toggleTransfer: function(bid) {
|
||||
if (typeof OTR !== 'function') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (jsxc.storage.getUserItem('buddy', bid).msgstate === 0) {
|
||||
jsxc.otr.goEncrypt(bid);
|
||||
} else {
|
||||
jsxc.otr.goPlain(bid);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Send request to encrypt the session
|
||||
*
|
||||
* @param {type} bid
|
||||
* @returns {undefined}
|
||||
*/
|
||||
goEncrypt: function(bid) {
|
||||
if (jsxc.master) {
|
||||
if (jsxc.otr.objects.hasOwnProperty(bid)) {
|
||||
jsxc.otr.objects[bid].sendQueryMsg();
|
||||
}
|
||||
} else {
|
||||
jsxc.storage.updateUserItem('buddy', bid, 'transferReq', 1);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Abort encryptet session
|
||||
*
|
||||
* @param {type} bid
|
||||
* @param cb callback
|
||||
* @returns {undefined}
|
||||
*/
|
||||
goPlain: function(bid, cb) {
|
||||
if (jsxc.master) {
|
||||
if (jsxc.otr.objects.hasOwnProperty(bid)) {
|
||||
jsxc.otr.objects[bid].endOtr.call(jsxc.otr.objects[bid], cb);
|
||||
jsxc.otr.objects[bid].init.call(jsxc.otr.objects[bid]);
|
||||
|
||||
jsxc.otr.backup(bid);
|
||||
}
|
||||
} else {
|
||||
jsxc.storage.updateUserItem('buddy', bid, 'transferReq', 0);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Backups otr session
|
||||
*
|
||||
* @param {string} bid
|
||||
*/
|
||||
backup: function(bid) {
|
||||
var o = jsxc.otr.objects[bid]; // otr object
|
||||
var r = {}; // return value
|
||||
|
||||
if (o === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// all variables which should be saved
|
||||
var savekey = ['jid', 'our_instance_tag', 'msgstate', 'authstate', 'fragment', 'their_y', 'their_old_y', 'their_keyid', 'their_instance_tag', 'our_dh', 'our_old_dh', 'our_keyid', 'sessKeys', 'storedMgs', 'oldMacKeys', 'trust', 'transmittedRS', 'ssid', 'receivedPlaintext', 'authstate', 'send_interval'];
|
||||
|
||||
var i;
|
||||
for (i = 0; i < savekey.length; i++) {
|
||||
r[savekey[i]] = JSON.stringify(o[savekey[i]]);
|
||||
}
|
||||
|
||||
if (o.their_priv_pk !== null) {
|
||||
r.their_priv_pk = JSON.stringify(o.their_priv_pk.packPublic());
|
||||
}
|
||||
|
||||
if (o.ake.otr_version && o.ake.otr_version !== '') {
|
||||
r.otr_version = JSON.stringify(o.ake.otr_version);
|
||||
}
|
||||
|
||||
jsxc.storage.setUserItem('otr', bid, r);
|
||||
},
|
||||
|
||||
/**
|
||||
* Restore old otr session
|
||||
*
|
||||
* @param {string} bid
|
||||
*/
|
||||
restore: function(bid) {
|
||||
var o = jsxc.otr.objects[bid];
|
||||
var d = jsxc.storage.getUserItem('otr', bid);
|
||||
|
||||
if (o !== null || d !== null) {
|
||||
var key;
|
||||
for (key in d) {
|
||||
if (d.hasOwnProperty(key)) {
|
||||
var val = JSON.parse(d[key]);
|
||||
if (key === 'their_priv_pk' && val !== null) {
|
||||
val = DSA.parsePublic(val);
|
||||
}
|
||||
if (key === 'otr_version' && val !== null) {
|
||||
o.ake.otr_version = val;
|
||||
} else {
|
||||
o[key] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
jsxc.otr.objects[bid] = o;
|
||||
|
||||
if (o.msgstate === 1 && o.their_priv_pk !== null) {
|
||||
o._smInit.call(jsxc.otr.objects[bid]);
|
||||
}
|
||||
}
|
||||
|
||||
jsxc.otr.enable(bid);
|
||||
},
|
||||
|
||||
/**
|
||||
* Create or load DSA key
|
||||
*
|
||||
* @returns {unresolved}
|
||||
*/
|
||||
createDSA: function() {
|
||||
if (jsxc.options.otr.priv) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof OTR !== 'function') {
|
||||
jsxc.warn('OTR support disabled');
|
||||
|
||||
OTR = {};
|
||||
OTR.CONST = {
|
||||
MSGSTATE_PLAINTEXT: 0,
|
||||
MSGSTATE_ENCRYPTED: 1,
|
||||
MSGSTATE_FINISHED: 2
|
||||
};
|
||||
|
||||
jsxc._onMaster();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (jsxc.storage.getUserItem('key') === null) {
|
||||
var msg = $.t('Creating_your_private_key_');
|
||||
var worker = null;
|
||||
|
||||
if (Worker) {
|
||||
// try to create web-worker
|
||||
|
||||
try {
|
||||
worker = new Worker(jsxc.options.root + '/lib/otr/lib/dsa-webworker.js');
|
||||
} catch (err) {
|
||||
jsxc.warn('Couldn\'t create web-worker.', err);
|
||||
}
|
||||
}
|
||||
|
||||
jsxc.otr.dsaFallback = (worker === null);
|
||||
|
||||
if (!jsxc.otr.dsaFallback) {
|
||||
// create DSA key in background
|
||||
|
||||
jsxc._onMaster();
|
||||
|
||||
worker.onmessage = function(e) {
|
||||
var type = e.data.type;
|
||||
var val = e.data.val;
|
||||
|
||||
if (type === 'debug') {
|
||||
jsxc.debug(val);
|
||||
} else if (type === 'data') {
|
||||
jsxc.otr.DSAready(DSA.parsePrivate(val));
|
||||
}
|
||||
};
|
||||
|
||||
// start worker
|
||||
worker.postMessage({
|
||||
imports: [jsxc.options.root + '/lib/otr/vendor/salsa20.js', jsxc.options.root + '/lib/otr/vendor/bigint.js', jsxc.options.root + '/lib/otr/vendor/crypto.js', jsxc.options.root + '/lib/otr/vendor/eventemitter.js', jsxc.options.root + '/lib/otr/lib/const.js', jsxc.options.root + '/lib/otr/lib/helpers.js', jsxc.options.root + '/lib/otr/lib/dsa.js'],
|
||||
seed: BigInt.getSeed(),
|
||||
debug: true
|
||||
});
|
||||
|
||||
} else {
|
||||
// fallback
|
||||
|
||||
jsxc.gui.dialog.open(jsxc.gui.template.get('waitAlert', null, msg), {
|
||||
noClose: true
|
||||
});
|
||||
|
||||
jsxc.debug('DSA key creation started.');
|
||||
|
||||
// wait until the wait alert is opened
|
||||
setTimeout(function() {
|
||||
var dsa = new DSA();
|
||||
jsxc.otr.DSAready(dsa);
|
||||
}, 500);
|
||||
}
|
||||
} else {
|
||||
jsxc.debug('DSA key loaded');
|
||||
jsxc.options.otr.priv = DSA.parsePrivate(jsxc.storage.getUserItem('key'));
|
||||
|
||||
jsxc.otr._createDSA();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Ending of createDSA().
|
||||
*/
|
||||
_createDSA: function() {
|
||||
|
||||
jsxc.storage.setUserItem('priv_fingerprint', jsxc.options.otr.priv.fingerprint());
|
||||
|
||||
if (jsxc.otr.dsaFallback !== false) {
|
||||
jsxc._onMaster();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Ending of DSA key generation.
|
||||
*
|
||||
* @param {DSA} dsa DSA object
|
||||
*/
|
||||
DSAready: function(dsa) {
|
||||
jsxc.storage.setUserItem('key', dsa.packPrivate());
|
||||
jsxc.options.otr.priv = dsa;
|
||||
|
||||
// close wait alert
|
||||
if (jsxc.otr.dsaFallback) {
|
||||
jsxc.gui.dialog.close();
|
||||
} else {
|
||||
$.each(jsxc.storage.getUserItem('windowlist'), function(index, val) {
|
||||
jsxc.otr.create(val);
|
||||
});
|
||||
}
|
||||
|
||||
jsxc.otr._createDSA();
|
||||
},
|
||||
|
||||
enable: function(bid) {
|
||||
jsxc.gui.window.get(bid).find('.jsxc_otr').removeClass('jsxc_disabled');
|
||||
}
|
||||
};
|
||||
</code></pre>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<nav>
|
||||
<h2><a href="index.html">Index</a></h2><h3>Namespaces</h3><ul><li><a href="jsxc.html">jsxc</a></li><li><a href="jsxc.gui.html">gui</a></li><li><a href="jsxc.gui.dialog.html">dialog</a></li><li><a href="jsxc.gui.queryActions.html">queryActions</a></li><li><a href="jsxc.gui.roster.html">roster</a></li><li><a href="jsxc.gui.window.html">window</a></li><li><a href="jsxc.muc.html">muc</a></li><li><a href="jsxc.notification.html">notification</a></li><li><a href="jsxc.options.html">options</a></li><li><a href="jsxc.otr.html">otr</a></li><li><a href="jsxc.storage.html">storage</a></li><li><a href="jsxc.webrtc.html">webrtc</a></li><li><a href="jsxc.xmpp.html">xmpp</a></li><li><a href="jsxc.xmpp.bookmarks.html">bookmarks</a></li><li><a href="jsxc.xmpp.carbons.html">carbons</a></li></ul><h3><a href="global.html">Global</a></h3>
|
||||
</nav>
|
||||
|
||||
<br clear="both">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.2.2</a> on Thu Sep 10 2015 11:03:21 GMT+0200 (CEST)
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
<script src="scripts/linenumber.js"> </script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,679 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>JSDoc: Source: jsxc.lib.storage.js</title>
|
||||
|
||||
<script src="scripts/prettify/prettify.js"> </script>
|
||||
<script src="scripts/prettify/lang-css.js"> </script>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
|
||||
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="main">
|
||||
|
||||
<h1 class="page-title">Source: jsxc.lib.storage.js</h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<section>
|
||||
<article>
|
||||
<pre class="prettyprint source"><code>/**
|
||||
* Handle long-live data
|
||||
*
|
||||
* @namespace jsxc.storage
|
||||
*/
|
||||
jsxc.storage = {
|
||||
/**
|
||||
* Prefix for localstorage
|
||||
*
|
||||
* @privat
|
||||
*/
|
||||
PREFIX: 'jsxc',
|
||||
|
||||
SEP: ':',
|
||||
|
||||
/**
|
||||
* @param {type} uk Should we generate a user prefix?
|
||||
* @returns {String} prefix
|
||||
* @memberOf jsxc.storage
|
||||
*/
|
||||
getPrefix: function(uk) {
|
||||
var self = jsxc.storage;
|
||||
|
||||
return self.PREFIX + self.SEP + ((uk && jsxc.bid) ? jsxc.bid + self.SEP : '');
|
||||
},
|
||||
|
||||
/**
|
||||
* Save item to storage
|
||||
*
|
||||
* @function
|
||||
* @param {String} key variablename
|
||||
* @param {Object} value value
|
||||
* @param {String} uk Userkey? Should we add the bid as prefix?
|
||||
*/
|
||||
setItem: function(key, value, uk) {
|
||||
|
||||
// Workaround for non-conform browser
|
||||
if (jsxc.storageNotConform > 0 && key !== 'rid' && key !== 'lastActivity') {
|
||||
if (jsxc.storageNotConform > 1 && jsxc.toSNC === null) {
|
||||
jsxc.toSNC = window.setTimeout(function() {
|
||||
jsxc.storageNotConform = 0;
|
||||
jsxc.storage.setItem('storageNotConform', 0);
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
jsxc.ls.push(JSON.stringify({
|
||||
key: key,
|
||||
value: value
|
||||
}));
|
||||
}
|
||||
|
||||
if (typeof(value) === 'object') {
|
||||
// exclude jquery objects, because otherwise safari will fail
|
||||
value = JSON.stringify(value, function(key, val) {
|
||||
if (!(val instanceof jQuery)) {
|
||||
return val;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
localStorage.setItem(jsxc.storage.getPrefix(uk) + key, value);
|
||||
},
|
||||
|
||||
setUserItem: function(type, key, value) {
|
||||
var self = jsxc.storage;
|
||||
|
||||
if (arguments.length === 2) {
|
||||
value = key;
|
||||
key = type;
|
||||
type = '';
|
||||
} else if (arguments.length === 3) {
|
||||
key = type + self.SEP + key;
|
||||
}
|
||||
|
||||
return jsxc.storage.setItem(key, value, true);
|
||||
},
|
||||
|
||||
/**
|
||||
* Load item from storage
|
||||
*
|
||||
* @function
|
||||
* @param {String} key variablename
|
||||
* @param {String} uk Userkey? Should we add the bid as prefix?
|
||||
*/
|
||||
getItem: function(key, uk) {
|
||||
key = jsxc.storage.getPrefix(uk) + key;
|
||||
|
||||
var value = localStorage.getItem(key);
|
||||
try {
|
||||
return JSON.parse(value);
|
||||
} catch (e) {
|
||||
return value;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Get a user item from storage.
|
||||
*
|
||||
* @param key
|
||||
* @returns user item
|
||||
*/
|
||||
getUserItem: function(type, key) {
|
||||
var self = jsxc.storage;
|
||||
|
||||
if (arguments.length === 1) {
|
||||
key = type;
|
||||
} else if (arguments.length === 2) {
|
||||
key = type + self.SEP + key;
|
||||
}
|
||||
|
||||
return jsxc.storage.getItem(key, true);
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove item from storage
|
||||
*
|
||||
* @function
|
||||
* @param {String} key variablename
|
||||
* @param {String} uk Userkey? Should we add the bid as prefix?
|
||||
*/
|
||||
removeItem: function(key, uk) {
|
||||
|
||||
// Workaround for non-conform browser
|
||||
if (jsxc.storageNotConform && key !== 'rid' && key !== 'lastActivity') {
|
||||
jsxc.ls.push(JSON.stringify({
|
||||
key: jsxc.storage.prefix + key,
|
||||
value: ''
|
||||
}));
|
||||
}
|
||||
|
||||
localStorage.removeItem(jsxc.storage.getPrefix(uk) + key);
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove user item from storage.
|
||||
*
|
||||
* @param key
|
||||
*/
|
||||
removeUserItem: function(type, key) {
|
||||
var self = jsxc.storage;
|
||||
|
||||
if (arguments.length === 1) {
|
||||
key = type;
|
||||
} else if (arguments.length === 2) {
|
||||
key = type + self.SEP + key;
|
||||
}
|
||||
|
||||
jsxc.storage.removeItem(key, true);
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates value of a variable in a saved object.
|
||||
*
|
||||
* @function
|
||||
* @param {String} key variablename
|
||||
* @param {String|object} variable variablename in object or object with
|
||||
* variable/key pairs
|
||||
* @param {Object} [value] value
|
||||
* @param {String} uk Userkey? Should we add the bid as prefix?
|
||||
*/
|
||||
updateItem: function(key, variable, value, uk) {
|
||||
|
||||
var data = jsxc.storage.getItem(key, uk) || {};
|
||||
|
||||
if (typeof(variable) === 'object') {
|
||||
|
||||
$.each(variable, function(key, val) {
|
||||
if (typeof(data[key]) === 'undefined') {
|
||||
jsxc.debug('Variable ' + key + ' doesn\'t exist in ' + variable + '. It was created.');
|
||||
}
|
||||
|
||||
data[key] = val;
|
||||
});
|
||||
} else {
|
||||
if (typeof(data[variable]) === 'undefined') {
|
||||
jsxc.debug('Variable ' + variable + ' doesn\'t exist. It was created.');
|
||||
}
|
||||
|
||||
data[variable] = value;
|
||||
}
|
||||
|
||||
jsxc.storage.setItem(key, data, uk);
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates value of a variable in a saved user object.
|
||||
*
|
||||
* @param {String} key variablename
|
||||
* @param {String|object} variable variablename in object or object with
|
||||
* variable/key pairs
|
||||
* @param {Object} [value] value
|
||||
*/
|
||||
updateUserItem: function(type, key, variable, value) {
|
||||
var self = jsxc.storage;
|
||||
|
||||
if (arguments.length === 4 || (arguments.length === 3 && typeof variable === 'object')) {
|
||||
key = type + self.SEP + key;
|
||||
} else {
|
||||
value = variable;
|
||||
variable = key;
|
||||
key = type;
|
||||
}
|
||||
|
||||
return jsxc.storage.updateItem(key, variable, value, true);
|
||||
},
|
||||
|
||||
/**
|
||||
* Inkrements value
|
||||
*
|
||||
* @function
|
||||
* @param {String} key variablename
|
||||
* @param {String} uk Userkey? Should we add the bid as prefix?
|
||||
*/
|
||||
ink: function(key, uk) {
|
||||
|
||||
jsxc.storage.setItem(key, Number(jsxc.storage.getItem(key, uk)) + 1, uk);
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove element from array or object
|
||||
*
|
||||
* @param {string} key name of array or object
|
||||
* @param {string} name name of element in array or object
|
||||
* @param {String} uk Userkey? Should we add the bid as prefix?
|
||||
* @returns {undefined}
|
||||
*/
|
||||
removeElement: function(key, name, uk) {
|
||||
var item = jsxc.storage.getItem(key, uk);
|
||||
|
||||
if ($.isArray(item)) {
|
||||
item = $.grep(item, function(e) {
|
||||
return e !== name;
|
||||
});
|
||||
} else if (typeof(item) === 'object' && item !== null) {
|
||||
delete item[name];
|
||||
}
|
||||
|
||||
jsxc.storage.setItem(key, item, uk);
|
||||
},
|
||||
|
||||
removeUserElement: function(type, key, name) {
|
||||
var self = jsxc.storage;
|
||||
|
||||
if (arguments.length === 2) {
|
||||
name = key;
|
||||
key = type;
|
||||
} else if (arguments.length === 3) {
|
||||
key = type + self.SEP + key;
|
||||
}
|
||||
|
||||
return jsxc.storage.removeElement(key, name, true);
|
||||
},
|
||||
|
||||
/**
|
||||
* Triggered if changes are recognized
|
||||
*
|
||||
* @function
|
||||
* @param {event} e Storageevent
|
||||
* @param {String} e.key Keyname which triggered event
|
||||
* @param {Object} e.oldValue Old Value for key
|
||||
* @param {Object} e.newValue New Value for key
|
||||
* @param {String} e.url
|
||||
*/
|
||||
onStorage: function(e) {
|
||||
|
||||
// skip
|
||||
if (e.key === jsxc.storage.PREFIX + jsxc.storage.SEP + 'rid' || e.key === jsxc.storage.PREFIX + jsxc.storage.SEP + 'lastActivity') {
|
||||
return;
|
||||
}
|
||||
|
||||
var re = new RegExp('^' + jsxc.storage.PREFIX + jsxc.storage.SEP + '(?:[^' + jsxc.storage.SEP + ']+@[^' + jsxc.storage.SEP + ']+' + jsxc.storage.SEP + ')?(.*)', 'i');
|
||||
var key = e.key.replace(re, '$1');
|
||||
|
||||
// Workaround for non-conform browser: Triggered event on every page
|
||||
// (own)
|
||||
if (jsxc.storageNotConform > 0 && jsxc.ls.length > 0) {
|
||||
|
||||
var val = e.newValue;
|
||||
try {
|
||||
val = JSON.parse(val);
|
||||
} catch (err) {}
|
||||
|
||||
var index = $.inArray(JSON.stringify({
|
||||
key: key,
|
||||
value: val
|
||||
}), jsxc.ls);
|
||||
|
||||
if (index >= 0) {
|
||||
|
||||
// confirm that the storage event is not fired regularly
|
||||
if (jsxc.storageNotConform > 1) {
|
||||
window.clearTimeout(jsxc.toSNC);
|
||||
jsxc.storageNotConform = 1;
|
||||
jsxc.storage.setItem('storageNotConform', 1);
|
||||
}
|
||||
|
||||
jsxc.ls.splice(index, 1);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Workaround for non-conform browser
|
||||
if (e.oldValue === e.newValue) {
|
||||
return;
|
||||
}
|
||||
|
||||
var n, o;
|
||||
var bid = key.replace(new RegExp('[^' + jsxc.storage.SEP + ']+' + jsxc.storage.SEP + '(.*)', 'i'), '$1');
|
||||
|
||||
// react if someone ask, if there is a master
|
||||
if (jsxc.master && key === 'alive') {
|
||||
jsxc.debug('Master request.');
|
||||
|
||||
jsxc.storage.ink('alive');
|
||||
return;
|
||||
}
|
||||
|
||||
// master alive
|
||||
if (!jsxc.master && (key === 'alive' || key === 'alive_busy') && !jsxc.triggeredFromElement) {
|
||||
|
||||
// reset timeout
|
||||
window.clearTimeout(jsxc.to);
|
||||
jsxc.to = window.setTimeout(jsxc.checkMaster, ((key === 'alive') ? jsxc.options.timeout : jsxc.options.busyTimeout) + jsxc.random(60));
|
||||
|
||||
// only call the first time
|
||||
if (!jsxc.role_allocation) {
|
||||
jsxc.onSlave();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (key.match(/^notices/)) {
|
||||
jsxc.notice.load();
|
||||
}
|
||||
|
||||
if (key.match(/^presence/)) {
|
||||
jsxc.gui.changePresence(e.newValue, true);
|
||||
}
|
||||
|
||||
if (key.match(/^options/) && e.newValue) {
|
||||
n = JSON.parse(e.newValue);
|
||||
|
||||
if (typeof n.muteNotification !== 'undefined' && n.muteNotification) {
|
||||
jsxc.notification.muteSound(true);
|
||||
} else {
|
||||
jsxc.notification.unmuteSound(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (key.match(/^hidden/)) {
|
||||
if (jsxc.master) {
|
||||
clearTimeout(jsxc.toNotification);
|
||||
} else {
|
||||
jsxc.isHidden();
|
||||
}
|
||||
}
|
||||
|
||||
if (key.match(/^focus/)) {
|
||||
if (jsxc.master) {
|
||||
clearTimeout(jsxc.toNotification);
|
||||
} else {
|
||||
jsxc.hasFocus();
|
||||
}
|
||||
}
|
||||
|
||||
if (key.match(new RegExp('^chat' + jsxc.storage.SEP))) {
|
||||
|
||||
var posts = JSON.parse(e.newValue);
|
||||
var data, el;
|
||||
|
||||
while (posts.length > 0) {
|
||||
data = posts.pop();
|
||||
el = $('#' + data.uid);
|
||||
|
||||
if (el.length === 0) {
|
||||
if (jsxc.master && data.direction === 'out') {
|
||||
jsxc.xmpp.sendMessage(bid, data.msg, data.uid);
|
||||
}
|
||||
|
||||
jsxc.gui.window._postMessage(bid, data);
|
||||
} else if (data.received) {
|
||||
el.addClass('jsxc_received');
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (key.match(new RegExp('^window' + jsxc.storage.SEP))) {
|
||||
|
||||
if (!e.newValue) {
|
||||
jsxc.gui.window._close(bid);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!e.oldValue) {
|
||||
jsxc.gui.window.open(bid);
|
||||
return;
|
||||
}
|
||||
|
||||
n = JSON.parse(e.newValue);
|
||||
o = JSON.parse(e.oldValue);
|
||||
|
||||
if (n.minimize !== o.minimize) {
|
||||
if (n.minimize) {
|
||||
jsxc.gui.window._hide(bid);
|
||||
} else {
|
||||
jsxc.gui.window._show(bid);
|
||||
}
|
||||
}
|
||||
|
||||
jsxc.gui.window.setText(bid, n.text);
|
||||
|
||||
if (n.unread !== o.unread) {
|
||||
if (n.unread === 0) {
|
||||
jsxc.gui.readMsg(bid);
|
||||
} else {
|
||||
jsxc.gui._unreadMsg(bid, n.unread);
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (key.match(/^unreadMsg/) && jsxc.gui.favicon) {
|
||||
jsxc.gui.favicon.badge(parseInt(e.newValue) || 0);
|
||||
}
|
||||
|
||||
if (key.match(new RegExp('^smp' + jsxc.storage.SEP))) {
|
||||
|
||||
if (!e.newValue) {
|
||||
|
||||
jsxc.gui.dialog.close();
|
||||
|
||||
if (jsxc.master) {
|
||||
jsxc.otr.objects[bid].sm.abort();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
n = JSON.parse(e.newValue);
|
||||
|
||||
if (typeof(n.data) !== 'undefined') {
|
||||
|
||||
jsxc.otr.onSmpQuestion(bid, n.data);
|
||||
|
||||
} else if (jsxc.master && n.sec) {
|
||||
jsxc.gui.dialog.close();
|
||||
|
||||
jsxc.otr.sendSmpReq(bid, n.sec, n.quest);
|
||||
}
|
||||
}
|
||||
|
||||
if (!jsxc.master && key.match(new RegExp('^buddy' + jsxc.storage.SEP))) {
|
||||
|
||||
if (!e.newValue) {
|
||||
jsxc.gui.roster.purge(bid);
|
||||
return;
|
||||
}
|
||||
if (!e.oldValue) {
|
||||
jsxc.gui.roster.add(bid);
|
||||
return;
|
||||
}
|
||||
|
||||
n = JSON.parse(e.newValue);
|
||||
o = JSON.parse(e.oldValue);
|
||||
|
||||
jsxc.gui.update(bid);
|
||||
|
||||
if (o.status !== n.status || o.sub !== n.sub) {
|
||||
jsxc.gui.roster.reorder(bid);
|
||||
}
|
||||
}
|
||||
|
||||
if (jsxc.master && key.match(new RegExp('^deletebuddy' + jsxc.storage.SEP)) && e.newValue) {
|
||||
n = JSON.parse(e.newValue);
|
||||
|
||||
jsxc.xmpp.removeBuddy(n.jid);
|
||||
jsxc.storage.removeUserItem(key);
|
||||
}
|
||||
|
||||
if (jsxc.master && key.match(new RegExp('^buddy' + jsxc.storage.SEP))) {
|
||||
|
||||
n = JSON.parse(e.newValue);
|
||||
o = JSON.parse(e.oldValue);
|
||||
|
||||
if (o.transferReq !== n.transferReq) {
|
||||
jsxc.storage.updateUserItem('buddy', bid, 'transferReq', -1);
|
||||
|
||||
if (n.transferReq === 0) {
|
||||
jsxc.otr.goPlain(bid);
|
||||
}
|
||||
if (n.transferReq === 1) {
|
||||
jsxc.otr.goEncrypt(bid);
|
||||
}
|
||||
}
|
||||
|
||||
if (o.name !== n.name) {
|
||||
jsxc.gui.roster._rename(bid, n.name);
|
||||
}
|
||||
}
|
||||
|
||||
// logout
|
||||
if (key === 'sid') {
|
||||
if (!e.newValue) {
|
||||
// if (jsxc.master && jsxc.xmpp.conn) {
|
||||
// jsxc.xmpp.conn.disconnect();
|
||||
// jsxc.triggeredFromElement = true;
|
||||
// }
|
||||
jsxc.xmpp.logout();
|
||||
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (key === 'friendReq') {
|
||||
n = JSON.parse(e.newValue);
|
||||
|
||||
if (jsxc.master && n.approve >= 0) {
|
||||
jsxc.xmpp.resFriendReq(n.jid, n.approve);
|
||||
}
|
||||
}
|
||||
|
||||
if (jsxc.master && key.match(new RegExp('^add' + jsxc.storage.SEP))) {
|
||||
n = JSON.parse(e.newValue);
|
||||
|
||||
jsxc.xmpp.addBuddy(n.username, n.alias);
|
||||
}
|
||||
|
||||
if (key === 'roster') {
|
||||
jsxc.gui.roster.toggle();
|
||||
}
|
||||
|
||||
if (jsxc.master && key.match(new RegExp('^vcard' + jsxc.storage.SEP)) && e.newValue !== null && e.newValue.match(/^request:/)) {
|
||||
|
||||
jsxc.xmpp.loadVcard(bid, function(stanza) {
|
||||
jsxc.storage.setUserItem('vcard', bid, {
|
||||
state: 'success',
|
||||
data: $('<div>').append(stanza).html()
|
||||
});
|
||||
}, function() {
|
||||
jsxc.storage.setUserItem('vcard', bid, {
|
||||
state: 'error'
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if (!jsxc.master && key.match(new RegExp('^vcard' + jsxc.storage.SEP)) && e.newValue !== null && !e.newValue.match(/^request:/)) {
|
||||
n = JSON.parse(e.newValue);
|
||||
|
||||
if (typeof n.state !== 'undefined') {
|
||||
$(document).trigger('loaded.vcard.jsxc', n);
|
||||
}
|
||||
|
||||
jsxc.storage.removeUserItem('vcard', bid);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Save message to storage.
|
||||
*
|
||||
* @memberOf jsxc.storage
|
||||
* @param bid
|
||||
* @param direction
|
||||
* @param msg
|
||||
* @param encrypted
|
||||
* @param forwarded
|
||||
* @param sender
|
||||
* @return post
|
||||
*/
|
||||
saveMessage: function(bid, direction, msg, encrypted, forwarded, stamp, sender) {
|
||||
var chat = jsxc.storage.getUserItem('chat', bid) || [];
|
||||
|
||||
var uid = new Date().getTime() + ':msg';
|
||||
|
||||
if (chat.length > jsxc.options.get('numberOfMsg')) {
|
||||
chat.pop();
|
||||
}
|
||||
|
||||
var post = {
|
||||
direction: direction,
|
||||
msg: msg,
|
||||
uid: uid.replace(/:/, '-'),
|
||||
received: false,
|
||||
encrypted: encrypted || false,
|
||||
forwarded: forwarded || false,
|
||||
stamp: stamp || new Date().getTime(),
|
||||
sender: sender
|
||||
};
|
||||
|
||||
chat.unshift(post);
|
||||
jsxc.storage.setUserItem('chat', bid, chat);
|
||||
|
||||
return post;
|
||||
},
|
||||
|
||||
/**
|
||||
* Save or update buddy data.
|
||||
*
|
||||
* @memberOf jsxc.storage
|
||||
* @param bid
|
||||
* @param data
|
||||
* @returns {String} Updated or created
|
||||
*/
|
||||
saveBuddy: function(bid, data) {
|
||||
|
||||
if (jsxc.storage.getUserItem('buddy', bid)) {
|
||||
jsxc.storage.updateUserItem('buddy', bid, data);
|
||||
|
||||
return 'updated';
|
||||
}
|
||||
|
||||
jsxc.storage.setUserItem('buddy', bid, $.extend({
|
||||
jid: '',
|
||||
name: '',
|
||||
status: 0,
|
||||
sub: 'none',
|
||||
msgstate: 0,
|
||||
transferReq: -1,
|
||||
trust: false,
|
||||
fingerprint: null,
|
||||
res: [],
|
||||
type: 'chat'
|
||||
}, data));
|
||||
|
||||
return 'created';
|
||||
}
|
||||
};
|
||||
</code></pre>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<nav>
|
||||
<h2><a href="index.html">Index</a></h2><h3>Namespaces</h3><ul><li><a href="jsxc.html">jsxc</a></li><li><a href="jsxc.gui.html">gui</a></li><li><a href="jsxc.gui.dialog.html">dialog</a></li><li><a href="jsxc.gui.queryActions.html">queryActions</a></li><li><a href="jsxc.gui.roster.html">roster</a></li><li><a href="jsxc.gui.window.html">window</a></li><li><a href="jsxc.muc.html">muc</a></li><li><a href="jsxc.notification.html">notification</a></li><li><a href="jsxc.options.html">options</a></li><li><a href="jsxc.otr.html">otr</a></li><li><a href="jsxc.storage.html">storage</a></li><li><a href="jsxc.webrtc.html">webrtc</a></li><li><a href="jsxc.xmpp.html">xmpp</a></li><li><a href="jsxc.xmpp.bookmarks.html">bookmarks</a></li><li><a href="jsxc.xmpp.carbons.html">carbons</a></li></ul><h3><a href="global.html">Global</a></h3>
|
||||
</nav>
|
||||
|
||||
<br clear="both">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.2.2</a> on Thu Sep 10 2015 11:03:21 GMT+0200 (CEST)
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
<script src="scripts/linenumber.js"> </script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,391 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>JSDoc: Source: jsxc.lib.xmpp.bookmarks.js</title>
|
||||
|
||||
<script src="scripts/prettify/prettify.js"> </script>
|
||||
<script src="scripts/prettify/lang-css.js"> </script>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
|
||||
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="main">
|
||||
|
||||
<h1 class="page-title">Source: jsxc.lib.xmpp.bookmarks.js</h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<section>
|
||||
<article>
|
||||
<pre class="prettyprint source"><code>/**
|
||||
* Load and save bookmarks according to XEP-0048.
|
||||
*
|
||||
* @namespace jsxc.xmpp.bookmarks
|
||||
*/
|
||||
jsxc.xmpp.bookmarks = {};
|
||||
|
||||
/**
|
||||
* Determines if server is able to store bookmarks.
|
||||
*
|
||||
* @return {boolean} True: Server supports bookmark storage
|
||||
*/
|
||||
jsxc.xmpp.bookmarks.remote = function() {
|
||||
return jsxc.xmpp.conn.caps && jsxc.xmpp.hasFeatureByJid(jsxc.xmpp.conn.domain, Strophe.NS.PUBSUB + "#publish");
|
||||
};
|
||||
|
||||
/**
|
||||
* Load bookmarks from pubsub.
|
||||
*
|
||||
* @memberOf jsxc.xmpp.bookmarks
|
||||
*/
|
||||
jsxc.xmpp.bookmarks.load = function() {
|
||||
var caps = jsxc.xmpp.conn.caps;
|
||||
var ver = caps._jidVerIndex[jsxc.xmpp.conn.domain];
|
||||
|
||||
if (!ver || !caps._knownCapabilities[ver]) {
|
||||
// wait until we know server capabilities
|
||||
$(document).on('caps.strophe', function(ev, from) {
|
||||
if (from === jsxc.xmpp.conn.domain) {
|
||||
jsxc.xmpp.bookmarks.load();
|
||||
|
||||
$(document).off(ev);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (jsxc.xmpp.bookmarks.remote()) {
|
||||
jsxc.xmpp.bookmarks.loadFromRemote();
|
||||
} else {
|
||||
jsxc.xmpp.bookmarks.loadFromLocal();
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Load bookmarks from local storage.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
jsxc.xmpp.bookmarks.loadFromLocal = function() {
|
||||
jsxc.debug('Load bookmarks from local storage');
|
||||
|
||||
var bookmarks = jsxc.storage.getUserItem('bookmarks') || [];
|
||||
var bl = jsxc.storage.getUserItem('buddylist') || [];
|
||||
|
||||
$.each(bookmarks, function() {
|
||||
var room = this;
|
||||
var roomdata = jsxc.storage.getUserItem('buddy', room) || {};
|
||||
|
||||
bl.push(room);
|
||||
jsxc.gui.roster.add(room);
|
||||
|
||||
if (roomdata.autojoin) {
|
||||
jsxc.debug('auto join ' + room);
|
||||
jsxc.xmpp.conn.muc.join(room, roomdata.nickname);
|
||||
}
|
||||
});
|
||||
|
||||
jsxc.storage.setUserItem('buddylist', bl);
|
||||
};
|
||||
|
||||
/**
|
||||
* Load bookmarks from remote storage.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
jsxc.xmpp.bookmarks.loadFromRemote = function() {
|
||||
jsxc.debug('Load bookmarks from pubsub');
|
||||
|
||||
var bookmarks = jsxc.xmpp.conn.bookmarks;
|
||||
|
||||
bookmarks.get(function(stanza) {
|
||||
var bl = jsxc.storage.getUserItem('buddylist');
|
||||
|
||||
$(stanza).find('conference').each(function() {
|
||||
var conference = $(this);
|
||||
var room = conference.attr('jid');
|
||||
var roomName = conference.attr('name') || room;
|
||||
var autojoin = conference.attr('autojoin') || false;
|
||||
var nickname = conference.find('nick').text();
|
||||
nickname = (nickname.length > 0) ? nickname : Strophe.getNodeFromJid(jsxc.xmpp.conn.jid);
|
||||
|
||||
if (autojoin === 'true') {
|
||||
autojoin = true;
|
||||
} else if (autojoin === 'false') {
|
||||
autojoin = false;
|
||||
}
|
||||
|
||||
var data = jsxc.storage.getUserItem('buddy', room) || {};
|
||||
|
||||
data = $.extend(data, {
|
||||
jid: room,
|
||||
name: roomName,
|
||||
sub: 'both',
|
||||
status: 0,
|
||||
type: 'groupchat',
|
||||
state: jsxc.muc.CONST.ROOMSTATE.INIT,
|
||||
subject: null,
|
||||
bookmarked: true,
|
||||
autojoin: autojoin,
|
||||
nickname: nickname
|
||||
});
|
||||
|
||||
jsxc.storage.setUserItem('buddy', room, data);
|
||||
|
||||
bl.push(room);
|
||||
jsxc.gui.roster.add(room);
|
||||
|
||||
if (autojoin) {
|
||||
jsxc.debug('auto join ' + room);
|
||||
jsxc.xmpp.conn.muc.join(room, nickname);
|
||||
}
|
||||
});
|
||||
|
||||
jsxc.storage.setUserItem('buddylist', bl);
|
||||
}, function(stanza) {
|
||||
var err = jsxc.xmpp.bookmarks.parseErr(stanza);
|
||||
|
||||
if (err.reasons[0] === 'item-not-found') {
|
||||
jsxc.debug('create bookmark node');
|
||||
|
||||
bookmarks.createBookmarksNode();
|
||||
} else {
|
||||
jsxc.debug('[XMPP] Could not create bookmark: ' + err.type, err.reasons);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Parse received error.
|
||||
*
|
||||
* @param {string} stanza
|
||||
* @return {object} err - The parsed error
|
||||
* @return {string} err.type - XMPP error type
|
||||
* @return {array} err.reasons - Array of error reasons
|
||||
*/
|
||||
jsxc.xmpp.bookmarks.parseErr = function(stanza) {
|
||||
var error = $(stanza).find('error');
|
||||
var type = error.attr('type');
|
||||
var reasons = error.children().map(function() {
|
||||
return $(this).prop('tagName');
|
||||
});
|
||||
|
||||
return {
|
||||
type: type,
|
||||
reasons: reasons
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Deletes the bookmark for the given room and removes it from the roster if soft is false.
|
||||
*
|
||||
* @param {string} room - room jid
|
||||
* @param {boolean} [soft=false] - True: leave room in roster
|
||||
*/
|
||||
jsxc.xmpp.bookmarks.delete = function(room, soft) {
|
||||
|
||||
if (!soft) {
|
||||
jsxc.gui.roster.purge(room);
|
||||
}
|
||||
|
||||
if (jsxc.xmpp.bookmarks.remote()) {
|
||||
jsxc.xmpp.bookmarks.deleteFromRemote(room, soft);
|
||||
} else {
|
||||
jsxc.xmpp.bookmarks.deleteFromLocal(room, soft);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete bookmark from remote storage.
|
||||
*
|
||||
* @private
|
||||
* @param {string} room - room jid
|
||||
* @param {boolean} [soft=false] - True: leave room in roster
|
||||
*/
|
||||
jsxc.xmpp.bookmarks.deleteFromRemote = function(room, soft) {
|
||||
var bookmarks = jsxc.xmpp.conn.bookmarks;
|
||||
|
||||
bookmarks.delete(room, function() {
|
||||
jsxc.debug('Bookmark deleted ' + room);
|
||||
|
||||
if (soft) {
|
||||
jsxc.gui.roster.getItem(room).removeClass('jsxc_bookmarked');
|
||||
jsxc.storage.updateUserItem('buddy', room, 'bookmarked', false);
|
||||
jsxc.storage.updateUserItem('buddy', room, 'autojoin', false);
|
||||
}
|
||||
}, function(stanza) {
|
||||
var err = jsxc.xmpp.bookmarks.parseErr(stanza);
|
||||
|
||||
jsxc.debug('[XMPP] Could not delete bookmark: ' + err.type, err.reasons);
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete bookmark from local storage.
|
||||
*
|
||||
* @private
|
||||
* @param {string} room - room jid
|
||||
* @param {boolean} [soft=false] - True: leave room in roster
|
||||
*/
|
||||
jsxc.xmpp.bookmarks.deleteFromLocal = function(room, soft) {
|
||||
var bookmarks = jsxc.storage.getUserItem('bookmarks');
|
||||
var index = bookmarks.indexOf(room);
|
||||
|
||||
if (index > -1) {
|
||||
bookmarks.splice(index, 1);
|
||||
}
|
||||
|
||||
jsxc.storage.setUserItem('bookmarks', bookmarks);
|
||||
|
||||
if (soft) {
|
||||
jsxc.gui.roster.getItem(room).removeClass('jsxc_bookmarked');
|
||||
jsxc.storage.updateUserItem('buddy', room, 'bookmarked', false);
|
||||
jsxc.storage.updateUserItem('buddy', room, 'autojoin', false);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds or overwrites bookmark for given room.
|
||||
*
|
||||
* @param {string} room - room jid
|
||||
* @param {string} alias - room alias
|
||||
* @param {string} nick - preferred user nickname
|
||||
* @param {boolean} autojoin - should we join this room after login?
|
||||
*/
|
||||
jsxc.xmpp.bookmarks.add = function(room, alias, nick, autojoin) {
|
||||
if (jsxc.xmpp.bookmarks.remote()) {
|
||||
jsxc.xmpp.bookmarks.addToRemote(room, alias, nick, autojoin);
|
||||
} else {
|
||||
jsxc.xmpp.bookmarks.addToLocal(room, alias, nick, autojoin);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds or overwrites bookmark for given room in remote storage.
|
||||
*
|
||||
* @private
|
||||
* @param {string} room - room jid
|
||||
* @param {string} alias - room alias
|
||||
* @param {string} nick - preferred user nickname
|
||||
* @param {boolean} autojoin - should we join this room after login?
|
||||
*/
|
||||
jsxc.xmpp.bookmarks.addToRemote = function(room, alias, nick, autojoin) {
|
||||
var bookmarks = jsxc.xmpp.conn.bookmarks;
|
||||
|
||||
var success = function() {
|
||||
jsxc.debug('New bookmark created', room);
|
||||
|
||||
jsxc.gui.roster.getItem(room).addClass('jsxc_bookmarked');
|
||||
jsxc.storage.updateUserItem('buddy', room, 'bookmarked', true);
|
||||
jsxc.storage.updateUserItem('buddy', room, 'autojoin', autojoin);
|
||||
jsxc.storage.updateUserItem('buddy', room, 'nickname', nick);
|
||||
};
|
||||
var error = function() {
|
||||
jsxc.warn('Could not create bookmark', room);
|
||||
};
|
||||
|
||||
bookmarks.add(room, alias, nick, autojoin, success, error);
|
||||
};
|
||||
|
||||
/**
|
||||
* Adds or overwrites bookmark for given room in local storage.
|
||||
*
|
||||
* @private
|
||||
* @param {string} room - room jid
|
||||
* @param {string} alias - room alias
|
||||
* @param {string} nick - preferred user nickname
|
||||
* @param {boolean} autojoin - should we join this room after login?
|
||||
*/
|
||||
jsxc.xmpp.bookmarks.addToLocal = function(room, alias, nick, autojoin) {
|
||||
jsxc.gui.roster.getItem(room).addClass('jsxc_bookmarked');
|
||||
jsxc.storage.updateUserItem('buddy', room, 'bookmarked', true);
|
||||
jsxc.storage.updateUserItem('buddy', room, 'autojoin', autojoin);
|
||||
jsxc.storage.updateUserItem('buddy', room, 'nickname', nick);
|
||||
|
||||
var bookmarks = jsxc.storage.getUserItem('bookmarks') || [];
|
||||
|
||||
if (bookmarks.indexOf(room) < 0) {
|
||||
bookmarks.push(room);
|
||||
|
||||
jsxc.storage.setUserItem('bookmarks', bookmarks);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Show dialog to edit bookmark.
|
||||
*
|
||||
* @param {string} room - room jid
|
||||
*/
|
||||
jsxc.xmpp.bookmarks.showDialog = function(room) {
|
||||
var dialog = jsxc.gui.dialog.open(jsxc.gui.template.get('bookmarkDialog'));
|
||||
var data = jsxc.storage.getUserItem('buddy', room);
|
||||
|
||||
$('#jsxc_room').val(room);
|
||||
$('#jsxc_nickname').val(data.nickname);
|
||||
|
||||
$('#jsxc_bookmark').change(function() {
|
||||
if ($(this).prop('checked')) {
|
||||
$('#jsxc_nickname').prop('disabled', false);
|
||||
$('#jsxc_autojoin').prop('disabled', false);
|
||||
$('#jsxc_autojoin').parent('.checkbox').removeClass('disabled');
|
||||
} else {
|
||||
$('#jsxc_nickname').prop('disabled', true);
|
||||
$('#jsxc_autojoin').prop('disabled', true).prop('checked', false);
|
||||
$('#jsxc_autojoin').parent('.checkbox').addClass('disabled');
|
||||
}
|
||||
});
|
||||
|
||||
$('#jsxc_bookmark').prop('checked', data.bookmarked);
|
||||
$('#jsxc_autojoin').prop('checked', data.autojoin);
|
||||
|
||||
$('#jsxc_bookmark').change();
|
||||
|
||||
dialog.find('form').submit(function(ev) {
|
||||
ev.preventDefault();
|
||||
|
||||
var bookmarked = $('#jsxc_bookmark').prop('checked');
|
||||
var autojoin = $('#jsxc_autojoin').prop('checked');
|
||||
var nickname = $('#jsxc_nickname').val();
|
||||
|
||||
if (bookmarked) {
|
||||
jsxc.xmpp.bookmarks.add(room, data.name, nickname, autojoin);
|
||||
} else if (data.bookmarked) {
|
||||
// bookmarked === false
|
||||
jsxc.xmpp.bookmarks.delete(room, true);
|
||||
}
|
||||
|
||||
jsxc.gui.dialog.close();
|
||||
|
||||
return false;
|
||||
});
|
||||
};
|
||||
</code></pre>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<nav>
|
||||
<h2><a href="index.html">Index</a></h2><h3>Namespaces</h3><ul><li><a href="jsxc.html">jsxc</a></li><li><a href="jsxc.gui.html">gui</a></li><li><a href="jsxc.gui.dialog.html">dialog</a></li><li><a href="jsxc.gui.queryActions.html">queryActions</a></li><li><a href="jsxc.gui.roster.html">roster</a></li><li><a href="jsxc.gui.window.html">window</a></li><li><a href="jsxc.muc.html">muc</a></li><li><a href="jsxc.notification.html">notification</a></li><li><a href="jsxc.options.html">options</a></li><li><a href="jsxc.otr.html">otr</a></li><li><a href="jsxc.storage.html">storage</a></li><li><a href="jsxc.webrtc.html">webrtc</a></li><li><a href="jsxc.xmpp.html">xmpp</a></li><li><a href="jsxc.xmpp.bookmarks.html">bookmarks</a></li><li><a href="jsxc.xmpp.carbons.html">carbons</a></li></ul><h3><a href="global.html">Global</a></h3>
|
||||
</nav>
|
||||
|
||||
<br clear="both">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.2.2</a> on Thu Sep 10 2015 11:03:21 GMT+0200 (CEST)
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
<script src="scripts/linenumber.js"> </script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,464 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>JSDoc: Namespace: carbons</title>
|
||||
|
||||
<script src="scripts/prettify/prettify.js"> </script>
|
||||
<script src="scripts/prettify/lang-css.js"> </script>
|
||||
<!--[if lt IE 9]>
|
||||
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
|
||||
<![endif]-->
|
||||
<link type="text/css" rel="stylesheet" href="styles/prettify-tomorrow.css">
|
||||
<link type="text/css" rel="stylesheet" href="styles/jsdoc-default.css">
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<div id="main">
|
||||
|
||||
<h1 class="page-title">Namespace: carbons</h1>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<section>
|
||||
|
||||
<header>
|
||||
<h2>
|
||||
<span class="ancestors"><a href="jsxc.html">jsxc</a><a href="jsxc.xmpp.html">.xmpp</a>.</span>
|
||||
|
||||
carbons
|
||||
</h2>
|
||||
|
||||
</header>
|
||||
|
||||
<article>
|
||||
<div class="container-overview">
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="description">Handle carbons (XEP-0280);</div>
|
||||
|
||||
|
||||
|
||||
<dl class="details">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="jsxc.lib.xmpp.js.html">jsxc.lib.xmpp.js</a>, <a href="jsxc.lib.xmpp.js.html#line1121">line 1121</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h3 class="subsection-title">Methods</h3>
|
||||
|
||||
<dl>
|
||||
|
||||
<dt>
|
||||
<h4 class="name" id="disable"><span class="type-signature"><static> </span>disable<span class="signature">(cb)</span><span class="type-signature"></span></h4>
|
||||
|
||||
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
<div class="description">
|
||||
Disable carbons.
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h5>Parameters:</h5>
|
||||
|
||||
|
||||
<table class="params">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
<th>Name</th>
|
||||
|
||||
|
||||
<th>Type</th>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<th class="last">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="name"><code>cb</code></td>
|
||||
|
||||
|
||||
<td class="type">
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<td class="description last">callback</td>
|
||||
</tr>
|
||||
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
<dl class="details">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="jsxc.lib.xmpp.js.html">jsxc.lib.xmpp.js</a>, <a href="jsxc.lib.xmpp.js.html#line1161">line 1161</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
|
||||
|
||||
|
||||
<dt>
|
||||
<h4 class="name" id="enable"><span class="type-signature"><static> </span>enable<span class="signature">(cb)</span><span class="type-signature"></span></h4>
|
||||
|
||||
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
<div class="description">
|
||||
Enable carbons.
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h5>Parameters:</h5>
|
||||
|
||||
|
||||
<table class="params">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
<th>Name</th>
|
||||
|
||||
|
||||
<th>Type</th>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<th class="last">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="name"><code>cb</code></td>
|
||||
|
||||
|
||||
<td class="type">
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<td class="description last">callback</td>
|
||||
</tr>
|
||||
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
<dl class="details">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="jsxc.lib.xmpp.js.html">jsxc.lib.xmpp.js</a>, <a href="jsxc.lib.xmpp.js.html#line1135">line 1135</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
|
||||
|
||||
|
||||
<dt>
|
||||
<h4 class="name" id="refresh"><span class="type-signature"><static> </span>refresh<span class="signature">(err)</span><span class="type-signature"></span></h4>
|
||||
|
||||
|
||||
</dt>
|
||||
<dd>
|
||||
|
||||
|
||||
<div class="description">
|
||||
Enable/Disable carbons depending on options key.
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<h5>Parameters:</h5>
|
||||
|
||||
|
||||
<table class="params">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
<th>Name</th>
|
||||
|
||||
|
||||
<th>Type</th>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<th class="last">Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
|
||||
|
||||
<tr>
|
||||
|
||||
<td class="name"><code>err</code></td>
|
||||
|
||||
|
||||
<td class="type">
|
||||
|
||||
</td>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<td class="description last">error message</td>
|
||||
</tr>
|
||||
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
|
||||
|
||||
<dl class="details">
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<dt class="tag-source">Source:</dt>
|
||||
<dd class="tag-source"><ul class="dummy"><li>
|
||||
<a href="jsxc.lib.xmpp.js.html">jsxc.lib.xmpp.js</a>, <a href="jsxc.lib.xmpp.js.html#line1187">line 1187</a>
|
||||
</li></ul></dd>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</article>
|
||||
|
||||
</section>
|
||||
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<nav>
|
||||
<h2><a href="index.html">Index</a></h2><h3>Namespaces</h3><ul><li><a href="jsxc.html">jsxc</a></li><li><a href="jsxc.gui.html">gui</a></li><li><a href="jsxc.gui.dialog.html">dialog</a></li><li><a href="jsxc.gui.queryActions.html">queryActions</a></li><li><a href="jsxc.gui.roster.html">roster</a></li><li><a href="jsxc.gui.window.html">window</a></li><li><a href="jsxc.muc.html">muc</a></li><li><a href="jsxc.notification.html">notification</a></li><li><a href="jsxc.options.html">options</a></li><li><a href="jsxc.otr.html">otr</a></li><li><a href="jsxc.storage.html">storage</a></li><li><a href="jsxc.webrtc.html">webrtc</a></li><li><a href="jsxc.xmpp.html">xmpp</a></li><li><a href="jsxc.xmpp.bookmarks.html">bookmarks</a></li><li><a href="jsxc.xmpp.carbons.html">carbons</a></li></ul><h3><a href="global.html">Global</a></h3>
|
||||
</nav>
|
||||
|
||||
<br clear="both">
|
||||
|
||||
<footer>
|
||||
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.2.2</a> on Thu Sep 10 2015 11:03:23 GMT+0200 (CEST)
|
||||
</footer>
|
||||
|
||||
<script> prettyPrint(); </script>
|
||||
<script src="scripts/linenumber.js"> </script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,17 @@
|
||||
(function() {
|
||||
var counter = 0;
|
||||
var numbered;
|
||||
var source = document.getElementsByClassName('prettyprint source');
|
||||
|
||||
if (source && source[0]) {
|
||||
source = source[0].getElementsByTagName('code')[0];
|
||||
|
||||
numbered = source.innerHTML.split('\n');
|
||||
numbered = numbered.map(function(item) {
|
||||
counter++;
|
||||
return '<span id="line' + counter + '" class="line"></span>' + item;
|
||||
});
|
||||
|
||||
source.innerHTML = numbered.join('\n');
|
||||
}
|
||||
})();
|
||||
@@ -0,0 +1,202 @@
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,2 @@
|
||||
PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n"]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com",
|
||||
/^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]);
|
||||
@@ -0,0 +1,28 @@
|
||||
var q=null;window.PR_SHOULD_USE_CONTINUATION=!0;
|
||||
(function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a=
|
||||
[],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c<i;++c){var j=f[c];if(/\\[bdsw]/i.test(j))a.push(j);else{var j=m(j),d;c+2<i&&"-"===f[c+1]?(d=m(f[c+2]),c+=2):d=j;b.push([j,d]);d<65||j>122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;c<b.length;++c)i=b[c],i[0]<=j[1]+1?j[1]=Math.max(j[1],i[1]):f.push(j=i);b=["["];o&&b.push("^");b.push.apply(b,a);for(c=0;c<
|
||||
f.length;++c)i=f[c],b.push(e(i[0])),i[1]>i[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c<b;++c){var j=f[c];j==="("?++i:"\\"===j.charAt(0)&&(j=+j.substring(1))&&j<=i&&(d[j]=-1)}for(c=1;c<d.length;++c)-1===d[c]&&(d[c]=++t);for(i=c=0;c<b;++c)j=f[c],j==="("?(++i,d[i]===void 0&&(f[c]="(?:")):"\\"===j.charAt(0)&&
|
||||
(j=+j.substring(1))&&j<=i&&(f[c]="\\"+d[i]);for(i=c=0;c<b;++c)"^"===f[c]&&"^"!==f[c+1]&&(f[c]="");if(a.ignoreCase&&s)for(c=0;c<b;++c)j=f[c],a=j.charAt(0),j.length>=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p<d;++p){var g=a[p];if(g.ignoreCase)l=!0;else if(/[a-z]/i.test(g.source.replace(/\\u[\da-f]{4}|\\x[\da-f]{2}|\\[^UXux]/gi,""))){s=!0;l=!1;break}}for(var r=
|
||||
{b:8,t:9,n:10,v:11,f:12,r:13},n=[],p=0,d=a.length;p<d;++p){g=a[p];if(g.global||g.multiline)throw Error(""+g);n.push("(?:"+y(g)+")")}return RegExp(n.join("|"),l?"gi":"g")}function M(a){function m(a){switch(a.nodeType){case 1:if(e.test(a.className))break;for(var g=a.firstChild;g;g=g.nextSibling)m(g);g=a.nodeName;if("BR"===g||"LI"===g)h[s]="\n",t[s<<1]=y++,t[s++<<1|1]=a;break;case 3:case 4:g=a.nodeValue,g.length&&(g=p?g.replace(/\r\n?/g,"\n"):g.replace(/[\t\n\r ]+/g," "),h[s]=g,t[s<<1]=y,y+=g.length,
|
||||
t[s++<<1|1]=a)}}var e=/(?:^|\s)nocode(?:\s|$)/,h=[],y=0,t=[],s=0,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=document.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);m(a);return{a:h.join("").replace(/\n$/,""),c:t}}function B(a,m,e,h){m&&(a={a:m,d:a},e(a),h.push.apply(h,a.e))}function x(a,m){function e(a){for(var l=a.d,p=[l,"pln"],d=0,g=a.a.match(y)||[],r={},n=0,z=g.length;n<z;++n){var f=g[n],b=r[f],o=void 0,c;if(typeof b===
|
||||
"string")c=!1;else{var i=h[f.charAt(0)];if(i)o=f.match(i[1]),b=i[0];else{for(c=0;c<t;++c)if(i=m[c],o=f.match(i[1])){b=i[0];break}o||(b="pln")}if((c=b.length>=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m),
|
||||
l=[],p={},d=0,g=e.length;d<g;++d){var r=e[d],n=r[3];if(n)for(var k=n.length;--k>=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/,
|
||||
q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/,
|
||||
q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g,
|
||||
"");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a),
|
||||
a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e}
|
||||
for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g<d.length;++g)e(d[g]);m===(m|0)&&d[0].setAttribute("value",
|
||||
m);var r=s.createElement("OL");r.className="linenums";for(var n=Math.max(0,m-1|0)||0,g=0,z=d.length;g<z;++g)l=d[g],l.className="L"+(g+n)%10,l.firstChild||l.appendChild(s.createTextNode("\xa0")),r.appendChild(l);a.appendChild(r)}function k(a,m){for(var e=m.length;--e>=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*</.test(m)?"default-markup":"default-code";return A[a]}function E(a){var m=
|
||||
a.g;try{var e=M(a.h),h=e.a;a.a=h;a.c=e.c;a.d=0;C(m,h)(a);var k=/\bMSIE\b/.test(navigator.userAgent),m=/\n/g,t=a.a,s=t.length,e=0,l=a.c,p=l.length,h=0,d=a.e,g=d.length,a=0;d[g]=s;var r,n;for(n=r=0;n<g;)d[n]!==d[n+2]?(d[r++]=d[n++],d[r++]=d[n++]):n+=2;g=r;for(n=r=0;n<g;){for(var z=d[n],f=d[n+1],b=n+2;b+2<=g&&d[b+1]===f;)b+=2;d[r++]=z;d[r++]=f;n=b}for(d.length=r;h<p;){var o=l[h+2]||s,c=d[a+2]||s,b=Math.min(o,c),i=l[h+1],j;if(i.nodeType!==1&&(j=t.substring(e,b))){k&&(j=j.replace(m,"\r"));i.nodeValue=
|
||||
j;var u=i.ownerDocument,v=u.createElement("SPAN");v.className=d[a+1];var x=i.parentNode;x.replaceChild(v,i);v.appendChild(i);e<o&&(l[h+1]=i=u.createTextNode(t.substring(b,o)),x.insertBefore(i,v.nextSibling))}e=b;e>=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],
|
||||
"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"],
|
||||
H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],
|
||||
J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+
|
||||
I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^<?]+/],["dec",/^<!\w[^>]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),
|
||||
["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css",
|
||||
/^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),
|
||||
["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes",
|
||||
hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p<h.length&&l.now()<e;p++){var n=h[p],k=n.className;if(k.indexOf("prettyprint")>=0){var k=k.match(g),f,b;if(b=
|
||||
!k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p<h.length?setTimeout(m,
|
||||
250):a&&a()}for(var e=[document.getElementsByTagName("pre"),document.getElementsByTagName("code"),document.getElementsByTagName("xmp")],h=[],k=0;k<e.length;++k)for(var t=0,s=e[k].length;t<s;++t)h.push(e[k][t]);var e=q,l=Date;l.now||(l={now:function(){return+new Date}});var p=0,d,g=/\blang(?:uage)?-([\w.]+)(?!\S)/;m()};window.PR={createSimpleLexer:x,registerLangHandler:k,sourceDecorator:u,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",
|
||||
PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ"}})();
|
||||
@@ -0,0 +1,290 @@
|
||||
html
|
||||
{
|
||||
overflow: auto;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
body
|
||||
{
|
||||
font: 14px "DejaVu Sans Condensed", "Liberation Sans", "Nimbus Sans L", Tahoma, Geneva, "Helvetica Neue", Helvetica, Arial, sans serif;
|
||||
line-height: 130%;
|
||||
color: #000;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
a:active {
|
||||
color: #444;
|
||||
}
|
||||
|
||||
header
|
||||
{
|
||||
display: block;
|
||||
padding: 6px 4px;
|
||||
}
|
||||
|
||||
.class-description {
|
||||
font-style: italic;
|
||||
font-family: Palatino, 'Palatino Linotype', serif;
|
||||
font-size: 130%;
|
||||
line-height: 140%;
|
||||
margin-bottom: 1em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
#main {
|
||||
float: left;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
section
|
||||
{
|
||||
display: block;
|
||||
|
||||
background-color: #fff;
|
||||
padding: 12px 24px;
|
||||
border-bottom: 1px solid #ccc;
|
||||
margin-right: 240px;
|
||||
}
|
||||
|
||||
.variation {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.optional:after {
|
||||
content: "opt";
|
||||
font-size: 60%;
|
||||
color: #aaa;
|
||||
font-style: italic;
|
||||
font-weight: lighter;
|
||||
}
|
||||
|
||||
nav
|
||||
{
|
||||
display: block;
|
||||
float: left;
|
||||
margin-left: -230px;
|
||||
margin-top: 28px;
|
||||
width: 220px;
|
||||
border-left: 1px solid #ccc;
|
||||
padding-left: 9px;
|
||||
}
|
||||
|
||||
nav ul {
|
||||
font-family: 'Lucida Grande', 'Lucida Sans Unicode', arial, sans-serif;
|
||||
font-size: 100%;
|
||||
line-height: 17px;
|
||||
padding:0;
|
||||
margin:0;
|
||||
list-style-type:none;
|
||||
}
|
||||
|
||||
nav h2 a, nav h2 a:visited {
|
||||
color: #A35A00;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
nav h3 {
|
||||
margin-top: 12px;
|
||||
}
|
||||
|
||||
nav li {
|
||||
margin-top: 6px;
|
||||
}
|
||||
|
||||
nav a {
|
||||
color: #5C5954;
|
||||
}
|
||||
|
||||
nav a:visited {
|
||||
color: #5C5954;
|
||||
}
|
||||
|
||||
nav a:active {
|
||||
color: #5C5954;
|
||||
}
|
||||
|
||||
footer {
|
||||
display: block;
|
||||
padding: 6px;
|
||||
margin-top: 12px;
|
||||
font-style: italic;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
h1
|
||||
{
|
||||
font-size: 200%;
|
||||
font-weight: bold;
|
||||
letter-spacing: -0.01em;
|
||||
margin: 6px 0 9px 0;
|
||||
}
|
||||
|
||||
h2
|
||||
{
|
||||
font-size: 170%;
|
||||
font-weight: bold;
|
||||
letter-spacing: -0.01em;
|
||||
margin: 6px 0 3px 0;
|
||||
}
|
||||
|
||||
h3
|
||||
{
|
||||
font-size: 150%;
|
||||
font-weight: bold;
|
||||
letter-spacing: -0.01em;
|
||||
margin-top: 16px;
|
||||
margin: 6px 0 3px 0;
|
||||
}
|
||||
|
||||
h4
|
||||
{
|
||||
font-size: 130%;
|
||||
font-weight: bold;
|
||||
letter-spacing: -0.01em;
|
||||
margin-top: 16px;
|
||||
margin: 18px 0 3px 0;
|
||||
color: #A35A00;
|
||||
}
|
||||
|
||||
h5, .container-overview .subsection-title
|
||||
{
|
||||
font-size: 120%;
|
||||
font-weight: bold;
|
||||
letter-spacing: -0.01em;
|
||||
margin: 8px 0 3px -16px;
|
||||
}
|
||||
|
||||
h6
|
||||
{
|
||||
font-size: 100%;
|
||||
letter-spacing: -0.01em;
|
||||
margin: 6px 0 3px 0;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.ancestors { color: #999; }
|
||||
.ancestors a
|
||||
{
|
||||
color: #999 !important;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.important
|
||||
{
|
||||
font-weight: bold;
|
||||
color: #950B02;
|
||||
}
|
||||
|
||||
.yes-def {
|
||||
text-indent: -1000px;
|
||||
}
|
||||
|
||||
.type-signature {
|
||||
color: #aaa;
|
||||
}
|
||||
|
||||
.name, .signature {
|
||||
font-family: Consolas, "Lucida Console", Monaco, monospace;
|
||||
}
|
||||
|
||||
.details { margin-top: 14px; border-left: 2px solid #DDD; }
|
||||
.details dt { width:100px; float:left; padding-left: 10px; padding-top: 6px; }
|
||||
.details dd { margin-left: 50px; }
|
||||
.details ul { margin: 0; }
|
||||
.details ul { list-style-type: none; }
|
||||
.details li { margin-left: 30px; padding-top: 6px; }
|
||||
.details pre.prettyprint { margin: 0 }
|
||||
.details .object-value { padding-top: 0; }
|
||||
|
||||
.description {
|
||||
margin-bottom: 1em;
|
||||
margin-left: -16px;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.code-caption
|
||||
{
|
||||
font-style: italic;
|
||||
font-family: Palatino, 'Palatino Linotype', serif;
|
||||
font-size: 107%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.prettyprint
|
||||
{
|
||||
border: 1px solid #ddd;
|
||||
width: 80%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.prettyprint.source {
|
||||
width: inherit;
|
||||
}
|
||||
|
||||
.prettyprint code
|
||||
{
|
||||
font-family: Consolas, 'Lucida Console', Monaco, monospace;
|
||||
font-size: 100%;
|
||||
line-height: 18px;
|
||||
display: block;
|
||||
padding: 4px 12px;
|
||||
margin: 0;
|
||||
background-color: #fff;
|
||||
color: #000;
|
||||
border-left: 3px #ddd solid;
|
||||
}
|
||||
|
||||
.prettyprint code span.line
|
||||
{
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.params, .props
|
||||
{
|
||||
border-spacing: 0;
|
||||
border: 0;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.params .name, .props .name, .name code {
|
||||
color: #A35A00;
|
||||
font-family: Consolas, 'Lucida Console', Monaco, monospace;
|
||||
font-size: 100%;
|
||||
}
|
||||
|
||||
.params td, .params th, .props td, .props th
|
||||
{
|
||||
border: 1px solid #ddd;
|
||||
margin: 0px;
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
padding: 4px 6px;
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
.params thead tr, .props thead tr
|
||||
{
|
||||
background-color: #ddd;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.params .params thead tr, .props .props thead tr
|
||||
{
|
||||
background-color: #fff;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.params th, .props th { border-right: 1px solid #aaa; }
|
||||
.params thead .last, .props thead .last { border-right: 1px solid #ddd; }
|
||||
|
||||
.disabled {
|
||||
color: #454545;
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/* JSDoc prettify.js theme */
|
||||
|
||||
/* plain text */
|
||||
.pln {
|
||||
color: #000000;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* string content */
|
||||
.str {
|
||||
color: #006400;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* a keyword */
|
||||
.kwd {
|
||||
color: #000000;
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* a comment */
|
||||
.com {
|
||||
font-weight: normal;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* a type name */
|
||||
.typ {
|
||||
color: #000000;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* a literal value */
|
||||
.lit {
|
||||
color: #006400;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* punctuation */
|
||||
.pun {
|
||||
color: #000000;
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* lisp open bracket */
|
||||
.opn {
|
||||
color: #000000;
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* lisp close bracket */
|
||||
.clo {
|
||||
color: #000000;
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* a markup tag name */
|
||||
.tag {
|
||||
color: #006400;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* a markup attribute name */
|
||||
.atn {
|
||||
color: #006400;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* a markup attribute value */
|
||||
.atv {
|
||||
color: #006400;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* a declaration */
|
||||
.dec {
|
||||
color: #000000;
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* a variable name */
|
||||
.var {
|
||||
color: #000000;
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* a function name */
|
||||
.fun {
|
||||
color: #000000;
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
/* Specify class=linenums on a pre to get line numbering */
|
||||
ol.linenums {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
/* Tomorrow Theme */
|
||||
/* Original theme - https://github.com/chriskempson/tomorrow-theme */
|
||||
/* Pretty printing styles. Used with prettify.js. */
|
||||
/* SPAN elements with the classes below are added by prettyprint. */
|
||||
/* plain text */
|
||||
.pln {
|
||||
color: #4d4d4c; }
|
||||
|
||||
@media screen {
|
||||
/* string content */
|
||||
.str {
|
||||
color: #718c00; }
|
||||
|
||||
/* a keyword */
|
||||
.kwd {
|
||||
color: #8959a8; }
|
||||
|
||||
/* a comment */
|
||||
.com {
|
||||
color: #8e908c; }
|
||||
|
||||
/* a type name */
|
||||
.typ {
|
||||
color: #4271ae; }
|
||||
|
||||
/* a literal value */
|
||||
.lit {
|
||||
color: #f5871f; }
|
||||
|
||||
/* punctuation */
|
||||
.pun {
|
||||
color: #4d4d4c; }
|
||||
|
||||
/* lisp open bracket */
|
||||
.opn {
|
||||
color: #4d4d4c; }
|
||||
|
||||
/* lisp close bracket */
|
||||
.clo {
|
||||
color: #4d4d4c; }
|
||||
|
||||
/* a markup tag name */
|
||||
.tag {
|
||||
color: #c82829; }
|
||||
|
||||
/* a markup attribute name */
|
||||
.atn {
|
||||
color: #f5871f; }
|
||||
|
||||
/* a markup attribute value */
|
||||
.atv {
|
||||
color: #3e999f; }
|
||||
|
||||
/* a declaration */
|
||||
.dec {
|
||||
color: #f5871f; }
|
||||
|
||||
/* a variable name */
|
||||
.var {
|
||||
color: #c82829; }
|
||||
|
||||
/* a function name */
|
||||
.fun {
|
||||
color: #4271ae; } }
|
||||
/* Use higher contrast and text-weight for printable form. */
|
||||
@media print, projection {
|
||||
.str {
|
||||
color: #060; }
|
||||
|
||||
.kwd {
|
||||
color: #006;
|
||||
font-weight: bold; }
|
||||
|
||||
.com {
|
||||
color: #600;
|
||||
font-style: italic; }
|
||||
|
||||
.typ {
|
||||
color: #404;
|
||||
font-weight: bold; }
|
||||
|
||||
.lit {
|
||||
color: #044; }
|
||||
|
||||
.pun, .opn, .clo {
|
||||
color: #440; }
|
||||
|
||||
.tag {
|
||||
color: #006;
|
||||
font-weight: bold; }
|
||||
|
||||
.atn {
|
||||
color: #404; }
|
||||
|
||||
.atv {
|
||||
color: #060; } }
|
||||
/* Style */
|
||||
/*
|
||||
pre.prettyprint {
|
||||
background: white;
|
||||
font-family: Menlo, Monaco, Consolas, monospace;
|
||||
font-size: 12px;
|
||||
line-height: 1.5;
|
||||
border: 1px solid #ccc;
|
||||
padding: 10px; }
|
||||
*/
|
||||
|
||||
/* Specify class=linenums on a pre to get line numbering */
|
||||
ol.linenums {
|
||||
margin-top: 0;
|
||||
margin-bottom: 0; }
|
||||
|
||||
/* IE indents via margin-left */
|
||||
li.L0,
|
||||
li.L1,
|
||||
li.L2,
|
||||
li.L3,
|
||||
li.L4,
|
||||
li.L5,
|
||||
li.L6,
|
||||
li.L7,
|
||||
li.L8,
|
||||
li.L9 {
|
||||
/* */ }
|
||||
|
||||
/* Alternate shading for lines */
|
||||
li.L1,
|
||||
li.L3,
|
||||
li.L5,
|
||||
li.L7,
|
||||
li.L9 {
|
||||
/* */ }
|
||||
@@ -0,0 +1 @@
|
||||
{"url":"numb.viagenie.ca","username":"webrtc@live.com","credential":"muazkh","ttl":43200}
|
||||
@@ -0,0 +1,28 @@
|
||||
body {
|
||||
margin-top: 30px;
|
||||
}
|
||||
|
||||
.logout {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#content form .alert {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#content h3 {
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
#content .form {
|
||||
min-height: 180px;
|
||||
}
|
||||
|
||||
#content .row:first-child {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
#content .col-md-4 > p {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>JSXC example application</title>
|
||||
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico">
|
||||
|
||||
<link href="css/bootstrap.min.css" media="all" rel="stylesheet" type="text/css" />
|
||||
|
||||
<!-- require:dependencies -->
|
||||
<link href="../build/css/jquery-ui.min.css" media="all" rel="stylesheet" type="text/css" />
|
||||
<link href="../dev/css/jsxc.css" media="all" rel="stylesheet" type="text/css" />
|
||||
<link href="../dev/css/jsxc.webrtc.css" media="all" rel="stylesheet" type="text/css" />
|
||||
<!-- endrequire -->
|
||||
|
||||
<link href="css/example.css" media="all" rel="stylesheet" type="text/css" />
|
||||
|
||||
<!-- require:dependencies -->
|
||||
<script src="../dev/lib/jquery.min.js"></script>
|
||||
<script src="../dev/lib/jquery.ui.min.js"></script>
|
||||
<script src="../dev/lib/jquery.colorbox-min.js"></script>
|
||||
<script src="../dev/lib/jquery.slimscroll.js"></script>
|
||||
<script src="../dev/lib/jquery.fullscreen.js"></script>
|
||||
<script src="../dev/lib/jsxc.dep.js"></script>
|
||||
<!-- endrequire -->
|
||||
|
||||
<script src="js/bootstrap.min.js"></script>
|
||||
|
||||
<!-- jsxc library -->
|
||||
<script src="../dev/jsxc.js"></script>
|
||||
|
||||
<!-- init script -->
|
||||
<script src="js/dev.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container" id="content" role="main">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-12">
|
||||
<h1 class="page-header">JSXC <small>developer example</small></h1>
|
||||
|
||||
<p>This example demonstrates different types of login methods for <a href="https://www.jsxc.org/">JSXC</a>. You find further information in our <a href="https://github.com/jsxc/jsxc/wiki">wiki</a>.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
|
||||
<div class="col-xs-12 col-md-4">
|
||||
<h3>Dual-Login</h3>
|
||||
|
||||
<p>You should use this method if you have already a login in your website.</p>
|
||||
|
||||
<form id="form" method="post" action="login.html" class="form form-horizontal">
|
||||
<fieldset>
|
||||
<div class="form-group">
|
||||
<label for="username" class="col-xs-4 control-label">Username:</label>
|
||||
<div class="col-xs-8">
|
||||
<input type="text" id="username" name="username" class="form-control" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password" class="col-xs-4 control-label">Password:</label>
|
||||
<div class="col-xs-8">
|
||||
<input type="password" id="password" name="password" class="form-control" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-xs-offset-4 col-xs-8">
|
||||
<button type="submit" class="submit btn btn-primary">Log in chat and submit</button>
|
||||
<button class="logout btn btn-default" style="display:none;">Log out</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
<pre><form id="form">
|
||||
<input type="text" id="username" />
|
||||
<input type="password" id="password" />
|
||||
<input type="submit" value="Submit" />
|
||||
</form>
|
||||
|
||||
<button id="logout">Logout</button></pre>
|
||||
|
||||
<pre>jsxc.init({
|
||||
loginForm: {
|
||||
form: '#form',
|
||||
jid: '#username',
|
||||
pass: '#password'
|
||||
},
|
||||
logoutElement: $('#logout'),
|
||||
loadSettings: function() {
|
||||
return xmpp: {
|
||||
url: '/http-bind/',
|
||||
domain: 'localhost',
|
||||
resource: 'example',
|
||||
overwrite: true,
|
||||
onlogin: true
|
||||
};
|
||||
},
|
||||
root: '/jsxc/'
|
||||
});</pre>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col-xs-12 col-md-4">
|
||||
<h3>AJAX Login</h3>
|
||||
|
||||
<p>Do you want to login directly within your script? Choose this type.
|
||||
|
||||
<form id="form2" class="form form-horizontal">
|
||||
<fieldset>
|
||||
<div class="alert alert-warning col-xs-12" role="alert">
|
||||
<strong>Warning!</strong> Your username or password is wrong!
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="username2" class="col-xs-4 control-label">Username:</label>
|
||||
<div class="col-xs-8">
|
||||
<input type="text" id="username2" class="form-control" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="password2" class="col-xs-4 control-label">Password:</label>
|
||||
<div class="col-xs-8">
|
||||
<input type="password" id="password2" class="form-control" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-xs-offset-4 col-xs-8">
|
||||
<button type="submit" id="submit2" class="submit btn btn-primary" data-loading-text="Logging in...">Log in chat</button>
|
||||
<button class="logout btn btn-default">Log out</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
<pre><input type="text" id="username" />
|
||||
<input type="password" id="password" />
|
||||
<button id="submit">Log in</button></pre>
|
||||
|
||||
<pre>jsxc.init({
|
||||
xmpp: {
|
||||
url: '/http-bind/'
|
||||
},
|
||||
root: '/jsxc/'
|
||||
});
|
||||
|
||||
$('#submit').click(function(){
|
||||
var username = $('#username').val();
|
||||
var password = $('#password').val();
|
||||
|
||||
var jid = username + '@localhost';
|
||||
|
||||
jsxc.xmpp.login(jid , password);
|
||||
});
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-12 col-md-4">
|
||||
<h3>Box Login</h3>
|
||||
|
||||
<p>Do you look for a discrete login method? Choose this.</p>
|
||||
|
||||
<div class="form" id="form3">
|
||||
<button class="submit btn btn-primary">Open Box</button>
|
||||
<button class="logout btn btn-default">Log out</button>
|
||||
</div>
|
||||
|
||||
<pre><button id="button">Open Box</button></pre>
|
||||
|
||||
<pre>jsxc.init({
|
||||
loadSettings: function() {
|
||||
return xmpp: {
|
||||
url: '/http-bind/',
|
||||
domain: 'localhost',
|
||||
resource: 'example',
|
||||
overwrite: true,
|
||||
onlogin: true
|
||||
};
|
||||
},
|
||||
root: '/jsxc/'
|
||||
});
|
||||
|
||||
$('#button').click(jsxc.gui.showLoginBox);</pre>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
Depois Largura: | Altura: | Tamanho: 38 KiB |
@@ -0,0 +1,288 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<metadata></metadata>
|
||||
<defs>
|
||||
<font id="glyphicons_halflingsregular" horiz-adv-x="1200" >
|
||||
<font-face units-per-em="1200" ascent="960" descent="-240" />
|
||||
<missing-glyph horiz-adv-x="500" />
|
||||
<glyph horiz-adv-x="0" />
|
||||
<glyph horiz-adv-x="400" />
|
||||
<glyph unicode=" " />
|
||||
<glyph unicode="*" d="M600 1100q15 0 34 -1.5t30 -3.5l11 -1q10 -2 17.5 -10.5t7.5 -18.5v-224l158 158q7 7 18 8t19 -6l106 -106q7 -8 6 -19t-8 -18l-158 -158h224q10 0 18.5 -7.5t10.5 -17.5q6 -41 6 -75q0 -15 -1.5 -34t-3.5 -30l-1 -11q-2 -10 -10.5 -17.5t-18.5 -7.5h-224l158 -158 q7 -7 8 -18t-6 -19l-106 -106q-8 -7 -19 -6t-18 8l-158 158v-224q0 -10 -7.5 -18.5t-17.5 -10.5q-41 -6 -75 -6q-15 0 -34 1.5t-30 3.5l-11 1q-10 2 -17.5 10.5t-7.5 18.5v224l-158 -158q-7 -7 -18 -8t-19 6l-106 106q-7 8 -6 19t8 18l158 158h-224q-10 0 -18.5 7.5 t-10.5 17.5q-6 41 -6 75q0 15 1.5 34t3.5 30l1 11q2 10 10.5 17.5t18.5 7.5h224l-158 158q-7 7 -8 18t6 19l106 106q8 7 19 6t18 -8l158 -158v224q0 10 7.5 18.5t17.5 10.5q41 6 75 6z" />
|
||||
<glyph unicode="+" d="M450 1100h200q21 0 35.5 -14.5t14.5 -35.5v-350h350q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-350v-350q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v350h-350q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5 h350v350q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode=" " />
|
||||
<glyph unicode="¥" d="M825 1100h250q10 0 12.5 -5t-5.5 -13l-364 -364q-6 -6 -11 -18h268q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-125v-100h275q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-125v-174q0 -11 -7.5 -18.5t-18.5 -7.5h-148q-11 0 -18.5 7.5t-7.5 18.5v174 h-275q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h125v100h-275q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h118q-5 12 -11 18l-364 364q-8 8 -5.5 13t12.5 5h250q25 0 43 -18l164 -164q8 -8 18 -8t18 8l164 164q18 18 43 18z" />
|
||||
<glyph unicode=" " horiz-adv-x="650" />
|
||||
<glyph unicode=" " horiz-adv-x="1300" />
|
||||
<glyph unicode=" " horiz-adv-x="650" />
|
||||
<glyph unicode=" " horiz-adv-x="1300" />
|
||||
<glyph unicode=" " horiz-adv-x="433" />
|
||||
<glyph unicode=" " horiz-adv-x="325" />
|
||||
<glyph unicode=" " horiz-adv-x="216" />
|
||||
<glyph unicode=" " horiz-adv-x="216" />
|
||||
<glyph unicode=" " horiz-adv-x="162" />
|
||||
<glyph unicode=" " horiz-adv-x="260" />
|
||||
<glyph unicode=" " horiz-adv-x="72" />
|
||||
<glyph unicode=" " horiz-adv-x="260" />
|
||||
<glyph unicode=" " horiz-adv-x="325" />
|
||||
<glyph unicode="€" d="M744 1198q242 0 354 -189q60 -104 66 -209h-181q0 45 -17.5 82.5t-43.5 61.5t-58 40.5t-60.5 24t-51.5 7.5q-19 0 -40.5 -5.5t-49.5 -20.5t-53 -38t-49 -62.5t-39 -89.5h379l-100 -100h-300q-6 -50 -6 -100h406l-100 -100h-300q9 -74 33 -132t52.5 -91t61.5 -54.5t59 -29 t47 -7.5q22 0 50.5 7.5t60.5 24.5t58 41t43.5 61t17.5 80h174q-30 -171 -128 -278q-107 -117 -274 -117q-206 0 -324 158q-36 48 -69 133t-45 204h-217l100 100h112q1 47 6 100h-218l100 100h134q20 87 51 153.5t62 103.5q117 141 297 141z" />
|
||||
<glyph unicode="₽" d="M428 1200h350q67 0 120 -13t86 -31t57 -49.5t35 -56.5t17 -64.5t6.5 -60.5t0.5 -57v-16.5v-16.5q0 -36 -0.5 -57t-6.5 -61t-17 -65t-35 -57t-57 -50.5t-86 -31.5t-120 -13h-178l-2 -100h288q10 0 13 -6t-3 -14l-120 -160q-6 -8 -18 -14t-22 -6h-138v-175q0 -11 -5.5 -18 t-15.5 -7h-149q-10 0 -17.5 7.5t-7.5 17.5v175h-267q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h117v100h-267q-10 0 -13 6t3 14l120 160q6 8 18 14t22 6h117v475q0 10 7.5 17.5t17.5 7.5zM600 1000v-300h203q64 0 86.5 33t22.5 119q0 84 -22.5 116t-86.5 32h-203z" />
|
||||
<glyph unicode="−" d="M250 700h800q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="⌛" d="M1000 1200v-150q0 -21 -14.5 -35.5t-35.5 -14.5h-50v-100q0 -91 -49.5 -165.5t-130.5 -109.5q81 -35 130.5 -109.5t49.5 -165.5v-150h50q21 0 35.5 -14.5t14.5 -35.5v-150h-800v150q0 21 14.5 35.5t35.5 14.5h50v150q0 91 49.5 165.5t130.5 109.5q-81 35 -130.5 109.5 t-49.5 165.5v100h-50q-21 0 -35.5 14.5t-14.5 35.5v150h800zM400 1000v-100q0 -60 32.5 -109.5t87.5 -73.5q28 -12 44 -37t16 -55t-16 -55t-44 -37q-55 -24 -87.5 -73.5t-32.5 -109.5v-150h400v150q0 60 -32.5 109.5t-87.5 73.5q-28 12 -44 37t-16 55t16 55t44 37 q55 24 87.5 73.5t32.5 109.5v100h-400z" />
|
||||
<glyph unicode="◼" horiz-adv-x="500" d="M0 0z" />
|
||||
<glyph unicode="☁" d="M503 1089q110 0 200.5 -59.5t134.5 -156.5q44 14 90 14q120 0 205 -86.5t85 -206.5q0 -121 -85 -207.5t-205 -86.5h-750q-79 0 -135.5 57t-56.5 137q0 69 42.5 122.5t108.5 67.5q-2 12 -2 37q0 153 108 260.5t260 107.5z" />
|
||||
<glyph unicode="⛺" d="M774 1193.5q16 -9.5 20.5 -27t-5.5 -33.5l-136 -187l467 -746h30q20 0 35 -18.5t15 -39.5v-42h-1200v42q0 21 15 39.5t35 18.5h30l468 746l-135 183q-10 16 -5.5 34t20.5 28t34 5.5t28 -20.5l111 -148l112 150q9 16 27 20.5t34 -5zM600 200h377l-182 112l-195 534v-646z " />
|
||||
<glyph unicode="✉" d="M25 1100h1150q10 0 12.5 -5t-5.5 -13l-564 -567q-8 -8 -18 -8t-18 8l-564 567q-8 8 -5.5 13t12.5 5zM18 882l264 -264q8 -8 8 -18t-8 -18l-264 -264q-8 -8 -13 -5.5t-5 12.5v550q0 10 5 12.5t13 -5.5zM918 618l264 264q8 8 13 5.5t5 -12.5v-550q0 -10 -5 -12.5t-13 5.5 l-264 264q-8 8 -8 18t8 18zM818 482l364 -364q8 -8 5.5 -13t-12.5 -5h-1150q-10 0 -12.5 5t5.5 13l364 364q8 8 18 8t18 -8l164 -164q8 -8 18 -8t18 8l164 164q8 8 18 8t18 -8z" />
|
||||
<glyph unicode="✏" d="M1011 1210q19 0 33 -13l153 -153q13 -14 13 -33t-13 -33l-99 -92l-214 214l95 96q13 14 32 14zM1013 800l-615 -614l-214 214l614 614zM317 96l-333 -112l110 335z" />
|
||||
<glyph unicode="" d="M700 650v-550h250q21 0 35.5 -14.5t14.5 -35.5v-50h-800v50q0 21 14.5 35.5t35.5 14.5h250v550l-500 550h1200z" />
|
||||
<glyph unicode="" d="M368 1017l645 163q39 15 63 0t24 -49v-831q0 -55 -41.5 -95.5t-111.5 -63.5q-79 -25 -147 -4.5t-86 75t25.5 111.5t122.5 82q72 24 138 8v521l-600 -155v-606q0 -42 -44 -90t-109 -69q-79 -26 -147 -5.5t-86 75.5t25.5 111.5t122.5 82.5q72 24 138 7v639q0 38 14.5 59 t53.5 34z" />
|
||||
<glyph unicode="" d="M500 1191q100 0 191 -39t156.5 -104.5t104.5 -156.5t39 -191l-1 -2l1 -5q0 -141 -78 -262l275 -274q23 -26 22.5 -44.5t-22.5 -42.5l-59 -58q-26 -20 -46.5 -20t-39.5 20l-275 274q-119 -77 -261 -77l-5 1l-2 -1q-100 0 -191 39t-156.5 104.5t-104.5 156.5t-39 191 t39 191t104.5 156.5t156.5 104.5t191 39zM500 1022q-88 0 -162 -43t-117 -117t-43 -162t43 -162t117 -117t162 -43t162 43t117 117t43 162t-43 162t-117 117t-162 43z" />
|
||||
<glyph unicode="" d="M649 949q48 68 109.5 104t121.5 38.5t118.5 -20t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-150 152.5t-126.5 127.5t-93.5 124.5t-33.5 117.5q0 64 28 123t73 100.5t104 64t119 20 t120.5 -38.5t104.5 -104z" />
|
||||
<glyph unicode="" d="M407 800l131 353q7 19 17.5 19t17.5 -19l129 -353h421q21 0 24 -8.5t-14 -20.5l-342 -249l130 -401q7 -20 -0.5 -25.5t-24.5 6.5l-343 246l-342 -247q-17 -12 -24.5 -6.5t-0.5 25.5l130 400l-347 251q-17 12 -14 20.5t23 8.5h429z" />
|
||||
<glyph unicode="" d="M407 800l131 353q7 19 17.5 19t17.5 -19l129 -353h421q21 0 24 -8.5t-14 -20.5l-342 -249l130 -401q7 -20 -0.5 -25.5t-24.5 6.5l-343 246l-342 -247q-17 -12 -24.5 -6.5t-0.5 25.5l130 400l-347 251q-17 12 -14 20.5t23 8.5h429zM477 700h-240l197 -142l-74 -226 l193 139l195 -140l-74 229l192 140h-234l-78 211z" />
|
||||
<glyph unicode="" d="M600 1200q124 0 212 -88t88 -212v-250q0 -46 -31 -98t-69 -52v-75q0 -10 6 -21.5t15 -17.5l358 -230q9 -5 15 -16.5t6 -21.5v-93q0 -10 -7.5 -17.5t-17.5 -7.5h-1150q-10 0 -17.5 7.5t-7.5 17.5v93q0 10 6 21.5t15 16.5l358 230q9 6 15 17.5t6 21.5v75q-38 0 -69 52 t-31 98v250q0 124 88 212t212 88z" />
|
||||
<glyph unicode="" d="M25 1100h1150q10 0 17.5 -7.5t7.5 -17.5v-1050q0 -10 -7.5 -17.5t-17.5 -7.5h-1150q-10 0 -17.5 7.5t-7.5 17.5v1050q0 10 7.5 17.5t17.5 7.5zM100 1000v-100h100v100h-100zM875 1000h-550q-10 0 -17.5 -7.5t-7.5 -17.5v-350q0 -10 7.5 -17.5t17.5 -7.5h550 q10 0 17.5 7.5t7.5 17.5v350q0 10 -7.5 17.5t-17.5 7.5zM1000 1000v-100h100v100h-100zM100 800v-100h100v100h-100zM1000 800v-100h100v100h-100zM100 600v-100h100v100h-100zM1000 600v-100h100v100h-100zM875 500h-550q-10 0 -17.5 -7.5t-7.5 -17.5v-350q0 -10 7.5 -17.5 t17.5 -7.5h550q10 0 17.5 7.5t7.5 17.5v350q0 10 -7.5 17.5t-17.5 7.5zM100 400v-100h100v100h-100zM1000 400v-100h100v100h-100zM100 200v-100h100v100h-100zM1000 200v-100h100v100h-100z" />
|
||||
<glyph unicode="" d="M50 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM650 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400 q0 21 14.5 35.5t35.5 14.5zM50 500h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM650 500h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M50 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200 q0 21 14.5 35.5t35.5 14.5zM850 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200 q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM850 700h200q21 0 35.5 -14.5t14.5 -35.5v-200 q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 300h200 q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM850 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5 t35.5 14.5z" />
|
||||
<glyph unicode="" d="M50 1100h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 1100h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v200 q0 21 14.5 35.5t35.5 14.5zM50 700h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 700h700q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-700 q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM50 300h200q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5zM450 300h700q21 0 35.5 -14.5t14.5 -35.5v-200 q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M465 477l571 571q8 8 18 8t17 -8l177 -177q8 -7 8 -17t-8 -18l-783 -784q-7 -8 -17.5 -8t-17.5 8l-384 384q-8 8 -8 18t8 17l177 177q7 8 17 8t18 -8l171 -171q7 -7 18 -7t18 7z" />
|
||||
<glyph unicode="" d="M904 1083l178 -179q8 -8 8 -18.5t-8 -17.5l-267 -268l267 -268q8 -7 8 -17.5t-8 -18.5l-178 -178q-8 -8 -18.5 -8t-17.5 8l-268 267l-268 -267q-7 -8 -17.5 -8t-18.5 8l-178 178q-8 8 -8 18.5t8 17.5l267 268l-267 268q-8 7 -8 17.5t8 18.5l178 178q8 8 18.5 8t17.5 -8 l268 -267l268 268q7 7 17.5 7t18.5 -7z" />
|
||||
<glyph unicode="" d="M507 1177q98 0 187.5 -38.5t154.5 -103.5t103.5 -154.5t38.5 -187.5q0 -141 -78 -262l300 -299q8 -8 8 -18.5t-8 -18.5l-109 -108q-7 -8 -17.5 -8t-18.5 8l-300 299q-119 -77 -261 -77q-98 0 -188 38.5t-154.5 103t-103 154.5t-38.5 188t38.5 187.5t103 154.5 t154.5 103.5t188 38.5zM506.5 1023q-89.5 0 -165.5 -44t-120 -120.5t-44 -166t44 -165.5t120 -120t165.5 -44t166 44t120.5 120t44 165.5t-44 166t-120.5 120.5t-166 44zM425 900h150q10 0 17.5 -7.5t7.5 -17.5v-75h75q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5 t-17.5 -7.5h-75v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-75q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h75v75q0 10 7.5 17.5t17.5 7.5z" />
|
||||
<glyph unicode="" d="M507 1177q98 0 187.5 -38.5t154.5 -103.5t103.5 -154.5t38.5 -187.5q0 -141 -78 -262l300 -299q8 -8 8 -18.5t-8 -18.5l-109 -108q-7 -8 -17.5 -8t-18.5 8l-300 299q-119 -77 -261 -77q-98 0 -188 38.5t-154.5 103t-103 154.5t-38.5 188t38.5 187.5t103 154.5 t154.5 103.5t188 38.5zM506.5 1023q-89.5 0 -165.5 -44t-120 -120.5t-44 -166t44 -165.5t120 -120t165.5 -44t166 44t120.5 120t44 165.5t-44 166t-120.5 120.5t-166 44zM325 800h350q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-350q-10 0 -17.5 7.5 t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
|
||||
<glyph unicode="" d="M550 1200h100q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM800 975v166q167 -62 272 -209.5t105 -331.5q0 -117 -45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5 t-184.5 123t-123 184.5t-45.5 224q0 184 105 331.5t272 209.5v-166q-103 -55 -165 -155t-62 -220q0 -116 57 -214.5t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5q0 120 -62 220t-165 155z" />
|
||||
<glyph unicode="" d="M1025 1200h150q10 0 17.5 -7.5t7.5 -17.5v-1150q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v1150q0 10 7.5 17.5t17.5 7.5zM725 800h150q10 0 17.5 -7.5t7.5 -17.5v-750q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v750 q0 10 7.5 17.5t17.5 7.5zM425 500h150q10 0 17.5 -7.5t7.5 -17.5v-450q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v450q0 10 7.5 17.5t17.5 7.5zM125 300h150q10 0 17.5 -7.5t7.5 -17.5v-250q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5 v250q0 10 7.5 17.5t17.5 7.5z" />
|
||||
<glyph unicode="" d="M600 1174q33 0 74 -5l38 -152l5 -1q49 -14 94 -39l5 -2l134 80q61 -48 104 -105l-80 -134l3 -5q25 -44 39 -93l1 -6l152 -38q5 -43 5 -73q0 -34 -5 -74l-152 -38l-1 -6q-15 -49 -39 -93l-3 -5l80 -134q-48 -61 -104 -105l-134 81l-5 -3q-44 -25 -94 -39l-5 -2l-38 -151 q-43 -5 -74 -5q-33 0 -74 5l-38 151l-5 2q-49 14 -94 39l-5 3l-134 -81q-60 48 -104 105l80 134l-3 5q-25 45 -38 93l-2 6l-151 38q-6 42 -6 74q0 33 6 73l151 38l2 6q13 48 38 93l3 5l-80 134q47 61 105 105l133 -80l5 2q45 25 94 39l5 1l38 152q43 5 74 5zM600 815 q-89 0 -152 -63t-63 -151.5t63 -151.5t152 -63t152 63t63 151.5t-63 151.5t-152 63z" />
|
||||
<glyph unicode="" d="M500 1300h300q41 0 70.5 -29.5t29.5 -70.5v-100h275q10 0 17.5 -7.5t7.5 -17.5v-75h-1100v75q0 10 7.5 17.5t17.5 7.5h275v100q0 41 29.5 70.5t70.5 29.5zM500 1200v-100h300v100h-300zM1100 900v-800q0 -41 -29.5 -70.5t-70.5 -29.5h-700q-41 0 -70.5 29.5t-29.5 70.5 v800h900zM300 800v-700h100v700h-100zM500 800v-700h100v700h-100zM700 800v-700h100v700h-100zM900 800v-700h100v700h-100z" />
|
||||
<glyph unicode="" d="M18 618l620 608q8 7 18.5 7t17.5 -7l608 -608q8 -8 5.5 -13t-12.5 -5h-175v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v375h-300v-375q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v575h-175q-10 0 -12.5 5t5.5 13z" />
|
||||
<glyph unicode="" d="M600 1200v-400q0 -41 29.5 -70.5t70.5 -29.5h300v-650q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v1100q0 21 14.5 35.5t35.5 14.5h450zM1000 800h-250q-21 0 -35.5 14.5t-14.5 35.5v250z" />
|
||||
<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM525 900h50q10 0 17.5 -7.5t7.5 -17.5v-275h175q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5z" />
|
||||
<glyph unicode="" d="M1300 0h-538l-41 400h-242l-41 -400h-538l431 1200h209l-21 -300h162l-20 300h208zM515 800l-27 -300h224l-27 300h-170z" />
|
||||
<glyph unicode="" d="M550 1200h200q21 0 35.5 -14.5t14.5 -35.5v-450h191q20 0 25.5 -11.5t-7.5 -27.5l-327 -400q-13 -16 -32 -16t-32 16l-327 400q-13 16 -7.5 27.5t25.5 11.5h191v450q0 21 14.5 35.5t35.5 14.5zM1125 400h50q10 0 17.5 -7.5t7.5 -17.5v-350q0 -10 -7.5 -17.5t-17.5 -7.5 h-1050q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h50q10 0 17.5 -7.5t7.5 -17.5v-175h900v175q0 10 7.5 17.5t17.5 7.5z" />
|
||||
<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM525 900h150q10 0 17.5 -7.5t7.5 -17.5v-275h137q21 0 26 -11.5t-8 -27.5l-223 -275q-13 -16 -32 -16t-32 16l-223 275q-13 16 -8 27.5t26 11.5h137v275q0 10 7.5 17.5t17.5 7.5z " />
|
||||
<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM632 914l223 -275q13 -16 8 -27.5t-26 -11.5h-137v-275q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v275h-137q-21 0 -26 11.5t8 27.5l223 275q13 16 32 16 t32 -16z" />
|
||||
<glyph unicode="" d="M225 1200h750q10 0 19.5 -7t12.5 -17l186 -652q7 -24 7 -49v-425q0 -12 -4 -27t-9 -17q-12 -6 -37 -6h-1100q-12 0 -27 4t-17 8q-6 13 -6 38l1 425q0 25 7 49l185 652q3 10 12.5 17t19.5 7zM878 1000h-556q-10 0 -19 -7t-11 -18l-87 -450q-2 -11 4 -18t16 -7h150 q10 0 19.5 -7t11.5 -17l38 -152q2 -10 11.5 -17t19.5 -7h250q10 0 19.5 7t11.5 17l38 152q2 10 11.5 17t19.5 7h150q10 0 16 7t4 18l-87 450q-2 11 -11 18t-19 7z" />
|
||||
<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM540 820l253 -190q17 -12 17 -30t-17 -30l-253 -190q-16 -12 -28 -6.5t-12 26.5v400q0 21 12 26.5t28 -6.5z" />
|
||||
<glyph unicode="" d="M947 1060l135 135q7 7 12.5 5t5.5 -13v-362q0 -10 -7.5 -17.5t-17.5 -7.5h-362q-11 0 -13 5.5t5 12.5l133 133q-109 76 -238 76q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5h150q0 -117 -45.5 -224 t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5q192 0 347 -117z" />
|
||||
<glyph unicode="" d="M947 1060l135 135q7 7 12.5 5t5.5 -13v-361q0 -11 -7.5 -18.5t-18.5 -7.5h-361q-11 0 -13 5.5t5 12.5l134 134q-110 75 -239 75q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5h-150q0 117 45.5 224t123 184.5t184.5 123t224 45.5q192 0 347 -117zM1027 600h150 q0 -117 -45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5q-192 0 -348 118l-134 -134q-7 -8 -12.5 -5.5t-5.5 12.5v360q0 11 7.5 18.5t18.5 7.5h360q10 0 12.5 -5.5t-5.5 -12.5l-133 -133q110 -76 240 -76q116 0 214.5 57t155.5 155.5t57 214.5z" />
|
||||
<glyph unicode="" d="M125 1200h1050q10 0 17.5 -7.5t7.5 -17.5v-1150q0 -10 -7.5 -17.5t-17.5 -7.5h-1050q-10 0 -17.5 7.5t-7.5 17.5v1150q0 10 7.5 17.5t17.5 7.5zM1075 1000h-850q-10 0 -17.5 -7.5t-7.5 -17.5v-850q0 -10 7.5 -17.5t17.5 -7.5h850q10 0 17.5 7.5t7.5 17.5v850 q0 10 -7.5 17.5t-17.5 7.5zM325 900h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 900h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 700h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 700h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 500h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 500h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5zM325 300h50q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM525 300h450q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-450q-10 0 -17.5 7.5t-7.5 17.5v50 q0 10 7.5 17.5t17.5 7.5z" />
|
||||
<glyph unicode="" d="M900 800v200q0 83 -58.5 141.5t-141.5 58.5h-300q-82 0 -141 -59t-59 -141v-200h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-600q0 -41 29.5 -70.5t70.5 -29.5h900q41 0 70.5 29.5t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5h-100zM400 800v150q0 21 15 35.5t35 14.5h200 q20 0 35 -14.5t15 -35.5v-150h-300z" />
|
||||
<glyph unicode="" d="M125 1100h50q10 0 17.5 -7.5t7.5 -17.5v-1075h-100v1075q0 10 7.5 17.5t17.5 7.5zM1075 1052q4 0 9 -2q16 -6 16 -23v-421q0 -6 -3 -12q-33 -59 -66.5 -99t-65.5 -58t-56.5 -24.5t-52.5 -6.5q-26 0 -57.5 6.5t-52.5 13.5t-60 21q-41 15 -63 22.5t-57.5 15t-65.5 7.5 q-85 0 -160 -57q-7 -5 -15 -5q-6 0 -11 3q-14 7 -14 22v438q22 55 82 98.5t119 46.5q23 2 43 0.5t43 -7t32.5 -8.5t38 -13t32.5 -11q41 -14 63.5 -21t57 -14t63.5 -7q103 0 183 87q7 8 18 8z" />
|
||||
<glyph unicode="" d="M600 1175q116 0 227 -49.5t192.5 -131t131 -192.5t49.5 -227v-300q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v300q0 127 -70.5 231.5t-184.5 161.5t-245 57t-245 -57t-184.5 -161.5t-70.5 -231.5v-300q0 -10 -7.5 -17.5t-17.5 -7.5h-50 q-10 0 -17.5 7.5t-7.5 17.5v300q0 116 49.5 227t131 192.5t192.5 131t227 49.5zM220 500h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14v460q0 8 6 14t14 6zM820 500h160q8 0 14 -6t6 -14v-460q0 -8 -6 -14t-14 -6h-160q-8 0 -14 6t-6 14v460 q0 8 6 14t14 6z" />
|
||||
<glyph unicode="" d="M321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM900 668l120 120q7 7 17 7t17 -7l34 -34q7 -7 7 -17t-7 -17l-120 -120l120 -120q7 -7 7 -17 t-7 -17l-34 -34q-7 -7 -17 -7t-17 7l-120 119l-120 -119q-7 -7 -17 -7t-17 7l-34 34q-7 7 -7 17t7 17l119 120l-119 120q-7 7 -7 17t7 17l34 34q7 8 17 8t17 -8z" />
|
||||
<glyph unicode="" d="M321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM766 900h4q10 -1 16 -10q96 -129 96 -290q0 -154 -90 -281q-6 -9 -17 -10l-3 -1q-9 0 -16 6 l-29 23q-7 7 -8.5 16.5t4.5 17.5q72 103 72 229q0 132 -78 238q-6 8 -4.5 18t9.5 17l29 22q7 5 15 5z" />
|
||||
<glyph unicode="" d="M967 1004h3q11 -1 17 -10q135 -179 135 -396q0 -105 -34 -206.5t-98 -185.5q-7 -9 -17 -10h-3q-9 0 -16 6l-42 34q-8 6 -9 16t5 18q111 150 111 328q0 90 -29.5 176t-84.5 157q-6 9 -5 19t10 16l42 33q7 5 15 5zM321 814l258 172q9 6 15 2.5t6 -13.5v-750q0 -10 -6 -13.5 t-15 2.5l-258 172q-21 14 -46 14h-250q-10 0 -17.5 7.5t-7.5 17.5v350q0 10 7.5 17.5t17.5 7.5h250q25 0 46 14zM766 900h4q10 -1 16 -10q96 -129 96 -290q0 -154 -90 -281q-6 -9 -17 -10l-3 -1q-9 0 -16 6l-29 23q-7 7 -8.5 16.5t4.5 17.5q72 103 72 229q0 132 -78 238 q-6 8 -4.5 18.5t9.5 16.5l29 22q7 5 15 5z" />
|
||||
<glyph unicode="" d="M500 900h100v-100h-100v-100h-400v-100h-100v600h500v-300zM1200 700h-200v-100h200v-200h-300v300h-200v300h-100v200h600v-500zM100 1100v-300h300v300h-300zM800 1100v-300h300v300h-300zM300 900h-100v100h100v-100zM1000 900h-100v100h100v-100zM300 500h200v-500 h-500v500h200v100h100v-100zM800 300h200v-100h-100v-100h-200v100h-100v100h100v200h-200v100h300v-300zM100 400v-300h300v300h-300zM300 200h-100v100h100v-100zM1200 200h-100v100h100v-100zM700 0h-100v100h100v-100zM1200 0h-300v100h300v-100z" />
|
||||
<glyph unicode="" d="M100 200h-100v1000h100v-1000zM300 200h-100v1000h100v-1000zM700 200h-200v1000h200v-1000zM900 200h-100v1000h100v-1000zM1200 200h-200v1000h200v-1000zM400 0h-300v100h300v-100zM600 0h-100v91h100v-91zM800 0h-100v91h100v-91zM1100 0h-200v91h200v-91z" />
|
||||
<glyph unicode="" d="M500 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-682 682l1 475q0 10 7.5 17.5t17.5 7.5h474zM319.5 1024.5q-29.5 29.5 -71 29.5t-71 -29.5t-29.5 -71.5t29.5 -71.5t71 -29.5t71 29.5t29.5 71.5t-29.5 71.5z" />
|
||||
<glyph unicode="" d="M500 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-682 682l1 475q0 10 7.5 17.5t17.5 7.5h474zM800 1200l682 -682q8 -8 8 -18t-8 -18l-464 -464q-8 -8 -18 -8t-18 8l-56 56l424 426l-700 700h150zM319.5 1024.5q-29.5 29.5 -71 29.5t-71 -29.5 t-29.5 -71.5t29.5 -71.5t71 -29.5t71 29.5t29.5 71.5t-29.5 71.5z" />
|
||||
<glyph unicode="" d="M300 1200h825q75 0 75 -75v-900q0 -25 -18 -43l-64 -64q-8 -8 -13 -5.5t-5 12.5v950q0 10 -7.5 17.5t-17.5 7.5h-700q-25 0 -43 -18l-64 -64q-8 -8 -5.5 -13t12.5 -5h700q10 0 17.5 -7.5t7.5 -17.5v-950q0 -10 -7.5 -17.5t-17.5 -7.5h-850q-10 0 -17.5 7.5t-7.5 17.5v975 q0 25 18 43l139 139q18 18 43 18z" />
|
||||
<glyph unicode="" d="M250 1200h800q21 0 35.5 -14.5t14.5 -35.5v-1150l-450 444l-450 -445v1151q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M822 1200h-444q-11 0 -19 -7.5t-9 -17.5l-78 -301q-7 -24 7 -45l57 -108q6 -9 17.5 -15t21.5 -6h450q10 0 21.5 6t17.5 15l62 108q14 21 7 45l-83 301q-1 10 -9 17.5t-19 7.5zM1175 800h-150q-10 0 -21 -6.5t-15 -15.5l-78 -156q-4 -9 -15 -15.5t-21 -6.5h-550 q-10 0 -21 6.5t-15 15.5l-78 156q-4 9 -15 15.5t-21 6.5h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-650q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h750q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5 t7.5 17.5v650q0 10 -7.5 17.5t-17.5 7.5zM850 200h-500q-10 0 -19.5 -7t-11.5 -17l-38 -152q-2 -10 3.5 -17t15.5 -7h600q10 0 15.5 7t3.5 17l-38 152q-2 10 -11.5 17t-19.5 7z" />
|
||||
<glyph unicode="" d="M500 1100h200q56 0 102.5 -20.5t72.5 -50t44 -59t25 -50.5l6 -20h150q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v600q0 41 29.5 70.5t70.5 29.5h150q2 8 6.5 21.5t24 48t45 61t72 48t102.5 21.5zM900 800v-100 h100v100h-100zM600 730q-95 0 -162.5 -67.5t-67.5 -162.5t67.5 -162.5t162.5 -67.5t162.5 67.5t67.5 162.5t-67.5 162.5t-162.5 67.5zM600 603q43 0 73 -30t30 -73t-30 -73t-73 -30t-73 30t-30 73t30 73t73 30z" />
|
||||
<glyph unicode="" d="M681 1199l385 -998q20 -50 60 -92q18 -19 36.5 -29.5t27.5 -11.5l10 -2v-66h-417v66q53 0 75 43.5t5 88.5l-82 222h-391q-58 -145 -92 -234q-11 -34 -6.5 -57t25.5 -37t46 -20t55 -6v-66h-365v66q56 24 84 52q12 12 25 30.5t20 31.5l7 13l399 1006h93zM416 521h340 l-162 457z" />
|
||||
<glyph unicode="" d="M753 641q5 -1 14.5 -4.5t36 -15.5t50.5 -26.5t53.5 -40t50.5 -54.5t35.5 -70t14.5 -87q0 -67 -27.5 -125.5t-71.5 -97.5t-98.5 -66.5t-108.5 -40.5t-102 -13h-500v89q41 7 70.5 32.5t29.5 65.5v827q0 24 -0.5 34t-3.5 24t-8.5 19.5t-17 13.5t-28 12.5t-42.5 11.5v71 l471 -1q57 0 115.5 -20.5t108 -57t80.5 -94t31 -124.5q0 -51 -15.5 -96.5t-38 -74.5t-45 -50.5t-38.5 -30.5zM400 700h139q78 0 130.5 48.5t52.5 122.5q0 41 -8.5 70.5t-29.5 55.5t-62.5 39.5t-103.5 13.5h-118v-350zM400 200h216q80 0 121 50.5t41 130.5q0 90 -62.5 154.5 t-156.5 64.5h-159v-400z" />
|
||||
<glyph unicode="" d="M877 1200l2 -57q-83 -19 -116 -45.5t-40 -66.5l-132 -839q-9 -49 13 -69t96 -26v-97h-500v97q186 16 200 98l173 832q3 17 3 30t-1.5 22.5t-9 17.5t-13.5 12.5t-21.5 10t-26 8.5t-33.5 10q-13 3 -19 5v57h425z" />
|
||||
<glyph unicode="" d="M1300 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-850q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v850h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM175 1000h-75v-800h75l-125 -167l-125 167h75v800h-75l125 167z" />
|
||||
<glyph unicode="" d="M1100 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-650q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v650h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM1167 50l-167 -125v75h-800v-75l-167 125l167 125v-75h800v75z" />
|
||||
<glyph unicode="" d="M50 1100h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 500h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M250 1100h700q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM250 500h700q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-700q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M500 950v100q0 21 14.5 35.5t35.5 14.5h600q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5zM100 650v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000 q-21 0 -35.5 14.5t-14.5 35.5zM300 350v100q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5zM0 50v100q0 21 14.5 35.5t35.5 14.5h1100q21 0 35.5 -14.5t14.5 -35.5v-100 q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5z" />
|
||||
<glyph unicode="" d="M50 1100h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 800h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 500h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h1100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 1100h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 800h800q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 500h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 500h800q21 0 35.5 -14.5t14.5 -35.5v-100 q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM350 200h800 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M400 0h-100v1100h100v-1100zM550 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM550 800h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM267 550l-167 -125v75h-200v100h200v75zM550 500h300q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM550 200h600 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM900 0h-100v1100h100v-1100zM50 800h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM1100 600h200v-100h-200v-75l-167 125l167 125v-75zM50 500h300q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5zM50 200h600 q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-600q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M75 1000h750q31 0 53 -22t22 -53v-650q0 -31 -22 -53t-53 -22h-750q-31 0 -53 22t-22 53v650q0 31 22 53t53 22zM1200 300l-300 300l300 300v-600z" />
|
||||
<glyph unicode="" d="M44 1100h1112q18 0 31 -13t13 -31v-1012q0 -18 -13 -31t-31 -13h-1112q-18 0 -31 13t-13 31v1012q0 18 13 31t31 13zM100 1000v-737l247 182l298 -131l-74 156l293 318l236 -288v500h-1000zM342 884q56 0 95 -39t39 -94.5t-39 -95t-95 -39.5t-95 39.5t-39 95t39 94.5 t95 39z" />
|
||||
<glyph unicode="" d="M648 1169q117 0 216 -60t156.5 -161t57.5 -218q0 -115 -70 -258q-69 -109 -158 -225.5t-143 -179.5l-54 -62q-9 8 -25.5 24.5t-63.5 67.5t-91 103t-98.5 128t-95.5 148q-60 132 -60 249q0 88 34 169.5t91.5 142t137 96.5t166.5 36zM652.5 974q-91.5 0 -156.5 -65 t-65 -157t65 -156.5t156.5 -64.5t156.5 64.5t65 156.5t-65 157t-156.5 65z" />
|
||||
<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 173v854q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57z" />
|
||||
<glyph unicode="" d="M554 1295q21 -72 57.5 -143.5t76 -130t83 -118t82.5 -117t70 -116t49.5 -126t18.5 -136.5q0 -71 -25.5 -135t-68.5 -111t-99 -82t-118.5 -54t-125.5 -23q-84 5 -161.5 34t-139.5 78.5t-99 125t-37 164.5q0 69 18 136.5t49.5 126.5t69.5 116.5t81.5 117.5t83.5 119 t76.5 131t58.5 143zM344 710q-23 -33 -43.5 -70.5t-40.5 -102.5t-17 -123q1 -37 14.5 -69.5t30 -52t41 -37t38.5 -24.5t33 -15q21 -7 32 -1t13 22l6 34q2 10 -2.5 22t-13.5 19q-5 4 -14 12t-29.5 40.5t-32.5 73.5q-26 89 6 271q2 11 -6 11q-8 1 -15 -10z" />
|
||||
<glyph unicode="" d="M1000 1013l108 115q2 1 5 2t13 2t20.5 -1t25 -9.5t28.5 -21.5q22 -22 27 -43t0 -32l-6 -10l-108 -115zM350 1100h400q50 0 105 -13l-187 -187h-368q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v182l200 200v-332 q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5zM1009 803l-362 -362l-161 -50l55 170l355 355z" />
|
||||
<glyph unicode="" d="M350 1100h361q-164 -146 -216 -200h-195q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5l200 153v-103q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5z M824 1073l339 -301q8 -7 8 -17.5t-8 -17.5l-340 -306q-7 -6 -12.5 -4t-6.5 11v203q-26 1 -54.5 0t-78.5 -7.5t-92 -17.5t-86 -35t-70 -57q10 59 33 108t51.5 81.5t65 58.5t68.5 40.5t67 24.5t56 13.5t40 4.5v210q1 10 6.5 12.5t13.5 -4.5z" />
|
||||
<glyph unicode="" d="M350 1100h350q60 0 127 -23l-178 -177h-349q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v69l200 200v-219q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5z M643 639l395 395q7 7 17.5 7t17.5 -7l101 -101q7 -7 7 -17.5t-7 -17.5l-531 -532q-7 -7 -17.5 -7t-17.5 7l-248 248q-7 7 -7 17.5t7 17.5l101 101q7 7 17.5 7t17.5 -7l111 -111q8 -7 18 -7t18 7z" />
|
||||
<glyph unicode="" d="M318 918l264 264q8 8 18 8t18 -8l260 -264q7 -8 4.5 -13t-12.5 -5h-170v-200h200v173q0 10 5 12t13 -5l264 -260q8 -7 8 -17.5t-8 -17.5l-264 -265q-8 -7 -13 -5t-5 12v173h-200v-200h170q10 0 12.5 -5t-4.5 -13l-260 -264q-8 -8 -18 -8t-18 8l-264 264q-8 8 -5.5 13 t12.5 5h175v200h-200v-173q0 -10 -5 -12t-13 5l-264 265q-8 7 -8 17.5t8 17.5l264 260q8 7 13 5t5 -12v-173h200v200h-175q-10 0 -12.5 5t5.5 13z" />
|
||||
<glyph unicode="" d="M250 1100h100q21 0 35.5 -14.5t14.5 -35.5v-438l464 453q15 14 25.5 10t10.5 -25v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v1000q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M50 1100h100q21 0 35.5 -14.5t14.5 -35.5v-438l464 453q15 14 25.5 10t10.5 -25v-438l464 453q15 14 25.5 10t10.5 -25v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5 t-14.5 35.5v1000q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M1200 1050v-1000q0 -21 -10.5 -25t-25.5 10l-464 453v-438q0 -21 -10.5 -25t-25.5 10l-492 480q-15 14 -15 35t15 35l492 480q15 14 25.5 10t10.5 -25v-438l464 453q15 14 25.5 10t10.5 -25z" />
|
||||
<glyph unicode="" d="M243 1074l814 -498q18 -11 18 -26t-18 -26l-814 -498q-18 -11 -30.5 -4t-12.5 28v1000q0 21 12.5 28t30.5 -4z" />
|
||||
<glyph unicode="" d="M250 1000h200q21 0 35.5 -14.5t14.5 -35.5v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5zM650 1000h200q21 0 35.5 -14.5t14.5 -35.5v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v800 q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M1100 950v-800q0 -21 -14.5 -35.5t-35.5 -14.5h-800q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5h800q21 0 35.5 -14.5t14.5 -35.5z" />
|
||||
<glyph unicode="" d="M500 612v438q0 21 10.5 25t25.5 -10l492 -480q15 -14 15 -35t-15 -35l-492 -480q-15 -14 -25.5 -10t-10.5 25v438l-464 -453q-15 -14 -25.5 -10t-10.5 25v1000q0 21 10.5 25t25.5 -10z" />
|
||||
<glyph unicode="" d="M1048 1102l100 1q20 0 35 -14.5t15 -35.5l5 -1000q0 -21 -14.5 -35.5t-35.5 -14.5l-100 -1q-21 0 -35.5 14.5t-14.5 35.5l-2 437l-463 -454q-14 -15 -24.5 -10.5t-10.5 25.5l-2 437l-462 -455q-15 -14 -25.5 -9.5t-10.5 24.5l-5 1000q0 21 10.5 25.5t25.5 -10.5l466 -450 l-2 438q0 20 10.5 24.5t25.5 -9.5l466 -451l-2 438q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M850 1100h100q21 0 35.5 -14.5t14.5 -35.5v-1000q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v438l-464 -453q-15 -14 -25.5 -10t-10.5 25v1000q0 21 10.5 25t25.5 -10l464 -453v438q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M686 1081l501 -540q15 -15 10.5 -26t-26.5 -11h-1042q-22 0 -26.5 11t10.5 26l501 540q15 15 36 15t36 -15zM150 400h1000q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M885 900l-352 -353l352 -353l-197 -198l-552 552l552 550z" />
|
||||
<glyph unicode="" d="M1064 547l-551 -551l-198 198l353 353l-353 353l198 198z" />
|
||||
<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM650 900h-100q-21 0 -35.5 -14.5t-14.5 -35.5v-150h-150 q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5t35.5 -14.5h150v-150q0 -21 14.5 -35.5t35.5 -14.5h100q21 0 35.5 14.5t14.5 35.5v150h150q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5h-150v150q0 21 -14.5 35.5t-35.5 14.5z" />
|
||||
<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM850 700h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5 t35.5 -14.5h500q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5z" />
|
||||
<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM741.5 913q-12.5 0 -21.5 -9l-120 -120l-120 120q-9 9 -21.5 9 t-21.5 -9l-141 -141q-9 -9 -9 -21.5t9 -21.5l120 -120l-120 -120q-9 -9 -9 -21.5t9 -21.5l141 -141q9 -9 21.5 -9t21.5 9l120 120l120 -120q9 -9 21.5 -9t21.5 9l141 141q9 9 9 21.5t-9 21.5l-120 120l120 120q9 9 9 21.5t-9 21.5l-141 141q-9 9 -21.5 9z" />
|
||||
<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM546 623l-84 85q-7 7 -17.5 7t-18.5 -7l-139 -139q-7 -8 -7 -18t7 -18 l242 -241q7 -8 17.5 -8t17.5 8l375 375q7 7 7 17.5t-7 18.5l-139 139q-7 7 -17.5 7t-17.5 -7z" />
|
||||
<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM588 941q-29 0 -59 -5.5t-63 -20.5t-58 -38.5t-41.5 -63t-16.5 -89.5 q0 -25 20 -25h131q30 -5 35 11q6 20 20.5 28t45.5 8q20 0 31.5 -10.5t11.5 -28.5q0 -23 -7 -34t-26 -18q-1 0 -13.5 -4t-19.5 -7.5t-20 -10.5t-22 -17t-18.5 -24t-15.5 -35t-8 -46q-1 -8 5.5 -16.5t20.5 -8.5h173q7 0 22 8t35 28t37.5 48t29.5 74t12 100q0 47 -17 83 t-42.5 57t-59.5 34.5t-64 18t-59 4.5zM675 400h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5z" />
|
||||
<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM675 1000h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5 t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5zM675 700h-250q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h75v-200h-75q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h350q10 0 17.5 7.5t7.5 17.5v50q0 10 -7.5 17.5 t-17.5 7.5h-75v275q0 10 -7.5 17.5t-17.5 7.5z" />
|
||||
<glyph unicode="" d="M525 1200h150q10 0 17.5 -7.5t7.5 -17.5v-194q103 -27 178.5 -102.5t102.5 -178.5h194q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-194q-27 -103 -102.5 -178.5t-178.5 -102.5v-194q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v194 q-103 27 -178.5 102.5t-102.5 178.5h-194q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h194q27 103 102.5 178.5t178.5 102.5v194q0 10 7.5 17.5t17.5 7.5zM700 893v-168q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v168q-68 -23 -119 -74 t-74 -119h168q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-168q23 -68 74 -119t119 -74v168q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-168q68 23 119 74t74 119h-168q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h168 q-23 68 -74 119t-119 74z" />
|
||||
<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM759 823l64 -64q7 -7 7 -17.5t-7 -17.5l-124 -124l124 -124q7 -7 7 -17.5t-7 -17.5l-64 -64q-7 -7 -17.5 -7t-17.5 7l-124 124l-124 -124q-7 -7 -17.5 -7t-17.5 7l-64 64 q-7 7 -7 17.5t7 17.5l124 124l-124 124q-7 7 -7 17.5t7 17.5l64 64q7 7 17.5 7t17.5 -7l124 -124l124 124q7 7 17.5 7t17.5 -7z" />
|
||||
<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5t57 -214.5 t155.5 -155.5t214.5 -57t214.5 57t155.5 155.5t57 214.5t-57 214.5t-155.5 155.5t-214.5 57zM782 788l106 -106q7 -7 7 -17.5t-7 -17.5l-320 -321q-8 -7 -18 -7t-18 7l-202 203q-8 7 -8 17.5t8 17.5l106 106q7 8 17.5 8t17.5 -8l79 -79l197 197q7 7 17.5 7t17.5 -7z" />
|
||||
<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM600 1027q-116 0 -214.5 -57t-155.5 -155.5t-57 -214.5q0 -120 65 -225 l587 587q-105 65 -225 65zM965 819l-584 -584q104 -62 219 -62q116 0 214.5 57t155.5 155.5t57 214.5q0 115 -62 219z" />
|
||||
<glyph unicode="" d="M39 582l522 427q16 13 27.5 8t11.5 -26v-291h550q21 0 35.5 -14.5t14.5 -35.5v-200q0 -21 -14.5 -35.5t-35.5 -14.5h-550v-291q0 -21 -11.5 -26t-27.5 8l-522 427q-16 13 -16 32t16 32z" />
|
||||
<glyph unicode="" d="M639 1009l522 -427q16 -13 16 -32t-16 -32l-522 -427q-16 -13 -27.5 -8t-11.5 26v291h-550q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h550v291q0 21 11.5 26t27.5 -8z" />
|
||||
<glyph unicode="" d="M682 1161l427 -522q13 -16 8 -27.5t-26 -11.5h-291v-550q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v550h-291q-21 0 -26 11.5t8 27.5l427 522q13 16 32 16t32 -16z" />
|
||||
<glyph unicode="" d="M550 1200h200q21 0 35.5 -14.5t14.5 -35.5v-550h291q21 0 26 -11.5t-8 -27.5l-427 -522q-13 -16 -32 -16t-32 16l-427 522q-13 16 -8 27.5t26 11.5h291v550q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M639 1109l522 -427q16 -13 16 -32t-16 -32l-522 -427q-16 -13 -27.5 -8t-11.5 26v291q-94 -2 -182 -20t-170.5 -52t-147 -92.5t-100.5 -135.5q5 105 27 193.5t67.5 167t113 135t167 91.5t225.5 42v262q0 21 11.5 26t27.5 -8z" />
|
||||
<glyph unicode="" d="M850 1200h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94l-249 -249q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l249 249l-94 94q-14 14 -10 24.5t25 10.5zM350 0h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l249 249 q8 7 18 7t18 -7l106 -106q7 -8 7 -18t-7 -18l-249 -249l94 -94q14 -14 10 -24.5t-25 -10.5z" />
|
||||
<glyph unicode="" d="M1014 1120l106 -106q7 -8 7 -18t-7 -18l-249 -249l94 -94q14 -14 10 -24.5t-25 -10.5h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l249 249q8 7 18 7t18 -7zM250 600h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94 l-249 -249q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l249 249l-94 94q-14 14 -10 24.5t25 10.5z" />
|
||||
<glyph unicode="" d="M600 1177q117 0 224 -45.5t184.5 -123t123 -184.5t45.5 -224t-45.5 -224t-123 -184.5t-184.5 -123t-224 -45.5t-224 45.5t-184.5 123t-123 184.5t-45.5 224t45.5 224t123 184.5t184.5 123t224 45.5zM704 900h-208q-20 0 -32 -14.5t-8 -34.5l58 -302q4 -20 21.5 -34.5 t37.5 -14.5h54q20 0 37.5 14.5t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5zM675 400h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5z" />
|
||||
<glyph unicode="" d="M260 1200q9 0 19 -2t15 -4l5 -2q22 -10 44 -23l196 -118q21 -13 36 -24q29 -21 37 -12q11 13 49 35l196 118q22 13 45 23q17 7 38 7q23 0 47 -16.5t37 -33.5l13 -16q14 -21 18 -45l25 -123l8 -44q1 -9 8.5 -14.5t17.5 -5.5h61q10 0 17.5 -7.5t7.5 -17.5v-50 q0 -10 -7.5 -17.5t-17.5 -7.5h-50q-10 0 -17.5 -7.5t-7.5 -17.5v-175h-400v300h-200v-300h-400v175q0 10 -7.5 17.5t-17.5 7.5h-50q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5h61q11 0 18 3t7 8q0 4 9 52l25 128q5 25 19 45q2 3 5 7t13.5 15t21.5 19.5t26.5 15.5 t29.5 7zM915 1079l-166 -162q-7 -7 -5 -12t12 -5h219q10 0 15 7t2 17l-51 149q-3 10 -11 12t-15 -6zM463 917l-177 157q-8 7 -16 5t-11 -12l-51 -143q-3 -10 2 -17t15 -7h231q11 0 12.5 5t-5.5 12zM500 0h-375q-10 0 -17.5 7.5t-7.5 17.5v375h400v-400zM1100 400v-375 q0 -10 -7.5 -17.5t-17.5 -7.5h-375v400h400z" />
|
||||
<glyph unicode="" d="M1165 1190q8 3 21 -6.5t13 -17.5q-2 -178 -24.5 -323.5t-55.5 -245.5t-87 -174.5t-102.5 -118.5t-118 -68.5t-118.5 -33t-120 -4.5t-105 9.5t-90 16.5q-61 12 -78 11q-4 1 -12.5 0t-34 -14.5t-52.5 -40.5l-153 -153q-26 -24 -37 -14.5t-11 43.5q0 64 42 102q8 8 50.5 45 t66.5 58q19 17 35 47t13 61q-9 55 -10 102.5t7 111t37 130t78 129.5q39 51 80 88t89.5 63.5t94.5 45t113.5 36t129 31t157.5 37t182 47.5zM1116 1098q-8 9 -22.5 -3t-45.5 -50q-38 -47 -119 -103.5t-142 -89.5l-62 -33q-56 -30 -102 -57t-104 -68t-102.5 -80.5t-85.5 -91 t-64 -104.5q-24 -56 -31 -86t2 -32t31.5 17.5t55.5 59.5q25 30 94 75.5t125.5 77.5t147.5 81q70 37 118.5 69t102 79.5t99 111t86.5 148.5q22 50 24 60t-6 19z" />
|
||||
<glyph unicode="" d="M653 1231q-39 -67 -54.5 -131t-10.5 -114.5t24.5 -96.5t47.5 -80t63.5 -62.5t68.5 -46.5t65 -30q-4 7 -17.5 35t-18.5 39.5t-17 39.5t-17 43t-13 42t-9.5 44.5t-2 42t4 43t13.5 39t23 38.5q96 -42 165 -107.5t105 -138t52 -156t13 -159t-19 -149.5q-13 -55 -44 -106.5 t-68 -87t-78.5 -64.5t-72.5 -45t-53 -22q-72 -22 -127 -11q-31 6 -13 19q6 3 17 7q13 5 32.5 21t41 44t38.5 63.5t21.5 81.5t-6.5 94.5t-50 107t-104 115.5q10 -104 -0.5 -189t-37 -140.5t-65 -93t-84 -52t-93.5 -11t-95 24.5q-80 36 -131.5 114t-53.5 171q-2 23 0 49.5 t4.5 52.5t13.5 56t27.5 60t46 64.5t69.5 68.5q-8 -53 -5 -102.5t17.5 -90t34 -68.5t44.5 -39t49 -2q31 13 38.5 36t-4.5 55t-29 64.5t-36 75t-26 75.5q-15 85 2 161.5t53.5 128.5t85.5 92.5t93.5 61t81.5 25.5z" />
|
||||
<glyph unicode="" d="M600 1094q82 0 160.5 -22.5t140 -59t116.5 -82.5t94.5 -95t68 -95t42.5 -82.5t14 -57.5t-14 -57.5t-43 -82.5t-68.5 -95t-94.5 -95t-116.5 -82.5t-140 -59t-159.5 -22.5t-159.5 22.5t-140 59t-116.5 82.5t-94.5 95t-68.5 95t-43 82.5t-14 57.5t14 57.5t42.5 82.5t68 95 t94.5 95t116.5 82.5t140 59t160.5 22.5zM888 829q-15 15 -18 12t5 -22q25 -57 25 -119q0 -124 -88 -212t-212 -88t-212 88t-88 212q0 59 23 114q8 19 4.5 22t-17.5 -12q-70 -69 -160 -184q-13 -16 -15 -40.5t9 -42.5q22 -36 47 -71t70 -82t92.5 -81t113 -58.5t133.5 -24.5 t133.5 24t113 58.5t92.5 81.5t70 81.5t47 70.5q11 18 9 42.5t-14 41.5q-90 117 -163 189zM448 727l-35 -36q-15 -15 -19.5 -38.5t4.5 -41.5q37 -68 93 -116q16 -13 38.5 -11t36.5 17l35 34q14 15 12.5 33.5t-16.5 33.5q-44 44 -89 117q-11 18 -28 20t-32 -12z" />
|
||||
<glyph unicode="" d="M592 0h-148l31 120q-91 20 -175.5 68.5t-143.5 106.5t-103.5 119t-66.5 110t-22 76q0 21 14 57.5t42.5 82.5t68 95t94.5 95t116.5 82.5t140 59t160.5 22.5q61 0 126 -15l32 121h148zM944 770l47 181q108 -85 176.5 -192t68.5 -159q0 -26 -19.5 -71t-59.5 -102t-93 -112 t-129 -104.5t-158 -75.5l46 173q77 49 136 117t97 131q11 18 9 42.5t-14 41.5q-54 70 -107 130zM310 824q-70 -69 -160 -184q-13 -16 -15 -40.5t9 -42.5q18 -30 39 -60t57 -70.5t74 -73t90 -61t105 -41.5l41 154q-107 18 -178.5 101.5t-71.5 193.5q0 59 23 114q8 19 4.5 22 t-17.5 -12zM448 727l-35 -36q-15 -15 -19.5 -38.5t4.5 -41.5q37 -68 93 -116q16 -13 38.5 -11t36.5 17l12 11l22 86l-3 4q-44 44 -89 117q-11 18 -28 20t-32 -12z" />
|
||||
<glyph unicode="" d="M-90 100l642 1066q20 31 48 28.5t48 -35.5l642 -1056q21 -32 7.5 -67.5t-50.5 -35.5h-1294q-37 0 -50.5 34t7.5 66zM155 200h345v75q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-75h345l-445 723zM496 700h208q20 0 32 -14.5t8 -34.5l-58 -252 q-4 -20 -21.5 -34.5t-37.5 -14.5h-54q-20 0 -37.5 14.5t-21.5 34.5l-58 252q-4 20 8 34.5t32 14.5z" />
|
||||
<glyph unicode="" d="M650 1200q62 0 106 -44t44 -106v-339l363 -325q15 -14 26 -38.5t11 -44.5v-41q0 -20 -12 -26.5t-29 5.5l-359 249v-263q100 -93 100 -113v-64q0 -21 -13 -29t-32 1l-205 128l-205 -128q-19 -9 -32 -1t-13 29v64q0 20 100 113v263l-359 -249q-17 -12 -29 -5.5t-12 26.5v41 q0 20 11 44.5t26 38.5l363 325v339q0 62 44 106t106 44z" />
|
||||
<glyph unicode="" d="M850 1200h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-150h-1100v150q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5h100q21 0 35.5 -14.5t14.5 -35.5v-50h500v50q0 21 14.5 35.5t35.5 14.5zM1100 800v-750q0 -21 -14.5 -35.5 t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v750h1100zM100 600v-100h100v100h-100zM300 600v-100h100v100h-100zM500 600v-100h100v100h-100zM700 600v-100h100v100h-100zM900 600v-100h100v100h-100zM100 400v-100h100v100h-100zM300 400v-100h100v100h-100zM500 400 v-100h100v100h-100zM700 400v-100h100v100h-100zM900 400v-100h100v100h-100zM100 200v-100h100v100h-100zM300 200v-100h100v100h-100zM500 200v-100h100v100h-100zM700 200v-100h100v100h-100zM900 200v-100h100v100h-100z" />
|
||||
<glyph unicode="" d="M1135 1165l249 -230q15 -14 15 -35t-15 -35l-249 -230q-14 -14 -24.5 -10t-10.5 25v150h-159l-600 -600h-291q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h209l600 600h241v150q0 21 10.5 25t24.5 -10zM522 819l-141 -141l-122 122h-209q-21 0 -35.5 14.5 t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h291zM1135 565l249 -230q15 -14 15 -35t-15 -35l-249 -230q-14 -14 -24.5 -10t-10.5 25v150h-241l-181 181l141 141l122 -122h159v150q0 21 10.5 25t24.5 -10z" />
|
||||
<glyph unicode="" d="M100 1100h1000q41 0 70.5 -29.5t29.5 -70.5v-600q0 -41 -29.5 -70.5t-70.5 -29.5h-596l-304 -300v300h-100q-41 0 -70.5 29.5t-29.5 70.5v600q0 41 29.5 70.5t70.5 29.5z" />
|
||||
<glyph unicode="" d="M150 1200h200q21 0 35.5 -14.5t14.5 -35.5v-250h-300v250q0 21 14.5 35.5t35.5 14.5zM850 1200h200q21 0 35.5 -14.5t14.5 -35.5v-250h-300v250q0 21 14.5 35.5t35.5 14.5zM1100 800v-300q0 -41 -3 -77.5t-15 -89.5t-32 -96t-58 -89t-89 -77t-129 -51t-174 -20t-174 20 t-129 51t-89 77t-58 89t-32 96t-15 89.5t-3 77.5v300h300v-250v-27v-42.5t1.5 -41t5 -38t10 -35t16.5 -30t25.5 -24.5t35 -19t46.5 -12t60 -4t60 4.5t46.5 12.5t35 19.5t25 25.5t17 30.5t10 35t5 38t2 40.5t-0.5 42v25v250h300z" />
|
||||
<glyph unicode="" d="M1100 411l-198 -199l-353 353l-353 -353l-197 199l551 551z" />
|
||||
<glyph unicode="" d="M1101 789l-550 -551l-551 551l198 199l353 -353l353 353z" />
|
||||
<glyph unicode="" d="M404 1000h746q21 0 35.5 -14.5t14.5 -35.5v-551h150q21 0 25 -10.5t-10 -24.5l-230 -249q-14 -15 -35 -15t-35 15l-230 249q-14 14 -10 24.5t25 10.5h150v401h-381zM135 984l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-400h385l215 -200h-750q-21 0 -35.5 14.5 t-14.5 35.5v550h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
|
||||
<glyph unicode="" d="M56 1200h94q17 0 31 -11t18 -27l38 -162h896q24 0 39 -18.5t10 -42.5l-100 -475q-5 -21 -27 -42.5t-55 -21.5h-633l48 -200h535q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-50q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v50h-300v-50 q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v50h-31q-18 0 -32.5 10t-20.5 19l-5 10l-201 961h-54q-20 0 -35 14.5t-15 35.5t15 35.5t35 14.5z" />
|
||||
<glyph unicode="" d="M1200 1000v-100h-1200v100h200q0 41 29.5 70.5t70.5 29.5h300q41 0 70.5 -29.5t29.5 -70.5h500zM0 800h1200v-800h-1200v800z" />
|
||||
<glyph unicode="" d="M200 800l-200 -400v600h200q0 41 29.5 70.5t70.5 29.5h300q42 0 71 -29.5t29 -70.5h500v-200h-1000zM1500 700l-300 -700h-1200l300 700h1200z" />
|
||||
<glyph unicode="" d="M635 1184l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-601h150q21 0 25 -10.5t-10 -24.5l-230 -249q-14 -15 -35 -15t-35 15l-230 249q-14 14 -10 24.5t25 10.5h150v601h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
|
||||
<glyph unicode="" d="M936 864l249 -229q14 -15 14 -35.5t-14 -35.5l-249 -229q-15 -15 -25.5 -10.5t-10.5 24.5v151h-600v-151q0 -20 -10.5 -24.5t-25.5 10.5l-249 229q-14 15 -14 35.5t14 35.5l249 229q15 15 25.5 10.5t10.5 -25.5v-149h600v149q0 21 10.5 25.5t25.5 -10.5z" />
|
||||
<glyph unicode="" d="M1169 400l-172 732q-5 23 -23 45.5t-38 22.5h-672q-20 0 -38 -20t-23 -41l-172 -739h1138zM1100 300h-1000q-41 0 -70.5 -29.5t-29.5 -70.5v-100q0 -41 29.5 -70.5t70.5 -29.5h1000q41 0 70.5 29.5t29.5 70.5v100q0 41 -29.5 70.5t-70.5 29.5zM800 100v100h100v-100h-100 zM1000 100v100h100v-100h-100z" />
|
||||
<glyph unicode="" d="M1150 1100q21 0 35.5 -14.5t14.5 -35.5v-850q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v850q0 21 14.5 35.5t35.5 14.5zM1000 200l-675 200h-38l47 -276q3 -16 -5.5 -20t-29.5 -4h-7h-84q-20 0 -34.5 14t-18.5 35q-55 337 -55 351v250v6q0 16 1 23.5t6.5 14 t17.5 6.5h200l675 250v-850zM0 750v-250q-4 0 -11 0.5t-24 6t-30 15t-24 30t-11 48.5v50q0 26 10.5 46t25 30t29 16t25.5 7z" />
|
||||
<glyph unicode="" d="M553 1200h94q20 0 29 -10.5t3 -29.5l-18 -37q83 -19 144 -82.5t76 -140.5l63 -327l118 -173h17q19 0 33 -14.5t14 -35t-13 -40.5t-31 -27q-8 -4 -23 -9.5t-65 -19.5t-103 -25t-132.5 -20t-158.5 -9q-57 0 -115 5t-104 12t-88.5 15.5t-73.5 17.5t-54.5 16t-35.5 12l-11 4 q-18 8 -31 28t-13 40.5t14 35t33 14.5h17l118 173l63 327q15 77 76 140t144 83l-18 32q-6 19 3.5 32t28.5 13zM498 110q50 -6 102 -6q53 0 102 6q-12 -49 -39.5 -79.5t-62.5 -30.5t-63 30.5t-39 79.5z" />
|
||||
<glyph unicode="" d="M800 946l224 78l-78 -224l234 -45l-180 -155l180 -155l-234 -45l78 -224l-224 78l-45 -234l-155 180l-155 -180l-45 234l-224 -78l78 224l-234 45l180 155l-180 155l234 45l-78 224l224 -78l45 234l155 -180l155 180z" />
|
||||
<glyph unicode="" d="M650 1200h50q40 0 70 -40.5t30 -84.5v-150l-28 -125h328q40 0 70 -40.5t30 -84.5v-100q0 -45 -29 -74l-238 -344q-16 -24 -38 -40.5t-45 -16.5h-250q-7 0 -42 25t-66 50l-31 25h-61q-45 0 -72.5 18t-27.5 57v400q0 36 20 63l145 196l96 198q13 28 37.5 48t51.5 20z M650 1100l-100 -212l-150 -213v-375h100l136 -100h214l250 375v125h-450l50 225v175h-50zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M600 1100h250q23 0 45 -16.5t38 -40.5l238 -344q29 -29 29 -74v-100q0 -44 -30 -84.5t-70 -40.5h-328q28 -118 28 -125v-150q0 -44 -30 -84.5t-70 -40.5h-50q-27 0 -51.5 20t-37.5 48l-96 198l-145 196q-20 27 -20 63v400q0 39 27.5 57t72.5 18h61q124 100 139 100z M50 1000h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5zM636 1000l-136 -100h-100v-375l150 -213l100 -212h50v175l-50 225h450v125l-250 375h-214z" />
|
||||
<glyph unicode="" d="M356 873l363 230q31 16 53 -6l110 -112q13 -13 13.5 -32t-11.5 -34l-84 -121h302q84 0 138 -38t54 -110t-55 -111t-139 -39h-106l-131 -339q-6 -21 -19.5 -41t-28.5 -20h-342q-7 0 -90 81t-83 94v525q0 17 14 35.5t28 28.5zM400 792v-503l100 -89h293l131 339 q6 21 19.5 41t28.5 20h203q21 0 30.5 25t0.5 50t-31 25h-456h-7h-6h-5.5t-6 0.5t-5 1.5t-5 2t-4 2.5t-4 4t-2.5 4.5q-12 25 5 47l146 183l-86 83zM50 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v500 q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M475 1103l366 -230q2 -1 6 -3.5t14 -10.5t18 -16.5t14.5 -20t6.5 -22.5v-525q0 -13 -86 -94t-93 -81h-342q-15 0 -28.5 20t-19.5 41l-131 339h-106q-85 0 -139.5 39t-54.5 111t54 110t138 38h302l-85 121q-11 15 -10.5 34t13.5 32l110 112q22 22 53 6zM370 945l146 -183 q17 -22 5 -47q-2 -2 -3.5 -4.5t-4 -4t-4 -2.5t-5 -2t-5 -1.5t-6 -0.5h-6h-6.5h-6h-475v-100h221q15 0 29 -20t20 -41l130 -339h294l106 89v503l-342 236zM1050 800h100q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5 v500q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M550 1294q72 0 111 -55t39 -139v-106l339 -131q21 -6 41 -19.5t20 -28.5v-342q0 -7 -81 -90t-94 -83h-525q-17 0 -35.5 14t-28.5 28l-9 14l-230 363q-16 31 6 53l112 110q13 13 32 13.5t34 -11.5l121 -84v302q0 84 38 138t110 54zM600 972v203q0 21 -25 30.5t-50 0.5 t-25 -31v-456v-7v-6v-5.5t-0.5 -6t-1.5 -5t-2 -5t-2.5 -4t-4 -4t-4.5 -2.5q-25 -12 -47 5l-183 146l-83 -86l236 -339h503l89 100v293l-339 131q-21 6 -41 19.5t-20 28.5zM450 200h500q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-500 q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M350 1100h500q21 0 35.5 14.5t14.5 35.5v100q0 21 -14.5 35.5t-35.5 14.5h-500q-21 0 -35.5 -14.5t-14.5 -35.5v-100q0 -21 14.5 -35.5t35.5 -14.5zM600 306v-106q0 -84 -39 -139t-111 -55t-110 54t-38 138v302l-121 -84q-15 -12 -34 -11.5t-32 13.5l-112 110 q-22 22 -6 53l230 363q1 2 3.5 6t10.5 13.5t16.5 17t20 13.5t22.5 6h525q13 0 94 -83t81 -90v-342q0 -15 -20 -28.5t-41 -19.5zM308 900l-236 -339l83 -86l183 146q22 17 47 5q2 -1 4.5 -2.5t4 -4t2.5 -4t2 -5t1.5 -5t0.5 -6v-5.5v-6v-7v-456q0 -22 25 -31t50 0.5t25 30.5 v203q0 15 20 28.5t41 19.5l339 131v293l-89 100h-503z" />
|
||||
<glyph unicode="" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM914 632l-275 223q-16 13 -27.5 8t-11.5 -26v-137h-275 q-10 0 -17.5 -7.5t-7.5 -17.5v-150q0 -10 7.5 -17.5t17.5 -7.5h275v-137q0 -21 11.5 -26t27.5 8l275 223q16 13 16 32t-16 32z" />
|
||||
<glyph unicode="" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM561 855l-275 -223q-16 -13 -16 -32t16 -32l275 -223q16 -13 27.5 -8 t11.5 26v137h275q10 0 17.5 7.5t7.5 17.5v150q0 10 -7.5 17.5t-17.5 7.5h-275v137q0 21 -11.5 26t-27.5 -8z" />
|
||||
<glyph unicode="" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM855 639l-223 275q-13 16 -32 16t-32 -16l-223 -275q-13 -16 -8 -27.5 t26 -11.5h137v-275q0 -10 7.5 -17.5t17.5 -7.5h150q10 0 17.5 7.5t7.5 17.5v275h137q21 0 26 11.5t-8 27.5z" />
|
||||
<glyph unicode="" d="M600 1178q118 0 225 -45.5t184.5 -123t123 -184.5t45.5 -225t-45.5 -225t-123 -184.5t-184.5 -123t-225 -45.5t-225 45.5t-184.5 123t-123 184.5t-45.5 225t45.5 225t123 184.5t184.5 123t225 45.5zM675 900h-150q-10 0 -17.5 -7.5t-7.5 -17.5v-275h-137q-21 0 -26 -11.5 t8 -27.5l223 -275q13 -16 32 -16t32 16l223 275q13 16 8 27.5t-26 11.5h-137v275q0 10 -7.5 17.5t-17.5 7.5z" />
|
||||
<glyph unicode="" d="M600 1176q116 0 222.5 -46t184 -123.5t123.5 -184t46 -222.5t-46 -222.5t-123.5 -184t-184 -123.5t-222.5 -46t-222.5 46t-184 123.5t-123.5 184t-46 222.5t46 222.5t123.5 184t184 123.5t222.5 46zM627 1101q-15 -12 -36.5 -20.5t-35.5 -12t-43 -8t-39 -6.5 q-15 -3 -45.5 0t-45.5 -2q-20 -7 -51.5 -26.5t-34.5 -34.5q-3 -11 6.5 -22.5t8.5 -18.5q-3 -34 -27.5 -91t-29.5 -79q-9 -34 5 -93t8 -87q0 -9 17 -44.5t16 -59.5q12 0 23 -5t23.5 -15t19.5 -14q16 -8 33 -15t40.5 -15t34.5 -12q21 -9 52.5 -32t60 -38t57.5 -11 q7 -15 -3 -34t-22.5 -40t-9.5 -38q13 -21 23 -34.5t27.5 -27.5t36.5 -18q0 -7 -3.5 -16t-3.5 -14t5 -17q104 -2 221 112q30 29 46.5 47t34.5 49t21 63q-13 8 -37 8.5t-36 7.5q-15 7 -49.5 15t-51.5 19q-18 0 -41 -0.5t-43 -1.5t-42 -6.5t-38 -16.5q-51 -35 -66 -12 q-4 1 -3.5 25.5t0.5 25.5q-6 13 -26.5 17.5t-24.5 6.5q1 15 -0.5 30.5t-7 28t-18.5 11.5t-31 -21q-23 -25 -42 4q-19 28 -8 58q6 16 22 22q6 -1 26 -1.5t33.5 -4t19.5 -13.5q7 -12 18 -24t21.5 -20.5t20 -15t15.5 -10.5l5 -3q2 12 7.5 30.5t8 34.5t-0.5 32q-3 18 3.5 29 t18 22.5t15.5 24.5q6 14 10.5 35t8 31t15.5 22.5t34 22.5q-6 18 10 36q8 0 24 -1.5t24.5 -1.5t20 4.5t20.5 15.5q-10 23 -31 42.5t-37.5 29.5t-49 27t-43.5 23q0 1 2 8t3 11.5t1.5 10.5t-1 9.5t-4.5 4.5q31 -13 58.5 -14.5t38.5 2.5l12 5q5 28 -9.5 46t-36.5 24t-50 15 t-41 20q-18 -4 -37 0zM613 994q0 -17 8 -42t17 -45t9 -23q-8 1 -39.5 5.5t-52.5 10t-37 16.5q3 11 16 29.5t16 25.5q10 -10 19 -10t14 6t13.5 14.5t16.5 12.5z" />
|
||||
<glyph unicode="" d="M756 1157q164 92 306 -9l-259 -138l145 -232l251 126q6 -89 -34 -156.5t-117 -110.5q-60 -34 -127 -39.5t-126 16.5l-596 -596q-15 -16 -36.5 -16t-36.5 16l-111 110q-15 15 -15 36.5t15 37.5l600 599q-34 101 5.5 201.5t135.5 154.5z" />
|
||||
<glyph unicode="" horiz-adv-x="1220" d="M100 1196h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 1096h-200v-100h200v100zM100 796h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 696h-500v-100h500v100zM100 396h1000q41 0 70.5 -29.5t29.5 -70.5v-100q0 -41 -29.5 -70.5t-70.5 -29.5h-1000q-41 0 -70.5 29.5t-29.5 70.5v100q0 41 29.5 70.5t70.5 29.5zM1100 296h-300v-100h300v100z " />
|
||||
<glyph unicode="" d="M150 1200h900q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM700 500v-300l-200 -200v500l-350 500h900z" />
|
||||
<glyph unicode="" d="M500 1200h200q41 0 70.5 -29.5t29.5 -70.5v-100h300q41 0 70.5 -29.5t29.5 -70.5v-400h-500v100h-200v-100h-500v400q0 41 29.5 70.5t70.5 29.5h300v100q0 41 29.5 70.5t70.5 29.5zM500 1100v-100h200v100h-200zM1200 400v-200q0 -41 -29.5 -70.5t-70.5 -29.5h-1000 q-41 0 -70.5 29.5t-29.5 70.5v200h1200z" />
|
||||
<glyph unicode="" d="M50 1200h300q21 0 25 -10.5t-10 -24.5l-94 -94l199 -199q7 -8 7 -18t-7 -18l-106 -106q-8 -7 -18 -7t-18 7l-199 199l-94 -94q-14 -14 -24.5 -10t-10.5 25v300q0 21 14.5 35.5t35.5 14.5zM850 1200h300q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -10.5 -25t-24.5 10l-94 94 l-199 -199q-8 -7 -18 -7t-18 7l-106 106q-7 8 -7 18t7 18l199 199l-94 94q-14 14 -10 24.5t25 10.5zM364 470l106 -106q7 -8 7 -18t-7 -18l-199 -199l94 -94q14 -14 10 -24.5t-25 -10.5h-300q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 10.5 25t24.5 -10l94 -94l199 199 q8 7 18 7t18 -7zM1071 271l94 94q14 14 24.5 10t10.5 -25v-300q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -25 10.5t10 24.5l94 94l-199 199q-7 8 -7 18t7 18l106 106q8 7 18 7t18 -7z" />
|
||||
<glyph unicode="" d="M596 1192q121 0 231.5 -47.5t190 -127t127 -190t47.5 -231.5t-47.5 -231.5t-127 -190.5t-190 -127t-231.5 -47t-231.5 47t-190.5 127t-127 190.5t-47 231.5t47 231.5t127 190t190.5 127t231.5 47.5zM596 1010q-112 0 -207.5 -55.5t-151 -151t-55.5 -207.5t55.5 -207.5 t151 -151t207.5 -55.5t207.5 55.5t151 151t55.5 207.5t-55.5 207.5t-151 151t-207.5 55.5zM454.5 905q22.5 0 38.5 -16t16 -38.5t-16 -39t-38.5 -16.5t-38.5 16.5t-16 39t16 38.5t38.5 16zM754.5 905q22.5 0 38.5 -16t16 -38.5t-16 -39t-38 -16.5q-14 0 -29 10l-55 -145 q17 -23 17 -51q0 -36 -25.5 -61.5t-61.5 -25.5t-61.5 25.5t-25.5 61.5q0 32 20.5 56.5t51.5 29.5l122 126l1 1q-9 14 -9 28q0 23 16 39t38.5 16zM345.5 709q22.5 0 38.5 -16t16 -38.5t-16 -38.5t-38.5 -16t-38.5 16t-16 38.5t16 38.5t38.5 16zM854.5 709q22.5 0 38.5 -16 t16 -38.5t-16 -38.5t-38.5 -16t-38.5 16t-16 38.5t16 38.5t38.5 16z" />
|
||||
<glyph unicode="" d="M546 173l469 470q91 91 99 192q7 98 -52 175.5t-154 94.5q-22 4 -47 4q-34 0 -66.5 -10t-56.5 -23t-55.5 -38t-48 -41.5t-48.5 -47.5q-376 -375 -391 -390q-30 -27 -45 -41.5t-37.5 -41t-32 -46.5t-16 -47.5t-1.5 -56.5q9 -62 53.5 -95t99.5 -33q74 0 125 51l548 548 q36 36 20 75q-7 16 -21.5 26t-32.5 10q-26 0 -50 -23q-13 -12 -39 -38l-341 -338q-15 -15 -35.5 -15.5t-34.5 13.5t-14 34.5t14 34.5q327 333 361 367q35 35 67.5 51.5t78.5 16.5q14 0 29 -1q44 -8 74.5 -35.5t43.5 -68.5q14 -47 2 -96.5t-47 -84.5q-12 -11 -32 -32 t-79.5 -81t-114.5 -115t-124.5 -123.5t-123 -119.5t-96.5 -89t-57 -45q-56 -27 -120 -27q-70 0 -129 32t-93 89q-48 78 -35 173t81 163l511 511q71 72 111 96q91 55 198 55q80 0 152 -33q78 -36 129.5 -103t66.5 -154q17 -93 -11 -183.5t-94 -156.5l-482 -476 q-15 -15 -36 -16t-37 14t-17.5 34t14.5 35z" />
|
||||
<glyph unicode="" d="M649 949q48 68 109.5 104t121.5 38.5t118.5 -20t102.5 -64t71 -100.5t27 -123q0 -57 -33.5 -117.5t-94 -124.5t-126.5 -127.5t-150 -152.5t-146 -174q-62 85 -145.5 174t-150 152.5t-126.5 127.5t-93.5 124.5t-33.5 117.5q0 64 28 123t73 100.5t104 64t119 20 t120.5 -38.5t104.5 -104zM896 972q-33 0 -64.5 -19t-56.5 -46t-47.5 -53.5t-43.5 -45.5t-37.5 -19t-36 19t-40 45.5t-43 53.5t-54 46t-65.5 19q-67 0 -122.5 -55.5t-55.5 -132.5q0 -23 13.5 -51t46 -65t57.5 -63t76 -75l22 -22q15 -14 44 -44t50.5 -51t46 -44t41 -35t23 -12 t23.5 12t42.5 36t46 44t52.5 52t44 43q4 4 12 13q43 41 63.5 62t52 55t46 55t26 46t11.5 44q0 79 -53 133.5t-120 54.5z" />
|
||||
<glyph unicode="" d="M776.5 1214q93.5 0 159.5 -66l141 -141q66 -66 66 -160q0 -42 -28 -95.5t-62 -87.5l-29 -29q-31 53 -77 99l-18 18l95 95l-247 248l-389 -389l212 -212l-105 -106l-19 18l-141 141q-66 66 -66 159t66 159l283 283q65 66 158.5 66zM600 706l105 105q10 -8 19 -17l141 -141 q66 -66 66 -159t-66 -159l-283 -283q-66 -66 -159 -66t-159 66l-141 141q-66 66 -66 159.5t66 159.5l55 55q29 -55 75 -102l18 -17l-95 -95l247 -248l389 389z" />
|
||||
<glyph unicode="" d="M603 1200q85 0 162 -15t127 -38t79 -48t29 -46v-953q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-41 0 -70.5 29.5t-29.5 70.5v953q0 21 30 46.5t81 48t129 37.5t163 15zM300 1000v-700h600v700h-600zM600 254q-43 0 -73.5 -30.5t-30.5 -73.5t30.5 -73.5t73.5 -30.5t73.5 30.5 t30.5 73.5t-30.5 73.5t-73.5 30.5z" />
|
||||
<glyph unicode="" d="M902 1185l283 -282q15 -15 15 -36t-14.5 -35.5t-35.5 -14.5t-35 15l-36 35l-279 -267v-300l-212 210l-308 -307l-280 -203l203 280l307 308l-210 212h300l267 279l-35 36q-15 14 -15 35t14.5 35.5t35.5 14.5t35 -15z" />
|
||||
<glyph unicode="" d="M700 1248v-78q38 -5 72.5 -14.5t75.5 -31.5t71 -53.5t52 -84t24 -118.5h-159q-4 36 -10.5 59t-21 45t-40 35.5t-64.5 20.5v-307l64 -13q34 -7 64 -16.5t70 -32t67.5 -52.5t47.5 -80t20 -112q0 -139 -89 -224t-244 -97v-77h-100v79q-150 16 -237 103q-40 40 -52.5 93.5 t-15.5 139.5h139q5 -77 48.5 -126t117.5 -65v335l-27 8q-46 14 -79 26.5t-72 36t-63 52t-40 72.5t-16 98q0 70 25 126t67.5 92t94.5 57t110 27v77h100zM600 754v274q-29 -4 -50 -11t-42 -21.5t-31.5 -41.5t-10.5 -65q0 -29 7 -50.5t16.5 -34t28.5 -22.5t31.5 -14t37.5 -10 q9 -3 13 -4zM700 547v-310q22 2 42.5 6.5t45 15.5t41.5 27t29 42t12 59.5t-12.5 59.5t-38 44.5t-53 31t-66.5 24.5z" />
|
||||
<glyph unicode="" d="M561 1197q84 0 160.5 -40t123.5 -109.5t47 -147.5h-153q0 40 -19.5 71.5t-49.5 48.5t-59.5 26t-55.5 9q-37 0 -79 -14.5t-62 -35.5q-41 -44 -41 -101q0 -26 13.5 -63t26.5 -61t37 -66q6 -9 9 -14h241v-100h-197q8 -50 -2.5 -115t-31.5 -95q-45 -62 -99 -112 q34 10 83 17.5t71 7.5q32 1 102 -16t104 -17q83 0 136 30l50 -147q-31 -19 -58 -30.5t-55 -15.5t-42 -4.5t-46 -0.5q-23 0 -76 17t-111 32.5t-96 11.5q-39 -3 -82 -16t-67 -25l-23 -11l-55 145q4 3 16 11t15.5 10.5t13 9t15.5 12t14.5 14t17.5 18.5q48 55 54 126.5 t-30 142.5h-221v100h166q-23 47 -44 104q-7 20 -12 41.5t-6 55.5t6 66.5t29.5 70.5t58.5 71q97 88 263 88z" />
|
||||
<glyph unicode="" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM935 1184l230 -249q14 -14 10 -24.5t-25 -10.5h-150v-900h-200v900h-150q-21 0 -25 10.5t10 24.5l230 249q14 15 35 15t35 -15z" />
|
||||
<glyph unicode="" d="M1000 700h-100v100h-100v-100h-100v500h300v-500zM400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM801 1100v-200h100v200h-100zM1000 350l-200 -250h200v-100h-300v150l200 250h-200v100h300v-150z " />
|
||||
<glyph unicode="" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1000 1050l-200 -250h200v-100h-300v150l200 250h-200v100h300v-150zM1000 0h-100v100h-100v-100h-100v500h300v-500zM801 400v-200h100v200h-100z " />
|
||||
<glyph unicode="" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1000 700h-100v400h-100v100h200v-500zM1100 0h-100v100h-200v400h300v-500zM901 400v-200h100v200h-100z" />
|
||||
<glyph unicode="" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1100 700h-100v100h-200v400h300v-500zM901 1100v-200h100v200h-100zM1000 0h-100v400h-100v100h200v-500z" />
|
||||
<glyph unicode="" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM900 1000h-200v200h200v-200zM1000 700h-300v200h300v-200zM1100 400h-400v200h400v-200zM1200 100h-500v200h500v-200z" />
|
||||
<glyph unicode="" d="M400 300h150q21 0 25 -11t-10 -25l-230 -250q-14 -15 -35 -15t-35 15l-230 250q-14 14 -10 25t25 11h150v900h200v-900zM1200 1000h-500v200h500v-200zM1100 700h-400v200h400v-200zM1000 400h-300v200h300v-200zM900 100h-200v200h200v-200z" />
|
||||
<glyph unicode="" d="M350 1100h400q162 0 256 -93.5t94 -256.5v-400q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5z" />
|
||||
<glyph unicode="" d="M350 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-163 0 -256.5 92.5t-93.5 257.5v400q0 163 94 256.5t256 93.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM440 770l253 -190q17 -12 17 -30t-17 -30l-253 -190q-16 -12 -28 -6.5t-12 26.5v400q0 21 12 26.5t28 -6.5z" />
|
||||
<glyph unicode="" d="M350 1100h400q163 0 256.5 -94t93.5 -256v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 163 92.5 256.5t257.5 93.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM350 700h400q21 0 26.5 -12t-6.5 -28l-190 -253q-12 -17 -30 -17t-30 17l-190 253q-12 16 -6.5 28t26.5 12z" />
|
||||
<glyph unicode="" d="M350 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -163 -92.5 -256.5t-257.5 -93.5h-400q-163 0 -256.5 94t-93.5 256v400q0 165 92.5 257.5t257.5 92.5zM800 900h-500q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5 v500q0 41 -29.5 70.5t-70.5 29.5zM580 693l190 -253q12 -16 6.5 -28t-26.5 -12h-400q-21 0 -26.5 12t6.5 28l190 253q12 17 30 17t30 -17z" />
|
||||
<glyph unicode="" d="M550 1100h400q165 0 257.5 -92.5t92.5 -257.5v-400q0 -165 -92.5 -257.5t-257.5 -92.5h-400q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h450q41 0 70.5 29.5t29.5 70.5v500q0 41 -29.5 70.5t-70.5 29.5h-450q-21 0 -35.5 14.5t-14.5 35.5v100 q0 21 14.5 35.5t35.5 14.5zM338 867l324 -284q16 -14 16 -33t-16 -33l-324 -284q-16 -14 -27 -9t-11 26v150h-250q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h250v150q0 21 11 26t27 -9z" />
|
||||
<glyph unicode="" d="M793 1182l9 -9q8 -10 5 -27q-3 -11 -79 -225.5t-78 -221.5l300 1q24 0 32.5 -17.5t-5.5 -35.5q-1 0 -133.5 -155t-267 -312.5t-138.5 -162.5q-12 -15 -26 -15h-9l-9 8q-9 11 -4 32q2 9 42 123.5t79 224.5l39 110h-302q-23 0 -31 19q-10 21 6 41q75 86 209.5 237.5 t228 257t98.5 111.5q9 16 25 16h9z" />
|
||||
<glyph unicode="" d="M350 1100h400q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-450q-41 0 -70.5 -29.5t-29.5 -70.5v-500q0 -41 29.5 -70.5t70.5 -29.5h450q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400 q0 165 92.5 257.5t257.5 92.5zM938 867l324 -284q16 -14 16 -33t-16 -33l-324 -284q-16 -14 -27 -9t-11 26v150h-250q-21 0 -35.5 14.5t-14.5 35.5v200q0 21 14.5 35.5t35.5 14.5h250v150q0 21 11 26t27 -9z" />
|
||||
<glyph unicode="" d="M750 1200h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -10.5 -25t-24.5 10l-109 109l-312 -312q-15 -15 -35.5 -15t-35.5 15l-141 141q-15 15 -15 35.5t15 35.5l312 312l-109 109q-14 14 -10 24.5t25 10.5zM456 900h-156q-41 0 -70.5 -29.5t-29.5 -70.5v-500 q0 -41 29.5 -70.5t70.5 -29.5h500q41 0 70.5 29.5t29.5 70.5v148l200 200v-298q0 -165 -93.5 -257.5t-256.5 -92.5h-400q-165 0 -257.5 92.5t-92.5 257.5v400q0 165 92.5 257.5t257.5 92.5h300z" />
|
||||
<glyph unicode="" d="M600 1186q119 0 227.5 -46.5t187 -125t125 -187t46.5 -227.5t-46.5 -227.5t-125 -187t-187 -125t-227.5 -46.5t-227.5 46.5t-187 125t-125 187t-46.5 227.5t46.5 227.5t125 187t187 125t227.5 46.5zM600 1022q-115 0 -212 -56.5t-153.5 -153.5t-56.5 -212t56.5 -212 t153.5 -153.5t212 -56.5t212 56.5t153.5 153.5t56.5 212t-56.5 212t-153.5 153.5t-212 56.5zM600 794q80 0 137 -57t57 -137t-57 -137t-137 -57t-137 57t-57 137t57 137t137 57z" />
|
||||
<glyph unicode="" d="M450 1200h200q21 0 35.5 -14.5t14.5 -35.5v-350h245q20 0 25 -11t-9 -26l-383 -426q-14 -15 -33.5 -15t-32.5 15l-379 426q-13 15 -8.5 26t25.5 11h250v350q0 21 14.5 35.5t35.5 14.5zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5z M900 200v-50h100v50h-100z" />
|
||||
<glyph unicode="" d="M583 1182l378 -435q14 -15 9 -31t-26 -16h-244v-250q0 -20 -17 -35t-39 -15h-200q-20 0 -32 14.5t-12 35.5v250h-250q-20 0 -25.5 16.5t8.5 31.5l383 431q14 16 33.5 17t33.5 -14zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5z M900 200v-50h100v50h-100z" />
|
||||
<glyph unicode="" d="M396 723l369 369q7 7 17.5 7t17.5 -7l139 -139q7 -8 7 -18.5t-7 -17.5l-525 -525q-7 -8 -17.5 -8t-17.5 8l-292 291q-7 8 -7 18t7 18l139 139q8 7 18.5 7t17.5 -7zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50 h-100z" />
|
||||
<glyph unicode="" d="M135 1023l142 142q14 14 35 14t35 -14l77 -77l-212 -212l-77 76q-14 15 -14 36t14 35zM655 855l210 210q14 14 24.5 10t10.5 -25l-2 -599q-1 -20 -15.5 -35t-35.5 -15l-597 -1q-21 0 -25 10.5t10 24.5l208 208l-154 155l212 212zM50 300h1000q21 0 35.5 -14.5t14.5 -35.5 v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50h-100z" />
|
||||
<glyph unicode="" d="M350 1200l599 -2q20 -1 35 -15.5t15 -35.5l1 -597q0 -21 -10.5 -25t-24.5 10l-208 208l-155 -154l-212 212l155 154l-210 210q-14 14 -10 24.5t25 10.5zM524 512l-76 -77q-15 -14 -36 -14t-35 14l-142 142q-14 14 -14 35t14 35l77 77zM50 300h1000q21 0 35.5 -14.5 t14.5 -35.5v-250h-1100v250q0 21 14.5 35.5t35.5 14.5zM900 200v-50h100v50h-100z" />
|
||||
<glyph unicode="" d="M1200 103l-483 276l-314 -399v423h-399l1196 796v-1096zM483 424v-230l683 953z" />
|
||||
<glyph unicode="" d="M1100 1000v-850q0 -21 -14.5 -35.5t-35.5 -14.5h-150v400h-700v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200z" />
|
||||
<glyph unicode="" d="M1100 1000l-2 -149l-299 -299l-95 95q-9 9 -21.5 9t-21.5 -9l-149 -147h-312v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM1132 638l106 -106q7 -7 7 -17.5t-7 -17.5l-420 -421q-8 -7 -18 -7 t-18 7l-202 203q-8 7 -8 17.5t8 17.5l106 106q7 8 17.5 8t17.5 -8l79 -79l297 297q7 7 17.5 7t17.5 -7z" />
|
||||
<glyph unicode="" d="M1100 1000v-269l-103 -103l-134 134q-15 15 -33.5 16.5t-34.5 -12.5l-266 -266h-329v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM1202 572l70 -70q15 -15 15 -35.5t-15 -35.5l-131 -131 l131 -131q15 -15 15 -35.5t-15 -35.5l-70 -70q-15 -15 -35.5 -15t-35.5 15l-131 131l-131 -131q-15 -15 -35.5 -15t-35.5 15l-70 70q-15 15 -15 35.5t15 35.5l131 131l-131 131q-15 15 -15 35.5t15 35.5l70 70q15 15 35.5 15t35.5 -15l131 -131l131 131q15 15 35.5 15 t35.5 -15z" />
|
||||
<glyph unicode="" d="M1100 1000v-300h-350q-21 0 -35.5 -14.5t-14.5 -35.5v-150h-500v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM850 600h100q21 0 35.5 -14.5t14.5 -35.5v-250h150q21 0 25 -10.5t-10 -24.5 l-230 -230q-14 -14 -35 -14t-35 14l-230 230q-14 14 -10 24.5t25 10.5h150v250q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M1100 1000v-400l-165 165q-14 15 -35 15t-35 -15l-263 -265h-402v-400h-150q-21 0 -35.5 14.5t-14.5 35.5v1000q0 20 14.5 35t35.5 15h250v-300h500v300h100zM700 1000h-100v200h100v-200zM935 565l230 -229q14 -15 10 -25.5t-25 -10.5h-150v-250q0 -20 -14.5 -35 t-35.5 -15h-100q-21 0 -35.5 15t-14.5 35v250h-150q-21 0 -25 10.5t10 25.5l230 229q14 15 35 15t35 -15z" />
|
||||
<glyph unicode="" d="M50 1100h1100q21 0 35.5 -14.5t14.5 -35.5v-150h-1200v150q0 21 14.5 35.5t35.5 14.5zM1200 800v-550q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v550h1200zM100 500v-200h400v200h-400z" />
|
||||
<glyph unicode="" d="M935 1165l248 -230q14 -14 14 -35t-14 -35l-248 -230q-14 -14 -24.5 -10t-10.5 25v150h-400v200h400v150q0 21 10.5 25t24.5 -10zM200 800h-50q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v-200zM400 800h-100v200h100v-200zM18 435l247 230 q14 14 24.5 10t10.5 -25v-150h400v-200h-400v-150q0 -21 -10.5 -25t-24.5 10l-247 230q-15 14 -15 35t15 35zM900 300h-100v200h100v-200zM1000 500h51q20 0 34.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-34.5 -14.5h-51v200z" />
|
||||
<glyph unicode="" d="M862 1073l276 116q25 18 43.5 8t18.5 -41v-1106q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v397q-4 1 -11 5t-24 17.5t-30 29t-24 42t-11 56.5v359q0 31 18.5 65t43.5 52zM550 1200q22 0 34.5 -12.5t14.5 -24.5l1 -13v-450q0 -28 -10.5 -59.5 t-25 -56t-29 -45t-25.5 -31.5l-10 -11v-447q0 -21 -14.5 -35.5t-35.5 -14.5h-200q-21 0 -35.5 14.5t-14.5 35.5v447q-4 4 -11 11.5t-24 30.5t-30 46t-24 55t-11 60v450q0 2 0.5 5.5t4 12t8.5 15t14.5 12t22.5 5.5q20 0 32.5 -12.5t14.5 -24.5l3 -13v-350h100v350v5.5t2.5 12 t7 15t15 12t25.5 5.5q23 0 35.5 -12.5t13.5 -24.5l1 -13v-350h100v350q0 2 0.5 5.5t3 12t7 15t15 12t24.5 5.5z" />
|
||||
<glyph unicode="" d="M1200 1100v-56q-4 0 -11 -0.5t-24 -3t-30 -7.5t-24 -15t-11 -24v-888q0 -22 25 -34.5t50 -13.5l25 -2v-56h-400v56q75 0 87.5 6.5t12.5 43.5v394h-500v-394q0 -37 12.5 -43.5t87.5 -6.5v-56h-400v56q4 0 11 0.5t24 3t30 7.5t24 15t11 24v888q0 22 -25 34.5t-50 13.5 l-25 2v56h400v-56q-75 0 -87.5 -6.5t-12.5 -43.5v-394h500v394q0 37 -12.5 43.5t-87.5 6.5v56h400z" />
|
||||
<glyph unicode="" d="M675 1000h375q21 0 35.5 -14.5t14.5 -35.5v-150h-105l-295 -98v98l-200 200h-400l100 100h375zM100 900h300q41 0 70.5 -29.5t29.5 -70.5v-500q0 -41 -29.5 -70.5t-70.5 -29.5h-300q-41 0 -70.5 29.5t-29.5 70.5v500q0 41 29.5 70.5t70.5 29.5zM100 800v-200h300v200 h-300zM1100 535l-400 -133v163l400 133v-163zM100 500v-200h300v200h-300zM1100 398v-248q0 -21 -14.5 -35.5t-35.5 -14.5h-375l-100 -100h-375l-100 100h400l200 200h105z" />
|
||||
<glyph unicode="" d="M17 1007l162 162q17 17 40 14t37 -22l139 -194q14 -20 11 -44.5t-20 -41.5l-119 -118q102 -142 228 -268t267 -227l119 118q17 17 42.5 19t44.5 -12l192 -136q19 -14 22.5 -37.5t-13.5 -40.5l-163 -162q-3 -1 -9.5 -1t-29.5 2t-47.5 6t-62.5 14.5t-77.5 26.5t-90 42.5 t-101.5 60t-111 83t-119 108.5q-74 74 -133.5 150.5t-94.5 138.5t-60 119.5t-34.5 100t-15 74.5t-4.5 48z" />
|
||||
<glyph unicode="" d="M600 1100q92 0 175 -10.5t141.5 -27t108.5 -36.5t81.5 -40t53.5 -37t31 -27l9 -10v-200q0 -21 -14.5 -33t-34.5 -9l-202 34q-20 3 -34.5 20t-14.5 38v146q-141 24 -300 24t-300 -24v-146q0 -21 -14.5 -38t-34.5 -20l-202 -34q-20 -3 -34.5 9t-14.5 33v200q3 4 9.5 10.5 t31 26t54 37.5t80.5 39.5t109 37.5t141 26.5t175 10.5zM600 795q56 0 97 -9.5t60 -23.5t30 -28t12 -24l1 -10v-50l365 -303q14 -15 24.5 -40t10.5 -45v-212q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v212q0 20 10.5 45t24.5 40l365 303v50 q0 4 1 10.5t12 23t30 29t60 22.5t97 10z" />
|
||||
<glyph unicode="" d="M1100 700l-200 -200h-600l-200 200v500h200v-200h200v200h200v-200h200v200h200v-500zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-12l137 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5 t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M700 1100h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-1000h300v1000q0 41 -29.5 70.5t-70.5 29.5zM1100 800h-100q-41 0 -70.5 -29.5t-29.5 -70.5v-700h300v700q0 41 -29.5 70.5t-70.5 29.5zM400 0h-300v400q0 41 29.5 70.5t70.5 29.5h100q41 0 70.5 -29.5t29.5 -70.5v-400z " />
|
||||
<glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-100h200v-300h-300v100h200v100h-200v300h300v-100zM900 700v-300l-100 -100h-200v500h200z M700 700v-300h100v300h-100z" />
|
||||
<glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 300h-100v200h-100v-200h-100v500h100v-200h100v200h100v-500zM900 700v-300l-100 -100h-200v500h200z M700 700v-300h100v300h-100z" />
|
||||
<glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-300h200v-100h-300v500h300v-100zM900 700h-200v-300h200v-100h-300v500h300v-100z" />
|
||||
<glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 400l-300 150l300 150v-300zM900 550l-300 -150v300z" />
|
||||
<glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM900 300h-700v500h700v-500zM800 700h-130q-38 0 -66.5 -43t-28.5 -108t27 -107t68 -42h130v300zM300 700v-300 h130q41 0 68 42t27 107t-28.5 108t-66.5 43h-130z" />
|
||||
<glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 700h-200v-100h200v-300h-300v100h200v100h-200v300h300v-100zM900 300h-100v400h-100v100h200v-500z M700 300h-100v100h100v-100z" />
|
||||
<glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM300 700h200v-400h-300v500h100v-100zM900 300h-100v400h-100v100h200v-500zM300 600v-200h100v200h-100z M700 300h-100v100h100v-100z" />
|
||||
<glyph unicode="" d="M200 1100h700q124 0 212 -88t88 -212v-500q0 -124 -88 -212t-212 -88h-700q-124 0 -212 88t-88 212v500q0 124 88 212t212 88zM100 900v-700h900v700h-900zM500 500l-199 -200h-100v50l199 200v150h-200v100h300v-300zM900 300h-100v400h-100v100h200v-500zM701 300h-100 v100h100v-100z" />
|
||||
<glyph unicode="" d="M600 1191q120 0 229.5 -47t188.5 -126t126 -188.5t47 -229.5t-47 -229.5t-126 -188.5t-188.5 -126t-229.5 -47t-229.5 47t-188.5 126t-126 188.5t-47 229.5t47 229.5t126 188.5t188.5 126t229.5 47zM600 1021q-114 0 -211 -56.5t-153.5 -153.5t-56.5 -211t56.5 -211 t153.5 -153.5t211 -56.5t211 56.5t153.5 153.5t56.5 211t-56.5 211t-153.5 153.5t-211 56.5zM800 700h-300v-200h300v-100h-300l-100 100v200l100 100h300v-100z" />
|
||||
<glyph unicode="" d="M600 1191q120 0 229.5 -47t188.5 -126t126 -188.5t47 -229.5t-47 -229.5t-126 -188.5t-188.5 -126t-229.5 -47t-229.5 47t-188.5 126t-126 188.5t-47 229.5t47 229.5t126 188.5t188.5 126t229.5 47zM600 1021q-114 0 -211 -56.5t-153.5 -153.5t-56.5 -211t56.5 -211 t153.5 -153.5t211 -56.5t211 56.5t153.5 153.5t56.5 211t-56.5 211t-153.5 153.5t-211 56.5zM800 700v-100l-50 -50l100 -100v-50h-100l-100 100h-150v-100h-100v400h300zM500 700v-100h200v100h-200z" />
|
||||
<glyph unicode="" d="M503 1089q110 0 200.5 -59.5t134.5 -156.5q44 14 90 14q120 0 205 -86.5t85 -207t-85 -207t-205 -86.5h-128v250q0 21 -14.5 35.5t-35.5 14.5h-300q-21 0 -35.5 -14.5t-14.5 -35.5v-250h-222q-80 0 -136 57.5t-56 136.5q0 69 43 122.5t108 67.5q-2 19 -2 37q0 100 49 185 t134 134t185 49zM525 500h150q10 0 17.5 -7.5t7.5 -17.5v-275h137q21 0 26 -11.5t-8 -27.5l-223 -244q-13 -16 -32 -16t-32 16l-223 244q-13 16 -8 27.5t26 11.5h137v275q0 10 7.5 17.5t17.5 7.5z" />
|
||||
<glyph unicode="" d="M502 1089q110 0 201 -59.5t135 -156.5q43 15 89 15q121 0 206 -86.5t86 -206.5q0 -99 -60 -181t-150 -110l-378 360q-13 16 -31.5 16t-31.5 -16l-381 -365h-9q-79 0 -135.5 57.5t-56.5 136.5q0 69 43 122.5t108 67.5q-2 19 -2 38q0 100 49 184.5t133.5 134t184.5 49.5z M632 467l223 -228q13 -16 8 -27.5t-26 -11.5h-137v-275q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v275h-137q-21 0 -26 11.5t8 27.5q199 204 223 228q19 19 31.5 19t32.5 -19z" />
|
||||
<glyph unicode="" d="M700 100v100h400l-270 300h170l-270 300h170l-300 333l-300 -333h170l-270 -300h170l-270 -300h400v-100h-50q-21 0 -35.5 -14.5t-14.5 -35.5v-50h400v50q0 21 -14.5 35.5t-35.5 14.5h-50z" />
|
||||
<glyph unicode="" d="M600 1179q94 0 167.5 -56.5t99.5 -145.5q89 -6 150.5 -71.5t61.5 -155.5q0 -61 -29.5 -112.5t-79.5 -82.5q9 -29 9 -55q0 -74 -52.5 -126.5t-126.5 -52.5q-55 0 -100 30v-251q21 0 35.5 -14.5t14.5 -35.5v-50h-300v50q0 21 14.5 35.5t35.5 14.5v251q-45 -30 -100 -30 q-74 0 -126.5 52.5t-52.5 126.5q0 18 4 38q-47 21 -75.5 65t-28.5 97q0 74 52.5 126.5t126.5 52.5q5 0 23 -2q0 2 -1 10t-1 13q0 116 81.5 197.5t197.5 81.5z" />
|
||||
<glyph unicode="" d="M1010 1010q111 -111 150.5 -260.5t0 -299t-150.5 -260.5q-83 -83 -191.5 -126.5t-218.5 -43.5t-218.5 43.5t-191.5 126.5q-111 111 -150.5 260.5t0 299t150.5 260.5q83 83 191.5 126.5t218.5 43.5t218.5 -43.5t191.5 -126.5zM476 1065q-4 0 -8 -1q-121 -34 -209.5 -122.5 t-122.5 -209.5q-4 -12 2.5 -23t18.5 -14l36 -9q3 -1 7 -1q23 0 29 22q27 96 98 166q70 71 166 98q11 3 17.5 13.5t3.5 22.5l-9 35q-3 13 -14 19q-7 4 -15 4zM512 920q-4 0 -9 -2q-80 -24 -138.5 -82.5t-82.5 -138.5q-4 -13 2 -24t19 -14l34 -9q4 -1 8 -1q22 0 28 21 q18 58 58.5 98.5t97.5 58.5q12 3 18 13.5t3 21.5l-9 35q-3 12 -14 19q-7 4 -15 4zM719.5 719.5q-49.5 49.5 -119.5 49.5t-119.5 -49.5t-49.5 -119.5t49.5 -119.5t119.5 -49.5t119.5 49.5t49.5 119.5t-49.5 119.5zM855 551q-22 0 -28 -21q-18 -58 -58.5 -98.5t-98.5 -57.5 q-11 -4 -17 -14.5t-3 -21.5l9 -35q3 -12 14 -19q7 -4 15 -4q4 0 9 2q80 24 138.5 82.5t82.5 138.5q4 13 -2.5 24t-18.5 14l-34 9q-4 1 -8 1zM1000 515q-23 0 -29 -22q-27 -96 -98 -166q-70 -71 -166 -98q-11 -3 -17.5 -13.5t-3.5 -22.5l9 -35q3 -13 14 -19q7 -4 15 -4 q4 0 8 1q121 34 209.5 122.5t122.5 209.5q4 12 -2.5 23t-18.5 14l-36 9q-3 1 -7 1z" />
|
||||
<glyph unicode="" d="M700 800h300v-380h-180v200h-340v-200h-380v755q0 10 7.5 17.5t17.5 7.5h575v-400zM1000 900h-200v200zM700 300h162l-212 -212l-212 212h162v200h100v-200zM520 0h-395q-10 0 -17.5 7.5t-7.5 17.5v395zM1000 220v-195q0 -10 -7.5 -17.5t-17.5 -7.5h-195z" />
|
||||
<glyph unicode="" d="M700 800h300v-520l-350 350l-550 -550v1095q0 10 7.5 17.5t17.5 7.5h575v-400zM1000 900h-200v200zM862 200h-162v-200h-100v200h-162l212 212zM480 0h-355q-10 0 -17.5 7.5t-7.5 17.5v55h380v-80zM1000 80v-55q0 -10 -7.5 -17.5t-17.5 -7.5h-155v80h180z" />
|
||||
<glyph unicode="" d="M1162 800h-162v-200h100l100 -100h-300v300h-162l212 212zM200 800h200q27 0 40 -2t29.5 -10.5t23.5 -30t7 -57.5h300v-100h-600l-200 -350v450h100q0 36 7 57.5t23.5 30t29.5 10.5t40 2zM800 400h240l-240 -400h-800l300 500h500v-100z" />
|
||||
<glyph unicode="" d="M650 1100h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5zM1000 850v150q41 0 70.5 -29.5t29.5 -70.5v-800 q0 -41 -29.5 -70.5t-70.5 -29.5h-600q-1 0 -20 4l246 246l-326 326v324q0 41 29.5 70.5t70.5 29.5v-150q0 -62 44 -106t106 -44h300q62 0 106 44t44 106zM412 250l-212 -212v162h-200v100h200v162z" />
|
||||
<glyph unicode="" d="M450 1100h100q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-300q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h50v50q0 21 14.5 35.5t35.5 14.5zM800 850v150q41 0 70.5 -29.5t29.5 -70.5v-500 h-200v-300h200q0 -36 -7 -57.5t-23.5 -30t-29.5 -10.5t-40 -2h-600q-41 0 -70.5 29.5t-29.5 70.5v800q0 41 29.5 70.5t70.5 29.5v-150q0 -62 44 -106t106 -44h300q62 0 106 44t44 106zM1212 250l-212 -212v162h-200v100h200v162z" />
|
||||
<glyph unicode="" d="M658 1197l637 -1104q23 -38 7 -65.5t-60 -27.5h-1276q-44 0 -60 27.5t7 65.5l637 1104q22 39 54 39t54 -39zM704 800h-208q-20 0 -32 -14.5t-8 -34.5l58 -302q4 -20 21.5 -34.5t37.5 -14.5h54q20 0 37.5 14.5t21.5 34.5l58 302q4 20 -8 34.5t-32 14.5zM500 300v-100h200 v100h-200z" />
|
||||
<glyph unicode="" d="M425 1100h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM425 800h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5 t17.5 7.5zM825 800h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM25 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150 q0 10 7.5 17.5t17.5 7.5zM425 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM825 500h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5 v150q0 10 7.5 17.5t17.5 7.5zM25 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM425 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5 t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM825 200h250q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-250q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
|
||||
<glyph unicode="" d="M700 1200h100v-200h-100v-100h350q62 0 86.5 -39.5t-3.5 -94.5l-66 -132q-41 -83 -81 -134h-772q-40 51 -81 134l-66 132q-28 55 -3.5 94.5t86.5 39.5h350v100h-100v200h100v100h200v-100zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-12l137 -100 h-950l138 100h-13q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M600 1300q40 0 68.5 -29.5t28.5 -70.5h-194q0 41 28.5 70.5t68.5 29.5zM443 1100h314q18 -37 18 -75q0 -8 -3 -25h328q41 0 44.5 -16.5t-30.5 -38.5l-175 -145h-678l-178 145q-34 22 -29 38.5t46 16.5h328q-3 17 -3 25q0 38 18 75zM250 700h700q21 0 35.5 -14.5 t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-150v-200l275 -200h-950l275 200v200h-150q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M600 1181q75 0 128 -53t53 -128t-53 -128t-128 -53t-128 53t-53 128t53 128t128 53zM602 798h46q34 0 55.5 -28.5t21.5 -86.5q0 -76 39 -183h-324q39 107 39 183q0 58 21.5 86.5t56.5 28.5h45zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13 l138 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M600 1300q47 0 92.5 -53.5t71 -123t25.5 -123.5q0 -78 -55.5 -133.5t-133.5 -55.5t-133.5 55.5t-55.5 133.5q0 62 34 143l144 -143l111 111l-163 163q34 26 63 26zM602 798h46q34 0 55.5 -28.5t21.5 -86.5q0 -76 39 -183h-324q39 107 39 183q0 58 21.5 86.5t56.5 28.5h45 zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13l138 -100h-950l137 100h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M600 1200l300 -161v-139h-300q0 -57 18.5 -108t50 -91.5t63 -72t70 -67.5t57.5 -61h-530q-60 83 -90.5 177.5t-30.5 178.5t33 164.5t87.5 139.5t126 96.5t145.5 41.5v-98zM250 400h700q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-13l138 -100h-950l137 100 h-12q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5zM50 100h1100q21 0 35.5 -14.5t14.5 -35.5v-50h-1200v50q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M600 1300q41 0 70.5 -29.5t29.5 -70.5v-78q46 -26 73 -72t27 -100v-50h-400v50q0 54 27 100t73 72v78q0 41 29.5 70.5t70.5 29.5zM400 800h400q54 0 100 -27t72 -73h-172v-100h200v-100h-200v-100h200v-100h-200v-100h200q0 -83 -58.5 -141.5t-141.5 -58.5h-400 q-83 0 -141.5 58.5t-58.5 141.5v400q0 83 58.5 141.5t141.5 58.5z" />
|
||||
<glyph unicode="" d="M150 1100h900q21 0 35.5 -14.5t14.5 -35.5v-500q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v500q0 21 14.5 35.5t35.5 14.5zM125 400h950q10 0 17.5 -7.5t7.5 -17.5v-50q0 -10 -7.5 -17.5t-17.5 -7.5h-283l224 -224q13 -13 13 -31.5t-13 -32 t-31.5 -13.5t-31.5 13l-88 88h-524l-87 -88q-13 -13 -32 -13t-32 13.5t-13 32t13 31.5l224 224h-289q-10 0 -17.5 7.5t-7.5 17.5v50q0 10 7.5 17.5t17.5 7.5zM541 300l-100 -100h324l-100 100h-124z" />
|
||||
<glyph unicode="" d="M200 1100h800q83 0 141.5 -58.5t58.5 -141.5v-200h-100q0 41 -29.5 70.5t-70.5 29.5h-250q-41 0 -70.5 -29.5t-29.5 -70.5h-100q0 41 -29.5 70.5t-70.5 29.5h-250q-41 0 -70.5 -29.5t-29.5 -70.5h-100v200q0 83 58.5 141.5t141.5 58.5zM100 600h1000q41 0 70.5 -29.5 t29.5 -70.5v-300h-1200v300q0 41 29.5 70.5t70.5 29.5zM300 100v-50q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v50h200zM1100 100v-50q0 -21 -14.5 -35.5t-35.5 -14.5h-100q-21 0 -35.5 14.5t-14.5 35.5v50h200z" />
|
||||
<glyph unicode="" d="M480 1165l682 -683q31 -31 31 -75.5t-31 -75.5l-131 -131h-481l-517 518q-32 31 -32 75.5t32 75.5l295 296q31 31 75.5 31t76.5 -31zM108 794l342 -342l303 304l-341 341zM250 100h800q21 0 35.5 -14.5t14.5 -35.5v-50h-900v50q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M1057 647l-189 506q-8 19 -27.5 33t-40.5 14h-400q-21 0 -40.5 -14t-27.5 -33l-189 -506q-8 -19 1.5 -33t30.5 -14h625v-150q0 -21 14.5 -35.5t35.5 -14.5t35.5 14.5t14.5 35.5v150h125q21 0 30.5 14t1.5 33zM897 0h-595v50q0 21 14.5 35.5t35.5 14.5h50v50 q0 21 14.5 35.5t35.5 14.5h48v300h200v-300h47q21 0 35.5 -14.5t14.5 -35.5v-50h50q21 0 35.5 -14.5t14.5 -35.5v-50z" />
|
||||
<glyph unicode="" d="M900 800h300v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-375v591l-300 300v84q0 10 7.5 17.5t17.5 7.5h375v-400zM1200 900h-200v200zM400 600h300v-575q0 -10 -7.5 -17.5t-17.5 -7.5h-650q-10 0 -17.5 7.5t-7.5 17.5v950q0 10 7.5 17.5t17.5 7.5h375v-400zM700 700h-200v200z " />
|
||||
<glyph unicode="" d="M484 1095h195q75 0 146 -32.5t124 -86t89.5 -122.5t48.5 -142q18 -14 35 -20q31 -10 64.5 6.5t43.5 48.5q10 34 -15 71q-19 27 -9 43q5 8 12.5 11t19 -1t23.5 -16q41 -44 39 -105q-3 -63 -46 -106.5t-104 -43.5h-62q-7 -55 -35 -117t-56 -100l-39 -234q-3 -20 -20 -34.5 t-38 -14.5h-100q-21 0 -33 14.5t-9 34.5l12 70q-49 -14 -91 -14h-195q-24 0 -65 8l-11 -64q-3 -20 -20 -34.5t-38 -14.5h-100q-21 0 -33 14.5t-9 34.5l26 157q-84 74 -128 175l-159 53q-19 7 -33 26t-14 40v50q0 21 14.5 35.5t35.5 14.5h124q11 87 56 166l-111 95 q-16 14 -12.5 23.5t24.5 9.5h203q116 101 250 101zM675 1000h-250q-10 0 -17.5 -7.5t-7.5 -17.5v-50q0 -10 7.5 -17.5t17.5 -7.5h250q10 0 17.5 7.5t7.5 17.5v50q0 10 -7.5 17.5t-17.5 7.5z" />
|
||||
<glyph unicode="" d="M641 900l423 247q19 8 42 2.5t37 -21.5l32 -38q14 -15 12.5 -36t-17.5 -34l-139 -120h-390zM50 1100h106q67 0 103 -17t66 -71l102 -212h823q21 0 35.5 -14.5t14.5 -35.5v-50q0 -21 -14 -40t-33 -26l-737 -132q-23 -4 -40 6t-26 25q-42 67 -100 67h-300q-62 0 -106 44 t-44 106v200q0 62 44 106t106 44zM173 928h-80q-19 0 -28 -14t-9 -35v-56q0 -51 42 -51h134q16 0 21.5 8t5.5 24q0 11 -16 45t-27 51q-18 28 -43 28zM550 727q-32 0 -54.5 -22.5t-22.5 -54.5t22.5 -54.5t54.5 -22.5t54.5 22.5t22.5 54.5t-22.5 54.5t-54.5 22.5zM130 389 l152 130q18 19 34 24t31 -3.5t24.5 -17.5t25.5 -28q28 -35 50.5 -51t48.5 -13l63 5l48 -179q13 -61 -3.5 -97.5t-67.5 -79.5l-80 -69q-47 -40 -109 -35.5t-103 51.5l-130 151q-40 47 -35.5 109.5t51.5 102.5zM380 377l-102 -88q-31 -27 2 -65l37 -43q13 -15 27.5 -19.5 t31.5 6.5l61 53q19 16 14 49q-2 20 -12 56t-17 45q-11 12 -19 14t-23 -8z" />
|
||||
<glyph unicode="" d="M625 1200h150q10 0 17.5 -7.5t7.5 -17.5v-109q79 -33 131 -87.5t53 -128.5q1 -46 -15 -84.5t-39 -61t-46 -38t-39 -21.5l-17 -6q6 0 15 -1.5t35 -9t50 -17.5t53 -30t50 -45t35.5 -64t14.5 -84q0 -59 -11.5 -105.5t-28.5 -76.5t-44 -51t-49.5 -31.5t-54.5 -16t-49.5 -6.5 t-43.5 -1v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-100v-75q0 -10 -7.5 -17.5t-17.5 -7.5h-150q-10 0 -17.5 7.5t-7.5 17.5v75h-175q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5h75v600h-75q-10 0 -17.5 7.5t-7.5 17.5v150 q0 10 7.5 17.5t17.5 7.5h175v75q0 10 7.5 17.5t17.5 7.5h150q10 0 17.5 -7.5t7.5 -17.5v-75h100v75q0 10 7.5 17.5t17.5 7.5zM400 900v-200h263q28 0 48.5 10.5t30 25t15 29t5.5 25.5l1 10q0 4 -0.5 11t-6 24t-15 30t-30 24t-48.5 11h-263zM400 500v-200h363q28 0 48.5 10.5 t30 25t15 29t5.5 25.5l1 10q0 4 -0.5 11t-6 24t-15 30t-30 24t-48.5 11h-363z" />
|
||||
<glyph unicode="" d="M212 1198h780q86 0 147 -61t61 -147v-416q0 -51 -18 -142.5t-36 -157.5l-18 -66q-29 -87 -93.5 -146.5t-146.5 -59.5h-572q-82 0 -147 59t-93 147q-8 28 -20 73t-32 143.5t-20 149.5v416q0 86 61 147t147 61zM600 1045q-70 0 -132.5 -11.5t-105.5 -30.5t-78.5 -41.5 t-57 -45t-36 -41t-20.5 -30.5l-6 -12l156 -243h560l156 243q-2 5 -6 12.5t-20 29.5t-36.5 42t-57 44.5t-79 42t-105 29.5t-132.5 12zM762 703h-157l195 261z" />
|
||||
<glyph unicode="" d="M475 1300h150q103 0 189 -86t86 -189v-500q0 -41 -42 -83t-83 -42h-450q-41 0 -83 42t-42 83v500q0 103 86 189t189 86zM700 300v-225q0 -21 -27 -48t-48 -27h-150q-21 0 -48 27t-27 48v225h300z" />
|
||||
<glyph unicode="" d="M475 1300h96q0 -150 89.5 -239.5t239.5 -89.5v-446q0 -41 -42 -83t-83 -42h-450q-41 0 -83 42t-42 83v500q0 103 86 189t189 86zM700 300v-225q0 -21 -27 -48t-48 -27h-150q-21 0 -48 27t-27 48v225h300z" />
|
||||
<glyph unicode="" d="M1294 767l-638 -283l-378 170l-78 -60v-224l100 -150v-199l-150 148l-150 -149v200l100 150v250q0 4 -0.5 10.5t0 9.5t1 8t3 8t6.5 6l47 40l-147 65l642 283zM1000 380l-350 -166l-350 166v147l350 -165l350 165v-147z" />
|
||||
<glyph unicode="" d="M250 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM650 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM1050 800q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44z" />
|
||||
<glyph unicode="" d="M550 1100q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM550 700q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44zM550 300q62 0 106 -44t44 -106t-44 -106t-106 -44t-106 44t-44 106t44 106t106 44z" />
|
||||
<glyph unicode="" d="M125 1100h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5zM125 700h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5 t17.5 7.5zM125 300h950q10 0 17.5 -7.5t7.5 -17.5v-150q0 -10 -7.5 -17.5t-17.5 -7.5h-950q-10 0 -17.5 7.5t-7.5 17.5v150q0 10 7.5 17.5t17.5 7.5z" />
|
||||
<glyph unicode="" d="M350 1200h500q162 0 256 -93.5t94 -256.5v-500q0 -165 -93.5 -257.5t-256.5 -92.5h-500q-165 0 -257.5 92.5t-92.5 257.5v500q0 165 92.5 257.5t257.5 92.5zM900 1000h-600q-41 0 -70.5 -29.5t-29.5 -70.5v-600q0 -41 29.5 -70.5t70.5 -29.5h600q41 0 70.5 29.5 t29.5 70.5v600q0 41 -29.5 70.5t-70.5 29.5zM350 900h500q21 0 35.5 -14.5t14.5 -35.5v-300q0 -21 -14.5 -35.5t-35.5 -14.5h-500q-21 0 -35.5 14.5t-14.5 35.5v300q0 21 14.5 35.5t35.5 14.5zM400 800v-200h400v200h-400z" />
|
||||
<glyph unicode="" d="M150 1100h1000q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5t-35.5 -14.5h-50v-200h50q21 0 35.5 -14.5t14.5 -35.5t-14.5 -35.5 t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5h50v200h-50q-21 0 -35.5 14.5t-14.5 35.5t14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M650 1187q87 -67 118.5 -156t0 -178t-118.5 -155q-87 66 -118.5 155t0 178t118.5 156zM300 800q124 0 212 -88t88 -212q-124 0 -212 88t-88 212zM1000 800q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM300 500q124 0 212 -88t88 -212q-124 0 -212 88t-88 212z M1000 500q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM700 199v-144q0 -21 -14.5 -35.5t-35.5 -14.5t-35.5 14.5t-14.5 35.5v142q40 -4 43 -4q17 0 57 6z" />
|
||||
<glyph unicode="" d="M745 878l69 19q25 6 45 -12l298 -295q11 -11 15 -26.5t-2 -30.5q-5 -14 -18 -23.5t-28 -9.5h-8q1 0 1 -13q0 -29 -2 -56t-8.5 -62t-20 -63t-33 -53t-51 -39t-72.5 -14h-146q-184 0 -184 288q0 24 10 47q-20 4 -62 4t-63 -4q11 -24 11 -47q0 -288 -184 -288h-142 q-48 0 -84.5 21t-56 51t-32 71.5t-16 75t-3.5 68.5q0 13 2 13h-7q-15 0 -27.5 9.5t-18.5 23.5q-6 15 -2 30.5t15 25.5l298 296q20 18 46 11l76 -19q20 -5 30.5 -22.5t5.5 -37.5t-22.5 -31t-37.5 -5l-51 12l-182 -193h891l-182 193l-44 -12q-20 -5 -37.5 6t-22.5 31t6 37.5 t31 22.5z" />
|
||||
<glyph unicode="" d="M1200 900h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-200v-850q0 -22 25 -34.5t50 -13.5l25 -2v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v850h-200q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h1000v-300zM500 450h-25q0 15 -4 24.5t-9 14.5t-17 7.5t-20 3t-25 0.5h-100v-425q0 -11 12.5 -17.5t25.5 -7.5h12v-50h-200v50q50 0 50 25v425h-100q-17 0 -25 -0.5t-20 -3t-17 -7.5t-9 -14.5t-4 -24.5h-25v150h500v-150z" />
|
||||
<glyph unicode="" d="M1000 300v50q-25 0 -55 32q-14 14 -25 31t-16 27l-4 11l-289 747h-69l-300 -754q-18 -35 -39 -56q-9 -9 -24.5 -18.5t-26.5 -14.5l-11 -5v-50h273v50q-49 0 -78.5 21.5t-11.5 67.5l69 176h293l61 -166q13 -34 -3.5 -66.5t-55.5 -32.5v-50h312zM412 691l134 342l121 -342 h-255zM1100 150v-100q0 -21 -14.5 -35.5t-35.5 -14.5h-1000q-21 0 -35.5 14.5t-14.5 35.5v100q0 21 14.5 35.5t35.5 14.5h1000q21 0 35.5 -14.5t14.5 -35.5z" />
|
||||
<glyph unicode="" d="M50 1200h1100q21 0 35.5 -14.5t14.5 -35.5v-1100q0 -21 -14.5 -35.5t-35.5 -14.5h-1100q-21 0 -35.5 14.5t-14.5 35.5v1100q0 21 14.5 35.5t35.5 14.5zM611 1118h-70q-13 0 -18 -12l-299 -753q-17 -32 -35 -51q-18 -18 -56 -34q-12 -5 -12 -18v-50q0 -8 5.5 -14t14.5 -6 h273q8 0 14 6t6 14v50q0 8 -6 14t-14 6q-55 0 -71 23q-10 14 0 39l63 163h266l57 -153q11 -31 -6 -55q-12 -17 -36 -17q-8 0 -14 -6t-6 -14v-50q0 -8 6 -14t14 -6h313q8 0 14 6t6 14v50q0 7 -5.5 13t-13.5 7q-17 0 -42 25q-25 27 -40 63h-1l-288 748q-5 12 -19 12zM639 611 h-197l103 264z" />
|
||||
<glyph unicode="" d="M1200 1100h-1200v100h1200v-100zM50 1000h400q21 0 35.5 -14.5t14.5 -35.5v-900q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v900q0 21 14.5 35.5t35.5 14.5zM650 1000h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM700 900v-300h300v300h-300z" />
|
||||
<glyph unicode="" d="M50 1200h400q21 0 35.5 -14.5t14.5 -35.5v-900q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v900q0 21 14.5 35.5t35.5 14.5zM650 700h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400 q0 21 14.5 35.5t35.5 14.5zM700 600v-300h300v300h-300zM1200 0h-1200v100h1200v-100z" />
|
||||
<glyph unicode="" d="M50 1000h400q21 0 35.5 -14.5t14.5 -35.5v-350h100v150q0 21 14.5 35.5t35.5 14.5h400q21 0 35.5 -14.5t14.5 -35.5v-150h100v-100h-100v-150q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v150h-100v-350q0 -21 -14.5 -35.5t-35.5 -14.5h-400 q-21 0 -35.5 14.5t-14.5 35.5v800q0 21 14.5 35.5t35.5 14.5zM700 700v-300h300v300h-300z" />
|
||||
<glyph unicode="" d="M100 0h-100v1200h100v-1200zM250 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM300 1000v-300h300v300h-300zM250 500h900q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M600 1100h150q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-150v-100h450q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5h350v100h-150q-21 0 -35.5 14.5 t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5h150v100h100v-100zM400 1000v-300h300v300h-300z" />
|
||||
<glyph unicode="" d="M1200 0h-100v1200h100v-1200zM550 1100h400q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-400q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM600 1000v-300h300v300h-300zM50 500h900q21 0 35.5 -14.5t14.5 -35.5v-400 q0 -21 -14.5 -35.5t-35.5 -14.5h-900q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5z" />
|
||||
<glyph unicode="" d="M865 565l-494 -494q-23 -23 -41 -23q-14 0 -22 13.5t-8 38.5v1000q0 25 8 38.5t22 13.5q18 0 41 -23l494 -494q14 -14 14 -35t-14 -35z" />
|
||||
<glyph unicode="" d="M335 635l494 494q29 29 50 20.5t21 -49.5v-1000q0 -41 -21 -49.5t-50 20.5l-494 494q-14 14 -14 35t14 35z" />
|
||||
<glyph unicode="" d="M100 900h1000q41 0 49.5 -21t-20.5 -50l-494 -494q-14 -14 -35 -14t-35 14l-494 494q-29 29 -20.5 50t49.5 21z" />
|
||||
<glyph unicode="" d="M635 865l494 -494q29 -29 20.5 -50t-49.5 -21h-1000q-41 0 -49.5 21t20.5 50l494 494q14 14 35 14t35 -14z" />
|
||||
<glyph unicode="" d="M700 741v-182l-692 -323v221l413 193l-413 193v221zM1200 0h-800v200h800v-200z" />
|
||||
<glyph unicode="" d="M1200 900h-200v-100h200v-100h-300v300h200v100h-200v100h300v-300zM0 700h50q0 21 4 37t9.5 26.5t18 17.5t22 11t28.5 5.5t31 2t37 0.5h100v-550q0 -22 -25 -34.5t-50 -13.5l-25 -2v-100h400v100q-4 0 -11 0.5t-24 3t-30 7t-24 15t-11 24.5v550h100q25 0 37 -0.5t31 -2 t28.5 -5.5t22 -11t18 -17.5t9.5 -26.5t4 -37h50v300h-800v-300z" />
|
||||
<glyph unicode="" d="M800 700h-50q0 21 -4 37t-9.5 26.5t-18 17.5t-22 11t-28.5 5.5t-31 2t-37 0.5h-100v-550q0 -22 25 -34.5t50 -14.5l25 -1v-100h-400v100q4 0 11 0.5t24 3t30 7t24 15t11 24.5v550h-100q-25 0 -37 -0.5t-31 -2t-28.5 -5.5t-22 -11t-18 -17.5t-9.5 -26.5t-4 -37h-50v300 h800v-300zM1100 200h-200v-100h200v-100h-300v300h200v100h-200v100h300v-300z" />
|
||||
<glyph unicode="" d="M701 1098h160q16 0 21 -11t-7 -23l-464 -464l464 -464q12 -12 7 -23t-21 -11h-160q-13 0 -23 9l-471 471q-7 8 -7 18t7 18l471 471q10 9 23 9z" />
|
||||
<glyph unicode="" d="M339 1098h160q13 0 23 -9l471 -471q7 -8 7 -18t-7 -18l-471 -471q-10 -9 -23 -9h-160q-16 0 -21 11t7 23l464 464l-464 464q-12 12 -7 23t21 11z" />
|
||||
<glyph unicode="" d="M1087 882q11 -5 11 -21v-160q0 -13 -9 -23l-471 -471q-8 -7 -18 -7t-18 7l-471 471q-9 10 -9 23v160q0 16 11 21t23 -7l464 -464l464 464q12 12 23 7z" />
|
||||
<glyph unicode="" d="M618 993l471 -471q9 -10 9 -23v-160q0 -16 -11 -21t-23 7l-464 464l-464 -464q-12 -12 -23 -7t-11 21v160q0 13 9 23l471 471q8 7 18 7t18 -7z" />
|
||||
<glyph unicode="" d="M1000 1200q0 -124 -88 -212t-212 -88q0 124 88 212t212 88zM450 1000h100q21 0 40 -14t26 -33l79 -194q5 1 16 3q34 6 54 9.5t60 7t65.5 1t61 -10t56.5 -23t42.5 -42t29 -64t5 -92t-19.5 -121.5q-1 -7 -3 -19.5t-11 -50t-20.5 -73t-32.5 -81.5t-46.5 -83t-64 -70 t-82.5 -50q-13 -5 -42 -5t-65.5 2.5t-47.5 2.5q-14 0 -49.5 -3.5t-63 -3.5t-43.5 7q-57 25 -104.5 78.5t-75 111.5t-46.5 112t-26 90l-7 35q-15 63 -18 115t4.5 88.5t26 64t39.5 43.5t52 25.5t58.5 13t62.5 2t59.5 -4.5t55.5 -8l-147 192q-12 18 -5.5 30t27.5 12z" />
|
||||
<glyph unicode="🔑" d="M250 1200h600q21 0 35.5 -14.5t14.5 -35.5v-400q0 -21 -14.5 -35.5t-35.5 -14.5h-150v-500l-255 -178q-19 -9 -32 -1t-13 29v650h-150q-21 0 -35.5 14.5t-14.5 35.5v400q0 21 14.5 35.5t35.5 14.5zM400 1100v-100h300v100h-300z" />
|
||||
<glyph unicode="🚪" d="M250 1200h750q39 0 69.5 -40.5t30.5 -84.5v-933l-700 -117v950l600 125h-700v-1000h-100v1025q0 23 15.5 49t34.5 26zM500 525v-100l100 20v100z" />
|
||||
</font>
|
||||
</defs></svg>
|
||||
|
Depois Largura: | Altura: | Tamanho: 106 KiB |