Quellcode durchsuchen

Merge branch 'master' into converse-omemo

JC Brand vor 7 Jahren
Ursprung
Commit
6785eff4a7
100 geänderte Dateien mit 13502 neuen und 19312 gelöschten Zeilen
  1. 0 9
      .babelrc
  2. 1 0
      .eslintrc.json
  3. 2 0
      .gitignore
  4. 6 0
      CHANGES.md
  5. 33 43
      Makefile
  6. 0 210
      bootstrap.py
  7. 1 9
      buildout.cfg
  8. 0 3
      builds/README.md
  9. 503 147
      css/converse.css
  10. 26 0
      css/fullpage.css
  11. 0 8908
      css/inverse.css
  12. 21 2
      css/website.css
  13. 22 24
      dev.html
  14. 3933 2026
      dist/converse-no-dependencies.js
  15. 5614 5251
      dist/converse.js
  16. 97 83
      docs/source/configuration.rst
  17. 39 22
      docs/source/events.rst
  18. 9 12
      docs/source/features.rst
  19. 2 10
      docs/source/quickstart.rst
  20. 3 2
      fullscreen.html
  21. 101 12
      index.html
  22. 602 737
      locale/converse.pot
  23. BIN
      logo/hostpresto.png
  24. 1 1
      mockup/chatbox.html
  25. 2 3
      mockup/chatroom.html
  26. 1 1
      mockup/fullscreen-login.html
  27. 790 338
      package-lock.json
  28. 21 13
      package.json
  29. 18 0
      redirect.html
  30. 1 0
      requirements.txt
  31. 0 1
      sass/_awesomplete.scss
  32. 232 14
      sass/_chatbox.scss
  33. 157 32
      sass/_chatrooms.scss
  34. 131 12
      sass/_controlbox.scss
  35. 28 2
      sass/_core.scss
  36. 0 1
      sass/_embedded.scss
  37. 17 0
      sass/_headline.scss
  38. 1 1
      sass/_minimized_chats.scss
  39. 6 0
      sass/_roomslist.scss
  40. 0 4
      sass/_roster.scss
  41. 32 2
      sass/_variables.scss
  42. 54 26
      sass/_website.scss
  43. 2 6
      sass/converse.scss
  44. 0 71
      sass/converse/_chatbox.scss
  45. 0 22
      sass/converse/_chatrooms.scss
  46. 0 5
      sass/converse/_core.scss
  47. 0 26
      sass/converse/_variables.scss
  48. 0 58
      sass/inverse.scss
  49. 0 96
      sass/inverse/_chatbox.scss
  50. 0 64
      sass/inverse/_chatrooms.scss
  51. 0 102
      sass/inverse/_controlbox.scss
  52. 0 42
      sass/inverse/_core.scss
  53. 0 17
      sass/inverse/_headline.scss
  54. 0 58
      sass/inverse/_minimized_chats.scss
  55. 0 5
      sass/inverse/_roster.scss
  56. 0 34
      sass/inverse/_variables.scss
  57. 34 32
      spec/bookmarks.js
  58. 7 9
      spec/chatbox.js
  59. 190 133
      spec/chatroom.js
  60. 2 2
      spec/controlbox.js
  61. 1 2
      spec/converse.js
  62. 6 3
      spec/disco.js
  63. 2 2
      spec/eventemitter.js
  64. 3 4
      spec/headline.js
  65. 3 3
      spec/http-file-upload.js
  66. 2 2
      spec/login.js
  67. 2 2
      spec/mam.js
  68. 62 20
      spec/messages.js
  69. 2 2
      spec/minchats.js
  70. 2 2
      spec/notification.js
  71. 2 2
      spec/omemo.js
  72. 85 49
      spec/otr.js
  73. 1 1
      spec/ping.js
  74. 3 3
      spec/presence.js
  75. 3 2
      spec/profiling.js
  76. 2 3
      spec/protocol.js
  77. 164 0
      spec/push.js
  78. 20 6
      spec/register.js
  79. 106 5
      spec/roomslist.js
  80. 64 2
      spec/roster.js
  81. 2 9
      spec/spoilers.js
  82. 1 3
      spec/user-details-modal.js
  83. 2 2
      spec/utils.js
  84. 2 2
      spec/xmppstatus.js
  85. 0 9
      src/build-esnext.js
  86. 0 54
      src/build-no-dependencies.js
  87. 0 43
      src/build.js
  88. 0 168
      src/config.js
  89. 7 8
      src/converse-bookmarks.js
  90. 83 73
      src/converse-chatboxes.js
  91. 33 26
      src/converse-chatview.js
  92. 6 6
      src/converse-controlbox.js
  93. 6 8
      src/converse-core.js
  94. 53 13
      src/converse-disco.js
  95. 1 1
      src/converse-dragresize.js
  96. 1 1
      src/converse-fullscreen.js
  97. 2 2
      src/converse-headline.js
  98. 4 4
      src/converse-mam.js
  99. 9 8
      src/converse-message-view.js
  100. 13 14
      src/converse-minimize.js

+ 0 - 9
.babelrc

@@ -1,9 +0,0 @@
-{
-  "presets": [
-    ["@babel/preset-env", {
-      "targets": {
-		"browsers": ["last 2 versions", "safari >= 10", "IE >= 11"]
-      }
-    }]
-  ]
-}

+ 1 - 0
.eslintrc.json

@@ -10,6 +10,7 @@
     "extends": ["eslint:recommended", "plugin:lodash/canonical"],
     "globals": {
         "Promise": true,
+        "converse": true,
         "define": true,
         "require": true,
         "sinon": true,

+ 2 - 0
.gitignore

@@ -13,6 +13,8 @@
 .su?
 builds/*
 3rdparty/libsignal-protocol-javascript/
+*.map
+dist/converse-no-dependencies-es2015.js
 
 analytics.js
 inverse-analytics.js

+ 6 - 0
CHANGES.md

@@ -7,7 +7,11 @@
 - #161 XEP-0363: HTTP File Upload
 - #194 Include entity capabilities in outgoing presence stanzas
 - #337 API call to update a VCard
+- #968 Use nickname from VCard when joining a room
+- #1091 There's now only one CSS file for all view modes.
 - #1094 Show room members who aren't currently online
+- #1106 Support for Roster Versioning
+- #1081 Allow for shift-enter to insert newlines
 - It's now also possible to edit your VCard via the UI
 - Automatically grow/shrink input as text is entered/removed
 - MP4 and MP3 files when sent as XEP-0066 Out of Band Data, are now playable directly in chat
@@ -16,6 +20,8 @@
 - Add a checkbox to indicate whether a trusted device is being used or not.
   If the device is not trusted, sessionStorage is used and all user data is deleted from the browser cache upon logout.
   If the device is trusted, localStorage is used and user data is cached indefinitely.
+- Initial support for XEP-0357 Push Notifications, specifically registering an "App Server".
+- Add support for logging in via OAuth (see the [oauth_providers](https://conversejs.org/docs/html/configurations.html#oauth-providers) setting)
 
 ### Bugfixes
 

+ 33 - 43
Makefile

@@ -8,15 +8,16 @@ CHROMIUM		?= ./node_modules/.bin/run-headless-chromium
 CLEANCSS		?= ./node_modules/clean-css-cli/bin/cleancss --skip-rebase
 ESLINT		  	?= ./node_modules/.bin/eslint
 HTTPSERVE	   	?= ./node_modules/.bin/http-server
-HTTPSERVE_PORT  ?= 8000
-INKSCAPE        ?= inkscape
+HTTPSERVE_PORT		?= 8000
+INKSCAPE		?= inkscape
 JSDOC			?=  ./node_modules/.bin/jsdoc
-OXIPNG          ?= oxipng
+OXIPNG			?= oxipng
 PAPER		   	=
 PO2JSON		 	?= ./node_modules/.bin/po2json
-RJS			 	?= ./node_modules/.bin/r.js
+RJS			?= ./node_modules/.bin/r.js
+WEBPACK 		?= ./node_modules/.bin/npx
 SASS			?= ./.bundle/bin/sass
-SED				?= sed
+SED			?= sed
 SPHINXBUILD	 	?= ./bin/sphinx-build
 SPHINXOPTS	  	=
 UGLIFYJS		?= node_modules/.bin/uglifyjs
@@ -73,7 +74,7 @@ serve_bg: dev
 GETTEXT = xgettext --language="JavaScript" --keyword=__ --keyword=___ --from-code=UTF-8 --output=locale/converse.pot dist/converse-no-dependencies.js --package-name=Converse.js --copyright-holder="Jan-Carel Brand" --package-version=3.3.4 -c
 
 .PHONY: pot
-pot: dist/converse-no-dependencies.js
+pot: dist/converse-no-dependencies-es2015.js
 	$(GETTEXT) 2>&1 > /dev/null; exit $$?;
 
 .PHONY: po
@@ -121,7 +122,7 @@ stamp-bundler: Gemfile
 
 .PHONY: clean
 clean:
-	rm -rf node_modules .bundle stamp-npm
+	rm -rf node_modules .bundle stamp-npm stamp-bundler
 	rm dist/*.min.js
 	rm css/website.min.css
 	rm css/converse.min.css
@@ -134,10 +135,7 @@ dev: stamp-bundler stamp-npm
 ## Builds
 
 .PHONY: css
-css: dev sass/*.scss css/converse.css css/converse.min.css css/website.css css/website.min.css css/inverse.css css/inverse.min.css css/fonts.css
-
-css/inverse.css:: dev sass sass
-	$(SASS) -I $(BOURBON) -I $(BOOTSTRAP) sass/inverse.scss css/inverse.css
+css: dev sass/*.scss css/converse.css css/converse.min.css css/website.css css/website.min.css css/fonts.css
 
 css/converse.css:: dev sass
 	$(SASS) -I $(BOURBON) -I $(BOOTSTRAP) sass/converse.scss css/converse.css
@@ -158,12 +156,7 @@ watch: dev
 
 .PHONY: watchjs
 watchjs: dev
-	$(BABEL) --source-maps --watch=./src --out-dir=./builds
-
-transpile: dev src
-	$(BABEL) --source-maps --out-dir=./builds ./src
-	$(BABEL) --source-maps --out-dir=./builds ./node_modules/backbone.vdomview/backbone.vdomview.js
-	touch transpile
+	./node_modules/.bin/npx  webpack --mode=development  --watch
 
 .PHONY: logo
 logo: logo/conversejs-transparent16.png \
@@ -186,37 +179,34 @@ logo/conversejs-filled%.png:: logo/conversejs-filled.svg
 	$(OXIPNG) $@
 
 BUILDS = dist/converse.js \
-		 dist/converse.min.js \
-         dist/converse-headless.js \
-		 dist/converse-headless.min.js \
-		 dist/converse-no-dependencies.min.js \
-		 dist/converse-no-dependencies.js
-
-# dist/converse-esnext.js \
-# dist/converse-esnext.min.js \
-
-dist/converse.js: transpile src stamp-npm
-	$(RJS) -o src/build.js include=converse out=dist/converse.js optimize=none 
-dist/converse.min.js: transpile src stamp-npm
-	$(RJS) -o src/build.js include=converse out=dist/converse.min.js
-dist/converse-headless.js: transpile src stamp-npm
-	$(RJS) -o src/build.js paths.converse=src/headless include=converse out=dist/converse-headless.js optimize=none 
-dist/converse-headless.min.js: transpile src stamp-npm
-	$(RJS) -o src/build.js paths.converse=src/headless include=converse out=dist/converse-headless.min.js
-dist/converse-esnext.js: src stamp-npm
-	$(RJS) -o src/build-esnext.js include=converse out=dist/converse-esnext.js optimize=none 
-dist/converse-esnext.min.js: src stamp-npm
-	$(RJS) -o src/build-esnext.js include=converse out=dist/converse-esnext.min.js
-dist/converse-no-dependencies.js: transpile src stamp-npm
-	$(RJS) -o src/build-no-dependencies.js optimize=none out=dist/converse-no-dependencies.js
-dist/converse-no-dependencies.min.js: transpile src stamp-npm
-	$(RJS) -o src/build-no-dependencies.js out=dist/converse-no-dependencies.min.js
+	dist/converse.min.js \
+	dist/converse-headless.js \
+	dist/converse-headless.min.js \
+	dist/converse-no-dependencies.min.js \
+	dist/converse-no-dependencies.js \
+	dist/converse-no-dependencies-es2015.js
+
+dist/converse.js: src webpack.config.js stamp-npm
+	./node_modules/.bin/npx  webpack --mode=development
+dist/converse.min.js: src webpack.config.js stamp-npm
+	./node_modules/.bin/npx  webpack --mode=production
+dist/converse-headless.js: src webpack.config.js stamp-npm
+	./node_modules/.bin/npx  webpack --mode=development --type=headless
+dist/converse-headless.min.js: src webpack.config.js stamp-npm
+	./node_modules/.bin/npx  webpack --mode=production --type=headless
+dist/converse-no-dependencies.js: src webpack.config.js stamp-npm
+	./node_modules/.bin/npx  webpack --mode=development --type=nodeps
+dist/converse-no-dependencies.min.js: src webpack.config.js stamp-npm
+	./node_modules/.bin/npx  webpack --mode=production --type=nodeps 
+dist/converse-no-dependencies-es2015.js: src webpack.config.js stamp-npm
+	./node_modules/.bin/npx  webpack --mode=development --type=nodeps --lang=es2015
+
 
 .PHONY: dist
 dist:: build
 
 .PHONY: build
-build:: dev css transpile $(BUILDS)
+build:: dev css $(BUILDS)
 
 ########################################################################
 ## Tests

+ 0 - 210
bootstrap.py

@@ -1,210 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2006 Zope Foundation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-"""Bootstrap a buildout-based project
-
-Simply run this script in a directory containing a buildout.cfg.
-The script accepts buildout command-line options, so you can
-use the -c option to specify an alternate configuration file.
-"""
-
-import os
-import shutil
-import sys
-import tempfile
-
-from optparse import OptionParser
-
-__version__ = '2015-07-01'
-# See zc.buildout's changelog if this version is up to date.
-
-tmpeggs = tempfile.mkdtemp(prefix='bootstrap-')
-
-usage = '''\
-[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
-
-Bootstraps a buildout-based project.
-
-Simply run this script in a directory containing a buildout.cfg, using the
-Python that you want bin/buildout to use.
-
-Note that by using --find-links to point to local resources, you can keep
-this script from going over the network.
-'''
-
-parser = OptionParser(usage=usage)
-parser.add_option("--version",
-                  action="store_true", default=False,
-                  help=("Return bootstrap.py version."))
-parser.add_option("-t", "--accept-buildout-test-releases",
-                  dest='accept_buildout_test_releases',
-                  action="store_true", default=False,
-                  help=("Normally, if you do not specify a --version, the "
-                        "bootstrap script and buildout gets the newest "
-                        "*final* versions of zc.buildout and its recipes and "
-                        "extensions for you.  If you use this flag, "
-                        "bootstrap and buildout will get the newest releases "
-                        "even if they are alphas or betas."))
-parser.add_option("-c", "--config-file",
-                  help=("Specify the path to the buildout configuration "
-                        "file to be used."))
-parser.add_option("-f", "--find-links",
-                  help=("Specify a URL to search for buildout releases"))
-parser.add_option("--allow-site-packages",
-                  action="store_true", default=False,
-                  help=("Let bootstrap.py use existing site packages"))
-parser.add_option("--buildout-version",
-                  help="Use a specific zc.buildout version")
-parser.add_option("--setuptools-version",
-                  help="Use a specific setuptools version")
-parser.add_option("--setuptools-to-dir",
-                  help=("Allow for re-use of existing directory of "
-                        "setuptools versions"))
-
-options, args = parser.parse_args()
-if options.version:
-    print("bootstrap.py version %s" % __version__)
-    sys.exit(0)
-
-
-######################################################################
-# load/install setuptools
-
-try:
-    from urllib.request import urlopen
-except ImportError:
-    from urllib2 import urlopen
-
-ez = {}
-if os.path.exists('ez_setup.py'):
-    exec(open('ez_setup.py').read(), ez)
-else:
-    exec(urlopen('https://bootstrap.pypa.io/ez_setup.py').read(), ez)
-
-if not options.allow_site_packages:
-    # ez_setup imports site, which adds site packages
-    # this will remove them from the path to ensure that incompatible versions
-    # of setuptools are not in the path
-    import site
-    # inside a virtualenv, there is no 'getsitepackages'.
-    # We can't remove these reliably
-    if hasattr(site, 'getsitepackages'):
-        for sitepackage_path in site.getsitepackages():
-            # Strip all site-packages directories from sys.path that
-            # are not sys.prefix; this is because on Windows
-            # sys.prefix is a site-package directory.
-            if sitepackage_path != sys.prefix:
-                sys.path[:] = [x for x in sys.path
-                               if sitepackage_path not in x]
-
-setup_args = dict(to_dir=tmpeggs, download_delay=0)
-
-if options.setuptools_version is not None:
-    setup_args['version'] = options.setuptools_version
-if options.setuptools_to_dir is not None:
-    setup_args['to_dir'] = options.setuptools_to_dir
-
-ez['use_setuptools'](**setup_args)
-import setuptools
-import pkg_resources
-
-# This does not (always?) update the default working set.  We will
-# do it.
-for path in sys.path:
-    if path not in pkg_resources.working_set.entries:
-        pkg_resources.working_set.add_entry(path)
-
-######################################################################
-# Install buildout
-
-ws = pkg_resources.working_set
-
-setuptools_path = ws.find(
-    pkg_resources.Requirement.parse('setuptools')).location
-
-# Fix sys.path here as easy_install.pth added before PYTHONPATH
-cmd = [sys.executable, '-c',
-       'import sys; sys.path[0:0] = [%r]; ' % setuptools_path +
-       'from setuptools.command.easy_install import main; main()',
-       '-mZqNxd', tmpeggs]
-
-find_links = os.environ.get(
-    'bootstrap-testing-find-links',
-    options.find_links or
-    ('http://downloads.buildout.org/'
-     if options.accept_buildout_test_releases else None)
-    )
-if find_links:
-    cmd.extend(['-f', find_links])
-
-requirement = 'zc.buildout'
-version = options.buildout_version
-if version is None and not options.accept_buildout_test_releases:
-    # Figure out the most recent final version of zc.buildout.
-    import setuptools.package_index
-    _final_parts = '*final-', '*final'
-
-    def _final_version(parsed_version):
-        try:
-            return not parsed_version.is_prerelease
-        except AttributeError:
-            # Older setuptools
-            for part in parsed_version:
-                if (part[:1] == '*') and (part not in _final_parts):
-                    return False
-            return True
-
-    index = setuptools.package_index.PackageIndex(
-        search_path=[setuptools_path])
-    if find_links:
-        index.add_find_links((find_links,))
-    req = pkg_resources.Requirement.parse(requirement)
-    if index.obtain(req) is not None:
-        best = []
-        bestv = None
-        for dist in index[req.project_name]:
-            distv = dist.parsed_version
-            if _final_version(distv):
-                if bestv is None or distv > bestv:
-                    best = [dist]
-                    bestv = distv
-                elif distv == bestv:
-                    best.append(dist)
-        if best:
-            best.sort()
-            version = best[-1].version
-if version:
-    requirement = '=='.join((requirement, version))
-cmd.append(requirement)
-
-import subprocess
-if subprocess.call(cmd) != 0:
-    raise Exception(
-        "Failed to execute command:\n%s" % repr(cmd)[1:-1])
-
-######################################################################
-# Import and run buildout
-
-ws.add_entry(tmpeggs)
-ws.require(requirement)
-import zc.buildout.buildout
-
-if not [a for a in args if '=' not in a]:
-    args.append('bootstrap')
-
-# if -c was provided, we push it back into args for buildout' main function
-if options.config_file is not None:
-    args[0:0] = ['-c', options.config_file]
-
-zc.buildout.buildout.main(args)
-shutil.rmtree(tmpeggs)

+ 1 - 9
buildout.cfg

@@ -11,12 +11,4 @@ eggs =
     sphinx-bootstrap-theme
 
 [versions]
-docutils = 0.13.1
-Jinja2 = 2.9.5
-MarkupSafe = 0.23
-Pygments = 2.2.0
-six = 1.10.0
-setuptools = 28.6.1
-Sphinx = 1.5.2
-z3c.recipe.egg = 2.0.3
-zc.buildout = 2.5.3
+Sphinx = 1.7.5

+ 0 - 3
builds/README.md

@@ -1,3 +0,0 @@
-This directory exists as a location for intermediate files generated by the
-Babel compiler, before they're bundled into distribution bundles in the
-`./dist/` directory.

+ 503 - 147
css/converse.css

@@ -3,7 +3,7 @@
  * Converse.js (Web-based XMPP instant messaging client)
  * http://conversejs.org
  *
- * Copyright (c) 2012-2016, JC Brand <jc@opkode.com>
+ * Copyright (c) 2013-2018, JC Brand <jc@opkode.com>
  * Licensed under the Mozilla Public License
  */
 @font-face {
@@ -6868,6 +6868,13 @@ body.reset {
   font-size: 14px;
   direction: ltr;
   z-index: 1031; }
+  #conversejs.converse-overlayed > .row {
+    flex-direction: row-reverse; }
+  #conversejs.converse-fullscreen .converse-chatboxes, #conversejs.converse-mobile .converse-chatboxes {
+    width: 100vw;
+    right: 15px; }
+  #conversejs.converse-overlayed {
+    height: 3em; }
   #conversejs .brand-heading {
     font-family: "Century Gothic", futura, "URW Gothic L", Verdana, sans-serif; }
     #conversejs .brand-heading .icon-conversejs {
@@ -6878,7 +6885,6 @@ body.reset {
     z-index: 1031;
     position: fixed;
     bottom: 0;
-    height: 2.7rem;
     right: 0; }
   #conversejs ::-webkit-input-placeholder {
     /* Chrome/Opera/Safari */
@@ -6932,6 +6938,8 @@ body.reset {
     min-height: 0; }
   #conversejs strong {
     font-weight: 700; }
+  #conversejs em {
+    font-style: italic; }
   #conversejs ol, #conversejs ul {
     list-style: none; }
   #conversejs li {
@@ -6939,13 +6947,17 @@ body.reset {
   #conversejs ul, #conversejs ol, #conversejs dl {
     font: inherit;
     margin: 0; }
-  #conversejs a, #conversejs a:visited, #conversejs a:hover, #conversejs a:not([href]):not([tabindex]) {
+  #conversejs a, #conversejs a:visited, #conversejs a:not([href]):not([tabindex]) {
     text-decoration: none;
     color: #578EA9;
     text-shadow: none; }
-    #conversejs a.fa, #conversejs a:visited.fa, #conversejs a:hover.fa, #conversejs a:not([href]):not([tabindex]).fa {
+    #conversejs a:hover, #conversejs a:visited:hover, #conversejs a:not([href]):not([tabindex]):hover {
+      color: #345566;
+      text-decoration: none;
+      text-shadow: none; }
+    #conversejs a.fa, #conversejs a:visited.fa, #conversejs a:not([href]):not([tabindex]).fa {
       color: #A8ABA1; }
-      #conversejs a.fa:hover, #conversejs a:visited.fa:hover, #conversejs a:hover.fa:hover, #conversejs a:not([href]):not([tabindex]).fa:hover {
+      #conversejs a.fa:hover, #conversejs a:visited.fa:hover, #conversejs a:not([href]):not([tabindex]).fa:hover {
         color: #818479; }
   #conversejs canvas {
     border-radius: 4px; }
@@ -7201,9 +7213,6 @@ body.reset {
 @media screen and (max-height: 450px) {
   #conversejs {
     left: 0; } }
-#conversejs > .row {
-  flex-direction: row-reverse; }
-
 #conversejs form .form-group {
   margin-bottom: 2em; }
 #conversejs form .form-check-label {
@@ -7283,9 +7292,10 @@ body.reset {
 #conversejs #user-profile-modal label {
   font-weight: bold; }
 
+#conversejs .chatbox-navback {
+  display: none; }
 #conversejs .flyout {
   border-radius: 4px;
-  bottom: 1em;
   position: absolute; }
   @media screen and (max-height: 450px) {
     #conversejs .flyout {
@@ -7314,7 +7324,6 @@ body.reset {
   flex-wrap: nowrap;
   color: #ffffff;
   font-size: 100%;
-  height: 55px;
   margin: 0;
   padding: 0.5em;
   position: relative; }
@@ -7324,6 +7333,8 @@ body.reset {
     height: 36px;
     width: 36px;
     margin-right: 0.5em; }
+  #conversejs .chat-head .chatbox-title .chatroom-description {
+    font-size: 80%; }
   #conversejs .chat-head .chatbox-buttons {
     flex-direction: row-reverse;
     position: relative;
@@ -7377,8 +7388,6 @@ body.reset {
     justify-content: space-between;
     background-color: #3AA569;
     box-shadow: 1px 3px 5px 3px rgba(0, 0, 0, 0.4);
-    height: 450px;
-    min-height: 225px;
     z-index: 1;
     overflow-y: scroll;
     width: 100%; }
@@ -7486,7 +7495,6 @@ body.reset {
       width: 100%;
       border: none;
       min-height: 60px;
-      max-height: 200px;
       margin-bottom: -4px; }
       #conversejs .chatbox .sendXMPPMessage .chat-textarea.spoiler {
         height: 42px; }
@@ -7551,7 +7559,6 @@ body.reset {
           #conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu a {
             color: #578EA9; }
           #conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-picker {
-            height: 100px;
             overflow: scroll;
             padding: 0.5em; }
           #conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu ul li {
@@ -7618,75 +7625,209 @@ body.reset {
       top: 0;
       left: 0; }
 
-#conversejs.converse-fullscreen .chatbox-btn {
-  font-size: 16px; }
-#conversejs.converse-fullscreen .chat-head .chatbox-buttons {
-  flex: 0 0 25%;
-  max-width: 25%; }
-
-@media screen and (max-width: 767px) {
-  #conversejs:not(.converse-embedded) > .row {
-    flex-direction: row-reverse; }
-  #conversejs:not(.converse-embedded) #converse-login-panel .converse-form {
-    padding: 3em 2em 3em; }
-  #conversejs:not(.converse-embedded) .sidebar {
-    display: block; }
-  #conversejs:not(.converse-embedded) .chatbox {
-    width: calc(100% - 50px); }
-    #conversejs:not(.converse-embedded) .chatbox .row .box-flyout {
-      left: 50px;
-      bottom: 0;
-      height: 100vh;
-      box-shadow: none; } }
-#converse-embedded-chat .chat-head,
-#conversejs:not(.fullscreen) .chat-head {
+/* ******************* Overlay and embedded styles *************************** */
+#conversejs.converse-embedded .chat-head,
+#conversejs.converse-overlayed .chat-head {
   border-top-left-radius: 4px;
   border-top-right-radius: 4px; }
   @media screen and (max-height: 450px) {
-    #converse-embedded-chat .chat-head,
-    #conversejs:not(.fullscreen) .chat-head {
+    #conversejs.converse-embedded .chat-head,
+    #conversejs.converse-overlayed .chat-head {
       border-top-left-radius: 0;
       border-top-right-radius: 0; } }
   @media screen and (max-width: 480px) {
-    #converse-embedded-chat .chat-head,
-    #conversejs:not(.fullscreen) .chat-head {
+    #conversejs.converse-embedded .chat-head,
+    #conversejs.converse-overlayed .chat-head {
       border-top-left-radius: 0;
       border-top-right-radius: 0; } }
-#converse-embedded-chat .chatbox,
-#conversejs:not(.fullscreen) .chatbox {
+  #conversejs.converse-embedded .chat-head .chatbox-title,
+  #conversejs.converse-overlayed .chat-head .chatbox-title {
+    flex: 0 0 66.6666666667%;
+    max-width: 66.6666666667%; }
+  #conversejs.converse-embedded .chat-head .chatbox-buttons,
+  #conversejs.converse-overlayed .chat-head .chatbox-buttons {
+    flex: 0 0 33.3333333333%;
+    max-width: 33.3333333333%; }
+#conversejs.converse-embedded .chatbox,
+#conversejs.converse-overlayed .chatbox {
   min-width: 250px !important;
   width: 250px; }
-  #converse-embedded-chat .chatbox .box-flyout,
-  #conversejs:not(.fullscreen) .chatbox .box-flyout {
+  #conversejs.converse-embedded .chatbox .box-flyout,
+  #conversejs.converse-overlayed .chatbox .box-flyout {
     min-width: 250px !important;
     width: 250px; }
-  #converse-embedded-chat .chatbox .chat-body .chat-message,
-  #conversejs:not(.fullscreen) .chatbox .chat-body .chat-message {
+  #conversejs.converse-embedded .chatbox .chat-body .chat-message,
+  #conversejs.converse-overlayed .chatbox .chat-body .chat-message {
     line-height: 20px; }
-    #converse-embedded-chat .chatbox .chat-body .chat-message .chat-msg-author,
-    #conversejs:not(.fullscreen) .chatbox .chat-body .chat-message .chat-msg-author {
+    #conversejs.converse-embedded .chatbox .chat-body .chat-message .chat-msg-author,
+    #conversejs.converse-overlayed .chatbox .chat-body .chat-message .chat-msg-author {
       line-height: 20px; }
-    #converse-embedded-chat .chatbox .chat-body .chat-message .chat-msg-content,
-    #conversejs:not(.fullscreen) .chatbox .chat-body .chat-message .chat-msg-content {
+    #conversejs.converse-embedded .chatbox .chat-body .chat-message .chat-msg-content,
+    #conversejs.converse-overlayed .chatbox .chat-body .chat-message .chat-msg-content {
       line-height: 20px; }
-      #converse-embedded-chat .chatbox .chat-body .chat-message .chat-msg-content .emojione,
-      #conversejs:not(.fullscreen) .chatbox .chat-body .chat-message .chat-msg-content .emojione {
+      #conversejs.converse-embedded .chatbox .chat-body .chat-message .chat-msg-content .emojione,
+      #conversejs.converse-overlayed .chatbox .chat-body .chat-message .chat-msg-content .emojione {
         margin-bottom: -5px; }
-#converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu,
-#conversejs:not(.fullscreen) .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu {
+#conversejs.converse-embedded .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu,
+#conversejs.converse-overlayed .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu {
   min-width: 235px; }
-  #converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-toolbar,
-  #conversejs:not(.fullscreen) .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-toolbar {
+  #conversejs.converse-embedded .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-toolbar,
+  #conversejs.converse-overlayed .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-toolbar {
     width: 100%; }
-    #converse-embedded-chat .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-toolbar .emoji-category,
-    #conversejs:not(.fullscreen) .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-toolbar .emoji-category {
+    #conversejs.converse-embedded .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-toolbar .emoji-category,
+    #conversejs.converse-overlayed .chatbox form.sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-toolbar .emoji-category {
       float: left; }
 
+#conversejs.converse-overlayed .flyout {
+  bottom: 1em; }
+#conversejs.converse-overlayed .box-flyout {
+  height: 450px;
+  min-height: 225px; }
+#conversejs.converse-overlayed .chat-head {
+  height: 55px; }
+#conversejs.converse-overlayed .chat-textarea {
+  max-height: 200px; }
+#conversejs.converse-overlayed .emoji-picker {
+  height: 100px; }
+
 @media (max-width: 767.98px) {
-  #conversejs:not(.converse-fullscreen):not(.converse-embedded) > .row {
+  #conversejs.converse-overlayed > .row {
     flex-direction: column; }
-    #conversejs:not(.converse-fullscreen):not(.converse-embedded) > .row.no-gutters {
+    #conversejs.converse-overlayed > .row.no-gutters {
       margin: -1em; } }
+/* ******************* Fullpage styles *************************** */
+#conversejs.converse-fullscreen .flyout {
+  border-radius: 0;
+  border-top: 0.8em solid #3AA569;
+  border: 1.2em solid #3AA569;
+  bottom: 0; }
+#conversejs.converse-fullscreen .chatbox-btn {
+  font-size: 16px;
+  margin: 0 0.3em; }
+#conversejs.converse-fullscreen .chat-head {
+  height: 62px;
+  font-size: 20px;
+  padding: 0; }
+  #conversejs.converse-fullscreen .chat-head .user-custom-message {
+    font-size: 50%;
+    height: auto;
+    line-height: 16px; }
+  #conversejs.converse-fullscreen .chat-head .chatbox-title {
+    flex: 0 0 83.3333333333%;
+    max-width: 83.3333333333%; }
+  #conversejs.converse-fullscreen .chat-head .chatbox-buttons {
+    flex: 0 0 16.6666666667%;
+    max-width: 16.6666666667%; }
+#conversejs.converse-fullscreen .chat-textarea {
+  max-height: 400px; }
+#conversejs.converse-fullscreen .emoji-picker {
+  height: 150px; }
+#conversejs.converse-fullscreen .chatbox {
+  width: 100%;
+  height: 100%;
+  margin: 0;
+  position: relative;
+  width: 100%;
+  min-height: 1px;
+  padding-right: 15px;
+  padding-left: 15px; }
+  @media (min-width: 768px) {
+    #conversejs.converse-fullscreen .chatbox {
+      flex: 0 0 75%;
+      max-width: 75%; } }
+  @media (min-width: 992px) {
+    #conversejs.converse-fullscreen .chatbox {
+      flex: 0 0 75%;
+      max-width: 75%; } }
+  @media (min-width: 1200px) {
+    #conversejs.converse-fullscreen .chatbox {
+      flex: 0 0 83.3333333333%;
+      max-width: 83.3333333333%; } }
+  #conversejs.converse-fullscreen .chatbox .box-flyout {
+    background-color: #3AA569;
+    box-shadow: none;
+    height: 100vh;
+    min-height: 50vh;
+    width: 100%; }
+  #conversejs.converse-fullscreen .chatbox .chat-body {
+    background-color: #3AA569;
+    border-top-left-radius: 4px;
+    border-top-right-radius: 4px; }
+    #conversejs.converse-fullscreen .chatbox .chat-body .chat-message {
+      line-height: 16px;
+      font-size: 12px; }
+      #conversejs.converse-fullscreen .chatbox .chat-body .chat-message .chat-msg-author {
+        line-height: 16px; }
+      #conversejs.converse-fullscreen .chatbox .chat-body .chat-message .chat-msg-content {
+        line-height: 16px; }
+        #conversejs.converse-fullscreen .chatbox .chat-body .chat-message .chat-msg-content .emojione {
+          height: 16px;
+          margin-bottom: -4px; }
+  #conversejs.converse-fullscreen .chatbox .chat-content {
+    border-top-left-radius: 4px;
+    border-top-right-radius: 4px; }
+  #conversejs.converse-fullscreen .chatbox .chat-title {
+    font-size: 20px;
+    line-height: 24px; }
+  #conversejs.converse-fullscreen .chatbox .sendXMPPMessage ul {
+    width: 100%; }
+  #conversejs.converse-fullscreen .chatbox .sendXMPPMessage .toggle-smiley ul.emoji-toolbar .emoji-category-picker {
+    margin-right: 5em; }
+  #conversejs.converse-fullscreen .chatbox .sendXMPPMessage .toggle-smiley ul.emoji-toolbar .emoji-category {
+    padding-left: 10px;
+    padding-right: 10px; }
+
+@media (max-width: 767.98px) {
+  #conversejs:not(.converse-embedded) > .row {
+    flex-direction: row-reverse; }
+  #conversejs:not(.converse-embedded) #converse-login-panel .converse-form {
+    padding: 3em 2em 3em; }
+  #conversejs:not(.converse-embedded) .chatbox {
+    width: calc(100% - 50px); }
+    #conversejs:not(.converse-embedded) .chatbox .row .box-flyout {
+      left: 50px;
+      bottom: 0;
+      height: 100vh;
+      box-shadow: none; }
+
+  #conversejs.converse-mobile .chatbox .box-flyout .chatbox-navback,
+  #conversejs.converse-overlayed .chatbox .box-flyout .chatbox-navback,
+  #conversejs.converse-embedded .chatbox .box-flyout .chatbox-navback,
+  #conversejs.converse-fullscreen .chatbox .box-flyout .chatbox-navback {
+    display: flex;
+    flex: 0 0 16.6666666667%;
+    max-width: 16.6666666667%; }
+    #conversejs.converse-mobile .chatbox .box-flyout .chatbox-navback .fa-arrow-left:before,
+    #conversejs.converse-overlayed .chatbox .box-flyout .chatbox-navback .fa-arrow-left:before,
+    #conversejs.converse-embedded .chatbox .box-flyout .chatbox-navback .fa-arrow-left:before,
+    #conversejs.converse-fullscreen .chatbox .box-flyout .chatbox-navback .fa-arrow-left:before {
+      color: white; }
+  #conversejs.converse-mobile .chatbox .box-flyout .chatbox-title,
+  #conversejs.converse-overlayed .chatbox .box-flyout .chatbox-title,
+  #conversejs.converse-embedded .chatbox .box-flyout .chatbox-title,
+  #conversejs.converse-fullscreen .chatbox .box-flyout .chatbox-title {
+    flex: 0 0 58.3333333333%;
+    max-width: 58.3333333333%; }
+  #conversejs.converse-mobile .chatbox .box-flyout .chatbox-buttons,
+  #conversejs.converse-overlayed .chatbox .box-flyout .chatbox-buttons,
+  #conversejs.converse-embedded .chatbox .box-flyout .chatbox-buttons,
+  #conversejs.converse-fullscreen .chatbox .box-flyout .chatbox-buttons {
+    flex: 0 0 25%;
+    max-width: 25%; } }
+#conversejs .oauth-providers {
+  text-align: center; }
+  #conversejs .oauth-providers .oauth-provider {
+    margin: 1em 0; }
+    #conversejs .oauth-providers .oauth-provider .oauth-login {
+      margin-left: 0;
+      color: #578EA9;
+      font-size: 16px; }
+      #conversejs .oauth-providers .oauth-provider .oauth-login:hover {
+        color: #345566; }
+      #conversejs .oauth-providers .oauth-provider .oauth-login i {
+        color: #578EA9;
+        font-size: 20px;
+        margin-right: 0.5em; }
 #conversejs .set-xmpp-status .fa-circle, #conversejs .xmpp-status .fa-circle, #conversejs .roster-contacts .fa-circle {
   color: #3AA569; }
 #conversejs .set-xmpp-status .fa-minus-circle, #conversejs .xmpp-status .fa-minus-circle, #conversejs .roster-contacts .fa-minus-circle {
@@ -7805,11 +7946,6 @@ body.reset {
       color: #578EA9; }
   #conversejs #controlbox .toggle-register-login {
     font-weight: bold; }
-  #conversejs #controlbox .oauth-login {
-    margin-left: 0;
-    color: #666; }
-    #conversejs #controlbox .oauth-login .icon-social:before {
-      font-size: 16px; }
   #conversejs #controlbox .controlbox-pane .userinfo {
     padding-bottom: 1em; }
     #conversejs #controlbox .controlbox-pane .userinfo .username {
@@ -7884,6 +8020,7 @@ body.reset {
     #conversejs #controlbox .controlbox-pane .chatbox-btn {
       margin: 0; }
     #conversejs #controlbox .controlbox-pane .switch-form {
+      text-align: center;
       padding: 2em 0; }
       #conversejs #controlbox .controlbox-pane .switch-form p {
         margin-top: 0.5em; }
@@ -7925,7 +8062,6 @@ body.reset {
       #conversejs:not(.converse-embedded) .converse-chatboxes .converse-chatroom {
         font-size: 14px; }
       #conversejs:not(.converse-embedded) .converse-chatboxes .chatbox .box-flyout {
-        top: -100vh;
         margin-left: 15px;
         left: 0;
         bottom: 0;
@@ -7933,31 +8069,32 @@ body.reset {
         width: 100vw !important;
         height: 100vh !important; }
       #conversejs:not(.converse-embedded) .converse-chatboxes #controlbox {
-        order: 0; }
+        width: 100vw !important; }
         #conversejs:not(.converse-embedded) .converse-chatboxes #controlbox .box-flyout {
           width: 100vw !important;
-          height: 100vh !important; }
+          height: 100vh !important;
+          margin-left: 30px; }
         #conversejs:not(.converse-embedded) .converse-chatboxes #controlbox .sidebar {
           display: block; }
       #conversejs:not(.converse-embedded) .converse-chatboxes.sidebar-open .chatbox:not(#controlbox) {
         display: none; }
       #conversejs:not(.converse-embedded) .converse-chatboxes.sidebar-open #controlbox .controlbox-pane {
         display: block; } }
-#conversejs:not(.converse-fullscreen) #controlbox {
+#conversejs.converse-overlayed #controlbox {
   order: -1;
   min-width: 250px !important;
   width: 250px; }
-  #conversejs:not(.converse-fullscreen) #controlbox .box-flyout {
+  #conversejs.converse-overlayed #controlbox .box-flyout {
     min-width: 250px !important;
     width: 250px; }
-  #conversejs:not(.converse-fullscreen) #controlbox:not(.logged-out) .controlbox-head {
+  #conversejs.converse-overlayed #controlbox:not(.logged-out) .controlbox-head {
     height: 15px; }
-  #conversejs:not(.converse-fullscreen) #controlbox .controlbox-head {
+  #conversejs.converse-overlayed #controlbox .controlbox-head {
     display: flex;
     flex-direction: row-reverse;
     flex-wrap: nowrap;
     justify-content: space-between; }
-    #conversejs:not(.converse-fullscreen) #controlbox .controlbox-head .brand-heading {
+    #conversejs.converse-overlayed #controlbox .controlbox-head .brand-heading {
       position: relative;
       width: 100%;
       min-height: 1px;
@@ -7967,18 +8104,158 @@ body.reset {
       max-width: 66.6666666667%;
       color: #666;
       font-size: 2em; }
-    #conversejs:not(.converse-fullscreen) #controlbox .controlbox-head .chatbox-btn {
+    #conversejs.converse-overlayed #controlbox .controlbox-head .chatbox-btn {
       color: #578EA9;
       margin: 0; }
-  #conversejs:not(.converse-fullscreen) #controlbox #converse-register, #conversejs:not(.converse-fullscreen) #controlbox #converse-login {
+  #conversejs.converse-overlayed #controlbox #converse-register, #conversejs.converse-overlayed #controlbox #converse-login {
     flex: 0 0 100%;
     max-width: 100%;
     padding-bottom: 0; }
-  #conversejs:not(.converse-fullscreen) #controlbox #converse-register .button-cancel {
+  #conversejs.converse-overlayed #controlbox #converse-register .button-cancel {
     font-size: 90%; }
-  #conversejs:not(.converse-fullscreen) #controlbox .controlbox-panes {
+  #conversejs.converse-overlayed #controlbox .controlbox-panes {
     border-radius: 4px; }
 
+#conversejs.converse-fullscreen #controlbox,
+#conversejs.converse-mobile #controlbox {
+  position: relative;
+  width: 100%;
+  min-height: 1px;
+  padding-right: 15px;
+  padding-left: 15px;
+  margin: 0; }
+  @media (min-width: 768px) {
+    #conversejs.converse-fullscreen #controlbox,
+    #conversejs.converse-mobile #controlbox {
+      flex: 0 0 25%;
+      max-width: 25%; } }
+  @media (min-width: 992px) {
+    #conversejs.converse-fullscreen #controlbox,
+    #conversejs.converse-mobile #controlbox {
+      flex: 0 0 25%;
+      max-width: 25%; } }
+  @media (min-width: 1200px) {
+    #conversejs.converse-fullscreen #controlbox,
+    #conversejs.converse-mobile #controlbox {
+      flex: 0 0 16.6666666667%;
+      max-width: 16.6666666667%; } }
+  #conversejs.converse-fullscreen #controlbox.logged-out,
+  #conversejs.converse-mobile #controlbox.logged-out {
+    flex: 0 0 100%;
+    max-width: 100%; }
+  #conversejs.converse-fullscreen #controlbox .controlbox-pane,
+  #conversejs.converse-mobile #controlbox .controlbox-pane {
+    border-radius: 0; }
+  #conversejs.converse-fullscreen #controlbox .flyout,
+  #conversejs.converse-mobile #controlbox .flyout {
+    border-radius: 0; }
+  #conversejs.converse-fullscreen #controlbox #converse-login-panel,
+  #conversejs.converse-mobile #controlbox #converse-login-panel {
+    border-radius: 0; }
+    #conversejs.converse-fullscreen #controlbox #converse-login-panel .converse-form,
+    #conversejs.converse-mobile #controlbox #converse-login-panel .converse-form {
+      padding: 3em 2em 3em; }
+  #conversejs.converse-fullscreen #controlbox .toggle-register-login,
+  #conversejs.converse-mobile #controlbox .toggle-register-login {
+    line-height: 24px; }
+  #conversejs.converse-fullscreen #controlbox .brand-heading-container,
+  #conversejs.converse-mobile #controlbox .brand-heading-container {
+    flex: 0 0 100%;
+    max-width: 100%;
+    text-align: center; }
+    #conversejs.converse-fullscreen #controlbox .brand-heading-container .brand-heading,
+    #conversejs.converse-mobile #controlbox .brand-heading-container .brand-heading {
+      font-size: 150%;
+      font-size: 600%;
+      padding: 0.7em 0 0 0;
+      opacity: 0.8;
+      color: #387592; }
+    #conversejs.converse-fullscreen #controlbox .brand-heading-container .brand-subtitle,
+    #conversejs.converse-mobile #controlbox .brand-heading-container .brand-subtitle {
+      font-size: 90%;
+      padding: 0.5em; }
+    @media screen and (max-width: 480px) {
+      #conversejs.converse-fullscreen #controlbox .brand-heading-container .brand-heading,
+      #conversejs.converse-mobile #controlbox .brand-heading-container .brand-heading {
+        font-size: 400%; } }
+  #conversejs.converse-fullscreen #controlbox.logged-out,
+  #conversejs.converse-mobile #controlbox.logged-out {
+    flex: 0 0 100%;
+    max-width: 100%;
+    opacity: 0;
+    /* make things invisible upon start */
+    -webkit-animation-name: fadein;
+    -moz-animation-name: fadein;
+    animation-name: fadein;
+    -webkit-animation-fill-mode: forwards;
+    -moz-animation-fill-mode: forwards;
+    animation-fill-mode: forwards;
+    -webkit-animation-duration: 0.75s;
+    -moz-animation-duration: 0.75s;
+    animation-duration: 0.75s;
+    -webkit-animation-timing-function: ease;
+    -moz-animation-timing-function: ease;
+    animation-timing-function: ease;
+    width: 100%; }
+    #conversejs.converse-fullscreen #controlbox.logged-out .box-flyout,
+    #conversejs.converse-mobile #controlbox.logged-out .box-flyout {
+      width: 100%; }
+  #conversejs.converse-fullscreen #controlbox .box-flyout,
+  #conversejs.converse-mobile #controlbox .box-flyout {
+    border: 0;
+    width: 100%;
+    z-index: 1;
+    background-color: #578EA9; }
+    #conversejs.converse-fullscreen #controlbox .box-flyout .controlbox-head,
+    #conversejs.converse-mobile #controlbox .box-flyout .controlbox-head {
+      display: none; }
+  #conversejs.converse-fullscreen #controlbox #converse-register, #conversejs.converse-fullscreen #controlbox #converse-login,
+  #conversejs.converse-mobile #controlbox #converse-register,
+  #conversejs.converse-mobile #controlbox #converse-login {
+    position: relative;
+    width: 100%;
+    min-height: 1px;
+    padding-right: 15px;
+    padding-left: 15px;
+    flex: 0 0 66.6666666667%;
+    max-width: 66.6666666667%;
+    margin-left: 16.6666666667%; }
+    @media (min-width: 576px) {
+      #conversejs.converse-fullscreen #controlbox #converse-register, #conversejs.converse-fullscreen #controlbox #converse-login,
+      #conversejs.converse-mobile #controlbox #converse-register,
+      #conversejs.converse-mobile #controlbox #converse-login {
+        flex: 0 0 66.6666666667%;
+        max-width: 66.6666666667%;
+        margin-left: 16.6666666667%; } }
+    @media (min-width: 768px) {
+      #conversejs.converse-fullscreen #controlbox #converse-register, #conversejs.converse-fullscreen #controlbox #converse-login,
+      #conversejs.converse-mobile #controlbox #converse-register,
+      #conversejs.converse-mobile #controlbox #converse-login {
+        flex: 0 0 66.6666666667%;
+        max-width: 66.6666666667%;
+        margin-left: 16.6666666667%; } }
+    @media (min-width: 992px) {
+      #conversejs.converse-fullscreen #controlbox #converse-register, #conversejs.converse-fullscreen #controlbox #converse-login,
+      #conversejs.converse-mobile #controlbox #converse-register,
+      #conversejs.converse-mobile #controlbox #converse-login {
+        flex: 0 0 50%;
+        max-width: 50%;
+        margin-left: 25%; } }
+    #conversejs.converse-fullscreen #controlbox #converse-register .title, #conversejs.converse-fullscreen #controlbox #converse-register .instructions, #conversejs.converse-fullscreen #controlbox #converse-login .title, #conversejs.converse-fullscreen #controlbox #converse-login .instructions,
+    #conversejs.converse-mobile #controlbox #converse-register .title,
+    #conversejs.converse-mobile #controlbox #converse-register .instructions,
+    #conversejs.converse-mobile #controlbox #converse-login .title,
+    #conversejs.converse-mobile #controlbox #converse-login .instructions {
+      margin: 1em 0; }
+    #conversejs.converse-fullscreen #controlbox #converse-register input[type=submit],
+    #conversejs.converse-fullscreen #controlbox #converse-register input[type=button], #conversejs.converse-fullscreen #controlbox #converse-login input[type=submit],
+    #conversejs.converse-fullscreen #controlbox #converse-login input[type=button],
+    #conversejs.converse-mobile #controlbox #converse-register input[type=submit],
+    #conversejs.converse-mobile #controlbox #converse-register input[type=button],
+    #conversejs.converse-mobile #controlbox #converse-login input[type=submit],
+    #conversejs.converse-mobile #controlbox #converse-login input[type=button] {
+      width: auto; }
+
 #conversejs .list-container {
   text-align: left;
   padding: 0.3em 0; }
@@ -8005,6 +8282,13 @@ body.reset {
     #conversejs .list-container .items-list .open-headline:hover,
     #conversejs .list-container .items-list .open-chatroom:hover {
       background-color: #eff4f7; }
+      #conversejs .list-container .items-list .available-chatroom:hover a.add-bookmark,
+      #conversejs .list-container .items-list .available-chatroom:hover a.room-info,
+      #conversejs .list-container .items-list .open-headline:hover a.add-bookmark,
+      #conversejs .list-container .items-list .open-headline:hover a.room-info,
+      #conversejs .list-container .items-list .open-chatroom:hover a.add-bookmark,
+      #conversejs .list-container .items-list .open-chatroom:hover a.room-info {
+        display: block !important; }
     #conversejs .list-container .items-list .available-chatroom.unread-msgs .msgs-indicator,
     #conversejs .list-container .items-list .open-headline.unread-msgs .msgs-indicator,
     #conversejs .list-container .items-list .open-chatroom.unread-msgs .msgs-indicator {
@@ -8022,10 +8306,18 @@ body.reset {
     #conversejs .list-container .items-list .open-headline a:hover,
     #conversejs .list-container .items-list .open-chatroom a:hover {
       color: #206485; }
-    #conversejs .list-container .items-list .available-chatroom a.room-info:before,
-    #conversejs .list-container .items-list .open-headline a.room-info:before,
-    #conversejs .list-container .items-list .open-chatroom a.room-info:before {
-      font-size: 15px; }
+    #conversejs .list-container .items-list .available-chatroom a.add-bookmark, #conversejs .list-container .items-list .available-chatroom a.room-info,
+    #conversejs .list-container .items-list .open-headline a.add-bookmark,
+    #conversejs .list-container .items-list .open-headline a.room-info,
+    #conversejs .list-container .items-list .open-chatroom a.add-bookmark,
+    #conversejs .list-container .items-list .open-chatroom a.room-info {
+      display: none; }
+      #conversejs .list-container .items-list .available-chatroom a.add-bookmark:before, #conversejs .list-container .items-list .available-chatroom a.room-info:before,
+      #conversejs .list-container .items-list .open-headline a.add-bookmark:before,
+      #conversejs .list-container .items-list .open-headline a.room-info:before,
+      #conversejs .list-container .items-list .open-chatroom a.add-bookmark:before,
+      #conversejs .list-container .items-list .open-chatroom a.room-info:before {
+        font-size: 15px; }
     #conversejs .list-container .items-list .available-chatroom a.open-room,
     #conversejs .list-container .items-list .open-headline a.open-room,
     #conversejs .list-container .items-list .open-chatroom a.open-room {
@@ -8070,7 +8362,6 @@ body.reset {
   position: relative;
   margin: 0;
   height: 194px;
-  height: calc(~"100% - 50px - 20px");
   padding: 0;
   overflow: hidden;
   height: calc(100% - 70px);
@@ -8092,7 +8383,6 @@ body.reset {
       font-size: calc(14px - 2px); }
     #conversejs #converse-roster .roster-filter-form .state-type {
       font-size: calc(14px - 2px);
-      height: 25px;
       width: 100%; }
   #conversejs #converse-roster .roster-contacts {
     padding: 0;
@@ -8163,8 +8453,7 @@ body.reset {
               max-width: 60%; }
           #conversejs #converse-roster .roster-contacts .roster-group li .open-chat .avatar {
             float: left;
-            display: inline-block;
-            height: 60px; }
+            display: inline-block; }
         #conversejs #converse-roster .roster-contacts .roster-group li.current-xmpp-contact span {
           font-size: 14px;
           float: left;
@@ -8202,13 +8491,33 @@ body.reset {
 #conversejs .add-chatroom input[type="submit"],
 #conversejs .add-chatroom input[type="button"] {
   margin: 0.3em 0; }
+#conversejs.converse-embedded #room-details-modal .features-list,
+#conversejs #room-details-modal .features-list {
+  margin-left: 1em; }
+#conversejs.converse-embedded .chatroom-features,
+#conversejs .chatroom-features {
+  width: 100%; }
+  #conversejs.converse-embedded .chatroom-features .features-list,
+  #conversejs .chatroom-features .features-list {
+    padding-top: 0; }
+    #conversejs.converse-embedded .chatroom-features .features-list .feature,
+    #conversejs .chatroom-features .features-list .feature {
+      width: 100%;
+      margin-right: 0.5em;
+      padding-right: 0;
+      font-size: 1em;
+      cursor: help; }
+      #conversejs.converse-embedded .chatroom-features .features-list .feature .fa,
+      #conversejs .chatroom-features .features-list .feature .fa {
+        margin-right: 0.5em;
+        color: #666; }
 #conversejs.converse-embedded .chat-head-chatroom,
 #conversejs .chat-head-chatroom {
   background-color: #E77051; }
   #conversejs.converse-embedded .chat-head-chatroom .chatroom-description,
   #conversejs .chat-head-chatroom .chatroom-description {
     color: #f6ccc1;
-    font-size: 16px;
+    font-size: 14px;
     font-size: 70%;
     margin-top: 3px;
     overflow-y: hidden;
@@ -8295,17 +8604,13 @@ body.reset {
       #conversejs .chatroom .box-flyout .chatroom-body .chat-area {
         display: flex;
         flex-direction: column;
-        word-wrap: break-word;
-        min-width: 250px; }
+        word-wrap: break-word; }
         #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-area .new-msgs-indicator,
         #conversejs .chatroom .box-flyout .chatroom-body .chat-area .new-msgs-indicator {
           background-color: #E77051; }
         #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-area .chat-content,
         #conversejs .chatroom .box-flyout .chatroom-body .chat-area .chat-content {
           height: 100%; }
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-area.full,
-        #conversejs .chatroom .box-flyout .chatroom-body .chat-area.full {
-          min-width: 100%; }
       #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants,
       #conversejs .chatroom .box-flyout .chatroom-body .occupants {
         display: flex;
@@ -8318,20 +8623,18 @@ body.reset {
         border-left: 1px solid #666;
         border-bottom-right-radius: 4px;
         padding: 0.5em; }
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .occupants-heading,
-        #conversejs .chatroom .box-flyout .chatroom-body .occupants .occupants-heading {
-          font-family: "Century Gothic", futura, "URW Gothic L", Verdana, sans-serif;
-          padding: 0.3em 0; }
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .chatroom-features,
-        #conversejs .chatroom .box-flyout .chatroom-body .occupants .chatroom-features {
-          width: 100%; }
-          #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .chatroom-features .feature,
-          #conversejs .chatroom .box-flyout .chatroom-body .occupants .chatroom-features .feature {
-            float: left;
-            margin-right: 0.5em;
-            padding-right: 0;
-            font-size: 1em;
-            cursor: help; }
+        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .occupants-header,
+        #conversejs .chatroom .box-flyout .chatroom-body .occupants .occupants-header {
+          display: flex;
+          flex-direction: column; }
+          #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .occupants-header .hide-occupants,
+          #conversejs .chatroom .box-flyout .chatroom-body .occupants .occupants-header .hide-occupants {
+            align-self: flex-end;
+            cursor: pointer; }
+          #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .occupants-header .occupants-heading,
+          #conversejs .chatroom .box-flyout .chatroom-body .occupants .occupants-header .occupants-heading {
+            font-family: "Century Gothic", futura, "URW Gothic L", Verdana, sans-serif;
+            padding: 0.3em 0; }
         #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .awesomplete ul,
         #conversejs .chatroom .box-flyout .chatroom-body .occupants .awesomplete ul {
           padding: 0; }
@@ -8351,15 +8654,6 @@ body.reset {
             flex-basis: 0;
             flex-grow: 1;
             border-bottom: 1px solid lightgrey; }
-          #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul.features-list,
-          #conversejs .chatroom .box-flyout .chatroom-body .occupants ul.features-list {
-            padding-top: 0; }
-            #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul.features-list .feature,
-            #conversejs .chatroom .box-flyout .chatroom-body .occupants ul.features-list .feature {
-              width: 100%; }
-              #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul.features-list .feature .fa,
-              #conversejs .chatroom .box-flyout .chatroom-body .occupants ul.features-list .feature .fa {
-                color: #666; }
           #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li,
           #conversejs .chatroom .box-flyout .chatroom-body .occupants ul li {
             cursor: default;
@@ -8455,14 +8749,86 @@ body.reset {
     width: 100%;
     border: 1px solid #999; }
 
-#conversejs .chatbox.chatroom {
+/* ******************* Overlay  styles *************************** */
+#conversejs.converse-overlayed .chatbox.chatroom {
   min-width: 400px !important;
   width: 400px; }
-  #conversejs .chatbox.chatroom .box-flyout {
+  #conversejs.converse-overlayed .chatbox.chatroom .box-flyout {
     min-width: 400px !important;
     width: 400px; }
-  #conversejs .chatbox.chatroom .chatroom-body .occupants .chatroom-features .feature {
+  #conversejs.converse-overlayed .chatbox.chatroom .chatbox-title {
+    flex: 0 0 66.6666666667%;
+    max-width: 66.6666666667%; }
+    #conversejs.converse-overlayed .chatbox.chatroom .chatbox-title .chatroom-description {
+      font-size: 80%; }
+  #conversejs.converse-overlayed .chatbox.chatroom .chatbox-buttons {
+    flex: 0 0 33.3333333333%;
+    max-width: 33.3333333333%; }
+  #conversejs.converse-overlayed .chatbox.chatroom .chatroom-body .occupants .chatroom-features .feature {
     font-size: 12px; }
+  #conversejs.converse-overlayed .chatbox.chatroom .chatroom-body .chat-area {
+    min-width: 250px; }
+
+#conversejs.converse-fullscreen .chatroom .box-flyout .chatbox-title {
+  flex: 0 0 75%;
+  max-width: 75%; }
+#conversejs.converse-fullscreen .chatroom .box-flyout .chatbox-buttons {
+  flex: 0 0 25%;
+  max-width: 25%; }
+
+@media (max-width: 767.98px) {
+  #conversejs:not(.converse-embedded) .chatroom {
+    width: 100vw !important; }
+    #conversejs:not(.converse-embedded) .chatroom .box-flyout .chatbox-navback {
+      flex: 0 0 16.6666666667%;
+      max-width: 16.6666666667%; }
+    #conversejs:not(.converse-embedded) .chatroom .box-flyout .chatbox-title {
+      flex: 0 0 58.3333333333%;
+      max-width: 58.3333333333%; }
+    #conversejs:not(.converse-embedded) .chatroom .box-flyout .chatbox-buttons {
+      flex: 0 0 25%;
+      max-width: 25%; } }
+#conversejs.converse-fullscreen .chatroom .box-flyout,
+#conversejs.converse-mobile .chatroom .box-flyout {
+  background-color: #E77051;
+  border: 1.2em solid #E77051;
+  border-top: 0.8em solid #E77051;
+  width: 100%; }
+  #conversejs.converse-fullscreen .chatroom .box-flyout .chatbox-title .chatroom-description,
+  #conversejs.converse-mobile .chatroom .box-flyout .chatbox-title .chatroom-description {
+    font-size: 70%; }
+  #conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body,
+  #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body {
+    border-top-left-radius: 4px;
+    border-top-right-radius: 4px; }
+    #conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .chatroom-form-container,
+    #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .chatroom-form-container {
+      border-radius: 4px; }
+    #conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .chat-area,
+    #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .chat-area {
+      border-top-left-radius: 4px; }
+      #conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .chat-area .chat-content,
+      #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .chat-area .chat-content {
+        border-top-left-radius: 4px; }
+      #conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .chat-area.full,
+      #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .chat-area.full {
+        max-width: 100%; }
+        #conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .chat-area.full .new-msgs-indicator,
+        #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .chat-area.full .new-msgs-indicator {
+          max-width: 100%; }
+    #conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .occupants,
+    #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .occupants {
+      border-top-right-radius: 4px;
+      padding: 1em; }
+      #conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .occupants .occupants-heading,
+      #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .occupants .occupants-heading {
+        font-size: 16px; }
+      #conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .occupants ul.occupant-list li,
+      #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .occupants ul.occupant-list li {
+        font-size: 12px; }
+#conversejs.converse-fullscreen .chatroom .room-invite span .invited-contact,
+#conversejs.converse-mobile .chatroom .room-invite span .invited-contact {
+  margin: 0 0 0.5em -1px; }
 
 #conversejs .chatbox.headlines .chat-head.chat-head-chatbox {
   background-color: #E7A151; }
@@ -8474,6 +8840,14 @@ body.reset {
 #conversejs .chatbox.headlines .chat-content {
   height: 100%; }
 
+#conversejs.converse-fullscreen .chatbox.headlines .box-flyout {
+  background-color: #E7A151; }
+#conversejs.converse-fullscreen .chatbox.headlines .chat-head.chat-head-chatbox {
+  background-color: #E7A151; }
+#conversejs.converse-fullscreen .chatbox.headlines .flyout {
+  border: 1.2em solid #E7A151;
+  border-top: 0.8em solid #E7A151; }
+
 #conversejs .message.date-separator {
   height: 2em;
   margin: 0;
@@ -8600,7 +8974,7 @@ body.reset {
 @media screen and (max-width: 767px) {
   #conversejs:not(.converse-embedded) .message.chat-msg .chat-msg-author {
     white-space: normal; } }
-#conversejs:not(.fullscreen) #minimized-chats {
+#conversejs.converse-overlayed #minimized-chats {
   order: 100;
   width: 130px;
   margin-bottom: -1em;
@@ -8609,10 +8983,10 @@ body.reset {
   color: white;
   margin-right: 0.5em;
   padding: 0; }
-  #conversejs:not(.fullscreen) #minimized-chats .badge {
+  #conversejs.converse-overlayed #minimized-chats .badge {
     bottom: 8px;
     border: 1px solid #818479; }
-  #conversejs:not(.fullscreen) #minimized-chats #toggle-minimized-chats {
+  #conversejs.converse-overlayed #minimized-chats #toggle-minimized-chats {
     border-top-left-radius: 4px;
     border-top-right-radius: 4px;
     background-color: #578EA9;
@@ -8624,7 +8998,7 @@ body.reset {
     text-overflow: ellipsis;
     display: block;
     height: 45px; }
-  #conversejs:not(.fullscreen) #minimized-chats a.restore-chat {
+  #conversejs.converse-overlayed #minimized-chats a.restore-chat {
     padding: 1px 0 1px 5px;
     color: white;
     line-height: 15px;
@@ -8632,24 +9006,24 @@ body.reset {
     overflow: hidden;
     text-overflow: ellipsis;
     white-space: nowrap; }
-    #conversejs:not(.fullscreen) #minimized-chats a.restore-chat:hover {
+    #conversejs.converse-overlayed #minimized-chats a.restore-chat:hover {
       text-decoration: none; }
-  #conversejs:not(.fullscreen) #minimized-chats a.restore-chat:visited {
+  #conversejs.converse-overlayed #minimized-chats a.restore-chat:visited {
     color: white; }
-  #conversejs:not(.fullscreen) #minimized-chats .minimized-chats-flyout {
+  #conversejs.converse-overlayed #minimized-chats .minimized-chats-flyout {
     flex-direction: column-reverse;
     bottom: 42px;
     width: 130px; }
-    #conversejs:not(.fullscreen) #minimized-chats .minimized-chats-flyout .chat-head {
+    #conversejs.converse-overlayed #minimized-chats .minimized-chats-flyout .chat-head {
       padding: 0.3em;
       border-radius: 4px;
       height: 35px;
       margin-bottom: 0.2em;
       box-shadow: 1px 3px 5px 3px rgba(0, 0, 0, 0.4);
       width: 100%; }
-    #conversejs:not(.fullscreen) #minimized-chats .minimized-chats-flyout.minimized {
+    #conversejs.converse-overlayed #minimized-chats .minimized-chats-flyout.minimized {
       height: auto; }
-  #conversejs:not(.fullscreen) #minimized-chats .unread-message-count {
+  #conversejs.converse-overlayed #minimized-chats .unread-message-count {
     font-weight: bold;
     background-color: white;
     border: 1px solid;
@@ -8662,31 +9036,24 @@ body.reset {
     position: absolute;
     right: 116px;
     bottom: 10px; }
-  #conversejs:not(.fullscreen) #minimized-chats .unread-message-count-hidden,
-  #conversejs:not(.fullscreen) #minimized-chats .chat-head-message-count-hidden {
+  #conversejs.converse-overlayed #minimized-chats .unread-message-count-hidden,
+  #conversejs.converse-overlayed #minimized-chats .chat-head-message-count-hidden {
     display: none; }
 
-#converse-embedded-chat [hidden],
 #conversejs [hidden] {
   display: none; }
-#converse-embedded-chat .visually-hidden,
 #conversejs .visually-hidden {
   position: absolute;
   clip: rect(0, 0, 0, 0); }
-#converse-embedded-chat .form-group .awesomplete,
 #conversejs .form-group .awesomplete {
   width: 100%; }
-#converse-embedded-chat div.awesomplete,
 #conversejs div.awesomplete {
   display: inline-block;
   position: relative; }
-  #converse-embedded-chat div.awesomplete mark,
   #conversejs div.awesomplete mark {
     background: #FFB9A7; }
-  #converse-embedded-chat div.awesomplete > input,
   #conversejs div.awesomplete > input {
     display: block; }
-  #converse-embedded-chat div.awesomplete > ul,
   #conversejs div.awesomplete > ul {
     position: absolute;
     left: 0;
@@ -8703,7 +9070,6 @@ body.reset {
     border: 1px solid rgba(0, 0, 0, 0.3);
     box-shadow: 0.05em 0.2em 0.6em rgba(0, 0, 0, 0.2);
     text-shadow: none; }
-    #converse-embedded-chat div.awesomplete > ul:before,
     #conversejs div.awesomplete > ul:before {
       content: "";
       position: absolute;
@@ -8717,44 +9083,34 @@ body.reset {
       border-bottom: 0;
       -webkit-transform: rotate(45deg);
       transform: rotate(45deg); }
-    #converse-embedded-chat div.awesomplete > ul > li,
     #conversejs div.awesomplete > ul > li {
       text-overflow: ellipsis;
       overflow-x: hidden;
       position: relative;
       cursor: pointer;
       padding: 1em; }
-#converse-embedded-chat div.awesomplete > ul[hidden],
-#converse-embedded-chat div.awesomplete > ul:empty,
 #conversejs div.awesomplete > ul[hidden],
 #conversejs div.awesomplete > ul:empty {
   display: none; }
 @supports (transform: scale(0)) {
-  #converse-embedded-chat div.awesomplete > ul,
   #conversejs div.awesomplete > ul {
     transition: 0.3s cubic-bezier(0.4, 0.2, 0.5, 1.4);
     transform-origin: 1.43em -.43em; }
-  #converse-embedded-chat div.awesomplete > ul[hidden],
-  #converse-embedded-chat div.awesomplete > ul:empty,
   #conversejs div.awesomplete > ul[hidden],
   #conversejs div.awesomplete > ul:empty {
     opacity: 0;
     transform: scale(0);
     display: block;
     transition-timing-function: ease; } }
-#converse-embedded-chat div.awesomplete > ul > li:hover,
 #conversejs div.awesomplete > ul > li:hover {
   background: #E77051;
   color: white; }
-#converse-embedded-chat div.awesomplete > ul > li[aria-selected="true"],
 #conversejs div.awesomplete > ul > li[aria-selected="true"] {
   background: #3d6d8f;
   color: white; }
-#converse-embedded-chat div.awesomplete li:hover mark,
 #conversejs div.awesomplete li:hover mark {
   background: #A53214;
   color: white; }
-#converse-embedded-chat div.awesomplete li[aria-selected="true"] mark,
 #conversejs div.awesomplete li[aria-selected="true"] mark {
   background: #3d6b00;
   color: inherit; }

+ 26 - 0
css/fullpage.css

@@ -0,0 +1,26 @@
+body {
+    font-family: "Lora", "Helvetica Neue", Helvetica, Arial, sans-serif;
+    color: #ffffff;
+    background-color: #578EA9;
+}
+.brand-heading {
+    font-size: 600%;
+    margin-left: -10%;
+}
+.icon-conversejs {
+    font-size: 88%;
+}
+.brand-heading div.content {
+    height: 100vh;
+    width: 100vw;
+    position: fixed;
+    background-color: #578EA9;
+}
+.brand-heading div.content .inner-content {
+    text-align: center;
+    padding: 7%;
+}
+p.no-chats {
+    padding-right: 10%;
+    font-size: 120%;
+}

+ 0 - 8908
css/inverse.css

@@ -1,8908 +0,0 @@
-@charset "UTF-8";
-/*!
- * Converse.js (Web-based XMPP instant messaging client)
- * http://conversejs.org
- *
- * Copyright (c) 2012-2014, JC Brand <jc@opkode.com>
- * Licensed under the Mozilla Public License
- */
-@font-face {
-  font-family: 'ConverseFontAwesome';
-  src: url("../fonts/fontawesome-webfont.eot?v=4.7.0");
-  src: url("../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0") format("embedded-opentype"), url("../fonts/fontawesome-webfont.woff2?v=4.7.0") format("woff2"), url("../fonts/fontawesome-webfont.woff?v=4.7.0") format("woff"), url("../fonts/fontawesome-webfont.ttf?v=4.7.0") format("truetype"), url("../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular") format("svg");
-  font-weight: normal;
-  font-style: normal; }
-.fa {
-  display: inline-block;
-  font: normal normal normal 14px/1 FontAwesome;
-  font-size: inherit;
-  text-rendering: auto;
-  -webkit-font-smoothing: antialiased;
-  -moz-osx-font-smoothing: grayscale; }
-
-/* makes the font 33% larger relative to the icon container */
-.fa-lg {
-  font-size: 1.3333333333em;
-  line-height: 0.75em;
-  vertical-align: -15%; }
-
-.fa-2x {
-  font-size: 2em; }
-
-.fa-3x {
-  font-size: 3em; }
-
-.fa-4x {
-  font-size: 4em; }
-
-.fa-5x {
-  font-size: 5em; }
-
-.fa-fw {
-  width: 1.2857142857em;
-  text-align: center; }
-
-.fa-ul {
-  padding-left: 0;
-  margin-left: 2.1428571429em;
-  list-style-type: none; }
-  .fa-ul > li {
-    position: relative; }
-
-.fa-li {
-  position: absolute;
-  left: -2.1428571429em;
-  width: 2.1428571429em;
-  top: 0.1428571429em;
-  text-align: center; }
-  .fa-li.fa-lg {
-    left: -1.8571428571em; }
-
-.fa-border {
-  padding: .2em .25em .15em;
-  border: solid 0.08em #eee;
-  border-radius: .1em; }
-
-.fa-pull-left {
-  float: left; }
-
-.fa-pull-right {
-  float: right; }
-
-.fa.fa-pull-left {
-  margin-right: .3em; }
-.fa.fa-pull-right {
-  margin-left: .3em; }
-
-/* Deprecated as of 4.4.0 */
-.pull-right {
-  float: right; }
-
-.pull-left {
-  float: left; }
-
-.fa.pull-left {
-  margin-right: .3em; }
-.fa.pull-right {
-  margin-left: .3em; }
-
-.fa-spin {
-  -webkit-animation: fa-spin 2s infinite linear;
-  animation: fa-spin 2s infinite linear; }
-
-.fa-pulse {
-  -webkit-animation: fa-spin 1s infinite steps(8);
-  animation: fa-spin 1s infinite steps(8); }
-
-@-webkit-keyframes fa-spin {
-  0% {
-    -webkit-transform: rotate(0deg);
-    transform: rotate(0deg); }
-  100% {
-    -webkit-transform: rotate(359deg);
-    transform: rotate(359deg); } }
-@keyframes fa-spin {
-  0% {
-    -webkit-transform: rotate(0deg);
-    transform: rotate(0deg); }
-  100% {
-    -webkit-transform: rotate(359deg);
-    transform: rotate(359deg); } }
-.fa-rotate-90 {
-  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";
-  -webkit-transform: rotate(90deg);
-  -ms-transform: rotate(90deg);
-  transform: rotate(90deg); }
-
-.fa-rotate-180 {
-  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";
-  -webkit-transform: rotate(180deg);
-  -ms-transform: rotate(180deg);
-  transform: rotate(180deg); }
-
-.fa-rotate-270 {
-  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";
-  -webkit-transform: rotate(270deg);
-  -ms-transform: rotate(270deg);
-  transform: rotate(270deg); }
-
-.fa-flip-horizontal {
-  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";
-  -webkit-transform: scale(-1, 1);
-  -ms-transform: scale(-1, 1);
-  transform: scale(-1, 1); }
-
-.fa-flip-vertical {
-  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";
-  -webkit-transform: scale(1, -1);
-  -ms-transform: scale(1, -1);
-  transform: scale(1, -1); }
-
-:root .fa-rotate-90,
-:root .fa-rotate-180,
-:root .fa-rotate-270,
-:root .fa-flip-horizontal,
-:root .fa-flip-vertical {
-  filter: none; }
-
-.fa-stack {
-  position: relative;
-  display: inline-block;
-  width: 2em;
-  height: 2em;
-  line-height: 2em;
-  vertical-align: middle; }
-
-.fa-stack-1x, .fa-stack-2x {
-  position: absolute;
-  left: 0;
-  width: 100%;
-  text-align: center; }
-
-.fa-stack-1x {
-  line-height: inherit; }
-
-.fa-stack-2x {
-  font-size: 2em; }
-
-.fa-inverse {
-  color: #fff; }
-
-/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen
-   readers do not read off random characters that represent icons */
-.fa-glass:before {
-  content: ""; }
-
-.fa-music:before {
-  content: ""; }
-
-.fa-search:before {
-  content: ""; }
-
-.fa-envelope-o:before {
-  content: ""; }
-
-.fa-heart:before {
-  content: ""; }
-
-.fa-star:before {
-  content: ""; }
-
-.fa-star-o:before {
-  content: ""; }
-
-.fa-user:before {
-  content: ""; }
-
-.fa-film:before {
-  content: ""; }
-
-.fa-th-large:before {
-  content: ""; }
-
-.fa-th:before {
-  content: ""; }
-
-.fa-th-list:before {
-  content: ""; }
-
-.fa-check:before {
-  content: ""; }
-
-.fa-remove:before,
-.fa-close:before,
-.fa-times:before {
-  content: ""; }
-
-.fa-search-plus:before {
-  content: ""; }
-
-.fa-search-minus:before {
-  content: ""; }
-
-.fa-power-off:before {
-  content: ""; }
-
-.fa-signal:before {
-  content: ""; }
-
-.fa-gear:before,
-.fa-cog:before {
-  content: ""; }
-
-.fa-trash-o:before {
-  content: ""; }
-
-.fa-home:before {
-  content: ""; }
-
-.fa-file-o:before {
-  content: ""; }
-
-.fa-clock-o:before {
-  content: ""; }
-
-.fa-road:before {
-  content: ""; }
-
-.fa-download:before {
-  content: ""; }
-
-.fa-arrow-circle-o-down:before {
-  content: ""; }
-
-.fa-arrow-circle-o-up:before {
-  content: ""; }
-
-.fa-inbox:before {
-  content: ""; }
-
-.fa-play-circle-o:before {
-  content: ""; }
-
-.fa-rotate-right:before,
-.fa-repeat:before {
-  content: ""; }
-
-.fa-refresh:before {
-  content: ""; }
-
-.fa-list-alt:before {
-  content: ""; }
-
-.fa-lock:before {
-  content: ""; }
-
-.fa-flag:before {
-  content: ""; }
-
-.fa-headphones:before {
-  content: ""; }
-
-.fa-volume-off:before {
-  content: ""; }
-
-.fa-volume-down:before {
-  content: ""; }
-
-.fa-volume-up:before {
-  content: ""; }
-
-.fa-qrcode:before {
-  content: ""; }
-
-.fa-barcode:before {
-  content: ""; }
-
-.fa-tag:before {
-  content: ""; }
-
-.fa-tags:before {
-  content: ""; }
-
-.fa-book:before {
-  content: ""; }
-
-.fa-bookmark:before {
-  content: ""; }
-
-.fa-print:before {
-  content: ""; }
-
-.fa-camera:before {
-  content: ""; }
-
-.fa-font:before {
-  content: ""; }
-
-.fa-bold:before {
-  content: ""; }
-
-.fa-italic:before {
-  content: ""; }
-
-.fa-text-height:before {
-  content: ""; }
-
-.fa-text-width:before {
-  content: ""; }
-
-.fa-align-left:before {
-  content: ""; }
-
-.fa-align-center:before {
-  content: ""; }
-
-.fa-align-right:before {
-  content: ""; }
-
-.fa-align-justify:before {
-  content: ""; }
-
-.fa-list:before {
-  content: ""; }
-
-.fa-dedent:before,
-.fa-outdent:before {
-  content: ""; }
-
-.fa-indent:before {
-  content: ""; }
-
-.fa-video-camera:before {
-  content: ""; }
-
-.fa-photo:before,
-.fa-image:before,
-.fa-picture-o:before {
-  content: ""; }
-
-.fa-pencil:before {
-  content: ""; }
-
-.fa-map-marker:before {
-  content: ""; }
-
-.fa-adjust:before {
-  content: ""; }
-
-.fa-tint:before {
-  content: ""; }
-
-.fa-edit:before,
-.fa-pencil-square-o:before {
-  content: ""; }
-
-.fa-share-square-o:before {
-  content: ""; }
-
-.fa-check-square-o:before {
-  content: ""; }
-
-.fa-arrows:before {
-  content: ""; }
-
-.fa-step-backward:before {
-  content: ""; }
-
-.fa-fast-backward:before {
-  content: ""; }
-
-.fa-backward:before {
-  content: ""; }
-
-.fa-play:before {
-  content: ""; }
-
-.fa-pause:before {
-  content: ""; }
-
-.fa-stop:before {
-  content: ""; }
-
-.fa-forward:before {
-  content: ""; }
-
-.fa-fast-forward:before {
-  content: ""; }
-
-.fa-step-forward:before {
-  content: ""; }
-
-.fa-eject:before {
-  content: ""; }
-
-.fa-chevron-left:before {
-  content: ""; }
-
-.fa-chevron-right:before {
-  content: ""; }
-
-.fa-plus-circle:before {
-  content: ""; }
-
-.fa-minus-circle:before {
-  content: ""; }
-
-.fa-times-circle:before {
-  content: ""; }
-
-.fa-check-circle:before {
-  content: ""; }
-
-.fa-question-circle:before {
-  content: ""; }
-
-.fa-info-circle:before {
-  content: ""; }
-
-.fa-crosshairs:before {
-  content: ""; }
-
-.fa-times-circle-o:before {
-  content: ""; }
-
-.fa-check-circle-o:before {
-  content: ""; }
-
-.fa-ban:before {
-  content: ""; }
-
-.fa-arrow-left:before {
-  content: ""; }
-
-.fa-arrow-right:before {
-  content: ""; }
-
-.fa-arrow-up:before {
-  content: ""; }
-
-.fa-arrow-down:before {
-  content: ""; }
-
-.fa-mail-forward:before,
-.fa-share:before {
-  content: ""; }
-
-.fa-expand:before {
-  content: ""; }
-
-.fa-compress:before {
-  content: ""; }
-
-.fa-plus:before {
-  content: ""; }
-
-.fa-minus:before {
-  content: ""; }
-
-.fa-asterisk:before {
-  content: ""; }
-
-.fa-exclamation-circle:before {
-  content: ""; }
-
-.fa-gift:before {
-  content: ""; }
-
-.fa-leaf:before {
-  content: ""; }
-
-.fa-fire:before {
-  content: ""; }
-
-.fa-eye:before {
-  content: ""; }
-
-.fa-eye-slash:before {
-  content: ""; }
-
-.fa-warning:before,
-.fa-exclamation-triangle:before {
-  content: ""; }
-
-.fa-plane:before {
-  content: ""; }
-
-.fa-calendar:before {
-  content: ""; }
-
-.fa-random:before {
-  content: ""; }
-
-.fa-comment:before {
-  content: ""; }
-
-.fa-magnet:before {
-  content: ""; }
-
-.fa-chevron-up:before {
-  content: ""; }
-
-.fa-chevron-down:before {
-  content: ""; }
-
-.fa-retweet:before {
-  content: ""; }
-
-.fa-shopping-cart:before {
-  content: ""; }
-
-.fa-folder:before {
-  content: ""; }
-
-.fa-folder-open:before {
-  content: ""; }
-
-.fa-arrows-v:before {
-  content: ""; }
-
-.fa-arrows-h:before {
-  content: ""; }
-
-.fa-bar-chart-o:before,
-.fa-bar-chart:before {
-  content: ""; }
-
-.fa-twitter-square:before {
-  content: ""; }
-
-.fa-facebook-square:before {
-  content: ""; }
-
-.fa-camera-retro:before {
-  content: ""; }
-
-.fa-key:before {
-  content: ""; }
-
-.fa-gears:before,
-.fa-cogs:before {
-  content: ""; }
-
-.fa-comments:before {
-  content: ""; }
-
-.fa-thumbs-o-up:before {
-  content: ""; }
-
-.fa-thumbs-o-down:before {
-  content: ""; }
-
-.fa-star-half:before {
-  content: ""; }
-
-.fa-heart-o:before {
-  content: ""; }
-
-.fa-sign-out:before {
-  content: ""; }
-
-.fa-linkedin-square:before {
-  content: ""; }
-
-.fa-thumb-tack:before {
-  content: ""; }
-
-.fa-external-link:before {
-  content: ""; }
-
-.fa-sign-in:before {
-  content: ""; }
-
-.fa-trophy:before {
-  content: ""; }
-
-.fa-github-square:before {
-  content: ""; }
-
-.fa-upload:before {
-  content: ""; }
-
-.fa-lemon-o:before {
-  content: ""; }
-
-.fa-phone:before {
-  content: ""; }
-
-.fa-square-o:before {
-  content: ""; }
-
-.fa-bookmark-o:before {
-  content: ""; }
-
-.fa-phone-square:before {
-  content: ""; }
-
-.fa-twitter:before {
-  content: ""; }
-
-.fa-facebook-f:before,
-.fa-facebook:before {
-  content: ""; }
-
-.fa-github:before {
-  content: ""; }
-
-.fa-unlock:before {
-  content: ""; }
-
-.fa-credit-card:before {
-  content: ""; }
-
-.fa-feed:before,
-.fa-rss:before {
-  content: ""; }
-
-.fa-hdd-o:before {
-  content: ""; }
-
-.fa-bullhorn:before {
-  content: ""; }
-
-.fa-bell:before {
-  content: ""; }
-
-.fa-certificate:before {
-  content: ""; }
-
-.fa-hand-o-right:before {
-  content: ""; }
-
-.fa-hand-o-left:before {
-  content: ""; }
-
-.fa-hand-o-up:before {
-  content: ""; }
-
-.fa-hand-o-down:before {
-  content: ""; }
-
-.fa-arrow-circle-left:before {
-  content: ""; }
-
-.fa-arrow-circle-right:before {
-  content: ""; }
-
-.fa-arrow-circle-up:before {
-  content: ""; }
-
-.fa-arrow-circle-down:before {
-  content: ""; }
-
-.fa-globe:before {
-  content: ""; }
-
-.fa-wrench:before {
-  content: ""; }
-
-.fa-tasks:before {
-  content: ""; }
-
-.fa-filter:before {
-  content: ""; }
-
-.fa-briefcase:before {
-  content: ""; }
-
-.fa-arrows-alt:before {
-  content: ""; }
-
-.fa-group:before,
-.fa-users:before {
-  content: ""; }
-
-.fa-chain:before,
-.fa-link:before {
-  content: ""; }
-
-.fa-cloud:before {
-  content: ""; }
-
-.fa-flask:before {
-  content: ""; }
-
-.fa-cut:before,
-.fa-scissors:before {
-  content: ""; }
-
-.fa-copy:before,
-.fa-files-o:before {
-  content: ""; }
-
-.fa-paperclip:before {
-  content: ""; }
-
-.fa-save:before,
-.fa-floppy-o:before {
-  content: ""; }
-
-.fa-square:before {
-  content: ""; }
-
-.fa-navicon:before,
-.fa-reorder:before,
-.fa-bars:before {
-  content: ""; }
-
-.fa-list-ul:before {
-  content: ""; }
-
-.fa-list-ol:before {
-  content: ""; }
-
-.fa-strikethrough:before {
-  content: ""; }
-
-.fa-underline:before {
-  content: ""; }
-
-.fa-table:before {
-  content: ""; }
-
-.fa-magic:before {
-  content: ""; }
-
-.fa-truck:before {
-  content: ""; }
-
-.fa-pinterest:before {
-  content: ""; }
-
-.fa-pinterest-square:before {
-  content: ""; }
-
-.fa-google-plus-square:before {
-  content: ""; }
-
-.fa-google-plus:before {
-  content: ""; }
-
-.fa-money:before {
-  content: ""; }
-
-.fa-caret-down:before {
-  content: ""; }
-
-.fa-caret-up:before {
-  content: ""; }
-
-.fa-caret-left:before {
-  content: ""; }
-
-.fa-caret-right:before {
-  content: ""; }
-
-.fa-columns:before {
-  content: ""; }
-
-.fa-unsorted:before,
-.fa-sort:before {
-  content: ""; }
-
-.fa-sort-down:before,
-.fa-sort-desc:before {
-  content: ""; }
-
-.fa-sort-up:before,
-.fa-sort-asc:before {
-  content: ""; }
-
-.fa-envelope:before {
-  content: ""; }
-
-.fa-linkedin:before {
-  content: ""; }
-
-.fa-rotate-left:before,
-.fa-undo:before {
-  content: ""; }
-
-.fa-legal:before,
-.fa-gavel:before {
-  content: ""; }
-
-.fa-dashboard:before,
-.fa-tachometer:before {
-  content: ""; }
-
-.fa-comment-o:before {
-  content: ""; }
-
-.fa-comments-o:before {
-  content: ""; }
-
-.fa-flash:before,
-.fa-bolt:before {
-  content: ""; }
-
-.fa-sitemap:before {
-  content: ""; }
-
-.fa-umbrella:before {
-  content: ""; }
-
-.fa-paste:before,
-.fa-clipboard:before {
-  content: ""; }
-
-.fa-lightbulb-o:before {
-  content: ""; }
-
-.fa-exchange:before {
-  content: ""; }
-
-.fa-cloud-download:before {
-  content: ""; }
-
-.fa-cloud-upload:before {
-  content: ""; }
-
-.fa-user-md:before {
-  content: ""; }
-
-.fa-stethoscope:before {
-  content: ""; }
-
-.fa-suitcase:before {
-  content: ""; }
-
-.fa-bell-o:before {
-  content: ""; }
-
-.fa-coffee:before {
-  content: ""; }
-
-.fa-cutlery:before {
-  content: ""; }
-
-.fa-file-text-o:before {
-  content: ""; }
-
-.fa-building-o:before {
-  content: ""; }
-
-.fa-hospital-o:before {
-  content: ""; }
-
-.fa-ambulance:before {
-  content: ""; }
-
-.fa-medkit:before {
-  content: ""; }
-
-.fa-fighter-jet:before {
-  content: ""; }
-
-.fa-beer:before {
-  content: ""; }
-
-.fa-h-square:before {
-  content: ""; }
-
-.fa-plus-square:before {
-  content: ""; }
-
-.fa-angle-double-left:before {
-  content: ""; }
-
-.fa-angle-double-right:before {
-  content: ""; }
-
-.fa-angle-double-up:before {
-  content: ""; }
-
-.fa-angle-double-down:before {
-  content: ""; }
-
-.fa-angle-left:before {
-  content: ""; }
-
-.fa-angle-right:before {
-  content: ""; }
-
-.fa-angle-up:before {
-  content: ""; }
-
-.fa-angle-down:before {
-  content: ""; }
-
-.fa-desktop:before {
-  content: ""; }
-
-.fa-laptop:before {
-  content: ""; }
-
-.fa-tablet:before {
-  content: ""; }
-
-.fa-mobile-phone:before,
-.fa-mobile:before {
-  content: ""; }
-
-.fa-circle-o:before {
-  content: ""; }
-
-.fa-quote-left:before {
-  content: ""; }
-
-.fa-quote-right:before {
-  content: ""; }
-
-.fa-spinner:before {
-  content: ""; }
-
-.fa-circle:before {
-  content: ""; }
-
-.fa-mail-reply:before,
-.fa-reply:before {
-  content: ""; }
-
-.fa-github-alt:before {
-  content: ""; }
-
-.fa-folder-o:before {
-  content: ""; }
-
-.fa-folder-open-o:before {
-  content: ""; }
-
-.fa-smile-o:before {
-  content: ""; }
-
-.fa-frown-o:before {
-  content: ""; }
-
-.fa-meh-o:before {
-  content: ""; }
-
-.fa-gamepad:before {
-  content: ""; }
-
-.fa-keyboard-o:before {
-  content: ""; }
-
-.fa-flag-o:before {
-  content: ""; }
-
-.fa-flag-checkered:before {
-  content: ""; }
-
-.fa-terminal:before {
-  content: ""; }
-
-.fa-code:before {
-  content: ""; }
-
-.fa-mail-reply-all:before,
-.fa-reply-all:before {
-  content: ""; }
-
-.fa-star-half-empty:before,
-.fa-star-half-full:before,
-.fa-star-half-o:before {
-  content: ""; }
-
-.fa-location-arrow:before {
-  content: ""; }
-
-.fa-crop:before {
-  content: ""; }
-
-.fa-code-fork:before {
-  content: ""; }
-
-.fa-unlink:before,
-.fa-chain-broken:before {
-  content: ""; }
-
-.fa-question:before {
-  content: ""; }
-
-.fa-info:before {
-  content: ""; }
-
-.fa-exclamation:before {
-  content: ""; }
-
-.fa-superscript:before {
-  content: ""; }
-
-.fa-subscript:before {
-  content: ""; }
-
-.fa-eraser:before {
-  content: ""; }
-
-.fa-puzzle-piece:before {
-  content: ""; }
-
-.fa-microphone:before {
-  content: ""; }
-
-.fa-microphone-slash:before {
-  content: ""; }
-
-.fa-shield:before {
-  content: ""; }
-
-.fa-calendar-o:before {
-  content: ""; }
-
-.fa-fire-extinguisher:before {
-  content: ""; }
-
-.fa-rocket:before {
-  content: ""; }
-
-.fa-maxcdn:before {
-  content: ""; }
-
-.fa-chevron-circle-left:before {
-  content: ""; }
-
-.fa-chevron-circle-right:before {
-  content: ""; }
-
-.fa-chevron-circle-up:before {
-  content: ""; }
-
-.fa-chevron-circle-down:before {
-  content: ""; }
-
-.fa-html5:before {
-  content: ""; }
-
-.fa-css3:before {
-  content: ""; }
-
-.fa-anchor:before {
-  content: ""; }
-
-.fa-unlock-alt:before {
-  content: ""; }
-
-.fa-bullseye:before {
-  content: ""; }
-
-.fa-ellipsis-h:before {
-  content: ""; }
-
-.fa-ellipsis-v:before {
-  content: ""; }
-
-.fa-rss-square:before {
-  content: ""; }
-
-.fa-play-circle:before {
-  content: ""; }
-
-.fa-ticket:before {
-  content: ""; }
-
-.fa-minus-square:before {
-  content: ""; }
-
-.fa-minus-square-o:before {
-  content: ""; }
-
-.fa-level-up:before {
-  content: ""; }
-
-.fa-level-down:before {
-  content: ""; }
-
-.fa-check-square:before {
-  content: ""; }
-
-.fa-pencil-square:before {
-  content: ""; }
-
-.fa-external-link-square:before {
-  content: ""; }
-
-.fa-share-square:before {
-  content: ""; }
-
-.fa-compass:before {
-  content: ""; }
-
-.fa-toggle-down:before,
-.fa-caret-square-o-down:before {
-  content: ""; }
-
-.fa-toggle-up:before,
-.fa-caret-square-o-up:before {
-  content: ""; }
-
-.fa-toggle-right:before,
-.fa-caret-square-o-right:before {
-  content: ""; }
-
-.fa-euro:before,
-.fa-eur:before {
-  content: ""; }
-
-.fa-gbp:before {
-  content: ""; }
-
-.fa-dollar:before,
-.fa-usd:before {
-  content: ""; }
-
-.fa-rupee:before,
-.fa-inr:before {
-  content: ""; }
-
-.fa-cny:before,
-.fa-rmb:before,
-.fa-yen:before,
-.fa-jpy:before {
-  content: ""; }
-
-.fa-ruble:before,
-.fa-rouble:before,
-.fa-rub:before {
-  content: ""; }
-
-.fa-won:before,
-.fa-krw:before {
-  content: ""; }
-
-.fa-bitcoin:before,
-.fa-btc:before {
-  content: ""; }
-
-.fa-file:before {
-  content: ""; }
-
-.fa-file-text:before {
-  content: ""; }
-
-.fa-sort-alpha-asc:before {
-  content: ""; }
-
-.fa-sort-alpha-desc:before {
-  content: ""; }
-
-.fa-sort-amount-asc:before {
-  content: ""; }
-
-.fa-sort-amount-desc:before {
-  content: ""; }
-
-.fa-sort-numeric-asc:before {
-  content: ""; }
-
-.fa-sort-numeric-desc:before {
-  content: ""; }
-
-.fa-thumbs-up:before {
-  content: ""; }
-
-.fa-thumbs-down:before {
-  content: ""; }
-
-.fa-youtube-square:before {
-  content: ""; }
-
-.fa-youtube:before {
-  content: ""; }
-
-.fa-xing:before {
-  content: ""; }
-
-.fa-xing-square:before {
-  content: ""; }
-
-.fa-youtube-play:before {
-  content: ""; }
-
-.fa-dropbox:before {
-  content: ""; }
-
-.fa-stack-overflow:before {
-  content: ""; }
-
-.fa-instagram:before {
-  content: ""; }
-
-.fa-flickr:before {
-  content: ""; }
-
-.fa-adn:before {
-  content: ""; }
-
-.fa-bitbucket:before {
-  content: ""; }
-
-.fa-bitbucket-square:before {
-  content: ""; }
-
-.fa-tumblr:before {
-  content: ""; }
-
-.fa-tumblr-square:before {
-  content: ""; }
-
-.fa-long-arrow-down:before {
-  content: ""; }
-
-.fa-long-arrow-up:before {
-  content: ""; }
-
-.fa-long-arrow-left:before {
-  content: ""; }
-
-.fa-long-arrow-right:before {
-  content: ""; }
-
-.fa-apple:before {
-  content: ""; }
-
-.fa-windows:before {
-  content: ""; }
-
-.fa-android:before {
-  content: ""; }
-
-.fa-linux:before {
-  content: ""; }
-
-.fa-dribbble:before {
-  content: ""; }
-
-.fa-skype:before {
-  content: ""; }
-
-.fa-foursquare:before {
-  content: ""; }
-
-.fa-trello:before {
-  content: ""; }
-
-.fa-female:before {
-  content: ""; }
-
-.fa-male:before {
-  content: ""; }
-
-.fa-gittip:before,
-.fa-gratipay:before {
-  content: ""; }
-
-.fa-sun-o:before {
-  content: ""; }
-
-.fa-moon-o:before {
-  content: ""; }
-
-.fa-archive:before {
-  content: ""; }
-
-.fa-bug:before {
-  content: ""; }
-
-.fa-vk:before {
-  content: ""; }
-
-.fa-weibo:before {
-  content: ""; }
-
-.fa-renren:before {
-  content: ""; }
-
-.fa-pagelines:before {
-  content: ""; }
-
-.fa-stack-exchange:before {
-  content: ""; }
-
-.fa-arrow-circle-o-right:before {
-  content: ""; }
-
-.fa-arrow-circle-o-left:before {
-  content: ""; }
-
-.fa-toggle-left:before,
-.fa-caret-square-o-left:before {
-  content: ""; }
-
-.fa-dot-circle-o:before {
-  content: ""; }
-
-.fa-wheelchair:before {
-  content: ""; }
-
-.fa-vimeo-square:before {
-  content: ""; }
-
-.fa-turkish-lira:before,
-.fa-try:before {
-  content: ""; }
-
-.fa-plus-square-o:before {
-  content: ""; }
-
-.fa-space-shuttle:before {
-  content: ""; }
-
-.fa-slack:before {
-  content: ""; }
-
-.fa-envelope-square:before {
-  content: ""; }
-
-.fa-wordpress:before {
-  content: ""; }
-
-.fa-openid:before {
-  content: ""; }
-
-.fa-institution:before,
-.fa-bank:before,
-.fa-university:before {
-  content: ""; }
-
-.fa-mortar-board:before,
-.fa-graduation-cap:before {
-  content: ""; }
-
-.fa-yahoo:before {
-  content: ""; }
-
-.fa-google:before {
-  content: ""; }
-
-.fa-reddit:before {
-  content: ""; }
-
-.fa-reddit-square:before {
-  content: ""; }
-
-.fa-stumbleupon-circle:before {
-  content: ""; }
-
-.fa-stumbleupon:before {
-  content: ""; }
-
-.fa-delicious:before {
-  content: ""; }
-
-.fa-digg:before {
-  content: ""; }
-
-.fa-pied-piper-pp:before {
-  content: ""; }
-
-.fa-pied-piper-alt:before {
-  content: ""; }
-
-.fa-drupal:before {
-  content: ""; }
-
-.fa-joomla:before {
-  content: ""; }
-
-.fa-language:before {
-  content: ""; }
-
-.fa-fax:before {
-  content: ""; }
-
-.fa-building:before {
-  content: ""; }
-
-.fa-child:before {
-  content: ""; }
-
-.fa-paw:before {
-  content: ""; }
-
-.fa-spoon:before {
-  content: ""; }
-
-.fa-cube:before {
-  content: ""; }
-
-.fa-cubes:before {
-  content: ""; }
-
-.fa-behance:before {
-  content: ""; }
-
-.fa-behance-square:before {
-  content: ""; }
-
-.fa-steam:before {
-  content: ""; }
-
-.fa-steam-square:before {
-  content: ""; }
-
-.fa-recycle:before {
-  content: ""; }
-
-.fa-automobile:before,
-.fa-car:before {
-  content: ""; }
-
-.fa-cab:before,
-.fa-taxi:before {
-  content: ""; }
-
-.fa-tree:before {
-  content: ""; }
-
-.fa-spotify:before {
-  content: ""; }
-
-.fa-deviantart:before {
-  content: ""; }
-
-.fa-soundcloud:before {
-  content: ""; }
-
-.fa-database:before {
-  content: ""; }
-
-.fa-file-pdf-o:before {
-  content: ""; }
-
-.fa-file-word-o:before {
-  content: ""; }
-
-.fa-file-excel-o:before {
-  content: ""; }
-
-.fa-file-powerpoint-o:before {
-  content: ""; }
-
-.fa-file-photo-o:before,
-.fa-file-picture-o:before,
-.fa-file-image-o:before {
-  content: ""; }
-
-.fa-file-zip-o:before,
-.fa-file-archive-o:before {
-  content: ""; }
-
-.fa-file-sound-o:before,
-.fa-file-audio-o:before {
-  content: ""; }
-
-.fa-file-movie-o:before,
-.fa-file-video-o:before {
-  content: ""; }
-
-.fa-file-code-o:before {
-  content: ""; }
-
-.fa-vine:before {
-  content: ""; }
-
-.fa-codepen:before {
-  content: ""; }
-
-.fa-jsfiddle:before {
-  content: ""; }
-
-.fa-life-bouy:before,
-.fa-life-buoy:before,
-.fa-life-saver:before,
-.fa-support:before,
-.fa-life-ring:before {
-  content: ""; }
-
-.fa-circle-o-notch:before {
-  content: ""; }
-
-.fa-ra:before,
-.fa-resistance:before,
-.fa-rebel:before {
-  content: ""; }
-
-.fa-ge:before,
-.fa-empire:before {
-  content: ""; }
-
-.fa-git-square:before {
-  content: ""; }
-
-.fa-git:before {
-  content: ""; }
-
-.fa-y-combinator-square:before,
-.fa-yc-square:before,
-.fa-hacker-news:before {
-  content: ""; }
-
-.fa-tencent-weibo:before {
-  content: ""; }
-
-.fa-qq:before {
-  content: ""; }
-
-.fa-wechat:before,
-.fa-weixin:before {
-  content: ""; }
-
-.fa-send:before,
-.fa-paper-plane:before {
-  content: ""; }
-
-.fa-send-o:before,
-.fa-paper-plane-o:before {
-  content: ""; }
-
-.fa-history:before {
-  content: ""; }
-
-.fa-circle-thin:before {
-  content: ""; }
-
-.fa-header:before {
-  content: ""; }
-
-.fa-paragraph:before {
-  content: ""; }
-
-.fa-sliders:before {
-  content: ""; }
-
-.fa-share-alt:before {
-  content: ""; }
-
-.fa-share-alt-square:before {
-  content: ""; }
-
-.fa-bomb:before {
-  content: ""; }
-
-.fa-soccer-ball-o:before,
-.fa-futbol-o:before {
-  content: ""; }
-
-.fa-tty:before {
-  content: ""; }
-
-.fa-binoculars:before {
-  content: ""; }
-
-.fa-plug:before {
-  content: ""; }
-
-.fa-slideshare:before {
-  content: ""; }
-
-.fa-twitch:before {
-  content: ""; }
-
-.fa-yelp:before {
-  content: ""; }
-
-.fa-newspaper-o:before {
-  content: ""; }
-
-.fa-wifi:before {
-  content: ""; }
-
-.fa-calculator:before {
-  content: ""; }
-
-.fa-paypal:before {
-  content: ""; }
-
-.fa-google-wallet:before {
-  content: ""; }
-
-.fa-cc-visa:before {
-  content: ""; }
-
-.fa-cc-mastercard:before {
-  content: ""; }
-
-.fa-cc-discover:before {
-  content: ""; }
-
-.fa-cc-amex:before {
-  content: ""; }
-
-.fa-cc-paypal:before {
-  content: ""; }
-
-.fa-cc-stripe:before {
-  content: ""; }
-
-.fa-bell-slash:before {
-  content: ""; }
-
-.fa-bell-slash-o:before {
-  content: ""; }
-
-.fa-trash:before {
-  content: ""; }
-
-.fa-copyright:before {
-  content: ""; }
-
-.fa-at:before {
-  content: ""; }
-
-.fa-eyedropper:before {
-  content: ""; }
-
-.fa-paint-brush:before {
-  content: ""; }
-
-.fa-birthday-cake:before {
-  content: ""; }
-
-.fa-area-chart:before {
-  content: ""; }
-
-.fa-pie-chart:before {
-  content: ""; }
-
-.fa-line-chart:before {
-  content: ""; }
-
-.fa-lastfm:before {
-  content: ""; }
-
-.fa-lastfm-square:before {
-  content: ""; }
-
-.fa-toggle-off:before {
-  content: ""; }
-
-.fa-toggle-on:before {
-  content: ""; }
-
-.fa-bicycle:before {
-  content: ""; }
-
-.fa-bus:before {
-  content: ""; }
-
-.fa-ioxhost:before {
-  content: ""; }
-
-.fa-angellist:before {
-  content: ""; }
-
-.fa-cc:before {
-  content: ""; }
-
-.fa-shekel:before,
-.fa-sheqel:before,
-.fa-ils:before {
-  content: ""; }
-
-.fa-meanpath:before {
-  content: ""; }
-
-.fa-buysellads:before {
-  content: ""; }
-
-.fa-connectdevelop:before {
-  content: ""; }
-
-.fa-dashcube:before {
-  content: ""; }
-
-.fa-forumbee:before {
-  content: ""; }
-
-.fa-leanpub:before {
-  content: ""; }
-
-.fa-sellsy:before {
-  content: ""; }
-
-.fa-shirtsinbulk:before {
-  content: ""; }
-
-.fa-simplybuilt:before {
-  content: ""; }
-
-.fa-skyatlas:before {
-  content: ""; }
-
-.fa-cart-plus:before {
-  content: ""; }
-
-.fa-cart-arrow-down:before {
-  content: ""; }
-
-.fa-diamond:before {
-  content: ""; }
-
-.fa-ship:before {
-  content: ""; }
-
-.fa-user-secret:before {
-  content: ""; }
-
-.fa-motorcycle:before {
-  content: ""; }
-
-.fa-street-view:before {
-  content: ""; }
-
-.fa-heartbeat:before {
-  content: ""; }
-
-.fa-venus:before {
-  content: ""; }
-
-.fa-mars:before {
-  content: ""; }
-
-.fa-mercury:before {
-  content: ""; }
-
-.fa-intersex:before,
-.fa-transgender:before {
-  content: ""; }
-
-.fa-transgender-alt:before {
-  content: ""; }
-
-.fa-venus-double:before {
-  content: ""; }
-
-.fa-mars-double:before {
-  content: ""; }
-
-.fa-venus-mars:before {
-  content: ""; }
-
-.fa-mars-stroke:before {
-  content: ""; }
-
-.fa-mars-stroke-v:before {
-  content: ""; }
-
-.fa-mars-stroke-h:before {
-  content: ""; }
-
-.fa-neuter:before {
-  content: ""; }
-
-.fa-genderless:before {
-  content: ""; }
-
-.fa-facebook-official:before {
-  content: ""; }
-
-.fa-pinterest-p:before {
-  content: ""; }
-
-.fa-whatsapp:before {
-  content: ""; }
-
-.fa-server:before {
-  content: ""; }
-
-.fa-user-plus:before {
-  content: ""; }
-
-.fa-user-times:before {
-  content: ""; }
-
-.fa-hotel:before,
-.fa-bed:before {
-  content: ""; }
-
-.fa-viacoin:before {
-  content: ""; }
-
-.fa-train:before {
-  content: ""; }
-
-.fa-subway:before {
-  content: ""; }
-
-.fa-medium:before {
-  content: ""; }
-
-.fa-yc:before,
-.fa-y-combinator:before {
-  content: ""; }
-
-.fa-optin-monster:before {
-  content: ""; }
-
-.fa-opencart:before {
-  content: ""; }
-
-.fa-expeditedssl:before {
-  content: ""; }
-
-.fa-battery-4:before,
-.fa-battery:before,
-.fa-battery-full:before {
-  content: ""; }
-
-.fa-battery-3:before,
-.fa-battery-three-quarters:before {
-  content: ""; }
-
-.fa-battery-2:before,
-.fa-battery-half:before {
-  content: ""; }
-
-.fa-battery-1:before,
-.fa-battery-quarter:before {
-  content: ""; }
-
-.fa-battery-0:before,
-.fa-battery-empty:before {
-  content: ""; }
-
-.fa-mouse-pointer:before {
-  content: ""; }
-
-.fa-i-cursor:before {
-  content: ""; }
-
-.fa-object-group:before {
-  content: ""; }
-
-.fa-object-ungroup:before {
-  content: ""; }
-
-.fa-sticky-note:before {
-  content: ""; }
-
-.fa-sticky-note-o:before {
-  content: ""; }
-
-.fa-cc-jcb:before {
-  content: ""; }
-
-.fa-cc-diners-club:before {
-  content: ""; }
-
-.fa-clone:before {
-  content: ""; }
-
-.fa-balance-scale:before {
-  content: ""; }
-
-.fa-hourglass-o:before {
-  content: ""; }
-
-.fa-hourglass-1:before,
-.fa-hourglass-start:before {
-  content: ""; }
-
-.fa-hourglass-2:before,
-.fa-hourglass-half:before {
-  content: ""; }
-
-.fa-hourglass-3:before,
-.fa-hourglass-end:before {
-  content: ""; }
-
-.fa-hourglass:before {
-  content: ""; }
-
-.fa-hand-grab-o:before,
-.fa-hand-rock-o:before {
-  content: ""; }
-
-.fa-hand-stop-o:before,
-.fa-hand-paper-o:before {
-  content: ""; }
-
-.fa-hand-scissors-o:before {
-  content: ""; }
-
-.fa-hand-lizard-o:before {
-  content: ""; }
-
-.fa-hand-spock-o:before {
-  content: ""; }
-
-.fa-hand-pointer-o:before {
-  content: ""; }
-
-.fa-hand-peace-o:before {
-  content: ""; }
-
-.fa-trademark:before {
-  content: ""; }
-
-.fa-registered:before {
-  content: ""; }
-
-.fa-creative-commons:before {
-  content: ""; }
-
-.fa-gg:before {
-  content: ""; }
-
-.fa-gg-circle:before {
-  content: ""; }
-
-.fa-tripadvisor:before {
-  content: ""; }
-
-.fa-odnoklassniki:before {
-  content: ""; }
-
-.fa-odnoklassniki-square:before {
-  content: ""; }
-
-.fa-get-pocket:before {
-  content: ""; }
-
-.fa-wikipedia-w:before {
-  content: ""; }
-
-.fa-safari:before {
-  content: ""; }
-
-.fa-chrome:before {
-  content: ""; }
-
-.fa-firefox:before {
-  content: ""; }
-
-.fa-opera:before {
-  content: ""; }
-
-.fa-internet-explorer:before {
-  content: ""; }
-
-.fa-tv:before,
-.fa-television:before {
-  content: ""; }
-
-.fa-contao:before {
-  content: ""; }
-
-.fa-500px:before {
-  content: ""; }
-
-.fa-amazon:before {
-  content: ""; }
-
-.fa-calendar-plus-o:before {
-  content: ""; }
-
-.fa-calendar-minus-o:before {
-  content: ""; }
-
-.fa-calendar-times-o:before {
-  content: ""; }
-
-.fa-calendar-check-o:before {
-  content: ""; }
-
-.fa-industry:before {
-  content: ""; }
-
-.fa-map-pin:before {
-  content: ""; }
-
-.fa-map-signs:before {
-  content: ""; }
-
-.fa-map-o:before {
-  content: ""; }
-
-.fa-map:before {
-  content: ""; }
-
-.fa-commenting:before {
-  content: ""; }
-
-.fa-commenting-o:before {
-  content: ""; }
-
-.fa-houzz:before {
-  content: ""; }
-
-.fa-vimeo:before {
-  content: ""; }
-
-.fa-black-tie:before {
-  content: ""; }
-
-.fa-fonticons:before {
-  content: ""; }
-
-.fa-reddit-alien:before {
-  content: ""; }
-
-.fa-edge:before {
-  content: ""; }
-
-.fa-credit-card-alt:before {
-  content: ""; }
-
-.fa-codiepie:before {
-  content: ""; }
-
-.fa-modx:before {
-  content: ""; }
-
-.fa-fort-awesome:before {
-  content: ""; }
-
-.fa-usb:before {
-  content: ""; }
-
-.fa-product-hunt:before {
-  content: ""; }
-
-.fa-mixcloud:before {
-  content: ""; }
-
-.fa-scribd:before {
-  content: ""; }
-
-.fa-pause-circle:before {
-  content: ""; }
-
-.fa-pause-circle-o:before {
-  content: ""; }
-
-.fa-stop-circle:before {
-  content: ""; }
-
-.fa-stop-circle-o:before {
-  content: ""; }
-
-.fa-shopping-bag:before {
-  content: ""; }
-
-.fa-shopping-basket:before {
-  content: ""; }
-
-.fa-hashtag:before {
-  content: ""; }
-
-.fa-bluetooth:before {
-  content: ""; }
-
-.fa-bluetooth-b:before {
-  content: ""; }
-
-.fa-percent:before {
-  content: ""; }
-
-.fa-gitlab:before {
-  content: ""; }
-
-.fa-wpbeginner:before {
-  content: ""; }
-
-.fa-wpforms:before {
-  content: ""; }
-
-.fa-envira:before {
-  content: ""; }
-
-.fa-universal-access:before {
-  content: ""; }
-
-.fa-wheelchair-alt:before {
-  content: ""; }
-
-.fa-question-circle-o:before {
-  content: ""; }
-
-.fa-blind:before {
-  content: ""; }
-
-.fa-audio-description:before {
-  content: ""; }
-
-.fa-volume-control-phone:before {
-  content: ""; }
-
-.fa-braille:before {
-  content: ""; }
-
-.fa-assistive-listening-systems:before {
-  content: ""; }
-
-.fa-asl-interpreting:before,
-.fa-american-sign-language-interpreting:before {
-  content: ""; }
-
-.fa-deafness:before,
-.fa-hard-of-hearing:before,
-.fa-deaf:before {
-  content: ""; }
-
-.fa-glide:before {
-  content: ""; }
-
-.fa-glide-g:before {
-  content: ""; }
-
-.fa-signing:before,
-.fa-sign-language:before {
-  content: ""; }
-
-.fa-low-vision:before {
-  content: ""; }
-
-.fa-viadeo:before {
-  content: ""; }
-
-.fa-viadeo-square:before {
-  content: ""; }
-
-.fa-snapchat:before {
-  content: ""; }
-
-.fa-snapchat-ghost:before {
-  content: ""; }
-
-.fa-snapchat-square:before {
-  content: ""; }
-
-.fa-pied-piper:before {
-  content: ""; }
-
-.fa-first-order:before {
-  content: ""; }
-
-.fa-yoast:before {
-  content: ""; }
-
-.fa-themeisle:before {
-  content: ""; }
-
-.fa-google-plus-circle:before,
-.fa-google-plus-official:before {
-  content: ""; }
-
-.fa-fa:before,
-.fa-font-awesome:before {
-  content: ""; }
-
-.fa-handshake-o:before {
-  content: ""; }
-
-.fa-envelope-open:before {
-  content: ""; }
-
-.fa-envelope-open-o:before {
-  content: ""; }
-
-.fa-linode:before {
-  content: ""; }
-
-.fa-address-book:before {
-  content: ""; }
-
-.fa-address-book-o:before {
-  content: ""; }
-
-.fa-vcard:before,
-.fa-address-card:before {
-  content: ""; }
-
-.fa-vcard-o:before,
-.fa-address-card-o:before {
-  content: ""; }
-
-.fa-user-circle:before {
-  content: ""; }
-
-.fa-user-circle-o:before {
-  content: ""; }
-
-.fa-user-o:before {
-  content: ""; }
-
-.fa-id-badge:before {
-  content: ""; }
-
-.fa-drivers-license:before,
-.fa-id-card:before {
-  content: ""; }
-
-.fa-drivers-license-o:before,
-.fa-id-card-o:before {
-  content: ""; }
-
-.fa-quora:before {
-  content: ""; }
-
-.fa-free-code-camp:before {
-  content: ""; }
-
-.fa-telegram:before {
-  content: ""; }
-
-.fa-thermometer-4:before,
-.fa-thermometer:before,
-.fa-thermometer-full:before {
-  content: ""; }
-
-.fa-thermometer-3:before,
-.fa-thermometer-three-quarters:before {
-  content: ""; }
-
-.fa-thermometer-2:before,
-.fa-thermometer-half:before {
-  content: ""; }
-
-.fa-thermometer-1:before,
-.fa-thermometer-quarter:before {
-  content: ""; }
-
-.fa-thermometer-0:before,
-.fa-thermometer-empty:before {
-  content: ""; }
-
-.fa-shower:before {
-  content: ""; }
-
-.fa-bathtub:before,
-.fa-s15:before,
-.fa-bath:before {
-  content: ""; }
-
-.fa-podcast:before {
-  content: ""; }
-
-.fa-window-maximize:before {
-  content: ""; }
-
-.fa-window-minimize:before {
-  content: ""; }
-
-.fa-window-restore:before {
-  content: ""; }
-
-.fa-times-rectangle:before,
-.fa-window-close:before {
-  content: ""; }
-
-.fa-times-rectangle-o:before,
-.fa-window-close-o:before {
-  content: ""; }
-
-.fa-bandcamp:before {
-  content: ""; }
-
-.fa-grav:before {
-  content: ""; }
-
-.fa-etsy:before {
-  content: ""; }
-
-.fa-imdb:before {
-  content: ""; }
-
-.fa-ravelry:before {
-  content: ""; }
-
-.fa-eercast:before {
-  content: ""; }
-
-.fa-microchip:before {
-  content: ""; }
-
-.fa-snowflake-o:before {
-  content: ""; }
-
-.fa-superpowers:before {
-  content: ""; }
-
-.fa-wpexplorer:before {
-  content: ""; }
-
-.fa-meetup:before {
-  content: ""; }
-
-.sr-only {
-  position: absolute;
-  width: 1px;
-  height: 1px;
-  padding: 0;
-  margin: -1px;
-  overflow: hidden;
-  clip: rect(0, 0, 0, 0);
-  border: 0; }
-
-.sr-only-focusable:active, .sr-only-focusable:focus {
-  position: static;
-  width: auto;
-  height: auto;
-  margin: 0;
-  overflow: visible;
-  clip: auto; }
-
-/*
-    Color scheme helpers:
-    https://coolors.co/app/264653-2a9d8f-e9c46a-f4a261-e76f51
-    http://paletton.com/#uid=70a0u0kkNs+b4JOgryLpxqpsbkI
- */
-#conversejs :root {
-  --blue: #387592;
-  --indigo: #6610f2;
-  --purple: #6f42c1;
-  --pink: #e83e8c;
-  --red: #E77051;
-  --orange: #E7A151;
-  --yellow: #ffc107;
-  --green: #3AA569;
-  --teal: #20c997;
-  --cyan: #17a2b8;
-  --white: #fff;
-  --gray: #6c757d;
-  --gray-dark: #343a40;
-  --primary: #387592;
-  --secondary: #6c757d;
-  --success: #3AA569;
-  --info: #17a2b8;
-  --warning: #ffc107;
-  --danger: #E77051;
-  --light: #f8f9fa;
-  --dark: #343a40;
-  --breakpoint-xs: 0;
-  --breakpoint-sm: 576px;
-  --breakpoint-md: 768px;
-  --breakpoint-lg: 992px;
-  --breakpoint-xl: 1200px;
-  --font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
-  --font-family-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; }
-#conversejs *,
-#conversejs *::before,
-#conversejs *::after {
-  box-sizing: border-box; }
-#conversejs html {
-  font-family: sans-serif;
-  line-height: 1.15;
-  -webkit-text-size-adjust: 100%;
-  -ms-text-size-adjust: 100%;
-  -ms-overflow-style: scrollbar;
-  -webkit-tap-highlight-color: rgba(0, 0, 0, 0); }
-@-ms-viewport {
-  width: device-width; }
-#conversejs article, #conversejs aside, #conversejs dialog, #conversejs figcaption, #conversejs figure, #conversejs footer, #conversejs header, #conversejs hgroup, #conversejs main, #conversejs nav, #conversejs section {
-  display: block; }
-#conversejs body {
-  margin: 0;
-  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
-  font-size: 1rem;
-  font-weight: 400;
-  line-height: 1.5;
-  color: #212529;
-  text-align: left;
-  background-color: #fff; }
-#conversejs [tabindex="-1"]:focus {
-  outline: 0 !important; }
-#conversejs hr {
-  box-sizing: content-box;
-  height: 0;
-  overflow: visible; }
-#conversejs h1, #conversejs h2, #conversejs h3, #conversejs h4, #conversejs h5, #conversejs h6 {
-  margin-top: 0;
-  margin-bottom: 0.5rem; }
-#conversejs p {
-  margin-top: 0;
-  margin-bottom: 1rem; }
-#conversejs abbr[title],
-#conversejs abbr[data-original-title] {
-  text-decoration: underline;
-  text-decoration: underline dotted;
-  cursor: help;
-  border-bottom: 0; }
-#conversejs address {
-  margin-bottom: 1rem;
-  font-style: normal;
-  line-height: inherit; }
-#conversejs ol,
-#conversejs ul,
-#conversejs dl {
-  margin-top: 0;
-  margin-bottom: 1rem; }
-#conversejs ol ol,
-#conversejs ul ul,
-#conversejs ol ul,
-#conversejs ul ol {
-  margin-bottom: 0; }
-#conversejs dt {
-  font-weight: 700; }
-#conversejs dd {
-  margin-bottom: .5rem;
-  margin-left: 0; }
-#conversejs blockquote {
-  margin: 0 0 1rem; }
-#conversejs dfn {
-  font-style: italic; }
-#conversejs b,
-#conversejs strong {
-  font-weight: bolder; }
-#conversejs small {
-  font-size: 80%; }
-#conversejs sub,
-#conversejs sup {
-  position: relative;
-  font-size: 75%;
-  line-height: 0;
-  vertical-align: baseline; }
-#conversejs sub {
-  bottom: -.25em; }
-#conversejs sup {
-  top: -.5em; }
-#conversejs a {
-  color: #578EA9;
-  text-decoration: none;
-  background-color: transparent;
-  -webkit-text-decoration-skip: objects; }
-  #conversejs a:hover {
-    color: #3d6477;
-    text-decoration: underline; }
-#conversejs a:not([href]):not([tabindex]) {
-  color: inherit;
-  text-decoration: none; }
-  #conversejs a:not([href]):not([tabindex]):hover, #conversejs a:not([href]):not([tabindex]):focus {
-    color: inherit;
-    text-decoration: none; }
-  #conversejs a:not([href]):not([tabindex]):focus {
-    outline: 0; }
-#conversejs pre,
-#conversejs code,
-#conversejs kbd,
-#conversejs samp {
-  font-family: monospace, monospace;
-  font-size: 1em; }
-#conversejs pre {
-  margin-top: 0;
-  margin-bottom: 1rem;
-  overflow: auto;
-  -ms-overflow-style: scrollbar; }
-#conversejs figure {
-  margin: 0 0 1rem; }
-#conversejs img {
-  vertical-align: middle;
-  border-style: none; }
-#conversejs svg:not(:root) {
-  overflow: hidden; }
-#conversejs table {
-  border-collapse: collapse; }
-#conversejs caption {
-  padding-top: 0.75rem;
-  padding-bottom: 0.75rem;
-  color: #6c757d;
-  text-align: left;
-  caption-side: bottom; }
-#conversejs th {
-  text-align: inherit; }
-#conversejs label {
-  display: inline-block;
-  margin-bottom: .5rem; }
-#conversejs button {
-  border-radius: 0; }
-#conversejs button:focus {
-  outline: 1px dotted;
-  outline: 5px auto -webkit-focus-ring-color; }
-#conversejs input,
-#conversejs button,
-#conversejs select,
-#conversejs optgroup,
-#conversejs textarea {
-  margin: 0;
-  font-family: inherit;
-  font-size: inherit;
-  line-height: inherit; }
-#conversejs button,
-#conversejs input {
-  overflow: visible; }
-#conversejs button,
-#conversejs select {
-  text-transform: none; }
-#conversejs button,
-#conversejs html [type="button"],
-#conversejs [type="reset"],
-#conversejs [type="submit"] {
-  -webkit-appearance: button; }
-#conversejs button::-moz-focus-inner,
-#conversejs [type="button"]::-moz-focus-inner,
-#conversejs [type="reset"]::-moz-focus-inner,
-#conversejs [type="submit"]::-moz-focus-inner {
-  padding: 0;
-  border-style: none; }
-#conversejs input[type="radio"],
-#conversejs input[type="checkbox"] {
-  box-sizing: border-box;
-  padding: 0; }
-#conversejs input[type="date"],
-#conversejs input[type="time"],
-#conversejs input[type="datetime-local"],
-#conversejs input[type="month"] {
-  -webkit-appearance: listbox; }
-#conversejs textarea {
-  overflow: auto;
-  resize: vertical; }
-#conversejs fieldset {
-  min-width: 0;
-  padding: 0;
-  margin: 0;
-  border: 0; }
-#conversejs legend {
-  display: block;
-  width: 100%;
-  max-width: 100%;
-  padding: 0;
-  margin-bottom: .5rem;
-  font-size: 1.5rem;
-  line-height: inherit;
-  color: inherit;
-  white-space: normal; }
-#conversejs progress {
-  vertical-align: baseline; }
-#conversejs [type="number"]::-webkit-inner-spin-button,
-#conversejs [type="number"]::-webkit-outer-spin-button {
-  height: auto; }
-#conversejs [type="search"] {
-  outline-offset: -2px;
-  -webkit-appearance: none; }
-#conversejs [type="search"]::-webkit-search-cancel-button,
-#conversejs [type="search"]::-webkit-search-decoration {
-  -webkit-appearance: none; }
-#conversejs ::-webkit-file-upload-button {
-  font: inherit;
-  -webkit-appearance: button; }
-#conversejs output {
-  display: inline-block; }
-#conversejs summary {
-  display: list-item;
-  cursor: pointer; }
-#conversejs template {
-  display: none; }
-#conversejs [hidden] {
-  display: none !important; }
-#conversejs h1, #conversejs h2, #conversejs h3, #conversejs h4, #conversejs h5, #conversejs h6,
-#conversejs .h1, #conversejs .h2, #conversejs .h3, #conversejs .h4, #conversejs .h5, #conversejs .h6 {
-  margin-bottom: 0.5rem;
-  font-family: inherit;
-  font-weight: 500;
-  line-height: 1.2;
-  color: inherit; }
-#conversejs h1, #conversejs .h1 {
-  font-size: 2.5rem; }
-#conversejs h2, #conversejs .h2 {
-  font-size: 2rem; }
-#conversejs h3, #conversejs .h3 {
-  font-size: 1.75rem; }
-#conversejs h4, #conversejs .h4 {
-  font-size: 1.5rem; }
-#conversejs h5, #conversejs .h5 {
-  font-size: 1.25rem; }
-#conversejs h6, #conversejs .h6 {
-  font-size: 1rem; }
-#conversejs .lead {
-  font-size: 1.25rem;
-  font-weight: 300; }
-#conversejs .display-1 {
-  font-size: 6rem;
-  font-weight: 300;
-  line-height: 1.2; }
-#conversejs .display-2 {
-  font-size: 5.5rem;
-  font-weight: 300;
-  line-height: 1.2; }
-#conversejs .display-3 {
-  font-size: 4.5rem;
-  font-weight: 300;
-  line-height: 1.2; }
-#conversejs .display-4 {
-  font-size: 3.5rem;
-  font-weight: 300;
-  line-height: 1.2; }
-#conversejs hr {
-  margin-top: 1rem;
-  margin-bottom: 1rem;
-  border: 0;
-  border-top: 1px solid rgba(0, 0, 0, 0.1); }
-#conversejs small,
-#conversejs .small {
-  font-size: 80%;
-  font-weight: 400; }
-#conversejs mark,
-#conversejs .mark {
-  padding: 0.2em;
-  background-color: #fcf8e3; }
-#conversejs .list-unstyled {
-  padding-left: 0;
-  list-style: none; }
-#conversejs .list-inline {
-  padding-left: 0;
-  list-style: none; }
-#conversejs .list-inline-item {
-  display: inline-block; }
-  #conversejs .list-inline-item:not(:last-child) {
-    margin-right: 0.5rem; }
-#conversejs .initialism {
-  font-size: 90%;
-  text-transform: uppercase; }
-#conversejs .blockquote {
-  margin-bottom: 1rem;
-  font-size: 1.25rem; }
-#conversejs .blockquote-footer {
-  display: block;
-  font-size: 80%;
-  color: #6c757d; }
-  #conversejs .blockquote-footer::before {
-    content: "\2014 \00A0"; }
-#conversejs .img-fluid {
-  max-width: 100%;
-  height: auto; }
-#conversejs .img-thumbnail {
-  padding: 0.25rem;
-  background-color: #fff;
-  border: 1px solid #dee2e6;
-  border-radius: 0.25rem;
-  max-width: 100%;
-  height: auto; }
-#conversejs .figure {
-  display: inline-block; }
-#conversejs .figure-img {
-  margin-bottom: 0.5rem;
-  line-height: 1; }
-#conversejs .figure-caption {
-  font-size: 90%;
-  color: #6c757d; }
-#conversejs .container {
-  width: 100%;
-  padding-right: 15px;
-  padding-left: 15px;
-  margin-right: auto;
-  margin-left: auto; }
-  @media (min-width: 576px) {
-    #conversejs .container {
-      max-width: 540px; } }
-  @media (min-width: 768px) {
-    #conversejs .container {
-      max-width: 720px; } }
-  @media (min-width: 992px) {
-    #conversejs .container {
-      max-width: 960px; } }
-  @media (min-width: 1200px) {
-    #conversejs .container {
-      max-width: 1140px; } }
-#conversejs .container-fluid {
-  width: 100%;
-  padding-right: 15px;
-  padding-left: 15px;
-  margin-right: auto;
-  margin-left: auto; }
-#conversejs .row {
-  display: flex;
-  flex-wrap: wrap;
-  margin-right: -15px;
-  margin-left: -15px; }
-#conversejs .no-gutters {
-  margin-right: 0;
-  margin-left: 0; }
-  #conversejs .no-gutters > .col,
-  #conversejs .no-gutters > [class*="col-"] {
-    padding-right: 0;
-    padding-left: 0; }
-#conversejs .col-1, #conversejs .col-2, #conversejs .col-3, #conversejs .col-4, #conversejs .col-5, #conversejs .col-6, #conversejs .col-7, #conversejs .col-8, #conversejs .col-9, #conversejs .col-10, #conversejs .col-11, #conversejs .col-12, #conversejs .col,
-#conversejs .col-auto, #conversejs .col-sm-1, #conversejs .col-sm-2, #conversejs .col-sm-3, #conversejs .col-sm-4, #conversejs .col-sm-5, #conversejs .col-sm-6, #conversejs .col-sm-7, #conversejs .col-sm-8, #conversejs .col-sm-9, #conversejs .col-sm-10, #conversejs .col-sm-11, #conversejs .col-sm-12, #conversejs .col-sm,
-#conversejs .col-sm-auto, #conversejs .col-md-1, #conversejs .col-md-2, #conversejs .col-md-3, #conversejs .col-md-4, #conversejs .col-md-5, #conversejs .col-md-6, #conversejs .col-md-7, #conversejs .col-md-8, #conversejs .col-md-9, #conversejs .col-md-10, #conversejs .col-md-11, #conversejs .col-md-12, #conversejs .col-md,
-#conversejs .col-md-auto, #conversejs .col-lg-1, #conversejs .col-lg-2, #conversejs .col-lg-3, #conversejs .col-lg-4, #conversejs .col-lg-5, #conversejs .col-lg-6, #conversejs .col-lg-7, #conversejs .col-lg-8, #conversejs .col-lg-9, #conversejs .col-lg-10, #conversejs .col-lg-11, #conversejs .col-lg-12, #conversejs .col-lg,
-#conversejs .col-lg-auto, #conversejs .col-xl-1, #conversejs .col-xl-2, #conversejs .col-xl-3, #conversejs .col-xl-4, #conversejs .col-xl-5, #conversejs .col-xl-6, #conversejs .col-xl-7, #conversejs .col-xl-8, #conversejs .col-xl-9, #conversejs .col-xl-10, #conversejs .col-xl-11, #conversejs .col-xl-12, #conversejs .col-xl,
-#conversejs .col-xl-auto {
-  position: relative;
-  width: 100%;
-  min-height: 1px;
-  padding-right: 15px;
-  padding-left: 15px; }
-#conversejs .col {
-  flex-basis: 0;
-  flex-grow: 1;
-  max-width: 100%; }
-#conversejs .col-auto {
-  flex: 0 0 auto;
-  width: auto;
-  max-width: none; }
-#conversejs .col-1 {
-  flex: 0 0 8.3333333333%;
-  max-width: 8.3333333333%; }
-#conversejs .col-2 {
-  flex: 0 0 16.6666666667%;
-  max-width: 16.6666666667%; }
-#conversejs .col-3 {
-  flex: 0 0 25%;
-  max-width: 25%; }
-#conversejs .col-4 {
-  flex: 0 0 33.3333333333%;
-  max-width: 33.3333333333%; }
-#conversejs .col-5 {
-  flex: 0 0 41.6666666667%;
-  max-width: 41.6666666667%; }
-#conversejs .col-6 {
-  flex: 0 0 50%;
-  max-width: 50%; }
-#conversejs .col-7 {
-  flex: 0 0 58.3333333333%;
-  max-width: 58.3333333333%; }
-#conversejs .col-8 {
-  flex: 0 0 66.6666666667%;
-  max-width: 66.6666666667%; }
-#conversejs .col-9 {
-  flex: 0 0 75%;
-  max-width: 75%; }
-#conversejs .col-10 {
-  flex: 0 0 83.3333333333%;
-  max-width: 83.3333333333%; }
-#conversejs .col-11 {
-  flex: 0 0 91.6666666667%;
-  max-width: 91.6666666667%; }
-#conversejs .col-12 {
-  flex: 0 0 100%;
-  max-width: 100%; }
-#conversejs .order-first {
-  order: -1; }
-#conversejs .order-last {
-  order: 13; }
-#conversejs .order-0 {
-  order: 0; }
-#conversejs .order-1 {
-  order: 1; }
-#conversejs .order-2 {
-  order: 2; }
-#conversejs .order-3 {
-  order: 3; }
-#conversejs .order-4 {
-  order: 4; }
-#conversejs .order-5 {
-  order: 5; }
-#conversejs .order-6 {
-  order: 6; }
-#conversejs .order-7 {
-  order: 7; }
-#conversejs .order-8 {
-  order: 8; }
-#conversejs .order-9 {
-  order: 9; }
-#conversejs .order-10 {
-  order: 10; }
-#conversejs .order-11 {
-  order: 11; }
-#conversejs .order-12 {
-  order: 12; }
-#conversejs .offset-1 {
-  margin-left: 8.3333333333%; }
-#conversejs .offset-2 {
-  margin-left: 16.6666666667%; }
-#conversejs .offset-3 {
-  margin-left: 25%; }
-#conversejs .offset-4 {
-  margin-left: 33.3333333333%; }
-#conversejs .offset-5 {
-  margin-left: 41.6666666667%; }
-#conversejs .offset-6 {
-  margin-left: 50%; }
-#conversejs .offset-7 {
-  margin-left: 58.3333333333%; }
-#conversejs .offset-8 {
-  margin-left: 66.6666666667%; }
-#conversejs .offset-9 {
-  margin-left: 75%; }
-#conversejs .offset-10 {
-  margin-left: 83.3333333333%; }
-#conversejs .offset-11 {
-  margin-left: 91.6666666667%; }
-@media (min-width: 576px) {
-  #conversejs .col-sm {
-    flex-basis: 0;
-    flex-grow: 1;
-    max-width: 100%; }
-  #conversejs .col-sm-auto {
-    flex: 0 0 auto;
-    width: auto;
-    max-width: none; }
-  #conversejs .col-sm-1 {
-    flex: 0 0 8.3333333333%;
-    max-width: 8.3333333333%; }
-  #conversejs .col-sm-2 {
-    flex: 0 0 16.6666666667%;
-    max-width: 16.6666666667%; }
-  #conversejs .col-sm-3 {
-    flex: 0 0 25%;
-    max-width: 25%; }
-  #conversejs .col-sm-4 {
-    flex: 0 0 33.3333333333%;
-    max-width: 33.3333333333%; }
-  #conversejs .col-sm-5 {
-    flex: 0 0 41.6666666667%;
-    max-width: 41.6666666667%; }
-  #conversejs .col-sm-6 {
-    flex: 0 0 50%;
-    max-width: 50%; }
-  #conversejs .col-sm-7 {
-    flex: 0 0 58.3333333333%;
-    max-width: 58.3333333333%; }
-  #conversejs .col-sm-8 {
-    flex: 0 0 66.6666666667%;
-    max-width: 66.6666666667%; }
-  #conversejs .col-sm-9 {
-    flex: 0 0 75%;
-    max-width: 75%; }
-  #conversejs .col-sm-10 {
-    flex: 0 0 83.3333333333%;
-    max-width: 83.3333333333%; }
-  #conversejs .col-sm-11 {
-    flex: 0 0 91.6666666667%;
-    max-width: 91.6666666667%; }
-  #conversejs .col-sm-12 {
-    flex: 0 0 100%;
-    max-width: 100%; }
-  #conversejs .order-sm-first {
-    order: -1; }
-  #conversejs .order-sm-last {
-    order: 13; }
-  #conversejs .order-sm-0 {
-    order: 0; }
-  #conversejs .order-sm-1 {
-    order: 1; }
-  #conversejs .order-sm-2 {
-    order: 2; }
-  #conversejs .order-sm-3 {
-    order: 3; }
-  #conversejs .order-sm-4 {
-    order: 4; }
-  #conversejs .order-sm-5 {
-    order: 5; }
-  #conversejs .order-sm-6 {
-    order: 6; }
-  #conversejs .order-sm-7 {
-    order: 7; }
-  #conversejs .order-sm-8 {
-    order: 8; }
-  #conversejs .order-sm-9 {
-    order: 9; }
-  #conversejs .order-sm-10 {
-    order: 10; }
-  #conversejs .order-sm-11 {
-    order: 11; }
-  #conversejs .order-sm-12 {
-    order: 12; }
-  #conversejs .offset-sm-0 {
-    margin-left: 0; }
-  #conversejs .offset-sm-1 {
-    margin-left: 8.3333333333%; }
-  #conversejs .offset-sm-2 {
-    margin-left: 16.6666666667%; }
-  #conversejs .offset-sm-3 {
-    margin-left: 25%; }
-  #conversejs .offset-sm-4 {
-    margin-left: 33.3333333333%; }
-  #conversejs .offset-sm-5 {
-    margin-left: 41.6666666667%; }
-  #conversejs .offset-sm-6 {
-    margin-left: 50%; }
-  #conversejs .offset-sm-7 {
-    margin-left: 58.3333333333%; }
-  #conversejs .offset-sm-8 {
-    margin-left: 66.6666666667%; }
-  #conversejs .offset-sm-9 {
-    margin-left: 75%; }
-  #conversejs .offset-sm-10 {
-    margin-left: 83.3333333333%; }
-  #conversejs .offset-sm-11 {
-    margin-left: 91.6666666667%; } }
-@media (min-width: 768px) {
-  #conversejs .col-md {
-    flex-basis: 0;
-    flex-grow: 1;
-    max-width: 100%; }
-  #conversejs .col-md-auto {
-    flex: 0 0 auto;
-    width: auto;
-    max-width: none; }
-  #conversejs .col-md-1 {
-    flex: 0 0 8.3333333333%;
-    max-width: 8.3333333333%; }
-  #conversejs .col-md-2 {
-    flex: 0 0 16.6666666667%;
-    max-width: 16.6666666667%; }
-  #conversejs .col-md-3 {
-    flex: 0 0 25%;
-    max-width: 25%; }
-  #conversejs .col-md-4 {
-    flex: 0 0 33.3333333333%;
-    max-width: 33.3333333333%; }
-  #conversejs .col-md-5 {
-    flex: 0 0 41.6666666667%;
-    max-width: 41.6666666667%; }
-  #conversejs .col-md-6 {
-    flex: 0 0 50%;
-    max-width: 50%; }
-  #conversejs .col-md-7 {
-    flex: 0 0 58.3333333333%;
-    max-width: 58.3333333333%; }
-  #conversejs .col-md-8 {
-    flex: 0 0 66.6666666667%;
-    max-width: 66.6666666667%; }
-  #conversejs .col-md-9 {
-    flex: 0 0 75%;
-    max-width: 75%; }
-  #conversejs .col-md-10 {
-    flex: 0 0 83.3333333333%;
-    max-width: 83.3333333333%; }
-  #conversejs .col-md-11 {
-    flex: 0 0 91.6666666667%;
-    max-width: 91.6666666667%; }
-  #conversejs .col-md-12 {
-    flex: 0 0 100%;
-    max-width: 100%; }
-  #conversejs .order-md-first {
-    order: -1; }
-  #conversejs .order-md-last {
-    order: 13; }
-  #conversejs .order-md-0 {
-    order: 0; }
-  #conversejs .order-md-1 {
-    order: 1; }
-  #conversejs .order-md-2 {
-    order: 2; }
-  #conversejs .order-md-3 {
-    order: 3; }
-  #conversejs .order-md-4 {
-    order: 4; }
-  #conversejs .order-md-5 {
-    order: 5; }
-  #conversejs .order-md-6 {
-    order: 6; }
-  #conversejs .order-md-7 {
-    order: 7; }
-  #conversejs .order-md-8 {
-    order: 8; }
-  #conversejs .order-md-9 {
-    order: 9; }
-  #conversejs .order-md-10 {
-    order: 10; }
-  #conversejs .order-md-11 {
-    order: 11; }
-  #conversejs .order-md-12 {
-    order: 12; }
-  #conversejs .offset-md-0 {
-    margin-left: 0; }
-  #conversejs .offset-md-1 {
-    margin-left: 8.3333333333%; }
-  #conversejs .offset-md-2 {
-    margin-left: 16.6666666667%; }
-  #conversejs .offset-md-3 {
-    margin-left: 25%; }
-  #conversejs .offset-md-4 {
-    margin-left: 33.3333333333%; }
-  #conversejs .offset-md-5 {
-    margin-left: 41.6666666667%; }
-  #conversejs .offset-md-6 {
-    margin-left: 50%; }
-  #conversejs .offset-md-7 {
-    margin-left: 58.3333333333%; }
-  #conversejs .offset-md-8 {
-    margin-left: 66.6666666667%; }
-  #conversejs .offset-md-9 {
-    margin-left: 75%; }
-  #conversejs .offset-md-10 {
-    margin-left: 83.3333333333%; }
-  #conversejs .offset-md-11 {
-    margin-left: 91.6666666667%; } }
-@media (min-width: 992px) {
-  #conversejs .col-lg {
-    flex-basis: 0;
-    flex-grow: 1;
-    max-width: 100%; }
-  #conversejs .col-lg-auto {
-    flex: 0 0 auto;
-    width: auto;
-    max-width: none; }
-  #conversejs .col-lg-1 {
-    flex: 0 0 8.3333333333%;
-    max-width: 8.3333333333%; }
-  #conversejs .col-lg-2 {
-    flex: 0 0 16.6666666667%;
-    max-width: 16.6666666667%; }
-  #conversejs .col-lg-3 {
-    flex: 0 0 25%;
-    max-width: 25%; }
-  #conversejs .col-lg-4 {
-    flex: 0 0 33.3333333333%;
-    max-width: 33.3333333333%; }
-  #conversejs .col-lg-5 {
-    flex: 0 0 41.6666666667%;
-    max-width: 41.6666666667%; }
-  #conversejs .col-lg-6 {
-    flex: 0 0 50%;
-    max-width: 50%; }
-  #conversejs .col-lg-7 {
-    flex: 0 0 58.3333333333%;
-    max-width: 58.3333333333%; }
-  #conversejs .col-lg-8 {
-    flex: 0 0 66.6666666667%;
-    max-width: 66.6666666667%; }
-  #conversejs .col-lg-9 {
-    flex: 0 0 75%;
-    max-width: 75%; }
-  #conversejs .col-lg-10 {
-    flex: 0 0 83.3333333333%;
-    max-width: 83.3333333333%; }
-  #conversejs .col-lg-11 {
-    flex: 0 0 91.6666666667%;
-    max-width: 91.6666666667%; }
-  #conversejs .col-lg-12 {
-    flex: 0 0 100%;
-    max-width: 100%; }
-  #conversejs .order-lg-first {
-    order: -1; }
-  #conversejs .order-lg-last {
-    order: 13; }
-  #conversejs .order-lg-0 {
-    order: 0; }
-  #conversejs .order-lg-1 {
-    order: 1; }
-  #conversejs .order-lg-2 {
-    order: 2; }
-  #conversejs .order-lg-3 {
-    order: 3; }
-  #conversejs .order-lg-4 {
-    order: 4; }
-  #conversejs .order-lg-5 {
-    order: 5; }
-  #conversejs .order-lg-6 {
-    order: 6; }
-  #conversejs .order-lg-7 {
-    order: 7; }
-  #conversejs .order-lg-8 {
-    order: 8; }
-  #conversejs .order-lg-9 {
-    order: 9; }
-  #conversejs .order-lg-10 {
-    order: 10; }
-  #conversejs .order-lg-11 {
-    order: 11; }
-  #conversejs .order-lg-12 {
-    order: 12; }
-  #conversejs .offset-lg-0 {
-    margin-left: 0; }
-  #conversejs .offset-lg-1 {
-    margin-left: 8.3333333333%; }
-  #conversejs .offset-lg-2 {
-    margin-left: 16.6666666667%; }
-  #conversejs .offset-lg-3 {
-    margin-left: 25%; }
-  #conversejs .offset-lg-4 {
-    margin-left: 33.3333333333%; }
-  #conversejs .offset-lg-5 {
-    margin-left: 41.6666666667%; }
-  #conversejs .offset-lg-6 {
-    margin-left: 50%; }
-  #conversejs .offset-lg-7 {
-    margin-left: 58.3333333333%; }
-  #conversejs .offset-lg-8 {
-    margin-left: 66.6666666667%; }
-  #conversejs .offset-lg-9 {
-    margin-left: 75%; }
-  #conversejs .offset-lg-10 {
-    margin-left: 83.3333333333%; }
-  #conversejs .offset-lg-11 {
-    margin-left: 91.6666666667%; } }
-@media (min-width: 1200px) {
-  #conversejs .col-xl {
-    flex-basis: 0;
-    flex-grow: 1;
-    max-width: 100%; }
-  #conversejs .col-xl-auto {
-    flex: 0 0 auto;
-    width: auto;
-    max-width: none; }
-  #conversejs .col-xl-1 {
-    flex: 0 0 8.3333333333%;
-    max-width: 8.3333333333%; }
-  #conversejs .col-xl-2 {
-    flex: 0 0 16.6666666667%;
-    max-width: 16.6666666667%; }
-  #conversejs .col-xl-3 {
-    flex: 0 0 25%;
-    max-width: 25%; }
-  #conversejs .col-xl-4 {
-    flex: 0 0 33.3333333333%;
-    max-width: 33.3333333333%; }
-  #conversejs .col-xl-5 {
-    flex: 0 0 41.6666666667%;
-    max-width: 41.6666666667%; }
-  #conversejs .col-xl-6 {
-    flex: 0 0 50%;
-    max-width: 50%; }
-  #conversejs .col-xl-7 {
-    flex: 0 0 58.3333333333%;
-    max-width: 58.3333333333%; }
-  #conversejs .col-xl-8 {
-    flex: 0 0 66.6666666667%;
-    max-width: 66.6666666667%; }
-  #conversejs .col-xl-9 {
-    flex: 0 0 75%;
-    max-width: 75%; }
-  #conversejs .col-xl-10 {
-    flex: 0 0 83.3333333333%;
-    max-width: 83.3333333333%; }
-  #conversejs .col-xl-11 {
-    flex: 0 0 91.6666666667%;
-    max-width: 91.6666666667%; }
-  #conversejs .col-xl-12 {
-    flex: 0 0 100%;
-    max-width: 100%; }
-  #conversejs .order-xl-first {
-    order: -1; }
-  #conversejs .order-xl-last {
-    order: 13; }
-  #conversejs .order-xl-0 {
-    order: 0; }
-  #conversejs .order-xl-1 {
-    order: 1; }
-  #conversejs .order-xl-2 {
-    order: 2; }
-  #conversejs .order-xl-3 {
-    order: 3; }
-  #conversejs .order-xl-4 {
-    order: 4; }
-  #conversejs .order-xl-5 {
-    order: 5; }
-  #conversejs .order-xl-6 {
-    order: 6; }
-  #conversejs .order-xl-7 {
-    order: 7; }
-  #conversejs .order-xl-8 {
-    order: 8; }
-  #conversejs .order-xl-9 {
-    order: 9; }
-  #conversejs .order-xl-10 {
-    order: 10; }
-  #conversejs .order-xl-11 {
-    order: 11; }
-  #conversejs .order-xl-12 {
-    order: 12; }
-  #conversejs .offset-xl-0 {
-    margin-left: 0; }
-  #conversejs .offset-xl-1 {
-    margin-left: 8.3333333333%; }
-  #conversejs .offset-xl-2 {
-    margin-left: 16.6666666667%; }
-  #conversejs .offset-xl-3 {
-    margin-left: 25%; }
-  #conversejs .offset-xl-4 {
-    margin-left: 33.3333333333%; }
-  #conversejs .offset-xl-5 {
-    margin-left: 41.6666666667%; }
-  #conversejs .offset-xl-6 {
-    margin-left: 50%; }
-  #conversejs .offset-xl-7 {
-    margin-left: 58.3333333333%; }
-  #conversejs .offset-xl-8 {
-    margin-left: 66.6666666667%; }
-  #conversejs .offset-xl-9 {
-    margin-left: 75%; }
-  #conversejs .offset-xl-10 {
-    margin-left: 83.3333333333%; }
-  #conversejs .offset-xl-11 {
-    margin-left: 91.6666666667%; } }
-#conversejs .form-control {
-  display: block;
-  width: 100%;
-  padding: 0.375rem 0.75rem;
-  font-size: 1rem;
-  line-height: 1.5;
-  color: #495057;
-  background-color: #fff;
-  background-clip: padding-box;
-  border: 1px solid #ced4da;
-  border-radius: 0.25rem;
-  transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; }
-  #conversejs .form-control::-ms-expand {
-    background-color: transparent;
-    border: 0; }
-  #conversejs .form-control:focus {
-    color: #1A9707;
-    background-color: #fff;
-    border-color: #7db3cd;
-    outline: 0;
-    box-shadow: 0 0 0 0.2rem rgba(56, 117, 146, 0.25); }
-  #conversejs .form-control::placeholder {
-    color: #6c757d;
-    opacity: 1; }
-  #conversejs .form-control:disabled, #conversejs .form-control[readonly] {
-    background-color: #e9ecef;
-    opacity: 1; }
-#conversejs select.form-control:not([size]):not([multiple]) {
-  height: calc(2.25rem + 2px); }
-#conversejs select.form-control:focus::-ms-value {
-  color: #495057;
-  background-color: #fff; }
-#conversejs .form-control-file,
-#conversejs .form-control-range {
-  display: block;
-  width: 100%; }
-#conversejs .col-form-label {
-  padding-top: calc(0.375rem + 1px);
-  padding-bottom: calc(0.375rem + 1px);
-  margin-bottom: 0;
-  font-size: inherit;
-  line-height: 1.5; }
-#conversejs .col-form-label-lg {
-  padding-top: calc(0.5rem + 1px);
-  padding-bottom: calc(0.5rem + 1px);
-  font-size: 1.25rem;
-  line-height: 1.5; }
-#conversejs .col-form-label-sm {
-  padding-top: calc(0.25rem + 1px);
-  padding-bottom: calc(0.25rem + 1px);
-  font-size: 0.875rem;
-  line-height: 1.5; }
-#conversejs .form-control-plaintext {
-  display: block;
-  width: 100%;
-  padding-top: 0.375rem;
-  padding-bottom: 0.375rem;
-  margin-bottom: 0;
-  line-height: 1.5;
-  background-color: transparent;
-  border: solid transparent;
-  border-width: 1px 0; }
-  #conversejs .form-control-plaintext.form-control-sm, #conversejs .input-group-sm > .form-control-plaintext.form-control,
-  #conversejs .input-group-sm > .input-group-prepend > .form-control-plaintext.input-group-text,
-  #conversejs .input-group-sm > .input-group-append > .form-control-plaintext.input-group-text,
-  #conversejs .input-group-sm > .input-group-prepend > .form-control-plaintext.btn,
-  #conversejs .input-group-sm > .input-group-append > .form-control-plaintext.btn, #conversejs .form-control-plaintext.form-control-lg, #conversejs .input-group-lg > .form-control-plaintext.form-control,
-  #conversejs .input-group-lg > .input-group-prepend > .form-control-plaintext.input-group-text,
-  #conversejs .input-group-lg > .input-group-append > .form-control-plaintext.input-group-text,
-  #conversejs .input-group-lg > .input-group-prepend > .form-control-plaintext.btn,
-  #conversejs .input-group-lg > .input-group-append > .form-control-plaintext.btn {
-    padding-right: 0;
-    padding-left: 0; }
-#conversejs .form-control-sm, #conversejs .input-group-sm > .form-control,
-#conversejs .input-group-sm > .input-group-prepend > .input-group-text,
-#conversejs .input-group-sm > .input-group-append > .input-group-text,
-#conversejs .input-group-sm > .input-group-prepend > .btn,
-#conversejs .input-group-sm > .input-group-append > .btn {
-  padding: 0.25rem 0.5rem;
-  font-size: 0.875rem;
-  line-height: 1.5;
-  border-radius: 0.2rem; }
-#conversejs select.form-control-sm:not([size]):not([multiple]), #conversejs .input-group-sm > select.form-control:not([size]):not([multiple]),
-#conversejs .input-group-sm > .input-group-prepend > select.input-group-text:not([size]):not([multiple]),
-#conversejs .input-group-sm > .input-group-append > select.input-group-text:not([size]):not([multiple]),
-#conversejs .input-group-sm > .input-group-prepend > select.btn:not([size]):not([multiple]),
-#conversejs .input-group-sm > .input-group-append > select.btn:not([size]):not([multiple]) {
-  height: calc(1.8125rem + 2px); }
-#conversejs .form-control-lg, #conversejs .input-group-lg > .form-control,
-#conversejs .input-group-lg > .input-group-prepend > .input-group-text,
-#conversejs .input-group-lg > .input-group-append > .input-group-text,
-#conversejs .input-group-lg > .input-group-prepend > .btn,
-#conversejs .input-group-lg > .input-group-append > .btn {
-  padding: 0.5rem 1rem;
-  font-size: 1.25rem;
-  line-height: 1.5;
-  border-radius: 0.3rem; }
-#conversejs select.form-control-lg:not([size]):not([multiple]), #conversejs .input-group-lg > select.form-control:not([size]):not([multiple]),
-#conversejs .input-group-lg > .input-group-prepend > select.input-group-text:not([size]):not([multiple]),
-#conversejs .input-group-lg > .input-group-append > select.input-group-text:not([size]):not([multiple]),
-#conversejs .input-group-lg > .input-group-prepend > select.btn:not([size]):not([multiple]),
-#conversejs .input-group-lg > .input-group-append > select.btn:not([size]):not([multiple]) {
-  height: calc(2.875rem + 2px); }
-#conversejs .form-group {
-  margin-bottom: 1rem; }
-#conversejs .form-text {
-  display: block;
-  margin-top: 0.25rem; }
-#conversejs .form-row {
-  display: flex;
-  flex-wrap: wrap;
-  margin-right: -5px;
-  margin-left: -5px; }
-  #conversejs .form-row > .col,
-  #conversejs .form-row > [class*="col-"] {
-    padding-right: 5px;
-    padding-left: 5px; }
-#conversejs .form-check {
-  position: relative;
-  display: block;
-  padding-left: 1.25rem; }
-#conversejs .form-check-input {
-  position: absolute;
-  margin-top: 0.3rem;
-  margin-left: -1.25rem; }
-  #conversejs .form-check-input:disabled ~ .form-check-label {
-    color: #6c757d; }
-#conversejs .form-check-label {
-  margin-bottom: 0; }
-#conversejs .form-check-inline {
-  display: inline-flex;
-  align-items: center;
-  padding-left: 0;
-  margin-right: 0.75rem; }
-  #conversejs .form-check-inline .form-check-input {
-    position: static;
-    margin-top: 0;
-    margin-right: 0.3125rem;
-    margin-left: 0; }
-#conversejs .valid-feedback {
-  display: none;
-  width: 100%;
-  margin-top: 0.25rem;
-  font-size: 80%;
-  color: #3AA569; }
-#conversejs .valid-tooltip {
-  position: absolute;
-  top: 100%;
-  z-index: 5;
-  display: none;
-  max-width: 100%;
-  padding: .5rem;
-  margin-top: .1rem;
-  font-size: .875rem;
-  line-height: 1;
-  color: #fff;
-  background-color: rgba(58, 165, 105, 0.8);
-  border-radius: .2rem; }
-.was-validated #conversejs .form-control:valid, #conversejs .form-control.is-valid,
-.was-validated #conversejs .custom-select:valid,
-#conversejs .custom-select.is-valid {
-  border-color: #3AA569; }
-  .was-validated #conversejs .form-control:valid:focus, #conversejs .form-control.is-valid:focus,
-  .was-validated #conversejs .custom-select:valid:focus,
-  #conversejs .custom-select.is-valid:focus {
-    border-color: #3AA569;
-    box-shadow: 0 0 0 0.2rem rgba(58, 165, 105, 0.25); }
-  .was-validated #conversejs .form-control:valid ~ .valid-feedback,
-  .was-validated #conversejs .form-control:valid ~ .valid-tooltip, #conversejs .form-control.is-valid ~ .valid-feedback,
-  #conversejs .form-control.is-valid ~ .valid-tooltip,
-  .was-validated #conversejs .custom-select:valid ~ .valid-feedback,
-  .was-validated #conversejs .custom-select:valid ~ .valid-tooltip,
-  #conversejs .custom-select.is-valid ~ .valid-feedback,
-  #conversejs .custom-select.is-valid ~ .valid-tooltip {
-    display: block; }
-.was-validated #conversejs .form-check-input:valid ~ .form-check-label, #conversejs .form-check-input.is-valid ~ .form-check-label {
-  color: #3AA569; }
-.was-validated #conversejs .form-check-input:valid ~ .valid-feedback,
-.was-validated #conversejs .form-check-input:valid ~ .valid-tooltip, #conversejs .form-check-input.is-valid ~ .valid-feedback,
-#conversejs .form-check-input.is-valid ~ .valid-tooltip {
-  display: block; }
-.was-validated #conversejs .custom-control-input:valid ~ .custom-control-label, #conversejs .custom-control-input.is-valid ~ .custom-control-label {
-  color: #3AA569; }
-  .was-validated #conversejs .custom-control-input:valid ~ .custom-control-label::before, #conversejs .custom-control-input.is-valid ~ .custom-control-label::before {
-    background-color: #89d6ab; }
-.was-validated #conversejs .custom-control-input:valid ~ .valid-feedback,
-.was-validated #conversejs .custom-control-input:valid ~ .valid-tooltip, #conversejs .custom-control-input.is-valid ~ .valid-feedback,
-#conversejs .custom-control-input.is-valid ~ .valid-tooltip {
-  display: block; }
-.was-validated #conversejs .custom-control-input:valid:checked ~ .custom-control-label::before, #conversejs .custom-control-input.is-valid:checked ~ .custom-control-label::before {
-  background-color: #50c282; }
-.was-validated #conversejs .custom-control-input:valid:focus ~ .custom-control-label::before, #conversejs .custom-control-input.is-valid:focus ~ .custom-control-label::before {
-  box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(58, 165, 105, 0.25); }
-.was-validated #conversejs .custom-file-input:valid ~ .custom-file-label, #conversejs .custom-file-input.is-valid ~ .custom-file-label {
-  border-color: #3AA569; }
-  .was-validated #conversejs .custom-file-input:valid ~ .custom-file-label::before, #conversejs .custom-file-input.is-valid ~ .custom-file-label::before {
-    border-color: inherit; }
-.was-validated #conversejs .custom-file-input:valid ~ .valid-feedback,
-.was-validated #conversejs .custom-file-input:valid ~ .valid-tooltip, #conversejs .custom-file-input.is-valid ~ .valid-feedback,
-#conversejs .custom-file-input.is-valid ~ .valid-tooltip {
-  display: block; }
-.was-validated #conversejs .custom-file-input:valid:focus ~ .custom-file-label, #conversejs .custom-file-input.is-valid:focus ~ .custom-file-label {
-  box-shadow: 0 0 0 0.2rem rgba(58, 165, 105, 0.25); }
-#conversejs .invalid-feedback {
-  display: none;
-  width: 100%;
-  margin-top: 0.25rem;
-  font-size: 80%;
-  color: #E77051; }
-#conversejs .invalid-tooltip {
-  position: absolute;
-  top: 100%;
-  z-index: 5;
-  display: none;
-  max-width: 100%;
-  padding: .5rem;
-  margin-top: .1rem;
-  font-size: .875rem;
-  line-height: 1;
-  color: #fff;
-  background-color: rgba(231, 112, 81, 0.8);
-  border-radius: .2rem; }
-.was-validated #conversejs .form-control:invalid, #conversejs .form-control.is-invalid,
-.was-validated #conversejs .custom-select:invalid,
-#conversejs .custom-select.is-invalid {
-  border-color: #E77051; }
-  .was-validated #conversejs .form-control:invalid:focus, #conversejs .form-control.is-invalid:focus,
-  .was-validated #conversejs .custom-select:invalid:focus,
-  #conversejs .custom-select.is-invalid:focus {
-    border-color: #E77051;
-    box-shadow: 0 0 0 0.2rem rgba(231, 112, 81, 0.25); }
-  .was-validated #conversejs .form-control:invalid ~ .invalid-feedback,
-  .was-validated #conversejs .form-control:invalid ~ .invalid-tooltip, #conversejs .form-control.is-invalid ~ .invalid-feedback,
-  #conversejs .form-control.is-invalid ~ .invalid-tooltip,
-  .was-validated #conversejs .custom-select:invalid ~ .invalid-feedback,
-  .was-validated #conversejs .custom-select:invalid ~ .invalid-tooltip,
-  #conversejs .custom-select.is-invalid ~ .invalid-feedback,
-  #conversejs .custom-select.is-invalid ~ .invalid-tooltip {
-    display: block; }
-.was-validated #conversejs .form-check-input:invalid ~ .form-check-label, #conversejs .form-check-input.is-invalid ~ .form-check-label {
-  color: #E77051; }
-.was-validated #conversejs .form-check-input:invalid ~ .invalid-feedback,
-.was-validated #conversejs .form-check-input:invalid ~ .invalid-tooltip, #conversejs .form-check-input.is-invalid ~ .invalid-feedback,
-#conversejs .form-check-input.is-invalid ~ .invalid-tooltip {
-  display: block; }
-.was-validated #conversejs .custom-control-input:invalid ~ .custom-control-label, #conversejs .custom-control-input.is-invalid ~ .custom-control-label {
-  color: #E77051; }
-  .was-validated #conversejs .custom-control-input:invalid ~ .custom-control-label::before, #conversejs .custom-control-input.is-invalid ~ .custom-control-label::before {
-    background-color: #f6ccc1; }
-.was-validated #conversejs .custom-control-input:invalid ~ .invalid-feedback,
-.was-validated #conversejs .custom-control-input:invalid ~ .invalid-tooltip, #conversejs .custom-control-input.is-invalid ~ .invalid-feedback,
-#conversejs .custom-control-input.is-invalid ~ .invalid-tooltip {
-  display: block; }
-.was-validated #conversejs .custom-control-input:invalid:checked ~ .custom-control-label::before, #conversejs .custom-control-input.is-invalid:checked ~ .custom-control-label::before {
-  background-color: #ed957e; }
-.was-validated #conversejs .custom-control-input:invalid:focus ~ .custom-control-label::before, #conversejs .custom-control-input.is-invalid:focus ~ .custom-control-label::before {
-  box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(231, 112, 81, 0.25); }
-.was-validated #conversejs .custom-file-input:invalid ~ .custom-file-label, #conversejs .custom-file-input.is-invalid ~ .custom-file-label {
-  border-color: #E77051; }
-  .was-validated #conversejs .custom-file-input:invalid ~ .custom-file-label::before, #conversejs .custom-file-input.is-invalid ~ .custom-file-label::before {
-    border-color: inherit; }
-.was-validated #conversejs .custom-file-input:invalid ~ .invalid-feedback,
-.was-validated #conversejs .custom-file-input:invalid ~ .invalid-tooltip, #conversejs .custom-file-input.is-invalid ~ .invalid-feedback,
-#conversejs .custom-file-input.is-invalid ~ .invalid-tooltip {
-  display: block; }
-.was-validated #conversejs .custom-file-input:invalid:focus ~ .custom-file-label, #conversejs .custom-file-input.is-invalid:focus ~ .custom-file-label {
-  box-shadow: 0 0 0 0.2rem rgba(231, 112, 81, 0.25); }
-#conversejs .form-inline {
-  display: flex;
-  flex-flow: row wrap;
-  align-items: center; }
-  #conversejs .form-inline .form-check {
-    width: 100%; }
-  @media (min-width: 576px) {
-    #conversejs .form-inline label {
-      display: flex;
-      align-items: center;
-      justify-content: center;
-      margin-bottom: 0; }
-    #conversejs .form-inline .form-group {
-      display: flex;
-      flex: 0 0 auto;
-      flex-flow: row wrap;
-      align-items: center;
-      margin-bottom: 0; }
-    #conversejs .form-inline .form-control {
-      display: inline-block;
-      width: auto;
-      vertical-align: middle; }
-    #conversejs .form-inline .form-control-plaintext {
-      display: inline-block; }
-    #conversejs .form-inline .input-group {
-      width: auto; }
-    #conversejs .form-inline .form-check {
-      display: flex;
-      align-items: center;
-      justify-content: center;
-      width: auto;
-      padding-left: 0; }
-    #conversejs .form-inline .form-check-input {
-      position: relative;
-      margin-top: 0;
-      margin-right: 0.25rem;
-      margin-left: 0; }
-    #conversejs .form-inline .custom-control {
-      align-items: center;
-      justify-content: center; }
-    #conversejs .form-inline .custom-control-label {
-      margin-bottom: 0; } }
-#conversejs .btn {
-  display: inline-block;
-  font-weight: 400;
-  text-align: center;
-  white-space: nowrap;
-  vertical-align: middle;
-  user-select: none;
-  border: 1px solid transparent;
-  padding: 0.375rem 0.75rem;
-  font-size: 1rem;
-  line-height: 1.5;
-  border-radius: 0.25rem;
-  transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out; }
-  #conversejs .btn:hover, #conversejs .btn:focus {
-    text-decoration: none; }
-  #conversejs .btn:focus, #conversejs .btn.focus {
-    outline: 0;
-    box-shadow: 0 0 0 0.2rem rgba(56, 117, 146, 0.25); }
-  #conversejs .btn.disabled, #conversejs .btn:disabled {
-    opacity: 0.65; }
-  #conversejs .btn:not(:disabled):not(.disabled) {
-    cursor: pointer; }
-  #conversejs .btn:not(:disabled):not(.disabled):active, #conversejs .btn:not(:disabled):not(.disabled).active {
-    background-image: none; }
-#conversejs a.btn.disabled,
-#conversejs fieldset:disabled a.btn {
-  pointer-events: none; }
-#conversejs .btn-primary {
-  color: #fff;
-  background-color: #387592;
-  border-color: #387592; }
-  #conversejs .btn-primary:hover {
-    color: #fff;
-    background-color: #2d5f76;
-    border-color: #2a576d; }
-  #conversejs .btn-primary:focus, #conversejs .btn-primary.focus {
-    box-shadow: 0 0 0 0.2rem rgba(56, 117, 146, 0.5); }
-  #conversejs .btn-primary.disabled, #conversejs .btn-primary:disabled {
-    color: #fff;
-    background-color: #387592;
-    border-color: #387592; }
-  #conversejs .btn-primary:not(:disabled):not(.disabled):active, #conversejs .btn-primary:not(:disabled):not(.disabled).active, .show > #conversejs .btn-primary.dropdown-toggle {
-    color: #fff;
-    background-color: #2a576d;
-    border-color: #265064; }
-    #conversejs .btn-primary:not(:disabled):not(.disabled):active:focus, #conversejs .btn-primary:not(:disabled):not(.disabled).active:focus, .show > #conversejs .btn-primary.dropdown-toggle:focus {
-      box-shadow: 0 0 0 0.2rem rgba(56, 117, 146, 0.5); }
-#conversejs .btn-secondary {
-  color: #fff;
-  background-color: #6c757d;
-  border-color: #6c757d; }
-  #conversejs .btn-secondary:hover {
-    color: #fff;
-    background-color: #5a6268;
-    border-color: #545b62; }
-  #conversejs .btn-secondary:focus, #conversejs .btn-secondary.focus {
-    box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); }
-  #conversejs .btn-secondary.disabled, #conversejs .btn-secondary:disabled {
-    color: #fff;
-    background-color: #6c757d;
-    border-color: #6c757d; }
-  #conversejs .btn-secondary:not(:disabled):not(.disabled):active, #conversejs .btn-secondary:not(:disabled):not(.disabled).active, .show > #conversejs .btn-secondary.dropdown-toggle {
-    color: #fff;
-    background-color: #545b62;
-    border-color: #4e555b; }
-    #conversejs .btn-secondary:not(:disabled):not(.disabled):active:focus, #conversejs .btn-secondary:not(:disabled):not(.disabled).active:focus, .show > #conversejs .btn-secondary.dropdown-toggle:focus {
-      box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); }
-#conversejs .btn-success {
-  color: #fff;
-  background-color: #3AA569;
-  border-color: #3AA569; }
-  #conversejs .btn-success:hover {
-    color: #fff;
-    background-color: #308957;
-    border-color: #2d7f51; }
-  #conversejs .btn-success:focus, #conversejs .btn-success.focus {
-    box-shadow: 0 0 0 0.2rem rgba(58, 165, 105, 0.5); }
-  #conversejs .btn-success.disabled, #conversejs .btn-success:disabled {
-    color: #fff;
-    background-color: #3AA569;
-    border-color: #3AA569; }
-  #conversejs .btn-success:not(:disabled):not(.disabled):active, #conversejs .btn-success:not(:disabled):not(.disabled).active, .show > #conversejs .btn-success.dropdown-toggle {
-    color: #fff;
-    background-color: #2d7f51;
-    border-color: #29764b; }
-    #conversejs .btn-success:not(:disabled):not(.disabled):active:focus, #conversejs .btn-success:not(:disabled):not(.disabled).active:focus, .show > #conversejs .btn-success.dropdown-toggle:focus {
-      box-shadow: 0 0 0 0.2rem rgba(58, 165, 105, 0.5); }
-#conversejs .btn-info {
-  color: #fff;
-  background-color: #17a2b8;
-  border-color: #17a2b8; }
-  #conversejs .btn-info:hover {
-    color: #fff;
-    background-color: #138496;
-    border-color: #117a8b; }
-  #conversejs .btn-info:focus, #conversejs .btn-info.focus {
-    box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); }
-  #conversejs .btn-info.disabled, #conversejs .btn-info:disabled {
-    color: #fff;
-    background-color: #17a2b8;
-    border-color: #17a2b8; }
-  #conversejs .btn-info:not(:disabled):not(.disabled):active, #conversejs .btn-info:not(:disabled):not(.disabled).active, .show > #conversejs .btn-info.dropdown-toggle {
-    color: #fff;
-    background-color: #117a8b;
-    border-color: #10707f; }
-    #conversejs .btn-info:not(:disabled):not(.disabled):active:focus, #conversejs .btn-info:not(:disabled):not(.disabled).active:focus, .show > #conversejs .btn-info.dropdown-toggle:focus {
-      box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); }
-#conversejs .btn-warning {
-  color: #212529;
-  background-color: #ffc107;
-  border-color: #ffc107; }
-  #conversejs .btn-warning:hover {
-    color: #212529;
-    background-color: #e0a800;
-    border-color: #d39e00; }
-  #conversejs .btn-warning:focus, #conversejs .btn-warning.focus {
-    box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); }
-  #conversejs .btn-warning.disabled, #conversejs .btn-warning:disabled {
-    color: #212529;
-    background-color: #ffc107;
-    border-color: #ffc107; }
-  #conversejs .btn-warning:not(:disabled):not(.disabled):active, #conversejs .btn-warning:not(:disabled):not(.disabled).active, .show > #conversejs .btn-warning.dropdown-toggle {
-    color: #212529;
-    background-color: #d39e00;
-    border-color: #c69500; }
-    #conversejs .btn-warning:not(:disabled):not(.disabled):active:focus, #conversejs .btn-warning:not(:disabled):not(.disabled).active:focus, .show > #conversejs .btn-warning.dropdown-toggle:focus {
-      box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); }
-#conversejs .btn-danger {
-  color: #fff;
-  background-color: #E77051;
-  border-color: #E77051; }
-  #conversejs .btn-danger:hover {
-    color: #fff;
-    background-color: #e2542f;
-    border-color: #e14b24; }
-  #conversejs .btn-danger:focus, #conversejs .btn-danger.focus {
-    box-shadow: 0 0 0 0.2rem rgba(231, 112, 81, 0.5); }
-  #conversejs .btn-danger.disabled, #conversejs .btn-danger:disabled {
-    color: #fff;
-    background-color: #E77051;
-    border-color: #E77051; }
-  #conversejs .btn-danger:not(:disabled):not(.disabled):active, #conversejs .btn-danger:not(:disabled):not(.disabled).active, .show > #conversejs .btn-danger.dropdown-toggle {
-    color: #fff;
-    background-color: #e14b24;
-    border-color: #da451e; }
-    #conversejs .btn-danger:not(:disabled):not(.disabled):active:focus, #conversejs .btn-danger:not(:disabled):not(.disabled).active:focus, .show > #conversejs .btn-danger.dropdown-toggle:focus {
-      box-shadow: 0 0 0 0.2rem rgba(231, 112, 81, 0.5); }
-#conversejs .btn-light {
-  color: #212529;
-  background-color: #f8f9fa;
-  border-color: #f8f9fa; }
-  #conversejs .btn-light:hover {
-    color: #212529;
-    background-color: #e2e6ea;
-    border-color: #dae0e5; }
-  #conversejs .btn-light:focus, #conversejs .btn-light.focus {
-    box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); }
-  #conversejs .btn-light.disabled, #conversejs .btn-light:disabled {
-    color: #212529;
-    background-color: #f8f9fa;
-    border-color: #f8f9fa; }
-  #conversejs .btn-light:not(:disabled):not(.disabled):active, #conversejs .btn-light:not(:disabled):not(.disabled).active, .show > #conversejs .btn-light.dropdown-toggle {
-    color: #212529;
-    background-color: #dae0e5;
-    border-color: #d3d9df; }
-    #conversejs .btn-light:not(:disabled):not(.disabled):active:focus, #conversejs .btn-light:not(:disabled):not(.disabled).active:focus, .show > #conversejs .btn-light.dropdown-toggle:focus {
-      box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); }
-#conversejs .btn-dark {
-  color: #fff;
-  background-color: #343a40;
-  border-color: #343a40; }
-  #conversejs .btn-dark:hover {
-    color: #fff;
-    background-color: #23272b;
-    border-color: #1d2124; }
-  #conversejs .btn-dark:focus, #conversejs .btn-dark.focus {
-    box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); }
-  #conversejs .btn-dark.disabled, #conversejs .btn-dark:disabled {
-    color: #fff;
-    background-color: #343a40;
-    border-color: #343a40; }
-  #conversejs .btn-dark:not(:disabled):not(.disabled):active, #conversejs .btn-dark:not(:disabled):not(.disabled).active, .show > #conversejs .btn-dark.dropdown-toggle {
-    color: #fff;
-    background-color: #1d2124;
-    border-color: #171a1d; }
-    #conversejs .btn-dark:not(:disabled):not(.disabled):active:focus, #conversejs .btn-dark:not(:disabled):not(.disabled).active:focus, .show > #conversejs .btn-dark.dropdown-toggle:focus {
-      box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); }
-#conversejs .btn-outline-primary {
-  color: #387592;
-  background-color: transparent;
-  background-image: none;
-  border-color: #387592; }
-  #conversejs .btn-outline-primary:hover {
-    color: #fff;
-    background-color: #387592;
-    border-color: #387592; }
-  #conversejs .btn-outline-primary:focus, #conversejs .btn-outline-primary.focus {
-    box-shadow: 0 0 0 0.2rem rgba(56, 117, 146, 0.5); }
-  #conversejs .btn-outline-primary.disabled, #conversejs .btn-outline-primary:disabled {
-    color: #387592;
-    background-color: transparent; }
-  #conversejs .btn-outline-primary:not(:disabled):not(.disabled):active, #conversejs .btn-outline-primary:not(:disabled):not(.disabled).active, .show > #conversejs .btn-outline-primary.dropdown-toggle {
-    color: #fff;
-    background-color: #387592;
-    border-color: #387592; }
-    #conversejs .btn-outline-primary:not(:disabled):not(.disabled):active:focus, #conversejs .btn-outline-primary:not(:disabled):not(.disabled).active:focus, .show > #conversejs .btn-outline-primary.dropdown-toggle:focus {
-      box-shadow: 0 0 0 0.2rem rgba(56, 117, 146, 0.5); }
-#conversejs .btn-outline-secondary {
-  color: #6c757d;
-  background-color: transparent;
-  background-image: none;
-  border-color: #6c757d; }
-  #conversejs .btn-outline-secondary:hover {
-    color: #fff;
-    background-color: #6c757d;
-    border-color: #6c757d; }
-  #conversejs .btn-outline-secondary:focus, #conversejs .btn-outline-secondary.focus {
-    box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); }
-  #conversejs .btn-outline-secondary.disabled, #conversejs .btn-outline-secondary:disabled {
-    color: #6c757d;
-    background-color: transparent; }
-  #conversejs .btn-outline-secondary:not(:disabled):not(.disabled):active, #conversejs .btn-outline-secondary:not(:disabled):not(.disabled).active, .show > #conversejs .btn-outline-secondary.dropdown-toggle {
-    color: #fff;
-    background-color: #6c757d;
-    border-color: #6c757d; }
-    #conversejs .btn-outline-secondary:not(:disabled):not(.disabled):active:focus, #conversejs .btn-outline-secondary:not(:disabled):not(.disabled).active:focus, .show > #conversejs .btn-outline-secondary.dropdown-toggle:focus {
-      box-shadow: 0 0 0 0.2rem rgba(108, 117, 125, 0.5); }
-#conversejs .btn-outline-success {
-  color: #3AA569;
-  background-color: transparent;
-  background-image: none;
-  border-color: #3AA569; }
-  #conversejs .btn-outline-success:hover {
-    color: #fff;
-    background-color: #3AA569;
-    border-color: #3AA569; }
-  #conversejs .btn-outline-success:focus, #conversejs .btn-outline-success.focus {
-    box-shadow: 0 0 0 0.2rem rgba(58, 165, 105, 0.5); }
-  #conversejs .btn-outline-success.disabled, #conversejs .btn-outline-success:disabled {
-    color: #3AA569;
-    background-color: transparent; }
-  #conversejs .btn-outline-success:not(:disabled):not(.disabled):active, #conversejs .btn-outline-success:not(:disabled):not(.disabled).active, .show > #conversejs .btn-outline-success.dropdown-toggle {
-    color: #fff;
-    background-color: #3AA569;
-    border-color: #3AA569; }
-    #conversejs .btn-outline-success:not(:disabled):not(.disabled):active:focus, #conversejs .btn-outline-success:not(:disabled):not(.disabled).active:focus, .show > #conversejs .btn-outline-success.dropdown-toggle:focus {
-      box-shadow: 0 0 0 0.2rem rgba(58, 165, 105, 0.5); }
-#conversejs .btn-outline-info {
-  color: #17a2b8;
-  background-color: transparent;
-  background-image: none;
-  border-color: #17a2b8; }
-  #conversejs .btn-outline-info:hover {
-    color: #fff;
-    background-color: #17a2b8;
-    border-color: #17a2b8; }
-  #conversejs .btn-outline-info:focus, #conversejs .btn-outline-info.focus {
-    box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); }
-  #conversejs .btn-outline-info.disabled, #conversejs .btn-outline-info:disabled {
-    color: #17a2b8;
-    background-color: transparent; }
-  #conversejs .btn-outline-info:not(:disabled):not(.disabled):active, #conversejs .btn-outline-info:not(:disabled):not(.disabled).active, .show > #conversejs .btn-outline-info.dropdown-toggle {
-    color: #fff;
-    background-color: #17a2b8;
-    border-color: #17a2b8; }
-    #conversejs .btn-outline-info:not(:disabled):not(.disabled):active:focus, #conversejs .btn-outline-info:not(:disabled):not(.disabled).active:focus, .show > #conversejs .btn-outline-info.dropdown-toggle:focus {
-      box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5); }
-#conversejs .btn-outline-warning {
-  color: #ffc107;
-  background-color: transparent;
-  background-image: none;
-  border-color: #ffc107; }
-  #conversejs .btn-outline-warning:hover {
-    color: #212529;
-    background-color: #ffc107;
-    border-color: #ffc107; }
-  #conversejs .btn-outline-warning:focus, #conversejs .btn-outline-warning.focus {
-    box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); }
-  #conversejs .btn-outline-warning.disabled, #conversejs .btn-outline-warning:disabled {
-    color: #ffc107;
-    background-color: transparent; }
-  #conversejs .btn-outline-warning:not(:disabled):not(.disabled):active, #conversejs .btn-outline-warning:not(:disabled):not(.disabled).active, .show > #conversejs .btn-outline-warning.dropdown-toggle {
-    color: #212529;
-    background-color: #ffc107;
-    border-color: #ffc107; }
-    #conversejs .btn-outline-warning:not(:disabled):not(.disabled):active:focus, #conversejs .btn-outline-warning:not(:disabled):not(.disabled).active:focus, .show > #conversejs .btn-outline-warning.dropdown-toggle:focus {
-      box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5); }
-#conversejs .btn-outline-danger {
-  color: #E77051;
-  background-color: transparent;
-  background-image: none;
-  border-color: #E77051; }
-  #conversejs .btn-outline-danger:hover {
-    color: #fff;
-    background-color: #E77051;
-    border-color: #E77051; }
-  #conversejs .btn-outline-danger:focus, #conversejs .btn-outline-danger.focus {
-    box-shadow: 0 0 0 0.2rem rgba(231, 112, 81, 0.5); }
-  #conversejs .btn-outline-danger.disabled, #conversejs .btn-outline-danger:disabled {
-    color: #E77051;
-    background-color: transparent; }
-  #conversejs .btn-outline-danger:not(:disabled):not(.disabled):active, #conversejs .btn-outline-danger:not(:disabled):not(.disabled).active, .show > #conversejs .btn-outline-danger.dropdown-toggle {
-    color: #fff;
-    background-color: #E77051;
-    border-color: #E77051; }
-    #conversejs .btn-outline-danger:not(:disabled):not(.disabled):active:focus, #conversejs .btn-outline-danger:not(:disabled):not(.disabled).active:focus, .show > #conversejs .btn-outline-danger.dropdown-toggle:focus {
-      box-shadow: 0 0 0 0.2rem rgba(231, 112, 81, 0.5); }
-#conversejs .btn-outline-light {
-  color: #f8f9fa;
-  background-color: transparent;
-  background-image: none;
-  border-color: #f8f9fa; }
-  #conversejs .btn-outline-light:hover {
-    color: #212529;
-    background-color: #f8f9fa;
-    border-color: #f8f9fa; }
-  #conversejs .btn-outline-light:focus, #conversejs .btn-outline-light.focus {
-    box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); }
-  #conversejs .btn-outline-light.disabled, #conversejs .btn-outline-light:disabled {
-    color: #f8f9fa;
-    background-color: transparent; }
-  #conversejs .btn-outline-light:not(:disabled):not(.disabled):active, #conversejs .btn-outline-light:not(:disabled):not(.disabled).active, .show > #conversejs .btn-outline-light.dropdown-toggle {
-    color: #212529;
-    background-color: #f8f9fa;
-    border-color: #f8f9fa; }
-    #conversejs .btn-outline-light:not(:disabled):not(.disabled):active:focus, #conversejs .btn-outline-light:not(:disabled):not(.disabled).active:focus, .show > #conversejs .btn-outline-light.dropdown-toggle:focus {
-      box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5); }
-#conversejs .btn-outline-dark {
-  color: #343a40;
-  background-color: transparent;
-  background-image: none;
-  border-color: #343a40; }
-  #conversejs .btn-outline-dark:hover {
-    color: #fff;
-    background-color: #343a40;
-    border-color: #343a40; }
-  #conversejs .btn-outline-dark:focus, #conversejs .btn-outline-dark.focus {
-    box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); }
-  #conversejs .btn-outline-dark.disabled, #conversejs .btn-outline-dark:disabled {
-    color: #343a40;
-    background-color: transparent; }
-  #conversejs .btn-outline-dark:not(:disabled):not(.disabled):active, #conversejs .btn-outline-dark:not(:disabled):not(.disabled).active, .show > #conversejs .btn-outline-dark.dropdown-toggle {
-    color: #fff;
-    background-color: #343a40;
-    border-color: #343a40; }
-    #conversejs .btn-outline-dark:not(:disabled):not(.disabled):active:focus, #conversejs .btn-outline-dark:not(:disabled):not(.disabled).active:focus, .show > #conversejs .btn-outline-dark.dropdown-toggle:focus {
-      box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5); }
-#conversejs .btn-link {
-  font-weight: 400;
-  color: #578EA9;
-  background-color: transparent; }
-  #conversejs .btn-link:hover {
-    color: #3d6477;
-    text-decoration: underline;
-    background-color: transparent;
-    border-color: transparent; }
-  #conversejs .btn-link:focus, #conversejs .btn-link.focus {
-    text-decoration: underline;
-    border-color: transparent;
-    box-shadow: none; }
-  #conversejs .btn-link:disabled, #conversejs .btn-link.disabled {
-    color: #6c757d; }
-#conversejs .btn-lg, #conversejs .btn-group-lg > .btn {
-  padding: 0.5rem 1rem;
-  font-size: 1.25rem;
-  line-height: 1.5;
-  border-radius: 0.3rem; }
-#conversejs .btn-sm, #conversejs .btn-group-sm > .btn {
-  padding: 0.25rem 0.5rem;
-  font-size: 0.875rem;
-  line-height: 1.5;
-  border-radius: 0.2rem; }
-#conversejs .btn-block {
-  display: block;
-  width: 100%; }
-  #conversejs .btn-block + .btn-block {
-    margin-top: 0.5rem; }
-#conversejs input[type="submit"].btn-block,
-#conversejs input[type="reset"].btn-block,
-#conversejs input[type="button"].btn-block {
-  width: 100%; }
-#conversejs .fade {
-  opacity: 0;
-  transition: opacity 0.15s linear; }
-  #conversejs .fade.show {
-    opacity: 1; }
-#conversejs .collapse {
-  display: none; }
-  #conversejs .collapse.show {
-    display: block; }
-#conversejs tr.collapse.show {
-  display: table-row; }
-#conversejs tbody.collapse.show {
-  display: table-row-group; }
-#conversejs .collapsing {
-  position: relative;
-  height: 0;
-  overflow: hidden;
-  transition: height 0.35s ease; }
-#conversejs .dropup,
-#conversejs .dropdown {
-  position: relative; }
-#conversejs .dropdown-toggle::after {
-  display: inline-block;
-  width: 0;
-  height: 0;
-  margin-left: 0.255em;
-  vertical-align: 0.255em;
-  content: "";
-  border-top: 0.3em solid;
-  border-right: 0.3em solid transparent;
-  border-bottom: 0;
-  border-left: 0.3em solid transparent; }
-#conversejs .dropdown-toggle:empty::after {
-  margin-left: 0; }
-#conversejs .dropdown-menu {
-  position: absolute;
-  top: 100%;
-  left: 0;
-  z-index: 1000;
-  display: none;
-  float: left;
-  min-width: 10rem;
-  padding: 0.5rem 0;
-  margin: 0.125rem 0 0;
-  font-size: 1rem;
-  color: #212529;
-  text-align: left;
-  list-style: none;
-  background-color: #fff;
-  background-clip: padding-box;
-  border: 1px solid rgba(0, 0, 0, 0.15);
-  border-radius: 0.25rem; }
-#conversejs .dropup .dropdown-menu {
-  margin-top: 0;
-  margin-bottom: 0.125rem; }
-#conversejs .dropup .dropdown-toggle::after {
-  display: inline-block;
-  width: 0;
-  height: 0;
-  margin-left: 0.255em;
-  vertical-align: 0.255em;
-  content: "";
-  border-top: 0;
-  border-right: 0.3em solid transparent;
-  border-bottom: 0.3em solid;
-  border-left: 0.3em solid transparent; }
-#conversejs .dropup .dropdown-toggle:empty::after {
-  margin-left: 0; }
-#conversejs .dropright .dropdown-menu {
-  margin-top: 0;
-  margin-left: 0.125rem; }
-#conversejs .dropright .dropdown-toggle::after {
-  display: inline-block;
-  width: 0;
-  height: 0;
-  margin-left: 0.255em;
-  vertical-align: 0.255em;
-  content: "";
-  border-top: 0.3em solid transparent;
-  border-bottom: 0.3em solid transparent;
-  border-left: 0.3em solid; }
-#conversejs .dropright .dropdown-toggle:empty::after {
-  margin-left: 0; }
-#conversejs .dropright .dropdown-toggle::after {
-  vertical-align: 0; }
-#conversejs .dropleft .dropdown-menu {
-  margin-top: 0;
-  margin-right: 0.125rem; }
-#conversejs .dropleft .dropdown-toggle::after {
-  display: inline-block;
-  width: 0;
-  height: 0;
-  margin-left: 0.255em;
-  vertical-align: 0.255em;
-  content: ""; }
-#conversejs .dropleft .dropdown-toggle::after {
-  display: none; }
-#conversejs .dropleft .dropdown-toggle::before {
-  display: inline-block;
-  width: 0;
-  height: 0;
-  margin-right: 0.255em;
-  vertical-align: 0.255em;
-  content: "";
-  border-top: 0.3em solid transparent;
-  border-right: 0.3em solid;
-  border-bottom: 0.3em solid transparent; }
-#conversejs .dropleft .dropdown-toggle:empty::after {
-  margin-left: 0; }
-#conversejs .dropleft .dropdown-toggle::before {
-  vertical-align: 0; }
-#conversejs .dropdown-divider {
-  height: 0;
-  margin: 0.5rem 0;
-  overflow: hidden;
-  border-top: 1px solid #e9ecef; }
-#conversejs .dropdown-item {
-  display: block;
-  width: 100%;
-  padding: 0.25rem 1.5rem;
-  clear: both;
-  font-weight: 400;
-  color: #212529;
-  text-align: inherit;
-  white-space: nowrap;
-  background-color: transparent;
-  border: 0; }
-  #conversejs .dropdown-item:hover, #conversejs .dropdown-item:focus {
-    color: #16181b;
-    text-decoration: none;
-    background-color: #f8f9fa; }
-  #conversejs .dropdown-item.active, #conversejs .dropdown-item:active {
-    color: #fff;
-    text-decoration: none;
-    background-color: #387592; }
-  #conversejs .dropdown-item.disabled, #conversejs .dropdown-item:disabled {
-    color: #6c757d;
-    background-color: transparent; }
-#conversejs .dropdown-menu.show {
-  display: block; }
-#conversejs .dropdown-header {
-  display: block;
-  padding: 0.5rem 1.5rem;
-  margin-bottom: 0;
-  font-size: 0.875rem;
-  color: #6c757d;
-  white-space: nowrap; }
-#conversejs .btn-group,
-#conversejs .btn-group-vertical {
-  position: relative;
-  display: inline-flex;
-  vertical-align: middle; }
-  #conversejs .btn-group > .btn,
-  #conversejs .btn-group-vertical > .btn {
-    position: relative;
-    flex: 0 1 auto; }
-    #conversejs .btn-group > .btn:hover,
-    #conversejs .btn-group-vertical > .btn:hover {
-      z-index: 1; }
-    #conversejs .btn-group > .btn:focus, #conversejs .btn-group > .btn:active, #conversejs .btn-group > .btn.active,
-    #conversejs .btn-group-vertical > .btn:focus,
-    #conversejs .btn-group-vertical > .btn:active,
-    #conversejs .btn-group-vertical > .btn.active {
-      z-index: 1; }
-  #conversejs .btn-group .btn + .btn,
-  #conversejs .btn-group .btn + .btn-group,
-  #conversejs .btn-group .btn-group + .btn,
-  #conversejs .btn-group .btn-group + .btn-group,
-  #conversejs .btn-group-vertical .btn + .btn,
-  #conversejs .btn-group-vertical .btn + .btn-group,
-  #conversejs .btn-group-vertical .btn-group + .btn,
-  #conversejs .btn-group-vertical .btn-group + .btn-group {
-    margin-left: -1px; }
-#conversejs .btn-toolbar {
-  display: flex;
-  flex-wrap: wrap;
-  justify-content: flex-start; }
-  #conversejs .btn-toolbar .input-group {
-    width: auto; }
-#conversejs .btn-group > .btn:first-child {
-  margin-left: 0; }
-#conversejs .btn-group > .btn:not(:last-child):not(.dropdown-toggle),
-#conversejs .btn-group > .btn-group:not(:last-child) > .btn {
-  border-top-right-radius: 0;
-  border-bottom-right-radius: 0; }
-#conversejs .btn-group > .btn:not(:first-child),
-#conversejs .btn-group > .btn-group:not(:first-child) > .btn {
-  border-top-left-radius: 0;
-  border-bottom-left-radius: 0; }
-#conversejs .dropdown-toggle-split {
-  padding-right: 0.5625rem;
-  padding-left: 0.5625rem; }
-  #conversejs .dropdown-toggle-split::after {
-    margin-left: 0; }
-#conversejs .btn-sm + .dropdown-toggle-split, #conversejs .btn-group-sm > .btn + .dropdown-toggle-split {
-  padding-right: 0.375rem;
-  padding-left: 0.375rem; }
-#conversejs .btn-lg + .dropdown-toggle-split, #conversejs .btn-group-lg > .btn + .dropdown-toggle-split {
-  padding-right: 0.75rem;
-  padding-left: 0.75rem; }
-#conversejs .btn-group-vertical {
-  flex-direction: column;
-  align-items: flex-start;
-  justify-content: center; }
-  #conversejs .btn-group-vertical .btn,
-  #conversejs .btn-group-vertical .btn-group {
-    width: 100%; }
-  #conversejs .btn-group-vertical > .btn + .btn,
-  #conversejs .btn-group-vertical > .btn + .btn-group,
-  #conversejs .btn-group-vertical > .btn-group + .btn,
-  #conversejs .btn-group-vertical > .btn-group + .btn-group {
-    margin-top: -1px;
-    margin-left: 0; }
-  #conversejs .btn-group-vertical > .btn:not(:last-child):not(.dropdown-toggle),
-  #conversejs .btn-group-vertical > .btn-group:not(:last-child) > .btn {
-    border-bottom-right-radius: 0;
-    border-bottom-left-radius: 0; }
-  #conversejs .btn-group-vertical > .btn:not(:first-child),
-  #conversejs .btn-group-vertical > .btn-group:not(:first-child) > .btn {
-    border-top-left-radius: 0;
-    border-top-right-radius: 0; }
-#conversejs .btn-group-toggle > .btn,
-#conversejs .btn-group-toggle > .btn-group > .btn {
-  margin-bottom: 0; }
-  #conversejs .btn-group-toggle > .btn input[type="radio"],
-  #conversejs .btn-group-toggle > .btn input[type="checkbox"],
-  #conversejs .btn-group-toggle > .btn-group > .btn input[type="radio"],
-  #conversejs .btn-group-toggle > .btn-group > .btn input[type="checkbox"] {
-    position: absolute;
-    clip: rect(0, 0, 0, 0);
-    pointer-events: none; }
-#conversejs .input-group {
-  position: relative;
-  display: flex;
-  flex-wrap: wrap;
-  align-items: stretch;
-  width: 100%; }
-  #conversejs .input-group > .form-control,
-  #conversejs .input-group > .custom-select,
-  #conversejs .input-group > .custom-file {
-    position: relative;
-    flex: 1 1 auto;
-    width: 1%;
-    margin-bottom: 0; }
-    #conversejs .input-group > .form-control:focus,
-    #conversejs .input-group > .custom-select:focus,
-    #conversejs .input-group > .custom-file:focus {
-      z-index: 3; }
-    #conversejs .input-group > .form-control + .form-control,
-    #conversejs .input-group > .form-control + .custom-select,
-    #conversejs .input-group > .form-control + .custom-file,
-    #conversejs .input-group > .custom-select + .form-control,
-    #conversejs .input-group > .custom-select + .custom-select,
-    #conversejs .input-group > .custom-select + .custom-file,
-    #conversejs .input-group > .custom-file + .form-control,
-    #conversejs .input-group > .custom-file + .custom-select,
-    #conversejs .input-group > .custom-file + .custom-file {
-      margin-left: -1px; }
-  #conversejs .input-group > .form-control:not(:last-child),
-  #conversejs .input-group > .custom-select:not(:last-child) {
-    border-top-right-radius: 0;
-    border-bottom-right-radius: 0; }
-  #conversejs .input-group > .form-control:not(:first-child),
-  #conversejs .input-group > .custom-select:not(:first-child) {
-    border-top-left-radius: 0;
-    border-bottom-left-radius: 0; }
-  #conversejs .input-group > .custom-file {
-    display: flex;
-    align-items: center; }
-    #conversejs .input-group > .custom-file:not(:last-child) .custom-file-label, #conversejs .input-group > .custom-file:not(:last-child) .custom-file-label::before {
-      border-top-right-radius: 0;
-      border-bottom-right-radius: 0; }
-    #conversejs .input-group > .custom-file:not(:first-child) .custom-file-label, #conversejs .input-group > .custom-file:not(:first-child) .custom-file-label::before {
-      border-top-left-radius: 0;
-      border-bottom-left-radius: 0; }
-#conversejs .input-group-prepend,
-#conversejs .input-group-append {
-  display: flex; }
-  #conversejs .input-group-prepend .btn,
-  #conversejs .input-group-append .btn {
-    position: relative;
-    z-index: 2; }
-  #conversejs .input-group-prepend .btn + .btn,
-  #conversejs .input-group-prepend .btn + .input-group-text,
-  #conversejs .input-group-prepend .input-group-text + .input-group-text,
-  #conversejs .input-group-prepend .input-group-text + .btn,
-  #conversejs .input-group-append .btn + .btn,
-  #conversejs .input-group-append .btn + .input-group-text,
-  #conversejs .input-group-append .input-group-text + .input-group-text,
-  #conversejs .input-group-append .input-group-text + .btn {
-    margin-left: -1px; }
-#conversejs .input-group-prepend {
-  margin-right: -1px; }
-#conversejs .input-group-append {
-  margin-left: -1px; }
-#conversejs .input-group-text {
-  display: flex;
-  align-items: center;
-  padding: 0.375rem 0.75rem;
-  margin-bottom: 0;
-  font-size: 1rem;
-  font-weight: 400;
-  line-height: 1.5;
-  color: #495057;
-  text-align: center;
-  white-space: nowrap;
-  background-color: #e9ecef;
-  border: 1px solid #ced4da;
-  border-radius: 0.25rem; }
-  #conversejs .input-group-text input[type="radio"],
-  #conversejs .input-group-text input[type="checkbox"] {
-    margin-top: 0; }
-#conversejs .input-group > .input-group-prepend > .btn,
-#conversejs .input-group > .input-group-prepend > .input-group-text,
-#conversejs .input-group > .input-group-append:not(:last-child) > .btn,
-#conversejs .input-group > .input-group-append:not(:last-child) > .input-group-text,
-#conversejs .input-group > .input-group-append:last-child > .btn:not(:last-child):not(.dropdown-toggle),
-#conversejs .input-group > .input-group-append:last-child > .input-group-text:not(:last-child) {
-  border-top-right-radius: 0;
-  border-bottom-right-radius: 0; }
-#conversejs .input-group > .input-group-append > .btn,
-#conversejs .input-group > .input-group-append > .input-group-text,
-#conversejs .input-group > .input-group-prepend:not(:first-child) > .btn,
-#conversejs .input-group > .input-group-prepend:not(:first-child) > .input-group-text,
-#conversejs .input-group > .input-group-prepend:first-child > .btn:not(:first-child),
-#conversejs .input-group > .input-group-prepend:first-child > .input-group-text:not(:first-child) {
-  border-top-left-radius: 0;
-  border-bottom-left-radius: 0; }
-#conversejs .custom-control {
-  position: relative;
-  display: block;
-  min-height: 1.5rem;
-  padding-left: 1.5rem; }
-#conversejs .custom-control-inline {
-  display: inline-flex;
-  margin-right: 1rem; }
-#conversejs .custom-control-input {
-  position: absolute;
-  z-index: -1;
-  opacity: 0; }
-  #conversejs .custom-control-input:checked ~ .custom-control-label::before {
-    color: #fff;
-    background-color: #387592; }
-  #conversejs .custom-control-input:focus ~ .custom-control-label::before {
-    box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(56, 117, 146, 0.25); }
-  #conversejs .custom-control-input:active ~ .custom-control-label::before {
-    color: #fff;
-    background-color: #a1c9db; }
-  #conversejs .custom-control-input:disabled ~ .custom-control-label {
-    color: #6c757d; }
-    #conversejs .custom-control-input:disabled ~ .custom-control-label::before {
-      background-color: #e9ecef; }
-#conversejs .custom-control-label {
-  margin-bottom: 0; }
-  #conversejs .custom-control-label::before {
-    position: absolute;
-    top: 0.25rem;
-    left: 0;
-    display: block;
-    width: 1rem;
-    height: 1rem;
-    pointer-events: none;
-    content: "";
-    user-select: none;
-    background-color: #dee2e6; }
-  #conversejs .custom-control-label::after {
-    position: absolute;
-    top: 0.25rem;
-    left: 0;
-    display: block;
-    width: 1rem;
-    height: 1rem;
-    content: "";
-    background-repeat: no-repeat;
-    background-position: center center;
-    background-size: 50% 50%; }
-#conversejs .custom-checkbox .custom-control-label::before {
-  border-radius: 0.25rem; }
-#conversejs .custom-checkbox .custom-control-input:checked ~ .custom-control-label::before {
-  background-color: #387592; }
-#conversejs .custom-checkbox .custom-control-input:checked ~ .custom-control-label::after {
-  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E"); }
-#conversejs .custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::before {
-  background-color: #387592; }
-#conversejs .custom-checkbox .custom-control-input:indeterminate ~ .custom-control-label::after {
-  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E"); }
-#conversejs .custom-checkbox .custom-control-input:disabled:checked ~ .custom-control-label::before {
-  background-color: rgba(56, 117, 146, 0.5); }
-#conversejs .custom-checkbox .custom-control-input:disabled:indeterminate ~ .custom-control-label::before {
-  background-color: rgba(56, 117, 146, 0.5); }
-#conversejs .custom-radio .custom-control-label::before {
-  border-radius: 50%; }
-#conversejs .custom-radio .custom-control-input:checked ~ .custom-control-label::before {
-  background-color: #387592; }
-#conversejs .custom-radio .custom-control-input:checked ~ .custom-control-label::after {
-  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E"); }
-#conversejs .custom-radio .custom-control-input:disabled:checked ~ .custom-control-label::before {
-  background-color: rgba(56, 117, 146, 0.5); }
-#conversejs .custom-select {
-  display: inline-block;
-  width: 100%;
-  height: calc(2.25rem + 2px);
-  padding: 0.375rem 1.75rem 0.375rem 0.75rem;
-  line-height: 1.5;
-  color: #495057;
-  vertical-align: middle;
-  background: #fff url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right 0.75rem center;
-  background-size: 8px 10px;
-  border: 1px solid #ced4da;
-  border-radius: 0.25rem;
-  appearance: none; }
-  #conversejs .custom-select:focus {
-    border-color: #7db3cd;
-    outline: 0;
-    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.075), 0 0 5px rgba(125, 179, 205, 0.5); }
-    #conversejs .custom-select:focus::-ms-value {
-      color: #495057;
-      background-color: #fff; }
-  #conversejs .custom-select[multiple], #conversejs .custom-select[size]:not([size="1"]) {
-    height: auto;
-    padding-right: 0.75rem;
-    background-image: none; }
-  #conversejs .custom-select:disabled {
-    color: #6c757d;
-    background-color: #e9ecef; }
-  #conversejs .custom-select::-ms-expand {
-    opacity: 0; }
-#conversejs .custom-select-sm {
-  height: calc(1.8125rem + 2px);
-  padding-top: 0.375rem;
-  padding-bottom: 0.375rem;
-  font-size: 75%; }
-#conversejs .custom-select-lg {
-  height: calc(2.875rem + 2px);
-  padding-top: 0.375rem;
-  padding-bottom: 0.375rem;
-  font-size: 125%; }
-#conversejs .custom-file {
-  position: relative;
-  display: inline-block;
-  width: 100%;
-  height: calc(2.25rem + 2px);
-  margin-bottom: 0; }
-#conversejs .custom-file-input {
-  position: relative;
-  z-index: 2;
-  width: 100%;
-  height: calc(2.25rem + 2px);
-  margin: 0;
-  opacity: 0; }
-  #conversejs .custom-file-input:focus ~ .custom-file-control {
-    border-color: #7db3cd;
-    box-shadow: 0 0 0 0.2rem rgba(56, 117, 146, 0.25); }
-    #conversejs .custom-file-input:focus ~ .custom-file-control::before {
-      border-color: #7db3cd; }
-  #conversejs .custom-file-input:lang(en) ~ .custom-file-label::after {
-    content: "Browse"; }
-#conversejs .custom-file-label {
-  position: absolute;
-  top: 0;
-  right: 0;
-  left: 0;
-  z-index: 1;
-  height: calc(2.25rem + 2px);
-  padding: 0.375rem 0.75rem;
-  line-height: 1.5;
-  color: #495057;
-  background-color: #fff;
-  border: 1px solid #ced4da;
-  border-radius: 0.25rem; }
-  #conversejs .custom-file-label::after {
-    position: absolute;
-    top: 0;
-    right: 0;
-    bottom: 0;
-    z-index: 3;
-    display: block;
-    height: calc(calc(2.25rem + 2px) - 1px * 2);
-    padding: 0.375rem 0.75rem;
-    line-height: 1.5;
-    color: #495057;
-    content: "Browse";
-    background-color: #e9ecef;
-    border-left: 1px solid #ced4da;
-    border-radius: 0 0.25rem 0.25rem 0; }
-#conversejs .card {
-  position: relative;
-  display: flex;
-  flex-direction: column;
-  min-width: 0;
-  word-wrap: break-word;
-  background-color: #fff;
-  background-clip: border-box;
-  border: 1px solid rgba(0, 0, 0, 0.125);
-  border-radius: 0.25rem; }
-  #conversejs .card > hr {
-    margin-right: 0;
-    margin-left: 0; }
-  #conversejs .card > .list-group:first-child .list-group-item:first-child {
-    border-top-left-radius: 0.25rem;
-    border-top-right-radius: 0.25rem; }
-  #conversejs .card > .list-group:last-child .list-group-item:last-child {
-    border-bottom-right-radius: 0.25rem;
-    border-bottom-left-radius: 0.25rem; }
-#conversejs .card-body {
-  flex: 1 1 auto;
-  padding: 1.25rem; }
-#conversejs .card-title {
-  margin-bottom: 0.75rem; }
-#conversejs .card-subtitle {
-  margin-top: -0.375rem;
-  margin-bottom: 0; }
-#conversejs .card-text:last-child {
-  margin-bottom: 0; }
-#conversejs .card-link:hover {
-  text-decoration: none; }
-#conversejs .card-link + .card-link {
-  margin-left: 1.25rem; }
-#conversejs .card-header {
-  padding: 0.75rem 1.25rem;
-  margin-bottom: 0;
-  background-color: rgba(0, 0, 0, 0.03);
-  border-bottom: 1px solid rgba(0, 0, 0, 0.125); }
-  #conversejs .card-header:first-child {
-    border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0; }
-  #conversejs .card-header + .list-group .list-group-item:first-child {
-    border-top: 0; }
-#conversejs .card-footer {
-  padding: 0.75rem 1.25rem;
-  background-color: rgba(0, 0, 0, 0.03);
-  border-top: 1px solid rgba(0, 0, 0, 0.125); }
-  #conversejs .card-footer:last-child {
-    border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px); }
-#conversejs .card-header-tabs {
-  margin-right: -0.625rem;
-  margin-bottom: -0.75rem;
-  margin-left: -0.625rem;
-  border-bottom: 0; }
-#conversejs .card-header-pills {
-  margin-right: -0.625rem;
-  margin-left: -0.625rem; }
-#conversejs .card-img-overlay {
-  position: absolute;
-  top: 0;
-  right: 0;
-  bottom: 0;
-  left: 0;
-  padding: 1.25rem; }
-#conversejs .card-img {
-  width: 100%;
-  border-radius: calc(0.25rem - 1px); }
-#conversejs .card-img-top {
-  width: 100%;
-  border-top-left-radius: calc(0.25rem - 1px);
-  border-top-right-radius: calc(0.25rem - 1px); }
-#conversejs .card-img-bottom {
-  width: 100%;
-  border-bottom-right-radius: calc(0.25rem - 1px);
-  border-bottom-left-radius: calc(0.25rem - 1px); }
-#conversejs .card-deck {
-  display: flex;
-  flex-direction: column; }
-  #conversejs .card-deck .card {
-    margin-bottom: 15px; }
-  @media (min-width: 576px) {
-    #conversejs .card-deck {
-      flex-flow: row wrap;
-      margin-right: -15px;
-      margin-left: -15px; }
-      #conversejs .card-deck .card {
-        display: flex;
-        flex: 1 0 0%;
-        flex-direction: column;
-        margin-right: 15px;
-        margin-bottom: 0;
-        margin-left: 15px; } }
-#conversejs .card-group {
-  display: flex;
-  flex-direction: column; }
-  #conversejs .card-group > .card {
-    margin-bottom: 15px; }
-  @media (min-width: 576px) {
-    #conversejs .card-group {
-      flex-flow: row wrap; }
-      #conversejs .card-group > .card {
-        flex: 1 0 0%;
-        margin-bottom: 0; }
-        #conversejs .card-group > .card + .card {
-          margin-left: 0;
-          border-left: 0; }
-        #conversejs .card-group > .card:first-child {
-          border-top-right-radius: 0;
-          border-bottom-right-radius: 0; }
-          #conversejs .card-group > .card:first-child .card-img-top,
-          #conversejs .card-group > .card:first-child .card-header {
-            border-top-right-radius: 0; }
-          #conversejs .card-group > .card:first-child .card-img-bottom,
-          #conversejs .card-group > .card:first-child .card-footer {
-            border-bottom-right-radius: 0; }
-        #conversejs .card-group > .card:last-child {
-          border-top-left-radius: 0;
-          border-bottom-left-radius: 0; }
-          #conversejs .card-group > .card:last-child .card-img-top,
-          #conversejs .card-group > .card:last-child .card-header {
-            border-top-left-radius: 0; }
-          #conversejs .card-group > .card:last-child .card-img-bottom,
-          #conversejs .card-group > .card:last-child .card-footer {
-            border-bottom-left-radius: 0; }
-        #conversejs .card-group > .card:only-child {
-          border-radius: 0.25rem; }
-          #conversejs .card-group > .card:only-child .card-img-top,
-          #conversejs .card-group > .card:only-child .card-header {
-            border-top-left-radius: 0.25rem;
-            border-top-right-radius: 0.25rem; }
-          #conversejs .card-group > .card:only-child .card-img-bottom,
-          #conversejs .card-group > .card:only-child .card-footer {
-            border-bottom-right-radius: 0.25rem;
-            border-bottom-left-radius: 0.25rem; }
-        #conversejs .card-group > .card:not(:first-child):not(:last-child):not(:only-child) {
-          border-radius: 0; }
-          #conversejs .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-img-top,
-          #conversejs .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom,
-          #conversejs .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-header,
-          #conversejs .card-group > .card:not(:first-child):not(:last-child):not(:only-child) .card-footer {
-            border-radius: 0; } }
-#conversejs .card-columns .card {
-  margin-bottom: 0.75rem; }
-@media (min-width: 576px) {
-  #conversejs .card-columns {
-    column-count: 3;
-    column-gap: 1.25rem; }
-    #conversejs .card-columns .card {
-      display: inline-block;
-      width: 100%; } }
-#conversejs .breadcrumb {
-  display: flex;
-  flex-wrap: wrap;
-  padding: 0.75rem 1rem;
-  margin-bottom: 1rem;
-  list-style: none;
-  background-color: #e9ecef;
-  border-radius: 0.25rem; }
-#conversejs .breadcrumb-item + .breadcrumb-item::before {
-  display: inline-block;
-  padding-right: 0.5rem;
-  padding-left: 0.5rem;
-  color: #6c757d;
-  content: "/"; }
-#conversejs .breadcrumb-item + .breadcrumb-item:hover::before {
-  text-decoration: underline; }
-#conversejs .breadcrumb-item + .breadcrumb-item:hover::before {
-  text-decoration: none; }
-#conversejs .breadcrumb-item.active {
-  color: #6c757d; }
-#conversejs .badge {
-  display: inline-block;
-  padding: 0.25em 0.4em;
-  font-size: 75%;
-  font-weight: 700;
-  line-height: 1;
-  text-align: center;
-  white-space: nowrap;
-  vertical-align: baseline;
-  border-radius: 0.25rem; }
-  #conversejs .badge:empty {
-    display: none; }
-#conversejs .btn .badge {
-  position: relative;
-  top: -1px; }
-#conversejs .badge-pill {
-  padding-right: 0.6em;
-  padding-left: 0.6em;
-  border-radius: 10rem; }
-#conversejs .badge-primary {
-  color: #fff;
-  background-color: #387592; }
-  #conversejs .badge-primary[href]:hover, #conversejs .badge-primary[href]:focus {
-    color: #fff;
-    text-decoration: none;
-    background-color: #2a576d; }
-#conversejs .badge-secondary {
-  color: #fff;
-  background-color: #6c757d; }
-  #conversejs .badge-secondary[href]:hover, #conversejs .badge-secondary[href]:focus {
-    color: #fff;
-    text-decoration: none;
-    background-color: #545b62; }
-#conversejs .badge-success {
-  color: #fff;
-  background-color: #3AA569; }
-  #conversejs .badge-success[href]:hover, #conversejs .badge-success[href]:focus {
-    color: #fff;
-    text-decoration: none;
-    background-color: #2d7f51; }
-#conversejs .badge-info {
-  color: #fff;
-  background-color: #17a2b8; }
-  #conversejs .badge-info[href]:hover, #conversejs .badge-info[href]:focus {
-    color: #fff;
-    text-decoration: none;
-    background-color: #117a8b; }
-#conversejs .badge-warning {
-  color: #212529;
-  background-color: #ffc107; }
-  #conversejs .badge-warning[href]:hover, #conversejs .badge-warning[href]:focus {
-    color: #212529;
-    text-decoration: none;
-    background-color: #d39e00; }
-#conversejs .badge-danger {
-  color: #fff;
-  background-color: #E77051; }
-  #conversejs .badge-danger[href]:hover, #conversejs .badge-danger[href]:focus {
-    color: #fff;
-    text-decoration: none;
-    background-color: #e14b24; }
-#conversejs .badge-light {
-  color: #212529;
-  background-color: #f8f9fa; }
-  #conversejs .badge-light[href]:hover, #conversejs .badge-light[href]:focus {
-    color: #212529;
-    text-decoration: none;
-    background-color: #dae0e5; }
-#conversejs .badge-dark {
-  color: #fff;
-  background-color: #343a40; }
-  #conversejs .badge-dark[href]:hover, #conversejs .badge-dark[href]:focus {
-    color: #fff;
-    text-decoration: none;
-    background-color: #1d2124; }
-#conversejs .alert {
-  position: relative;
-  padding: 0.75rem 1.25rem;
-  margin-bottom: 1rem;
-  border: 1px solid transparent;
-  border-radius: 0.25rem; }
-#conversejs .alert-heading {
-  color: inherit; }
-#conversejs .alert-link {
-  font-weight: 700; }
-#conversejs .alert-dismissible {
-  padding-right: 4rem; }
-  #conversejs .alert-dismissible .close {
-    position: absolute;
-    top: 0;
-    right: 0;
-    padding: 0.75rem 1.25rem;
-    color: inherit; }
-#conversejs .alert-primary {
-  color: #1d3d4c;
-  background-color: #d7e3e9;
-  border-color: #c7d8e0; }
-  #conversejs .alert-primary hr {
-    border-top-color: #b7cdd7; }
-  #conversejs .alert-primary .alert-link {
-    color: #0f1f27; }
-#conversejs .alert-secondary {
-  color: #383d41;
-  background-color: #e2e3e5;
-  border-color: #d6d8db; }
-  #conversejs .alert-secondary hr {
-    border-top-color: #c8cbcf; }
-  #conversejs .alert-secondary .alert-link {
-    color: #202326; }
-#conversejs .alert-success {
-  color: #1e5637;
-  background-color: #d8ede1;
-  border-color: #c8e6d5; }
-  #conversejs .alert-success hr {
-    border-top-color: #b6dec8; }
-  #conversejs .alert-success .alert-link {
-    color: #11301f; }
-#conversejs .alert-info {
-  color: #0c5460;
-  background-color: #d1ecf1;
-  border-color: #bee5eb; }
-  #conversejs .alert-info hr {
-    border-top-color: #abdde5; }
-  #conversejs .alert-info .alert-link {
-    color: #062c33; }
-#conversejs .alert-warning {
-  color: #856404;
-  background-color: #fff3cd;
-  border-color: #ffeeba; }
-  #conversejs .alert-warning hr {
-    border-top-color: #ffe8a1; }
-  #conversejs .alert-warning .alert-link {
-    color: #533f03; }
-#conversejs .alert-danger {
-  color: #783a2a;
-  background-color: #fae2dc;
-  border-color: #f8d7ce; }
-  #conversejs .alert-danger hr {
-    border-top-color: #f5c5b8; }
-  #conversejs .alert-danger .alert-link {
-    color: #52281d; }
-#conversejs .alert-light {
-  color: #818182;
-  background-color: #fefefe;
-  border-color: #fdfdfe; }
-  #conversejs .alert-light hr {
-    border-top-color: #ececf6; }
-  #conversejs .alert-light .alert-link {
-    color: #686868; }
-#conversejs .alert-dark {
-  color: #1b1e21;
-  background-color: #d6d8d9;
-  border-color: #c6c8ca; }
-  #conversejs .alert-dark hr {
-    border-top-color: #b9bbbe; }
-  #conversejs .alert-dark .alert-link {
-    color: #040505; }
-#conversejs .media {
-  display: flex;
-  align-items: flex-start; }
-#conversejs .media-body {
-  flex: 1; }
-#conversejs .list-group {
-  display: flex;
-  flex-direction: column;
-  padding-left: 0;
-  margin-bottom: 0; }
-#conversejs .list-group-item-action {
-  width: 100%;
-  color: #495057;
-  text-align: inherit; }
-  #conversejs .list-group-item-action:hover, #conversejs .list-group-item-action:focus {
-    color: #495057;
-    text-decoration: none;
-    background-color: #f8f9fa; }
-  #conversejs .list-group-item-action:active {
-    color: #212529;
-    background-color: #e9ecef; }
-#conversejs .list-group-item {
-  position: relative;
-  display: block;
-  padding: 0.75rem 1.25rem;
-  margin-bottom: -1px;
-  background-color: #fff;
-  border: 1px solid rgba(0, 0, 0, 0.125); }
-  #conversejs .list-group-item:first-child {
-    border-top-left-radius: 0.25rem;
-    border-top-right-radius: 0.25rem; }
-  #conversejs .list-group-item:last-child {
-    margin-bottom: 0;
-    border-bottom-right-radius: 0.25rem;
-    border-bottom-left-radius: 0.25rem; }
-  #conversejs .list-group-item:hover, #conversejs .list-group-item:focus {
-    z-index: 1;
-    text-decoration: none; }
-  #conversejs .list-group-item.disabled, #conversejs .list-group-item:disabled {
-    color: #6c757d;
-    background-color: #fff; }
-  #conversejs .list-group-item.active {
-    z-index: 2;
-    color: #fff;
-    background-color: #387592;
-    border-color: #387592; }
-#conversejs .list-group-flush .list-group-item {
-  border-right: 0;
-  border-left: 0;
-  border-radius: 0; }
-#conversejs .list-group-flush:first-child .list-group-item:first-child {
-  border-top: 0; }
-#conversejs .list-group-flush:last-child .list-group-item:last-child {
-  border-bottom: 0; }
-#conversejs .list-group-item-primary {
-  color: #1d3d4c;
-  background-color: #c7d8e0; }
-  #conversejs .list-group-item-primary.list-group-item-action:hover, #conversejs .list-group-item-primary.list-group-item-action:focus {
-    color: #1d3d4c;
-    background-color: #b7cdd7; }
-  #conversejs .list-group-item-primary.list-group-item-action.active {
-    color: #fff;
-    background-color: #1d3d4c;
-    border-color: #1d3d4c; }
-#conversejs .list-group-item-secondary {
-  color: #383d41;
-  background-color: #d6d8db; }
-  #conversejs .list-group-item-secondary.list-group-item-action:hover, #conversejs .list-group-item-secondary.list-group-item-action:focus {
-    color: #383d41;
-    background-color: #c8cbcf; }
-  #conversejs .list-group-item-secondary.list-group-item-action.active {
-    color: #fff;
-    background-color: #383d41;
-    border-color: #383d41; }
-#conversejs .list-group-item-success {
-  color: #1e5637;
-  background-color: #c8e6d5; }
-  #conversejs .list-group-item-success.list-group-item-action:hover, #conversejs .list-group-item-success.list-group-item-action:focus {
-    color: #1e5637;
-    background-color: #b6dec8; }
-  #conversejs .list-group-item-success.list-group-item-action.active {
-    color: #fff;
-    background-color: #1e5637;
-    border-color: #1e5637; }
-#conversejs .list-group-item-info {
-  color: #0c5460;
-  background-color: #bee5eb; }
-  #conversejs .list-group-item-info.list-group-item-action:hover, #conversejs .list-group-item-info.list-group-item-action:focus {
-    color: #0c5460;
-    background-color: #abdde5; }
-  #conversejs .list-group-item-info.list-group-item-action.active {
-    color: #fff;
-    background-color: #0c5460;
-    border-color: #0c5460; }
-#conversejs .list-group-item-warning {
-  color: #856404;
-  background-color: #ffeeba; }
-  #conversejs .list-group-item-warning.list-group-item-action:hover, #conversejs .list-group-item-warning.list-group-item-action:focus {
-    color: #856404;
-    background-color: #ffe8a1; }
-  #conversejs .list-group-item-warning.list-group-item-action.active {
-    color: #fff;
-    background-color: #856404;
-    border-color: #856404; }
-#conversejs .list-group-item-danger {
-  color: #783a2a;
-  background-color: #f8d7ce; }
-  #conversejs .list-group-item-danger.list-group-item-action:hover, #conversejs .list-group-item-danger.list-group-item-action:focus {
-    color: #783a2a;
-    background-color: #f5c5b8; }
-  #conversejs .list-group-item-danger.list-group-item-action.active {
-    color: #fff;
-    background-color: #783a2a;
-    border-color: #783a2a; }
-#conversejs .list-group-item-light {
-  color: #818182;
-  background-color: #fdfdfe; }
-  #conversejs .list-group-item-light.list-group-item-action:hover, #conversejs .list-group-item-light.list-group-item-action:focus {
-    color: #818182;
-    background-color: #ececf6; }
-  #conversejs .list-group-item-light.list-group-item-action.active {
-    color: #fff;
-    background-color: #818182;
-    border-color: #818182; }
-#conversejs .list-group-item-dark {
-  color: #1b1e21;
-  background-color: #c6c8ca; }
-  #conversejs .list-group-item-dark.list-group-item-action:hover, #conversejs .list-group-item-dark.list-group-item-action:focus {
-    color: #1b1e21;
-    background-color: #b9bbbe; }
-  #conversejs .list-group-item-dark.list-group-item-action.active {
-    color: #fff;
-    background-color: #1b1e21;
-    border-color: #1b1e21; }
-#conversejs .close {
-  float: right;
-  font-size: 1.5rem;
-  font-weight: 700;
-  line-height: 1;
-  color: #000;
-  text-shadow: 0 1px 0 #fff;
-  opacity: .5; }
-  #conversejs .close:hover, #conversejs .close:focus {
-    color: #000;
-    text-decoration: none;
-    opacity: .75; }
-  #conversejs .close:not(:disabled):not(.disabled) {
-    cursor: pointer; }
-#conversejs button.close {
-  padding: 0;
-  background-color: transparent;
-  border: 0;
-  -webkit-appearance: none; }
-#conversejs .modal-open {
-  overflow: hidden; }
-#conversejs .modal {
-  position: fixed;
-  top: 0;
-  right: 0;
-  bottom: 0;
-  left: 0;
-  z-index: 1050;
-  display: none;
-  overflow: hidden;
-  outline: 0; }
-  .modal-open #conversejs .modal {
-    overflow-x: hidden;
-    overflow-y: auto; }
-#conversejs .modal-dialog {
-  position: relative;
-  width: auto;
-  margin: 0.5rem;
-  pointer-events: none; }
-  .modal.fade #conversejs .modal-dialog {
-    transition: transform 0.3s ease-out;
-    transform: translate(0, -25%); }
-  .modal.show #conversejs .modal-dialog {
-    transform: translate(0, 0); }
-#conversejs .modal-dialog-centered {
-  display: flex;
-  align-items: center;
-  min-height: calc(100% - (0.5rem * 2)); }
-#conversejs .modal-content {
-  position: relative;
-  display: flex;
-  flex-direction: column;
-  width: 100%;
-  pointer-events: auto;
-  background-color: #fff;
-  background-clip: padding-box;
-  border: 1px solid rgba(0, 0, 0, 0.2);
-  border-radius: 0.3rem;
-  outline: 0; }
-#conversejs .modal-backdrop {
-  position: fixed;
-  top: 0;
-  right: 0;
-  bottom: 0;
-  left: 0;
-  z-index: 1040;
-  background-color: #000; }
-  #conversejs .modal-backdrop.fade {
-    opacity: 0; }
-  #conversejs .modal-backdrop.show {
-    opacity: 0.5; }
-#conversejs .modal-header {
-  display: flex;
-  align-items: flex-start;
-  justify-content: space-between;
-  padding: 1rem;
-  border-bottom: 1px solid #e9ecef;
-  border-top-left-radius: 0.3rem;
-  border-top-right-radius: 0.3rem; }
-  #conversejs .modal-header .close {
-    padding: 1rem;
-    margin: -1rem -1rem -1rem auto; }
-#conversejs .modal-title {
-  margin-bottom: 0;
-  line-height: 1.5; }
-#conversejs .modal-body {
-  position: relative;
-  flex: 1 1 auto;
-  padding: 1rem; }
-#conversejs .modal-footer {
-  display: flex;
-  align-items: center;
-  justify-content: flex-end;
-  padding: 1rem;
-  border-top: 1px solid #e9ecef; }
-  #conversejs .modal-footer > :not(:first-child) {
-    margin-left: .25rem; }
-  #conversejs .modal-footer > :not(:last-child) {
-    margin-right: .25rem; }
-#conversejs .modal-scrollbar-measure {
-  position: absolute;
-  top: -9999px;
-  width: 50px;
-  height: 50px;
-  overflow: scroll; }
-@media (min-width: 576px) {
-  #conversejs .modal-dialog {
-    max-width: 500px;
-    margin: 1.75rem auto; }
-  #conversejs .modal-dialog-centered {
-    min-height: calc(100% - (1.75rem * 2)); }
-  #conversejs .modal-sm {
-    max-width: 300px; } }
-@media (min-width: 992px) {
-  #conversejs .modal-lg {
-    max-width: 800px; } }
-#conversejs .tooltip {
-  position: absolute;
-  z-index: 1070;
-  display: block;
-  margin: 0;
-  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
-  font-style: normal;
-  font-weight: 400;
-  line-height: 1.5;
-  text-align: left;
-  text-align: start;
-  text-decoration: none;
-  text-shadow: none;
-  text-transform: none;
-  letter-spacing: normal;
-  word-break: normal;
-  word-spacing: normal;
-  white-space: normal;
-  line-break: auto;
-  font-size: 0.875rem;
-  word-wrap: break-word;
-  opacity: 0; }
-  #conversejs .tooltip.show {
-    opacity: 0.9; }
-  #conversejs .tooltip .arrow {
-    position: absolute;
-    display: block;
-    width: 0.8rem;
-    height: 0.4rem; }
-    #conversejs .tooltip .arrow::before {
-      position: absolute;
-      content: "";
-      border-color: transparent;
-      border-style: solid; }
-#conversejs .bs-tooltip-top, #conversejs .bs-tooltip-auto[x-placement^="top"] {
-  padding: 0.4rem 0; }
-  #conversejs .bs-tooltip-top .arrow, #conversejs .bs-tooltip-auto[x-placement^="top"] .arrow {
-    bottom: 0; }
-    #conversejs .bs-tooltip-top .arrow::before, #conversejs .bs-tooltip-auto[x-placement^="top"] .arrow::before {
-      top: 0;
-      border-width: 0.4rem 0.4rem 0;
-      border-top-color: #000; }
-#conversejs .bs-tooltip-right, #conversejs .bs-tooltip-auto[x-placement^="right"] {
-  padding: 0 0.4rem; }
-  #conversejs .bs-tooltip-right .arrow, #conversejs .bs-tooltip-auto[x-placement^="right"] .arrow {
-    left: 0;
-    width: 0.4rem;
-    height: 0.8rem; }
-    #conversejs .bs-tooltip-right .arrow::before, #conversejs .bs-tooltip-auto[x-placement^="right"] .arrow::before {
-      right: 0;
-      border-width: 0.4rem 0.4rem 0.4rem 0;
-      border-right-color: #000; }
-#conversejs .bs-tooltip-bottom, #conversejs .bs-tooltip-auto[x-placement^="bottom"] {
-  padding: 0.4rem 0; }
-  #conversejs .bs-tooltip-bottom .arrow, #conversejs .bs-tooltip-auto[x-placement^="bottom"] .arrow {
-    top: 0; }
-    #conversejs .bs-tooltip-bottom .arrow::before, #conversejs .bs-tooltip-auto[x-placement^="bottom"] .arrow::before {
-      bottom: 0;
-      border-width: 0 0.4rem 0.4rem;
-      border-bottom-color: #000; }
-#conversejs .bs-tooltip-left, #conversejs .bs-tooltip-auto[x-placement^="left"] {
-  padding: 0 0.4rem; }
-  #conversejs .bs-tooltip-left .arrow, #conversejs .bs-tooltip-auto[x-placement^="left"] .arrow {
-    right: 0;
-    width: 0.4rem;
-    height: 0.8rem; }
-    #conversejs .bs-tooltip-left .arrow::before, #conversejs .bs-tooltip-auto[x-placement^="left"] .arrow::before {
-      left: 0;
-      border-width: 0.4rem 0 0.4rem 0.4rem;
-      border-left-color: #000; }
-#conversejs .tooltip-inner {
-  max-width: 200px;
-  padding: 0.25rem 0.5rem;
-  color: #fff;
-  text-align: center;
-  background-color: #000;
-  border-radius: 0.25rem; }
-#conversejs .popover {
-  position: absolute;
-  top: 0;
-  left: 0;
-  z-index: 1060;
-  display: block;
-  max-width: 276px;
-  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
-  font-style: normal;
-  font-weight: 400;
-  line-height: 1.5;
-  text-align: left;
-  text-align: start;
-  text-decoration: none;
-  text-shadow: none;
-  text-transform: none;
-  letter-spacing: normal;
-  word-break: normal;
-  word-spacing: normal;
-  white-space: normal;
-  line-break: auto;
-  font-size: 0.875rem;
-  word-wrap: break-word;
-  background-color: #fff;
-  background-clip: padding-box;
-  border: 1px solid rgba(0, 0, 0, 0.2);
-  border-radius: 0.3rem; }
-  #conversejs .popover .arrow {
-    position: absolute;
-    display: block;
-    width: 1rem;
-    height: 0.5rem;
-    margin: 0 0.3rem; }
-    #conversejs .popover .arrow::before, #conversejs .popover .arrow::after {
-      position: absolute;
-      display: block;
-      content: "";
-      border-color: transparent;
-      border-style: solid; }
-#conversejs .bs-popover-top, #conversejs .bs-popover-auto[x-placement^="top"] {
-  margin-bottom: 0.5rem; }
-  #conversejs .bs-popover-top .arrow, #conversejs .bs-popover-auto[x-placement^="top"] .arrow {
-    bottom: calc((0.5rem + 1px) * -1); }
-  #conversejs .bs-popover-top .arrow::before, #conversejs .bs-popover-auto[x-placement^="top"] .arrow::before,
-  #conversejs .bs-popover-top .arrow::after,
-  #conversejs .bs-popover-auto[x-placement^="top"] .arrow::after {
-    border-width: 0.5rem 0.5rem 0; }
-  #conversejs .bs-popover-top .arrow::before, #conversejs .bs-popover-auto[x-placement^="top"] .arrow::before {
-    bottom: 0;
-    border-top-color: rgba(0, 0, 0, 0.25); }
-  #conversejs .bs-popover-top .arrow::after, #conversejs .bs-popover-auto[x-placement^="top"] .arrow::after {
-    bottom: 1px;
-    border-top-color: #fff; }
-#conversejs .bs-popover-right, #conversejs .bs-popover-auto[x-placement^="right"] {
-  margin-left: 0.5rem; }
-  #conversejs .bs-popover-right .arrow, #conversejs .bs-popover-auto[x-placement^="right"] .arrow {
-    left: calc((0.5rem + 1px) * -1);
-    width: 0.5rem;
-    height: 1rem;
-    margin: 0.3rem 0; }
-  #conversejs .bs-popover-right .arrow::before, #conversejs .bs-popover-auto[x-placement^="right"] .arrow::before,
-  #conversejs .bs-popover-right .arrow::after,
-  #conversejs .bs-popover-auto[x-placement^="right"] .arrow::after {
-    border-width: 0.5rem 0.5rem 0.5rem 0; }
-  #conversejs .bs-popover-right .arrow::before, #conversejs .bs-popover-auto[x-placement^="right"] .arrow::before {
-    left: 0;
-    border-right-color: rgba(0, 0, 0, 0.25); }
-  #conversejs .bs-popover-right .arrow::after, #conversejs .bs-popover-auto[x-placement^="right"] .arrow::after {
-    left: 1px;
-    border-right-color: #fff; }
-#conversejs .bs-popover-bottom, #conversejs .bs-popover-auto[x-placement^="bottom"] {
-  margin-top: 0.5rem; }
-  #conversejs .bs-popover-bottom .arrow, #conversejs .bs-popover-auto[x-placement^="bottom"] .arrow {
-    top: calc((0.5rem + 1px) * -1); }
-  #conversejs .bs-popover-bottom .arrow::before, #conversejs .bs-popover-auto[x-placement^="bottom"] .arrow::before,
-  #conversejs .bs-popover-bottom .arrow::after,
-  #conversejs .bs-popover-auto[x-placement^="bottom"] .arrow::after {
-    border-width: 0 0.5rem 0.5rem 0.5rem; }
-  #conversejs .bs-popover-bottom .arrow::before, #conversejs .bs-popover-auto[x-placement^="bottom"] .arrow::before {
-    top: 0;
-    border-bottom-color: rgba(0, 0, 0, 0.25); }
-  #conversejs .bs-popover-bottom .arrow::after, #conversejs .bs-popover-auto[x-placement^="bottom"] .arrow::after {
-    top: 1px;
-    border-bottom-color: #fff; }
-  #conversejs .bs-popover-bottom .popover-header::before, #conversejs .bs-popover-auto[x-placement^="bottom"] .popover-header::before {
-    position: absolute;
-    top: 0;
-    left: 50%;
-    display: block;
-    width: 1rem;
-    margin-left: -0.5rem;
-    content: "";
-    border-bottom: 1px solid #f7f7f7; }
-#conversejs .bs-popover-left, #conversejs .bs-popover-auto[x-placement^="left"] {
-  margin-right: 0.5rem; }
-  #conversejs .bs-popover-left .arrow, #conversejs .bs-popover-auto[x-placement^="left"] .arrow {
-    right: calc((0.5rem + 1px) * -1);
-    width: 0.5rem;
-    height: 1rem;
-    margin: 0.3rem 0; }
-  #conversejs .bs-popover-left .arrow::before, #conversejs .bs-popover-auto[x-placement^="left"] .arrow::before,
-  #conversejs .bs-popover-left .arrow::after,
-  #conversejs .bs-popover-auto[x-placement^="left"] .arrow::after {
-    border-width: 0.5rem 0 0.5rem 0.5rem; }
-  #conversejs .bs-popover-left .arrow::before, #conversejs .bs-popover-auto[x-placement^="left"] .arrow::before {
-    right: 0;
-    border-left-color: rgba(0, 0, 0, 0.25); }
-  #conversejs .bs-popover-left .arrow::after, #conversejs .bs-popover-auto[x-placement^="left"] .arrow::after {
-    right: 1px;
-    border-left-color: #fff; }
-#conversejs .popover-header {
-  padding: 0.5rem 0.75rem;
-  margin-bottom: 0;
-  font-size: 1rem;
-  color: inherit;
-  background-color: #f7f7f7;
-  border-bottom: 1px solid #ebebeb;
-  border-top-left-radius: calc(0.3rem - 1px);
-  border-top-right-radius: calc(0.3rem - 1px); }
-  #conversejs .popover-header:empty {
-    display: none; }
-#conversejs .popover-body {
-  padding: 0.5rem 0.75rem;
-  color: #212529; }
-#conversejs .align-baseline {
-  vertical-align: baseline !important; }
-#conversejs .align-top {
-  vertical-align: top !important; }
-#conversejs .align-middle {
-  vertical-align: middle !important; }
-#conversejs .align-bottom {
-  vertical-align: bottom !important; }
-#conversejs .align-text-bottom {
-  vertical-align: text-bottom !important; }
-#conversejs .align-text-top {
-  vertical-align: text-top !important; }
-#conversejs .bg-primary {
-  background-color: #387592 !important; }
-#conversejs a.bg-primary:hover, #conversejs a.bg-primary:focus,
-#conversejs button.bg-primary:hover,
-#conversejs button.bg-primary:focus {
-  background-color: #2a576d !important; }
-#conversejs .bg-secondary {
-  background-color: #6c757d !important; }
-#conversejs a.bg-secondary:hover, #conversejs a.bg-secondary:focus,
-#conversejs button.bg-secondary:hover,
-#conversejs button.bg-secondary:focus {
-  background-color: #545b62 !important; }
-#conversejs .bg-success {
-  background-color: #3AA569 !important; }
-#conversejs a.bg-success:hover, #conversejs a.bg-success:focus,
-#conversejs button.bg-success:hover,
-#conversejs button.bg-success:focus {
-  background-color: #2d7f51 !important; }
-#conversejs .bg-info {
-  background-color: #17a2b8 !important; }
-#conversejs a.bg-info:hover, #conversejs a.bg-info:focus,
-#conversejs button.bg-info:hover,
-#conversejs button.bg-info:focus {
-  background-color: #117a8b !important; }
-#conversejs .bg-warning {
-  background-color: #ffc107 !important; }
-#conversejs a.bg-warning:hover, #conversejs a.bg-warning:focus,
-#conversejs button.bg-warning:hover,
-#conversejs button.bg-warning:focus {
-  background-color: #d39e00 !important; }
-#conversejs .bg-danger {
-  background-color: #E77051 !important; }
-#conversejs a.bg-danger:hover, #conversejs a.bg-danger:focus,
-#conversejs button.bg-danger:hover,
-#conversejs button.bg-danger:focus {
-  background-color: #e14b24 !important; }
-#conversejs .bg-light {
-  background-color: #f8f9fa !important; }
-#conversejs a.bg-light:hover, #conversejs a.bg-light:focus,
-#conversejs button.bg-light:hover,
-#conversejs button.bg-light:focus {
-  background-color: #dae0e5 !important; }
-#conversejs .bg-dark {
-  background-color: #343a40 !important; }
-#conversejs a.bg-dark:hover, #conversejs a.bg-dark:focus,
-#conversejs button.bg-dark:hover,
-#conversejs button.bg-dark:focus {
-  background-color: #1d2124 !important; }
-#conversejs .bg-white {
-  background-color: #fff !important; }
-#conversejs .bg-transparent {
-  background-color: transparent !important; }
-#conversejs .border {
-  border: 1px solid #CCC !important; }
-#conversejs .border-top {
-  border-top: 1px solid #CCC !important; }
-#conversejs .border-right {
-  border-right: 1px solid #CCC !important; }
-#conversejs .border-bottom {
-  border-bottom: 1px solid #CCC !important; }
-#conversejs .border-left {
-  border-left: 1px solid #CCC !important; }
-#conversejs .border-0 {
-  border: 0 !important; }
-#conversejs .border-top-0 {
-  border-top: 0 !important; }
-#conversejs .border-right-0 {
-  border-right: 0 !important; }
-#conversejs .border-bottom-0 {
-  border-bottom: 0 !important; }
-#conversejs .border-left-0 {
-  border-left: 0 !important; }
-#conversejs .border-primary {
-  border-color: #387592 !important; }
-#conversejs .border-secondary {
-  border-color: #6c757d !important; }
-#conversejs .border-success {
-  border-color: #3AA569 !important; }
-#conversejs .border-info {
-  border-color: #17a2b8 !important; }
-#conversejs .border-warning {
-  border-color: #ffc107 !important; }
-#conversejs .border-danger {
-  border-color: #E77051 !important; }
-#conversejs .border-light {
-  border-color: #f8f9fa !important; }
-#conversejs .border-dark {
-  border-color: #343a40 !important; }
-#conversejs .border-white {
-  border-color: #fff !important; }
-#conversejs .rounded {
-  border-radius: 0.25rem !important; }
-#conversejs .rounded-top {
-  border-top-left-radius: 0.25rem !important;
-  border-top-right-radius: 0.25rem !important; }
-#conversejs .rounded-right {
-  border-top-right-radius: 0.25rem !important;
-  border-bottom-right-radius: 0.25rem !important; }
-#conversejs .rounded-bottom {
-  border-bottom-right-radius: 0.25rem !important;
-  border-bottom-left-radius: 0.25rem !important; }
-#conversejs .rounded-left {
-  border-top-left-radius: 0.25rem !important;
-  border-bottom-left-radius: 0.25rem !important; }
-#conversejs .rounded-circle {
-  border-radius: 50% !important; }
-#conversejs .rounded-0 {
-  border-radius: 0 !important; }
-#conversejs .clearfix::after {
-  display: block;
-  clear: both;
-  content: ""; }
-#conversejs .d-none {
-  display: none !important; }
-#conversejs .d-inline {
-  display: inline !important; }
-#conversejs .d-inline-block {
-  display: inline-block !important; }
-#conversejs .d-block {
-  display: block !important; }
-#conversejs .d-table {
-  display: table !important; }
-#conversejs .d-table-row {
-  display: table-row !important; }
-#conversejs .d-table-cell {
-  display: table-cell !important; }
-#conversejs .d-flex {
-  display: flex !important; }
-#conversejs .d-inline-flex {
-  display: inline-flex !important; }
-@media (min-width: 576px) {
-  #conversejs .d-sm-none {
-    display: none !important; }
-  #conversejs .d-sm-inline {
-    display: inline !important; }
-  #conversejs .d-sm-inline-block {
-    display: inline-block !important; }
-  #conversejs .d-sm-block {
-    display: block !important; }
-  #conversejs .d-sm-table {
-    display: table !important; }
-  #conversejs .d-sm-table-row {
-    display: table-row !important; }
-  #conversejs .d-sm-table-cell {
-    display: table-cell !important; }
-  #conversejs .d-sm-flex {
-    display: flex !important; }
-  #conversejs .d-sm-inline-flex {
-    display: inline-flex !important; } }
-@media (min-width: 768px) {
-  #conversejs .d-md-none {
-    display: none !important; }
-  #conversejs .d-md-inline {
-    display: inline !important; }
-  #conversejs .d-md-inline-block {
-    display: inline-block !important; }
-  #conversejs .d-md-block {
-    display: block !important; }
-  #conversejs .d-md-table {
-    display: table !important; }
-  #conversejs .d-md-table-row {
-    display: table-row !important; }
-  #conversejs .d-md-table-cell {
-    display: table-cell !important; }
-  #conversejs .d-md-flex {
-    display: flex !important; }
-  #conversejs .d-md-inline-flex {
-    display: inline-flex !important; } }
-@media (min-width: 992px) {
-  #conversejs .d-lg-none {
-    display: none !important; }
-  #conversejs .d-lg-inline {
-    display: inline !important; }
-  #conversejs .d-lg-inline-block {
-    display: inline-block !important; }
-  #conversejs .d-lg-block {
-    display: block !important; }
-  #conversejs .d-lg-table {
-    display: table !important; }
-  #conversejs .d-lg-table-row {
-    display: table-row !important; }
-  #conversejs .d-lg-table-cell {
-    display: table-cell !important; }
-  #conversejs .d-lg-flex {
-    display: flex !important; }
-  #conversejs .d-lg-inline-flex {
-    display: inline-flex !important; } }
-@media (min-width: 1200px) {
-  #conversejs .d-xl-none {
-    display: none !important; }
-  #conversejs .d-xl-inline {
-    display: inline !important; }
-  #conversejs .d-xl-inline-block {
-    display: inline-block !important; }
-  #conversejs .d-xl-block {
-    display: block !important; }
-  #conversejs .d-xl-table {
-    display: table !important; }
-  #conversejs .d-xl-table-row {
-    display: table-row !important; }
-  #conversejs .d-xl-table-cell {
-    display: table-cell !important; }
-  #conversejs .d-xl-flex {
-    display: flex !important; }
-  #conversejs .d-xl-inline-flex {
-    display: inline-flex !important; } }
-@media print {
-  #conversejs .d-print-none {
-    display: none !important; }
-  #conversejs .d-print-inline {
-    display: inline !important; }
-  #conversejs .d-print-inline-block {
-    display: inline-block !important; }
-  #conversejs .d-print-block {
-    display: block !important; }
-  #conversejs .d-print-table {
-    display: table !important; }
-  #conversejs .d-print-table-row {
-    display: table-row !important; }
-  #conversejs .d-print-table-cell {
-    display: table-cell !important; }
-  #conversejs .d-print-flex {
-    display: flex !important; }
-  #conversejs .d-print-inline-flex {
-    display: inline-flex !important; } }
-#conversejs .embed-responsive {
-  position: relative;
-  display: block;
-  width: 100%;
-  padding: 0;
-  overflow: hidden; }
-  #conversejs .embed-responsive::before {
-    display: block;
-    content: ""; }
-  #conversejs .embed-responsive .embed-responsive-item,
-  #conversejs .embed-responsive iframe,
-  #conversejs .embed-responsive embed,
-  #conversejs .embed-responsive object,
-  #conversejs .embed-responsive video {
-    position: absolute;
-    top: 0;
-    bottom: 0;
-    left: 0;
-    width: 100%;
-    height: 100%;
-    border: 0; }
-#conversejs .embed-responsive-21by9::before {
-  padding-top: 42.8571428571%; }
-#conversejs .embed-responsive-16by9::before {
-  padding-top: 56.25%; }
-#conversejs .embed-responsive-4by3::before {
-  padding-top: 75%; }
-#conversejs .embed-responsive-1by1::before {
-  padding-top: 100%; }
-#conversejs .flex-row {
-  flex-direction: row !important; }
-#conversejs .flex-column {
-  flex-direction: column !important; }
-#conversejs .flex-row-reverse {
-  flex-direction: row-reverse !important; }
-#conversejs .flex-column-reverse {
-  flex-direction: column-reverse !important; }
-#conversejs .flex-wrap {
-  flex-wrap: wrap !important; }
-#conversejs .flex-nowrap {
-  flex-wrap: nowrap !important; }
-#conversejs .flex-wrap-reverse {
-  flex-wrap: wrap-reverse !important; }
-#conversejs .justify-content-start {
-  justify-content: flex-start !important; }
-#conversejs .justify-content-end {
-  justify-content: flex-end !important; }
-#conversejs .justify-content-center {
-  justify-content: center !important; }
-#conversejs .justify-content-between {
-  justify-content: space-between !important; }
-#conversejs .justify-content-around {
-  justify-content: space-around !important; }
-#conversejs .align-items-start {
-  align-items: flex-start !important; }
-#conversejs .align-items-end {
-  align-items: flex-end !important; }
-#conversejs .align-items-center {
-  align-items: center !important; }
-#conversejs .align-items-baseline {
-  align-items: baseline !important; }
-#conversejs .align-items-stretch {
-  align-items: stretch !important; }
-#conversejs .align-content-start {
-  align-content: flex-start !important; }
-#conversejs .align-content-end {
-  align-content: flex-end !important; }
-#conversejs .align-content-center {
-  align-content: center !important; }
-#conversejs .align-content-between {
-  align-content: space-between !important; }
-#conversejs .align-content-around {
-  align-content: space-around !important; }
-#conversejs .align-content-stretch {
-  align-content: stretch !important; }
-#conversejs .align-self-auto {
-  align-self: auto !important; }
-#conversejs .align-self-start {
-  align-self: flex-start !important; }
-#conversejs .align-self-end {
-  align-self: flex-end !important; }
-#conversejs .align-self-center {
-  align-self: center !important; }
-#conversejs .align-self-baseline {
-  align-self: baseline !important; }
-#conversejs .align-self-stretch {
-  align-self: stretch !important; }
-@media (min-width: 576px) {
-  #conversejs .flex-sm-row {
-    flex-direction: row !important; }
-  #conversejs .flex-sm-column {
-    flex-direction: column !important; }
-  #conversejs .flex-sm-row-reverse {
-    flex-direction: row-reverse !important; }
-  #conversejs .flex-sm-column-reverse {
-    flex-direction: column-reverse !important; }
-  #conversejs .flex-sm-wrap {
-    flex-wrap: wrap !important; }
-  #conversejs .flex-sm-nowrap {
-    flex-wrap: nowrap !important; }
-  #conversejs .flex-sm-wrap-reverse {
-    flex-wrap: wrap-reverse !important; }
-  #conversejs .justify-content-sm-start {
-    justify-content: flex-start !important; }
-  #conversejs .justify-content-sm-end {
-    justify-content: flex-end !important; }
-  #conversejs .justify-content-sm-center {
-    justify-content: center !important; }
-  #conversejs .justify-content-sm-between {
-    justify-content: space-between !important; }
-  #conversejs .justify-content-sm-around {
-    justify-content: space-around !important; }
-  #conversejs .align-items-sm-start {
-    align-items: flex-start !important; }
-  #conversejs .align-items-sm-end {
-    align-items: flex-end !important; }
-  #conversejs .align-items-sm-center {
-    align-items: center !important; }
-  #conversejs .align-items-sm-baseline {
-    align-items: baseline !important; }
-  #conversejs .align-items-sm-stretch {
-    align-items: stretch !important; }
-  #conversejs .align-content-sm-start {
-    align-content: flex-start !important; }
-  #conversejs .align-content-sm-end {
-    align-content: flex-end !important; }
-  #conversejs .align-content-sm-center {
-    align-content: center !important; }
-  #conversejs .align-content-sm-between {
-    align-content: space-between !important; }
-  #conversejs .align-content-sm-around {
-    align-content: space-around !important; }
-  #conversejs .align-content-sm-stretch {
-    align-content: stretch !important; }
-  #conversejs .align-self-sm-auto {
-    align-self: auto !important; }
-  #conversejs .align-self-sm-start {
-    align-self: flex-start !important; }
-  #conversejs .align-self-sm-end {
-    align-self: flex-end !important; }
-  #conversejs .align-self-sm-center {
-    align-self: center !important; }
-  #conversejs .align-self-sm-baseline {
-    align-self: baseline !important; }
-  #conversejs .align-self-sm-stretch {
-    align-self: stretch !important; } }
-@media (min-width: 768px) {
-  #conversejs .flex-md-row {
-    flex-direction: row !important; }
-  #conversejs .flex-md-column {
-    flex-direction: column !important; }
-  #conversejs .flex-md-row-reverse {
-    flex-direction: row-reverse !important; }
-  #conversejs .flex-md-column-reverse {
-    flex-direction: column-reverse !important; }
-  #conversejs .flex-md-wrap {
-    flex-wrap: wrap !important; }
-  #conversejs .flex-md-nowrap {
-    flex-wrap: nowrap !important; }
-  #conversejs .flex-md-wrap-reverse {
-    flex-wrap: wrap-reverse !important; }
-  #conversejs .justify-content-md-start {
-    justify-content: flex-start !important; }
-  #conversejs .justify-content-md-end {
-    justify-content: flex-end !important; }
-  #conversejs .justify-content-md-center {
-    justify-content: center !important; }
-  #conversejs .justify-content-md-between {
-    justify-content: space-between !important; }
-  #conversejs .justify-content-md-around {
-    justify-content: space-around !important; }
-  #conversejs .align-items-md-start {
-    align-items: flex-start !important; }
-  #conversejs .align-items-md-end {
-    align-items: flex-end !important; }
-  #conversejs .align-items-md-center {
-    align-items: center !important; }
-  #conversejs .align-items-md-baseline {
-    align-items: baseline !important; }
-  #conversejs .align-items-md-stretch {
-    align-items: stretch !important; }
-  #conversejs .align-content-md-start {
-    align-content: flex-start !important; }
-  #conversejs .align-content-md-end {
-    align-content: flex-end !important; }
-  #conversejs .align-content-md-center {
-    align-content: center !important; }
-  #conversejs .align-content-md-between {
-    align-content: space-between !important; }
-  #conversejs .align-content-md-around {
-    align-content: space-around !important; }
-  #conversejs .align-content-md-stretch {
-    align-content: stretch !important; }
-  #conversejs .align-self-md-auto {
-    align-self: auto !important; }
-  #conversejs .align-self-md-start {
-    align-self: flex-start !important; }
-  #conversejs .align-self-md-end {
-    align-self: flex-end !important; }
-  #conversejs .align-self-md-center {
-    align-self: center !important; }
-  #conversejs .align-self-md-baseline {
-    align-self: baseline !important; }
-  #conversejs .align-self-md-stretch {
-    align-self: stretch !important; } }
-@media (min-width: 992px) {
-  #conversejs .flex-lg-row {
-    flex-direction: row !important; }
-  #conversejs .flex-lg-column {
-    flex-direction: column !important; }
-  #conversejs .flex-lg-row-reverse {
-    flex-direction: row-reverse !important; }
-  #conversejs .flex-lg-column-reverse {
-    flex-direction: column-reverse !important; }
-  #conversejs .flex-lg-wrap {
-    flex-wrap: wrap !important; }
-  #conversejs .flex-lg-nowrap {
-    flex-wrap: nowrap !important; }
-  #conversejs .flex-lg-wrap-reverse {
-    flex-wrap: wrap-reverse !important; }
-  #conversejs .justify-content-lg-start {
-    justify-content: flex-start !important; }
-  #conversejs .justify-content-lg-end {
-    justify-content: flex-end !important; }
-  #conversejs .justify-content-lg-center {
-    justify-content: center !important; }
-  #conversejs .justify-content-lg-between {
-    justify-content: space-between !important; }
-  #conversejs .justify-content-lg-around {
-    justify-content: space-around !important; }
-  #conversejs .align-items-lg-start {
-    align-items: flex-start !important; }
-  #conversejs .align-items-lg-end {
-    align-items: flex-end !important; }
-  #conversejs .align-items-lg-center {
-    align-items: center !important; }
-  #conversejs .align-items-lg-baseline {
-    align-items: baseline !important; }
-  #conversejs .align-items-lg-stretch {
-    align-items: stretch !important; }
-  #conversejs .align-content-lg-start {
-    align-content: flex-start !important; }
-  #conversejs .align-content-lg-end {
-    align-content: flex-end !important; }
-  #conversejs .align-content-lg-center {
-    align-content: center !important; }
-  #conversejs .align-content-lg-between {
-    align-content: space-between !important; }
-  #conversejs .align-content-lg-around {
-    align-content: space-around !important; }
-  #conversejs .align-content-lg-stretch {
-    align-content: stretch !important; }
-  #conversejs .align-self-lg-auto {
-    align-self: auto !important; }
-  #conversejs .align-self-lg-start {
-    align-self: flex-start !important; }
-  #conversejs .align-self-lg-end {
-    align-self: flex-end !important; }
-  #conversejs .align-self-lg-center {
-    align-self: center !important; }
-  #conversejs .align-self-lg-baseline {
-    align-self: baseline !important; }
-  #conversejs .align-self-lg-stretch {
-    align-self: stretch !important; } }
-@media (min-width: 1200px) {
-  #conversejs .flex-xl-row {
-    flex-direction: row !important; }
-  #conversejs .flex-xl-column {
-    flex-direction: column !important; }
-  #conversejs .flex-xl-row-reverse {
-    flex-direction: row-reverse !important; }
-  #conversejs .flex-xl-column-reverse {
-    flex-direction: column-reverse !important; }
-  #conversejs .flex-xl-wrap {
-    flex-wrap: wrap !important; }
-  #conversejs .flex-xl-nowrap {
-    flex-wrap: nowrap !important; }
-  #conversejs .flex-xl-wrap-reverse {
-    flex-wrap: wrap-reverse !important; }
-  #conversejs .justify-content-xl-start {
-    justify-content: flex-start !important; }
-  #conversejs .justify-content-xl-end {
-    justify-content: flex-end !important; }
-  #conversejs .justify-content-xl-center {
-    justify-content: center !important; }
-  #conversejs .justify-content-xl-between {
-    justify-content: space-between !important; }
-  #conversejs .justify-content-xl-around {
-    justify-content: space-around !important; }
-  #conversejs .align-items-xl-start {
-    align-items: flex-start !important; }
-  #conversejs .align-items-xl-end {
-    align-items: flex-end !important; }
-  #conversejs .align-items-xl-center {
-    align-items: center !important; }
-  #conversejs .align-items-xl-baseline {
-    align-items: baseline !important; }
-  #conversejs .align-items-xl-stretch {
-    align-items: stretch !important; }
-  #conversejs .align-content-xl-start {
-    align-content: flex-start !important; }
-  #conversejs .align-content-xl-end {
-    align-content: flex-end !important; }
-  #conversejs .align-content-xl-center {
-    align-content: center !important; }
-  #conversejs .align-content-xl-between {
-    align-content: space-between !important; }
-  #conversejs .align-content-xl-around {
-    align-content: space-around !important; }
-  #conversejs .align-content-xl-stretch {
-    align-content: stretch !important; }
-  #conversejs .align-self-xl-auto {
-    align-self: auto !important; }
-  #conversejs .align-self-xl-start {
-    align-self: flex-start !important; }
-  #conversejs .align-self-xl-end {
-    align-self: flex-end !important; }
-  #conversejs .align-self-xl-center {
-    align-self: center !important; }
-  #conversejs .align-self-xl-baseline {
-    align-self: baseline !important; }
-  #conversejs .align-self-xl-stretch {
-    align-self: stretch !important; } }
-#conversejs .float-left {
-  float: left !important; }
-#conversejs .float-right {
-  float: right !important; }
-#conversejs .float-none {
-  float: none !important; }
-@media (min-width: 576px) {
-  #conversejs .float-sm-left {
-    float: left !important; }
-  #conversejs .float-sm-right {
-    float: right !important; }
-  #conversejs .float-sm-none {
-    float: none !important; } }
-@media (min-width: 768px) {
-  #conversejs .float-md-left {
-    float: left !important; }
-  #conversejs .float-md-right {
-    float: right !important; }
-  #conversejs .float-md-none {
-    float: none !important; } }
-@media (min-width: 992px) {
-  #conversejs .float-lg-left {
-    float: left !important; }
-  #conversejs .float-lg-right {
-    float: right !important; }
-  #conversejs .float-lg-none {
-    float: none !important; } }
-@media (min-width: 1200px) {
-  #conversejs .float-xl-left {
-    float: left !important; }
-  #conversejs .float-xl-right {
-    float: right !important; }
-  #conversejs .float-xl-none {
-    float: none !important; } }
-#conversejs .position-static {
-  position: static !important; }
-#conversejs .position-relative {
-  position: relative !important; }
-#conversejs .position-absolute {
-  position: absolute !important; }
-#conversejs .position-fixed {
-  position: fixed !important; }
-#conversejs .position-sticky {
-  position: sticky !important; }
-#conversejs .fixed-top {
-  position: fixed;
-  top: 0;
-  right: 0;
-  left: 0;
-  z-index: 1030; }
-#conversejs .fixed-bottom {
-  position: fixed;
-  right: 0;
-  bottom: 0;
-  left: 0;
-  z-index: 1030; }
-@supports (position: sticky) {
-  #conversejs .sticky-top {
-    position: sticky;
-    top: 0;
-    z-index: 1020; } }
-#conversejs .sr-only {
-  position: absolute;
-  width: 1px;
-  height: 1px;
-  padding: 0;
-  overflow: hidden;
-  clip: rect(0, 0, 0, 0);
-  white-space: nowrap;
-  clip-path: inset(50%);
-  border: 0; }
-#conversejs .sr-only-focusable:active, #conversejs .sr-only-focusable:focus {
-  position: static;
-  width: auto;
-  height: auto;
-  overflow: visible;
-  clip: auto;
-  white-space: normal;
-  clip-path: none; }
-#conversejs .w-25 {
-  width: 25% !important; }
-#conversejs .w-50 {
-  width: 50% !important; }
-#conversejs .w-75 {
-  width: 75% !important; }
-#conversejs .w-100 {
-  width: 100% !important; }
-#conversejs .h-25 {
-  height: 25% !important; }
-#conversejs .h-50 {
-  height: 50% !important; }
-#conversejs .h-75 {
-  height: 75% !important; }
-#conversejs .h-100 {
-  height: 100% !important; }
-#conversejs .mw-100 {
-  max-width: 100% !important; }
-#conversejs .mh-100 {
-  max-height: 100% !important; }
-#conversejs .m-0 {
-  margin: 0 !important; }
-#conversejs .mt-0,
-#conversejs .my-0 {
-  margin-top: 0 !important; }
-#conversejs .mr-0,
-#conversejs .mx-0 {
-  margin-right: 0 !important; }
-#conversejs .mb-0,
-#conversejs .my-0 {
-  margin-bottom: 0 !important; }
-#conversejs .ml-0,
-#conversejs .mx-0 {
-  margin-left: 0 !important; }
-#conversejs .m-1 {
-  margin: 0.25rem !important; }
-#conversejs .mt-1,
-#conversejs .my-1 {
-  margin-top: 0.25rem !important; }
-#conversejs .mr-1,
-#conversejs .mx-1 {
-  margin-right: 0.25rem !important; }
-#conversejs .mb-1,
-#conversejs .my-1 {
-  margin-bottom: 0.25rem !important; }
-#conversejs .ml-1,
-#conversejs .mx-1 {
-  margin-left: 0.25rem !important; }
-#conversejs .m-2 {
-  margin: 0.5rem !important; }
-#conversejs .mt-2,
-#conversejs .my-2 {
-  margin-top: 0.5rem !important; }
-#conversejs .mr-2,
-#conversejs .mx-2 {
-  margin-right: 0.5rem !important; }
-#conversejs .mb-2,
-#conversejs .my-2 {
-  margin-bottom: 0.5rem !important; }
-#conversejs .ml-2,
-#conversejs .mx-2 {
-  margin-left: 0.5rem !important; }
-#conversejs .m-3 {
-  margin: 1rem !important; }
-#conversejs .mt-3,
-#conversejs .my-3 {
-  margin-top: 1rem !important; }
-#conversejs .mr-3,
-#conversejs .mx-3 {
-  margin-right: 1rem !important; }
-#conversejs .mb-3,
-#conversejs .my-3 {
-  margin-bottom: 1rem !important; }
-#conversejs .ml-3,
-#conversejs .mx-3 {
-  margin-left: 1rem !important; }
-#conversejs .m-4 {
-  margin: 1.5rem !important; }
-#conversejs .mt-4,
-#conversejs .my-4 {
-  margin-top: 1.5rem !important; }
-#conversejs .mr-4,
-#conversejs .mx-4 {
-  margin-right: 1.5rem !important; }
-#conversejs .mb-4,
-#conversejs .my-4 {
-  margin-bottom: 1.5rem !important; }
-#conversejs .ml-4,
-#conversejs .mx-4 {
-  margin-left: 1.5rem !important; }
-#conversejs .m-5 {
-  margin: 3rem !important; }
-#conversejs .mt-5,
-#conversejs .my-5 {
-  margin-top: 3rem !important; }
-#conversejs .mr-5,
-#conversejs .mx-5 {
-  margin-right: 3rem !important; }
-#conversejs .mb-5,
-#conversejs .my-5 {
-  margin-bottom: 3rem !important; }
-#conversejs .ml-5,
-#conversejs .mx-5 {
-  margin-left: 3rem !important; }
-#conversejs .p-0 {
-  padding: 0 !important; }
-#conversejs .pt-0,
-#conversejs .py-0 {
-  padding-top: 0 !important; }
-#conversejs .pr-0,
-#conversejs .px-0 {
-  padding-right: 0 !important; }
-#conversejs .pb-0,
-#conversejs .py-0 {
-  padding-bottom: 0 !important; }
-#conversejs .pl-0,
-#conversejs .px-0 {
-  padding-left: 0 !important; }
-#conversejs .p-1 {
-  padding: 0.25rem !important; }
-#conversejs .pt-1,
-#conversejs .py-1 {
-  padding-top: 0.25rem !important; }
-#conversejs .pr-1,
-#conversejs .px-1 {
-  padding-right: 0.25rem !important; }
-#conversejs .pb-1,
-#conversejs .py-1 {
-  padding-bottom: 0.25rem !important; }
-#conversejs .pl-1,
-#conversejs .px-1 {
-  padding-left: 0.25rem !important; }
-#conversejs .p-2 {
-  padding: 0.5rem !important; }
-#conversejs .pt-2,
-#conversejs .py-2 {
-  padding-top: 0.5rem !important; }
-#conversejs .pr-2,
-#conversejs .px-2 {
-  padding-right: 0.5rem !important; }
-#conversejs .pb-2,
-#conversejs .py-2 {
-  padding-bottom: 0.5rem !important; }
-#conversejs .pl-2,
-#conversejs .px-2 {
-  padding-left: 0.5rem !important; }
-#conversejs .p-3 {
-  padding: 1rem !important; }
-#conversejs .pt-3,
-#conversejs .py-3 {
-  padding-top: 1rem !important; }
-#conversejs .pr-3,
-#conversejs .px-3 {
-  padding-right: 1rem !important; }
-#conversejs .pb-3,
-#conversejs .py-3 {
-  padding-bottom: 1rem !important; }
-#conversejs .pl-3,
-#conversejs .px-3 {
-  padding-left: 1rem !important; }
-#conversejs .p-4 {
-  padding: 1.5rem !important; }
-#conversejs .pt-4,
-#conversejs .py-4 {
-  padding-top: 1.5rem !important; }
-#conversejs .pr-4,
-#conversejs .px-4 {
-  padding-right: 1.5rem !important; }
-#conversejs .pb-4,
-#conversejs .py-4 {
-  padding-bottom: 1.5rem !important; }
-#conversejs .pl-4,
-#conversejs .px-4 {
-  padding-left: 1.5rem !important; }
-#conversejs .p-5 {
-  padding: 3rem !important; }
-#conversejs .pt-5,
-#conversejs .py-5 {
-  padding-top: 3rem !important; }
-#conversejs .pr-5,
-#conversejs .px-5 {
-  padding-right: 3rem !important; }
-#conversejs .pb-5,
-#conversejs .py-5 {
-  padding-bottom: 3rem !important; }
-#conversejs .pl-5,
-#conversejs .px-5 {
-  padding-left: 3rem !important; }
-#conversejs .m-auto {
-  margin: auto !important; }
-#conversejs .mt-auto,
-#conversejs .my-auto {
-  margin-top: auto !important; }
-#conversejs .mr-auto,
-#conversejs .mx-auto {
-  margin-right: auto !important; }
-#conversejs .mb-auto,
-#conversejs .my-auto {
-  margin-bottom: auto !important; }
-#conversejs .ml-auto,
-#conversejs .mx-auto {
-  margin-left: auto !important; }
-@media (min-width: 576px) {
-  #conversejs .m-sm-0 {
-    margin: 0 !important; }
-  #conversejs .mt-sm-0,
-  #conversejs .my-sm-0 {
-    margin-top: 0 !important; }
-  #conversejs .mr-sm-0,
-  #conversejs .mx-sm-0 {
-    margin-right: 0 !important; }
-  #conversejs .mb-sm-0,
-  #conversejs .my-sm-0 {
-    margin-bottom: 0 !important; }
-  #conversejs .ml-sm-0,
-  #conversejs .mx-sm-0 {
-    margin-left: 0 !important; }
-  #conversejs .m-sm-1 {
-    margin: 0.25rem !important; }
-  #conversejs .mt-sm-1,
-  #conversejs .my-sm-1 {
-    margin-top: 0.25rem !important; }
-  #conversejs .mr-sm-1,
-  #conversejs .mx-sm-1 {
-    margin-right: 0.25rem !important; }
-  #conversejs .mb-sm-1,
-  #conversejs .my-sm-1 {
-    margin-bottom: 0.25rem !important; }
-  #conversejs .ml-sm-1,
-  #conversejs .mx-sm-1 {
-    margin-left: 0.25rem !important; }
-  #conversejs .m-sm-2 {
-    margin: 0.5rem !important; }
-  #conversejs .mt-sm-2,
-  #conversejs .my-sm-2 {
-    margin-top: 0.5rem !important; }
-  #conversejs .mr-sm-2,
-  #conversejs .mx-sm-2 {
-    margin-right: 0.5rem !important; }
-  #conversejs .mb-sm-2,
-  #conversejs .my-sm-2 {
-    margin-bottom: 0.5rem !important; }
-  #conversejs .ml-sm-2,
-  #conversejs .mx-sm-2 {
-    margin-left: 0.5rem !important; }
-  #conversejs .m-sm-3 {
-    margin: 1rem !important; }
-  #conversejs .mt-sm-3,
-  #conversejs .my-sm-3 {
-    margin-top: 1rem !important; }
-  #conversejs .mr-sm-3,
-  #conversejs .mx-sm-3 {
-    margin-right: 1rem !important; }
-  #conversejs .mb-sm-3,
-  #conversejs .my-sm-3 {
-    margin-bottom: 1rem !important; }
-  #conversejs .ml-sm-3,
-  #conversejs .mx-sm-3 {
-    margin-left: 1rem !important; }
-  #conversejs .m-sm-4 {
-    margin: 1.5rem !important; }
-  #conversejs .mt-sm-4,
-  #conversejs .my-sm-4 {
-    margin-top: 1.5rem !important; }
-  #conversejs .mr-sm-4,
-  #conversejs .mx-sm-4 {
-    margin-right: 1.5rem !important; }
-  #conversejs .mb-sm-4,
-  #conversejs .my-sm-4 {
-    margin-bottom: 1.5rem !important; }
-  #conversejs .ml-sm-4,
-  #conversejs .mx-sm-4 {
-    margin-left: 1.5rem !important; }
-  #conversejs .m-sm-5 {
-    margin: 3rem !important; }
-  #conversejs .mt-sm-5,
-  #conversejs .my-sm-5 {
-    margin-top: 3rem !important; }
-  #conversejs .mr-sm-5,
-  #conversejs .mx-sm-5 {
-    margin-right: 3rem !important; }
-  #conversejs .mb-sm-5,
-  #conversejs .my-sm-5 {
-    margin-bottom: 3rem !important; }
-  #conversejs .ml-sm-5,
-  #conversejs .mx-sm-5 {
-    margin-left: 3rem !important; }
-  #conversejs .p-sm-0 {
-    padding: 0 !important; }
-  #conversejs .pt-sm-0,
-  #conversejs .py-sm-0 {
-    padding-top: 0 !important; }
-  #conversejs .pr-sm-0,
-  #conversejs .px-sm-0 {
-    padding-right: 0 !important; }
-  #conversejs .pb-sm-0,
-  #conversejs .py-sm-0 {
-    padding-bottom: 0 !important; }
-  #conversejs .pl-sm-0,
-  #conversejs .px-sm-0 {
-    padding-left: 0 !important; }
-  #conversejs .p-sm-1 {
-    padding: 0.25rem !important; }
-  #conversejs .pt-sm-1,
-  #conversejs .py-sm-1 {
-    padding-top: 0.25rem !important; }
-  #conversejs .pr-sm-1,
-  #conversejs .px-sm-1 {
-    padding-right: 0.25rem !important; }
-  #conversejs .pb-sm-1,
-  #conversejs .py-sm-1 {
-    padding-bottom: 0.25rem !important; }
-  #conversejs .pl-sm-1,
-  #conversejs .px-sm-1 {
-    padding-left: 0.25rem !important; }
-  #conversejs .p-sm-2 {
-    padding: 0.5rem !important; }
-  #conversejs .pt-sm-2,
-  #conversejs .py-sm-2 {
-    padding-top: 0.5rem !important; }
-  #conversejs .pr-sm-2,
-  #conversejs .px-sm-2 {
-    padding-right: 0.5rem !important; }
-  #conversejs .pb-sm-2,
-  #conversejs .py-sm-2 {
-    padding-bottom: 0.5rem !important; }
-  #conversejs .pl-sm-2,
-  #conversejs .px-sm-2 {
-    padding-left: 0.5rem !important; }
-  #conversejs .p-sm-3 {
-    padding: 1rem !important; }
-  #conversejs .pt-sm-3,
-  #conversejs .py-sm-3 {
-    padding-top: 1rem !important; }
-  #conversejs .pr-sm-3,
-  #conversejs .px-sm-3 {
-    padding-right: 1rem !important; }
-  #conversejs .pb-sm-3,
-  #conversejs .py-sm-3 {
-    padding-bottom: 1rem !important; }
-  #conversejs .pl-sm-3,
-  #conversejs .px-sm-3 {
-    padding-left: 1rem !important; }
-  #conversejs .p-sm-4 {
-    padding: 1.5rem !important; }
-  #conversejs .pt-sm-4,
-  #conversejs .py-sm-4 {
-    padding-top: 1.5rem !important; }
-  #conversejs .pr-sm-4,
-  #conversejs .px-sm-4 {
-    padding-right: 1.5rem !important; }
-  #conversejs .pb-sm-4,
-  #conversejs .py-sm-4 {
-    padding-bottom: 1.5rem !important; }
-  #conversejs .pl-sm-4,
-  #conversejs .px-sm-4 {
-    padding-left: 1.5rem !important; }
-  #conversejs .p-sm-5 {
-    padding: 3rem !important; }
-  #conversejs .pt-sm-5,
-  #conversejs .py-sm-5 {
-    padding-top: 3rem !important; }
-  #conversejs .pr-sm-5,
-  #conversejs .px-sm-5 {
-    padding-right: 3rem !important; }
-  #conversejs .pb-sm-5,
-  #conversejs .py-sm-5 {
-    padding-bottom: 3rem !important; }
-  #conversejs .pl-sm-5,
-  #conversejs .px-sm-5 {
-    padding-left: 3rem !important; }
-  #conversejs .m-sm-auto {
-    margin: auto !important; }
-  #conversejs .mt-sm-auto,
-  #conversejs .my-sm-auto {
-    margin-top: auto !important; }
-  #conversejs .mr-sm-auto,
-  #conversejs .mx-sm-auto {
-    margin-right: auto !important; }
-  #conversejs .mb-sm-auto,
-  #conversejs .my-sm-auto {
-    margin-bottom: auto !important; }
-  #conversejs .ml-sm-auto,
-  #conversejs .mx-sm-auto {
-    margin-left: auto !important; } }
-@media (min-width: 768px) {
-  #conversejs .m-md-0 {
-    margin: 0 !important; }
-  #conversejs .mt-md-0,
-  #conversejs .my-md-0 {
-    margin-top: 0 !important; }
-  #conversejs .mr-md-0,
-  #conversejs .mx-md-0 {
-    margin-right: 0 !important; }
-  #conversejs .mb-md-0,
-  #conversejs .my-md-0 {
-    margin-bottom: 0 !important; }
-  #conversejs .ml-md-0,
-  #conversejs .mx-md-0 {
-    margin-left: 0 !important; }
-  #conversejs .m-md-1 {
-    margin: 0.25rem !important; }
-  #conversejs .mt-md-1,
-  #conversejs .my-md-1 {
-    margin-top: 0.25rem !important; }
-  #conversejs .mr-md-1,
-  #conversejs .mx-md-1 {
-    margin-right: 0.25rem !important; }
-  #conversejs .mb-md-1,
-  #conversejs .my-md-1 {
-    margin-bottom: 0.25rem !important; }
-  #conversejs .ml-md-1,
-  #conversejs .mx-md-1 {
-    margin-left: 0.25rem !important; }
-  #conversejs .m-md-2 {
-    margin: 0.5rem !important; }
-  #conversejs .mt-md-2,
-  #conversejs .my-md-2 {
-    margin-top: 0.5rem !important; }
-  #conversejs .mr-md-2,
-  #conversejs .mx-md-2 {
-    margin-right: 0.5rem !important; }
-  #conversejs .mb-md-2,
-  #conversejs .my-md-2 {
-    margin-bottom: 0.5rem !important; }
-  #conversejs .ml-md-2,
-  #conversejs .mx-md-2 {
-    margin-left: 0.5rem !important; }
-  #conversejs .m-md-3 {
-    margin: 1rem !important; }
-  #conversejs .mt-md-3,
-  #conversejs .my-md-3 {
-    margin-top: 1rem !important; }
-  #conversejs .mr-md-3,
-  #conversejs .mx-md-3 {
-    margin-right: 1rem !important; }
-  #conversejs .mb-md-3,
-  #conversejs .my-md-3 {
-    margin-bottom: 1rem !important; }
-  #conversejs .ml-md-3,
-  #conversejs .mx-md-3 {
-    margin-left: 1rem !important; }
-  #conversejs .m-md-4 {
-    margin: 1.5rem !important; }
-  #conversejs .mt-md-4,
-  #conversejs .my-md-4 {
-    margin-top: 1.5rem !important; }
-  #conversejs .mr-md-4,
-  #conversejs .mx-md-4 {
-    margin-right: 1.5rem !important; }
-  #conversejs .mb-md-4,
-  #conversejs .my-md-4 {
-    margin-bottom: 1.5rem !important; }
-  #conversejs .ml-md-4,
-  #conversejs .mx-md-4 {
-    margin-left: 1.5rem !important; }
-  #conversejs .m-md-5 {
-    margin: 3rem !important; }
-  #conversejs .mt-md-5,
-  #conversejs .my-md-5 {
-    margin-top: 3rem !important; }
-  #conversejs .mr-md-5,
-  #conversejs .mx-md-5 {
-    margin-right: 3rem !important; }
-  #conversejs .mb-md-5,
-  #conversejs .my-md-5 {
-    margin-bottom: 3rem !important; }
-  #conversejs .ml-md-5,
-  #conversejs .mx-md-5 {
-    margin-left: 3rem !important; }
-  #conversejs .p-md-0 {
-    padding: 0 !important; }
-  #conversejs .pt-md-0,
-  #conversejs .py-md-0 {
-    padding-top: 0 !important; }
-  #conversejs .pr-md-0,
-  #conversejs .px-md-0 {
-    padding-right: 0 !important; }
-  #conversejs .pb-md-0,
-  #conversejs .py-md-0 {
-    padding-bottom: 0 !important; }
-  #conversejs .pl-md-0,
-  #conversejs .px-md-0 {
-    padding-left: 0 !important; }
-  #conversejs .p-md-1 {
-    padding: 0.25rem !important; }
-  #conversejs .pt-md-1,
-  #conversejs .py-md-1 {
-    padding-top: 0.25rem !important; }
-  #conversejs .pr-md-1,
-  #conversejs .px-md-1 {
-    padding-right: 0.25rem !important; }
-  #conversejs .pb-md-1,
-  #conversejs .py-md-1 {
-    padding-bottom: 0.25rem !important; }
-  #conversejs .pl-md-1,
-  #conversejs .px-md-1 {
-    padding-left: 0.25rem !important; }
-  #conversejs .p-md-2 {
-    padding: 0.5rem !important; }
-  #conversejs .pt-md-2,
-  #conversejs .py-md-2 {
-    padding-top: 0.5rem !important; }
-  #conversejs .pr-md-2,
-  #conversejs .px-md-2 {
-    padding-right: 0.5rem !important; }
-  #conversejs .pb-md-2,
-  #conversejs .py-md-2 {
-    padding-bottom: 0.5rem !important; }
-  #conversejs .pl-md-2,
-  #conversejs .px-md-2 {
-    padding-left: 0.5rem !important; }
-  #conversejs .p-md-3 {
-    padding: 1rem !important; }
-  #conversejs .pt-md-3,
-  #conversejs .py-md-3 {
-    padding-top: 1rem !important; }
-  #conversejs .pr-md-3,
-  #conversejs .px-md-3 {
-    padding-right: 1rem !important; }
-  #conversejs .pb-md-3,
-  #conversejs .py-md-3 {
-    padding-bottom: 1rem !important; }
-  #conversejs .pl-md-3,
-  #conversejs .px-md-3 {
-    padding-left: 1rem !important; }
-  #conversejs .p-md-4 {
-    padding: 1.5rem !important; }
-  #conversejs .pt-md-4,
-  #conversejs .py-md-4 {
-    padding-top: 1.5rem !important; }
-  #conversejs .pr-md-4,
-  #conversejs .px-md-4 {
-    padding-right: 1.5rem !important; }
-  #conversejs .pb-md-4,
-  #conversejs .py-md-4 {
-    padding-bottom: 1.5rem !important; }
-  #conversejs .pl-md-4,
-  #conversejs .px-md-4 {
-    padding-left: 1.5rem !important; }
-  #conversejs .p-md-5 {
-    padding: 3rem !important; }
-  #conversejs .pt-md-5,
-  #conversejs .py-md-5 {
-    padding-top: 3rem !important; }
-  #conversejs .pr-md-5,
-  #conversejs .px-md-5 {
-    padding-right: 3rem !important; }
-  #conversejs .pb-md-5,
-  #conversejs .py-md-5 {
-    padding-bottom: 3rem !important; }
-  #conversejs .pl-md-5,
-  #conversejs .px-md-5 {
-    padding-left: 3rem !important; }
-  #conversejs .m-md-auto {
-    margin: auto !important; }
-  #conversejs .mt-md-auto,
-  #conversejs .my-md-auto {
-    margin-top: auto !important; }
-  #conversejs .mr-md-auto,
-  #conversejs .mx-md-auto {
-    margin-right: auto !important; }
-  #conversejs .mb-md-auto,
-  #conversejs .my-md-auto {
-    margin-bottom: auto !important; }
-  #conversejs .ml-md-auto,
-  #conversejs .mx-md-auto {
-    margin-left: auto !important; } }
-@media (min-width: 992px) {
-  #conversejs .m-lg-0 {
-    margin: 0 !important; }
-  #conversejs .mt-lg-0,
-  #conversejs .my-lg-0 {
-    margin-top: 0 !important; }
-  #conversejs .mr-lg-0,
-  #conversejs .mx-lg-0 {
-    margin-right: 0 !important; }
-  #conversejs .mb-lg-0,
-  #conversejs .my-lg-0 {
-    margin-bottom: 0 !important; }
-  #conversejs .ml-lg-0,
-  #conversejs .mx-lg-0 {
-    margin-left: 0 !important; }
-  #conversejs .m-lg-1 {
-    margin: 0.25rem !important; }
-  #conversejs .mt-lg-1,
-  #conversejs .my-lg-1 {
-    margin-top: 0.25rem !important; }
-  #conversejs .mr-lg-1,
-  #conversejs .mx-lg-1 {
-    margin-right: 0.25rem !important; }
-  #conversejs .mb-lg-1,
-  #conversejs .my-lg-1 {
-    margin-bottom: 0.25rem !important; }
-  #conversejs .ml-lg-1,
-  #conversejs .mx-lg-1 {
-    margin-left: 0.25rem !important; }
-  #conversejs .m-lg-2 {
-    margin: 0.5rem !important; }
-  #conversejs .mt-lg-2,
-  #conversejs .my-lg-2 {
-    margin-top: 0.5rem !important; }
-  #conversejs .mr-lg-2,
-  #conversejs .mx-lg-2 {
-    margin-right: 0.5rem !important; }
-  #conversejs .mb-lg-2,
-  #conversejs .my-lg-2 {
-    margin-bottom: 0.5rem !important; }
-  #conversejs .ml-lg-2,
-  #conversejs .mx-lg-2 {
-    margin-left: 0.5rem !important; }
-  #conversejs .m-lg-3 {
-    margin: 1rem !important; }
-  #conversejs .mt-lg-3,
-  #conversejs .my-lg-3 {
-    margin-top: 1rem !important; }
-  #conversejs .mr-lg-3,
-  #conversejs .mx-lg-3 {
-    margin-right: 1rem !important; }
-  #conversejs .mb-lg-3,
-  #conversejs .my-lg-3 {
-    margin-bottom: 1rem !important; }
-  #conversejs .ml-lg-3,
-  #conversejs .mx-lg-3 {
-    margin-left: 1rem !important; }
-  #conversejs .m-lg-4 {
-    margin: 1.5rem !important; }
-  #conversejs .mt-lg-4,
-  #conversejs .my-lg-4 {
-    margin-top: 1.5rem !important; }
-  #conversejs .mr-lg-4,
-  #conversejs .mx-lg-4 {
-    margin-right: 1.5rem !important; }
-  #conversejs .mb-lg-4,
-  #conversejs .my-lg-4 {
-    margin-bottom: 1.5rem !important; }
-  #conversejs .ml-lg-4,
-  #conversejs .mx-lg-4 {
-    margin-left: 1.5rem !important; }
-  #conversejs .m-lg-5 {
-    margin: 3rem !important; }
-  #conversejs .mt-lg-5,
-  #conversejs .my-lg-5 {
-    margin-top: 3rem !important; }
-  #conversejs .mr-lg-5,
-  #conversejs .mx-lg-5 {
-    margin-right: 3rem !important; }
-  #conversejs .mb-lg-5,
-  #conversejs .my-lg-5 {
-    margin-bottom: 3rem !important; }
-  #conversejs .ml-lg-5,
-  #conversejs .mx-lg-5 {
-    margin-left: 3rem !important; }
-  #conversejs .p-lg-0 {
-    padding: 0 !important; }
-  #conversejs .pt-lg-0,
-  #conversejs .py-lg-0 {
-    padding-top: 0 !important; }
-  #conversejs .pr-lg-0,
-  #conversejs .px-lg-0 {
-    padding-right: 0 !important; }
-  #conversejs .pb-lg-0,
-  #conversejs .py-lg-0 {
-    padding-bottom: 0 !important; }
-  #conversejs .pl-lg-0,
-  #conversejs .px-lg-0 {
-    padding-left: 0 !important; }
-  #conversejs .p-lg-1 {
-    padding: 0.25rem !important; }
-  #conversejs .pt-lg-1,
-  #conversejs .py-lg-1 {
-    padding-top: 0.25rem !important; }
-  #conversejs .pr-lg-1,
-  #conversejs .px-lg-1 {
-    padding-right: 0.25rem !important; }
-  #conversejs .pb-lg-1,
-  #conversejs .py-lg-1 {
-    padding-bottom: 0.25rem !important; }
-  #conversejs .pl-lg-1,
-  #conversejs .px-lg-1 {
-    padding-left: 0.25rem !important; }
-  #conversejs .p-lg-2 {
-    padding: 0.5rem !important; }
-  #conversejs .pt-lg-2,
-  #conversejs .py-lg-2 {
-    padding-top: 0.5rem !important; }
-  #conversejs .pr-lg-2,
-  #conversejs .px-lg-2 {
-    padding-right: 0.5rem !important; }
-  #conversejs .pb-lg-2,
-  #conversejs .py-lg-2 {
-    padding-bottom: 0.5rem !important; }
-  #conversejs .pl-lg-2,
-  #conversejs .px-lg-2 {
-    padding-left: 0.5rem !important; }
-  #conversejs .p-lg-3 {
-    padding: 1rem !important; }
-  #conversejs .pt-lg-3,
-  #conversejs .py-lg-3 {
-    padding-top: 1rem !important; }
-  #conversejs .pr-lg-3,
-  #conversejs .px-lg-3 {
-    padding-right: 1rem !important; }
-  #conversejs .pb-lg-3,
-  #conversejs .py-lg-3 {
-    padding-bottom: 1rem !important; }
-  #conversejs .pl-lg-3,
-  #conversejs .px-lg-3 {
-    padding-left: 1rem !important; }
-  #conversejs .p-lg-4 {
-    padding: 1.5rem !important; }
-  #conversejs .pt-lg-4,
-  #conversejs .py-lg-4 {
-    padding-top: 1.5rem !important; }
-  #conversejs .pr-lg-4,
-  #conversejs .px-lg-4 {
-    padding-right: 1.5rem !important; }
-  #conversejs .pb-lg-4,
-  #conversejs .py-lg-4 {
-    padding-bottom: 1.5rem !important; }
-  #conversejs .pl-lg-4,
-  #conversejs .px-lg-4 {
-    padding-left: 1.5rem !important; }
-  #conversejs .p-lg-5 {
-    padding: 3rem !important; }
-  #conversejs .pt-lg-5,
-  #conversejs .py-lg-5 {
-    padding-top: 3rem !important; }
-  #conversejs .pr-lg-5,
-  #conversejs .px-lg-5 {
-    padding-right: 3rem !important; }
-  #conversejs .pb-lg-5,
-  #conversejs .py-lg-5 {
-    padding-bottom: 3rem !important; }
-  #conversejs .pl-lg-5,
-  #conversejs .px-lg-5 {
-    padding-left: 3rem !important; }
-  #conversejs .m-lg-auto {
-    margin: auto !important; }
-  #conversejs .mt-lg-auto,
-  #conversejs .my-lg-auto {
-    margin-top: auto !important; }
-  #conversejs .mr-lg-auto,
-  #conversejs .mx-lg-auto {
-    margin-right: auto !important; }
-  #conversejs .mb-lg-auto,
-  #conversejs .my-lg-auto {
-    margin-bottom: auto !important; }
-  #conversejs .ml-lg-auto,
-  #conversejs .mx-lg-auto {
-    margin-left: auto !important; } }
-@media (min-width: 1200px) {
-  #conversejs .m-xl-0 {
-    margin: 0 !important; }
-  #conversejs .mt-xl-0,
-  #conversejs .my-xl-0 {
-    margin-top: 0 !important; }
-  #conversejs .mr-xl-0,
-  #conversejs .mx-xl-0 {
-    margin-right: 0 !important; }
-  #conversejs .mb-xl-0,
-  #conversejs .my-xl-0 {
-    margin-bottom: 0 !important; }
-  #conversejs .ml-xl-0,
-  #conversejs .mx-xl-0 {
-    margin-left: 0 !important; }
-  #conversejs .m-xl-1 {
-    margin: 0.25rem !important; }
-  #conversejs .mt-xl-1,
-  #conversejs .my-xl-1 {
-    margin-top: 0.25rem !important; }
-  #conversejs .mr-xl-1,
-  #conversejs .mx-xl-1 {
-    margin-right: 0.25rem !important; }
-  #conversejs .mb-xl-1,
-  #conversejs .my-xl-1 {
-    margin-bottom: 0.25rem !important; }
-  #conversejs .ml-xl-1,
-  #conversejs .mx-xl-1 {
-    margin-left: 0.25rem !important; }
-  #conversejs .m-xl-2 {
-    margin: 0.5rem !important; }
-  #conversejs .mt-xl-2,
-  #conversejs .my-xl-2 {
-    margin-top: 0.5rem !important; }
-  #conversejs .mr-xl-2,
-  #conversejs .mx-xl-2 {
-    margin-right: 0.5rem !important; }
-  #conversejs .mb-xl-2,
-  #conversejs .my-xl-2 {
-    margin-bottom: 0.5rem !important; }
-  #conversejs .ml-xl-2,
-  #conversejs .mx-xl-2 {
-    margin-left: 0.5rem !important; }
-  #conversejs .m-xl-3 {
-    margin: 1rem !important; }
-  #conversejs .mt-xl-3,
-  #conversejs .my-xl-3 {
-    margin-top: 1rem !important; }
-  #conversejs .mr-xl-3,
-  #conversejs .mx-xl-3 {
-    margin-right: 1rem !important; }
-  #conversejs .mb-xl-3,
-  #conversejs .my-xl-3 {
-    margin-bottom: 1rem !important; }
-  #conversejs .ml-xl-3,
-  #conversejs .mx-xl-3 {
-    margin-left: 1rem !important; }
-  #conversejs .m-xl-4 {
-    margin: 1.5rem !important; }
-  #conversejs .mt-xl-4,
-  #conversejs .my-xl-4 {
-    margin-top: 1.5rem !important; }
-  #conversejs .mr-xl-4,
-  #conversejs .mx-xl-4 {
-    margin-right: 1.5rem !important; }
-  #conversejs .mb-xl-4,
-  #conversejs .my-xl-4 {
-    margin-bottom: 1.5rem !important; }
-  #conversejs .ml-xl-4,
-  #conversejs .mx-xl-4 {
-    margin-left: 1.5rem !important; }
-  #conversejs .m-xl-5 {
-    margin: 3rem !important; }
-  #conversejs .mt-xl-5,
-  #conversejs .my-xl-5 {
-    margin-top: 3rem !important; }
-  #conversejs .mr-xl-5,
-  #conversejs .mx-xl-5 {
-    margin-right: 3rem !important; }
-  #conversejs .mb-xl-5,
-  #conversejs .my-xl-5 {
-    margin-bottom: 3rem !important; }
-  #conversejs .ml-xl-5,
-  #conversejs .mx-xl-5 {
-    margin-left: 3rem !important; }
-  #conversejs .p-xl-0 {
-    padding: 0 !important; }
-  #conversejs .pt-xl-0,
-  #conversejs .py-xl-0 {
-    padding-top: 0 !important; }
-  #conversejs .pr-xl-0,
-  #conversejs .px-xl-0 {
-    padding-right: 0 !important; }
-  #conversejs .pb-xl-0,
-  #conversejs .py-xl-0 {
-    padding-bottom: 0 !important; }
-  #conversejs .pl-xl-0,
-  #conversejs .px-xl-0 {
-    padding-left: 0 !important; }
-  #conversejs .p-xl-1 {
-    padding: 0.25rem !important; }
-  #conversejs .pt-xl-1,
-  #conversejs .py-xl-1 {
-    padding-top: 0.25rem !important; }
-  #conversejs .pr-xl-1,
-  #conversejs .px-xl-1 {
-    padding-right: 0.25rem !important; }
-  #conversejs .pb-xl-1,
-  #conversejs .py-xl-1 {
-    padding-bottom: 0.25rem !important; }
-  #conversejs .pl-xl-1,
-  #conversejs .px-xl-1 {
-    padding-left: 0.25rem !important; }
-  #conversejs .p-xl-2 {
-    padding: 0.5rem !important; }
-  #conversejs .pt-xl-2,
-  #conversejs .py-xl-2 {
-    padding-top: 0.5rem !important; }
-  #conversejs .pr-xl-2,
-  #conversejs .px-xl-2 {
-    padding-right: 0.5rem !important; }
-  #conversejs .pb-xl-2,
-  #conversejs .py-xl-2 {
-    padding-bottom: 0.5rem !important; }
-  #conversejs .pl-xl-2,
-  #conversejs .px-xl-2 {
-    padding-left: 0.5rem !important; }
-  #conversejs .p-xl-3 {
-    padding: 1rem !important; }
-  #conversejs .pt-xl-3,
-  #conversejs .py-xl-3 {
-    padding-top: 1rem !important; }
-  #conversejs .pr-xl-3,
-  #conversejs .px-xl-3 {
-    padding-right: 1rem !important; }
-  #conversejs .pb-xl-3,
-  #conversejs .py-xl-3 {
-    padding-bottom: 1rem !important; }
-  #conversejs .pl-xl-3,
-  #conversejs .px-xl-3 {
-    padding-left: 1rem !important; }
-  #conversejs .p-xl-4 {
-    padding: 1.5rem !important; }
-  #conversejs .pt-xl-4,
-  #conversejs .py-xl-4 {
-    padding-top: 1.5rem !important; }
-  #conversejs .pr-xl-4,
-  #conversejs .px-xl-4 {
-    padding-right: 1.5rem !important; }
-  #conversejs .pb-xl-4,
-  #conversejs .py-xl-4 {
-    padding-bottom: 1.5rem !important; }
-  #conversejs .pl-xl-4,
-  #conversejs .px-xl-4 {
-    padding-left: 1.5rem !important; }
-  #conversejs .p-xl-5 {
-    padding: 3rem !important; }
-  #conversejs .pt-xl-5,
-  #conversejs .py-xl-5 {
-    padding-top: 3rem !important; }
-  #conversejs .pr-xl-5,
-  #conversejs .px-xl-5 {
-    padding-right: 3rem !important; }
-  #conversejs .pb-xl-5,
-  #conversejs .py-xl-5 {
-    padding-bottom: 3rem !important; }
-  #conversejs .pl-xl-5,
-  #conversejs .px-xl-5 {
-    padding-left: 3rem !important; }
-  #conversejs .m-xl-auto {
-    margin: auto !important; }
-  #conversejs .mt-xl-auto,
-  #conversejs .my-xl-auto {
-    margin-top: auto !important; }
-  #conversejs .mr-xl-auto,
-  #conversejs .mx-xl-auto {
-    margin-right: auto !important; }
-  #conversejs .mb-xl-auto,
-  #conversejs .my-xl-auto {
-    margin-bottom: auto !important; }
-  #conversejs .ml-xl-auto,
-  #conversejs .mx-xl-auto {
-    margin-left: auto !important; } }
-#conversejs .text-justify {
-  text-align: justify !important; }
-#conversejs .text-nowrap {
-  white-space: nowrap !important; }
-#conversejs .text-truncate {
-  overflow: hidden;
-  text-overflow: ellipsis;
-  white-space: nowrap; }
-#conversejs .text-left {
-  text-align: left !important; }
-#conversejs .text-right {
-  text-align: right !important; }
-#conversejs .text-center {
-  text-align: center !important; }
-@media (min-width: 576px) {
-  #conversejs .text-sm-left {
-    text-align: left !important; }
-  #conversejs .text-sm-right {
-    text-align: right !important; }
-  #conversejs .text-sm-center {
-    text-align: center !important; } }
-@media (min-width: 768px) {
-  #conversejs .text-md-left {
-    text-align: left !important; }
-  #conversejs .text-md-right {
-    text-align: right !important; }
-  #conversejs .text-md-center {
-    text-align: center !important; } }
-@media (min-width: 992px) {
-  #conversejs .text-lg-left {
-    text-align: left !important; }
-  #conversejs .text-lg-right {
-    text-align: right !important; }
-  #conversejs .text-lg-center {
-    text-align: center !important; } }
-@media (min-width: 1200px) {
-  #conversejs .text-xl-left {
-    text-align: left !important; }
-  #conversejs .text-xl-right {
-    text-align: right !important; }
-  #conversejs .text-xl-center {
-    text-align: center !important; } }
-#conversejs .text-lowercase {
-  text-transform: lowercase !important; }
-#conversejs .text-uppercase {
-  text-transform: uppercase !important; }
-#conversejs .text-capitalize {
-  text-transform: capitalize !important; }
-#conversejs .font-weight-light {
-  font-weight: 300 !important; }
-#conversejs .font-weight-normal {
-  font-weight: 400 !important; }
-#conversejs .font-weight-bold {
-  font-weight: 700 !important; }
-#conversejs .font-italic {
-  font-style: italic !important; }
-#conversejs .text-white {
-  color: #fff !important; }
-#conversejs .text-primary {
-  color: #387592 !important; }
-#conversejs a.text-primary:hover, #conversejs a.text-primary:focus {
-  color: #2a576d !important; }
-#conversejs .text-secondary {
-  color: #6c757d !important; }
-#conversejs a.text-secondary:hover, #conversejs a.text-secondary:focus {
-  color: #545b62 !important; }
-#conversejs .text-success {
-  color: #3AA569 !important; }
-#conversejs a.text-success:hover, #conversejs a.text-success:focus {
-  color: #2d7f51 !important; }
-#conversejs .text-info {
-  color: #17a2b8 !important; }
-#conversejs a.text-info:hover, #conversejs a.text-info:focus {
-  color: #117a8b !important; }
-#conversejs .text-warning {
-  color: #ffc107 !important; }
-#conversejs a.text-warning:hover, #conversejs a.text-warning:focus {
-  color: #d39e00 !important; }
-#conversejs .text-danger {
-  color: #E77051 !important; }
-#conversejs a.text-danger:hover, #conversejs a.text-danger:focus {
-  color: #e14b24 !important; }
-#conversejs .text-light {
-  color: #f8f9fa !important; }
-#conversejs a.text-light:hover, #conversejs a.text-light:focus {
-  color: #dae0e5 !important; }
-#conversejs .text-dark {
-  color: #343a40 !important; }
-#conversejs a.text-dark:hover, #conversejs a.text-dark:focus {
-  color: #1d2124 !important; }
-#conversejs .text-muted {
-  color: #6c757d !important; }
-#conversejs .text-hide {
-  font: 0/0 a;
-  color: transparent;
-  text-shadow: none;
-  background-color: transparent;
-  border: 0; }
-#conversejs .visible {
-  visibility: visible !important; }
-#conversejs .invisible {
-  visibility: hidden !important; }
-
-body.reset {
-  margin: 0; }
-
-@font-face {
-  font-family: 'Converse-js';
-  src: url("../fonticons/fonts/icomoon.eot?wvi0ht");
-  src: url("../fonticons/fonts/icomoon.eot?wvi0ht#iefix") format("embedded-opentype"), url("../fonticons/fonts/icomoon.ttf?wvi0ht") format("truetype"), url("../fonticons/fonts/icomoon.woff?wvi0ht") format("woff"), url("../fonticons/fonts/icomoon.svg?wvi0ht#icomoon") format("svg");
-  font-weight: normal;
-  font-style: normal; }
-.icon-conversejs {
-  padding-right: 0.5em;
-  font-family: 'Converse-js';
-  font-size: 80%;
-  speak: none;
-  font-style: normal;
-  font-weight: normal;
-  font-variant: normal;
-  text-transform: none;
-  line-height: 1;
-  /* Better Font Rendering =========== */
-  -webkit-font-smoothing: antialiased;
-  -moz-osx-font-smoothing: grayscale; }
-
-.icon-conversejs:before {
-  content: "\e600"; }
-
-.converse-brand-heading {
-  font-family: "Century Gothic", futura, "URW Gothic L", Verdana, sans-serif;
-  font-size: 6em;
-  font-weight: normal; }
-  .converse-brand-heading .icon-conversejs {
-    font-size: 60%; }
-
-#conversejs {
-  bottom: 0;
-  height: 100%;
-  position: fixed;
-  padding-left: env(safe-area-inset-left);
-  padding-right: env(safe-area-inset-right);
-  color: #666;
-  font-family: "Helvetica", "Arial", sans-serif;
-  font-size: 16px;
-  direction: ltr;
-  z-index: 1031; }
-  #conversejs .brand-heading {
-    font-family: "Century Gothic", futura, "URW Gothic L", Verdana, sans-serif; }
-    #conversejs .brand-heading .icon-conversejs {
-      font-size: 80%; }
-  #conversejs .popover {
-    position: fixed; }
-  #conversejs .converse-chatboxes {
-    z-index: 1031;
-    position: fixed;
-    bottom: 0;
-    height: 2.7rem;
-    right: 0; }
-  #conversejs ::-webkit-input-placeholder {
-    /* Chrome/Opera/Safari */
-    color: #A8ABA1; }
-  #conversejs ::-moz-placeholder {
-    /* Firefox 19+ */
-    color: #A8ABA1; }
-  #conversejs :-ms-input-placeholder {
-    /* IE 10+ */
-    color: #A8ABA1; }
-  #conversejs :-moz-placeholder {
-    /* Firefox 18- */
-    color: #A8ABA1; }
-  #conversejs ::placeholder {
-    color: #A8ABA1; }
-  #conversejs ::selection {
-    background-color: #DCF9F6; }
-  #conversejs ::-moz-selection {
-    background-color: #DCF9F6; }
-  @media screen and (max-width: 480px) {
-    #conversejs {
-      margin: 0;
-      right: 10px;
-      left: 10px;
-      bottom: 5px; } }
-  @media screen and (max-height: 450px) {
-    #conversejs {
-      margin: 0;
-      right: 10px;
-      left: 10px;
-      bottom: 5px; } }
-  #conversejs ul li {
-    height: auto; }
-  #conversejs div, #conversejs span, #conversejs h1, #conversejs h2, #conversejs h3, #conversejs h4, #conversejs h5, #conversejs h6, #conversejs p, #conversejs blockquote,
-  #conversejs pre, #conversejs a, #conversejs em, #conversejs img, #conversejs strong, #conversejs dl, #conversejs dt, #conversejs dd, #conversejs ol, #conversejs ul, #conversejs li,
-  #conversejs fieldset, #conversejs form, #conversejs legend, #conversejs table, #conversejs caption, #conversejs tbody,
-  #conversejs tfoot, #conversejs thead, #conversejs tr, #conversejs th, #conversejs td, #conversejs article, #conversejs aside, #conversejs canvas, #conversejs details,
-  #conversejs embed, #conversejs figure, #conversejs figcaption, #conversejs footer, #conversejs header, #conversejs hgroup, #conversejs menu,
-  #conversejs nav, #conversejs output, #conversejs ruby, #conversejs section, #conversejs summary, #conversejs time, #conversejs mark, #conversejs audio, #conversejs video {
-    margin: 0;
-    padding: 0;
-    border: 0;
-    font: inherit;
-    vertical-align: baseline; }
-  #conversejs textarea,
-  #conversejs input[type=submit], #conversejs input[type=button],
-  #conversejs input[type=text], #conversejs input[type=password],
-  #conversejs button {
-    font-size: 16px;
-    padding: 0.25em;
-    min-height: 0; }
-  #conversejs strong {
-    font-weight: 700; }
-  #conversejs ol, #conversejs ul {
-    list-style: none; }
-  #conversejs li {
-    height: 10px; }
-  #conversejs ul, #conversejs ol, #conversejs dl {
-    font: inherit;
-    margin: 0; }
-  #conversejs a, #conversejs a:visited, #conversejs a:hover, #conversejs a:not([href]):not([tabindex]) {
-    text-decoration: none;
-    color: #578EA9;
-    text-shadow: none; }
-    #conversejs a.fa, #conversejs a:visited.fa, #conversejs a:hover.fa, #conversejs a:not([href]):not([tabindex]).fa {
-      color: #A8ABA1; }
-      #conversejs a.fa:hover, #conversejs a:visited.fa:hover, #conversejs a:hover.fa:hover, #conversejs a:not([href]):not([tabindex]).fa:hover {
-        color: #818479; }
-  #conversejs canvas {
-    border-radius: 4px; }
-  #conversejs .fa {
-    color: #A8ABA1; }
-  #conversejs .fa:hover {
-    color: #818479; }
-  #conversejs .modal {
-    background-color: rgba(0, 0, 0, 0.4); }
-    #conversejs .modal .modal-body p {
-      padding: 0.25rem 0; }
-  #conversejs .selected {
-    color: #578EA9 !important; }
-  #conversejs .circle {
-    border-radius: 50%; }
-  #conversejs .sidebar {
-    display: none;
-    width: 50px;
-    height: 100vh;
-    padding: 1rem 0;
-    background-color: #578EA9;
-    color: white;
-    text-align: center; }
-    #conversejs .sidebar .chatbox-btn {
-      float: none;
-      margin: 0;
-      font-size: 1.35em; }
-      #conversejs .sidebar .chatbox-btn.fa-vcard {
-        margin-top: 1em; }
-    #conversejs .sidebar .bottom {
-      position: absolute;
-      bottom: 1em; }
-  #conversejs .badge {
-    line-height: 1;
-    font-weight: normal;
-    font-size: 90%; }
-  #conversejs .fa {
-    font: normal normal normal 14px/1 ConverseFontAwesome;
-    display: inline-block;
-    font-size: inherit;
-    text-rendering: auto;
-    -webkit-font-smoothing: antialiased;
-    -moz-osx-font-smoothing: grayscale; }
-  #conversejs .btn {
-    font-family: "Century Gothic", futura, "URW Gothic L", Verdana, sans-serif;
-    font-weight: normal;
-    color: #fff; }
-    #conversejs .btn .fa {
-      color: #fff;
-      margin-right: 0.5em; }
-  #conversejs .no-text-select {
-    -webkit-touch-callout: none;
-    -webkit-user-select: none;
-    -moz-user-select: none;
-    -ms-user-select: none;
-    user-select: none; }
-@keyframes colorchange-chatmessage {
-  0% {
-    background-color: #8dd8ae; }
-  25% {
-    background-color: rgba(141, 216, 174, 0.75); }
-  50% {
-    background-color: rgba(141, 216, 174, 0.5); }
-  75% {
-    background-color: rgba(141, 216, 174, 0.25); }
-  100% {
-    background-color: transparent; } }
-@-webkit-keyframes colorchange-chatmessage {
-  0% {
-    background-color: #8dd8ae; }
-  25% {
-    background-color: rgba(141, 216, 174, 0.75); }
-  50% {
-    background-color: rgba(141, 216, 174, 0.5); }
-  75% {
-    background-color: rgba(141, 216, 174, 0.25); }
-  100% {
-    background-color: transparent; } }
-@keyframes colorchange-chatmessage-muc {
-  0% {
-    background-color: #ffb5a2; }
-  25% {
-    background-color: rgba(255, 181, 162, 0.75); }
-  50% {
-    background-color: rgba(255, 181, 162, 0.5); }
-  75% {
-    background-color: rgba(255, 181, 162, 0.25); }
-  100% {
-    background-color: transparent; } }
-@-webkit-keyframes colorchange-chatmessage-muc {
-  0% {
-    background-color: #ffb5a2; }
-  25% {
-    background-color: rgba(255, 181, 162, 0.75); }
-  50% {
-    background-color: rgba(255, 181, 162, 0.5); }
-  75% {
-    background-color: rgba(255, 181, 162, 0.25); }
-  100% {
-    background-color: transparent; } }
-@keyframes fadein {
-  0% {
-    opacity: 0; }
-  100% {
-    opacity: 1; } }
-@-webkit-keyframes fadein {
-  0% {
-    opacity: 0; }
-  100% {
-    opacity: 1; } }
-  #conversejs .fade-in {
-    opacity: 0;
-    /* make things invisible upon start */
-    -webkit-animation-name: fadein;
-    -moz-animation-name: fadein;
-    animation-name: fadein;
-    -webkit-animation-fill-mode: forwards;
-    -moz-animation-fill-mode: forwards;
-    animation-fill-mode: forwards;
-    -webkit-animation-duration: 0.75s;
-    -moz-animation-duration: 0.75s;
-    animation-duration: 0.75s;
-    -webkit-animation-timing-function: ease;
-    -moz-animation-timing-function: ease;
-    animation-timing-function: ease; }
-  #conversejs .visible {
-    opacity: 0;
-    /* make things invisible upon start */
-    -webkit-animation-name: fadein;
-    -moz-animation-name: fadein;
-    animation-name: fadein;
-    -webkit-animation-fill-mode: forwards;
-    -moz-animation-fill-mode: forwards;
-    animation-fill-mode: forwards;
-    -webkit-animation-duration: 500ms;
-    -moz-animation-duration: 500ms;
-    animation-duration: 500ms;
-    -webkit-animation-timing-function: ease;
-    -moz-animation-timing-function: ease;
-    animation-timing-function: ease; }
-  #conversejs .hidden {
-    opacity: 0 !important;
-    display: none !important; }
-  #conversejs .collapsed {
-    height: 0 !important;
-    overflow: hidden !important;
-    padding: 0 !important; }
-  #conversejs .locked {
-    padding-right: 22px; }
-@-webkit-keyframes spin {
-  from {
-    -webkit-transform: rotate(0deg); }
-  to {
-    -webkit-transform: rotate(359deg); } }
-@-moz-keyframes spin {
-  from {
-    -moz-transform: rotate(0deg); }
-  to {
-    -moz-transform: rotate(359deg); } }
-@keyframes spin {
-  from {
-    -webkit-transform: rotate(0deg);
-    -moz-transform: rotate(0deg);
-    -ms-transform: rotate(0deg);
-    -o-transform: rotate(0deg);
-    transform: rotate(0deg); }
-  to {
-    -webkit-transform: rotate(359deg);
-    -moz-transform: rotate(359deg);
-    -ms-transform: rotate(359deg);
-    -o-transform: rotate(359deg);
-    transform: rotate(359deg); } }
-  #conversejs .spinner {
-    -webkit-animation: spin 2s infinite, linear;
-    -moz-animation: spin 2s infinite, linear;
-    animation: spin 2s infinite, linear;
-    display: block;
-    text-align: center;
-    margin: 2em;
-    font-size: 24px; }
-  #conversejs .left {
-    float: left; }
-  #conversejs .right {
-    float: right; }
-  #conversejs .centered {
-    text-align: center;
-    display: block;
-    margin: auto; }
-  #conversejs .hor_centered {
-    text-align: center;
-    display: block;
-    margin: 0 auto;
-    clear: both; }
-  #conversejs .error {
-    color: #A53214; }
-  #conversejs .info {
-    color: #1E9652; }
-  #conversejs .reg-feedback {
-    font-size: 85%;
-    margin-bottom: 1em; }
-  #conversejs .reg-feedback,
-  #conversejs #converse-login .conn-feedback {
-    display: block;
-    text-align: center;
-    width: 100%; }
-  #conversejs .avatar {
-    border-radius: 10%;
-    border: 1px solid lightgrey; }
-  #conversejs .activated {
-    display: block !important; }
-  #conversejs .button-primary {
-    color: white;
-    background-color: #E7A151; }
-  #conversejs .button-secondary {
-    color: white;
-    background-color: #387592; }
-  #conversejs .button-cancel {
-    color: white;
-    background-color: #666; }
-  #conversejs .chat-textarea-chatbox-selected {
-    border: 1px solid #578308;
-    margin: 0; }
-  #conversejs .chat-textarea-chatroom-selected {
-    border: 2px solid #578EA9;
-    margin: 0; }
-
-@media screen and (max-width: 575px) {
-  body .converse-brand-heading {
-    font-size: 3.75em; }
-
-  #conversejs:not(.converse-embedded) .chatbox .chat-body {
-    border-radius: 4px; }
-  #conversejs:not(.converse-embedded) .flyout {
-    border-radius: 4px; } }
-@media screen and (min-width: 576px) {
-  #conversejs .offset-sm-2 {
-    margin-left: 16.666667%; } }
-@media screen and (min-width: 768px) {
-  #conversejs .offset-md-2 {
-    margin-left: 16.666667%; }
-
-  #conversejs .offset-md-3 {
-    margin-left: 25%; } }
-@media screen and (min-width: 992px) {
-  #conversejs .offset-lg-2 {
-    margin-left: 16.666667%; }
-
-  #conversejs .offset-lg-3 {
-    margin-left: 25%; } }
-@media screen and (min-width: 1200px) {
-  #conversejs .offset-xl-2 {
-    margin-left: 16.666667%; } }
-@media screen and (max-height: 450px) {
-  #conversejs {
-    left: 0; } }
-body {
-  font-family: "Lora", "Helvetica Neue", Helvetica, Arial, sans-serif;
-  color: #ffffff;
-  background-color: #578EA9; }
-  body .brand-heading {
-    font-size: 600%;
-    margin-left: -10%; }
-    body .brand-heading.fade-in {
-      opacity: 0;
-      /* make things invisible upon start */
-      -webkit-animation-name: fadein;
-      -moz-animation-name: fadein;
-      animation-name: fadein;
-      -webkit-animation-fill-mode: forwards;
-      -moz-animation-fill-mode: forwards;
-      animation-fill-mode: forwards;
-      -webkit-animation-duration: 0.75s;
-      -moz-animation-duration: 0.75s;
-      animation-duration: 0.75s;
-      -webkit-animation-timing-function: ease;
-      -moz-animation-timing-function: ease;
-      animation-timing-function: ease;
-      -webkit-animation-delay: 2s;
-      -moz-animation-delay: 2s;
-      animation-delay: 2s; }
-    body .brand-heading .icon-conversejs {
-      font-size: 88%; }
-  body div.content {
-    height: 100vh;
-    width: 100vw;
-    position: fixed;
-    background-color: #578EA9; }
-    body div.content .inner-content {
-      text-align: center;
-      padding: 7%;
-      padding-left: -webkit-calc(5% + 250px);
-      padding-left: calc(5% + 250px); }
-      body div.content .inner-content p.no-chats {
-        padding-right: 10%;
-        font-size: 120%; }
-
-#conversejs.fullscreen .converse-chatboxes {
-  width: 100vw;
-  right: 15px; }
-
-#conversejs form .form-group {
-  margin-bottom: 2em; }
-#conversejs form .form-check-label {
-  margin-top: 0.3rem; }
-#conversejs form .form-control::-webkit-input-placeholder {
-  /* Chrome/Opera/Safari */
-  color: #A8ABA1; }
-#conversejs form .form-control::-moz-placeholder {
-  /* Firefox 19+ */
-  color: #A8ABA1; }
-#conversejs form .form-control:-ms-input-placeholder {
-  /* IE 10+ */
-  color: #A8ABA1; }
-#conversejs form .form-control:-moz-placeholder {
-  /* Firefox 18- */
-  color: #A8ABA1; }
-#conversejs form .form-control::placeholder {
-  color: #A8ABA1; }
-#conversejs form .clear-input {
-  position: absolute;
-  right: 0.2em;
-  cursor: pointer;
-  font-size: 0.75rem; }
-#conversejs form#converse-register legend, #conversejs form#converse-login legend {
-  width: 100%;
-  text-align: center;
-  margin: 0 auto 0.5em auto; }
-#conversejs form#converse-register fieldset.buttons, #conversejs form#converse-login fieldset.buttons {
-  text-align: center; }
-#conversejs form#converse-register .login-anon, #conversejs form#converse-login .login-anon {
-  height: auto;
-  white-space: normal; }
-#conversejs form#converse-register .save-submit, #conversejs form#converse-login .save-submit {
-  color: #3AA569; }
-#conversejs form#converse-register .form-url, #conversejs form#converse-login .form-url {
-  display: block;
-  font-weight: normal;
-  margin: 1em 0; }
-#conversejs form.converse-form {
-  background: white;
-  padding: 1.5em; }
-  #conversejs form.converse-form legend {
-    color: #666;
-    font-size: 125%;
-    margin-bottom: 1.5em; }
-  #conversejs form.converse-form select,
-  #conversejs form.converse-form input[type=password],
-  #conversejs form.converse-form input[type=number],
-  #conversejs form.converse-form input[type=text] {
-    min-width: 50%; }
-  #conversejs form.converse-form input[type=text],
-  #conversejs form.converse-form input[type=password],
-  #conversejs form.converse-form input[type=number],
-  #conversejs form.converse-form input[type=button],
-  #conversejs form.converse-form input[type=submit] {
-    padding: 0.5em; }
-  #conversejs form.converse-form input[type=button],
-  #conversejs form.converse-form input[type=submit] {
-    padding-left: 1em;
-    padding-right: 1em;
-    margin: 0.5em 0;
-    border: none; }
-  #conversejs form.converse-form input.error {
-    border: 1px solid #A53214;
-    color: #666; }
-  #conversejs form.converse-form .text-muted {
-    color: #A8ABA1 !important;
-    font-size: 85%;
-    padding-top: 0.5em; }
-    #conversejs form.converse-form .text-muted a {
-      color: #79a5ba; }
-    #conversejs form.converse-form .text-muted.error {
-      color: #A53214; }
-#conversejs form.converse-centered-form {
-  text-align: center; }
-
-#conversejs #user-profile-modal label {
-  font-weight: bold; }
-
-#conversejs .flyout {
-  border-radius: 4px;
-  bottom: 6px;
-  position: absolute; }
-  @media screen and (max-height: 450px) {
-    #conversejs .flyout {
-      border-radius: 0; } }
-  @media screen and (max-width: 480px) {
-    #conversejs .flyout {
-      border-radius: 0; } }
-  @media screen and (max-height: 450px) {
-    #conversejs .flyout {
-      bottom: 0; } }
-  @media screen and (max-width: 480px) {
-    #conversejs .flyout {
-      bottom: 0; } }
-#conversejs .chatbox-btn {
-  border-radius: 25%;
-  border: none;
-  cursor: pointer;
-  font-size: 14px;
-  margin: 0 0.2em;
-  padding: 0 0 0 0.5em;
-  text-decoration: none; }
-  #conversejs .chatbox-btn:active {
-    position: relative;
-    top: 1px; }
-#conversejs .chat-head {
-  flex-wrap: nowrap;
-  color: #ffffff;
-  font-size: 100%;
-  height: 62px;
-  margin: 0;
-  padding: 0.5em;
-  position: relative; }
-  #conversejs .chat-head.chat-head-chatbox {
-    background-color: #3AA569; }
-  #conversejs .chat-head .avatar {
-    height: 36px;
-    width: 36px;
-    margin-right: 0.5em; }
-  #conversejs .chat-head .chatbox-buttons {
-    flex-direction: row-reverse;
-    position: relative;
-    width: 100%;
-    min-height: 1px;
-    padding-right: 15px;
-    padding-left: 15px;
-    flex: 0 0 25%;
-    max-width: 25%;
-    padding: 0; }
-  #conversejs .chat-head .user-custom-message {
-    color: white;
-    font-size: 75%;
-    font-style: italic;
-    overflow: hidden;
-    text-overflow: ellipsis;
-    white-space: nowrap;
-    margin: 0;
-    padding-top: 0.2em; }
-  #conversejs .chat-head a.chatbox-btn.fa, #conversejs .chat-head a:visited.chatbox-btn.fa, #conversejs .chat-head a:hover.chatbox-btn.fa, #conversejs .chat-head a:not([href]):not([tabindex]).chatbox-btn.fa {
-    color: white; }
-    #conversejs .chat-head a.chatbox-btn.fa.button-on:before, #conversejs .chat-head a:visited.chatbox-btn.fa.button-on:before, #conversejs .chat-head a:hover.chatbox-btn.fa.button-on:before, #conversejs .chat-head a:not([href]):not([tabindex]).chatbox-btn.fa.button-on:before {
-      padding: 0.2em;
-      background-color: white;
-      color: #3AA569; }
-  #conversejs .chat-head .chatbox-btn {
-    color: white; }
-    #conversejs .chat-head .chatbox-btn.fa {
-      color: white; }
-    #conversejs .chat-head .chatbox-btn:active {
-      position: relative;
-      top: 1px; }
-    #conversejs .chat-head .chatbox-btn.button-on:before {
-      border-radius: 5%;
-      background-color: white;
-      color: #3AA569; }
-#conversejs .chatbox {
-  text-align: left;
-  margin: 0 0.5em; }
-  @media screen and (max-height: 450px) {
-    #conversejs .chatbox {
-      margin: 0;
-      width: 100%; } }
-  @media screen and (max-width: 480px) {
-    #conversejs .chatbox {
-      margin: 0;
-      width: 100%; } }
-  #conversejs .chatbox .box-flyout {
-    display: flex;
-    flex-direction: column;
-    justify-content: space-between;
-    background-color: #3AA569;
-    box-shadow: 1px 3px 5px 3px rgba(0, 0, 0, 0.4);
-    height: 100%;
-    min-height: 50%;
-    z-index: 1;
-    overflow-y: scroll;
-    width: 100%; }
-    @media screen and (max-height: 450px) {
-      #conversejs .chatbox .box-flyout {
-        height: 400px;
-        width: 100%;
-        height: 100vh; } }
-    @media screen and (max-width: 480px) {
-      #conversejs .chatbox .box-flyout {
-        height: 400px;
-        width: 100%;
-        height: 100vh; } }
-  #conversejs .chatbox .chat-title {
-    font-family: "Century Gothic", futura, "URW Gothic L", Verdana, sans-serif;
-    color: white;
-    display: block;
-    line-height: 24px;
-    overflow: hidden;
-    text-overflow: ellipsis;
-    white-space: nowrap; }
-    #conversejs .chatbox .chat-title a {
-      color: white;
-      width: 100%; }
-  #conversejs .chatbox .chat-body {
-    display: flex;
-    flex-direction: column;
-    justify-content: space-between;
-    height: 100%;
-    background-color: #3AA569;
-    border-bottom-left-radius: 4px;
-    border-bottom-right-radius: 4px;
-    border-top: 0; }
-    @media screen and (max-height: 450px) {
-      #conversejs .chatbox .chat-body {
-        border-bottom-left-radius: 0;
-        border-bottom-right-radius: 0; } }
-    @media screen and (max-width: 480px) {
-      #conversejs .chatbox .chat-body {
-        border-bottom-left-radius: 0;
-        border-bottom-right-radius: 0; } }
-    #conversejs .chatbox .chat-body p {
-      color: #666;
-      font-size: 14px;
-      margin: 0;
-      padding: 5px; }
-  #conversejs .chatbox .new-msgs-indicator {
-    position: relative;
-    width: 100%;
-    cursor: pointer;
-    background-color: #3AA569;
-    color: #FCFDFD;
-    padding: 0.5em;
-    font-size: 0.9em;
-    text-align: center;
-    z-index: 20;
-    white-space: nowrap;
-    margin-bottom: 0.25em; }
-  #conversejs .chatbox .chat-content {
-    height: 100%;
-    font-size: 14px;
-    color: #666;
-    overflow-y: auto;
-    border: 0;
-    background-color: #ffffff;
-    line-height: 1.3em; }
-    #conversejs .chatbox .chat-content video {
-      width: 100%; }
-    #conversejs .chatbox .chat-content progress {
-      margin: 0.5em 0;
-      width: 100%; }
-  #conversejs .chatbox .chat-content-sendbutton {
-    height: calc(100% - 93px); }
-  #conversejs .chatbox .dropdown {
-    /* status dropdown styles */
-    background-color: #FCFDFD; }
-    #conversejs .chatbox .dropdown dd {
-      margin: 0;
-      padding: 0;
-      position: relative; }
-  #conversejs .chatbox .sendXMPPMessage {
-    -moz-background-clip: padding;
-    -webkit-background-clip: padding-box;
-    border-bottom-right-radius: 4px;
-    border-bottom-left-radius: 4px;
-    background-clip: padding-box;
-    background-color: white;
-    border: 0;
-    margin: 0;
-    padding: 0; }
-    @media screen and (max-height: 450px) {
-      #conversejs .chatbox .sendXMPPMessage {
-        width: 100%; } }
-    @media screen and (max-width: 480px) {
-      #conversejs .chatbox .sendXMPPMessage {
-        width: 100%; } }
-    #conversejs .chatbox .sendXMPPMessage .spoiler-hint {
-      width: 100%; }
-    #conversejs .chatbox .sendXMPPMessage .chat-textarea {
-      border-top-left-radius: 0;
-      border-top-right-radius: 0;
-      border-bottom-right-radius: 4px;
-      border-bottom-left-radius: 4px;
-      padding: 0.5em;
-      width: 100%;
-      border: none;
-      min-height: 60px;
-      max-height: 400px;
-      margin-bottom: -4px; }
-      #conversejs .chatbox .sendXMPPMessage .chat-textarea.spoiler {
-        height: 42px; }
-    #conversejs .chatbox .sendXMPPMessage .send-button {
-      position: absolute;
-      left: 3px;
-      width: -webkit-calc(100% - 6px);
-      width: calc(100% - 6px);
-      background-color: #3AA569;
-      color: white;
-      font-size: 80%;
-      height: 27px;
-      bottom: -30px; }
-    #conversejs .chatbox .sendXMPPMessage .chat-toolbar {
-      box-sizing: border-box;
-      margin: 0;
-      padding: 0.25em;
-      display: block;
-      border-top: 8px solid #3AA569;
-      background-color: white;
-      color: #3AA569; }
-      #conversejs .chatbox .sendXMPPMessage .chat-toolbar .fa, #conversejs .chatbox .sendXMPPMessage .chat-toolbar .fa:hover {
-        color: #3AA569;
-        font-size: 18px; }
-      #conversejs .chatbox .sendXMPPMessage .chat-toolbar .unencrypted a,
-      #conversejs .chatbox .sendXMPPMessage .chat-toolbar .unencrypted {
-        color: #666; }
-        #conversejs .chatbox .sendXMPPMessage .chat-toolbar .unencrypted a .toolbar-menu a,
-        #conversejs .chatbox .sendXMPPMessage .chat-toolbar .unencrypted .toolbar-menu a {
-          color: #578EA9; }
-      #conversejs .chatbox .sendXMPPMessage .chat-toolbar .unverified a,
-      #conversejs .chatbox .sendXMPPMessage .chat-toolbar .unverified {
-        color: #cf5300; }
-      #conversejs .chatbox .sendXMPPMessage .chat-toolbar .private a,
-      #conversejs .chatbox .sendXMPPMessage .chat-toolbar .private {
-        color: #4b7003; }
-      #conversejs .chatbox .sendXMPPMessage .chat-toolbar .toggle-occupants {
-        float: right; }
-      #conversejs .chatbox .sendXMPPMessage .chat-toolbar li {
-        cursor: pointer;
-        display: inline-block;
-        list-style: none;
-        padding: 0 0.5em; }
-        #conversejs .chatbox .sendXMPPMessage .chat-toolbar li:hover {
-          cursor: pointer; }
-        #conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu {
-          background-color: #fff;
-          bottom: 2rem;
-          box-shadow: -1px -1px 2px 0 rgba(0, 0, 0, 0.4);
-          margin-bottom: 0;
-          min-width: 20rem;
-          position: absolute;
-          right: 0;
-          top: auto;
-          z-index: 1000; }
-          #conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu.otr-menu {
-            left: -6em;
-            min-width: 15rem; }
-            #conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu.otr-menu.show {
-              display: flex;
-              flex-direction: column; }
-          #conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu a {
-            color: #578EA9; }
-          #conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu ul.emoji-picker {
-            height: 150px;
-            overflow: scroll;
-            padding: 0.5em; }
-          #conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu ul li {
-            margin-left: 0;
-            cursor: pointer;
-            list-style: none;
-            position: relative; }
-            #conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu ul li.insert-emoji {
-              padding: 0.2em; }
-              #conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu ul li.insert-emoji.picked {
-                background-color: #DCF9F6; }
-              #conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu ul li.insert-emoji:hover {
-                background-color: #DCF9F6; }
-              #conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu ul li.insert-emoji a {
-                font-size: 26px; }
-                #conversejs .chatbox .sendXMPPMessage .chat-toolbar li .toolbar-menu ul li.insert-emoji a:hover {
-                  color: #8f2831; }
-        #conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley a.toggle-smiley {
-          padding: 0; }
-        #conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar {
-          box-shadow: 0 -1px 1px 0 rgba(0, 0, 0, 0.4); }
-          #conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-category-picker {
-            padding-top: 0.5em; }
-            #conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-category-picker ul {
-              display: flex;
-              flex-direction: row;
-              justify-content: space-between; }
-          #conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-category-picker li,
-          #conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-skintone-picker li {
-            padding: 0.2em;
-            font-size: 26px; }
-            #conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-category-picker li:hover,
-            #conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-smiley .emoji-toolbar .emoji-skintone-picker li:hover {
-              background-color: #DCF9F6; }
-        #conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-otr ul {
-          z-index: 99; }
-          #conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-otr ul li {
-            display: block;
-            padding: 7px; }
-            #conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-otr ul li:hover {
-              background-color: #DCF9F6; }
-            #conversejs .chatbox .sendXMPPMessage .chat-toolbar li.toggle-otr ul li a {
-              display: block; }
-  #conversejs .chatbox .dragresize {
-    background: transparent;
-    border: 0;
-    margin: 0;
-    position: absolute;
-    top: 0;
-    z-index: 20; }
-    #conversejs .chatbox .dragresize-top {
-      cursor: n-resize;
-      height: 5px;
-      width: 100%; }
-    #conversejs .chatbox .dragresize-left {
-      cursor: w-resize;
-      width: 5px;
-      height: 100%;
-      left: 0; }
-    #conversejs .chatbox .dragresize-topleft {
-      cursor: nw-resize;
-      width: 15px;
-      height: 15px;
-      top: 0;
-      left: 0; }
-
-#conversejs.converse-fullscreen .chatbox-btn {
-  font-size: 16px; }
-#conversejs.converse-fullscreen .chat-head .chatbox-buttons {
-  flex: 0 0 25%;
-  max-width: 25%; }
-
-@media screen and (max-width: 767px) {
-  #conversejs:not(.converse-embedded) > .row {
-    flex-direction: row-reverse; }
-  #conversejs:not(.converse-embedded) #converse-login-panel .converse-form {
-    padding: 3em 2em 3em; }
-  #conversejs:not(.converse-embedded) .sidebar {
-    display: block; }
-  #conversejs:not(.converse-embedded) .chatbox {
-    width: calc(100% - 50px); }
-    #conversejs:not(.converse-embedded) .chatbox .row .box-flyout {
-      left: 50px;
-      bottom: 0;
-      height: 100vh;
-      box-shadow: none; } }
-#conversejs.fullscreen .chatbox-btn {
-  font-size: 18px;
-  margin: 0 0.3em; }
-#conversejs.fullscreen .flyout {
-  border-radius: 0;
-  border: 1.2em solid #3AA569;
-  border-top: 0.8em solid #3AA569;
-  bottom: 0; }
-#conversejs.fullscreen .chat-head {
-  font-size: 20px;
-  padding: 0; }
-  #conversejs.fullscreen .chat-head .user-custom-message {
-    font-size: 50%;
-    height: auto;
-    line-height: 22px; }
-#conversejs.fullscreen .chatbox {
-  width: 100%;
-  height: 100%;
-  margin: 0;
-  position: relative;
-  width: 100%;
-  min-height: 1px;
-  padding-right: 15px;
-  padding-left: 15px; }
-  @media (min-width: 768px) {
-    #conversejs.fullscreen .chatbox {
-      flex: 0 0 75%;
-      max-width: 75%; } }
-  @media (min-width: 1200px) {
-    #conversejs.fullscreen .chatbox {
-      flex: 0 0 83.3333333333%;
-      max-width: 83.3333333333%; } }
-  #conversejs.fullscreen .chatbox .box-flyout {
-    background-color: #3AA569;
-    height: 100vh;
-    width: 100%;
-    box-shadow: none; }
-  #conversejs.fullscreen .chatbox .chat-body {
-    background-color: #3AA569;
-    border-top-left-radius: 4px;
-    border-top-right-radius: 4px; }
-    #conversejs.fullscreen .chatbox .chat-body .chat-message {
-      line-height: 22px;
-      font-size: 14px; }
-      #conversejs.fullscreen .chatbox .chat-body .chat-message .chat-msg-author {
-        line-height: 22px; }
-      #conversejs.fullscreen .chatbox .chat-body .chat-message .chat-msg-content {
-        line-height: 22px; }
-        #conversejs.fullscreen .chatbox .chat-body .chat-message .chat-msg-content .emojione {
-          height: 22px;
-          margin-bottom: -5.5px; }
-  #conversejs.fullscreen .chatbox .chat-content {
-    border-top-left-radius: 4px;
-    border-top-right-radius: 4px; }
-  #conversejs.fullscreen .chatbox .chat-title {
-    font-size: 26px;
-    line-height: 30px; }
-  #conversejs.fullscreen .chatbox .sendXMPPMessage ul {
-    width: 100%; }
-  #conversejs.fullscreen .chatbox .sendXMPPMessage .toggle-smiley ul.emoji-toolbar .emoji-category-picker {
-    margin-right: 5em; }
-  #conversejs.fullscreen .chatbox .sendXMPPMessage .toggle-smiley ul.emoji-toolbar .emoji-category {
-    padding-left: 10px;
-    padding-right: 10px; }
-
-@media screen and (max-width: 767px) {
-  #conversejs:not(.converse-embedded).fullscreen .chatbox {
-    width: calc(100% - 50px); } }
-#conversejs .set-xmpp-status .fa-circle, #conversejs .xmpp-status .fa-circle, #conversejs .roster-contacts .fa-circle {
-  color: #3AA569; }
-#conversejs .set-xmpp-status .fa-minus-circle, #conversejs .xmpp-status .fa-minus-circle, #conversejs .roster-contacts .fa-minus-circle {
-  color: #E77051; }
-#conversejs .set-xmpp-status .fa-dot-circle-o, #conversejs .xmpp-status .fa-dot-circle-o, #conversejs .roster-contacts .fa-dot-circle-o {
-  color: #E7A151; }
-#conversejs .set-xmpp-status .fa-circle-o, #conversejs .xmpp-status .fa-circle-o, #conversejs .roster-contacts .fa-circle-o {
-  color: #A8ABA1; }
-#conversejs .set-xmpp-status .fa-times-circle, #conversejs .xmpp-status .fa-times-circle, #conversejs .roster-contacts .fa-times-circle {
-  color: #A8ABA1; }
-#conversejs .room-info {
-  font-size: 14px;
-  font-style: normal;
-  font-weight: normal; }
-  #conversejs .room-info li.room-info {
-    display: block;
-    margin-left: 5px; }
-  #conversejs .room-info p.room-info {
-    line-height: 22px;
-    margin: 0;
-    display: block;
-    white-space: normal; }
-#conversejs div.room-info {
-  padding: 0.3em 0;
-  clear: left;
-  width: 100%; }
-#conversejs #converse-modals .set-xmpp-status {
-  margin: 1em; }
-  #conversejs #converse-modals .set-xmpp-status .custom-control-label {
-    margin-top: 0.25em; }
-#conversejs #controlbox {
-  margin-right: 1.5em; }
-  #conversejs #controlbox .box-flyout {
-    background-color: white; }
-  #conversejs #controlbox.logged-out .box-flyout .controlbox-pane {
-    overflow-y: auto; }
-  #conversejs #controlbox form.search-xmpp-contact {
-    margin: 0;
-    padding-left: 5px;
-    padding: 0 0 5px 5px; }
-    #conversejs #controlbox form.search-xmpp-contact input {
-      width: 8em; }
-  #conversejs #controlbox .msgs-indicator {
-    margin-right: 0.5em; }
-  #conversejs #controlbox a.subscribe-to-user {
-    padding-left: 2em;
-    font-weight: bold; }
-  #conversejs #controlbox #converse-register {
-    opacity: 0;
-    /* make things invisible upon start */
-    -webkit-animation-name: fadein;
-    -moz-animation-name: fadein;
-    animation-name: fadein;
-    -webkit-animation-fill-mode: forwards;
-    -moz-animation-fill-mode: forwards;
-    animation-fill-mode: forwards;
-    -webkit-animation-duration: 0.75s;
-    -moz-animation-duration: 0.75s;
-    animation-duration: 0.75s;
-    -webkit-animation-timing-function: ease;
-    -moz-animation-timing-function: ease;
-    animation-timing-function: ease;
-    background: white; }
-    #conversejs #controlbox #converse-register .title {
-      font-weight: bold; }
-    #conversejs #controlbox #converse-register .info {
-      color: green;
-      font-size: 90%;
-      margin: 1.5em 0; }
-    #conversejs #controlbox #converse-register .form-errors {
-      color: #A53214;
-      margin: 1em 0; }
-    #conversejs #controlbox #converse-register .provider-title {
-      font-size: 26px;
-      margin: 0; }
-    #conversejs #controlbox #converse-register .provider-score {
-      width: 178px;
-      margin-bottom: 8px; }
-    #conversejs #controlbox #converse-register .form-help .url {
-      font-weight: bold;
-      color: #578EA9; }
-    #conversejs #controlbox #converse-register .input-group {
-      display: table;
-      margin: auto;
-      width: 100%; }
-      #conversejs #controlbox #converse-register .input-group span {
-        overflow-x: hidden;
-        text-overflow: ellipsis;
-        max-width: 110px; }
-      #conversejs #controlbox #converse-register .input-group span, #conversejs #controlbox #converse-register .input-group input[name=username] {
-        display: table-cell;
-        text-align: left; }
-    #conversejs #controlbox #converse-register .instructions {
-      color: gray;
-      font-size: 85%; }
-      #conversejs #controlbox #converse-register .instructions:hover {
-        color: #666; }
-  #conversejs #controlbox .conn-feedback {
-    color: #578EA9; }
-    #conversejs #controlbox .conn-feedback.error {
-      color: #A53214; }
-    #conversejs #controlbox .conn-feedback p {
-      padding-bottom: 1em; }
-      #conversejs #controlbox .conn-feedback p.feedback-subject.error {
-        font-weight: bold; }
-  #conversejs #controlbox .brand-heading-container .brand-heading {
-    text-align: center; }
-  #conversejs #controlbox .brand-heading-container .brand-name {
-    font-size: 120%; }
-  #conversejs #controlbox #converse-login-panel, #conversejs #controlbox #converse-register-panel {
-    padding-top: 0;
-    padding-bottom: 0; }
-  #conversejs #controlbox #converse-login-panel {
-    flex-direction: column; }
-    #conversejs #controlbox #converse-login-panel .brand-heading {
-      color: #578EA9; }
-  #conversejs #controlbox .toggle-register-login {
-    font-weight: bold; }
-  #conversejs #controlbox .oauth-login {
-    margin-left: 0;
-    color: #666; }
-    #conversejs #controlbox .oauth-login .icon-social:before {
-      font-size: 18px; }
-  #conversejs #controlbox .controlbox-pane .userinfo {
-    padding-bottom: 1em; }
-    #conversejs #controlbox .controlbox-pane .userinfo .username {
-      margin-left: 0.5em;
-      overflow: hidden;
-      text-overflow: ellipsis; }
-    #conversejs #controlbox .controlbox-pane .userinfo .profile {
-      margin-bottom: 0.75em; }
-  #conversejs #controlbox #chatrooms {
-    padding: 0; }
-    #conversejs #controlbox #chatrooms .add-chatroom {
-      margin: 0;
-      padding: 0; }
-      #conversejs #controlbox #chatrooms .add-chatroom input[type=button],
-      #conversejs #controlbox #chatrooms .add-chatroom input[type=submit],
-      #conversejs #controlbox #chatrooms .add-chatroom input[type=text] {
-        width: 100%; }
-  #conversejs #controlbox .controlbox-section {
-    margin: 1em 0 0 0; }
-    #conversejs #controlbox .controlbox-section .controlbox-heading {
-      font-family: "Century Gothic", futura, "URW Gothic L", Verdana, sans-serif;
-      margin: 0 0 0.5em 0;
-      text-transform: uppercase; }
-  #conversejs #controlbox .dropdown a {
-    width: 143px;
-    display: inline-block; }
-  #conversejs #controlbox .dropdown li {
-    list-style: none;
-    padding-left: 0; }
-  #conversejs #controlbox .dropdown dd ul {
-    padding: 0;
-    list-style: none;
-    position: absolute;
-    left: 0;
-    top: 0;
-    width: 100%;
-    z-index: 21;
-    background-color: #FCFDFD; }
-    #conversejs #controlbox .dropdown dd ul li:hover {
-      background-color: #DCF9F6; }
-  #conversejs #controlbox .dropdown dd.search-xmpp {
-    height: 0; }
-    #conversejs #controlbox .dropdown dd.search-xmpp .contact-form-container {
-      position: absolute;
-      z-index: 22; }
-      #conversejs #controlbox .dropdown dd.search-xmpp .contact-form-container form {
-        box-shadow: 1px 4px 10px 1px rgba(0, 0, 0, 0.4);
-        background-color: white; }
-    #conversejs #controlbox .dropdown dd.search-xmpp li:hover {
-      background-color: #FCFDFD; }
-  #conversejs #controlbox .dropdown dt a span {
-    cursor: pointer;
-    display: block;
-    padding: 4px 7px 0 5px; }
-  #conversejs #controlbox .controlbox-panes {
-    height: 100%;
-    overflow-y: auto;
-    background-color: white; }
-  #conversejs #controlbox .controlbox-pane {
-    background-color: white;
-    border: 0;
-    font-size: 16px;
-    left: 0;
-    text-align: left;
-    overflow-x: hidden;
-    padding: 1em 0 1em 0; }
-    #conversejs #controlbox .controlbox-pane .controlbox-padded {
-      padding-left: 1em;
-      padding-right: 1em; }
-    #conversejs #controlbox .controlbox-pane .add-converse-contact {
-      margin: 0 0 0.75em 0; }
-    #conversejs #controlbox .controlbox-pane .chatbox-btn {
-      margin: 0; }
-    #conversejs #controlbox .controlbox-pane .switch-form {
-      padding: 2em 0; }
-      #conversejs #controlbox .controlbox-pane .switch-form p {
-        margin-top: 0.5em; }
-    #conversejs #controlbox .controlbox-pane dd {
-      margin-left: 0;
-      margin-bottom: 0; }
-      #conversejs #controlbox .controlbox-pane dd.odd {
-        background-color: #DCEAC5; }
-  #conversejs #controlbox .add-xmpp-contact {
-    padding: 1em 0.5em; }
-    #conversejs #controlbox .add-xmpp-contact input {
-      margin: 0 0 1rem;
-      width: 100%; }
-    #conversejs #controlbox .add-xmpp-contact button {
-      width: 100%; }
-#conversejs .toggle-controlbox {
-  text-align: center;
-  background-color: #578EA9;
-  border-top-left-radius: 5px;
-  border-top-right-radius: 5px;
-  color: #0a0a0a;
-  float: right;
-  height: 100%;
-  margin: 0 0.5em;
-  padding: 1em; }
-  #conversejs .toggle-controlbox span {
-    color: white; }
-
-@media (max-width: 767.98px) {
-  #conversejs:not(.converse-embedded) {
-    left: 0;
-    right: 0;
-    padding-left: env(safe-area-inset-left);
-    padding-right: env(safe-area-inset-right); }
-    #conversejs:not(.converse-embedded) .converse-chatboxes {
-      margin: 0 !important;
-      flex-direction: row !important;
-      justify-content: space-between; }
-      #conversejs:not(.converse-embedded) .converse-chatboxes .converse-chatroom {
-        font-size: 14px; }
-      #conversejs:not(.converse-embedded) .converse-chatboxes .chatbox .box-flyout {
-        top: -100vh;
-        margin-left: 15px;
-        left: 0;
-        bottom: 0;
-        border-radius: 0;
-        width: 100vw !important;
-        height: 100vh !important; }
-      #conversejs:not(.converse-embedded) .converse-chatboxes #controlbox {
-        order: 0; }
-        #conversejs:not(.converse-embedded) .converse-chatboxes #controlbox .box-flyout {
-          width: 100vw !important;
-          height: 100vh !important; }
-        #conversejs:not(.converse-embedded) .converse-chatboxes #controlbox .sidebar {
-          display: block; }
-      #conversejs:not(.converse-embedded) .converse-chatboxes.sidebar-open .chatbox:not(#controlbox) {
-        display: none; }
-      #conversejs:not(.converse-embedded) .converse-chatboxes.sidebar-open #controlbox .controlbox-pane {
-        display: block; } }
-#conversejs:not(.converse-fullscreen) #controlbox {
-  order: -1;
-  min-width: 250px !important;
-  width: 250px; }
-  #conversejs:not(.converse-fullscreen) #controlbox .box-flyout {
-    min-width: 250px !important;
-    width: 250px; }
-  #conversejs:not(.converse-fullscreen) #controlbox:not(.logged-out) .controlbox-head {
-    height: 15px; }
-  #conversejs:not(.converse-fullscreen) #controlbox .controlbox-head {
-    display: flex;
-    flex-direction: row-reverse;
-    flex-wrap: nowrap;
-    justify-content: space-between; }
-    #conversejs:not(.converse-fullscreen) #controlbox .controlbox-head .brand-heading {
-      position: relative;
-      width: 100%;
-      min-height: 1px;
-      padding-right: 15px;
-      padding-left: 15px;
-      flex: 0 0 66.6666666667%;
-      max-width: 66.6666666667%;
-      color: #666;
-      font-size: 2em; }
-    #conversejs:not(.converse-fullscreen) #controlbox .controlbox-head .chatbox-btn {
-      color: #578EA9;
-      margin: 0; }
-  #conversejs:not(.converse-fullscreen) #controlbox #converse-register, #conversejs:not(.converse-fullscreen) #controlbox #converse-login {
-    flex: 0 0 100%;
-    max-width: 100%;
-    padding-bottom: 0; }
-  #conversejs:not(.converse-fullscreen) #controlbox #converse-register .button-cancel {
-    font-size: 90%; }
-  #conversejs:not(.converse-fullscreen) #controlbox .controlbox-panes {
-    border-radius: 4px; }
-
-#conversejs.fullscreen #controlbox {
-  position: relative;
-  width: 100%;
-  min-height: 1px;
-  padding-right: 15px;
-  padding-left: 15px;
-  margin: 0; }
-  @media (min-width: 768px) {
-    #conversejs.fullscreen #controlbox {
-      flex: 0 0 25%;
-      max-width: 25%; } }
-  @media (min-width: 1200px) {
-    #conversejs.fullscreen #controlbox {
-      flex: 0 0 16.6666666667%;
-      max-width: 16.6666666667%; } }
-  #conversejs.fullscreen #controlbox.logged-out {
-    flex: 0 0 100%;
-    max-width: 100%; }
-  #conversejs.fullscreen #controlbox .controlbox-pane {
-    border-radius: 0; }
-  #conversejs.fullscreen #controlbox .flyout {
-    border-radius: 0; }
-  #conversejs.fullscreen #controlbox #converse-login-panel {
-    border-radius: 0; }
-    #conversejs.fullscreen #controlbox #converse-login-panel .converse-form {
-      padding: 3em 2em 3em; }
-  #conversejs.fullscreen #controlbox .toggle-register-login {
-    line-height: 30px; }
-  #conversejs.fullscreen #controlbox .brand-heading-container {
-    flex: 0 0 100%;
-    max-width: 100%;
-    text-align: center; }
-    #conversejs.fullscreen #controlbox .brand-heading-container .brand-heading {
-      font-size: 150%;
-      font-size: 600%;
-      padding: 0.7em 0 0 0;
-      opacity: 0.8;
-      color: #387592; }
-    #conversejs.fullscreen #controlbox .brand-heading-container .brand-subtitle {
-      font-size: 90%;
-      padding: 0.5em; }
-    @media screen and (max-width: 480px) {
-      #conversejs.fullscreen #controlbox .brand-heading-container .brand-heading {
-        font-size: 400%; } }
-  #conversejs.fullscreen #controlbox.logged-out {
-    flex: 0 0 100%;
-    max-width: 100%;
-    opacity: 0;
-    /* make things invisible upon start */
-    -webkit-animation-name: fadein;
-    -moz-animation-name: fadein;
-    animation-name: fadein;
-    -webkit-animation-fill-mode: forwards;
-    -moz-animation-fill-mode: forwards;
-    animation-fill-mode: forwards;
-    -webkit-animation-duration: 0.75s;
-    -moz-animation-duration: 0.75s;
-    animation-duration: 0.75s;
-    -webkit-animation-timing-function: ease;
-    -moz-animation-timing-function: ease;
-    animation-timing-function: ease;
-    width: 100%; }
-    #conversejs.fullscreen #controlbox.logged-out .box-flyout {
-      width: 100%; }
-  #conversejs.fullscreen #controlbox .box-flyout {
-    border: 0;
-    width: 100%;
-    z-index: 1;
-    background-color: #578EA9; }
-    #conversejs.fullscreen #controlbox .box-flyout .controlbox-head {
-      display: none; }
-  #conversejs.fullscreen #controlbox #converse-register, #conversejs.fullscreen #controlbox #converse-login {
-    position: relative;
-    width: 100%;
-    min-height: 1px;
-    padding-right: 15px;
-    padding-left: 15px;
-    flex: 0 0 66.6666666667%;
-    max-width: 66.6666666667%;
-    margin-left: 16.6666666667%; }
-    @media (min-width: 576px) {
-      #conversejs.fullscreen #controlbox #converse-register, #conversejs.fullscreen #controlbox #converse-login {
-        flex: 0 0 66.6666666667%;
-        max-width: 66.6666666667%;
-        margin-left: 16.6666666667%; } }
-    @media (min-width: 768px) {
-      #conversejs.fullscreen #controlbox #converse-register, #conversejs.fullscreen #controlbox #converse-login {
-        flex: 0 0 66.6666666667%;
-        max-width: 66.6666666667%;
-        margin-left: 16.6666666667%; } }
-    @media (min-width: 992px) {
-      #conversejs.fullscreen #controlbox #converse-register, #conversejs.fullscreen #controlbox #converse-login {
-        flex: 0 0 50%;
-        max-width: 50%;
-        margin-left: 25%; } }
-    #conversejs.fullscreen #controlbox #converse-register .title, #conversejs.fullscreen #controlbox #converse-register .instructions, #conversejs.fullscreen #controlbox #converse-login .title, #conversejs.fullscreen #controlbox #converse-login .instructions {
-      margin: 1em 0; }
-    #conversejs.fullscreen #controlbox #converse-register input[type=submit],
-    #conversejs.fullscreen #controlbox #converse-register input[type=button], #conversejs.fullscreen #controlbox #converse-login input[type=submit],
-    #conversejs.fullscreen #controlbox #converse-login input[type=button] {
-      width: auto; }
-
-#conversejs #converse-roster {
-  text-align: left;
-  width: 100%;
-  position: relative;
-  margin: 0;
-  height: 194px;
-  height: calc(~"100% - 60px - 20px");
-  padding: 0;
-  overflow: hidden;
-  height: calc(100% - 70px);
-  /* Custom addition for CSP */ }
-  #conversejs #converse-roster #online-count {
-    display: none; }
-  #conversejs #converse-roster .search-xmpp ul li.chat-info {
-    padding-left: 10px; }
-  #conversejs #converse-roster .roster-filter-form {
-    width: 100%; }
-    #conversejs #converse-roster .roster-filter-form .button-group {
-      padding: 0.2em; }
-    #conversejs #converse-roster .roster-filter-form span {
-      padding: 0.3em;
-      cursor: pointer; }
-    #conversejs #converse-roster .roster-filter-form .roster-filter {
-      width: 100%;
-      margin: 0.2em;
-      font-size: calc(16px - 2px); }
-    #conversejs #converse-roster .roster-filter-form .state-type {
-      font-size: calc(16px - 2px);
-      height: 30px;
-      width: 100%; }
-  #conversejs #converse-roster .roster-contacts {
-    padding: 0;
-    margin: 0 0 0.2em 0;
-    height: 100%;
-    overflow-x: hidden;
-    overflow-y: auto; }
-    #conversejs #converse-roster .roster-contacts .roster-group {
-      border: none;
-      color: #666;
-      font-weight: normal;
-      text-shadow: 0 1px 0 #FAFAFA;
-      margin: 0.75em 0 0.75em 0; }
-      #conversejs #converse-roster .roster-contacts .roster-group .group-toggle {
-        font-family: "Century Gothic", futura, "URW Gothic L", Verdana, sans-serif;
-        color: #666;
-        display: block;
-        width: 100%;
-        padding-top: 0;
-        padding-bottom: 0.3rem; }
-        #conversejs #converse-roster .roster-contacts .roster-group .group-toggle:hover {
-          color: #585B51; }
-      #conversejs #converse-roster .roster-contacts .roster-group li {
-        border: none;
-        clear: both;
-        color: #666;
-        display: block;
-        overflow-y: hidden;
-        text-shadow: 0 1px 0 #FAFAFA;
-        line-height: 16px;
-        width: 100%;
-        height: 2em;
-        padding-top: 0.5em; }
-        #conversejs #converse-roster .roster-contacts .roster-group li.requesting-xmpp-contact a {
-          line-height: 22px; }
-          #conversejs #converse-roster .roster-contacts .roster-group li.requesting-xmpp-contact a.fa {
-            width: 1.5em; }
-        #conversejs #converse-roster .roster-contacts .roster-group li.requesting-xmpp-contact .req-contact-name {
-          padding: 0 0.2em 0 0; }
-        #conversejs #converse-roster .roster-contacts .roster-group li a:hover {
-          color: #206485; }
-        #conversejs #converse-roster .roster-contacts .roster-group li a .fa:hover {
-          color: white; }
-        #conversejs #converse-roster .roster-contacts .roster-group li .open-chat {
-          margin: 0;
-          padding: 0; }
-          #conversejs #converse-roster .roster-contacts .roster-group li .open-chat.unread-msgs {
-            font-weight: bold; }
-            #conversejs #converse-roster .roster-contacts .roster-group li .open-chat.unread-msgs .contact-name {
-              width: 70%; }
-          #conversejs #converse-roster .roster-contacts .roster-group li .open-chat .msgs-indicator {
-            color: white;
-            background-color: #3AA569;
-            opacity: 1;
-            border-radius: 10%;
-            padding: 0.2em;
-            font-size: 14px; }
-          #conversejs #converse-roster .roster-contacts .roster-group li .open-chat .contact-name {
-            overflow: hidden;
-            white-space: nowrap;
-            text-overflow: ellipsis;
-            padding: 0;
-            margin: 0;
-            max-width: 80%;
-            float: none;
-            height: 100%; }
-            #conversejs #converse-roster .roster-contacts .roster-group li .open-chat .contact-name.unread-msgs {
-              max-width: 60%; }
-          #conversejs #converse-roster .roster-contacts .roster-group li .open-chat .avatar {
-            float: left;
-            display: inline-block;
-            height: 30px; }
-        #conversejs #converse-roster .roster-contacts .roster-group li.current-xmpp-contact span {
-          font-size: 16px;
-          float: left;
-          margin-right: 0.5em; }
-        #conversejs #converse-roster .roster-contacts .roster-group li.odd {
-          background-color: #DCEAC5;
-          /* Make this difference */ }
-        #conversejs #converse-roster .roster-contacts .roster-group li a, #conversejs #converse-roster .roster-contacts .roster-group li span {
-          display: inline-block;
-          overflow: hidden;
-          white-space: nowrap;
-          text-overflow: ellipsis; }
-        #conversejs #converse-roster .roster-contacts .roster-group li span {
-          padding: 0; }
-        #conversejs #converse-roster .roster-contacts .roster-group li .decline-xmpp-request {
-          margin-left: 5px; }
-        #conversejs #converse-roster .roster-contacts .roster-group li .remove-xmpp-contact {
-          font-size: 10px;
-          margin: 0;
-          padding: 0;
-          width: 2em;
-          display: none; }
-          #conversejs #converse-roster .roster-contacts .roster-group li .remove-xmpp-contact:before {
-            font-size: 16px; }
-        #conversejs #converse-roster .roster-contacts .roster-group li:hover {
-          background-color: #eff4f7; }
-          #conversejs #converse-roster .roster-contacts .roster-group li:hover .remove-xmpp-contact {
-            display: inline-block; }
-  #conversejs #converse-roster span.pending-contact-name {
-    line-height: 22px;
-    width: 100%; }
-
-#conversejs .list-container {
-  text-align: left;
-  padding: 0.3em 0; }
-  #conversejs .list-container .rooms-toggle {
-    font-family: "Century Gothic", futura, "URW Gothic L", Verdana, sans-serif;
-    display: block;
-    color: #666;
-    padding: 0 0 0.5rem 0; }
-    #conversejs .list-container .rooms-toggle:hover {
-      color: #585B51; }
-  #conversejs .list-container .items-list {
-    text-align: left; }
-    #conversejs .list-container .items-list .list-item {
-      border: none;
-      clear: both;
-      color: #666;
-      display: block;
-      height: 2em;
-      overflow: hidden;
-      padding-top: 0.5em;
-      text-shadow: 0 1px 0 #FAFAFA;
-      word-wrap: break-word; }
-    #conversejs .list-container .items-list .available-chatroom:hover,
-    #conversejs .list-container .items-list .open-headline:hover,
-    #conversejs .list-container .items-list .open-chatroom:hover {
-      background-color: #eff4f7; }
-    #conversejs .list-container .items-list .available-chatroom.unread-msgs .msgs-indicator,
-    #conversejs .list-container .items-list .open-headline.unread-msgs .msgs-indicator,
-    #conversejs .list-container .items-list .open-chatroom.unread-msgs .msgs-indicator {
-      border-radius: 10%;
-      opacity: 1; }
-    #conversejs .list-container .items-list .available-chatroom.unread-msgs .available-room,
-    #conversejs .list-container .items-list .available-chatroom.unread-msgs .open-room,
-    #conversejs .list-container .items-list .open-headline.unread-msgs .available-room,
-    #conversejs .list-container .items-list .open-headline.unread-msgs .open-room,
-    #conversejs .list-container .items-list .open-chatroom.unread-msgs .available-room,
-    #conversejs .list-container .items-list .open-chatroom.unread-msgs .open-room {
-      width: 100%;
-      font-weight: bold; }
-    #conversejs .list-container .items-list .available-chatroom a:hover,
-    #conversejs .list-container .items-list .open-headline a:hover,
-    #conversejs .list-container .items-list .open-chatroom a:hover {
-      color: #206485; }
-    #conversejs .list-container .items-list .available-chatroom a.room-info:before,
-    #conversejs .list-container .items-list .open-headline a.room-info:before,
-    #conversejs .list-container .items-list .open-chatroom a.room-info:before {
-      font-size: 15px; }
-    #conversejs .list-container .items-list .available-chatroom a.open-room,
-    #conversejs .list-container .items-list .open-headline a.open-room,
-    #conversejs .list-container .items-list .open-chatroom a.open-room {
-      width: 68%;
-      float: left;
-      overflow: hidden;
-      text-overflow: ellipsis;
-      white-space: nowrap;
-      padding-right: 0.5em; }
-    #conversejs .list-container .items-list .available-chatroom a.available-room,
-    #conversejs .list-container .items-list .open-headline a.available-room,
-    #conversejs .list-container .items-list .open-chatroom a.available-room {
-      width: 85%; }
-    #conversejs .list-container .items-list .available-chatroom .add-bookmark,
-    #conversejs .list-container .items-list .available-chatroom .remove-bookmark,
-    #conversejs .list-container .items-list .open-headline .add-bookmark,
-    #conversejs .list-container .items-list .open-headline .remove-bookmark,
-    #conversejs .list-container .items-list .open-chatroom .add-bookmark,
-    #conversejs .list-container .items-list .open-chatroom .remove-bookmark {
-      color: #A8ABA1; }
-      #conversejs .list-container .items-list .available-chatroom .add-bookmark.button-on,
-      #conversejs .list-container .items-list .available-chatroom .remove-bookmark.button-on,
-      #conversejs .list-container .items-list .open-headline .add-bookmark.button-on,
-      #conversejs .list-container .items-list .open-headline .remove-bookmark.button-on,
-      #conversejs .list-container .items-list .open-chatroom .add-bookmark.button-on,
-      #conversejs .list-container .items-list .open-chatroom .remove-bookmark.button-on {
-        color: #578EA9; }
-        #conversejs .list-container .items-list .available-chatroom .add-bookmark.button-on:hover,
-        #conversejs .list-container .items-list .available-chatroom .remove-bookmark.button-on:hover,
-        #conversejs .list-container .items-list .open-headline .add-bookmark.button-on:hover,
-        #conversejs .list-container .items-list .open-headline .remove-bookmark.button-on:hover,
-        #conversejs .list-container .items-list .open-chatroom .add-bookmark.button-on:hover,
-        #conversejs .list-container .items-list .open-chatroom .remove-bookmark.button-on:hover {
-          color: #206485; }
-
-#conversejs.fullscreen #controlbox #chatrooms .bookmarks-list dl.rooms-list.bookmarks dd.available-chatroom a.open-room {
-  width: 80%; }
-
-#conversejs #converse-roster {
-  padding-bottom: 3em; }
-
-#conversejs.converse-embedded .add-chatroom input[type="submit"],
-#conversejs.converse-embedded .add-chatroom input[type="button"],
-#conversejs .add-chatroom input[type="submit"],
-#conversejs .add-chatroom input[type="button"] {
-  margin: 0.3em 0; }
-#conversejs.converse-embedded .chat-head-chatroom,
-#conversejs .chat-head-chatroom {
-  background-color: #E77051; }
-  #conversejs.converse-embedded .chat-head-chatroom .chatroom-description,
-  #conversejs .chat-head-chatroom .chatroom-description {
-    color: #f6ccc1;
-    font-size: 18px;
-    font-size: 70%;
-    margin-top: 3px;
-    overflow-y: hidden;
-    overflow: hidden;
-    text-overflow: ellipsis;
-    white-space: nowrap; }
-  #conversejs.converse-embedded .chat-head-chatroom a.chatbox-btn.fa, #conversejs.converse-embedded .chat-head-chatroom a:visited.chatbox-btn.fa, #conversejs.converse-embedded .chat-head-chatroom a:hover.chatbox-btn.fa, #conversejs.converse-embedded .chat-head-chatroom a:not([href]):not([tabindex]).chatbox-btn.fa,
-  #conversejs .chat-head-chatroom a.chatbox-btn.fa,
-  #conversejs .chat-head-chatroom a:visited.chatbox-btn.fa,
-  #conversejs .chat-head-chatroom a:hover.chatbox-btn.fa,
-  #conversejs .chat-head-chatroom a:not([href]):not([tabindex]).chatbox-btn.fa {
-    color: white; }
-    #conversejs.converse-embedded .chat-head-chatroom a.chatbox-btn.fa.button-on:before, #conversejs.converse-embedded .chat-head-chatroom a:visited.chatbox-btn.fa.button-on:before, #conversejs.converse-embedded .chat-head-chatroom a:hover.chatbox-btn.fa.button-on:before, #conversejs.converse-embedded .chat-head-chatroom a:not([href]):not([tabindex]).chatbox-btn.fa.button-on:before,
-    #conversejs .chat-head-chatroom a.chatbox-btn.fa.button-on:before,
-    #conversejs .chat-head-chatroom a:visited.chatbox-btn.fa.button-on:before,
-    #conversejs .chat-head-chatroom a:hover.chatbox-btn.fa.button-on:before,
-    #conversejs .chat-head-chatroom a:not([href]):not([tabindex]).chatbox-btn.fa.button-on:before {
-      color: #E77051; }
-  #conversejs.converse-embedded .chat-head-chatroom .chatbox-btn.button-on:before,
-  #conversejs .chat-head-chatroom .chatbox-btn.button-on:before {
-    color: #E77051; }
-  #conversejs.converse-embedded .chat-head-chatroom .chat-title .chatroom-jid,
-  #conversejs .chat-head-chatroom .chat-title .chatroom-jid {
-    font-size: 14px; }
-#conversejs.converse-embedded .chatroom,
-#conversejs .chatroom {
-  width: 300px; }
-  @media screen and (max-height: 450px) {
-    #conversejs.converse-embedded .chatroom,
-    #conversejs .chatroom {
-      width: 100%; } }
-  @media screen and (max-width: 480px) {
-    #conversejs.converse-embedded .chatroom,
-    #conversejs .chatroom {
-      width: 100%; } }
-  #conversejs.converse-embedded .chatroom .box-flyout,
-  #conversejs .chatroom .box-flyout {
-    overflow-y: hidden;
-    background-color: #E77051;
-    width: 100%; }
-    @media screen and (max-height: 450px) {
-      #conversejs.converse-embedded .chatroom .box-flyout,
-      #conversejs .chatroom .box-flyout {
-        height: 400px;
-        width: 100%;
-        height: 100vh; } }
-    @media screen and (max-width: 480px) {
-      #conversejs.converse-embedded .chatroom .box-flyout,
-      #conversejs .chatroom .box-flyout {
-        height: 400px;
-        width: 100%;
-        height: 100vh; } }
-    #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body,
-    #conversejs .chatroom .box-flyout .chatroom-body {
-      flex-direction: row;
-      flex-flow: nowrap;
-      border-bottom-right-radius: 4px;
-      border-bottom-left-radius: 4px;
-      background-color: white;
-      border-top: 0;
-      width: 100%;
-      overflow: hidden; }
-      #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .row,
-      #conversejs .chatroom .box-flyout .chatroom-body .row {
-        flex-direction: row; }
-      #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-topic,
-      #conversejs .chatroom .box-flyout .chatroom-body .chat-topic {
-        font-weight: bold;
-        color: #E77051; }
-      #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-info,
-      #conversejs .chatroom .box-flyout .chatroom-body .chat-info {
-        color: #E77051;
-        line-height: normal; }
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-info.badge,
-        #conversejs .chatroom .box-flyout .chatroom-body .chat-info.badge {
-          color: white; }
-      #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .mentioned,
-      #conversejs .chatroom .box-flyout .chatroom-body .mentioned {
-        font-weight: bold; }
-      #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .disconnect-msg,
-      #conversejs .chatroom .box-flyout .chatroom-body .disconnect-msg {
-        padding: 2em 2em 0 2em; }
-      #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-area,
-      #conversejs .chatroom .box-flyout .chatroom-body .chat-area {
-        display: flex;
-        flex-direction: column;
-        word-wrap: break-word;
-        min-width: 100%; }
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-area .new-msgs-indicator,
-        #conversejs .chatroom .box-flyout .chatroom-body .chat-area .new-msgs-indicator {
-          background-color: #E77051; }
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-area .chat-content,
-        #conversejs .chatroom .box-flyout .chatroom-body .chat-area .chat-content {
-          height: 100%; }
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chat-area.full,
-        #conversejs .chatroom .box-flyout .chatroom-body .chat-area.full {
-          min-width: 100%; }
-      #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants,
-      #conversejs .chatroom .box-flyout .chatroom-body .occupants {
-        display: flex;
-        flex-direction: column;
-        justify-content: space-between;
-        overflow-x: hidden;
-        overflow-y: hidden;
-        vertical-align: top;
-        background-color: white;
-        border-left: 1px solid #666;
-        border-bottom-right-radius: 4px;
-        padding: 0.5em; }
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .occupants-heading,
-        #conversejs .chatroom .box-flyout .chatroom-body .occupants .occupants-heading {
-          font-family: "Century Gothic", futura, "URW Gothic L", Verdana, sans-serif;
-          padding: 0.3em 0; }
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .chatroom-features,
-        #conversejs .chatroom .box-flyout .chatroom-body .occupants .chatroom-features {
-          width: 100%; }
-          #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .chatroom-features .feature,
-          #conversejs .chatroom .box-flyout .chatroom-body .occupants .chatroom-features .feature {
-            float: left;
-            margin-right: 0.5em;
-            padding-right: 0;
-            font-size: 1em;
-            cursor: help; }
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .awesomplete ul,
-        #conversejs .chatroom .box-flyout .chatroom-body .occupants .awesomplete ul {
-          padding: 0; }
-          #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants .awesomplete ul li,
-          #conversejs .chatroom .box-flyout .chatroom-body .occupants .awesomplete ul li {
-            padding: .5em; }
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul,
-        #conversejs .chatroom .box-flyout .chatroom-body .occupants ul {
-          padding: 0.5em 0 0 0;
-          margin-bottom: 0.5em;
-          overflow-x: hidden;
-          overflow-y: auto;
-          list-style: none; }
-          #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul.occupant-list,
-          #conversejs .chatroom .box-flyout .chatroom-body .occupants ul.occupant-list {
-            overflow-y: auto;
-            flex-basis: 0;
-            flex-grow: 1;
-            border-bottom: 1px solid lightgrey; }
-          #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul.features-list,
-          #conversejs .chatroom .box-flyout .chatroom-body .occupants ul.features-list {
-            padding-top: 0; }
-            #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul.features-list .feature,
-            #conversejs .chatroom .box-flyout .chatroom-body .occupants ul.features-list .feature {
-              width: 100%; }
-              #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul.features-list .feature .fa,
-              #conversejs .chatroom .box-flyout .chatroom-body .occupants ul.features-list .feature .fa {
-                color: #666; }
-          #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li,
-          #conversejs .chatroom .box-flyout .chatroom-body .occupants ul li {
-            cursor: default;
-            display: block;
-            font-size: 14px;
-            overflow: hidden;
-            padding: 0.25em 0.25em 0.25em 0;
-            text-overflow: ellipsis; }
-            #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li .fa,
-            #conversejs .chatroom .box-flyout .chatroom-body .occupants ul li .fa {
-              margin-right: 0.5em; }
-            #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.feature,
-            #conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.feature {
-              font-size: 10px; }
-            #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant,
-            #conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant {
-              cursor: pointer; }
-              #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant div.row.no-gutters,
-              #conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant div.row.no-gutters {
-                flex-wrap: nowrap;
-                min-height: 1.5em; }
-              #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .badge,
-              #conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .badge {
-                margin-bottom: 0.125rem; }
-              #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status,
-              #conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status {
-                display: inline-block;
-                margin: 0 0.5em 0.125em 0;
-                width: 0.5em;
-                height: 0.5em; }
-                #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-online, #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-chat,
-                #conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-online,
-                #conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-chat {
-                  background-color: #1A9707; }
-                #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-dnd,
-                #conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-dnd {
-                  background-color: red; }
-                #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-away,
-                #conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-away {
-                  background-color: darkorange; }
-                #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-xa,
-                #conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-xa {
-                  background-color: orange; }
-                #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-offline,
-                #conversejs .chatroom .box-flyout .chatroom-body .occupants ul li.occupant .occupant-status.occupant-offline {
-                  background-color: darkgrey; }
-      #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container,
-      #conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container {
-        background-color: white;
-        border-bottom-left-radius: 4px;
-        border-bottom-right-radius: 4px;
-        border: 0;
-        color: #666;
-        font-size: 16px;
-        height: 100%;
-        width: 100%;
-        overflow-y: auto; }
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container .validation-message,
-        #conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container .validation-message {
-          font-size: 90%;
-          color: #A53214; }
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container .chatroom-form label,
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container .chatroom-form input[type=text],
-        #conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container .chatroom-form label,
-        #conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container .chatroom-form input[type=text] {
-          display: block; }
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container input[type=button],
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container input[type=submit],
-        #conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container input[type=button],
-        #conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container input[type=submit] {
-          margin: 0 0.5em; }
-        #conversejs.converse-embedded .chatroom .box-flyout .chatroom-body .chatroom-form-container .button-primary,
-        #conversejs .chatroom .box-flyout .chatroom-body .chatroom-form-container .button-primary {
-          background-color: #E77051; }
-  #conversejs.converse-embedded .chatroom .sendXMPPMessage .chat-toolbar,
-  #conversejs .chatroom .sendXMPPMessage .chat-toolbar {
-    background-color: white;
-    border-top: 8px solid #E77051;
-    color: #E77051; }
-    #conversejs.converse-embedded .chatroom .sendXMPPMessage .chat-toolbar .fa, #conversejs.converse-embedded .chatroom .sendXMPPMessage .chat-toolbar .fa:hover,
-    #conversejs .chatroom .sendXMPPMessage .chat-toolbar .fa,
-    #conversejs .chatroom .sendXMPPMessage .chat-toolbar .fa:hover {
-      color: #E77051; }
-  #conversejs.converse-embedded .chatroom .sendXMPPMessage .chat-textarea,
-  #conversejs .chatroom .sendXMPPMessage .chat-textarea {
-    border-bottom-right-radius: 0; }
-  #conversejs.converse-embedded .chatroom .sendXMPPMessage .send-button,
-  #conversejs .chatroom .sendXMPPMessage .send-button {
-    background-color: #E77051; }
-  #conversejs.converse-embedded .chatroom .room-invite .invited-contact,
-  #conversejs .chatroom .room-invite .invited-contact {
-    margin: -1px 0 0 -1px;
-    width: 100%;
-    border: 1px solid #999; }
-
-#conversejs.converse-fullscreen .chat-head-chatroom,
-#conversejs.converse-mobile .chat-head-chatroom {
-  height: 62px;
-  font-size: 20px; }
-  #conversejs.converse-fullscreen .chat-head-chatroom .chat-title .chatroom-description,
-  #conversejs.converse-mobile .chat-head-chatroom .chat-title .chatroom-description {
-    font-size: 65%; }
-#conversejs.converse-fullscreen .chatroom .box-flyout,
-#conversejs.converse-mobile .chatroom .box-flyout {
-  background-color: #E77051;
-  border: 1.2em solid #E77051;
-  border-top: 0.8em solid #E77051;
-  width: 100%; }
-  #conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body,
-  #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body {
-    border-top-left-radius: 4px;
-    border-top-right-radius: 4px; }
-    #conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .chatroom-form-container,
-    #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .chatroom-form-container {
-      border-radius: 4px; }
-    #conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .chat-area,
-    #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .chat-area {
-      border-top-left-radius: 4px;
-      min-width: auto; }
-      #conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .chat-area .chat-content,
-      #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .chat-area .chat-content {
-        border-top-left-radius: 4px; }
-      #conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .chat-area.full,
-      #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .chat-area.full {
-        max-width: 100%; }
-        #conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .chat-area.full .new-msgs-indicator,
-        #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .chat-area.full .new-msgs-indicator {
-          max-width: 100%; }
-    #conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .occupants,
-    #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .occupants {
-      border-top-right-radius: 4px;
-      padding: 1em; }
-      #conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .occupants .occupants-heading,
-      #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .occupants .occupants-heading {
-        font-size: 18px; }
-      #conversejs.converse-fullscreen .chatroom .box-flyout .chatroom-body .occupants ul.occupant-list li,
-      #conversejs.converse-mobile .chatroom .box-flyout .chatroom-body .occupants ul.occupant-list li {
-        font-size: 14px; }
-#conversejs.converse-fullscreen .chatroom .room-invite span .invited-contact,
-#conversejs.converse-mobile .chatroom .room-invite span .invited-contact {
-  margin: 0 0 0.5em -1px; }
-
-#conversejs .chatbox.headlines .chat-head.chat-head-chatbox {
-  background-color: #E7A151; }
-#conversejs .chatbox.headlines .chat-body {
-  background-color: #E7A151;
-  border-radius: 4px; }
-  #conversejs .chatbox.headlines .chat-body .chat-message {
-    color: #D2842B; }
-#conversejs .chatbox.headlines .chat-content {
-  height: 100%; }
-
-#conversejs.fullscreen .chatbox.headlines .box-flyout {
-  background-color: #E7A151; }
-#conversejs.fullscreen .chatbox.headlines .chat-head.chat-head-chatbox {
-  background-color: #E7A151; }
-#conversejs.fullscreen .chatbox.headlines .flyout {
-  border: 1.2em solid #E7A151;
-  border-top: 0.8em solid #E7A151; }
-
-#conversejs .message.date-separator {
-  height: 2em;
-  margin: 0;
-  position: relative;
-  text-align: center;
-  z-index: 0; }
-  #conversejs .message.date-separator .separator {
-    border: 0.5px solid #3AA569;
-    margin: 0 1em;
-    position: relative;
-    top: 1em;
-    z-index: 5; }
-  #conversejs .message.date-separator .separator-text {
-    background: white;
-    bottom: 1px;
-    color: #555;
-    display: inline-block;
-    line-height: 2em;
-    padding: 0 1em;
-    position: relative;
-    z-index: 5; }
-#conversejs .message.chat-info {
-  color: #3AA569;
-  font-size: 14px;
-  line-height: 20px;
-  padding: 0.35rem 1rem; }
-  #conversejs .message.chat-info.badge {
-    color: white; }
-  #conversejs .message.chat-info.chat-state-notification {
-    font-style: italic; }
-  #conversejs .message.chat-info.chat-event {
-    clear: left;
-    font-style: italic; }
-  #conversejs .message.chat-info.chat-error {
-    color: #D24E2B;
-    font-weight: bold; }
-#conversejs .message .chat-image {
-  height: auto;
-  width: auto;
-  max-height: 15em;
-  max-width: 100%; }
-#conversejs .message.chat-action {
-  font-style: italic; }
-#conversejs .message.chat-msg {
-  display: flex;
-  flex-direction: row;
-  overflow: auto;
-  padding: 0.25rem 1rem; }
-  #conversejs .message.chat-msg.onload {
-    animation: colorchange-chatmessage 1s;
-    -webkit-animation: colorchange-chatmessage 1s; }
-  #conversejs .message.chat-msg:hover {
-    background-color: rgba(0, 0, 0, 0.035); }
-  #conversejs .message.chat-msg .spoiler {
-    margin-top: 0.5em; }
-  #conversejs .message.chat-msg .spoiler-hint {
-    margin-bottom: 0.5em; }
-  #conversejs .message.chat-msg .spoiler-toggle {
-    color: white; }
-    #conversejs .message.chat-msg .spoiler-toggle i {
-      color: white;
-      padding-right: 0.5em; }
-    #conversejs .message.chat-msg .spoiler-toggle:before {
-      padding-right: 0.25em;
-      whitespace: nowrap; }
-  #conversejs .message.chat-msg .chat-msg-content {
-    margin-left: 0.5rem;
-    width: 100%; }
-  #conversejs .message.chat-msg.headline .chat-msg-content {
-    margin-left: 0; }
-  #conversejs .message.chat-msg .chat-msg-text {
-    padding: 0;
-    color: #555; }
-    #conversejs .message.chat-msg .chat-msg-text a {
-      word-wrap: break-word;
-      word-break: break-all; }
-    #conversejs .message.chat-msg .chat-msg-text .emojione {
-      margin-bottom: -6px; }
-  #conversejs .message.chat-msg .chat-msg-media {
-    margin-top: 0.25rem; }
-    #conversejs .message.chat-msg .chat-msg-media a {
-      word-wrap: break-word; }
-    #conversejs .message.chat-msg .chat-msg-media audio {
-      width: 100%; }
-  #conversejs .message.chat-msg .avatar {
-    margin-top: 0.5em;
-    height: 36px;
-    vertical-align: middle;
-    width: 36px; }
-  #conversejs .message.chat-msg .chat-msg-heading {
-    margin-top: 0.5em;
-    padding-right: 0.25rem;
-    padding-bottom: 0.25rem;
-    display: block; }
-    #conversejs .message.chat-msg .chat-msg-heading .chat-msg-author {
-      font-family: "Century Gothic", futura, "URW Gothic L", Verdana, sans-serif;
-      font-size: 115%; }
-      #conversejs .message.chat-msg .chat-msg-heading .chat-msg-author .badge {
-        font-size: 80%;
-        font-family: "Helvetica", "Arial", sans-serif; }
-    #conversejs .message.chat-msg .chat-msg-heading .chat-msg-time {
-      padding-left: 0.25em;
-      color: #8c8c8c; }
-  #conversejs .message.chat-msg.chat-action {
-    display: block; }
-    #conversejs .message.chat-msg.chat-action .chat-msg-heading {
-      float: left;
-      margin-top: 0;
-      padding-bottom: 0; }
-  #conversejs .message.chat-msg.chat-msg-followup .chat-msg-heading,
-  #conversejs .message.chat-msg.chat-msg-followup .avatar {
-    display: none; }
-  #conversejs .message.chat-msg.chat-msg-followup .chat-msg-content {
-    margin-left: 2.75rem; }
-#conversejs .chatroom-body .message.onload {
-  animation: colorchange-chatmessage-muc 1s;
-  -webkit-animation: colorchange-chatmessage-muc 1s; }
-#conversejs .chatroom-body .message .separator {
-  border: 0.5px solid #E77051; }
-
-#conversejs.converse-overlayed .message.chat-msg.chat-msg-followup .chat-msg-content {
-  margin-left: 0; }
-
-@media screen and (max-width: 767px) {
-  #conversejs:not(.converse-embedded) .message.chat-msg .chat-msg-author {
-    white-space: normal; } }
-#converse-embedded-chat [hidden],
-#conversejs [hidden] {
-  display: none; }
-#converse-embedded-chat .visually-hidden,
-#conversejs .visually-hidden {
-  position: absolute;
-  clip: rect(0, 0, 0, 0); }
-#converse-embedded-chat .form-group .awesomplete,
-#conversejs .form-group .awesomplete {
-  width: 100%; }
-#converse-embedded-chat div.awesomplete,
-#conversejs div.awesomplete {
-  display: inline-block;
-  position: relative; }
-  #converse-embedded-chat div.awesomplete mark,
-  #conversejs div.awesomplete mark {
-    background: #FFB9A7; }
-  #converse-embedded-chat div.awesomplete > input,
-  #conversejs div.awesomplete > input {
-    display: block; }
-  #converse-embedded-chat div.awesomplete > ul,
-  #conversejs div.awesomplete > ul {
-    position: absolute;
-    left: 0;
-    right: 0;
-    z-index: 1;
-    min-width: 100%;
-    box-sizing: border-box;
-    list-style: none;
-    padding: 0;
-    border-radius: .3em;
-    margin: .2em 0 0;
-    background: rgba(255, 255, 255, 0.9);
-    background: linear-gradient(to bottom right, white, rgba(255, 255, 255, 0.8));
-    border: 1px solid rgba(0, 0, 0, 0.3);
-    box-shadow: 0.05em 0.2em 0.6em rgba(0, 0, 0, 0.2);
-    text-shadow: none; }
-    #converse-embedded-chat div.awesomplete > ul:before,
-    #conversejs div.awesomplete > ul:before {
-      content: "";
-      position: absolute;
-      top: -.43em;
-      left: 1em;
-      width: 0;
-      height: 0;
-      background: white;
-      border: inherit;
-      border-right: 0;
-      border-bottom: 0;
-      -webkit-transform: rotate(45deg);
-      transform: rotate(45deg); }
-    #converse-embedded-chat div.awesomplete > ul > li,
-    #conversejs div.awesomplete > ul > li {
-      text-overflow: ellipsis;
-      overflow-x: hidden;
-      position: relative;
-      cursor: pointer;
-      padding: 1em; }
-#converse-embedded-chat div.awesomplete > ul[hidden],
-#converse-embedded-chat div.awesomplete > ul:empty,
-#conversejs div.awesomplete > ul[hidden],
-#conversejs div.awesomplete > ul:empty {
-  display: none; }
-@supports (transform: scale(0)) {
-  #converse-embedded-chat div.awesomplete > ul,
-  #conversejs div.awesomplete > ul {
-    transition: 0.3s cubic-bezier(0.4, 0.2, 0.5, 1.4);
-    transform-origin: 1.43em -.43em; }
-  #converse-embedded-chat div.awesomplete > ul[hidden],
-  #converse-embedded-chat div.awesomplete > ul:empty,
-  #conversejs div.awesomplete > ul[hidden],
-  #conversejs div.awesomplete > ul:empty {
-    opacity: 0;
-    transform: scale(0);
-    display: block;
-    transition-timing-function: ease; } }
-#converse-embedded-chat div.awesomplete > ul > li:hover,
-#conversejs div.awesomplete > ul > li:hover {
-  background: #E77051;
-  color: white; }
-#converse-embedded-chat div.awesomplete > ul > li[aria-selected="true"],
-#conversejs div.awesomplete > ul > li[aria-selected="true"] {
-  background: #3d6d8f;
-  color: white; }
-#converse-embedded-chat div.awesomplete li:hover mark,
-#conversejs div.awesomplete li:hover mark {
-  background: #A53214;
-  color: white; }
-#converse-embedded-chat div.awesomplete li[aria-selected="true"] mark,
-#conversejs div.awesomplete li[aria-selected="true"] mark {
-  background: #3d6b00;
-  color: inherit; }
-
-/*# sourceMappingURL=inverse.css.map */

+ 21 - 2
css/website.css

@@ -117,6 +117,14 @@ a:hover, a:focus {
 .outro {
   background: url("images/bgtr.svg") top right no-repeat, url("images/bgbl.svg") bottom left no-repeat, url("images/overlay.png"), linear-gradient(45deg, #384955, #655361, #85505f); }
 
+section h2 {
+  color: #E7A151; }
+section h3 {
+  color: #89B7CD; }
+section h4 {
+  color: #5CBC86;
+  font-size: 1.5em; }
+
 .brand-heading {
   font-family: Futura,Helvetica,Trebuchet MS,Arial,sans-serif;
   font-weight: normal;
@@ -181,7 +189,17 @@ a:hover, a:focus {
   -moz-animation-timing-function: linear; }
 
 .content-section {
-  padding-top: 100px; }
+  padding-top: 100px;
+  padding-top: 100px;
+  min-height: 100vh; }
+  .content-section .privacy-policy {
+    padding-top: 2em; }
+    .content-section .privacy-policy h4 {
+      padding-top: 1.5em; }
+    .content-section .privacy-policy p {
+      font-size: 1.2em;
+      padding-bottom: 0;
+      margin-bottom: 1em; }
 
 .donate-section {
   width: 100%;
@@ -194,7 +212,6 @@ a:hover, a:focus {
 
 @media (min-width: 767px) {
   .content-section {
-    padding-top: 150px;
     padding-bottom: 50px; }
 
   .donate-section {
@@ -304,6 +321,8 @@ ul.features {
   clear: both;
   font-size: 1.4em;
   padding: 2em 0 6em 0; }
+  .sponsors ul {
+    padding: 0; }
 
 .sponsors h2 {
   text-align: center; }

+ 22 - 24
dev.html

@@ -9,35 +9,33 @@
     <meta name="author" content="JC Brand" />
     <meta name="keywords" content="xmpp chat webchat converse.js" />
     <link rel="shortcut icon" type="image/ico" href="css/images/favicon.ico"/>
-    <link type="text/css" rel="stylesheet" media="screen" href="css/inverse.css" />
-    <script src="node_modules/requirejs/require.js"></script>
-    <script src="src/config.js"></script>
+    <link type="text/css" rel="stylesheet" media="screen" href="css/fullpage.css" />
+    <link type="text/css" rel="stylesheet" media="screen" href="css/converse.css" />
+    <script src="dist/converse.js"></script>
 </head>
 
 <body class="reset">
 
 <script>
-    require(['converse', 'converse-omemo'], function (converse) {
-        converse.initialize({
-            auto_away: 300,
-            i18n: 'en',
-            // auto_join_rooms: [
-            //     'discuss@conference.conversejs.org',
-            //     'prosody@conference.prosody.im',
-            //     'jdev@conference.jabber.org'
-            // ],
-            // websocket_url: 'ws://chat.example.org:5280/xmpp-websocket',
-            view_mode: 'fullscreen',
-            archived_messages_page_size: '500',
-            allow_public_bookmarks: true,
-            notify_all_room_messages: [
-                'discuss@conference.conversejs.org'
-            ],
-            // bosh_service_url: 'http://chat.example.org:5280/http-bind/',
-            bosh_service_url: 'https://conversejs.org/http-bind/', // Please use this connection manager only for testing purposes
-            message_archiving: 'always',
-            debug: true
-        });
+    converse.initialize({
+        auto_away: 300,
+        i18n: 'en',
+        // auto_join_rooms: [
+        //     'discuss@conference.conversejs.org',
+        //     'prosody@conference.prosody.im',
+        //     'jdev@conference.jabber.org'
+        // ],
+        // websocket_url: 'ws://chat.example.org:5280/xmpp-websocket',
+        view_mode: 'fullscreen',
+        archived_messages_page_size: '500',
+        allow_public_bookmarks: true,
+        notify_all_room_messages: [
+            'discuss@conference.conversejs.org'
+        ],
+        // bosh_service_url: 'http://chat.example.org:5280/http-bind/',
+        bosh_service_url: 'https://conversejs.org/http-bind/', // Please use this connection manager only for testing purposes
+        message_archiving: 'always',
+        debug: true
     });
 </script>
 </body>

Datei-Diff unterdrückt, da er zu groß ist
+ 3933 - 2026
dist/converse-no-dependencies.js


Datei-Diff unterdrückt, da er zu groß ist
+ 5614 - 5251
dist/converse.js


+ 97 - 83
docs/source/configuration.rst

@@ -7,10 +7,10 @@ Configuration
 =============
 
 The included minified JavaScript and CSS files can be used for demoing or testing, but
-you'll want to configure *Converse.js* to suit your needs before you deploy it
+you'll want to configure *Converse* to suit your needs before you deploy it
 on your website.
 
-*Converse.js* is passed its configuration settings when you call its *initialize* method.
+*Converse* is passed its configuration settings when you call its *initialize* method.
 
 You'll most likely want to call the *initialize* method in your HTML page. For
 an example of how this is done, please see the bottom of the *./index.html* page.
@@ -18,7 +18,7 @@ an example of how this is done, please see the bottom of the *./index.html* page
 Please refer to the `Configuration settings`_ section below for info on
 all the available configuration settings.
 
-After you have configured *Converse.js*, you'll have to regenerate the minified
+After you have configured *Converse*, you'll have to regenerate the minified
 JavaScript file so that it will include the new settings. Please refer to the
 :ref:`minification` section for more info on how to do this.
 
@@ -83,7 +83,7 @@ requiring them to log in manually.
 When a BOSH session is initially created, you'll receive three tokens.
 A JID (jabber ID), SID (session ID) and RID (Request ID).
 
-Converse.js needs these tokens in order to attach to that same session.
+Converse needs these tokens in order to attach to that same session.
 
 There are two complementary configuration settings to ``prebind``.
 They are :ref:`keepalive` and `prebind_url`_.
@@ -200,7 +200,7 @@ allow_public_bookmarks
 Some XMPP servers don't support private PEP/PubSub nodes, as required for
 private bookmarks and outlined in `XEP-0223 <https://xmpp.org/extensions/xep-0223.html>`_.
 
-Even though Converse.js asks for the bookmarks to be kept private (via the
+Even though Converse asks for the bookmarks to be kept private (via the
 `<publish-options>` XML node), the server simply ignores the privacy settings
 and publishes the node contents under the default privacy setting, which makes
 the information available to all roster contacts.
@@ -376,13 +376,13 @@ For example::
 blacklisted_plugins
 -------------------
 
-* Default: ``[]`` (``['converse-minimize', 'converse-dragresize']`` for inVerse)
+* Default: ``[]``
 
 A list of plugin names that are blacklisted and will therefore not be
 initialized once ``converse.initialize`` is called, even if the same plugin is
 whitelisted.
 
-From Converse.js 3.0 onwards most of the API is available only to plugins and
+From Converse 3.0 onwards most of the API is available only to plugins and
 all plugins need to be whitelisted first.
 
 The usecase for blacklisting is generally to disable removed core plugins
@@ -495,7 +495,7 @@ connection_options
 * Default:  ``{}``
 * Type:  Object
 
-Converse.js relies on `Strophe.js <http://strophe.im>`_ to establish and
+Converse relies on `Strophe.js <http://strophe.im>`_ to establish and
 maintain a connection to the XMPP server.
 
 This option allows you to pass a map of configuration options to be passed into
@@ -672,7 +672,7 @@ geouri_regex
 Regular expression used to extract geo coordinates from links to openstreetmap.
 
 geouri_replacement
-----------------
+------------------
 
 * Default:  ``'https://www.openstreetmap.org/?mlat=$1&mlon=$2#map=18/$1/$2'``
 
@@ -698,7 +698,7 @@ If set to ``true``, then don't show offline users.
 hide_open_bookmarks
 -------------------
 
-* Default:  ``false`` (``true`` for inVerse).
+* Default:  ``false`` (``true`` when the ``view_mode`` is set to ``fullscreen``).
 
 This setting applies to the ``converse-bookmarks`` plugin and specfically the
 list of bookmarks shown in the ``Rooms`` tab of the control box.
@@ -711,48 +711,6 @@ Makes sense to set this to ``true`` when also using the non-core
 ``converse-roomslist`` plugin, which shows a list of currently open (i.e.
 "joined") rooms.
 
-include_offline_state
----------------------
-
-* Default: `false`
-
-Originally, converse.js included an `offline` state which the user could
-choose (along with `online`, `busy` and `away`).
-
-Eventually it was however decided to remove this state, since the `offline`
-state doesn't propagate across tabs like the others do.
-
-What's meant by "propagate across tabs", is that when you set the state to
-`offline` in one tab, and you have instances of converse.js open in other tabs
-in your browser, then those instances will not have their states changed to
-`offline` as well. For the other statees the change is however propagated.
-
-The reason for this is that according to the XMPP spec, there is no `offline`
-state. The only defined states are:
-
-* away -- The entity or resource is temporarily away.
-* chat -- The entity or resource is actively interested in chattiIng.
-* dnd -- The entity or resource is busy (dnd = "Do Not Disturb").
-* xa -- The entity or resource is away for an extended period (xa = "eXtended Away").
-
-Read the `relevant section in the XMPP spec <https://xmpp.org/rfcs/rfc6121.html#presence-syntax-children-show>`_
-for more info.
-
-What used to happen in converse.js when the `offline` state was chosen, is
-that a presence stanza with a `type` of `unavailable` was sent out.
-
-This is actually exactly what happens when you log out of converse.js as well,
-with the notable exception that in the `offline` state, the connection is not
-terminated. So you can at any time change your state to something else and
-start chatting again.
-
-This might be useful to people, however the fact that the `offline` state
-doesn't propagate across tabs means that the user experience is inconsistent,
-confusing and appears "broken".
-
-If you are however aware of this issue and still want to allow the `offline`
-state, then you can set this option to `true` to enable it.
-
 .. _`i18n`:
 
 i18n
@@ -767,7 +725,7 @@ The translations for that locale must be available in JSON format at the
 
 If an explicit locale is specified via the ``i18n`` setting and the
 translations for that locale are not found at the `locales_url``, then 
-then Converse.js will fall back to trying to determine the browser's language
+then Converse will fall back to trying to determine the browser's language
 and fetching those translations, or if that fails the default English texts
 will be used.
 
@@ -789,7 +747,7 @@ keepalive
 
 * Default:    ``true``
 
-Determines whether Converse.js will maintain the chat session across page
+Determines whether Converse will maintain the chat session across page
 loads.
 
 This setting should also be used in conjunction with ``authentication`` set to `prebind`_.
@@ -827,7 +785,7 @@ locales
         'ru', 'uk', 'zh'
     ]
 
-This setting restricts the locales that are supported by Converse.js and
+This setting restricts the locales that are supported by Converse and
 therefore what may be given as value for the :ref:`i18n` option.
 
 Any other locales will be ignored.
@@ -842,7 +800,7 @@ locales_url
 
 * Default: ``/locale/{{{locale}}}/LC_MESSAGES/converse.json``,
 
-The URL from where Converse.js should fetch translation JSON.
+The URL from where Converse should fetch translation JSON.
 
 The three curly braces ``{{{ }}}`` are
 `Mustache <https://github.com/janl/mustache.js#readme>`_-style
@@ -854,7 +812,7 @@ The variable being interpolated via the curly braces is ``locale``, which is
 the value passed in to the `i18n`_ setting, or the browser's locale or the
 default local or `en` (resolved in that order).
 
-From version 3.3.0, Converse.js no longer bundles all translations into its
+From version 3.3.0, Converse no longer bundles all translations into its
 final build file. Instead, only the relevant translations are fetched at
 runtime.
 
@@ -995,7 +953,7 @@ muc_show_join_leave
 
 * Default; ``true``
 
-Determines whether Converse.js will show info messages inside a chatroom
+Determines whether Converse will show info messages inside a chatroom
 whenever a user joins or leaves it.
 
 nickname
@@ -1028,6 +986,39 @@ This option specifies which icon is shown in HTML5 notifications, as provided
 by the ``src/converse-notification.js`` plugin.
 
 
+oauth_providers
+---------------
+
+* Default: ``[]``
+
+Allows you to specify a list of OAuth providers that the user may use to log in
+with.
+
+.. note::
+    Your XMPP server will have to support Oauth logins
+
+.. code-block:: javascript
+
+        converse.initialize({
+            oauth_providers: {
+                'github': {
+                    'client_id': '1338d9f7ff52b1309b29',
+                    'host': 'chat.example.org',
+                    'class': 'fa-github-alt',
+                    'id': 'github',
+                    'name': 'Github'
+                },
+                'twitter': {
+                    'client_id': '0332d98cff83b1999b22',
+                    'host': 'chat.example.org',
+                    'class': 'fa-twitter',
+                    'id': 'twitter',
+                    'name': 'Twitter'
+                }
+            },
+        });
+
+
 ping_interval
 -------------
 
@@ -1049,7 +1040,7 @@ play_sounds
 Plays a notification sound when you receive a personal message or when your
 nickname is mentioned in a chatroom.
 
-Inside the ``./sounds`` directory of the Converse.js repo you'll see MP3 and Ogg
+Inside the ``./sounds`` directory of the Converse repo you'll see MP3 and Ogg
 formatted sound files. We need both, because neither format is supported by all browsers.
 
 You can set the URL where the sound files are hosted with the `sounds_path`_
@@ -1089,12 +1080,12 @@ priority
 * Type:     Number
 
 Determines the priority used for presence stanzas sent out from this resource
-(i.e. this instance of Converse.js).
+(i.e. this instance of Converse).
 
 The priority of a given XMPP chat client determines the importance of its presence
 stanzas in relation to stanzas received from other clients of the same user.
 
-In Converse.js, the indicated chat status of a roster contact will be taken from the
+In Converse, the indicated chat status of a roster contact will be taken from the
 presence stanza (and associated resource) with the highest priority.
 
 If multiple resources have the same top priority, then the chat status will be
@@ -1110,6 +1101,39 @@ providers_link
 The hyperlink on the registration form which points to a directory of public
 XMPP servers.
 
+push_app_servers
+----------------
+
+* Default: ``[]``
+
+This option lets you enable or disable so-called push notification "App Servers"
+(as per `XEP-0357 <https://xmpp.org/extensions/xep-0357.html>`_).
+
+For each "App Server" an object needs to be passed in. When enabling, you need
+to specify ``jid`` and ``node`` values. You can also provide a
+``secret``, if required by your App Server.
+
+When disabling, you need to specify at least a ``jid`` and set ``disabled`` to
+``true``. This will disable notifications to all pubsub nodes on that "App
+Server". If you want to disable only a particular node, then specify a ``node``
+value as well.
+
+For example:
+
+
+.. code-block:: javascript
+
+        converse.initialize({
+            'push_app_servers':  [{
+                'jid': 'push-4@client.example',
+                'node': 'yxs32uqsflafdk3iuqo',
+                'disable': true
+            }, {
+                'jid': 'push-5@client.example',
+                'node': 'yxs32uqsflafdk3iuqo',
+            }]
+        });
+
 root
 ----
 
@@ -1150,7 +1174,7 @@ configured.
 
 .. note::
     It's currently not possible to use converse.js to assign contacts to groups.
-    Converse.js can only show users and groups that were previously configured
+    Converse can only show users and groups that were previously configured
     elsewhere.
 
 show_chatstate_notifications
@@ -1163,7 +1187,7 @@ Specifies whether chat state (online, dnd, away) HTML5 desktop notifications sho
 show_controlbox_by_default
 --------------------------
 
-* Default:  ``false`` (``true`` for inVerse)
+* Default:  ``false`` (``true`` when the ``view_mode`` is set to ``fullscreen``)
 
 The "controlbox" refers to the special chatbox containing your contacts roster,
 status widget, chatrooms and other controls.
@@ -1280,7 +1304,7 @@ See also `trusted`_.
 sticky_controlbox
 -----------------
 
-* Default: ``false`` (``true`` for inVerse).
+* Default: ``false`` (``true`` when the ``view_mode`` is set to ``fullscreen``).
 
 If set to ``true``, the control box (which includes the login, registration,
 contacts and rooms tabs) will not be closeable. It won't have a close button at
@@ -1304,10 +1328,10 @@ loaded), then an error will be raised.
 
 Otherwise a message will simply be logged and the override instruction ignored.
 
-The Converse.js plugins architecture can have an :ref:`dependencies`
+The Converse plugins architecture can have an :ref:`dependencies`
 plugin attribute. This enables you to specify an array of other plugins which
 this one depends on.
-Converse.js (more specifically, `pluggable.js <https://jcbrand.github.io/pluggable.js/>`_)
+Converse (more specifically, `pluggable.js <https://jcbrand.github.io/pluggable.js/>`_)
 will first load these dependencies before executing the plugin's overrides and
 calling its ``initialize`` method.
 
@@ -1344,7 +1368,7 @@ This setting determines whether the default value of the "This is a trusted devi
 When the current device is not trusted, then localStorage and sessionStorage
 will be cleared when the user logs out, thereby removing all cached data.
 
-Clearing the cache in this way makes Converse.js much slower when the user logs
+Clearing the cache in this way makes Converse much slower when the user logs
 in again, because all data needs to be fetch anew.
 
 See also `storage`_.
@@ -1365,7 +1389,7 @@ use_otr_by_default
 
 * Default:  ``false``
 
-If set to ``true``, Converse.js will automatically try to initiate an OTR (off-the-record)
+If set to ``true``, Converse will automatically try to initiate an OTR (off-the-record)
 encrypted chat session every time you open a chatbox.
 
 visible_toolbar_buttons
@@ -1424,7 +1448,7 @@ support.
     configuration setting).
 
 .. note::
-    Converse.js does not yet support "keepalive" with websockets.
+    Converse does not yet support "keepalive" with websockets.
 
 .. _`view_mode`:
 
@@ -1468,6 +1492,9 @@ Since version 3.3.0, the ``inverse.js`` and ``converse-mobile.js`` builds no
 longer exist. Instead the standard ``converse.js`` build is used, together with
 the appropriate ``view_mode`` value.
 
+Since verseion 4.0.0, there is now also only one CSS file to be used for all
+the different view modes, ``converse.css``.
+
 The ``converse-muc-embedded.js`` build is still kept, because it's smaller than
 ``converse.js`` due to unused code being removed. It doesn't however contain
 any new code, so the full ``converse.js`` build could be used instead, as long
@@ -1476,19 +1503,6 @@ as ``view_mode`` is set to ``embedded``.
 Furthermore, it's no longer necessary to whitelist or blacklist any plugins
 when switching view modes.
 
-.. note::
-    Although the ``view_mode`` setting has removed the need for different
-    JavaScript builds, you'll still need to use different CSS files depending
-    on the view mode.
-
-    * For ``embedded`` you need to use ``./css/converse-muc-embedded.css``
-    * For ``fullscreen`` you need ``./css/inverse.css``
-    * For ``mobile`` you need to use both ``./css/converse.css`` and ``./css/mobile.css``
-    * For ``overlayed`` this is ``./css/converse.css``
-
-    Hopefully in a future release the CSS files will be combined and you'll
-    only need ``converse.css``
-
 
 .. _`whitelisted_plugins`:
 
@@ -1500,7 +1514,7 @@ whitelisted_plugins
 A list of plugin names that are whitelisted and will therefore be
 initialized once ``converse.initialize`` is called.
 
-From Converse.js 3.0 onwards most of the API is available only to plugins and
+From Converse 3.0 onwards most of the API is available only to plugins and
 all plugins need to be whitelisted first.
 
 This is done to prevent malicious scripts from using the API to trick users or

+ 39 - 22
docs/source/events.rst

@@ -7,7 +7,7 @@
 Events and promises
 ===================
 
-Converse.js and its plugins emit various events which you can listen to via the
+Converse and its plugins emit various events which you can listen to via the
 :ref:`listen-grouping`.
 
 Some of these events are also available as `ES2015 Promises <http://es6-features.org/#PromiseUsage>`_,
@@ -294,6 +294,25 @@ Also available as an `ES2015 Promise <http://es6-features.org/#PromiseUsage>`_:
         // Your code here...
     });
 
+privateChatsAutoJoined
+~~~~~~~~~~~~~~~~~~~~~~
+
+Emitted once any private chats have been automatically joined as specified by
+the _`auto_join_private_chats` settings.
+
+.. code-block:: javascript
+
+    _converse.api.listen.on('privateChatsAutoJoined', function () { ... });
+
+Also available as an `ES2015 Promise <http://es6-features.org/#PromiseUsage>`_.
+
+.. code-block:: javascript
+
+    _converse.api.waitUntil('privateChatsAutoJoined').then(function () {
+        // Your code here...
+    });
+
+
 reconnecting
 ~~~~~~~~~~~~
 
@@ -311,24 +330,14 @@ have to be registered anew.
 
     _converse.api.listen.on('reconnected', function () { ... });
 
+registeredGlobalEventHandlers
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-privateChatsAutoJoined
-~~~~~~~~~~~~~~~~~~~~~~
-
-Emitted once any private chats have been automatically joined as specified by
-the _`auto_join_private_chats` settings.
+Called once Converse has registered its global event handlers (for events such
+as window resize or unload).
 
-.. code-block:: javascript
-
-    _converse.api.listen.on('privateChatsAutoJoined', function () { ... });
-
-Also available as an `ES2015 Promise <http://es6-features.org/#PromiseUsage>`_.
-
-.. code-block:: javascript
-
-    _converse.api.waitUntil('privateChatsAutoJoined').then(function () {
-        // Your code here...
-    });
+Plugins can listen to this event as cue to register their own global event
+handlers.
 
 roomsAutoJoined
 ---------------
@@ -466,6 +475,14 @@ Similar to `rosterInitialized`, but instead pertaining to reconnection. This
 event indicates that the Backbone collections representing the roster and its
 groups are now again available after converse.js has reconnected.
 
+serviceDiscovered
+~~~~~~~~~~~~~~~~~
+
+When converse.js has learned of a service provided by the XMPP server. See XEP-0030.
+
+``_converse.api.listen.on('serviceDiscovered', function (service) { ... });``
+
+
 .. _`statusInitialized`:
 
 statusInitialized
@@ -497,12 +514,12 @@ When own custom status message has changed.
 
 ``_converse.api.listen.on('statusMessageChanged', function (message) { ... });``
 
-serviceDiscovered
-~~~~~~~~~~~~~~~~~
-
-When converse.js has learned of a service provided by the XMPP server. See XEP-0030.
+streamFeaturesAdded
+~~~~~~~~~~~~~~~~~~~
 
-``_converse.api.listen.on('serviceDiscovered', function (service) { ... });``
+Emitted as soon as Converse has processed the stream features as advertised by
+the server. If you want to check whether a stream feature is supported before
+proceeding, then you'll first want to wait for this event.
 
 windowStateChanged
 ~~~~~~~~~~~~~~~~~~

+ 9 - 12
docs/source/features.rst

@@ -19,7 +19,7 @@ and a private chat with a URL fragment such as
 Off-the-record encryption
 =========================
 
-Converse.js supports `Off-the-record (OTR) <https://otr.cypherpunks.ca/>`_
+Converse supports `Off-the-record (OTR) <https://otr.cypherpunks.ca/>`_
 encrypted messaging.
 
 The OTR protocol not only **encrypts your messages**, it provides ways to
@@ -38,17 +38,17 @@ secure crypto.
 For harsh but fairly valid criticism of JavaScript cryptography, read:
 `JavaScript Cryptography Considered Harmful <http://www.matasano.com/articles/javascript-cryptography/>`_.
 
-To get an idea on how this applies to OTR support in Converse.js, please read
+To get an idea on how this applies to OTR support in Converse, please read
 `my thoughts on it <https://opkode.com/media/blog/2013/11/11/conversejs-otr-support>`_.
 
 For now, suffice to say that although its useful to have OTR support in
-Converse.js in order to avoid most eavesdroppers, if you need serious
+Converse in order to avoid most eavesdroppers, if you need serious
 communications privacy, then you're much better off using native software.
 
 Notifications
 =============
 
-From version 0.8.1 Converse.js can play a sound notification when you receive a
+From version 0.8.1 Converse can play a sound notification when you receive a
 message.
 
 For more info, refer to the :ref:`play-sounds` configuration setting.
@@ -61,13 +61,10 @@ For more info, refer to the :ref:`show-desktop-notifications` configuration sett
 Multilingual Support
 ====================
 
-Converse.js is translated into multiple languages. The default build,
-``converse.min.js``, includes all languages.
-
-Languages increase the size of the Converse.js significantly.
-
-If you only need one, or a subset of the available languages, it's better to
-make a custom build which includes only those languages that you need.
+Converse is translated into multiple languages. Translations are supplied in
+JSON format and are loaded on demand. Converse will expect to find the
+translations in the ``/locales`` path of your site. This can be changed via the
+:ref:`locales-url` configuration setting.
 
 Moderating chatrooms
 ====================
@@ -103,7 +100,7 @@ Here are the different commands that may be used to moderate a chatroom:
 Passwordless login with client certificates
 ===========================================
 
-Converse.js supports the SASL-EXTERNAL authentication mechanism, which can be
+Converse supports the SASL-EXTERNAL authentication mechanism, which can be
 used together with x509 client certificates to enable passwordless login or
 even 2-factor authentication.
 

+ 2 - 10
docs/source/quickstart.rst

@@ -34,8 +34,6 @@ via the *script* and *link* tags:
     <script src="https://cdn.conversejs.org/dist/converse.min.js" charset="utf-8"></script>
 
 
-.. note:: For the fullscreen :ref:`view_mode` version of converse.js, replace ``converse.min.css`` with ``inverse.min.css``.
-
 .. note:: Instead of always loading the latest version of Converse.js via the
     CDN, it's generally better to load a specific version (preferably the
     latest one), to avoid breakage when new backwards-incompatible versions are
@@ -111,19 +109,13 @@ split up into two parts, with the UI part dropped for this build.
 Fullscreen version
 ------------------
 
-Converse.js also comes in a fullscreen version (often referred to as Inverse).
+Converse.js also comes in a fullscreen version.
 A hosted version is available online at `inverse.chat <https://inverse.chat>`_.
 
 Originally this version was available as a separate build file, but 
 as of version 4.0.0 and higher, the difference between the "overlay" and the
 "fullscreen" versions of converse.js is simply a matter of configuring the 
-:ref:`view_mode` and including the right CSS file.
-
-For the default "overlay" version, ``converse.css`` is used, and for the
-"fullscreen" version ``inverse.css`` is used.
-
-We'd like to eventually not require two different CSS files, and to allow you
-to seamlessly switch between the different view modes.
+:ref:`view_mode`.
 
 To generate the headless build, run ``make dist/converse-headless.js`` and/or 
 ``make dist/converse-headless.min.js``.

+ 3 - 2
fullscreen.html

@@ -3,11 +3,12 @@
 <head>
     <meta charset="utf-8"/>
     <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
-    <title>inVerse</title>
+    <title>Converse</title>
     <link rel="shortcut icon" type="image/ico" href="css/images/favicon.ico"/>
     <script type="text/javascript" src="inverse-analytics.js"></script>
     <noscript><p><img src="//stats.opkode.com/piwik.php?idsite=5" style="border:0;" alt="" /></p></noscript>
-    <link type="text/css" rel="stylesheet" media="screen" href="css/inverse.css" />
+    <link type="text/css" rel="stylesheet" media="screen" href="css/converse.css" />
+    <link type="text/css" rel="stylesheet" media="screen" href="css/fullpage.css" />
     <script src="dist/converse.js"></script>
 </head>
 <body class="reset">

+ 101 - 12
index.html

@@ -5,7 +5,7 @@
     <meta charset="utf-8">
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
-    <meta name="description" content="Converse.js: An XMPP chat client which can be integrated into any website" />
+    <meta name="description" content="Converse: An XMPP chat client which can be integrated into any website" />
     <meta name="author" content="JC Brand" />
     <meta name="keywords" content="xmpp chat webchat converse.js" />
 
@@ -56,8 +56,8 @@
                     <li class="page-scroll">
                         <a href="#sponsors">Sponsor</a>
                     </li>
-                    <li>
-                        <a href="/docs/html/manual.html">User Manual</a>
+                    <li class="page-scroll">
+                        <a href="#hosting">Hosting</a>
                     </li>
                     <li>
                         <a href="/docs/html/index.html">Documentation</a>
@@ -107,7 +107,7 @@
             <div class="col-lg-8 col-lg-offset-2">
                 <h2>Converse is written in JavaScript and runs in your browser.</h2>
                 <p>You can start using it here immediately, or you can <a href="/docs/html/index.html">integrate it into your own website</a>.</p>
-                <p>Take a look at the <a href="/demo">demo page</a> for other examples of how Converse.js can be configured and used.</a>
+                <p>Take a look at the <a href="/demo">demo page</a> for other examples of how Converse can be configured and used.</a>
 
                 <p>
                     You can connect to any publically accessible <a href="http://xmpp.org" target="_blank" rel="noopener">XMPP/Jabber</a> server,
@@ -193,7 +193,7 @@
                             or <a href="https://mastodon.xyz/@jcbrand" target="_blank" rel="noopener">Mastodon</a>
                         <li>Chat with me via XMPP at <a href="xmpp:jc@opkode.com" class="xmpp JSnocheck" title="XMPP/Jabber">jc@opkode.com</a></li>
                         <li>For technical support, you can ask on <a href="http://stackoverflow.com/questions/tagged/converse.js">Stack Overflow</a>
-                        <li>The Converse.js XMPP chatroom: <a href="xmpp:discuss@conference.conversejs.org" class="xmpp JSnocheck" title="Converse.js chat room">discuss@conference.conversejs.org</a>.</li>
+                        <li>The Converse XMPP chatroom: <a href="xmpp:discuss@conference.conversejs.org" class="xmpp JSnocheck" title="Converse chat room">discuss@conference.conversejs.org</a>.</li>
                         <li>Please file bugs and feature requests on <a target="_blank" rel="noopener" href="https://github.com/jcbrand/converse.js/issues">Github</a>.</li>
                     </ul>
                 </div>
@@ -217,17 +217,19 @@
             <div class="row">
                 <div class="col-lg-8 col-lg-offset-2" style="margin-top: 3em">
                     <div class="sponsors">
-                        <h2>Converse.js is supported by:</h2>
+                        <h2>Converse is supported by:</h2>
                         <ul>
-                            <li><a href="https://www.keycdn.com/" target="_blank" rel="noopener"><img style="height: 3em" src="/logo/keycdn.svg" alt="KeyCDN"></a></li>
-                            <li><a href="https://wikisuite.org" target="_blank" rel="noopener"><img style="height: 4em" src="/logo/wikisuite-white.png" alt="WikiSuite"></a></li>
+                            <li><a href="https://www.keycdn.com/?utm_source=conversejs" target="_blank" rel="noopener"><img style="height: 3em" src="/logo/keycdn.svg" alt="KeyCDN"></a></li>
+                            <li><a href="https://wikisuite.org/?utm_source=conversejs" target="_blank" rel="noopener"><img style="height: 4em" src="/logo/wikisuite-white.png" alt="WikiSuite"></a></li>
+                            <li><a href="https://hostpresto.com/?utm_source=conversejs" target="_blank" rel="noopener"><img style="height: 3em" src="/logo/hostpresto.png" alt="HostPresto"></a></li>
                         </ul>
                     </div>
 
-                    <p class="sponsors-text">Converse.js is a software commons; available at no cost to you or anyone else.
-                       Sponsorships allow us to fund further development and improvements and are greatly appreciated.
-                       If you'd like to sponsor this project, please visit <a href="https://www.patreon.com/jcbrand" target="_blank" rel="noopener">Patreon</a>
-                       or <a href="https://liberapay.com/jcbrand" target="_blank" rel="noopener">Liberapay</a>.
+                    <p class="sponsors-text">Converse is a software commons, available at no cost to you or anyone else.
+                       Sponsorships allow us to fund further development and improvements.
+                       If you'd like to sponsor this project, please visit <a href="https://www.patreon.com/jcbrand" target="_blank" rel="noopener">Patreon</a>,
+                       <a href="https://liberapay.com/jcbrand" target="_blank" rel="noopener">Liberapay</a> or
+                       <a href="http://opkode.com/contact" target="_blank" rel="noopener">contact us</a>.
                     </p>
                 </div>
             </div>
@@ -235,6 +237,93 @@
     </section>
 </body>
 
+    <section class="outro content-section text-center" id="hosting">
+        <div class="container">
+            <div class="row">
+                <div class="col-lg-8 col-lg-offset-2" style="margin-top: 3em">
+                    <h2>XMPP Account Hosting</h2>
+                    <p>
+                        We provide free XMPP accounts under the domain <strong>conversejs.org</strong>.
+                        You can create an account directly through the app on
+                        this website or on <a href="https://inverse.chat" target="_blank" rel="noopener">inverse.chat</a>.
+                    </p>
+                    <p>
+                        If you're interested in professional XMPP hosting under your
+                        own domain name, please <a href="http://opkode.com/contact" target="_blank" rel="noopener">contact us</a>.
+                    </p>
+
+                    <div class="privacy-policy">
+                        <h3>Privacy policy and GDPR compliance</h3>
+                        <p>
+                            This service is provided on a pro bono basis. An email
+                            address is not needed to sign up and we don't sell or
+                            monetize any of your data.
+                        </p>
+                        <h4>Sharing of data with 3rd parties</h4>
+                        <p>
+                            We don't share any of your data with 3rd parties,
+                            except when necessary to run the service. For example,
+                            when you send a message to a user on a differerent XMPP
+                            server.
+                            Your presence information (whether you're online or
+                            not) is shared with contacts that you've added from
+                            other servers.
+                        </p>
+                        <p>
+                            Users on other XMPP servers
+                            can request access to your (optionally filled-in) VCard data.
+                            You can remove your VCard data through an XMPP client.
+                            The latest version of Converse supports this, and you can
+                            <a href="https://conversejs.org/4.0.0-alpha/fullscreen.html" target="_blank" rel="noopener">use it here</a>.
+                        </p>
+                        <h4>Data storage</h4>
+                        <p>
+                            Our XMPP server runs in a Hetzner data centre in
+                            Strasbourg, France.
+                        </p>
+                        <p>
+                            Your chat messages are archived for a period of 1
+                            month, after which they are deleted.
+                        </p>
+                        <p>
+                            Currently the <strong>conversejs.org</strong> XMPP
+                            server does not support HTTP-file upload, which means
+                            that we don't host any uploaded files of users.
+                        </p>
+                        <p>
+                            During normal operations we don't log or process IP
+                            addresses, although it might be necessary in certain
+                            cases where a problem needs to be debugged (hasn't
+                            happened yet). Logs older than 6 months are deleted.
+                        </p>
+                        <h4>Data portability</h4>
+                        <p>
+                            Currently there is no standardized way to move a
+                            user account from one XMPP server to another.
+                        </p>
+                        <p>
+                            If you'd like to have a copy of your data for
+                            transferal to another account, please <a href="http://opkode.com/contact" target="_blank" rel="noopener">contact us</a>.
+                        </p>
+                        <h4>Account deletion</h4>
+                        <p>
+                            Currently it's not possible to automatically delete
+                            your account via Converse, although you might be
+                            able to do so via other XMPP clients that support
+                            account deletion via
+                            <a href="https://xmpp.org/extensions/xep-0077.html" target="_blank" rel="noopener">XEP-0077</a>.
+                        </p>
+                        <p>
+                            You can always <a href="http://opkode.com/contact" target="_blank" rel="noopener">contact us</a>
+                            and we'll delete your account manually.
+                        </p>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </section>
+</body>
+
 <script>
     /*
     @licstart

+ 602 - 737
locale/converse.pot

@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Converse.js 3.3.4\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2018-05-17 11:19+0200\n"
+"POT-Creation-Date: 2018-06-04 18:44+0200\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,688 +17,402 @@ msgstr ""
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 
-#: dist/converse-no-dependencies.js:9853 dist/converse-no-dependencies.js:9882
-msgid "Download"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:9872
-#, javascript-format
-msgid "Download: \"%1$s"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:9895
-msgid "Download video file"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:9908
-msgid "Download audio file"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:11229
-msgid "The connection has dropped, attempting to reconnect."
-msgstr ""
-
-#: dist/converse-no-dependencies.js:11327
-msgid "An error occurred while connecting to the chat server."
-msgstr ""
-
-#: dist/converse-no-dependencies.js:11334
-msgid "Your Jabber ID and/or password is incorrect. Please try again."
-msgstr ""
-
-#: dist/converse-no-dependencies.js:11346
-#, javascript-format
-msgid "Sorry, we could not connect to the XMPP host with domain: %1$s"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:11348
-msgid "The XMPP server did not offer a supported authentication mechanism"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:16016
-#, javascript-format
-msgid "%1$s has invited you to join a chat room: %2$s"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:16018
-#, javascript-format
-msgid ""
-"%1$s has invited you to join a chat room: %2$s, and left the following "
-"reason: \"%3$s\""
-msgstr ""
-
-#: dist/converse-no-dependencies.js:16379
-#: dist/converse-no-dependencies.js:16464
-#: dist/converse-no-dependencies.js:33114
+#: dist/converse-no-dependencies.js:34242
+#: dist/converse-no-dependencies.js:34327
+#: dist/converse-no-dependencies.js:46646
 msgid "Bookmark this room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16465
+#: dist/converse-no-dependencies.js:34328
 msgid "The name for this bookmark:"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16466
+#: dist/converse-no-dependencies.js:34329
 msgid "Would you like this room to be automatically joined upon startup?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16467
+#: dist/converse-no-dependencies.js:34330
 msgid "What should your nickname for this room be?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16469
-#: dist/converse-no-dependencies.js:25296
-#: dist/converse-no-dependencies.js:25380
+#: dist/converse-no-dependencies.js:34332
+#: dist/converse-no-dependencies.js:42768
+#: dist/converse-no-dependencies.js:45592
+#: dist/converse-no-dependencies.js:45677
 msgid "Save"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16470
-#: dist/converse-no-dependencies.js:25376
-#: dist/converse-no-dependencies.js:32190
+#: dist/converse-no-dependencies.js:34333
+#: dist/converse-no-dependencies.js:42769
+#: dist/converse-no-dependencies.js:45673
+#: dist/converse-no-dependencies.js:51631
 msgid "Cancel"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16543
+#: dist/converse-no-dependencies.js:34406
 #, javascript-format
 msgid "Are you sure you want to remove the bookmark \"%1$s\"?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16659
+#: dist/converse-no-dependencies.js:34522
 msgid "Sorry, something went wrong while trying to save your bookmark."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16738
-#: dist/converse-no-dependencies.js:33112
+#: dist/converse-no-dependencies.js:34601
+#: dist/converse-no-dependencies.js:46644
 msgid "Leave this room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16739
+#: dist/converse-no-dependencies.js:34602
 msgid "Remove this bookmark"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16740
-#: dist/converse-no-dependencies.js:33113
+#: dist/converse-no-dependencies.js:34603
+#: dist/converse-no-dependencies.js:46645
 msgid "Unbookmark this room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16741
-#: dist/converse-no-dependencies.js:28819
-#: dist/converse-no-dependencies.js:33115
+#: dist/converse-no-dependencies.js:34604
+#: dist/converse-no-dependencies.js:42041
+#: dist/converse-no-dependencies.js:46647
 msgid "Show more information on this room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16744
-#: dist/converse-no-dependencies.js:28818
-#: dist/converse-no-dependencies.js:33117
+#: dist/converse-no-dependencies.js:34607
+#: dist/converse-no-dependencies.js:42040
+#: dist/converse-no-dependencies.js:46649
 msgid "Click to open this room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16780
+#: dist/converse-no-dependencies.js:34643
 msgid "Click to toggle the bookmarks list"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:16781
+#: dist/converse-no-dependencies.js:34644
 msgid "Bookmarks"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:21217
+#: dist/converse-no-dependencies.js:35089
 msgid "Sorry, could not determine file upload URL."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:21225
+#: dist/converse-no-dependencies.js:35097
 msgid "Sorry, could not determine upload URL."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:21257
+#: dist/converse-no-dependencies.js:35129
 msgid "Sorry, could not succesfully upload your file."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:21260
+#: dist/converse-no-dependencies.js:35132
 #, javascript-format
 msgid "Your server's response: \"%1$s\""
 msgstr ""
 
-#: dist/converse-no-dependencies.js:21442
+#: dist/converse-no-dependencies.js:35306
 msgid "Sorry, looks like file upload is not supported by your server."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:21452
+#: dist/converse-no-dependencies.js:35316
 #, javascript-format
 msgid ""
 "The size of your file, %1$s, exceeds the maximum allowed by your server, "
 "which is %2$s."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22197
-msgid "Show more"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:22248
-msgid "Typing from another device"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:22250
-msgid "is typing"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:22254
-msgid "Stopped typing on the other device"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:22256
-msgid "has stopped typing"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:22259
-#: dist/converse-no-dependencies.js:23256
-#: dist/converse-no-dependencies.js:30521
-msgid "has gone away"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:22488
+#: dist/converse-no-dependencies.js:36039
 msgid "Close this chat box"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22516
+#: dist/converse-no-dependencies.js:36067
 msgid "The User's Profile Image"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22519
-#: dist/converse-no-dependencies.js:25289
-#: dist/converse-no-dependencies.js:25374
+#: dist/converse-no-dependencies.js:36070
+#: dist/converse-no-dependencies.js:45585
+#: dist/converse-no-dependencies.js:45671
 msgid "Close"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22520
-#: dist/converse-no-dependencies.js:25290
+#: dist/converse-no-dependencies.js:36071
+#: dist/converse-no-dependencies.js:45586
 msgid "Email"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22521
-#: dist/converse-no-dependencies.js:25291
+#: dist/converse-no-dependencies.js:36072
+#: dist/converse-no-dependencies.js:45587
 msgid "Full Name"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22522
+#: dist/converse-no-dependencies.js:36073
 msgid "Jabber ID"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22523
-#: dist/converse-no-dependencies.js:25292
-#: dist/converse-no-dependencies.js:29617
+#: dist/converse-no-dependencies.js:36074
+#: dist/converse-no-dependencies.js:42924
+#: dist/converse-no-dependencies.js:45588
 msgid "Nickname"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22524
+#: dist/converse-no-dependencies.js:36075
 msgid "Remove as contact"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22525
+#: dist/converse-no-dependencies.js:36076
 msgid "Refresh"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22526
-#: dist/converse-no-dependencies.js:25294
+#: dist/converse-no-dependencies.js:36077
+#: dist/converse-no-dependencies.js:45590
 msgid "Role"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22527
-#: dist/converse-no-dependencies.js:25297
+#: dist/converse-no-dependencies.js:36078
+#: dist/converse-no-dependencies.js:45593
 msgid "URL"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22566
-#: dist/converse-no-dependencies.js:24293
+#: dist/converse-no-dependencies.js:36117
+#: dist/converse-no-dependencies.js:48307
 msgid "Are you sure you want to remove this contact?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22575
-#: dist/converse-no-dependencies.js:25325
+#: dist/converse-no-dependencies.js:36126
+#: dist/converse-no-dependencies.js:45621
 msgid "Error"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22575
-#: dist/converse-no-dependencies.js:24301
+#: dist/converse-no-dependencies.js:36126
+#: dist/converse-no-dependencies.js:48315
 #, javascript-format
 msgid "Sorry, there was an error while trying to remove %1$s as a contact."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22629
-#: dist/converse-no-dependencies.js:22667
-#: dist/converse-no-dependencies.js:29029
+#: dist/converse-no-dependencies.js:36180
+#: dist/converse-no-dependencies.js:36218
+#: dist/converse-no-dependencies.js:42291
 msgid "You have unread messages"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22653
+#: dist/converse-no-dependencies.js:36204
 msgid "Hidden message"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22655
+#: dist/converse-no-dependencies.js:36206
 msgid "Personal message"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22662
-#: dist/converse-no-dependencies.js:29026
+#: dist/converse-no-dependencies.js:36213
+#: dist/converse-no-dependencies.js:42288
 msgid "Send"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22663
+#: dist/converse-no-dependencies.js:36214
 msgid "Optional hint"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22692
+#: dist/converse-no-dependencies.js:36252
 msgid "Choose a file to send"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22748
+#: dist/converse-no-dependencies.js:36308
 msgid "Click to write as a normal (non-spoiler) message"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22750
+#: dist/converse-no-dependencies.js:36310
 msgid "Click to write your message as a spoiler"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22754
+#: dist/converse-no-dependencies.js:36314
 msgid "Clear all messages"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22755
+#: dist/converse-no-dependencies.js:36315
 msgid "Insert emojis"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:22756
+#: dist/converse-no-dependencies.js:36316
 msgid "Start a call"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23069
-#: dist/converse-no-dependencies.js:29265
+#: dist/converse-no-dependencies.js:36629
+#: dist/converse-no-dependencies.js:42567
 msgid "Remove messages"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23069
+#: dist/converse-no-dependencies.js:36629
 msgid "Write in the third person"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23069
-#: dist/converse-no-dependencies.js:29267
+#: dist/converse-no-dependencies.js:36629
+#: dist/converse-no-dependencies.js:42567
 msgid "Show this menu"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23164
+#: dist/converse-no-dependencies.js:36728
 msgid "Are you sure you want to clear the messages from this conversation?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23254
-#: dist/converse-no-dependencies.js:30519
+#: dist/converse-no-dependencies.js:36817
+#: dist/converse-no-dependencies.js:45285
 msgid "has gone offline"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23258
-#: dist/converse-no-dependencies.js:30523
-msgid "is busy"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23260
-msgid "is online"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23501
-msgid "XMPP Username:"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23507
-msgid "Password:"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23509
-msgid "password"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23513
-#: dist/converse-no-dependencies.js:29643
-msgid "Submit"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23519
-msgid "Click here to log in anonymously"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23864
-msgid "This contact is busy"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23865
-msgid "This contact is online"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23866
-msgid "This contact is offline"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23867
-msgid "This contact is unavailable"
+#: dist/converse-no-dependencies.js:36819
+#: dist/converse-no-dependencies.js:41017
+#: dist/converse-no-dependencies.js:45287
+msgid "has gone away"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23868
-msgid "This contact is away for an extended period"
+#: dist/converse-no-dependencies.js:36821
+#: dist/converse-no-dependencies.js:45289
+msgid "is busy"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23869
-msgid "This contact is away"
+#: dist/converse-no-dependencies.js:36823
+msgid "is online"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23872
-#: dist/converse-no-dependencies.js:24584
-#: dist/converse-no-dependencies.js:25680
+#: dist/converse-no-dependencies.js:37209
+#: dist/converse-no-dependencies.js:47885
+#: dist/converse-no-dependencies.js:48606
 msgid "Contacts"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23874
-msgid "Groups"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23876
-msgid "My contacts"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23878
-msgid "Pending contacts"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23880
-msgid "Contact requests"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23882
-msgid "Ungrouped"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23925
-msgid "Contact name"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23925
-#: dist/converse-no-dependencies.js:28905
-msgid "Optional nickname"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23928
-msgid "Add a Contact"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23929
-msgid "XMPP Address"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:23931
-msgid "name@example.org"
+#: dist/converse-no-dependencies.js:37447
+msgid "Username"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:23932
-msgid "Add"
+#: dist/converse-no-dependencies.js:37447
+msgid "user@domain"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:24003
-#: dist/converse-no-dependencies.js:25917
+#: dist/converse-no-dependencies.js:37455
+#: dist/converse-no-dependencies.js:48016
 msgid "Please enter a valid XMPP address"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:24040
-msgid "Filter"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24041
-msgid "Filter by contact name"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24042
-msgid "Filter by group name"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24043
-msgid "Filter by status"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24044
-msgid "Any"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24045
-msgid "Unread"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24046
-#: dist/converse-no-dependencies.js:25379
-msgid "Online"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24047
-msgid "Chatty"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24048
-#: dist/converse-no-dependencies.js:25375
-msgid "Busy"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24049
-#: dist/converse-no-dependencies.js:25373
-msgid "Away"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24050
-msgid "Extended Away"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24051
-#: dist/converse-no-dependencies.js:25378
-msgid "Offline"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24205
-#: dist/converse-no-dependencies.js:24247
-#, javascript-format
-msgid "Click to remove %1$s as a contact"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24214
-#, javascript-format
-msgid "Click to accept the contact request from %1$s"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24215
-#, javascript-format
-msgid "Click to decline the contact request from %1$s"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24246
-#, javascript-format
-msgid "Click to chat with %1$s (JID: %2$s)"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24323
-msgid "Are you sure you want to decline this contact request?"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:24585
-msgid "Add a contact"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25288
-msgid "Your Profile"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25293
-msgid "XMPP Address (JID)"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25295
-msgid ""
-"Use commas to separate multiple roles. Your roles are shown next to your "
-"name on your chat messages."
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25298
-msgid "Your avatar image"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25325
-msgid "Sorry, an error happened while trying to save your profile data."
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25325
-msgid "You can check your browser's developer console for any error output."
+#: dist/converse-no-dependencies.js:37544
+msgid "Chat Contacts"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25377
-msgid "Custom status"
+#: dist/converse-no-dependencies.js:37544
+msgid "Toggle chat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25381
-msgid "Away for long"
+#: dist/converse-no-dependencies.js:38122
+msgid "The connection has dropped, attempting to reconnect."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25382
-msgid "Change chat status"
+#: dist/converse-no-dependencies.js:38220
+msgid "An error occurred while connecting to the chat server."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25383
-msgid "Personal status message"
+#: dist/converse-no-dependencies.js:38227
+msgid "Your Jabber ID and/or password is incorrect. Please try again."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25427
+#: dist/converse-no-dependencies.js:38239
 #, javascript-format
-msgid "I am %1$s"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25430
-msgid "Change settings"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25431
-msgid "Click to change your chat status"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25432
-msgid "Log out"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25433
-msgid "Your profile"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25456
-msgid "Are you sure you want to log out?"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25464
-#: dist/converse-no-dependencies.js:25474
-msgid "online"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25466
-msgid "busy"
-msgstr ""
-
-#: dist/converse-no-dependencies.js:25468
-msgid "away for long"
+msgid "Sorry, we could not connect to the XMPP host with domain: %1$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25470
-msgid "away"
+#: dist/converse-no-dependencies.js:38241
+msgid "The XMPP server did not offer a supported authentication mechanism"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25472
-msgid "offline"
+#: dist/converse-no-dependencies.js:40963
+msgid "Show more"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25909
-msgid "Username"
+#: dist/converse-no-dependencies.js:41006
+msgid "Typing from another device"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:25909
-msgid "user@domain"
+#: dist/converse-no-dependencies.js:41008
+msgid "is typing"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:26003
-msgid "Chat Contacts"
+#: dist/converse-no-dependencies.js:41012
+msgid "Stopped typing on the other device"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:26003
-msgid "Toggle chat"
+#: dist/converse-no-dependencies.js:41014
+msgid "has stopped typing"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:27529
-#: dist/converse-no-dependencies.js:27572
+#: dist/converse-no-dependencies.js:41245
+#: dist/converse-no-dependencies.js:41288
 msgid "Minimize this chat box"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:27705
+#: dist/converse-no-dependencies.js:41421
 msgid "Click to restore this chat"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:27892
+#: dist/converse-no-dependencies.js:41608
 msgid "Minimized"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28650
+#: dist/converse-no-dependencies.js:41937
 msgid "This room is not anonymous"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28651
+#: dist/converse-no-dependencies.js:41938
 msgid "This room now shows unavailable members"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28652
+#: dist/converse-no-dependencies.js:41939
 msgid "This room does not show unavailable members"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28653
+#: dist/converse-no-dependencies.js:41940
 msgid "The room configuration has changed"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28654
+#: dist/converse-no-dependencies.js:41941
 msgid "Room logging is now enabled"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28655
+#: dist/converse-no-dependencies.js:41942
 msgid "Room logging is now disabled"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28656
+#: dist/converse-no-dependencies.js:41943
 msgid "This room is now no longer anonymous"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28657
+#: dist/converse-no-dependencies.js:41944
 msgid "This room is now semi-anonymous"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28658
+#: dist/converse-no-dependencies.js:41945
 msgid "This room is now fully-anonymous"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28659
+#: dist/converse-no-dependencies.js:41946
 msgid "A new room has been created"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28663
+#: dist/converse-no-dependencies.js:41949
 msgid "You have been banned from this room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28664
+#: dist/converse-no-dependencies.js:41950
 msgid "You have been kicked from this room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28665
+#: dist/converse-no-dependencies.js:41951
 msgid "You have been removed from this room because of an affiliation change"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28666
+#: dist/converse-no-dependencies.js:41952
 msgid ""
 "You have been removed from this room because the room has changed to members-"
 "only and you're not a member"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28667
+#: dist/converse-no-dependencies.js:41953
 msgid ""
 "You have been removed from this room because the MUC (Multi-user chat) "
 "service is being shut down"
@@ -714,798 +428,949 @@ msgstr ""
 #. * can then at least tell gettext to scan for it so that these
 #. * strings are picked up by the translation machinery.
 #.
-#: dist/converse-no-dependencies.js:28681
+#: dist/converse-no-dependencies.js:41966
 #, javascript-format
 msgid "%1$s has been banned"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28682
+#: dist/converse-no-dependencies.js:41967
 #, javascript-format
 msgid "%1$s's nickname has changed"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28683
+#: dist/converse-no-dependencies.js:41968
 #, javascript-format
 msgid "%1$s has been kicked out"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28684
+#: dist/converse-no-dependencies.js:41969
 #, javascript-format
 msgid "%1$s has been removed because of an affiliation change"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28685
+#: dist/converse-no-dependencies.js:41970
 #, javascript-format
 msgid "%1$s has been removed for not being a member"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28689
+#: dist/converse-no-dependencies.js:41973
 #, javascript-format
 msgid "Your nickname has been automatically set to %1$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28690
+#: dist/converse-no-dependencies.js:41974
 #, javascript-format
 msgid "Your nickname has been changed to %1$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28724
-msgid "Description:"
+#: dist/converse-no-dependencies.js:41992
+msgid "Query for Chatrooms"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28725
-msgid "Room Address (JID):"
+#: dist/converse-no-dependencies.js:41993
+msgid "Server address"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28726
-msgid "Occupants:"
+#: dist/converse-no-dependencies.js:41994
+msgid "Show rooms"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28727
-msgid "Features:"
+#: dist/converse-no-dependencies.js:41995
+msgid "conference.example.org"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28728
-msgid "Requires authentication"
+#: dist/converse-no-dependencies.js:42053
+msgid "No rooms found"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28729
-#: dist/converse-no-dependencies.js:30122
-msgid "Hidden"
+#: dist/converse-no-dependencies.js:42070
+msgid "Rooms found:"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28730
-msgid "Requires an invitation"
+#: dist/converse-no-dependencies.js:42122
+msgid "Enter a new Chatroom"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28731
-#: dist/converse-no-dependencies.js:30125
-msgid "Moderated"
+#: dist/converse-no-dependencies.js:42123
+msgid "Room address"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28732
-#: dist/converse-no-dependencies.js:30126
-msgid "Non-anonymous"
+#: dist/converse-no-dependencies.js:42124
+#: dist/converse-no-dependencies.js:47938
+msgid "Optional nickname"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28733
-msgid "Open room"
+#: dist/converse-no-dependencies.js:42125
+msgid "name@conference.example.org"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28734
-msgid "Permanent room"
+#: dist/converse-no-dependencies.js:42126
+msgid "Join"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28735
-#: dist/converse-no-dependencies.js:30130
-msgid "Public"
+#: dist/converse-no-dependencies.js:42169
+msgid "Description:"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28736
-#: dist/converse-no-dependencies.js:30131
-msgid "Semi-anonymous"
+#: dist/converse-no-dependencies.js:42170
+msgid "Features:"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28737
-msgid "Temporary room"
+#: dist/converse-no-dependencies.js:42171
+#: dist/converse-no-dependencies.js:43424
+msgid "Hidden"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28738
-#: dist/converse-no-dependencies.js:30133
-msgid "Unmoderated"
+#: dist/converse-no-dependencies.js:42172
+#: dist/converse-no-dependencies.js:43427
+msgid "Moderated"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28777
-msgid "Query for Chatrooms"
+#: dist/converse-no-dependencies.js:42173
+#: dist/converse-no-dependencies.js:43428
+msgid "Non-anonymous"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28778
-msgid "Server address"
+#: dist/converse-no-dependencies.js:42174
+msgid "Online users:"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28779
-msgid "Show rooms"
+#: dist/converse-no-dependencies.js:42175
+msgid "Open room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28780
-msgid "conference.example.org"
+#: dist/converse-no-dependencies.js:42176
+msgid "Permanent room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28833
-msgid "No rooms found"
+#: dist/converse-no-dependencies.js:42177
+#: dist/converse-no-dependencies.js:43432
+msgid "Public"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28850
-msgid "Rooms found:"
+#: dist/converse-no-dependencies.js:42178
+msgid "Requires authentication"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28903
-msgid "Enter a new Chatroom"
+#: dist/converse-no-dependencies.js:42179
+msgid "Requires an invitation"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28904
-msgid "Room address"
+#: dist/converse-no-dependencies.js:42180
+#: dist/converse-no-dependencies.js:43433
+msgid "Semi-anonymous"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28906
-msgid "name@conference.example.org"
+#: dist/converse-no-dependencies.js:42181
+msgid "Temporary room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:28907
-msgid "Join"
+#: dist/converse-no-dependencies.js:42182
+#: dist/converse-no-dependencies.js:43435
+msgid "Unmoderated"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29025
+#: dist/converse-no-dependencies.js:42287
 msgid "Message"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29058
+#: dist/converse-no-dependencies.js:42322
 #, javascript-format
 msgid "%1$s is no longer a moderator"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29061
+#: dist/converse-no-dependencies.js:42326
 #, javascript-format
 msgid "%1$s has been given a voice again"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29064
+#: dist/converse-no-dependencies.js:42330
 #, javascript-format
 msgid "%1$s has been muted"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29067
+#: dist/converse-no-dependencies.js:42334
 #, javascript-format
 msgid "%1$s is now a moderator"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29077
+#: dist/converse-no-dependencies.js:42342
 msgid "Close and leave this room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29078
+#: dist/converse-no-dependencies.js:42343
 msgid "Configure this room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29122
+#: dist/converse-no-dependencies.js:42383
 msgid "Hide the list of occupants"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29206
+#: dist/converse-no-dependencies.js:42499
 #, javascript-format
 msgid ""
 "Error: the \"%1$s\" command takes two arguments, the user's nickname and "
 "optionally a reason."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29218
+#: dist/converse-no-dependencies.js:42508
 msgid ""
 "Sorry, an error happened while running the command. Check your browser's "
 "developer console for details."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29263
+#: dist/converse-no-dependencies.js:42567
 msgid "Change user's affiliation to admin"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29264
+#: dist/converse-no-dependencies.js:42567
 msgid "Ban user from room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29266
+#: dist/converse-no-dependencies.js:42567
 msgid "Change user role to participant"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29268
+#: dist/converse-no-dependencies.js:42567
 msgid "Kick user from room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29269
+#: dist/converse-no-dependencies.js:42567
 msgid "Write in 3rd person"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29270
+#: dist/converse-no-dependencies.js:42567
 msgid "Grant membership to a user"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29271
+#: dist/converse-no-dependencies.js:42567
 msgid "Remove user's ability to post messages"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29272
+#: dist/converse-no-dependencies.js:42567
 msgid "Change your nickname"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29273
+#: dist/converse-no-dependencies.js:42567
 msgid "Grant moderator role to user"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29274
+#: dist/converse-no-dependencies.js:42567
 msgid "Grant ownership of this room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29275
+#: dist/converse-no-dependencies.js:42567
 msgid "Revoke user's membership"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29276
+#: dist/converse-no-dependencies.js:42567
 msgid "Set room subject"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29277
+#: dist/converse-no-dependencies.js:42567
 msgid "Set room subject (alias for /subject)"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29278
+#: dist/converse-no-dependencies.js:42567
 msgid "Allow muted user to post messages"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29590
+#: dist/converse-no-dependencies.js:42897
 msgid ""
 "The nickname you chose is reserved or currently in use, please choose a "
 "different one."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29616
+#: dist/converse-no-dependencies.js:42923
 msgid "Please choose your nickname"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29618
+#: dist/converse-no-dependencies.js:42925
 msgid "Enter room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29641
+#: dist/converse-no-dependencies.js:42946
 msgid "This chatroom requires a password"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29642
+#: dist/converse-no-dependencies.js:42947
 msgid "Password: "
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29740
+#: dist/converse-no-dependencies.js:42948
+msgid "Submit"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:43062
 #, javascript-format
 msgid "This action was done by %1$s."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29743
-#: dist/converse-no-dependencies.js:29759
+#: dist/converse-no-dependencies.js:43066
+#: dist/converse-no-dependencies.js:43083
 #, javascript-format
 msgid "The reason given is: \"%1$s\"."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29781
+#: dist/converse-no-dependencies.js:43104
 #, javascript-format
 msgid "%1$s has left and re-entered the room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29786
+#: dist/converse-no-dependencies.js:43110
 #, javascript-format
 msgid "%1$s has entered the room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29788
+#: dist/converse-no-dependencies.js:43112
 #, javascript-format
 msgid "%1$s has entered the room. \"%2$s\""
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29818
+#: dist/converse-no-dependencies.js:43143
 #, javascript-format
 msgid "%1$s has entered and left the room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29820
+#: dist/converse-no-dependencies.js:43145
 #, javascript-format
 msgid "%1$s has entered and left the room. \"%2$s\""
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29832
+#: dist/converse-no-dependencies.js:43158
 #, javascript-format
 msgid "%1$s has left the room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29834
+#: dist/converse-no-dependencies.js:43160
 #, javascript-format
 msgid "%1$s has left the room. \"%2$s\""
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29877
+#: dist/converse-no-dependencies.js:43206
 msgid "You are not on the member list of this room."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29879
+#: dist/converse-no-dependencies.js:43208
 msgid "You have been banned from this room."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29883
+#: dist/converse-no-dependencies.js:43212
 msgid "No nickname was specified."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29887
+#: dist/converse-no-dependencies.js:43216
 msgid "You are not allowed to create new rooms."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29889
+#: dist/converse-no-dependencies.js:43218
 msgid "Your nickname doesn't conform to this room's policies."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29893
+#: dist/converse-no-dependencies.js:43222
 msgid "This room does not (yet) exist."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29895
+#: dist/converse-no-dependencies.js:43224
 msgid "This room has reached its maximum number of occupants."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29950
+#: dist/converse-no-dependencies.js:43274
 #, javascript-format
 msgid "Topic set by %1$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29981
+#: dist/converse-no-dependencies.js:43297
 msgid "Chatrooms"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29982
+#: dist/converse-no-dependencies.js:43298
 msgid "Add a new room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:29983
+#: dist/converse-no-dependencies.js:43299
 msgid "Query for rooms"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30022
+#: dist/converse-no-dependencies.js:43337
 #, javascript-format
 msgid "Click to mention %1$s in your message."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30023
+#: dist/converse-no-dependencies.js:43338
 msgid "This user is a moderator."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30024
+#: dist/converse-no-dependencies.js:43339
 msgid "This user can send messages in this room."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30025
+#: dist/converse-no-dependencies.js:43340
 msgid "This user can NOT send messages in this room."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30026
+#: dist/converse-no-dependencies.js:43341
 msgid "Moderator"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30027
+#: dist/converse-no-dependencies.js:43342
 msgid "Visitor"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30028
+#: dist/converse-no-dependencies.js:43343
 msgid "Owner"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30029
+#: dist/converse-no-dependencies.js:43344
 msgid "Member"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30030
+#: dist/converse-no-dependencies.js:43345
 msgid "Admin"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30082
+#: dist/converse-no-dependencies.js:43387
 msgid "Occupants"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30102
-#: dist/converse-no-dependencies.js:30209
+#: dist/converse-no-dependencies.js:43404
+#: dist/converse-no-dependencies.js:43511
 msgid "Invite"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30121
+#: dist/converse-no-dependencies.js:43423
 msgid "Features"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30123
+#: dist/converse-no-dependencies.js:43425
 msgid "Message archiving"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30124
+#: dist/converse-no-dependencies.js:43426
 msgid "Members only"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30127
+#: dist/converse-no-dependencies.js:43429
 msgid "Open"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30128
+#: dist/converse-no-dependencies.js:43430
 msgid "Password protected"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30129
+#: dist/converse-no-dependencies.js:43431
 msgid "Persistent"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30132
+#: dist/converse-no-dependencies.js:43434
 msgid "Temporary"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30134
+#: dist/converse-no-dependencies.js:43436
 msgid "No password"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30135
+#: dist/converse-no-dependencies.js:43437
 msgid "This room is not publicly searchable"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30136
+#: dist/converse-no-dependencies.js:43438
 msgid "Messages are archived on the server"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30137
+#: dist/converse-no-dependencies.js:43439
 msgid "This room is restricted to members only"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30138
+#: dist/converse-no-dependencies.js:43440
 msgid "This room is being moderated"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30139
+#: dist/converse-no-dependencies.js:43441
 msgid "All other room occupants can see your XMPP username"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30140
+#: dist/converse-no-dependencies.js:43442
 msgid "Anyone can join this room"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30141
+#: dist/converse-no-dependencies.js:43443
 msgid "This room requires a password before entry"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30142
+#: dist/converse-no-dependencies.js:43444
 msgid "This room persists even if it's unoccupied"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30143
+#: dist/converse-no-dependencies.js:43445
 msgid "This room is publicly searchable"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30144
+#: dist/converse-no-dependencies.js:43446
 msgid "Only moderators can see your XMPP username"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30145
+#: dist/converse-no-dependencies.js:43447
 msgid "This room will disappear once the last person leaves"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30146
+#: dist/converse-no-dependencies.js:43448
 msgid "This room is not being moderated"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30147
+#: dist/converse-no-dependencies.js:43449
 msgid "This room does not require a password upon entry"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30187
+#: dist/converse-no-dependencies.js:43488
 #, javascript-format
 msgid ""
 "You are about to invite %1$s to the chat room \"%2$s\". You may optionally "
 "include a message, explaining the reason for the invitation."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30208
+#: dist/converse-no-dependencies.js:43510
 msgid "Please enter a valid XMPP username"
 msgstr ""
 
+#: dist/converse-no-dependencies.js:44865
+#, javascript-format
+msgid "%1$s has invited you to join a chat room: %2$s"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:44867
+#, javascript-format
+msgid ""
+"%1$s has invited you to join a chat room: %2$s, and left the following "
+"reason: \"%3$s\""
+msgstr ""
+
 #. workaround for Prosody which doesn't give type "headline"
-#: dist/converse-no-dependencies.js:30469
-#: dist/converse-no-dependencies.js:30475
+#: dist/converse-no-dependencies.js:45235
+#: dist/converse-no-dependencies.js:45241
 #, javascript-format
 msgid "Notification from %1$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30477
-#: dist/converse-no-dependencies.js:30488
-#: dist/converse-no-dependencies.js:30491
+#: dist/converse-no-dependencies.js:45243
+#: dist/converse-no-dependencies.js:45254
+#: dist/converse-no-dependencies.js:45257
 #, javascript-format
 msgid "%1$s says"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30525
+#: dist/converse-no-dependencies.js:45291
 msgid "has come online"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30542
+#: dist/converse-no-dependencies.js:45308
 msgid "wants to be your contact"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30824
-msgid "Re-establishing encrypted session"
+#: dist/converse-no-dependencies.js:45584
+msgid "Your Profile"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:45589
+msgid "XMPP Address (JID)"
 msgstr ""
 
-#. We need to generate a new key and instance tag
-#: dist/converse-no-dependencies.js:30835
-msgid "Generating private key."
+#: dist/converse-no-dependencies.js:45591
+msgid ""
+"Use commas to separate multiple roles. Your roles are shown next to your "
+"name on your chat messages."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30835
-msgid "Your browser might become unresponsive."
+#: dist/converse-no-dependencies.js:45594
+msgid "Your avatar image"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30878
-#, javascript-format
-msgid ""
-"Authentication request from %1$s\n"
-"\n"
-"Your chat contact is attempting to verify your identity, by asking you the "
-"question below.\n"
-"\n"
-"%2$s"
+#: dist/converse-no-dependencies.js:45621
+msgid "Sorry, an error happened while trying to save your profile data."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30887
-msgid "Could not verify this user's identify."
+#: dist/converse-no-dependencies.js:45621
+msgid "You can check your browser's developer console for any error output."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:30941
-msgid "Exchanging private key with contact."
+#: dist/converse-no-dependencies.js:45670
+#: dist/converse-no-dependencies.js:48062
+msgid "Away"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31038
-msgid "Your messages are not encrypted anymore"
+#: dist/converse-no-dependencies.js:45672
+#: dist/converse-no-dependencies.js:48061
+msgid "Busy"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31040
-msgid ""
-"Your messages are now encrypted but your contact's identity has not been "
-"verified."
+#: dist/converse-no-dependencies.js:45674
+msgid "Custom status"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31042
-msgid "Your contact's identify has been verified."
+#: dist/converse-no-dependencies.js:45675
+#: dist/converse-no-dependencies.js:48064
+msgid "Offline"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31044
-msgid "Your contact has ended encryption on their end, you should do the same."
+#: dist/converse-no-dependencies.js:45676
+#: dist/converse-no-dependencies.js:48059
+msgid "Online"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31054
-msgid "Your message could not be sent"
+#: dist/converse-no-dependencies.js:45678
+msgid "Away for long"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31056
-msgid "We received an unencrypted message"
+#: dist/converse-no-dependencies.js:45679
+msgid "Change chat status"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31058
-msgid "We received an unreadable encrypted message"
+#: dist/converse-no-dependencies.js:45680
+msgid "Personal status message"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31084
+#: dist/converse-no-dependencies.js:45724
 #, javascript-format
-msgid ""
-"Here are the fingerprints, please confirm them with %1$s, outside of this "
-"chat.\n"
-"\n"
-"Fingerprint for you, %2$s: %3$s\n"
-"\n"
-"Fingerprint for %1$s: %4$s\n"
-"\n"
-"If you have confirmed that the fingerprints match, click OK, otherwise click "
-"Cancel."
-msgstr ""
-
-#: dist/converse-no-dependencies.js:31096
-msgid ""
-"You will be prompted to provide a security question and then an answer to "
-"that question.\n"
-"\n"
-"Your contact will then be prompted the same question and if they type the "
-"exact same answer (case sensitive), their identity will be verified."
+msgid "I am %1$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31097
-msgid "What is your security question?"
+#: dist/converse-no-dependencies.js:45727
+msgid "Change settings"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31100
-msgid "What is the answer to the security question?"
+#: dist/converse-no-dependencies.js:45728
+msgid "Click to change your chat status"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31104
-msgid "Invalid authentication scheme provided"
+#: dist/converse-no-dependencies.js:45729
+msgid "Log out"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31121
-msgid "Your messages are not encrypted. Click here to enable OTR encryption."
+#: dist/converse-no-dependencies.js:45730
+msgid "Your profile"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31123
-msgid "Your messages are encrypted, but your contact has not been verified."
+#: dist/converse-no-dependencies.js:45753
+msgid "Are you sure you want to log out?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31125
-msgid "Your messages are encrypted and your contact verified."
+#: dist/converse-no-dependencies.js:45761
+#: dist/converse-no-dependencies.js:45771
+msgid "online"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31127
-msgid ""
-"Your contact has closed their end of the private session, you should do the "
-"same"
+#: dist/converse-no-dependencies.js:45763
+msgid "busy"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:45765
+msgid "away for long"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:45767
+msgid "away"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:45769
+msgid "offline"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:45923
+msgid " e.g. conversejs.org"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:45970
+msgid "Fetch registration form"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:45971
+msgid "Tip: A list of public XMPP providers is available"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31141
-msgid "End encrypted conversation"
+#: dist/converse-no-dependencies.js:45972
+msgid "here"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31142
-msgid "Refresh encrypted conversation"
+#: dist/converse-no-dependencies.js:46020
+msgid "Sorry, we're unable to connect to your chosen provider."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31143
-msgid "Start encrypted conversation"
+#: dist/converse-no-dependencies.js:46036
+msgid ""
+"Sorry, the given provider does not support in band account registration. "
+"Please try with a different provider."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31144
-msgid "Verify with fingerprints"
+#: dist/converse-no-dependencies.js:46060
+#, javascript-format
+msgid ""
+"Something went wrong while establishing a connection with \"%1$s\". Are you "
+"sure it exists?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31145
-msgid "Verify with SMP"
+#: dist/converse-no-dependencies.js:46223
+msgid "Now logging you in"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31146
-msgid "What's this?"
+#: dist/converse-no-dependencies.js:46227
+msgid "Registered successfully"
 msgstr ""
 
-#. Translation aware constants
-#. ---------------------------
-#. We can only call the __ translation method *after* converse.js
-#. has been initialized and with it the i18n machinery. That's why
-#. we do it here in the "initialize" method and not at the top of
-#. the module.
-#: dist/converse-no-dependencies.js:31189
-msgid "unencrypted"
+#: dist/converse-no-dependencies.js:46336
+msgid ""
+"The provider rejected your registration attempt. Please check the values you "
+"entered for correctness."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31190
-msgid "unverified"
+#: dist/converse-no-dependencies.js:46705
+msgid "Click to toggle the rooms list"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31191
-msgid "verified"
+#: dist/converse-no-dependencies.js:46706
+msgid "Open Rooms"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31192
-msgid "finished"
+#: dist/converse-no-dependencies.js:46750
+#, javascript-format
+msgid "Are you sure you want to leave the room %1$s?"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31788
+#: dist/converse-no-dependencies.js:47359
 #, javascript-format
 msgid "Sorry, there was an error while trying to add %1$s as a contact."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:31936
+#: dist/converse-no-dependencies.js:47570
 msgid "This client does not allow presence subscriptions"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32028
+#: dist/converse-no-dependencies.js:47678
 msgid "Click to hide these contacts"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32112
-msgid "Don't have a chat account?"
+#: dist/converse-no-dependencies.js:47877
+msgid "This contact is busy"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32114
-msgid "Create an account"
+#: dist/converse-no-dependencies.js:47878
+msgid "This contact is online"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32126
-msgid "Create your account"
+#: dist/converse-no-dependencies.js:47879
+msgid "This contact is offline"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32128
-msgid "Please enter the XMPP provider to register with:"
+#: dist/converse-no-dependencies.js:47880
+msgid "This contact is unavailable"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32148
-msgid "Already have a chat account?"
+#: dist/converse-no-dependencies.js:47881
+msgid "This contact is away for an extended period"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32150
-msgid "Log in here"
+#: dist/converse-no-dependencies.js:47882
+msgid "This contact is away"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32162
-msgid "Account Registration:"
+#: dist/converse-no-dependencies.js:47887
+msgid "Groups"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32170
-msgid "Register"
+#: dist/converse-no-dependencies.js:47889
+msgid "My contacts"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32174
-msgid "Choose a different provider"
+#: dist/converse-no-dependencies.js:47891
+msgid "Pending contacts"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32186
-msgid "Hold tight, we're fetching the registration form…"
+#: dist/converse-no-dependencies.js:47893
+msgid "Contact requests"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32321
-msgid " e.g. conversejs.org"
+#: dist/converse-no-dependencies.js:47895
+msgid "Ungrouped"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32367
-msgid "Fetch registration form"
+#: dist/converse-no-dependencies.js:47938
+msgid "Contact name"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32368
-msgid "Tip: A list of public XMPP providers is available"
+#: dist/converse-no-dependencies.js:47941
+msgid "Add a Contact"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32369
-msgid "here"
+#: dist/converse-no-dependencies.js:47942
+msgid "XMPP Address"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32417
-msgid "Sorry, we're unable to connect to your chosen provider."
+#: dist/converse-no-dependencies.js:47944
+msgid "name@example.org"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32433
-msgid ""
-"Sorry, the given provider does not support in band account registration. "
-"Please try with a different provider."
+#: dist/converse-no-dependencies.js:47945
+msgid "Add"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:48053
+msgid "Filter"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:48054
+msgid "Filter by contact name"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:48055
+msgid "Filter by group name"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:48056
+msgid "Filter by status"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:48057
+msgid "Any"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:48058
+msgid "Unread"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:48060
+msgid "Chatty"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:48063
+msgid "Extended Away"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32457
+#: dist/converse-no-dependencies.js:48219
+#: dist/converse-no-dependencies.js:48261
 #, javascript-format
-msgid ""
-"Something went wrong while establishing a connection with \"%1$s\". Are you "
-"sure it exists?"
+msgid "Click to remove %1$s as a contact"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32620
-msgid "Now logging you in"
+#: dist/converse-no-dependencies.js:48228
+#, javascript-format
+msgid "Click to accept the contact request from %1$s"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32624
-msgid "Registered successfully"
+#: dist/converse-no-dependencies.js:48229
+#, javascript-format
+msgid "Click to decline the contact request from %1$s"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:48260
+#, javascript-format
+msgid "Click to chat with %1$s (JID: %2$s)"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:48337
+msgid "Are you sure you want to decline this contact request?"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:48607
+msgid "Add a contact"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:50080
+msgid "Room Address (JID)"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:50084
+msgid "Title"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:50088
+msgid "Description"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:51158
+msgid "XMPP Username:"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:51164
+msgid "Password:"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:51166
+msgid "password"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:32733
+#: dist/converse-no-dependencies.js:51174
+msgid "This is a trusted device"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:51176
 msgid ""
-"The provider rejected your registration attempt. Please check the values you "
-"entered for correctness."
+"To improve performance, we cache your data in this browser. Uncheck this box "
+"if this is a public computer or if you want your data to be deleted when you "
+"log out. It's important that you explicitly log out, otherwise not all "
+"cached data might be deleted."
 msgstr ""
 
-#: dist/converse-no-dependencies.js:33149
-msgid "Click to toggle the rooms list"
+#: dist/converse-no-dependencies.js:51178
+msgid "Log in"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:33150
-msgid "Open Rooms"
+#: dist/converse-no-dependencies.js:51184
+msgid "Click here to log in anonymously"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:51526
+msgid "Don't have a chat account?"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:51528
+msgid "Create an account"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:51549
+msgid "Create your account"
 msgstr ""
 
-#: dist/converse-no-dependencies.js:33194
+#: dist/converse-no-dependencies.js:51551
+msgid "Please enter the XMPP provider to register with:"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:51571
+msgid "Already have a chat account?"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:51573
+msgid "Log in here"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:51594
+msgid "Account Registration:"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:51602
+msgid "Register"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:51606
+msgid "Choose a different provider"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:51627
+msgid "Hold tight, we're fetching the registration form…"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:52762
+#: dist/converse-no-dependencies.js:52791
+msgid "Download"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:52781
 #, javascript-format
-msgid "Are you sure you want to leave the room %1$s?"
+msgid "Download: \"%1$s"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:52804
+msgid "Download video file"
+msgstr ""
+
+#: dist/converse-no-dependencies.js:52817
+msgid "Download audio file"
 msgstr ""

BIN
logo/hostpresto.png


+ 1 - 1
mockup/chatbox.html

@@ -5,7 +5,7 @@
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <title>Converse.js Mockups</title>
     <link type="text/css" rel="stylesheet" media="screen" href="../../node_modules/font-awesome/css/font-awesome.css" />
-    <link type="text/css" rel="stylesheet" media="screen" href="../../css/inverse.css" />
+    <link type="text/css" rel="stylesheet" media="screen" href="../../css/converse.css" />
 </head>
 
 <body class="reset">

+ 2 - 3
mockup/chatroom.html

@@ -5,7 +5,7 @@
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <title>Chatroom Fullscreen</title>
     <link type="text/css" rel="stylesheet" media="screen" href="../../node_modules/font-awesome/css/font-awesome.css" />
-    <link type="text/css" rel="stylesheet" media="screen" href="../../css/inverse.css" />
+    <link type="text/css" rel="stylesheet" media="screen" href="../../css/converse.css" />
 </head>
 
 <body class="reset">
@@ -23,12 +23,11 @@
             <div class="chatbox chatroom" id="chatroom">
                 <div class="flyout box-flyout">
                     <div class="chat-head chat-head-chatroom row no-gutters">
-                        <div class="col col-9">
+                        <div class="chatbox-title">
                             <div class="chat-title">Capulet's orchard</div>
                             <p class="chatroom-description">Two households, both alike in dignity, In fair Verona, where we lay our scene.</p>
                         </div>
                         <div class="chatbox-buttons row no-gutters">
-                            <a class="chatbox-btn fa fa-minus"></a>
                             <a class="chatbox-btn fa fa-close"></a>
                             <a class="chatbox-btn fa fa-wrench"></a>
                         </div>

+ 1 - 1
mockup/fullscreen-login.html

@@ -6,7 +6,7 @@
     <title>Login Fullscreen</title>
     <link type="text/css" rel="stylesheet" media="screen" href="../../node_modules/bootstrap/dist/css/bootstrap.css" />
     <link type="text/css" rel="stylesheet" media="screen" href="../../node_modules/font-awesome/css/font-awesome.css" />
-    <link type="text/css" rel="stylesheet" media="screen" href="../../css/inverse.css" />
+    <link type="text/css" rel="stylesheet" media="screen" href="../../css/converse.css" />
 </head>
 
 <body>

Datei-Diff unterdrückt, da er zu groß ist
+ 790 - 338
package-lock.json


+ 21 - 13
package.json

@@ -1,8 +1,8 @@
 {
   "name": "converse.js",
   "version": "3.3.4",
-  "description": "Browser based XMPP instant messaging client",
-  "main": "main.js",
+  "description": "Browser based XMPP chat client",
+  "main": "dist/converse.js",
   "directories": {
     "doc": "docs",
     "locale": "locale",
@@ -20,20 +20,24 @@
     "chatrooms",
     "webchat"
   ],
-  "author": "JC Brand",
+  "author": {
+    "name": "JC Brand",
+    "email": "jc@opkode.com"
+  },
   "license": "MPL-2.0",
   "bugs": {
-    "url": "https://github.com/jcbrand/converse.js/issues"
+    "url": "https://github.com/conversejs/converse.js/issues"
   },
   "engines": {
     "browser": "*"
   },
   "devDependencies": {
-    "@babel/cli": "^7.0.0-beta.35",
-    "@babel/core": "^7.0.0-beta.35",
-    "@babel/preset-env": "^7.0.0-beta.35",
-    "almond": "~0.3.3",
+    "@babel/cli": "^7.0.0-beta.48",
+    "@babel/core": "^7.0.0-beta.48",
+    "@babel/preset-env": "^7.0.0-beta.48",
+    "@babel/preset-es2015": "^7.0.0-beta.49",
     "awesomplete-avoid-xss": "^1.1.2",
+    "babel-loader": "^8.0.0-beta.3",
     "backbone": "1.3.3",
     "backbone.browserStorage": "0.0.3",
     "backbone.nativeview": "^0.3.3",
@@ -48,9 +52,12 @@
     "es6-promise": "^4.1.0",
     "eslint": "4.19.1",
     "eslint-plugin-lodash": "^2.3.3",
+    "exports-loader": "^0.7.0",
     "filesize": "^3.6.1",
     "font-awesome": "^4.7.0",
+    "hellojs": "^1.16.1",
     "http-server": "^0.10.0",
+    "imports-loader": "^0.8.0",
     "install": "^0.9.5",
     "jasmine-core": "2.6.4",
     "jed": "1.1.1",
@@ -60,7 +67,10 @@
     "lodash": "4.17.4",
     "lodash-template-loader": "^2.0.0",
     "long": "^3.1.0",
+    "lodash-template-webpack-loader": "jcbrand/lodash-template-webpack-loader",
+    "minimist": "^1.2.0",
     "moment": "~> 2.19.3 ",
+    "npm": "^5.7.1",
     "otr": "0.2.16",
     "pluggable.js": "2.0.0",
     "po2json": "^0.4.4",
@@ -70,17 +80,15 @@
     "sinon": "^2.1.0",
     "sizzle": "^2.3.3",
     "snabbdom": "0.7.1",
-    "strophe.js": "1.2.14",
+    "strophe.js": "1.2.15",
     "strophejs-plugin-ping": "0.0.1",
     "strophejs-plugin-register": "0.0.1",
     "strophejs-plugin-rsm": "0.0.1",
-    "text": "requirejs/text#2.0.15",
     "uglify-es": "^3.0.24",
     "urijs": "^1.19.1",
     "wait-until-promise": "^1.0.0",
+    "webpack": "^4.0.1",
+    "webpack-cli": "^2.1.4",
     "xss": "^0.3.3"
-  },
-  "dependencies": {
-    "npm": "^5.7.1"
   }
 }

+ 18 - 0
redirect.html

@@ -0,0 +1,18 @@
+<!doctype html>
+<html class="no-js" lang="en">
+<head>
+    <meta charset="utf-8"/>
+    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
+    <title>Converse</title>
+    <link rel="shortcut icon" type="image/ico" href="css/images/favicon.ico"/>
+    <link type="text/css" rel="stylesheet" media="screen" href="css/converse.css" />
+    <script src="node_modules/hellojs/dist/hello.all.js"></script>
+</head>
+<body>
+    <div class="content">
+        <div class="inner-content">
+            <h1 class="brand-heading"><i class="icon-conversejs"></i> Converse</h1>
+        </div>
+    </div>
+</body>
+</html>

+ 1 - 0
requirements.txt

@@ -0,0 +1 @@
+zc.buildout==2.11.4

+ 0 - 1
sass/_awesomplete.scss

@@ -1,4 +1,3 @@
-#converse-embedded-chat,
 #conversejs {
     [hidden] { display: none; }
 

+ 232 - 14
sass/_chatbox.scss

@@ -1,7 +1,9 @@
 #conversejs {
+    .chatbox-navback {
+        display: none;
+    }
     .flyout {
         border-radius: $chatbox-border-radius;
-        bottom: $chatbox-hover-height;
         position: absolute;
 
         @media screen and (max-height: $mobile-landscape-height) {
@@ -38,7 +40,6 @@
         flex-wrap: nowrap;
         color: #ffffff;
         font-size: 100%;
-        height: $chat-head-height;
         margin: 0;
         padding: 0.5em;
         position: relative;
@@ -53,6 +54,11 @@
             margin-right: 0.5em;
         }
 
+        .chatbox-title {
+            .chatroom-description {
+                font-size: 80%;
+            }
+        }
         .chatbox-buttons {
             flex-direction: row-reverse;
             @include make-col-ready();
@@ -120,8 +126,6 @@
             justify-content: space-between;
             background-color: $chat-head-color;
             box-shadow: 1px 3px 5px 3px rgba(0, 0, 0, 0.4);
-            height: $chat-height;
-            min-height: $chat-height/2;
             z-index: 1;
             overflow-y: scroll;
             width: 100%;
@@ -246,7 +250,6 @@
                 width: 100%;
                 border: none;
                 min-height: $chat-textarea-height;
-                max-height: $max-chat-textarea-height;
                 margin-bottom: -4px; // Not clear why this is necessar :(
                 &.spoiler {
                     height: 42px;
@@ -330,7 +333,6 @@
                         }
                         ul {
                             &.emoji-picker {
-                                height: $emoji-picker-height;
                                 overflow: scroll;
                                 padding: 0.5em;
                             }
@@ -434,33 +436,224 @@
     }
 }
 
+/* ******************* Overlay and embedded styles *************************** */
+
+#conversejs.converse-embedded,
+#conversejs.converse-overlayed {
+    .chat-head {
+        border-top-left-radius: $chatbox-border-radius;
+        border-top-right-radius: $chatbox-border-radius;
+        @media screen and (max-height: $mobile-landscape-height) {
+            border-top-left-radius: 0;
+            border-top-right-radius: 0;
+        }
+        @media screen and (max-width: $mobile-portrait-length) {
+            border-top-left-radius: 0;
+            border-top-right-radius: 0;
+        }
+        .chatbox-title {
+            @include make-col(8);
+        }
+        .chatbox-buttons {
+            @include make-col(4);
+        }
+    }
+
+    .chatbox {
+        min-width: $overlayed-chat-width!important;
+        width: $overlayed-chat-width;
+
+        .box-flyout {
+            min-width: $overlayed-chat-width!important;
+            width: $overlayed-chat-width;
+        }
+
+        .chat-body {
+            .chat-message {
+                line-height: $line-height-large;
+                .chat-msg-author {
+                    line-height: $line-height-large;
+                }
+                .chat-msg-content {
+                    line-height: $line-height-large;
+                    .emojione {
+                        margin-bottom: -5px;
+                    }
+                }
+            }
+        }
+    }
+    .chatbox {
+        form.sendXMPPMessage {
+            .chat-toolbar {
+                li {
+                    .toolbar-menu {
+                        min-width: 235px;
+
+                        ul {
+                            &.emoji-toolbar {
+                                width: 100%;
+                                .emoji-category {
+                                    float: left;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
+#conversejs.converse-overlayed  {
+    .flyout {
+        bottom: $overlayed-chatbox-hover-height;
+    }
+    .box-flyout {
+        height: $overlayed-chat-height;
+        min-height: $overlayed-chat-height/2;
+    }
+    .chat-head {
+        height: $overlayed-chat-head-height;
+    }
+    .chat-textarea {
+        max-height: $overlayed-max-chat-textarea-height;
+    }
+    .emoji-picker {
+        height: $overlayed-emoji-picker-height;
+    }
+}
+
+@include media-breakpoint-down(sm) {
+	#conversejs.converse-overlayed {
+		> .row {
+			flex-direction: column;
+
+            &.no-gutters {
+                margin: -1em;
+            }
+		}
+	}
+}
+
+/* ******************* Fullpage styles *************************** */
+
 #conversejs.converse-fullscreen  {
+    .flyout {
+        border-radius: 0;
+        border-top: 0.8em solid $chat-head-color;
+        border: $flyout-padding solid $chat-head-color;
+        bottom: 0;
+    }
     .chatbox-btn {
         font-size: $fullpage-chatbox-button-size;
+        margin: 0 0.3em;
     }
     .chat-head {
+        height: $fullpage-chat-head-height;
+        font-size: $font-size-huge;
+        padding: 0;
+        .user-custom-message {
+            font-size: 50%;
+            height: auto;
+            line-height: $line-height;
+        }
+        .chatbox-title {
+            @include make-col(10);
+        }
         .chatbox-buttons {
-            @include make-col(3);
+            @include make-col(2);
+        }
+    }
+    .chat-textarea {
+        max-height: $fullpage-max-chat-textarea-height;
+    }
+    .emoji-picker {
+        height: $fullpage-emoji-picker-height;
+    }
+
+    .chatbox {
+        width: 100%;
+        height: 100%;
+        margin: 0;
+
+        @include make-col-ready();
+        @include media-breakpoint-up(md) {
+            @include make-col(9);
+        }
+        @include media-breakpoint-up(lg) {
+            @include make-col(9);
+        }
+        @include media-breakpoint-up(xl) {
+            @include make-col(10);
+        }
+
+        .box-flyout {
+            background-color: $chat-head-color;
+            box-shadow: none;
+            height: $fullpage-chat-height;
+            min-height: $fullpage-chat-height/2;
+            width: $fullpage-chat-width;
+        }
+        .chat-body {
+            background-color: $chat-head-color;
+            border-top-left-radius: $chatbox-border-radius;
+            border-top-right-radius: $chatbox-border-radius;
+
+            .chat-message {
+                line-height: $line-height;
+                font-size: $font-size-small;
+                .chat-msg-author {
+                    line-height: $line-height;
+                }
+                .chat-msg-content {
+                    line-height: $line-height;
+                    .emojione {
+                        height: $line-height;
+                        margin-bottom: -$line-height/4;
+                    }
+                }
+            }
+        }
+        .chat-content {
+            border-top-left-radius: $chatbox-border-radius;
+            border-top-right-radius: $chatbox-border-radius;
+        }
+        .chat-title {
+            font-size: $font-size-huge;
+            line-height: $line-height-huge;
+        }
+        .sendXMPPMessage {
+            ul {
+                width: 100%;
+            }
+            .toggle-smiley {
+                ul {
+                    &.emoji-toolbar {
+                        .emoji-category-picker {
+                            margin-right: 5em;
+                        }
+                        .emoji-category {
+                            padding-left: 10px;
+                            padding-right: 10px;
+                        }
+                    }
+                }
+            }
         }
     }
 }
 
-@media screen and (max-width: 767px) {
+@include media-breakpoint-down(sm) {
     #conversejs:not(.converse-embedded)  {
         > .row {
             flex-direction: row-reverse;
         }
-
         #converse-login-panel {
             .converse-form {
                 padding: 3em 2em 3em;
             }
         }
-
-        .sidebar {
-            display: block;
-        }
-
         .chatbox {
             width: calc(100% - 50px);
             .row {
@@ -473,4 +666,29 @@
             }
         }
     }
+
+    #conversejs.converse-mobile,
+    #conversejs.converse-overlayed,
+    #conversejs.converse-embedded,
+    #conversejs.converse-fullscreen {
+        .chatbox {
+            .box-flyout {
+                .chatbox-navback {
+                    display: flex;
+                    @include make-col(2);
+                    .fa-arrow-left {
+                        &:before {
+                            color: white;
+                        }
+                    }
+                }
+                .chatbox-title {
+                    @include make-col(7);
+                }
+                .chatbox-buttons {
+                    @include make-col(3);
+                }
+            }
+        }
+    }
 }

+ 157 - 32
sass/_chatrooms.scss

@@ -7,12 +7,37 @@
         }
     }
 
+    #room-details-modal {
+        .features-list {
+            margin-left: 1em;
+        }
+    }
+
+    .chatroom-features {
+        width: 100%;
+        .features-list {
+            padding-top: 0;
+            .feature {
+                width: 100%;
+                margin-right: 0.5em;
+                padding-right: 0;
+                font-size: 1em;
+                cursor: help;
+                .fa {
+                    margin-right: 0.5em;
+                    color: $text-color;
+                }
+            }
+        }
+    }
+
+
     .chat-head-chatroom {
         background-color: $chatroom-head-color;
 
         .chatroom-description {
             color: lighten($chatroom-head-color, 25%);
-            font-size: $font-size-large;
+            font-size: $font-size;
             font-size: 70%;
             margin-top: 3px;
             overflow-y: hidden;
@@ -101,16 +126,12 @@
                     display: flex;
                     flex-direction: column;
                     word-wrap: break-word; 
-                    min-width: $chat-width;
                     .new-msgs-indicator {
                         background-color: $chatroom-head-color;
                     }
                     .chat-content {
                         height: 100%;
                     }
-                    &.full {
-                        min-width: 100%;
-                    }
                 }
                 .occupants {
                     display: flex;
@@ -124,21 +145,19 @@
                     border-bottom-right-radius: $chatbox-border-radius;
                     padding: 0.5em;
 
-                    .occupants-heading {
-                        font-family: $heading-font; 
-                        padding: 0.3em 0;
-                    }
-
-                    .chatroom-features {
-                        width: 100%;
-                        .feature {
-                            float: left;
-                            margin-right: 0.5em;
-                            padding-right: 0;
-                            font-size: 1em;
-                            cursor: help;
+                    .occupants-header {
+                        display: flex;
+                        flex-direction: column;
+                        .hide-occupants {
+                            align-self: flex-end;
+                            cursor: pointer;
+                        }
+                        .occupants-heading {
+                            font-family: $heading-font; 
+                            padding: 0.3em 0;
                         }
                     }
+
                     .awesomplete {
                         ul {
                             padding: 0;
@@ -160,15 +179,6 @@
                             flex-grow: 1;
                             border-bottom: 1px solid lightgrey;
                         }
-                        &.features-list {
-                            padding-top: 0;
-                            .feature {
-                                width: 100%;
-                                .fa {
-                                    color: $text-color;
-                                }
-                            }
-                        }
                         li {
                             cursor: default;
                             display: block;
@@ -279,13 +289,128 @@
     }
 }
 
-@media screen and (max-width: 767px) {
-    #conversejs:not(.converse-embedded)  {
-        .chatbox {
+/* ******************* Overlay  styles *************************** */
+
+#conversejs.converse-overlayed {
+    .chatbox {
+        &.chatroom {
+            min-width: $chatroom-width !important;
+            width: $chatroom-width;
+            .box-flyout {
+                min-width: $chatroom-width !important;
+                width: $chatroom-width;
+            }
+            .chatbox-title {
+                @include make-col(8);
+                .chatroom-description {
+                    font-size: 80%;
+                }
+            }
+            .chatbox-buttons {
+                @include make-col(4);
+            }
+            .chatroom-body {
+                .occupants {
+                    .chatroom-features {
+                        .feature {
+                            font-size: $font-size-small;
+                        }
+                    }
+                }
+                .chat-area {
+                    min-width: $overlayed-chat-width;
+                }
+            }
+        }
+    }
+}
+
+#conversejs.converse-fullscreen {
+    .chatroom {
+        .box-flyout {
+            .chatbox-title {
+                @include make-col(9);
+            }
+            .chatbox-buttons {
+                @include make-col(3);
+            }
+        }
+    }
+}
+
+@include media-breakpoint-down(sm) {
+
+    #conversejs:not(.converse-embedded) {
+        .chatroom {
+            width: 100vw !important;
             .box-flyout {
-                .chatroom-body {
-                    .chat-area {
+                .chatbox-navback {
+                    @include make-col(2);
+                }
+                .chatbox-title {
+                    @include make-col(7);
+                }
+                .chatbox-buttons {
+                    @include make-col(3);
+                }
+            }
+        }
+    }
+}
+
+#conversejs.converse-fullscreen,
+#conversejs.converse-mobile {
+
+    .chatroom {
+        .box-flyout {
+            background-color: $chatroom-head-color;
+            border: $flyout-padding solid $chatroom-head-color;
+            border-top: 0.8em solid $chatroom-head-color;
+            width: 100%;
+
+            .chatbox-title {
+                .chatroom-description {
+                    font-size: 70%;
+                }
+            }
+
+            .chatroom-body {
+                @include border-top-radius($chatbox-border-radius);
+                .chatroom-form-container {
+                    border-radius: $chatbox-border-radius;
+                }
+                .chat-area {
+                    border-top-left-radius: $chatbox-border-radius;
+                    .chat-content {
+                        border-top-left-radius: $chatbox-border-radius;
                     }
+                    &.full {
+                        max-width: 100%;
+                        .new-msgs-indicator {
+                            max-width: 100%;
+                        }
+                    }
+                }
+                .occupants {
+                    border-top-right-radius: $chatbox-border-radius;;
+                    padding: $occupants-padding;
+                    .occupants-heading {
+                        font-size: $font-size-large;
+                    }
+                    ul {
+                        &.occupant-list {
+                            li {
+                                font-size: $font-size-small;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        .room-invite {
+            span {
+                .invited-contact {
+                    margin: 0 0 0.5em -1px;
                 }
             }
         }

+ 131 - 12
sass/_controlbox.scss

@@ -1,4 +1,24 @@
 #conversejs {
+    .oauth-providers {
+        text-align: center;
+        .oauth-provider {
+            margin: 1em 0;
+
+            .oauth-login {
+                margin-left: 0;
+                color: $link-color;
+                font-size: $font-size-large;
+                &:hover {
+                    color: darken($link-color, 20%);
+                }
+                i {
+                    color: $link-color;
+                    font-size: $font-size-huge;
+                    margin-right: 0.5em;
+                }
+            }
+        }
+    }
 
     .set-xmpp-status, .xmpp-status, .roster-contacts {
         .fa-circle {
@@ -173,15 +193,6 @@
             font-weight: bold;
         }
 
-        .oauth-login {
-            margin-left: 0;
-            color: $text-color;
-            .icon-social:before {
-                font-size: $font-size-large;
-            }
-        }
-
-
         .controlbox-pane {
             .userinfo {
                 padding-bottom: 1em;
@@ -296,6 +307,7 @@
             }
 
             .switch-form {
+                text-align: center;
                 padding: 2em 0;
                 p {
                     margin-top: 0.5em;
@@ -357,7 +369,6 @@
 
             .chatbox { 
                 .box-flyout {
-                    top: -100vh;
                     margin-left: 15px; // Counteracts Bootstrap margins, but
                                        // not clear why needed...
                     left: 0;
@@ -369,10 +380,11 @@
             }
 
             #controlbox {
-                order: 0;
+                width: 100vw !important;
                 .box-flyout {
                     width: 100vw !important;
                     height: 100vh !important;
+                    margin-left: 30px;
                 }
                 .sidebar {
                     display: block;
@@ -393,7 +405,7 @@
     }
 }
 
-#conversejs:not(.converse-fullscreen) {
+#conversejs.converse-overlayed {
     #controlbox {
         order: -1;
         min-width: $controlbox-width !important;
@@ -444,3 +456,110 @@
         }
     }
 }
+
+#conversejs.converse-fullscreen,
+#conversejs.converse-mobile {
+    #controlbox {
+        @include make-col-ready();
+        @include media-breakpoint-up(md) {
+            @include make-col(3);
+        }
+        @include media-breakpoint-up(lg) {
+            @include make-col(3);
+        }
+        @include media-breakpoint-up(xl) {
+            @include make-col(2);
+        }
+
+        &.logged-out {
+            @include make-col(12);
+        }
+
+        margin: 0;
+
+        .controlbox-pane {
+            border-radius: 0;
+        }
+
+        .flyout {
+            border-radius: 0;
+        }
+
+        #converse-login-panel {
+            border-radius: 0;
+            .converse-form {
+                padding: 3em 2em 3em;
+            }
+        }
+
+        .toggle-register-login {
+            line-height: $line-height-huge;
+        }
+
+        .brand-heading-container {
+            @include make-col(12);
+            text-align: center;
+            .brand-heading {
+                font-size: 150%;
+                font-size: 600%;
+                padding: 0.7em 0 0 0;
+                opacity: 0.8;
+                color: $blue;
+            }
+            .brand-subtitle {
+                font-size: 90%;
+                padding: 0.5em;
+            }
+            @media screen and (max-width: $mobile-portrait-length) {
+                .brand-heading {
+                    font-size: 400%;
+                }
+            }
+        }
+
+        &.logged-out {
+            @include make-col(12);
+            @include fade-in;
+            width: 100%;
+            .box-flyout {
+                width: 100%;
+            }
+        }
+        .box-flyout {
+            border: 0;
+            width: 100%;
+            z-index: 1;
+            background-color: $controlbox-head-color;
+
+            .controlbox-head {
+                display: none;
+            }
+        }
+
+        #converse-register, #converse-login {
+            @include make-col-ready();
+            @include make-col(8);
+            @include make-col-offset(2);
+
+            @include media-breakpoint-up(sm) {
+                @include make-col(8);
+                @include make-col-offset(2);
+            }
+            @include media-breakpoint-up(md) {
+                @include make-col(8);
+                @include make-col-offset(2);
+            }
+            @include media-breakpoint-up(lg) {
+                @include make-col(6);
+                @include make-col-offset(3);
+            }
+            .title, .instructions {
+                margin: 1em 0;
+            }
+            input[type=submit],
+            input[type=button] {
+                width: auto;
+            }
+        }
+    }
+}

+ 28 - 2
sass/_core.scss

@@ -61,6 +61,23 @@ body.reset {
     direction: ltr;
     z-index: 1031; // One more than bootstrap navbar
 
+    &.converse-overlayed {
+        > .row {
+            flex-direction: row-reverse;
+        }
+    }
+
+    &.converse-fullscreen,
+    &.converse-mobile {
+        .converse-chatboxes {
+            width: 100vw;
+            right: 15px; // Hack due to padding added by bootstrap
+        }
+    }
+    &.converse-overlayed {
+        height: 3em;
+    }
+
     .brand-heading {
         font-family: $heading-font; 
         .icon-conversejs {
@@ -76,7 +93,6 @@ body.reset {
         z-index: 1031; // One more than bootstrap navbar
         position: fixed;
         bottom: 0;
-        height: 2.7rem;
         right: 0;
     }
 
@@ -143,6 +159,10 @@ body.reset {
         font-weight: 700;
     }
 
+    em {
+        font-style: italic;
+    }
+
     ol, ul {
         list-style: none;
     }
@@ -156,10 +176,16 @@ body.reset {
         margin: 0;
     }
 
-    a, a:visited, a:hover, a:not([href]):not([tabindex]) {
+    a, a:visited, a:not([href]):not([tabindex]) {
         text-decoration: none;
         color: $link-color;
         text-shadow: none;
+        &:hover {
+            color: darken($link-color, 20%);
+            text-decoration: none;
+            text-shadow: none;
+        }
+
         &.fa {
             color: $subdued-color;
             &:hover {

+ 0 - 1
sass/_embedded.scss

@@ -1,5 +1,4 @@
 @import "bourbon";
-@import "converse/variables";
 #conversejs.converse-embedded {
 
     @include box-sizing(border-box);

+ 17 - 0
sass/_headline.scss

@@ -18,3 +18,20 @@
     }
 }
 
+#conversejs.converse-fullscreen {
+    .chatbox.headlines {
+        .box-flyout {
+            background-color: $headline-head-color;
+        }
+        .chat-head {
+            &.chat-head-chatbox {
+                background-color: $headline-head-color;
+            }
+        }
+        .flyout {
+            border: $flyout-padding solid $headline-head-color;
+            border-top: 0.8em solid $headline-head-color;
+        }
+    }
+}
+

+ 1 - 1
sass/converse/_minimized_chats.scss → sass/_minimized_chats.scss

@@ -1,4 +1,4 @@
-#conversejs:not(.fullscreen) {
+#conversejs.converse-overlayed {
     #minimized-chats {
         order: 100;
 

+ 6 - 0
sass/_roomslist.scss

@@ -32,6 +32,10 @@
             .open-chatroom {
                 &:hover {
                     background-color: lighten($controlbox-head-color, 45%);
+                    a.add-bookmark,
+                    a.room-info {
+                        display: block !important;
+                    }
                 }
                 &.unread-msgs {
                     .msgs-indicator {
@@ -48,7 +52,9 @@
                     &:hover {
                         color: $dark-link-color;
                     }
+                    &.add-bookmark,
                     &.room-info {
+                        display: none;
                         &:before {
                             font-size: 15px;
                         }

+ 0 - 4
sass/_roster.scss

@@ -4,10 +4,8 @@
     position: relative;
     margin: 0;
     height: $roster-height;
-    height: calc(~"100% - #{$controlbox-dropdown-height*2} - 20px");
     padding: 0;
     overflow: hidden;
-
     // XXX: FIXME
     height: calc(100% - 70px);
 
@@ -43,7 +41,6 @@
         }
         .state-type {
             font-size: calc(#{$font-size} - 2px);
-            height: $controlbox-dropdown-height;
             width: 100%;
         }
     }
@@ -142,7 +139,6 @@
                     .avatar {
                         float: left;
                         display: inline-block;
-                        height: $roster-item-height;
                     }
                 }
                 &.current-xmpp-contact span {

+ 32 - 2
sass/_variables.scss

@@ -63,6 +63,8 @@ $message-them-color: $green !default;
 
 $roster-height: 194px !default;
 
+$flyout-padding: 1.2em;
+
 $chat-head-color: $green !default;
 $chat-head-text-color: white !default;
 $chat-head-inverse-text-color: white !default;
@@ -110,10 +112,11 @@ $font-path: "../fonticons/fonts/" !default;
 $normal-font: "Helvetica", "Arial", sans-serif;
 $heading-font: 'Century Gothic', futura, 'URW Gothic L', Verdana, sans-serif !default;
 
-$chatroom-head-color: $red !default;
-$chatroom-color-light: $light-red !default;
 $chatroom-color-dark: $darkest-red !default;
+$chatroom-color-light: $light-red !default;
+$chatroom-head-color: $red !default;
 $chatroom-message-them-color: $green !default;
+$chatroom-width: 400px !default;
 
 $headline-head-color: $orange !default;
 
@@ -124,3 +127,30 @@ $box-close-button-padding-right: 4px !default;
 
 $chatbox-button-size: 14px !default;
 $fullpage-chatbox-button-size: 16px !default;
+
+$font-size-small: 12px !default;
+$font-size: 14px !default;
+$font-size-large: 16px !default;
+$font-size-huge: 20px !default;
+
+$legend-font-size: 16px !default;
+
+$line-height-small:  14px !default;
+$line-height:  16px !default;
+$line-height-large:  20px !default;
+$line-height-huge:  24px !default;
+
+$occupants-padding: 1em;
+
+$fullpage-chat-head-height: 62px !default;
+$fullpage-chat-height: 100vh;
+$fullpage-chat-width: 100%;
+$fullpage-emoji-picker-height: 150px !default;
+$fullpage-max-chat-textarea-height: 400px !default;
+
+$overlayed-chat-head-height: 55px !default;
+$overlayed-chat-height: 450px !default;
+$overlayed-chat-width: 250px !default;
+$overlayed-chatbox-hover-height: 1em !default;
+$overlayed-emoji-picker-height: 100px !default;
+$overlayed-max-chat-textarea-height: 200px !default;

+ 54 - 26
sass/_website.scss

@@ -113,29 +113,41 @@ a:hover, a:focus {
 .features-section,
 .outro,
 .intro {
-  width: 100%;
-  padding: 100px 0;
-  text-align: center;
-  color: #fff;
+    width: 100%;
+    padding: 100px 0;
+    text-align: center;
+    color: #fff;
 }
 .intro {
-  background: url(images/header.jpg) no-repeat bottom center scroll;
-  background-color: #211018;
-  -webkit-background-size: cover;
-  -moz-background-size: cover;
-  background-size: cover;
-  -o-background-size: cover;
+    background: url(images/header.jpg) no-repeat bottom center scroll;
+    background-color: #211018;
+    -webkit-background-size: cover;
+    -moz-background-size: cover;
+    background-size: cover;
+    -o-background-size: cover;
 }
 .features-section {
-  background: url('images/bgtr.svg') top right no-repeat, url('images/bgbl.svg') bottom left no-repeat, url('images/bgbl.svg') bottom left no-repeat, url('images/overlay.png'), linear-gradient(45deg, #85505f, #384955, #655361);
+    background: url('images/bgtr.svg') top right no-repeat, url('images/bgbl.svg') bottom left no-repeat, url('images/bgbl.svg') bottom left no-repeat, url('images/overlay.png'), linear-gradient(45deg, #85505f, #384955, #655361);
 }
 .features-section a {
-  color: #82B397;
+    color: #82B397;
 }
 .outro {
-  background: url('images/bgtr.svg') top right no-repeat, url('images/bgbl.svg') bottom left no-repeat, url('images/overlay.png'), linear-gradient(45deg, #384955, #655361, #85505f);
+    background: url('images/bgtr.svg') top right no-repeat, url('images/bgbl.svg') bottom left no-repeat, url('images/overlay.png'), linear-gradient(45deg, #384955, #655361, #85505f);
 }
 
+section {
+    h2 {
+        color: #E7A151;
+    }
+    h3 {
+        color: #89B7CD;
+    }
+    h4 {
+        color: #5CBC86;
+        font-size: 1.5em;
+    }
+}
 
 .brand-heading {
     font-family: Futura,Helvetica,Trebuchet MS,Arial,sans-serif;
@@ -205,25 +217,38 @@ a:hover, a:focus {
 }
 
 .content-section {
-  padding-top: 100px;
+    padding-top: 100px;
+    padding-top: 100px;
+    min-height: 100vh;
+
+    .privacy-policy {
+        padding-top: 2em;
+        h4 {
+            padding-top: 1.5em;
+        }
+        p {
+            font-size: 1.2em;
+            padding-bottom: 0;
+            margin-bottom: 1em;
+        }
+    }
 }
 .donate-section {
-  width: 100%;
-  padding: 50px 0;
-  color: #ffffff;
-  background-color: #211018;
+    width: 100%;
+    padding: 50px 0;
+    color: #ffffff;
+    background-color: #211018;
 }
 .donate-section p.bitcoin-header {
-  margin: 0 0 5px;
+    margin: 0 0 5px;
 }
 @media (min-width: 767px) {
-  .content-section {
-    padding-top: 150px;
-    padding-bottom: 50px;
-  }
-  .donate-section {
-    padding: 100px 0;
-  }
+    .content-section {
+        padding-bottom: 50px;
+    }
+    .donate-section {
+        padding: 100px 0;
+    }
 }
 .btn {
   font-family: Futura,Helvetica,Trebuchet MS,Arial,sans-serif;
@@ -332,6 +357,9 @@ ul.features {
     clear: both;
     font-size: 1.4em;
     padding: 2em 0 6em 0;
+    ul {
+        padding: 0;
+    }
 }
 .sponsors h2 {
     text-align: center;

+ 2 - 6
sass/converse.scss

@@ -2,13 +2,12 @@
  * Converse.js (Web-based XMPP instant messaging client)
  * http://conversejs.org
  *
- * Copyright (c) 2012-2016, JC Brand <jc@opkode.com>
+ * Copyright (c) 2013-2018, JC Brand <jc@opkode.com>
  * Licensed under the Mozilla Public License
  */
 @import "font-awesome";
 @import "bourbon";
 @import "variables";
-@import "converse/variables";
 
 @import "bootstrap/scss/functions";
 @import "bootstrap/scss/variables";
@@ -40,19 +39,16 @@
     @import "bootstrap/scss/utilities";
 }
 @import "core";
-@import "converse/core";
 @import "forms";
 @import "profile";
 @import "chatbox";
-@import "converse/chatbox";
 @import "controlbox";
 @import "roomslist";
 @import "roster";
 @import "chatrooms";
-@import "converse/chatrooms";
 @import "headline";
 @import "messages";
-@import "converse/minimized_chats";
+@import "minimized_chats";
 @import "bookmarks";
 @import "awesomplete";
 @import "embedded";

+ 0 - 71
sass/converse/_chatbox.scss

@@ -1,71 +0,0 @@
-#converse-embedded-chat,
-#conversejs:not(.fullscreen) {
-    .chat-head {
-        border-top-left-radius: $chatbox-border-radius;
-        border-top-right-radius: $chatbox-border-radius;
-        @media screen and (max-height: $mobile-landscape-height) {
-            border-top-left-radius: 0;
-            border-top-right-radius: 0;
-        }
-        @media screen and (max-width: $mobile-portrait-length) {
-            border-top-left-radius: 0;
-            border-top-right-radius: 0;
-        }
-    }
-    .chatbox {
-        min-width: $chat-width!important;
-        width: $chat-width;
-
-        .box-flyout {
-            min-width: $chat-width!important;
-            width: $chat-width;
-        }
-
-        .chat-body {
-            .chat-message {
-                line-height: $line-height-large;
-                .chat-msg-author {
-                    line-height: $line-height-large;
-                }
-                .chat-msg-content {
-                    line-height: $line-height-large;
-                    .emojione {
-                        margin-bottom: -5px;
-                    }
-                }
-            }
-        }
-    }
-    .chatbox {
-        form.sendXMPPMessage {
-            .chat-toolbar {
-                li {
-                    .toolbar-menu {
-                        min-width: 235px;
-
-                        ul {
-                            &.emoji-toolbar {
-                                width: 100%;
-                                .emoji-category {
-                                    float: left;
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
-
-@include media-breakpoint-down(sm) {
-	#conversejs:not(.converse-fullscreen):not(.converse-embedded) {
-		> .row {
-			flex-direction: column;
-
-            &.no-gutters {
-                margin: -1em;
-            }
-		}
-	}
-}

+ 0 - 22
sass/converse/_chatrooms.scss

@@ -1,22 +0,0 @@
-#conversejs {
-    .chatbox {
-        &.chatroom {
-            min-width: $chatroom-width !important;
-            width: $chatroom-width;
-            .box-flyout {
-                min-width: $chatroom-width !important;
-                width: $chatroom-width;
-            }
-
-            .chatroom-body {
-                .occupants {
-                    .chatroom-features {
-                        .feature {
-                            font-size: $font-size-small;
-                        }
-                    }
-                }
-            }
-        }
-    }
-}

+ 0 - 5
sass/converse/_core.scss

@@ -1,5 +0,0 @@
-#conversejs {
-    > .row {
-        flex-direction: row-reverse;
-    }
-}

+ 0 - 26
sass/converse/_variables.scss

@@ -1,26 +0,0 @@
-$max-chat-textarea-height: 200px !default;
-$emoji-picker-height: 100px !default;
-
-$roster-item-height: 60px !default;
-
-$chat-head-height: 55px !default;
-
-$controlbox-dropdown-height: 25px !default;
-$controlbox-head-height: 55px !default;
-
-$chatbox-hover-height: 1em !default;
-
-$font-size-small: 12px !default;
-$font-size: 14px !default;
-$font-size-large: 16px !default;
-$font-size-huge: 20px !default;
-$legend-font-size: 16px !default;
-
-$line-height-small:  14px !default;
-$line-height:  16px !default;
-$line-height-large:  20px !default;
-
-$chat-width: 250px !default;
-$chat-height: 450px !default;
-
-$chatroom-width: 400px !default;

+ 0 - 58
sass/inverse.scss

@@ -1,58 +0,0 @@
-/*!
- * Converse.js (Web-based XMPP instant messaging client)
- * http://conversejs.org
- *
- * Copyright (c) 2012-2014, JC Brand <jc@opkode.com>
- * Licensed under the Mozilla Public License
- */
-@import "font-awesome";
-@import "bourbon";
-@import "variables";
-@import "inverse/variables";
-
-@import "bootstrap/scss/functions";
-@import "bootstrap/scss/variables";
-@import "bootstrap/scss/mixins";
-#conversejs {
-    @import "bootstrap/scss/root";
-    @import "bootstrap/scss/reboot";
-    @import "bootstrap/scss/type";
-    @import "bootstrap/scss/images";
-    @import "bootstrap/scss/grid";
-    @import "bootstrap/scss/forms";
-    @import "bootstrap/scss/buttons";
-    @import "bootstrap/scss/transitions";
-    @import "bootstrap/scss/dropdown";
-    @import "bootstrap/scss/button-group";
-    @import "bootstrap/scss/input-group";
-    @import "bootstrap/scss/custom-forms";
-    @import "bootstrap/scss/card";
-    @import "bootstrap/scss/breadcrumb";
-    @import "bootstrap/scss/badge";
-    @import "bootstrap/scss/alert";
-    @import "bootstrap/scss/media";
-    @import "bootstrap/scss/list-group";
-    @import "bootstrap/scss/close";
-    @import "bootstrap/scss/modal";
-    @import "bootstrap/scss/tooltip";
-    @import "bootstrap/scss/popover";
-    @import "bootstrap/scss/utilities";
-}
-@import "core";
-@import "inverse/core";
-@import "forms";
-@import "profile";
-@import "chatbox";
-@import "inverse/chatbox";
-@import "controlbox";
-@import "inverse/controlbox";
-@import "roster";
-@import "roomslist";
-@import "inverse/roster";
-@import "bookmarks";
-@import "chatrooms";
-@import "inverse/chatrooms";
-@import "headline";
-@import "inverse/headline";
-@import "messages";
-@import "awesomplete"

+ 0 - 96
sass/inverse/_chatbox.scss

@@ -1,96 +0,0 @@
-#conversejs.fullscreen {
-    .chatbox-btn {
-        font-size: $font-size-large;
-        margin: 0 0.3em;
-    }
-    .flyout {
-        border-radius: 0;
-        border: $flyout-padding solid $chat-head-color;
-        border-top: 0.8em solid $chat-head-color;
-        bottom: 0;
-    }
-    .chat-head {
-        font-size: 20px;
-        padding: 0;
-        .user-custom-message {
-            font-size: 50%;
-            height: auto;
-            line-height: $line-height;
-        }
-    }
-    .chatbox {
-        width: 100%;
-        height: 100%;
-        margin: 0;
-
-        @include make-col-ready();
-        @include media-breakpoint-up(md) {
-            @include make-col(9);
-        }
-        @include media-breakpoint-up(xl) {
-            @include make-col(10);
-        }
-
-        .box-flyout {
-            background-color: $chat-head-color;
-            height: 100vh;
-            width: 100%;
-            box-shadow: none;
-        }
-        .chat-body {
-            background-color: $chat-head-color;
-            border-top-left-radius: $chatbox-border-radius;
-            border-top-right-radius: $chatbox-border-radius;
-
-            .chat-message {
-                line-height: $line-height;
-                font-size: $font-size-small;
-                .chat-msg-author {
-                    line-height: $line-height;
-                }
-                .chat-msg-content {
-                    line-height: $line-height;
-                    .emojione {
-                        height: $line-height;
-                        margin-bottom: -$line-height/4;
-                    }
-                }
-            }
-        }
-        .chat-content {
-            border-top-left-radius: $chatbox-border-radius;
-            border-top-right-radius: $chatbox-border-radius;
-        }
-        .chat-title {
-            font-size: $font-size-huge;
-            line-height: $line-height-huge;
-        }
-
-        .sendXMPPMessage {
-            ul {
-                width: 100%;
-            }
-            .toggle-smiley {
-                ul {
-                    &.emoji-toolbar {
-                        .emoji-category-picker {
-                            margin-right: 5em;
-                        }
-                        .emoji-category {
-                            padding-left: 10px;
-                            padding-right: 10px;
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
-
-@media screen and (max-width: 767px) {
-    #conversejs:not(.converse-embedded).fullscreen {
-        .chatbox {
-            width: calc(100% - 50px);
-        }
-    }
-}

+ 0 - 64
sass/inverse/_chatrooms.scss

@@ -1,64 +0,0 @@
-#conversejs.converse-fullscreen,
-#conversejs.converse-mobile {
-
-    .chat-head-chatroom {
-        height: $chatroom-head-height;
-        font-size: 20px;
-        .chat-title {
-            .chatroom-description {
-                font-size: 65%;
-            }
-        }
-    }
-
-    .chatroom {
-        .box-flyout {
-            background-color: $chatroom-head-color;
-            border: $flyout-padding solid $chatroom-head-color;
-            border-top: 0.8em solid $chatroom-head-color;
-            width: 100%;
-
-            .chatroom-body {
-                @include border-top-radius($chatbox-border-radius);
-                .chatroom-form-container {
-                    border-radius: $chatbox-border-radius;
-                }
-                .chat-area {
-                    border-top-left-radius: $chatbox-border-radius;
-                    min-width: auto;
-
-                    .chat-content {
-                        border-top-left-radius: $chatbox-border-radius;
-                    }
-                    &.full {
-                        max-width: 100%;
-                        .new-msgs-indicator {
-                            max-width: 100%;
-                        }
-                    }
-                }
-                .occupants {
-                    border-top-right-radius: $chatbox-border-radius;;
-                    padding: $padding;
-                    .occupants-heading {
-                        font-size: $font-size-large;
-                    }
-                    ul {
-                        &.occupant-list {
-                            li {
-                                font-size: $font-size-small;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        .room-invite {
-            span {
-                .invited-contact {
-                    margin: 0 0 0.5em -1px;
-                }
-            }
-        }
-    }
-}

+ 0 - 102
sass/inverse/_controlbox.scss

@@ -1,102 +0,0 @@
-#conversejs.fullscreen {
-    #controlbox {
-        @include make-col-ready();
-        @include media-breakpoint-up(md) {
-            @include make-col(3);
-        }
-        @include media-breakpoint-up(xl) {
-            @include make-col(2);
-        }
-
-        &.logged-out {
-            @include make-col(12);
-        }
-
-        margin: 0;
-
-        .controlbox-pane {
-            border-radius: 0;
-        }
-
-        .flyout {
-            border-radius: 0;
-        }
-
-        #converse-login-panel {
-            border-radius: 0;
-            .converse-form {
-                padding: 3em 2em 3em;
-            }
-        }
-
-        .toggle-register-login {
-            line-height: $line-height-huge;
-        }
-
-        .brand-heading-container {
-            @include make-col(12);
-            text-align: center;
-            .brand-heading {
-                font-size: 150%;
-                font-size: 600%;
-                padding: 0.7em 0 0 0;
-                opacity: 0.8;
-                color: $blue;
-            }
-            .brand-subtitle {
-                font-size: 90%;
-                padding: 0.5em;
-            }
-            @media screen and (max-width: $mobile-portrait-length) {
-                .brand-heading {
-                    font-size: 400%;
-                }
-            }
-        }
-
-        &.logged-out {
-            @include make-col(12);
-            @include fade-in;
-            width: 100%;
-            .box-flyout {
-                width: 100%;
-            }
-        }
-        .box-flyout {
-            border: 0;
-            width: 100%;
-            z-index: 1;
-            background-color: $controlbox-head-color;
-
-            .controlbox-head {
-                display: none;
-            }
-        }
-
-        #converse-register, #converse-login {
-            @include make-col-ready();
-            @include make-col(8);
-            @include make-col-offset(2);
-
-            @include media-breakpoint-up(sm) {
-                @include make-col(8);
-                @include make-col-offset(2);
-            }
-            @include media-breakpoint-up(md) {
-                @include make-col(8);
-                @include make-col-offset(2);
-            }
-            @include media-breakpoint-up(lg) {
-                @include make-col(6);
-                @include make-col-offset(3);
-            }
-            .title, .instructions {
-                margin: 1em 0;
-            }
-            input[type=submit],
-            input[type=button] {
-                width: auto;
-            }
-        }
-    }
-}

+ 0 - 42
sass/inverse/_core.scss

@@ -1,42 +0,0 @@
-body {
-    font-family: "Lora", "Helvetica Neue", Helvetica, Arial, sans-serif;
-    color: #ffffff;
-    background-color: $global-background-color;
-
-    .brand-heading {
-        font-size: 600%;
-        margin-left: -10%;
-        &.fade-in {
-            @include fade-in;
-            @include animation-delay(2s);
-        }
-        .icon-conversejs {
-            font-size: 88%;
-        }
-    }
-
-    div.content {
-        height: 100vh;
-        width: 100vw;
-        position: fixed;
-        background-color: $global-background-color;
-
-        .inner-content {
-            text-align: center;
-            padding: 7%;
-            @include calc(padding-left, '5% + #{$controlbox-width}');
-
-            p.no-chats {
-                padding-right: 10%;
-                font-size: 120%;
-            }
-        }
-    }
-}
-
-#conversejs.fullscreen {
-    .converse-chatboxes {
-        width: 100vw;
-        right: 15px; // Hack due to padding added by bootstrap
-    }
-}

+ 0 - 17
sass/inverse/_headline.scss

@@ -1,17 +0,0 @@
-#conversejs.fullscreen {
-    .chatbox.headlines {
-        .box-flyout {
-            background-color: $headline-head-color;
-        }
-        .chat-head {
-            &.chat-head-chatbox {
-                background-color: $headline-head-color;
-            }
-        }
-        .flyout {
-            border: $flyout-padding solid $headline-head-color;
-            border-top: 0.8em solid $headline-head-color;
-        }
-    }
-}
-

+ 0 - 58
sass/inverse/_minimized_chats.scss

@@ -1,58 +0,0 @@
-#conversejs.fullscreen {
-    #minimized-chats {
-        border-top-left-radius: $chatbox-border-radius;
-        border-top-right-radius: $chatbox-border-radius;
-        color: $inverse-link-color;
-        display: none;
-        float: right;
-        font-weight: bold;
-        height: 100%;
-        margin: 0 $chat-gutter;
-        padding: 0;
-        width: 130px;
-
-        #toggle-minimized-chats {
-            border-top-left-radius: $chatbox-border-radius;
-            border-top-right-radius: $chatbox-border-radius;
-            background-color: $link-color;
-            color: white;
-            position: relative;
-            padding: 10px 0 0 0;
-            display: block;
-            width: 100%;
-            height: 100%;
-            text-align: center;
-        }
-
-        .minimized-chats-flyout {
-            height: auto;
-            bottom: $bottom-gutter-height;
-            .chat-head {
-                padding: 0.3em;
-                border-radius: $chatbox-border-radius;
-                width: $minimized-chats-width;
-                height: 35px;
-                margin-bottom: 0.2em;
-                box-shadow: 1px 3px 5px 3px rgba(0, 0, 0, 0.4);
-            }
-            &.minimized {
-                height: auto;
-            }
-        }
-
-        .unread-message-count {
-            font-weight: bold;
-            background-color: white;
-            border: 1px solid;
-            text-shadow: 1px 1px 0 $text-shadow-color;
-            color: $warning-color;
-            border-radius: 5px;
-            padding: 2px 4px;
-            font-size: 16px;
-            text-align: center;
-            position: absolute;
-            right: 116px;
-            bottom: 10px;
-        }
-    }
-}

+ 0 - 5
sass/inverse/_roster.scss

@@ -1,5 +0,0 @@
-#conversejs {
-    #converse-roster {
-        padding-bottom: 3em;
-    }
-}

+ 0 - 34
sass/inverse/_variables.scss

@@ -1,34 +0,0 @@
-$max-chat-textarea-height: 400px !default;
-$emoji-picker-height: 150px !default;
-
-$roster-item-height: 30px !default;
-
-$flyout-padding: 1.2em;
-
-$chat-head-height: 62px !default;
-
-$controlbox-dropdown-height: 30px !default;
-$controlbox-head-height: 63px !default;
-
-$rounded-border-radius: 4px !default;
-
-$chatbox-hover-height: 6px !default;
-
-$font-size-small: 14px !default;
-$font-size: 16px !default;
-$font-size-large: 18px !default;
-$font-size-huge: 26px !default;
-$legend-font-size: 18px !default;
-
-$line-height-small:  20px !default;
-$line-height:  22px !default;
-$line-height-large:  24px !default;
-$line-height-huge:  30px !default;
-
-$chat-width: 100% !default;
-$chat-height: 100%;
-
-$padding: 1em;
-
-$chatroom-head-height: 62px !default;
-$chatroom-width: 300px !default;

+ 34 - 32
spec/bookmarks.js

@@ -4,12 +4,10 @@
     define([
         "jasmine",
         "jquery",
-        "converse-core",
-        "utils",
         "mock",
         "test-utils"
         ], factory);
-} (this, function (jasmine, $, converse, utils, mock, test_utils) {
+} (this, function (jasmine, $, mock, test_utils) {
     "use strict";
     var $iq = converse.env.$iq,
         $msg = converse.env.$msg,
@@ -381,14 +379,14 @@
                 ['http://jabber.org/protocol/pubsub#publish-options']
             ).then(function () {
                 /* Client requests all items
-                * -------------------------
-                *
-                *  <iq from='juliet@capulet.lit/randomID' type='get' id='retrieve1'>
-                *  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
-                *      <items node='storage:bookmarks'/>
-                *  </pubsub>
-                *  </iq>
-                */
+                 * -------------------------
+                 *
+                 *  <iq from='juliet@capulet.lit/randomID' type='get' id='retrieve1'>
+                 *  <pubsub xmlns='http://jabber.org/protocol/pubsub'>
+                 *      <items node='storage:bookmarks'/>
+                 *  </pubsub>
+                 *  </iq>
+                 */
                 var IQ_id;
                 expect(_.filter(_converse.connection.send.calls.all(), function (call) {
                     var stanza = call.args[0];
@@ -411,27 +409,29 @@
                 }).length).toBe(1);
 
                 /*
-                * Server returns all items
-                * ------------------------
-                * <iq type='result'
-                *     to='juliet@capulet.lit/randomID'
-                *     id='retrieve1'>
-                * <pubsub xmlns='http://jabber.org/protocol/pubsub'>
-                *     <items node='storage:bookmarks'>
-                *     <item id='current'>
-                *         <storage xmlns='storage:bookmarks'>
-                *         <conference name='The Play&apos;s the Thing'
-                *                     autojoin='true'
-                *                     jid='theplay@conference.shakespeare.lit'>
-                *             <nick>JC</nick>
-                *         </conference>
-                *         </storage>
-                *     </item>
-                *     </items>
-                * </pubsub>
-                * </iq>
-                */
+                 * Server returns all items
+                 * ------------------------
+                 * <iq type='result'
+                 *     to='juliet@capulet.lit/randomID'
+                 *     id='retrieve1'>
+                 * <pubsub xmlns='http://jabber.org/protocol/pubsub'>
+                 *     <items node='storage:bookmarks'>
+                 *     <item id='current'>
+                 *         <storage xmlns='storage:bookmarks'>
+                 *         <conference name='The Play&apos;s the Thing'
+                 *                     autojoin='true'
+                 *                     jid='theplay@conference.shakespeare.lit'>
+                 *             <nick>JC</nick>
+                 *         </conference>
+                 *         </storage>
+                 *     </item>
+                 *     </items>
+                 * </pubsub>
+                 * </iq>
+                 */
                 expect(_converse.bookmarks.models.length).toBe(0);
+
+                spyOn(_converse.bookmarks, 'onBookmarksReceived').and.callThrough();
                 var stanza = $iq({'to': _converse.connection.jid, 'type':'result', 'id':IQ_id})
                     .c('pubsub', {'xmlns': Strophe.NS.PUBSUB})
                         .c('items', {'node': 'storage:bookmarks'})
@@ -448,11 +448,13 @@
                                         'jid': 'another@conference.shakespeare.lit'
                                     }); // Purposefully exclude the <nick> element to test #1043
                 _converse.connection._dataRecv(test_utils.createRequest(stanza));
+                return test_utils.waitUntil(() => _converse.bookmarks.onBookmarksReceived.calls.count(), 300)
+            }).then(() => {
                 expect(_converse.bookmarks.models.length).toBe(2);
                 expect(_converse.bookmarks.findWhere({'jid': 'theplay@conference.shakespeare.lit'}).get('autojoin')).toBe(true);
                 expect(_converse.bookmarks.findWhere({'jid': 'another@conference.shakespeare.lit'}).get('autojoin')).toBe(false);
                 done();
-            });
+            }).catch(_.partial(console.error, _));
         }));
 
         describe("The rooms panel", function () {

+ 7 - 9
spec/chatbox.js

@@ -2,12 +2,10 @@
     define([
         "jquery",
         "jasmine",
-        "utils",
-        "converse-core",
         "mock",
         "test-utils"
         ], factory);
-} (this, function ($, jasmine, utils, converse, mock, test_utils) {
+} (this, function ($, jasmine, mock, test_utils) {
     "use strict";
     var _ = converse.env._;
     var $iq = converse.env.$iq;
@@ -429,9 +427,9 @@
                     var view = _converse.chatboxviews.get(contact_jid);
                     expect(chatbox).toBeDefined();
                     expect(view).toBeDefined();
-                    var $toolbar = $(view.el).find('ul.chat-toolbar');
-                    expect($toolbar.length).toBe(1);
-                    expect($toolbar.children('li').length).toBe(1);
+                    var toolbar = view.el.querySelector('ul.chat-toolbar');
+                    expect(_.isElement(toolbar)).toBe(true);
+                    expect(toolbar.querySelectorAll(':scope > li').length).toBe(1);
                     done();
                 }));
 
@@ -458,7 +456,7 @@
                     var timeout = false;
 
                     test_utils.waitUntil(function () {
-                        return utils.isVisible(view.el.querySelector('.toggle-smiley .emoji-picker-container'));
+                        return u.isVisible(view.el.querySelector('.toggle-smiley .emoji-picker-container'));
                     }, 500).then(function () {
                         var picker = view.el.querySelector('.toggle-smiley .emoji-picker-container');
                         var items = picker.querySelectorAll('.emoji-picker li');
@@ -747,7 +745,7 @@
                             expect(chatbox.messages.length).toEqual(1);
                             var msg_obj = chatbox.messages.models[0];
                             expect(msg_obj.get('sender')).toEqual('me');
-                            expect(msg_obj.get('delayed')).toEqual(false);
+                            expect(msg_obj.get('is_delayed')).toEqual(false);
                             var $chat_content = $(chatboxview.el).find('.chat-content');
                             var status_text = $chat_content.find('.chat-info.chat-state-notification').text();
                             expect(status_text).toBe('Typing from another device');
@@ -895,7 +893,7 @@
                             expect(chatbox.messages.length).toEqual(1);
                             var msg_obj = chatbox.messages.models[0];
                             expect(msg_obj.get('sender')).toEqual('me');
-                            expect(msg_obj.get('delayed')).toEqual(false);
+                            expect(msg_obj.get('is_delayed')).toEqual(false);
                             var $chat_content = $(chatboxview.el).find('.chat-content');
                             var status_text = $chat_content.find('.chat-info.chat-state-notification').text();
                             expect(status_text).toBe('Stopped typing on the other device');

+ 190 - 133
spec/chatroom.js

@@ -1,6 +1,6 @@
 (function (root, factory) {
-    define(["jquery", "jasmine", "mock", "converse-core", "test-utils", "utils" ], factory);
-} (this, function ($, jasmine, mock, converse, test_utils, utils) {
+    define(["jquery", "jasmine", "mock", "test-utils" ], factory);
+} (this, function ($, jasmine, mock, test_utils) {
     var _ = converse.env._;
     var $pres = converse.env.$pres;
     var $iq = converse.env.$iq;
@@ -657,6 +657,7 @@
                     expect(indicator.getAttribute('data-isodate')).toEqual(moment().startOf('day').format());
                     expect(indicator.querySelector('time').getAttribute('class')).toEqual('separator-text');
                     expect(indicator.querySelector('time').textContent).toEqual(moment().startOf('day').format("dddd MMM Do YYYY"));
+                    expect(chat_content.querySelectorAll('div.chat-info').length).toBe(2);
                     expect(chat_content.querySelector('div.chat-info:last-child').textContent).toBe(
                         "some1 has entered the room"
                     );
@@ -672,9 +673,9 @@
                         .c('status', 'Disconnected: Replaced by new connection').up()
                         .c('x', {xmlns: Strophe.NS.MUC_USER})
                             .c('item', {
-                                'affiliation': 'none',
+                                'affiliation': 'owner',
                                 'jid': 'some1@localhost/_converse.js-290929789',
-                                'role': 'none'
+                                'role': 'moderator'
                             });
                     _converse.connection._dataRecv(test_utils.createRequest(presence));
 
@@ -685,7 +686,7 @@
                     expect(indicator.getAttribute('data-isodate')).toEqual(moment().startOf('day').format());
 
                     expect(indicator.querySelector('time').textContent).toEqual(moment().startOf('day').format("dddd MMM Do YYYY"));
-                    expect($(chat_content).find('div.chat-info').length).toBe(4);
+                    expect(chat_content.querySelectorAll('div.chat-info').length).toBe(3);
                     expect($(chat_content).find('div.chat-info:last').html()).toBe(
                         'some1 has left the room. '+
                         '"Disconnected: Replaced by new connection"');
@@ -713,14 +714,14 @@
                         });
                     _converse.connection._dataRecv(test_utils.createRequest(presence));
 
-                    var $time = $chat_content.find('time');
-                    expect($time.length).toEqual(4);
+                    let time = chat_content.querySelectorAll('time.separator-text');
+                    expect(time.length).toEqual(4);
 
                     var $indicator = $chat_content.find('.date-separator:eq(3)');
                     expect($indicator.attr('class')).toEqual('message date-separator');
                     expect($indicator.data('isodate')).toEqual(moment().startOf('day').format());
                     expect($indicator.find('time').text()).toEqual(moment().startOf('day').format("dddd MMM Do YYYY"));
-                    expect($chat_content.find('div.chat-info').length).toBe(5);
+                    expect(chat_content.querySelectorAll('div.chat-info').length).toBe(4);
                     expect($chat_content.find('div.chat-info:last').html()).toBe("newguy has entered the room");
 
                     jasmine.clock().tick(ONE_DAY_LATER);
@@ -752,15 +753,15 @@
                             });
                     _converse.connection._dataRecv(test_utils.createRequest(presence));
 
-                    $time = $chat_content.find('time');
-                    expect($time.length).toEqual(6);
+                    time = chat_content.querySelectorAll('time.separator-text');
+                    expect(time.length).toEqual(6);
 
                     $indicator = $chat_content.find('.date-separator:eq(5)');
                     expect($indicator.attr('class')).toEqual('message date-separator');
                     expect($indicator.data('isodate')).toEqual(moment().startOf('day').format());
 
                     expect($indicator.find('time').text()).toEqual(moment().startOf('day').format("dddd MMM Do YYYY"));
-                    expect($chat_content.find('div.chat-info').length).toBe(6);
+                    expect(chat_content.querySelectorAll('div.chat-info').length).toBe(5);
                     expect($chat_content.find('div.chat-info:last').html()).toBe(
                         'newguy has left the room. '+
                         '"Disconnected: Replaced by new connection"');
@@ -813,9 +814,8 @@
                             .c('field', {'type':'text-single', 'var':'muc#roominfo_occupants', 'label':'Number of occupants'})
                                 .c('value').t(0);
                 _converse.connection._dataRecv(test_utils.createRequest(features_stanza));
-                test_utils.waitUntil(function () {
-                    return _.get(view.el.querySelector('.chatroom-description'), 'textContent');
-                }).then(function () {
+                test_utils.waitUntil(() => _.get(view.el.querySelector('.chatroom-description'), 'textContent'))
+                .then(function () {
                     expect($(view.el.querySelector('.chatroom-description')).text()).toBe('This is the description');
                     done();
                 });
@@ -1113,7 +1113,7 @@
                 }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
             }));
 
-            it("shows users currently present in the room",
+            it("shows all members even if they're not currently present in the room",
                 mock.initConverseWithPromises(
                     null, ['rosterGroupsFetched'], {},
                     function (done, _converse) {
@@ -1145,6 +1145,61 @@
                         expect(occupants.querySelectorAll('li .occupant-nick')[index].textContent.trim()).toBe(mock.chatroom_names[i]);
                     }
 
+                    // Test users leaving the room
+                    // http://xmpp.org/extensions/xep-0045.html#exit
+                    for (i=mock.chatroom_names.length-1; i>-1; i--) {
+                        name = mock.chatroom_names[i];
+                        role = mock.chatroom_roles[name].role;
+                        // See example 21 http://xmpp.org/extensions/xep-0045.html#enter-pres
+                        presence = $pres({
+                            to:'dummy@localhost/pda',
+                            from:'lounge@localhost/'+name,
+                            type: 'unavailable'
+                        }).c('x').attrs({xmlns:'http://jabber.org/protocol/muc#user'})
+                        .c('item').attrs({
+                            affiliation: mock.chatroom_roles[name].affiliation,
+                            jid: name.replace(/ /g,'.').toLowerCase() + '@localhost',
+                            role: 'none'
+                        }).nodeTree;
+                        _converse.connection._dataRecv(test_utils.createRequest(presence));
+                        expect(occupants.querySelectorAll('li').length).toBe(7);
+                    }
+                    done();
+                }).catch(_.partial(console.error, _));
+            }));
+
+            it("shows users currently present in the room",
+                mock.initConverseWithPromises(
+                    null, ['rosterGroupsFetched'], {},
+                    function (done, _converse) {
+
+                test_utils.openAndEnterChatRoom(_converse, 'lounge', 'localhost', 'dummy').then(function() {
+                    var name;
+                    var view = _converse.chatboxviews.get('lounge@localhost'),
+                        occupants = view.el.querySelector('.occupant-list');
+                    var presence, role, jid, model;
+                    for (var i=0; i<mock.chatroom_names.length; i++) {
+                        name = mock.chatroom_names[i];
+                        role = mock.chatroom_roles[name].role;
+                        // See example 21 http://xmpp.org/extensions/xep-0045.html#enter-pres
+                        jid =
+                        presence = $pres({
+                                to:'dummy@localhost/pda',
+                                from:'lounge@localhost/'+name
+                        }).c('x').attrs({xmlns:'http://jabber.org/protocol/muc#user'})
+                        .c('item').attrs({
+                            affiliation: 'none',
+                            jid: name.replace(/ /g,'.').toLowerCase() + '@localhost',
+                            role: role
+                        }).up()
+                        .c('status').attrs({code:'110'}).nodeTree;
+                        _converse.connection._dataRecv(test_utils.createRequest(presence));
+                        expect(occupants.querySelectorAll('li').length).toBe(2+i);
+                        model = view.occupantsview.model.where({'nick': name})[0];
+                        var index = view.occupantsview.model.indexOf(model);
+                        expect(occupants.querySelectorAll('li .occupant-nick')[index].textContent.trim()).toBe(mock.chatroom_names[i]);
+                    }
+
                     // Test users leaving the room
                     // http://xmpp.org/extensions/xep-0045.html#exit
                     for (i=mock.chatroom_names.length-1; i>-1; i--) {
@@ -1710,7 +1765,11 @@
                         .c('status').attrs({code:'110'}).nodeTree;
 
                     _converse.connection._dataRecv(test_utils.createRequest(presence));
-                    expect($chat_content.find('div.chat-info').length).toBe(2);
+                    // XXX: currently we still have an additional "has entered the room"
+                    // notification for the new nickname. Ideally we'd not have
+                    // that, but that's probably not possible without some
+                    // significant refactoring.
+                    expect($chat_content.find('div.chat-info').length).toBe(3);
                     expect($chat_content.find('div.chat-info').get(1).textContent).toBe(
                         __(_converse.muc.new_nickname_messages["303"], "newnick")
                     );
@@ -1741,6 +1800,8 @@
                         "<query xmlns='http://jabber.org/protocol/disco#info'/>"+
                     "</iq>");
 
+                var view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
+                spyOn(view.model, 'parseRoomFeatures').and.callThrough();
                 /* <iq from='coven@chat.shakespeare.lit'
                  *      id='ik3vs715'
                  *      to='hag66@shakespeare.lit/pda'
@@ -1780,16 +1841,17 @@
                         .c('feature', {'var': 'muc_unmoderated'}).up()
                         .c('feature', {'var': 'muc_nonanonymous'});
                 _converse.connection._dataRecv(test_utils.createRequest(features_stanza));
-
-                var view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
-                expect(view.model.get('features_fetched')).toBe(true);
-                expect(view.model.get('passwordprotected')).toBe(true);
-                expect(view.model.get('hidden')).toBe(true);
-                expect(view.model.get('temporary')).toBe(true);
-                expect(view.model.get('open')).toBe(true);
-                expect(view.model.get('unmoderated')).toBe(true);
-                expect(view.model.get('nonanonymous')).toBe(true);
-                done();
+                test_utils.waitUntil(() => view.model.parseRoomFeatures.calls.count(), 300)
+                .then(() => {
+                    expect(view.model.get('features_fetched')).toBeTruthy();
+                    expect(view.model.get('passwordprotected')).toBe(true);
+                    expect(view.model.get('hidden')).toBe(true);
+                    expect(view.model.get('temporary')).toBe(true);
+                    expect(view.model.get('open')).toBe(true);
+                    expect(view.model.get('unmoderated')).toBe(true);
+                    expect(view.model.get('nonanonymous')).toBe(true);
+                    done();
+                });
             }));
 
             it("updates the shown features when the room configuration has changed",
@@ -2888,6 +2950,7 @@
 
                 var muc_iq;
                 var sent_IQs = [], IQ_ids = [];
+                var invitee_jid, sent_stanza, sent_id;
                 var sendIQ = _converse.connection.sendIQ;
                 spyOn(_converse.connection, 'sendIQ').and.callFake(function (iq, callback, errback) {
                     sent_IQs.push(iq);
@@ -2896,6 +2959,9 @@
 
                 _converse.api.rooms.open('coven@chat.shakespeare.lit', {'nick': 'dummy'});
 
+                var view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
+                spyOn(view.model, 'parseRoomFeatures').and.callThrough();
+
                 // State that the chat is members-only via the features IQ
                 var features_stanza = $iq({
                         from: 'coven@chat.shakespeare.lit',
@@ -2915,111 +2981,102 @@
                         .c('feature', {'var': 'muc_membersonly'}).up();
                 _converse.connection._dataRecv(test_utils.createRequest(features_stanza));
 
-                var view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
-                expect(view.model.get('membersonly')).toBeTruthy();
-
-                test_utils.createContacts(_converse, 'current');
-
-                var sent_stanza, sent_id;
-                spyOn(_converse.connection, 'send').and.callFake(function (stanza) {
-                    if (stanza.nodeTree && stanza.nodeTree.nodeName === 'message') {
-                        sent_id = stanza.nodeTree.getAttribute('id');
-                        sent_stanza = stanza;
-                    }
-                });
-                var name = mock.cur_names[0];
-                var invitee_jid = name.replace(/ /g,'.').toLowerCase() + '@localhost';
-                var reason = "Please join this chat room";
-                view.model.directInvite(invitee_jid, reason);
-
-                // Check in reverse order that we requested all three lists
-                // (member, owner and admin).
-                var admin_iq_id = IQ_ids.pop();
-                var owner_iq_id = IQ_ids.pop();
-                var member_iq_id = IQ_ids.pop();
-
-                expect(sent_IQs.pop().toLocaleString()).toBe(
-                    "<iq to='coven@chat.shakespeare.lit' type='get' xmlns='jabber:client' id='"+admin_iq_id+"'>"+
-                        "<query xmlns='http://jabber.org/protocol/muc#admin'>"+
-                            "<item affiliation='admin'/>"+
-                        "</query>"+
-                    "</iq>");
-                expect(sent_IQs.pop().toLocaleString()).toBe(
-                    "<iq to='coven@chat.shakespeare.lit' type='get' xmlns='jabber:client' id='"+owner_iq_id+"'>"+
-                        "<query xmlns='http://jabber.org/protocol/muc#admin'>"+
-                            "<item affiliation='owner'/>"+
-                        "</query>"+
-                    "</iq>");
-                expect(sent_IQs.pop().toLocaleString()).toBe(
-                    "<iq to='coven@chat.shakespeare.lit' type='get' xmlns='jabber:client' id='"+member_iq_id+"'>"+
-                        "<query xmlns='http://jabber.org/protocol/muc#admin'>"+
-                            "<item affiliation='member'/>"+
-                        "</query>"+
-                    "</iq>");
-
-                /* Now the service sends the member list to the user
-                 *
-                 *  <iq from='coven@chat.shakespeare.lit'
-                 *      id='member3'
-                 *      to='crone1@shakespeare.lit/desktop'
-                 *      type='result'>
-                 *  <query xmlns='http://jabber.org/protocol/muc#admin'>
-                 *      <item affiliation='member'
-                 *          jid='hag66@shakespeare.lit'
-                 *          nick='thirdwitch'
-                 *          role='participant'/>
-                 *  </query>
-                 *  </iq>
-                 */
-                var member_list_stanza = $iq({
-                        'from': 'coven@chat.shakespeare.lit',
-                        'id': member_iq_id,
-                        'to': 'dummy@localhost/resource',
-                        'type': 'result'
-                    }).c('query', {'xmlns': Strophe.NS.MUC_ADMIN})
-                        .c('item', {
-                            'affiliation': 'member',
-                            'jid': 'hag66@shakespeare.lit',
-                            'nick': 'thirdwitch',
-                            'role': 'participant'
-                        });
-                _converse.connection._dataRecv(test_utils.createRequest(member_list_stanza));
-
-                var admin_list_stanza = $iq({
-                        'from': 'coven@chat.shakespeare.lit',
-                        'id': admin_iq_id,
-                        'to': 'dummy@localhost/resource',
-                        'type': 'result'
-                    }).c('query', {'xmlns': Strophe.NS.MUC_ADMIN})
-                        .c('item', {
-                            'affiliation': 'admin',
-                            'jid': 'wiccarocks@shakespeare.lit',
-                            'nick': 'secondwitch'
-                        });
-                _converse.connection._dataRecv(test_utils.createRequest(admin_list_stanza));
-
-                var owner_list_stanza = $iq({
-                        'from': 'coven@chat.shakespeare.lit',
-                        'id': owner_iq_id,
-                        'to': 'dummy@localhost/resource',
-                        'type': 'result'
-                    }).c('query', {'xmlns': Strophe.NS.MUC_ADMIN})
-                        .c('item', {
-                            'affiliation': 'owner',
-                            'jid': 'crone1@shakespeare.lit',
-                        });
-                _converse.connection._dataRecv(test_utils.createRequest(owner_list_stanza));
-                test_utils.waitUntil(() => {
-                    return _.filter(
-                        _converse.connection.IQ_stanzas,
-                        (iq) => {
-                            if (iq.nodeTree.getAttribute('to') === 'coven@chat.shakespeare.lit' && iq.nodeTree.getAttribute('type') === 'set') {
-                                muc_iq = iq;
-                                return true;
-                            }
-                            return false;
-                        }).length;
-                }).then(function () {
+                test_utils.waitUntil(() => view.model.parseRoomFeatures.calls.count(), 300)
+                .then(() => {
+                   expect(view.model.get('membersonly')).toBeTruthy();
+
+                   test_utils.createContacts(_converse, 'current');
+
+                   spyOn(_converse.connection, 'send').and.callFake(function (stanza) {
+                       if (stanza.nodeTree && stanza.nodeTree.nodeName === 'message') {
+                           sent_id = stanza.nodeTree.getAttribute('id');
+                           sent_stanza = stanza;
+                       }
+                   });
+                   var name = mock.cur_names[0];
+                   invitee_jid = name.replace(/ /g,'.').toLowerCase() + '@localhost';
+                   var reason = "Please join this chat room";
+                   view.model.directInvite(invitee_jid, reason);
+
+                   // Check in reverse order that we requested all three lists
+                   // (member, owner and admin).
+                   var admin_iq_id = IQ_ids.pop();
+                   var owner_iq_id = IQ_ids.pop();
+                   var member_iq_id = IQ_ids.pop();
+
+                   expect(sent_IQs.pop().toLocaleString()).toBe(
+                       "<iq to='coven@chat.shakespeare.lit' type='get' xmlns='jabber:client' id='"+admin_iq_id+"'>"+
+                           "<query xmlns='http://jabber.org/protocol/muc#admin'>"+
+                               "<item affiliation='admin'/>"+
+                           "</query>"+
+                       "</iq>");
+                   expect(sent_IQs.pop().toLocaleString()).toBe(
+                       "<iq to='coven@chat.shakespeare.lit' type='get' xmlns='jabber:client' id='"+owner_iq_id+"'>"+
+                           "<query xmlns='http://jabber.org/protocol/muc#admin'>"+
+                               "<item affiliation='owner'/>"+
+                           "</query>"+
+                       "</iq>");
+                   expect(sent_IQs.pop().toLocaleString()).toBe(
+                       "<iq to='coven@chat.shakespeare.lit' type='get' xmlns='jabber:client' id='"+member_iq_id+"'>"+
+                           "<query xmlns='http://jabber.org/protocol/muc#admin'>"+
+                               "<item affiliation='member'/>"+
+                           "</query>"+
+                       "</iq>");
+
+                   /* Now the service sends the member list to the user
+                    *
+                    *  <iq from='coven@chat.shakespeare.lit'
+                    *      id='member3'
+                    *      to='crone1@shakespeare.lit/desktop'
+                    *      type='result'>
+                    *  <query xmlns='http://jabber.org/protocol/muc#admin'>
+                    *      <item affiliation='member'
+                    *          jid='hag66@shakespeare.lit'
+                    *          nick='thirdwitch'
+                    *          role='participant'/>
+                    *  </query>
+                    *  </iq>
+                    */
+                   var member_list_stanza = $iq({
+                           'from': 'coven@chat.shakespeare.lit',
+                           'id': member_iq_id,
+                           'to': 'dummy@localhost/resource',
+                           'type': 'result'
+                       }).c('query', {'xmlns': Strophe.NS.MUC_ADMIN})
+                           .c('item', {
+                               'affiliation': 'member',
+                               'jid': 'hag66@shakespeare.lit',
+                               'nick': 'thirdwitch',
+                               'role': 'participant'
+                           });
+                   _converse.connection._dataRecv(test_utils.createRequest(member_list_stanza));
+
+                   var admin_list_stanza = $iq({
+                           'from': 'coven@chat.shakespeare.lit',
+                           'id': admin_iq_id,
+                           'to': 'dummy@localhost/resource',
+                           'type': 'result'
+                       }).c('query', {'xmlns': Strophe.NS.MUC_ADMIN})
+                           .c('item', {
+                               'affiliation': 'admin',
+                               'jid': 'wiccarocks@shakespeare.lit',
+                               'nick': 'secondwitch'
+                           });
+                   _converse.connection._dataRecv(test_utils.createRequest(admin_list_stanza));
+
+                   var owner_list_stanza = $iq({
+                           'from': 'coven@chat.shakespeare.lit',
+                           'id': owner_iq_id,
+                           'to': 'dummy@localhost/resource',
+                           'type': 'result'
+                       }).c('query', {'xmlns': Strophe.NS.MUC_ADMIN})
+                           .c('item', {
+                               'affiliation': 'owner',
+                               'jid': 'crone1@shakespeare.lit',
+                           });
+                   _converse.connection._dataRecv(test_utils.createRequest(owner_list_stanza));
+                    return test_utils.waitUntil(() => IQ_ids.length, 300);
+                }).then(() => {
                     // Check that the member list now gets updated
                     expect(muc_iq.toLocaleString()).toBe("<iq to='coven@chat.shakespeare.lit' type='set' xmlns='jabber:client' id='"+muc_iq.nodeTree.getAttribute('id')+"'>"+
                             "<query xmlns='http://jabber.org/protocol/muc#admin'>"+
@@ -3112,7 +3169,7 @@
 
                 test_utils.openControlBox();
                 var roomspanel = _converse.chatboxviews.get('controlbox').roomspanel;
-                roomspanel.el.querySelector('.trigger-add-chatrooms-modal').click();
+                roomspanel.el.querySelector('.show-add-muc-modal').click();
                 test_utils.closeControlBox(_converse);
                 const modal = roomspanel.add_room_modal;
                 test_utils.waitUntil(function () {
@@ -3147,7 +3204,7 @@
 
                 test_utils.openControlBox();
                 var roomspanel = _converse.chatboxviews.get('controlbox').roomspanel;
-                roomspanel.el.querySelector('.trigger-list-chatrooms-modal').click();
+                roomspanel.el.querySelector('.show-list-muc-modal').click();
                 test_utils.closeControlBox(_converse);
                 const modal = roomspanel.list_rooms_modal;
                 test_utils.waitUntil(function () {

+ 2 - 2
spec/controlbox.js

@@ -1,6 +1,6 @@
 (function (root, factory) {
-    define(["jquery", "jasmine", "mock", "converse-core", "test-utils"], factory);
-} (this, function ($, jasmine, mock, converse, test_utils) {
+    define(["jquery", "jasmine", "mock", "test-utils"], factory);
+} (this, function ($, jasmine, mock, test_utils) {
     var _ = converse.env._;
     var $pres = converse.env.$pres;
     var $msg = converse.env.$msg;

+ 1 - 2
spec/converse.js

@@ -2,10 +2,9 @@
     define([
         "jquery",
         "jasmine",
-        "converse-core",
         "mock",
         "test-utils"], factory);
-} (this, function ($, jasmine, converse, mock, test_utils) {
+} (this, function ($, jasmine, mock, test_utils) {
     var b64_sha1 = converse.env.b64_sha1;
     var _ = converse.env._;
 

+ 6 - 3
spec/disco.js

@@ -2,10 +2,9 @@
     define([
         "jasmine",
         "jquery",
-        "converse-core",
         "mock",
         "test-utils"], factory);
-} (this, function (jasmine, $, converse, mock, test_utils) {
+} (this, function (jasmine, $, mock, test_utils) {
     "use strict";
     var Strophe = converse.env.Strophe;
     var $iq = converse.env.$iq;
@@ -15,7 +14,11 @@
 
         describe("Whenever converse.js queries a server for its features", function () {
 
-            it("stores the features it receives", mock.initConverseWithAsync(function (done, _converse) {
+            it("stores the features it receives",
+                mock.initConverseWithPromises(
+                    null, ['discoInitialized'], {},
+                    function (done, _converse) {
+
                 var IQ_stanzas = _converse.connection.IQ_stanzas;
                 var IQ_ids =  _converse.connection.IQ_ids;
                 test_utils.waitUntil(function () {

+ 2 - 2
spec/eventemitter.js

@@ -1,6 +1,6 @@
 (function (root, factory) {
-    define(["jasmine", "mock", "converse-core", "test-utils"], factory);
-} (this, function (jasmine, mock, converse, test_utils) {
+    define(["jasmine", "mock", "test-utils"], factory);
+} (this, function (jasmine, mock, test_utils) {
 
     return describe("The _converse Event Emitter", function() {
 

+ 3 - 4
spec/headline.js

@@ -2,15 +2,14 @@
     define([
         "jasmine",
         "jquery",
-        "converse-core",
-        "utils",
         "mock",
         "test-utils"
         ], factory);
-} (this, function (jasmine, $, converse, utils, mock, test_utils) {
+} (this, function (jasmine, $, mock, test_utils) {
     "use strict";
     var $msg = converse.env.$msg,
-        _ = converse.env._;
+        _ = converse.env._,
+        utils = converse.env.utils;
 
     describe("A headlines box", function () {
 

+ 3 - 3
spec/http-file-upload.js

@@ -1,11 +1,9 @@
 (function (root, factory) {
     define([
         "jasmine",
-        "jquery",
-        "converse-core",
         "mock",
         "test-utils"], factory);
-} (this, function (jasmine, $, converse, mock, test_utils) {
+} (this, function (jasmine, mock, test_utils) {
     "use strict";
     var Strophe = converse.env.Strophe;
     var $iq = converse.env.$iq;
@@ -367,6 +365,7 @@
                                         }).then(function () {
                                             // Check that the image renders
                                             expect(view.el.querySelector('.chat-msg .chat-msg-media').innerHTML.trim()).toEqual(
+                                                '<!-- src/templates/image.html -->\n'+
                                                 '<a href="http://localhost:8000/logo/conversejs-filled.svg" target="_blank" rel="noopener">'+
                                                     '<img class="chat-image img-thumbnail" src="http://localhost:8000/logo/conversejs-filled.svg">'+
                                                 '</a>');
@@ -474,6 +473,7 @@
                                             }).then(function () {
                                                 // Check that the image renders
                                                 expect(view.el.querySelector('.chat-msg .chat-msg-media').innerHTML.trim()).toEqual(
+                                                    '<!-- src/templates/image.html -->\n'+
                                                     '<a href="http://localhost:8000/logo/conversejs-filled.svg" target="_blank" rel="noopener">'+
                                                         '<img class="chat-image img-thumbnail" src="http://localhost:8000/logo/conversejs-filled.svg"></a>')
                                                 XMLHttpRequest.prototype.send = send_backup;

+ 2 - 2
spec/login.js

@@ -1,6 +1,6 @@
 (function (root, factory) {
-    define(["jasmine", "mock", "converse-core", "test-utils"], factory);
-} (this, function (jasmine, mock, converse, test_utils) {
+    define(["jasmine", "mock", "test-utils"], factory);
+} (this, function (jasmine, mock, test_utils) {
 
     describe("The Login Form", function () {
 

+ 2 - 2
spec/mam.js

@@ -1,6 +1,6 @@
 (function (root, factory) {
-    define(["jasmine", "mock", "converse-core", "test-utils"], factory);
-} (this, function (jasmine, mock, converse, test_utils) {
+    define(["jasmine", "mock", "test-utils"], factory);
+} (this, function (jasmine, mock, test_utils) {
     "use strict";
     var _ = converse.env._;
     var Backbone = converse.env.Backbone;

+ 62 - 20
spec/messages.js

@@ -2,12 +2,10 @@
     define([
         "jquery",
         "jasmine",
-        "utils",
-        "converse-core",
         "mock",
         "test-utils"
         ], factory);
-} (this, function ($, jasmine, utils, converse, mock, test_utils) {
+} (this, function ($, jasmine, mock, test_utils) {
     "use strict";
     var _ = converse.env._;
     var $iq = converse.env.$iq;
@@ -62,7 +60,7 @@
                     expect(msg_obj.get('message')).toEqual(message);
                     expect(msg_obj.get('fullname')).toEqual(mock.cur_names[0]);
                     expect(msg_obj.get('sender')).toEqual('them');
-                    expect(msg_obj.get('delayed')).toEqual(false);
+                    expect(msg_obj.get('is_delayed')).toEqual(false);
                     // Now check that the message appears inside the chatbox in the DOM
                     var chat_content = chatboxview.el.querySelector('.chat-content');
                     expect(chat_content.querySelector('.chat-msg .chat-msg-text').textContent).toEqual(message);
@@ -178,7 +176,7 @@
                     expect(msg_obj.get('message')).toEqual(message);
                     expect(msg_obj.get('fullname')).toEqual(undefined);
                     expect(msg_obj.get('sender')).toEqual('them');
-                    expect(msg_obj.get('delayed')).toEqual(false);
+                    expect(msg_obj.get('is_delayed')).toEqual(false);
                     // Now check that the message appears inside the chatbox in the DOM
                     var chat_content = chatboxview.el.querySelector('.chat-content');
                     expect(chat_content.querySelector('.chat-msg .chat-msg-text').textContent).toEqual(message);
@@ -579,7 +577,7 @@
                 expect($el.hasClass('chat-msg-followup')).toBe(false);
                 expect($el.text()).toEqual('Older message');
 
-                $time = $chat_content.find('time:eq(1)');
+                $time = $chat_content.find('time.separator-text:eq(1)');
                 expect($time.text()).toEqual("Monday Jan 1st 2018");
 
                 $day = $chat_content.find('.date-separator:eq(1)');
@@ -593,7 +591,7 @@
                 expect($el.find('.chat-msg-text').text()).toEqual('another inbetween message');
                 expect($el.hasClass('chat-msg-followup')).toBe(true);
 
-                $time = $chat_content.find('time:nth(2)');
+                $time = $chat_content.find('time.separator-text:nth(2)');
                 expect($time.text()).toEqual("Tuesday Jan 2nd 2018");
 
                 $day = $chat_content.find('.date-separator:nth(2)');
@@ -630,7 +628,7 @@
             */
             sinon.spy(_converse, 'log');
             sinon.spy(_converse.chatboxes, 'getChatBox');
-            sinon.spy(utils, 'isHeadlineMessage');
+            sinon.spy(u, 'isHeadlineMessage');
             var msg = $msg({
                     from: 'localhost',
                     to: _converse.bare_jid,
@@ -642,13 +640,13 @@
                 "onMessage: Ignoring incoming headline message sent with type 'chat' from JID: localhost",
                 Strophe.LogLevel.INFO
             )).toBeTruthy();
-            expect(utils.isHeadlineMessage.called).toBeTruthy();
-            expect(utils.isHeadlineMessage.returned(true)).toBeTruthy();
+            expect(u.isHeadlineMessage.called).toBeTruthy();
+            expect(u.isHeadlineMessage.returned(true)).toBeTruthy();
             expect(_converse.chatboxes.getChatBox.called).toBeFalsy();
             // Remove sinon spies
             _converse.log.restore();
             _converse.chatboxes.getChatBox.restore();
-            utils.isHeadlineMessage.restore();
+            u.isHeadlineMessage.restore();
             done();
         }));
 
@@ -692,7 +690,7 @@
             expect(msg_obj.get('message')).toEqual(msgtext);
             expect(msg_obj.get('fullname')).toEqual(mock.cur_names[1]);
             expect(msg_obj.get('sender')).toEqual('them');
-            expect(msg_obj.get('delayed')).toEqual(false);
+            expect(msg_obj.get('is_delayed')).toEqual(false);
             // Now check that the message appears inside the chatbox in the DOM
             var chat_content = chatboxview.el.querySelector('.chat-content');
             expect(chat_content.querySelector('.chat-msg .chat-msg-text').textContent).toEqual(msgtext);
@@ -745,7 +743,7 @@
                 expect(msg_obj.get('message')).toEqual(msgtext);
                 expect(msg_obj.get('fullname')).toEqual(_converse.xmppstatus.get('fullname'));
                 expect(msg_obj.get('sender')).toEqual('me');
-                expect(msg_obj.get('delayed')).toEqual(false);
+                expect(msg_obj.get('is_delayed')).toEqual(false);
                 // Now check that the message appears inside the chatbox in the DOM
                 var $chat_content = $(chatboxview.el).find('.chat-content');
                 var msg_txt = $chat_content.find('.chat-msg').find('.chat-msg-text').text();
@@ -901,7 +899,7 @@
                 expect(msg_obj.get('message')).toEqual(message);
                 expect(msg_obj.get('fullname')).toEqual(contact_name);
                 expect(msg_obj.get('sender')).toEqual('them');
-                expect(msg_obj.get('delayed')).toEqual(true);
+                expect(msg_obj.get('is_delayed')).toEqual(true);
 
                 return test_utils.waitUntil(() => chatbox.vcard.get('fullname') === 'Candice van der Knijff')
                 .then(function () {
@@ -930,7 +928,7 @@
                     expect(_converse.emit).toHaveBeenCalledWith('message', jasmine.any(Object));
                     // Check that there is a <time> element, with the required
                     // props.
-                    expect($chat_content[0].querySelectorAll('time').length).toEqual(2); // There are now two time elements
+                    expect($chat_content[0].querySelectorAll('time.separator-text').length).toEqual(2); // There are now two time elements
 
                     var message_date = new Date();
                     $day = $chat_content.find('.date-separator:last');
@@ -947,7 +945,7 @@
                     expect(msg_obj.get('message')).toEqual(message);
                     expect(msg_obj.get('fullname')).toEqual(contact_name);
                     expect(msg_obj.get('sender')).toEqual('them');
-                    expect(msg_obj.get('delayed')).toEqual(false);
+                    expect(msg_obj.get('is_delayed')).toEqual(false);
                     msg_txt = $chat_content.find('.chat-msg').last().find('.chat-msg-text').text();
                     expect(msg_txt).toEqual(message);
 
@@ -1069,6 +1067,43 @@
             done();
         }));
 
+        it("will render newlines", mock.initConverseWithPromises(null, ['rosterGroupsFetched'], {}, function (done, _converse) {
+            test_utils.createContacts(_converse, 'current');
+            const contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
+            test_utils.openChatBoxFor(_converse, contact_jid);
+
+            let stanza = Strophe.xmlHtmlNode(
+                "<message from='"+contact_jid+"'"+
+                "         type='chat'"+
+                "         to='dummy@localhost/resource'>"+
+                "    <body>Hey\nHave you heard the news?</body>"+
+                "</message>").firstChild;
+            _converse.connection._dataRecv(test_utils.createRequest(stanza));
+
+            const view = _converse.chatboxviews.get(contact_jid);
+            const chat_content = view.el.querySelector('.chat-content');
+            expect(chat_content.querySelector('.chat-msg-text').innerHTML).toBe('Hey<br>Have you heard the news?');
+
+            stanza = Strophe.xmlHtmlNode(
+                "<message from='"+contact_jid+"'"+
+                "         type='chat'"+
+                "         to='dummy@localhost/resource'>"+
+                "    <body>Hey\n\n\nHave you heard the news?</body>"+
+                "</message>").firstChild;
+            _converse.connection._dataRecv(test_utils.createRequest(stanza));
+            expect(chat_content.querySelector('.message:last-child .chat-msg-text').innerHTML).toBe('Hey<br><br>Have you heard the news?');
+
+            stanza = Strophe.xmlHtmlNode(
+                "<message from='"+contact_jid+"'"+
+                "         type='chat'"+
+                "         to='dummy@localhost/resource'>"+
+                "    <body>Hey\nHave you heard\nthe news?</body>"+
+                "</message>").firstChild;
+            _converse.connection._dataRecv(test_utils.createRequest(stanza));
+            expect(chat_content.querySelector('.message:last-child .chat-msg-text').innerHTML).toBe('Hey<br>Have you heard<br>the news?');
+            done();
+        }));
+
         it("will render images from their URLs",
             mock.initConverseWithPromises(
                 null, ['rosterGroupsFetched'], {},
@@ -1083,12 +1118,12 @@
             spyOn(view.model, 'sendMessage').and.callThrough();
             test_utils.sendMessage(view, message);
 
-            test_utils.waitUntil(function () {
-                return view.el.querySelectorAll('.chat-content .chat-image').length;
-            }, 1000).then(function () {
+            test_utils.waitUntil(() => view.el.querySelectorAll('.chat-content .chat-image').length)
+            .then(() => {
                 expect(view.model.sendMessage).toHaveBeenCalled();
                 var msg = $(view.el).find('.chat-content .chat-msg').last().find('.chat-msg-text');
                 expect(msg.html().trim()).toEqual(
+                    '<!-- src/templates/image.html -->\n'+
                     '<a href="'+base_url+'/logo/conversejs-filled.svg" target="_blank" rel="noopener"><img class="chat-image img-thumbnail"'+
                     ' src="' + message + '"></a>');
                 message += "?param1=val1&param2=val2";
@@ -1096,10 +1131,11 @@
                 return test_utils.waitUntil(function () {
                     return view.el.querySelectorAll('.chat-content .chat-image').length === 2;
                 }, 1000);
-            }).then(function () {
+            }).then(() => {
                 expect(view.model.sendMessage).toHaveBeenCalled();
                 var msg = $(view.el).find('.chat-content').find('.chat-msg').last().find('.chat-msg-text');
                 expect(msg.html().trim()).toEqual(
+                    '<!-- src/templates/image.html -->\n'+
                     '<a href="'+base_url+'/logo/conversejs-filled.svg?param1=val1&amp;param2=val2" target="_blank" rel="noopener"><img'+
                     ' class="chat-image img-thumbnail" src="'+message.replace(/&/g, '&amp;')+'"></a>')
 
@@ -1342,6 +1378,7 @@
                     expect(msg.outerHTML).toEqual('<span class="chat-msg-text">Have you heard this funny audio?</span>');
                     var media = view.el.querySelector('.chat-msg .chat-msg-media');
                     expect(media.innerHTML.replace(/(\r\n|\n|\r)/gm, "")).toEqual(
+                        '<!-- src/templates/audio.html -->'+
                         '<audio controls=""><source src="http://localhost/audio.mp3" type="audio/mpeg"></audio>'+
                         '<a target="_blank" rel="noopener" href="http://localhost/audio.mp3">Download audio file</a>');
 
@@ -1359,6 +1396,7 @@
                     expect(msg.innerHTML).toEqual('');
                     media = view.el.querySelector('.chat-msg:last-child .chat-msg-media');
                     expect(media.innerHTML.replace(/(\r\n|\n|\r)/gm, "")).toEqual(
+                        '<!-- src/templates/audio.html -->'+
                         '<audio controls=""><source src="http://localhost/audio.mp3" type="audio/mpeg"></audio>'+
                         '<a target="_blank" rel="noopener" href="http://localhost/audio.mp3">Download audio file</a>');
                     done();
@@ -1392,6 +1430,7 @@
                     expect(msg.outerHTML).toEqual('<span class="chat-msg-text">Have you seen this funny video?</span>');
                     var media = view.el.querySelector('.chat-msg .chat-msg-media');
                     expect(media.innerHTML.replace(/(\r\n|\n|\r)/gm, "")).toEqual(
+                        '<!-- src/templates/video.html -->'+
                         '<video controls=""><source src="http://localhost/video.mp4" type="video/mp4"></video>'+
                         '<a target="_blank" rel="noopener" href="http://localhost/video.mp4">Download video file</a>');
 
@@ -1409,6 +1448,7 @@
                     expect(msg.innerHTML).toEqual('');
                     media = view.el.querySelector('.chat-msg:last-child .chat-msg-media');
                     expect(media.innerHTML.replace(/(\r\n|\n|\r)/gm, "")).toEqual(
+                        '<!-- src/templates/video.html -->'+
                         '<video controls=""><source src="http://localhost/video.mp4" type="video/mp4"></video>'+
                         '<a target="_blank" rel="noopener" href="http://localhost/video.mp4">Download video file</a>');
                     done();
@@ -1442,6 +1482,7 @@
                     expect(msg.outerHTML).toEqual('<span class="chat-msg-text">Have you downloaded this funny file?</span>');
                     var media = view.el.querySelector('.chat-msg .chat-msg-media');
                     expect(media.innerHTML.replace(/(\r\n|\n|\r)/gm, "")).toEqual(
+                        '<!-- src/templates/file.html -->'+
                         '<a target="_blank" rel="noopener" href="http://localhost/funny.pdf">Download: "funny.pdf</a>');
                     done();
                 });
@@ -1476,6 +1517,7 @@
                     expect(msg.outerHTML).toEqual('<span class="chat-msg-text">Have you seen this funny image?</span>');
                     var media = view.el.querySelector('.chat-msg .chat-msg-media');
                     expect(media.innerHTML.replace(/(\r\n|\n|\r)/gm, "")).toEqual(
+                        '<!-- src/templates/image.html -->'+
                         '<a href="http://localhost:8000/logo/conversejs-filled.svg" target="_blank" rel="noopener">'+
                             '<img class="chat-image img-thumbnail" src="http://localhost:8000/logo/conversejs-filled.svg">'+
                         '</a>');

+ 2 - 2
spec/minchats.js

@@ -1,6 +1,6 @@
 (function (root, factory) {
-    define(["jquery", "jasmine", "mock", "converse-core", "test-utils"], factory);
-} (this, function ($, jasmine, mock, converse, test_utils) {
+    define(["jquery", "jasmine", "mock", "test-utils"], factory);
+} (this, function ($, jasmine, mock, test_utils) {
     var _ = converse.env._;
     var $msg = converse.env.$msg;
 

+ 2 - 2
spec/notification.js

@@ -1,6 +1,6 @@
 (function (root, factory) {
-    define(["jquery", "jasmine", "mock", "converse-core", "test-utils", "utils"], factory);
-} (this, function ($, jasmine, mock, converse, test_utils, utils) {
+    define(["jquery", "jasmine", "mock", "test-utils"], factory);
+} (this, function ($, jasmine, mock, test_utils) {
     "use strict";
     var _ = converse.env._;
     var $msg = converse.env.$msg;

+ 2 - 2
spec/omemo.js

@@ -1,6 +1,6 @@
 (function (root, factory) {
-    define(["jasmine", "mock", "converse-core", "test-utils"], factory);
-} (this, function (jasmine, mock, converse, test_utils) {
+    define(["jasmine", "mock", "test-utils"], factory);
+} (this, function (jasmine, mock, test_utils) {
     var Strophe = converse.env.Strophe;
     var b64_sha1 = converse.env.b64_sha1;
     var $iq = converse.env.$iq;

+ 85 - 49
spec/otr.js

@@ -1,72 +1,108 @@
 (function (root, factory) {
-    define(["jquery", "jasmine", "mock", "converse-core", "test-utils"], factory);
-} (this, function ($, jasmine, mock, converse, test_utils) {
+    define(["jquery", "jasmine", "mock", "test-utils"], factory);
+} (this, function ($, jasmine, mock, test_utils) {
     var Strophe = converse.env.Strophe;
     var b64_sha1 = converse.env.b64_sha1;
     var $pres = converse.env.$pres;
     var _ = converse.env._;
 
-    describe("A chatbox with an active OTR session", function() {
-
-        it("will not show the spoiler toolbar button",
+    describe("A chatbox", function() {
+    
+        it("contains a button for starting an encrypted chat session",
             mock.initConverseWithPromises(
                 null, ['rosterGroupsFetched'], {},
                 function (done, _converse) {
 
+            var timeout = true, $toolbar, view;
             test_utils.createContacts(_converse, 'current');
-            var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
-
-            // XXX: We need to send a presence from the contact, so that we
-            // have a resource, that resource is then queried to see
-            // whether Strophe.NS.SPOILER is supported, in which case
-            // the spoiler button will appear.
-            var presence = $pres({
-                'from': contact_jid+'/phone',
-                'to': 'dummy@localhost'
+            test_utils.openControlBox();
+
+            test_utils.waitUntil(function () {
+                return $(_converse.rosterview.el).find('.roster-group').length;
+            }, 300).then(function () {
+                // TODO: More tests can be added here...
+                var contact_jid = mock.cur_names[2].replace(/ /g,'.').toLowerCase() + '@localhost';
+                test_utils.openChatBoxFor(_converse, contact_jid);
+                view = _converse.chatboxviews.get(contact_jid);
+                $toolbar = $(view.el).find('ul.chat-toolbar');
+                expect($toolbar.find('.toggle-otr').length).toBe(1);
+                // Register spies
+                spyOn(view, 'toggleOTRMenu').and.callThrough();
+                view.delegateEvents(); // We need to rebind all events otherwise our spy won't be called
+
+                timeout = false;
+                $toolbar[0].querySelector('.toggle-otr').click();
+                return test_utils.waitUntil(function () {
+                    return view.el.querySelector('.otr-menu').offsetHeight;
+                }, 300)
+            }).then(function () {
+                expect(view.toggleOTRMenu).toHaveBeenCalled();
+                done();
             });
-            _converse.connection._dataRecv(test_utils.createRequest(presence));
-            test_utils.openChatBoxFor(_converse, contact_jid);
+        }));
 
-            test_utils.waitUntilDiscoConfirmed(_converse, contact_jid+'/phone', [], [Strophe.NS.SPOILER]).then(function () {
-                var spoiler_toggle;
-                var view = _converse.chatboxviews.get(contact_jid);
-                spyOn(view, 'addSpoilerButton').and.callThrough();
-                view.model.set('otr_status', 1);
+        describe("with an active OTR session", function() {
 
-                test_utils.waitUntil(function () {
-                    return _.isNull(view.el.querySelector('.toggle-compose-spoiler'));
-                }).then(function () {
-                    spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
-                    expect(spoiler_toggle).toBe(null);
+            it("will not show the spoiler toolbar button",
+                mock.initConverseWithPromises(
+                    null, ['rosterGroupsFetched'], {},
+                    function (done, _converse) {
 
-                    view.model.set('otr_status', 3);
+                test_utils.createContacts(_converse, 'current');
+                var contact_jid = mock.cur_names[0].replace(/ /g,'.').toLowerCase() + '@localhost';
+
+                // XXX: We need to send a presence from the contact, so that we
+                // have a resource, that resource is then queried to see
+                // whether Strophe.NS.SPOILER is supported, in which case
+                // the spoiler button will appear.
+                var presence = $pres({
+                    'from': contact_jid+'/phone',
+                    'to': 'dummy@localhost'
+                });
+                _converse.connection._dataRecv(test_utils.createRequest(presence));
+                test_utils.openChatBoxFor(_converse, contact_jid);
 
-                    return test_utils.waitUntil(function () {
-                        return !_.isNull(view.el.querySelector('.toggle-compose-spoiler'));
-                    });
-                }).then(function () {
-                    spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
-                    expect(spoiler_toggle).not.toBe(null);
+                test_utils.waitUntilDiscoConfirmed(_converse, contact_jid+'/phone', [], [Strophe.NS.SPOILER]).then(function () {
+                    var spoiler_toggle;
+                    var view = _converse.chatboxviews.get(contact_jid);
+                    spyOn(view, 'addSpoilerButton').and.callThrough();
+                    view.model.set('otr_status', 1);
 
-                    view.model.set('otr_status', 2);
-                    return test_utils.waitUntil(function () {
+                    test_utils.waitUntil(function () {
                         return _.isNull(view.el.querySelector('.toggle-compose-spoiler'));
+                    }).then(function () {
+                        spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
+                        expect(spoiler_toggle).toBe(null);
+
+                        view.model.set('otr_status', 3);
+
+                        return test_utils.waitUntil(function () {
+                            return !_.isNull(view.el.querySelector('.toggle-compose-spoiler'));
+                        });
+                    }).then(function () {
+                        spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
+                        expect(spoiler_toggle).not.toBe(null);
+
+                        view.model.set('otr_status', 2);
+                        return test_utils.waitUntil(function () {
+                            return _.isNull(view.el.querySelector('.toggle-compose-spoiler'));
+                        });
+                    }).then(function () {
+                        spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
+                        expect(spoiler_toggle).toBe(null);
+
+                        view.model.set('otr_status', 4);
+                        return test_utils.waitUntil(function () {
+                            return !_.isNull(view.el.querySelector('.toggle-compose-spoiler'));
+                        });
+                    }).then(function () {
+                        spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
+                        expect(spoiler_toggle).not.toBe(null);
+                        done();
                     });
-                }).then(function () {
-                    spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
-                    expect(spoiler_toggle).toBe(null);
-
-                    view.model.set('otr_status', 4);
-                    return test_utils.waitUntil(function () {
-                        return !_.isNull(view.el.querySelector('.toggle-compose-spoiler'));
-                    });
-                }).then(function () {
-                    spoiler_toggle = view.el.querySelector('.toggle-compose-spoiler');
-                    expect(spoiler_toggle).not.toBe(null);
-                    done();
                 });
-            });
-        }));
+            }));
+        });
     });
 
     describe("The OTR module", function() {

+ 1 - 1
spec/ping.js

@@ -1,5 +1,5 @@
 (function (root, factory) {
-    define(["jasmine", "mock", "converse-core", "test-utils", "converse-ping"], factory);
+    define(["jasmine", "mock", "test-utils"], factory);
 } (this, function (jasmine, mock, test_utils) {
     "use strict";
 

+ 3 - 3
spec/presence.js

@@ -4,15 +4,15 @@
     define([
         "jasmine",
         "jquery",
-        "converse-core",
         "mock",
         "test-utils",
-        "lodash"], factory);
-} (this, function (jasmine, $, converse, mock, test_utils, _) {
+    ], factory);
+} (this, function (jasmine, $, mock, test_utils) {
     "use strict";
     var Strophe = converse.env.Strophe;
     var $iq = converse.env.$iq;
     var $pres = converse.env.$pres;
+    var _ = converse.env._;
     var u = converse.env.utils;
     // See: https://xmpp.org/rfcs/rfc3921.html
 

+ 3 - 2
spec/profiling.js

@@ -1,8 +1,9 @@
 (function (root, factory) {
-    define(["jasmine", "mock", "converse-core", "test-utils", "utils"], factory);
-} (this, function (jasmine, mock, converse, test_utils, u) {
+    define(["jasmine", "mock", "test-utils"], factory);
+} (this, function (jasmine, mock, test_utils) {
     var _ = converse.env._;
     var $iq = converse.env.$iq;
+    var u = converse.env.utils;
 
     describe("Profiling", function() {
         xit("adds hundreds of contacts to the roster",

+ 2 - 3
spec/protocol.js

@@ -2,10 +2,9 @@
     define([
         "jasmine",
         "jquery",
-        "converse-core",
         "mock",
         "test-utils"], factory);
-} (this, function (jasmine, $, converse, mock, test_utils) {
+} (this, function (jasmine, $, mock, test_utils) {
     "use strict";
     var Strophe = converse.env.Strophe;
     var $iq = converse.env.$iq;
@@ -210,7 +209,7 @@
                      *  </iq>
                      */
                     spyOn(_converse.roster, "updateContact").and.callThrough();
-                    stanza = $iq({'type': 'set', 'from': 'dummy@localhost'})
+                    stanza = $iq({'type': 'set', 'from': _converse.connection.jid})
                         .c('query', {'xmlns': 'jabber:iq:roster'})
                         .c('item', {
                             'jid': 'contact@example.org',

+ 164 - 0
spec/push.js

@@ -0,0 +1,164 @@
+(function (root, factory) {
+    define(["jasmine", "mock", "test-utils"], factory);
+} (this, function (jasmine, mock, test_utils) {
+    "use strict";
+    var $iq = converse.env.$iq;
+    var Strophe = converse.env.Strophe;
+    var _ = converse.env._;
+
+    describe("XEP-0357 Push Notifications", function () {
+
+        it("can be enabled",
+            mock.initConverseWithPromises(null,
+                ['rosterGroupsFetched'], {
+                    'push_app_servers': [{
+                        'jid': 'push-5@client.example',
+                        'node': 'yxs32uqsflafdk3iuqo'
+                    }]
+                }, function (done, _converse) {
+
+            const IQ_stanzas = _converse.connection.IQ_stanzas;
+            let stanza;
+
+            expect(_converse.session.get('push_enabled')).toBeFalsy();
+
+            test_utils.waitUntilDiscoConfirmed(
+                _converse, _converse.push_app_servers[0].jid,
+                [{'category': 'pubsub', 'type':'push'}],
+                ['urn:xmpp:push:0'], [], 'info')
+            .then(() => test_utils.waitUntilDiscoConfirmed(
+                    _converse,
+                    _converse.bare_jid,
+                    [{'category': 'account', 'type':'registered'}],
+                    ['urn:xmpp:push:0'], [], 'info'))
+            .then(() => {
+                return test_utils.waitUntil(() => {
+                    const node = _.filter(IQ_stanzas, function (iq) {
+                        return iq.nodeTree.querySelector('iq[type="set"] enable[xmlns="urn:xmpp:push:0"]');
+                    }).pop();
+                    if (node) {
+                        stanza = node.nodeTree;
+                        return true;
+                    }
+                })
+            }).then(() => {
+                expect(stanza.outerHTML).toEqual(
+                    `<iq type="set" xmlns="jabber:client" id="${stanza.getAttribute('id')}">`+
+                        '<enable xmlns="urn:xmpp:push:0" jid="push-5@client.example" node="yxs32uqsflafdk3iuqo"/>'+
+                    '</iq>'
+                )
+                _converse.connection._dataRecv(test_utils.createRequest($iq({
+                    'to': _converse.connection.jid,
+                    'type': 'result',
+                    'id': stanza.getAttribute('id')
+                })));
+                return test_utils.waitUntil(() => _converse.session.get('push_enabled'))
+            }).then(() => {
+                done();
+            }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
+        }));
+
+        it("can be disabled",
+            mock.initConverseWithPromises(null,
+                ['rosterGroupsFetched'], {
+                    'push_app_servers': [{
+                        'jid': 'push-5@client.example',
+                        'node': 'yxs32uqsflafdk3iuqo',
+                        'disable': true
+                    }]
+                }, function (done, _converse) {
+
+            const IQ_stanzas = _converse.connection.IQ_stanzas;
+            let stanza;
+
+            expect(_converse.session.get('push_enabled')).toBeFalsy();
+
+            test_utils.waitUntilDiscoConfirmed(
+                _converse,
+                _converse.bare_jid,
+                [{'category': 'account', 'type':'registered'}],
+                ['urn:xmpp:push:0'], [], 'info')
+            .then(() => {
+                return test_utils.waitUntil(() => {
+                    const node = _.filter(IQ_stanzas, function (iq) {
+                        return iq.nodeTree.querySelector('iq[type="set"] disable[xmlns="urn:xmpp:push:0"]');
+                    }).pop();
+                    if (node) {
+                        stanza = node.nodeTree;
+                        return true;
+                    }
+                })
+            }).then(() => {
+                expect(stanza.outerHTML).toEqual(
+                    `<iq type="set" xmlns="jabber:client" id="${stanza.getAttribute('id')}">`+
+                        '<disable xmlns="urn:xmpp:push:0" jid="push-5@client.example" node="yxs32uqsflafdk3iuqo"/>'+
+                    '</iq>'
+                )
+                _converse.connection._dataRecv(test_utils.createRequest($iq({
+                    'to': _converse.connection.jid,
+                    'type': 'result',
+                    'id': stanza.getAttribute('id')
+                })));
+                return test_utils.waitUntil(() => _converse.session.get('push_enabled'))
+            }).then(() => {
+                done();
+            }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
+        }));
+
+
+        it("can require a secret token to be included",
+            mock.initConverseWithPromises(null,
+                ['rosterGroupsFetched'], {
+                    'push_app_servers': [{
+                        'jid': 'push-5@client.example',
+                        'node': 'yxs32uqsflafdk3iuqo',
+                        'secret': 'eruio234vzxc2kla-91'
+                    }]
+                }, function (done, _converse) {
+
+            const IQ_stanzas = _converse.connection.IQ_stanzas;
+            let stanza;
+            expect(_converse.session.get('push_enabled')).toBeFalsy();
+
+            test_utils.waitUntilDiscoConfirmed(
+                _converse, _converse.push_app_servers[0].jid,
+                [{'category': 'pubsub', 'type':'push'}],
+                ['urn:xmpp:push:0'], [], 'info')
+            .then(() => test_utils.waitUntilDiscoConfirmed(
+                    _converse,
+                    _converse.bare_jid,
+                    [{'category': 'account', 'type':'registered'}],
+                    ['urn:xmpp:push:0'], [], 'info'))
+            .then(() => {
+                return test_utils.waitUntil(() => {
+                    const node = _.filter(IQ_stanzas, function (iq) {
+                        return iq.nodeTree.querySelector('iq[type="set"] enable[xmlns="urn:xmpp:push:0"]');
+                    }).pop();
+                    if (node) {
+                        stanza = node.nodeTree;
+                        return true;
+                    }
+                })
+            }).then(() => {
+                expect(stanza.outerHTML).toEqual(
+                    `<iq type="set" xmlns="jabber:client" id="${stanza.getAttribute('id')}">`+
+                        '<enable xmlns="urn:xmpp:push:0" jid="push-5@client.example" node="yxs32uqsflafdk3iuqo">'+
+                            '<x xmlns="jabber:x:data" type="submit">'+
+                                '<field var="FORM_TYPE"><value>http://jabber.org/protocol/pubsub#publish-options</value></field>'+
+                                '<field var="secret"><value>eruio234vzxc2kla-91</value></field>'+
+                            '</x>'+
+                        '</enable>'+
+                    '</iq>'
+                )
+                _converse.connection._dataRecv(test_utils.createRequest($iq({
+                    'to': _converse.connection.jid,
+                    'type': 'result',
+                    'id': stanza.getAttribute('id')
+                })));
+                return test_utils.waitUntil(() => _converse.session.get('push_enabled'))
+            }).then(() => {
+                done();
+            }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
+        }));
+    });
+}));

+ 20 - 6
spec/register.js

@@ -1,6 +1,6 @@
 (function (root, factory) {
-    define(["jquery", "jasmine", "mock", "converse-core", "test-utils"], factory);
-} (this, function ($, jasmine, mock, converse, test_utils) {
+    define(["jquery", "jasmine", "mock", "test-utils"], factory);
+} (this, function ($, jasmine, mock, test_utils) {
     var Strophe = converse.env.Strophe;
     var $iq = converse.env.$iq;
     var _ = converse.env._;
@@ -264,10 +264,24 @@
                 registerview.el.querySelector('input[type=submit]').click();
 
                 expect(_converse.connection.send).toHaveBeenCalled();
-                var $stanza = $(_converse.connection.send.calls.argsFor(0)[0].tree());
-                expect($stanza.children('query').children().length).toBe(1);
-                expect($stanza.children('query').children().children().length).toBe(3);
-                expect($stanza.children('query').children().children()[0].tagName).toBe('field');
+                stanza = _converse.connection.send.calls.argsFor(0)[0].tree();
+                expect(stanza.outerHTML.trim().replace(/(\n|\s{2,})/g, '')).toEqual(
+                    '<iq type="set" id="'+stanza.getAttribute('id')+'" xmlns="jabber:client">'+
+                        '<query xmlns="jabber:iq:register">'+
+                            '<x xmlns="jabber:x:data" type="submit">'+
+                                '<field xmlns="http://www.w3.org/1999/xhtml" var="username">'+
+                                    '<value>testusername</value>'+
+                                '</field>'+
+                                '<field xmlns="http://www.w3.org/1999/xhtml" var="password">'+
+                                    '<value>testpassword</value>'+
+                                '</field>'+
+                                '<field xmlns="http://www.w3.org/1999/xhtml" var="email">'+
+                                    '<value>test@email.local</value>'+
+                                '</field>'+
+                            '</x>'+
+                        '</query>'+
+                    '</iq>'
+                );
                 done();
             });
         }));

+ 106 - 5
spec/roomslist.js

@@ -1,13 +1,17 @@
 (function (root, factory) {
-    define(["jasmine", "mock", "converse-core", "converse-roomslist", "test-utils"], factory);
-} (this, function (jasmine, mock, converse, roomslist, test_utils) {
+    define(["jasmine", "mock", "test-utils"], factory);
+} (this, function (jasmine, mock, test_utils) {
     var _ = converse.env._;
     var $msg = converse.env.$msg;
+    var $iq = converse.env.$iq;
+    var $pres = converse.env.$pres;
     var Promise = converse.env.Promise;
+    var Strophe = converse.env.Strophe;
+    var u = converse.env.utils;
 
-    describe("The converse-roomslist plugin", function () {
+    describe("A list of open rooms", function () {
 
-        it("is shown under a list of open rooms in the \"Rooms\" panel", mock.initConverseWithPromises(
+        it("is shown in the \"Rooms\" panel", mock.initConverseWithPromises(
             null, ['rosterGroupsFetched'],
             { allow_bookmarks: false // Makes testing easier, otherwise we
                                      // have to mock stanza traffic.
@@ -50,7 +54,104 @@
         ));
     });
 
-    describe("An room shown in the rooms list", function () {
+    describe("A room shown in the rooms list", function () {
+
+        it("has an info icon which opens a details modal when clicked", mock.initConverseWithPromises(
+            null, ['rosterGroupsFetched'],
+            { whitelisted_plugins: ['converse-roomslist'],
+              allow_bookmarks: false // Makes testing easier, otherwise we
+                                     // have to mock stanza traffic.
+            }, function (done, _converse) {
+
+            test_utils.openControlBox();
+            _converse.api.rooms.open('coven@chat.shakespeare.lit', {'nick': 'some1'});
+            const view = _converse.chatboxviews.get('coven@chat.shakespeare.lit');
+            const last_stanza = _.last(_converse.connection.IQ_stanzas).nodeTree;
+            const IQ_id = last_stanza.getAttribute('id');
+            const features_stanza = $iq({
+                    'from': 'coven@chat.shakespeare.lit',
+                    'id': IQ_id,
+                    'to': 'dummy@localhost/desktop',
+                    'type': 'result'
+                })
+                .c('query', { 'xmlns': 'http://jabber.org/protocol/disco#info'})
+                    .c('identity', {
+                        'category': 'conference',
+                        'name': 'A Dark Cave',
+                        'type': 'text'
+                    }).up()
+                    .c('feature', {'var': 'http://jabber.org/protocol/muc'}).up()
+                    .c('feature', {'var': 'muc_passwordprotected'}).up()
+                    .c('feature', {'var': 'muc_hidden'}).up()
+                    .c('feature', {'var': 'muc_temporary'}).up()
+                    .c('feature', {'var': 'muc_open'}).up()
+                    .c('feature', {'var': 'muc_unmoderated'}).up()
+                    .c('feature', {'var': 'muc_nonanonymous'}).up()
+                    .c('feature', {'var': 'urn:xmpp:mam:0'}).up()
+                    .c('x', { 'xmlns':'jabber:x:data', 'type':'result'})
+                        .c('field', {'var':'FORM_TYPE', 'type':'hidden'})
+                            .c('value').t('http://jabber.org/protocol/muc#roominfo').up().up()
+                        .c('field', {'type':'text-single', 'var':'muc#roominfo_description', 'label':'Description'})
+                            .c('value').t('This is the description').up().up()
+                        .c('field', {'type':'text-single', 'var':'muc#roominfo_occupants', 'label':'Number of occupants'})
+                            .c('value').t(0);
+            _converse.connection._dataRecv(test_utils.createRequest(features_stanza));
+
+            test_utils.waitUntil(() => view.model.get('connection_status') === converse.ROOMSTATUS.CONNECTING)
+            .then(function () {
+                var presence = $pres({
+                        to: _converse.connection.jid,
+                        from: 'coven@chat.shakespeare.lit/some1',
+                        id: 'DC352437-C019-40EC-B590-AF29E879AF97'
+                }).c('x').attrs({xmlns:'http://jabber.org/protocol/muc#user'})
+                    .c('item').attrs({
+                        affiliation: 'member',
+                        jid: _converse.bare_jid,
+                        role: 'participant'
+                    }).up()
+                    .c('status').attrs({code:'110'});
+                _converse.connection._dataRecv(test_utils.createRequest(presence));
+
+                const room_els = _converse.rooms_list_view.el.querySelectorAll(".open-room");
+                expect(room_els.length).toBe(1);
+                var info_el = _converse.rooms_list_view.el.querySelector(".room-info");
+                info_el.click();
+
+                const modal = view.model.room_details_modal;
+                return test_utils.waitUntil(() => u.isVisible(modal.el), 2000);
+            }).then(() => {
+                const modal = view.model.room_details_modal;
+                let els = modal.el.querySelectorAll('p.room-info');
+                expect(els[0].textContent).toBe("Room address (JID): coven@chat.shakespeare.lit")
+                expect(els[1].textContent).toBe("Name: A Dark Cave")
+                expect(els[2].textContent).toBe("Description: This is the description")
+                expect(els[3].textContent).toBe("Online users: 1")
+                const features_list = modal.el.querySelector('.features-list');
+                expect(features_list.textContent.replace(/(\n|\s{2,})/g, '')).toBe(
+                    'Password protected - This room requires a password before entry'+
+                    'Hidden - This room is not publicly searchable'+
+                    'Open - Anyone can join this room'+
+                    'Temporary - This room will disappear once the last person leaves'+
+                    'Not anonymous - All other room occupants can see your XMPP username'+
+                    'Not moderated - This room is not being moderated'
+                );
+                const presence = $pres({
+                        to: 'dummy@localhost/_converse.js-29092160',
+                        from: 'coven@chat.shakespeare.lit/newguy'
+                    })
+                    .c('x', {xmlns: Strophe.NS.MUC_USER})
+                    .c('item', {
+                        'affiliation': 'none',
+                        'jid': 'newguy@localhost/_converse.js-290929789',
+                        'role': 'participant'
+                    });
+                _converse.connection._dataRecv(test_utils.createRequest(presence));
+
+                els = modal.el.querySelectorAll('p.room-info');
+                expect(els[3].textContent).toBe("Online users: 2")
+                done();
+            });
+        }));
 
         it("can be closed", mock.initConverseWithPromises(
             null, ['rosterGroupsFetched'],

+ 64 - 2
spec/roster.js

@@ -1,6 +1,6 @@
 (function (root, factory) {
-    define(["jquery", "jasmine", "mock", "converse-core", "test-utils"], factory);
-} (this, function ($, jasmine, mock, converse, test_utils) {
+    define(["jquery", "jasmine", "mock", "test-utils"], factory);
+} (this, function ($, jasmine, mock, test_utils) {
     var _ = converse.env._;
     var Strophe = converse.env.Strophe;
     var $pres = converse.env.$pres;
@@ -35,6 +35,68 @@
 
     describe("The Contacts Roster", function () {
 
+        it("supports roster versioning",
+            mock.initConverseWithPromises(
+                null, ['rosterGroupsFetched'], {},
+                function (done, _converse) {
+
+            var IQ_stanzas = _converse.connection.IQ_stanzas;
+            var stanza;
+
+            test_utils.waitUntil(() => {
+                const node = _.filter(IQ_stanzas, function (iq) {
+                    return iq.nodeTree.querySelector('iq query[xmlns="jabber:iq:roster"]');
+                }).pop();
+                if (node) {
+                    stanza = node.nodeTree;
+                    return true;
+                }
+            }).then(() => {
+                expect(_converse.roster.data.get('version')).toBeUndefined();
+                expect(stanza.outerHTML).toBe(
+                    `<iq type="get" id="${stanza.getAttribute('id')}" xmlns="jabber:client">`+
+                        `<query xmlns="jabber:iq:roster"/>`+
+                    `</iq>`);
+                let result = $iq({
+                    'to': _converse.connection.jid,
+                    'type': 'result',
+                    'id': stanza.getAttribute('id')
+                }).c('query', {
+                    'xmlns': 'jabber:iq:roster',
+                    'ver': 'ver7'
+                }).c('item', {'jid': 'nurse@example.com'}).up()
+                  .c('item', {'jid': 'romeo@example.com'})
+                _converse.connection._dataRecv(test_utils.createRequest(result));
+                expect(_converse.roster.data.get('version')).toBe('ver7');
+                expect(_converse.roster.models.length).toBe(2);
+
+                _converse.roster.fetchFromServer();
+                stanza = _converse.connection.IQ_stanzas.pop().nodeTree;
+                expect(stanza.outerHTML).toBe(
+                    `<iq type="get" id="${stanza.getAttribute('id')}" xmlns="jabber:client">`+
+                        `<query xmlns="jabber:iq:roster" ver="ver7"/>`+
+                    `</iq>`);
+
+                result = $iq({
+                    'to': _converse.connection.jid,
+                    'type': 'result',
+                    'id': stanza.getAttribute('id')
+                });
+                _converse.connection._dataRecv(test_utils.createRequest(result));
+
+                const roster_push = $iq({
+                    'to': _converse.connection.jid,
+                    'type': 'set',
+                }).c('query', {'xmlns': 'jabber:iq:roster', 'ver': 'ver34'})
+                    .c('item', {'jid': 'romeo@example.com', 'subscription': 'remove'});
+                _converse.connection._dataRecv(test_utils.createRequest(roster_push));
+                expect(_converse.roster.data.get('version')).toBe('ver34');
+                expect(_converse.roster.models.length).toBe(1);
+                expect(_converse.roster.at(0).get('jid')).toBe('nurse@example.com');
+                done();
+            });
+        }));
+
         describe("The live filter", function () {
 
             it("will only appear when roster contacts flow over the visible area",

+ 2 - 9
spec/spoilers.js

@@ -1,13 +1,6 @@
 (function (root, factory) {
-    define([
-        "jasmine",
-        "utils",
-        "mock",
-        "converse-core",
-        "test-utils"
-        ], factory);
-} (this, function (jasmine, utils, mock, converse, test_utils) {
-
+    define(["jasmine", "mock", "test-utils"], factory);
+} (this, function (jasmine, mock, test_utils) {
     var _ = converse.env._;
     var Strophe = converse.env.Strophe;
     var $msg = converse.env.$msg;

+ 1 - 3
spec/user-details-modal.js

@@ -1,12 +1,10 @@
 (function (root, factory) {
     define([
         "jasmine",
-        "utils",
-        "converse-core",
         "mock",
         "test-utils"
         ], factory);
-} (this, function (jasmine, utils, converse, mock, test_utils) {
+} (this, function (jasmine, mock, test_utils) {
     "use strict";
     var _ = converse.env._;
     var $iq = converse.env.$iq;

+ 2 - 2
spec/utils.js

@@ -1,6 +1,6 @@
 (function (root, factory) {
-    define(["jasmine", "converse-core"], factory);
-} (this, function (jasmine, converse) {
+    define(["jasmine"], factory);
+} (this, function (jasmine) {
     var utils = converse.env.utils,
         _ = converse.env._;
 

+ 2 - 2
spec/xmppstatus.js

@@ -1,6 +1,6 @@
 (function (root, factory) {
-    define(["jquery", "jasmine", "mock", "converse-core", "test-utils"], factory);
-} (this, function ($, jasmine, mock, converse, test_utils) {
+    define(["jquery", "jasmine", "mock", "test-utils"], factory);
+} (this, function ($, jasmine, mock, test_utils) {
 
     return describe("The XMPPStatus model", function() {
 

+ 0 - 9
src/build-esnext.js

@@ -1,9 +0,0 @@
-({
-    baseUrl: "../",
-    name: "almond",
-    mainConfigFile: 'config.js',
-    wrap: {
-        startFile: "start.frag",
-        endFile: "end.frag"
-    }
-});

+ 0 - 54
src/build-no-dependencies.js

@@ -1,54 +0,0 @@
-({
-    baseUrl: "../",
-    name: "almond",
-    out: "../dist/converse-no-dependencies.min.js",
-    include: ["converse"],
-    exclude: [
-        "awesomplete",
-        "backbone.browserStorage",
-        "backbone.overview",
-        "moment",
-        "strophe",
-        "strophe.rsm",
-        "strophe.ping",
-        "otr",
-        "lodash",
-        "lodash.converter",
-        "lodash.noconflict",
-        "es6-promise"
-    ],
-    paths: {
-        "backbone.vdomview":        "builds/backbone.vdomview",
-        "converse-bookmarks":       "builds/converse-bookmarks",
-        "converse-chatboxes":       "builds/converse-chatboxes",
-        "converse-chatview":        "builds/converse-chatview",
-        "converse-controlbox":      "builds/converse-controlbox",
-        "converse-core":            "builds/converse-core",
-        "converse-disco":           "builds/converse-disco",
-        "converse-dragresize":      "builds/converse-dragresize",
-        "converse-embedded":        "builds/converse-embedded",
-        "converse-fullscreen":      "builds/converse-fullscreen",
-        "converse-headline":        "builds/converse-headline",
-        "converse-mam":             "builds/converse-mam",
-        "converse-minimize":        "builds/converse-minimize",
-        "converse-muc":             "builds/converse-muc",
-        "converse-notification":    "builds/converse-notification",
-        "converse-otr":             "builds/converse-otr",
-        "converse-ping":            "builds/converse-ping",
-        "converse-profile":         "builds/converse-profile",
-        "converse-register":        "builds/converse-register",
-        "converse-roomslist":       "builds/converse-roomslist",
-        "converse-rosterview":      "builds/converse-rosterview",
-        "converse-singleton":       "builds/converse-singleton",
-        "converse-vcard":           "builds/converse-vcard",
-        "form-utils":               "builds/utils/form",
-        "i18n":                     "builds/i18n",
-        "utils":                    "builds/utils/core",
-        "muc-utils":                "builds/utils/muc"
-    },
-    wrap: {
-        startFile: "start.frag",
-        endFile: "end-no-dependencies.frag"
-    },
-    mainConfigFile: "config.js"
-});

+ 0 - 43
src/build.js

@@ -1,43 +0,0 @@
-({
-    baseUrl: "../",
-    name: "almond",
-    mainConfigFile: 'config.js',
-    paths: {
-        "backbone.vdomview":        "builds/backbone.vdomview",
-        "converse-bookmarks":       "builds/converse-bookmarks",
-        "converse-caps":            "builds/converse-caps",
-        "converse-chatboxes":       "builds/converse-chatboxes",
-        "converse-chatview":        "builds/converse-chatview",
-        "converse-controlbox":      "builds/converse-controlbox",
-        "converse-core":            "builds/converse-core",
-        "converse-disco":           "builds/converse-disco",
-        "converse-dragresize":      "builds/converse-dragresize",
-        "converse-embedded":        "builds/converse-embedded",
-        "converse-fullscreen":      "builds/converse-fullscreen",
-        "converse-headline":        "builds/converse-headline",
-        "converse-mam":             "builds/converse-mam",
-        "converse-message-view":    "builds/converse-message-view",
-        "converse-minimize":        "builds/converse-minimize",
-        "converse-modal":           "builds/converse-modal",
-        "converse-muc":             "builds/converse-muc",
-        "converse-muc-views":       "builds/converse-muc-views",
-        "converse-notification":    "builds/converse-notification",
-        "converse-otr":             "builds/converse-otr",
-        "converse-ping":            "builds/converse-ping",
-        "converse-profile":         "builds/converse-profile",
-        "converse-register":        "builds/converse-register",
-        "converse-roomslist":       "builds/converse-roomslist",
-        "converse-roster":          "builds/converse-roster",
-        "converse-rosterview":      "builds/converse-rosterview",
-        "converse-singleton":       "builds/converse-singleton",
-        "converse-vcard":           "builds/converse-vcard",
-        "form-utils":               "builds/utils/form",
-        "i18n":                     "builds/i18n",
-        "muc-utils":                "builds/utils/muc",
-        "utils":                    "builds/utils/core"
-    },
-    wrap: {
-        startFile: "start.frag",
-        endFile: "end.frag"
-    }
-});

+ 0 - 168
src/config.js

@@ -1,168 +0,0 @@
-var config;
-if (typeof(require) === 'undefined') {
-    /* XXX: Hack to work around r.js's stupid parsing.
-     * We want to save the configuration in a variable so that we can reuse it in
-     * tests/main.js.
-     */
-    // eslint-disable-next-line
-    require = { // jshint ignore:line
-        config: function (c) {
-            config = c;
-        }
-    };
-}
-
-require.config({
-    baseUrl: '.',
-    paths: {
-        "IPv6":                     "node_modules/urijs/src/IPv6",
-        "SecondLevelDomains":       "node_modules/urijs/src/SecondLevelDomains",
-        "almond":                   "node_modules/almond/almond",
-        "awesomplete":              "node_modules/awesomplete-avoid-xss/awesomplete",
-        "babel":                    "node_modules/requirejs-babel/babel-5.8.34.min",
-        "backbone":                 "node_modules/backbone/backbone",
-        "backbone.browserStorage":  "node_modules/backbone.browserStorage/backbone.browserStorage",
-        "backbone.nativeview":      "node_modules/backbone.nativeview/backbone.nativeview",
-        "backbone.noconflict":      "src/backbone.noconflict",
-        "backbone.orderedlistview": "node_modules/backbone.overview/dist/backbone.orderedlistview",
-        "backbone.overview":        "node_modules/backbone.overview/dist/backbone.overview",
-        "backbone.vdomview":        "node_modules/backbone.vdomview/dist/backbone.vdomview",
-        "bootstrap":                "node_modules/bootstrap.native/dist/bootstrap-native-v4",
-        "emojione":                 "node_modules/emojione/lib/js/emojione",
-        "es6-promise":              "node_modules/es6-promise/dist/es6-promise.auto",
-        "eventemitter":             "node_modules/otr/build/dep/eventemitter",
-        "filesize":                 "node_modules/filesize/lib/filesize",
-        "form-utils":               "src/utils/form",
-        "i18n":                     "src/i18n",
-        "jed":                      "node_modules/jed/jed",
-        "jquery":                   "src/jquery-stub",
-        "lodash":                   "node_modules/lodash/lodash",
-        "lodash.converter":         "3rdparty/lodash.fp",
-        "lodash.fp":                "src/lodash.fp",
-        "lodash.noconflict":        "src/lodash.noconflict",
-        "message-utils":            "src/utils/message",
-        "muc-utils":                "src/utils/muc",
-        "pluggable":                "node_modules/pluggable.js/dist/pluggable",
-        "polyfill":                 "src/polyfill",
-        "punycode":                 "node_modules/urijs/src/punycode",
-        "sizzle":                   "node_modules/sizzle/dist/sizzle",
-        "snabbdom":                 "node_modules/snabbdom/dist/snabbdom",
-        "snabbdom-attributes":      "node_modules/snabbdom/dist/snabbdom-attributes",
-        "snabbdom-class":           "node_modules/snabbdom/dist/snabbdom-class",
-        "snabbdom-dataset":         "node_modules/snabbdom/dist/snabbdom-dataset",
-        "snabbdom-eventlisteners":  "node_modules/snabbdom/dist/snabbdom-eventlisteners",
-        "snabbdom-props":           "node_modules/snabbdom/dist/snabbdom-props",
-        "snabbdom-style":           "node_modules/snabbdom/dist/snabbdom-style",
-        "strophe":                  "node_modules/strophe.js/strophe",
-        "strophe.ping":             "node_modules/strophejs-plugin-ping/strophe.ping",
-        "strophe.rsm":              "node_modules/strophejs-plugin-rsm/strophe.rsm",
-        "text":                     "node_modules/text/text",
-        "tovnode":                  "node_modules/snabbdom/dist/tovnode",
-        "tpl":                      "node_modules/lodash-template-loader/loader",
-        "underscore":               "src/underscore-shim",
-        "uri":                      "node_modules/urijs/src/URI",
-        "utils":                    "src/utils/core",
-        "vdom-parser":              "node_modules/vdom-parser/dist",
-        "xss":                      "node_modules/xss/dist/xss",
-        "xss.noconflict":           "src/xss.noconflict",
-
-        // OMEMO/libsignal requirements
-        "Long":                     "3rdparty/long",
-        "protobuf":                 "3rdparty/protobuf",
-        "bytebuffer":               "3rdparty/bytebuffer",
-        "libsignal":                "3rdparty/libsignal-protocol-javascript/dist/libsignal-protocol",
-
-        // Converse
-        "converse":                 "src/converse",
-
-        "converse-bookmarks":       "src/converse-bookmarks",
-        "converse-caps":            "src/converse-caps",
-        "converse-chatboxes":       "src/converse-chatboxes",
-        "converse-chatview":        "src/converse-chatview",
-        "converse-controlbox":      "src/converse-controlbox",
-        "converse-core":            "src/converse-core",
-        "converse-disco":           "src/converse-disco",
-        "converse-dragresize":      "src/converse-dragresize",
-        "converse-embedded":        "src/converse-embedded",
-        "converse-fullscreen":      "src/converse-fullscreen",
-        "converse-headline":        "src/converse-headline",
-        "converse-mam":             "src/converse-mam",
-        "converse-message-view":    "src/converse-message-view",
-        "converse-minimize":        "src/converse-minimize",
-        "converse-modal":           "src/converse-modal",
-        "converse-muc":             "src/converse-muc",
-        "converse-muc-views":       "src/converse-muc-views",
-        "converse-notification":    "src/converse-notification",
-        "converse-omemo":           "src/converse-omemo",
-        "converse-otr":             "src/converse-otr",
-        "converse-ping":            "src/converse-ping",
-        "converse-profile":         "src/converse-profile",
-        "converse-register":        "src/converse-register",
-        "converse-roomslist":       "src/converse-roomslist",
-        "converse-roster":          "src/converse-roster",
-        "converse-rosterview":      "src/converse-rosterview",
-        "converse-singleton":       "src/converse-singleton",
-        "converse-vcard":           "src/converse-vcard",
-
-        // Off-the-record-encryption
-        // "bigint":               "node_modules/otr/build/dep/bigint",
-        "bigint":               "3rdparty/bigint",
-        "crypto":               "node_modules/otr/build/dep/crypto",
-        "salsa20":              "node_modules/otr/build/dep/salsa20",
-        "otr":                  "node_modules/otr/build/otr",
-    },
-
-    packages: [{
-        'name': 'moment',
-        'location': 'node_modules/moment',
-        'main': 'moment'
-    }],
-
-    map: {
-        // '*' means all modules will get the '*.noconflict' version
-        // as their dependency.
-        '*': {
-            'backbone': 'backbone.noconflict',
-            'lodash': 'lodash.noconflict'
-         },
-        // '*.noconflict' wants the real module
-        // If this line was not here, there would
-        // be an unresolvable cyclic dependency.
-        'backbone.noconflict': { 'backbone': 'backbone' },
-        'lodash.noconflict': { 'lodash': 'lodash' }
-    },
-
-    lodashLoader: {
-        // Configuration for requirejs-tpl
-        // Use Mustache style syntax for variable interpolation
-        root: "src/templates/",
-        templateSettings: {
-            "escape": /\{\{\{([\s\S]+?)\}\}\}/g,
-            "evaluate": /\{\[([\s\S]+?)\]\}/g,
-            "interpolate": /\{\{([\s\S]+?)\}\}/g,
-            // By default, template places the values from your data in the
-            // local scope via the with statement. However, you can specify
-            // a single variable name with the variable setting. This can
-            // significantly improve the speed at which a template is able
-            // to render.
-            "variable": 'o'
-        }
-    },
-
-    // define module dependencies for modules not using define
-    shim: {
-        'backbone.orderedlistview': { deps: ['backbone.nativeview'] },
-        'backbone.overview':        { deps: ['backbone.nativeview'] },
-        'backbone.vdomview':        { deps: ['backbone.nativeview'] },
-        'awesomplete':              { exports: 'Awesomplete'},
-        'emojione':                 { exports: 'emojione'},
-        'xss':  {
-            'init': function (xss_noconflict) {
-                return {
-                    filterXSS: window.filterXSS,
-                    filterCSS: window.filterCSS
-                }
-            }
-        }
-    }
-});

+ 7 - 8
src/converse-bookmarks.js

@@ -12,10 +12,10 @@
 (function (root, factory) {
     define(["converse-core",
             "converse-muc",
-            "tpl!chatroom_bookmark_form",
-            "tpl!chatroom_bookmark_toggle",
-            "tpl!bookmark",
-            "tpl!bookmarks_list"
+            "templates/chatroom_bookmark_form.html",
+            "templates/chatroom_bookmark_toggle.html",
+            "templates/bookmark.html",
+            "templates/bookmarks_list.html"
         ],
         factory);
 }(this, function (
@@ -337,10 +337,9 @@
                         'type': 'get',
                     }).c('pubsub', {'xmlns': Strophe.NS.PUBSUB})
                         .c('items', {'node': 'storage:bookmarks'});
-                    _converse.connection.sendIQ(
-                        stanza,
-                        _.bind(this.onBookmarksReceived, this, deferred),
-                        _.bind(this.onBookmarksReceivedError, this, deferred)
+                    _converse.api.sendIQ(stanza)
+                        .then((iq) => this.onBookmarksReceived(deferred, iq))
+                        .catch((iq) => this.onBookmarksReceivedError(deferred, iq)
                     );
                 },
 

+ 83 - 73
src/converse-chatboxes.js

@@ -9,9 +9,9 @@
         "converse-core",
         "emojione",
         "filesize",
-        "tpl!chatboxes",
+        "templates/chatboxes.html",
         "backbone.overview",
-        "form-utils"
+        "utils/form"
     ], factory);
 }(this, function (converse, emojione, filesize, tpl_chatboxes) {
     "use strict";
@@ -29,18 +29,6 @@
             // plugin architecture they will replace existing methods on the
             // relevant objects or classes.
 
-            disconnect: function () {
-                const { _converse } = this.__super__;
-                _converse.chatboxviews.closeAllChatBoxes();
-                return this.__super__.disconnect.apply(this, arguments);
-            },
-
-            logOut: function () {
-                const { _converse } = this.__super__;
-                _converse.chatboxviews.closeAllChatBoxes();
-                return this.__super__.logOut.apply(this, arguments);
-            },
-
             initStatus: function (reconnecting) {
                 const { _converse } = this.__super__;
                 if (!reconnecting) {
@@ -62,7 +50,9 @@
             // Refer to docs/source/configuration.rst for explanations of these
             // configuration settings.
             _converse.api.settings.update({
-                auto_join_private_chats: [],
+                'filter_by_resource': false,
+                'auto_join_private_chats': [],
+                'forward_messages': false,
             });
             _converse.api.promises.add([
                 'chatBoxesFetched',
@@ -110,17 +100,35 @@
                     }
                 },
 
-                setVCard () {
-                    if (this.get('type') === 'groupchat') {
-                        const chatbox = this.collection.chatbox,
-                              nick = Strophe.getResourceFromJid(this.get('from'));
-                        if (chatbox.get('nick') === nick) {
-                            this.vcard = _converse.xmppstatus.vcard;
-                        } else {
+                getVCardForChatroomOccupant () {
+                    const chatbox = this.collection.chatbox,
+                          nick = Strophe.getResourceFromJid(this.get('from'));
+
+                    if (chatbox.get('nick') === nick) {
+                        return _converse.xmppstatus.vcard;
+                    } else {
+                        let vcard;
+                        if (this.get('vcard_jid')) {
+                            vcard = _converse.vcards.findWhere({'jid': this.get('vcard_jid')});
+                        }
+                        if (!vcard) {
+                            let jid;
                             const occupant = chatbox.occupants.findWhere({'nick': nick});
-                            const jid = (occupant && occupant.get('jid')) ? occupant.get('jid') : this.get('from');
-                            this.vcard = _converse.vcards.findWhere({'jid': jid}) || _converse.vcards.create({'jid': jid});
+                            if (occupant && occupant.get('jid')) {
+                                jid = occupant.get('jid');
+                                this.save({'vcard_jid': jid}, {'silent': true});
+                            } else {
+                                jid = this.get('from');
+                            }
+                            vcard = _converse.vcards.findWhere({'jid': jid}) || _converse.vcards.create({'jid': jid});
                         }
+                        return vcard;
+                    }
+                },
+
+                setVCard () {
+                    if (this.get('type') === 'groupchat') {
+                        this.vcard = this.getVCardForChatroomOccupant();
                     } else {
                         const jid = this.get('from');
                         this.vcard = _converse.vcards.findWhere({'jid': jid}) || _converse.vcards.create({'jid': jid});
@@ -231,13 +239,16 @@
 
 
             _converse.ChatBox = _converse.ModelWithVCardAndPresence.extend({
-                defaults: {
-                    'bookmarked': false,
-                    'chat_state': undefined,
-                    'num_unread': 0,
-                    'type': 'chatbox',
-                    'message_type': 'chat',
-                    'url': ''
+                defaults () {
+                    return {
+                        'bookmarked': false,
+                        'chat_state': undefined,
+                        'num_unread': 0,
+                        'type': 'chatbox',
+                        'message_type': 'chat',
+                        'url': '',
+                        'hidden': _.includes(['mobile', 'fullscreen'], _converse.view_mode)
+                    }
                 },
 
                 initialize () {
@@ -401,12 +412,17 @@
 
                 getMessageBody (message) {
                     const type = message.getAttribute('type');
-                    return (type === 'error') ?
-                        _.propertyOf(message.querySelector('error text'))('textContent') :
-                            _.propertyOf(message.querySelector('body'))('textContent');
+                    if (type === 'error') {
+                        const error = message.querySelector('error');
+                        return _.propertyOf(error.querySelector('text'))('textContent') ||
+                            __('Sorry, an error occured:') + ' ' + error.innerHTML;
+                    } else {
+                        return _.propertyOf(message.querySelector('body'))('textContent');
+                    }
+
                 },
 
-                getMessageAttributesFromStanza (message, delay, original_stanza) {
+                getMessageAttributesFromStanza (message, original_stanza) {
                     /* Parses a passed in message stanza and returns an object
                      * of attributes.
                      *
@@ -418,11 +434,11 @@
                      *      that contains the message stanza, if it was
                      *      contained, otherwise it's the message stanza itself.
                      */
-                    delay = delay || message.querySelector('delay');
-
                     const { _converse } = this.__super__,
                           { __ } = _converse,
-                          spoiler = message.querySelector(`spoiler[xmlns="${Strophe.NS.SPOILER}"]`),
+                          archive = sizzle(`result[xmlns="${Strophe.NS.MAM}"]`, original_stanza).pop(),
+                          spoiler = sizzle(`spoiler[xmlns="${Strophe.NS.SPOILER}"]`, original_stanza).pop(),
+                          delay = sizzle(`delay[xmlns="${Strophe.NS.DELAY}"]`, original_stanza).pop(),
                           chat_state = message.getElementsByTagName(_converse.COMPOSING).length && _converse.COMPOSING ||
                                 message.getElementsByTagName(_converse.PAUSED).length && _converse.PAUSED ||
                                 message.getElementsByTagName(_converse.INACTIVE).length && _converse.INACTIVE ||
@@ -430,13 +446,14 @@
                                 message.getElementsByTagName(_converse.GONE).length && _converse.GONE;
 
                     const attrs = {
-                        'type': message.getAttribute('type'),
                         'chat_state': chat_state,
-                        'delayed': !_.isNull(delay),
+                        'is_archived': !_.isNil(archive),
+                        'is_delayed': !_.isNil(delay),
+                        'is_spoiler': !_.isNil(spoiler),
                         'message': this.getMessageBody(message) || undefined,
                         'msgid': message.getAttribute('id'),
                         'time': delay ? delay.getAttribute('stamp') : moment().format(),
-                        'is_spoiler': !_.isNull(spoiler)
+                        'type': message.getAttribute('type')
                     };
                     if (attrs.type === 'groupchat') {
                         attrs.from = message.getAttribute('from');
@@ -466,14 +483,15 @@
                     return attrs;
                 },
 
-                createMessage (message, delay, original_stanza) {
+                createMessage (message, original_stanza) {
                     /* Create a Backbone.Message object inside this chat box
                      * based on the identified message stanza.
                      */
-                    const attrs = this.getMessageAttributesFromStanza.apply(this, arguments)
+                    const attrs = this.getMessageAttributesFromStanza(message, original_stanza);
                     const is_csn = u.isOnlyChatStateNotification(attrs);
-                    if (is_csn && attrs.delayed) {
-                        // No need showing old CSNs
+                    if (is_csn && (attrs.is_delayed || (attrs.type === 'groupchat' && Strophe.getResourceFromJid(attrs.from) == this.get('nick')))) {
+                        // XXX: MUC leakage
+                        // No need showing delayed or our own CSN messages
                         return;
                     } else if (!is_csn && !attrs.file && !attrs.message && !attrs.oob_url && attrs.type !== 'error') {
                         // TODO: handle <subject> messages (currently being done by ChatRoom)
@@ -483,7 +501,7 @@
                     }
                 },
 
-                newMessageWillBeHidden () {
+                isHidden () {
                     /* Returns a boolean to indicate whether a newly received
                      * message will be visible to the user or not.
                      */
@@ -500,7 +518,7 @@
                     if (_.isNull(stanza.querySelector('body'))) {
                         return; // The message has no text
                     }
-                    if (utils.isNewMessage(stanza) && this.newMessageWillBeHidden()) {
+                    if (utils.isNewMessage(stanza) && this.isHidden()) {
                         this.save({'num_unread': this.get('num_unread') + 1});
                         _converse.incrementMsgCounter();
                     }
@@ -524,12 +542,14 @@
                 },
 
                 registerMessageHandler () {
-                    _converse.connection.addHandler(
-                        this.onMessage.bind(this), null, 'message', 'chat'
-                    );
-                    _converse.connection.addHandler(
-                        this.onErrorMessage.bind(this), null, 'message', 'error'
-                    );
+                    _converse.connection.addHandler((stanza) => {
+                        this.onMessage(stanza);
+                        return true;
+                    }, null, 'message', 'chat');
+                    _converse.connection.addHandler((stanza) => {
+                        this.onErrorMessage(stanza);
+                        return true;
+                    }, null, 'message', 'error');
                 },
 
                 chatBoxMayBeShown (chatbox) {
@@ -547,29 +567,27 @@
                 },
 
                 onConnected () {
-                    this.browserStorage = new Backbone.BrowserStorage[_converse.storage](
+                    this.browserStorage = new Backbone.BrowserStorage.session(
                         b64_sha1(`converse.chatboxes-${_converse.bare_jid}`));
                     this.registerMessageHandler();
                     this.fetch({
-                        add: true,
-                        success: this.onChatBoxesFetched.bind(this)
+                        'add': true,
+                        'success': this.onChatBoxesFetched.bind(this)
                     });
                 },
 
                 onErrorMessage (message) {
                     /* Handler method for all incoming error message stanzas
                     */
-                    // TODO: we can likely just reuse "onMessage" below
                     const from_jid =  Strophe.getBareJidFromJid(message.getAttribute('from'));
                     if (utils.isSameBareJID(from_jid, _converse.bare_jid)) {
                         return true;
                     }
-                    // Get chat box, but only create a new one when the message has a body.
                     const chatbox = this.getChatBox(from_jid);
                     if (!chatbox) {
                         return true;
                     }
-                    chatbox.createMessage(message, null, message);
+                    chatbox.createMessage(message, message);
                     return true;
                 },
 
@@ -580,8 +598,7 @@
                      * Parameters:
                      *    (XMLElement) message - The incoming message stanza
                      */
-                    let contact_jid, delay, resource,
-                        from_jid = message.getAttribute('from'),
+                    let from_jid = message.getAttribute('from'),
                         to_jid = message.getAttribute('to');
 
                     const original_stanza = message,
@@ -610,12 +627,10 @@
                         const forwarded_from = forwarded_message.getAttribute('from');
                         if (is_carbon && Strophe.getBareJidFromJid(forwarded_from) !== from_jid) {
                             // Prevent message forging via carbons
-                            //
                             // https://xmpp.org/extensions/xep-0280.html#security
                             return true;
                         }
                         message = forwarded_message;
-                        delay = forwarded.querySelector('delay');
                         from_jid = message.getAttribute('from');
                         to_jid = message.getAttribute('to');
                     }
@@ -624,13 +639,12 @@
                         from_resource = Strophe.getResourceFromJid(from_jid),
                         is_me = from_bare_jid === _converse.bare_jid;
 
+                    let contact_jid;
                     if (is_me) {
                         // I am the sender, so this must be a forwarded message...
                         contact_jid = Strophe.getBareJidFromJid(to_jid);
-                        resource = Strophe.getResourceFromJid(to_jid);
                     } else {
                         contact_jid = from_bare_jid;
-                        resource = from_resource;
                     }
                     // Get chat box, but only create a new one when the message has a body.
                     const attrs = {
@@ -645,7 +659,7 @@
                             // Only create the message when we're sure it's not a
                             // duplicate
                             chatbox.incrementUnreadMsgCounter(original_stanza);
-                            chatbox.createMessage(message, delay, original_stanza);
+                            chatbox.createMessage(message, original_stanza);
                         }
                     }
                     _converse.emit('message', {'stanza': original_stanza, 'chatbox': chatbox});
@@ -700,9 +714,6 @@
                                 _converse.root.appendChild(el);
                             }
                         }
-                        if (_.includes(['mobile', 'fullscreen'], _converse.view_mode)) {
-                            el.classList.add('fullscreen');
-                        }
                         el.innerHTML = '';
                         this.setElement(el, false);
                     } else {
@@ -814,12 +825,11 @@
                 _converse.emit('chatBoxesInitialized');
             });
 
-            _converse.api.listen.on('beforeTearDown', () => {
-                _converse.chatboxes.remove(); // Don't call off(), events won't get re-registered upon reconnect.
-                delete _converse.chatboxes.browserStorage;
+            _converse.api.listen.on('clearSession', () => {
+                _converse.chatboxviews.closeAllChatBoxes();
             });
 
-            _converse.api.listen.on('statusInitialized', () => _converse.chatboxes.onConnected());
+            _converse.api.listen.on('presencesInitialized', () => _converse.chatboxes.onConnected());
             /************************ END Event Handlers ************************/
 
 

+ 33 - 26
src/converse-chatview.js

@@ -5,26 +5,25 @@
 // Licensed under the Mozilla Public License (MPLv2)
 
 (function (root, factory) {
-    define([
-            "converse-core",
+    define(["converse-core",
             "bootstrap",
             "emojione",
             "xss",
-            "tpl!action",
-            "tpl!chatbox",
-            "tpl!chatbox_head",
-            "tpl!chatbox_message_form",
-            "tpl!emojis",
-            "tpl!error_message",
-            "tpl!help_message",
-            "tpl!info",
-            "tpl!new_day",
-            "tpl!user_details_modal",
-            "tpl!toolbar_fileupload",
-            "tpl!spinner",
-            "tpl!spoiler_button",
-            "tpl!status_message",
-            "tpl!toolbar",
+            "templates/action.html",
+            "templates/chatbox.html",
+            "templates/chatbox_head.html",
+            "templates/chatbox_message_form.html",
+            "templates/emojis.html",
+            "templates/error_message.html",
+            "templates/help_message.html",
+            "templates/info.html",
+            "templates/new_day.html",
+            "templates/user_details_modal.html",
+            "templates/toolbar_fileupload.html",
+            "templates/spinner.html",
+            "templates/spoiler_button.html",
+            "templates/status_message.html",
+            "templates/toolbar.html",
             "converse-modal",
             "converse-chatboxes",
             "converse-message-view"
@@ -101,10 +100,11 @@
                 { __ } = _converse;
 
             _converse.api.settings.update({
-                'use_emojione': false,
                 'emojione_image_path': emojione.imagePathPNG,
+                'show_send_button': false,
                 'show_toolbar': true,
                 'time_format': 'HH:mm',
+                'use_emojione': false,
                 'visible_toolbar_buttons': {
                     'call': false,
                     'clear': true,
@@ -151,6 +151,7 @@
                     return tpl_emojis(
                         _.extend(
                             this.model.toJSON(), {
+                                '_': _,
                                 'transform': _converse.use_emojione ? emojione.shortnameToImage : emojione.shortnameToUnicode,
                                 'emojis_by_category': u.getEmojisByCategory(_converse, emojione),
                                 'toned_emojis': u.getTonedEmojis(_converse),
@@ -320,16 +321,17 @@
 
                 events: {
                     'change input.fileupload': 'onFileSelection',
+                    'click .chatbox-navback': 'showControlBox',
                     'click .close-chatbox-button': 'close',
-                    'click .show-user-details-modal': 'showUserDetailsModal',
                     'click .new-msgs-indicator': 'viewUnreadMessages',
                     'click .send-button': 'onFormSubmitted',
+                    'click .show-user-details-modal': 'showUserDetailsModal',
+                    'click .spoiler-toggle': 'toggleSpoilerMessage',
                     'click .toggle-call': 'toggleCall',
                     'click .toggle-clear': 'clearMessages',
                     'click .toggle-compose-spoiler': 'toggleComposeSpoilerMessage',
                     'click .toggle-smiley ul.emoji-picker li': 'insertEmoji',
                     'click .toggle-smiley': 'toggleEmojiMenu',
-                    'click .spoiler-toggle': 'toggleSpoilerMessage',
                     'click .upload-file': 'toggleFileUpload',
                     'keypress .chat-textarea': 'keyPressed',
                     'input .chat-textarea': 'inputChanged'
@@ -413,7 +415,15 @@
                     this.renderToolbar();
                 },
 
+                showControlBox () {
+                    // Used in mobile view, to navigate back to the controlbox
+                    const view = _converse.chatboxviews.get('controlbox');
+                    view.show();
+                    this.hide();
+                },
+
                 showUserDetailsModal (ev) {
+                    ev.preventDefault();
                     if (_.isUndefined(this.user_details_modal)) {
                         this.user_details_modal = new _converse.UserDetailsModal({model: this.model});
                     }
@@ -901,7 +911,7 @@
                 keyPressed (ev) {
                     /* Event handler for when a key is pressed in a chat box textarea.
                      */
-                    if (ev.keyCode === KEY.ENTER) {
+                    if (ev.keyCode === KEY.ENTER && !ev.shiftKey) {
                         this.onFormSubmitted(ev);
                     } else if (ev.keyCode !== KEY.FORWARD_SLASH && this.model.get('chat_state') !== _converse.COMPOSING) {
                         // Set chat state to composing if keyCode is not a forward-slash
@@ -1075,10 +1085,7 @@
                 },
 
                 afterShown () {
-                    if (u.isPersistableModel(this.model)) {
-                        this.model.clearUnreadMsgCounter();
-                        this.model.save();
-                    }
+                    this.model.clearUnreadMsgCounter();
                     this.setChatState(_converse.ACTIVE);
                     this.renderEmojiPicker();
                     this.scrollDown();
@@ -1155,7 +1162,7 @@
                 },
 
                 onWindowStateChanged (state) {
-                    if (this.model.get('num_unread', 0) && !this.model.newMessageWillBeHidden()) {
+                    if (this.model.get('num_unread', 0) && !this.model.isHidden()) {
                         this.model.clearUnreadMsgCounter();
                     }
                 }

+ 6 - 6
src/converse-controlbox.js

@@ -10,10 +10,10 @@
     define(["converse-core",
             "bootstrap",
             "lodash.fp",
-            "tpl!converse_brand_heading",
-            "tpl!controlbox",
-            "tpl!controlbox_toggle",
-            "tpl!login_panel",
+            "templates/converse_brand_heading.html",
+            "templates/controlbox.html",
+            "templates/controlbox_toggle.html",
+            "templates/login_panel.html",
             "converse-chatview",
             "converse-rosterview",
             "converse-profile"
@@ -91,8 +91,8 @@
             //
             // New functions which don't exist yet can also be added.
 
-            _tearDown () {
-                this.__super__._tearDown.apply(this, arguments);
+            tearDown () {
+                this.__super__.tearDown.apply(this, arguments);
                 if (this.rosterview) {
                     // Removes roster groups
                     this.rosterview.model.off().reset();

Datei-Diff unterdrückt, da er zu groß ist
+ 6 - 8
src/converse-core.js


+ 53 - 13
src/converse-disco.js

@@ -36,24 +36,24 @@
                     this.waitUntilFeaturesDiscovered = utils.getResolveablePromise();
 
                     this.dataforms = new Backbone.Collection();
-                    this.dataforms.browserStorage = new Backbone.BrowserStorage[_converse.storage](
+                    this.dataforms.browserStorage = new Backbone.BrowserStorage.session(
                         b64_sha1(`converse.dataforms-{this.get('jid')}`)
                     );
 
                     this.features = new Backbone.Collection();
-                    this.features.browserStorage = new Backbone.BrowserStorage[_converse.storage](
+                    this.features.browserStorage = new Backbone.BrowserStorage.session(
                         b64_sha1(`converse.features-${this.get('jid')}`)
                     );
                     this.features.on('add', this.onFeatureAdded, this);
 
                     this.identities = new Backbone.Collection();
-                    this.identities.browserStorage = new Backbone.BrowserStorage[_converse.storage](
+                    this.identities.browserStorage = new Backbone.BrowserStorage.session(
                         b64_sha1(`converse.identities-${this.get('jid')}`)
                     );
                     this.fetchFeatures();
 
                     this.items = new _converse.DiscoEntities();
-                    this.items.browserStorage = new Backbone.BrowserStorage[_converse.storage](
+                    this.items.browserStorage = new Backbone.BrowserStorage.session(
                         b64_sha1(`converse.disco-items-${this.get('jid')}`)
                     );
                     this.items.fetch();
@@ -125,7 +125,12 @@
                 },
 
                 queryInfo () {
-                    _converse.api.disco.info(this.get('jid'), null, this.onInfo.bind(this));
+                    _converse.api.disco.info(this.get('jid'), null)
+                        .then((stanza) => this.onInfo(stanza))
+                        .catch((iq) => {
+                            this.waitUntilFeaturesDiscovered.resolve();
+                            _converse.log(iq, Strophe.LogLevel.ERROR);
+                        });
                 },
 
                 onDiscoItems (stanza) {
@@ -137,7 +142,12 @@
                         }
                         const jid = item.getAttribute('jid');
                         if (_.isUndefined(this.items.get(jid))) {
-                            this.items.create({'jid': jid});
+                            const entity = _converse.disco_entities.get(jid);
+                            if (entity) {
+                                this.items.add(entity);
+                            } else {
+                                this.items.create({'jid': jid});
+                            }
                         }
                     });
                 },
@@ -216,12 +226,34 @@
                 return this;
             }
 
+            function initStreamFeatures () {
+                _converse.stream_features = new Backbone.Collection();
+                _converse.stream_features.browserStorage = new Backbone.BrowserStorage.session(
+                    b64_sha1(`converse.stream-features-${_converse.bare_jid}`)
+                );
+                _converse.stream_features.fetch({
+                    success (collection) {
+                        if (collection.length === 0 && _converse.connection.features) {
+                            _.forEach(
+                                _converse.connection.features.childNodes,
+                                (feature) => {
+                                    _converse.stream_features.create({
+                                        'name': feature.nodeName,
+                                        'xmlns': feature.getAttribute('xmlns')
+                                    });
+                                });
+                        }
+                    }
+                });
+                _converse.emit('streamFeaturesAdded');
+            }
+
             function initializeDisco () {
                 addClientFeatures();
                 _converse.connection.addHandler(onDiscoInfoRequest, Strophe.NS.DISCO_INFO, 'iq', 'get', null, null);
 
                 _converse.disco_entities = new _converse.DiscoEntities();
-                _converse.disco_entities.browserStorage = new Backbone.BrowserStorage[_converse.storage](
+                _converse.disco_entities.browserStorage = new Backbone.BrowserStorage.session(
                     b64_sha1(`converse.disco-entities-${_converse.bare_jid}`)
                 );
 
@@ -235,6 +267,7 @@
                 }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
             }
 
+            _converse.api.listen.on('sessionInitialized', initStreamFeatures);
             _converse.api.listen.on('reconnected', initializeDisco);
             _converse.api.listen.on('connected', initializeDisco);
 
@@ -290,6 +323,15 @@
                  * @namespace
                  */
                 'disco': {
+                    'stream': {
+                        'getFeature': function (name, xmlns) {
+                            if (_.isNil(name) || _.isNil(xmlns)) {
+                                throw new Error("name and xmlns need to be provided when calling disco.stream.getFeature");
+                            }
+                            return _converse.stream_features.findWhere({'name': name, 'xmlns': xmlns});
+                        }
+                    },
+
                     /**
                      * The "own" grouping
                      * @namespace
@@ -389,7 +431,7 @@
                         }
                     },
 
-                    'info' (jid, node, callback, errback, timeout) {
+                    'info' (jid, node) {
                         const attrs = {xmlns: Strophe.NS.DISCO_INFO};
                         if (node) {
                             attrs.node = node;
@@ -399,7 +441,7 @@
                             'to':jid,
                             'type':'get'
                         }).c('query', attrs);
-                        _converse.connection.sendIQ(info, callback, errback, timeout);
+                        return _converse.api.sendIQ(info);
                     },
 
                     'items' (jid, node, callback, errback, timeout) {
@@ -481,10 +523,8 @@
                          *    (String) entity_jid - The JID of the entity which might have the identity
                          */
                         return new Promise((resolve, reject) => {
-                            _converse.api.waitUntil('discoInitialized').then(() => {
-                                _converse.api.disco.entities.get(entity_jid, true)
-                                    .then((entity) => resolve(entity.getIdentity(category, type)));
-                            })
+                            _converse.api.disco.entities.get(entity_jid, true)
+                                .then((entity) => resolve(entity.getIdentity(category, type)));
                         }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
                     }
                 }

+ 1 - 1
src/converse-dragresize.js

@@ -8,7 +8,7 @@
 
 (function (root, factory) {
     define(["converse-core",
-            "tpl!dragresize",
+            "templates/dragresize.html",
             "converse-chatview",
             "converse-controlbox"
     ], factory);

+ 1 - 1
src/converse-fullscreen.js

@@ -8,7 +8,7 @@
 
 (function (root, factory) {
     define(["converse-core",
-            "tpl!inverse_brand_heading",
+            "templates/inverse_brand_heading.html",
             "converse-chatview",
             "converse-controlbox",
             "converse-muc",

+ 2 - 2
src/converse-headline.js

@@ -9,7 +9,7 @@
 (function (root, factory) {
     define([
             "converse-core",
-            "tpl!chatbox",
+            "templates/chatbox.html",
             "converse-chatview",
     ], factory);
 }(this, function (converse, tpl_chatbox) {
@@ -138,7 +138,7 @@
                         'type': 'headline',
                         'from': from_jid
                     });
-                    chatbox.createMessage(message, undefined, message);
+                    chatbox.createMessage(message, message);
                     _converse.emit('message', {'chatbox': chatbox, 'stanza': message});
                 }
                 return true;

+ 4 - 4
src/converse-mam.js

@@ -11,14 +11,14 @@
 (function (root, factory) {
     define(["sizzle",
             "converse-core",
-            "utils",
             "converse-disco",
             "strophe.rsm"
     ], factory);
-}(this, function (sizzle, converse, utils) {
+}(this, function (sizzle, converse) {
     "use strict";
     const CHATROOMS_TYPE = 'chatroom';
     const { Promise, Strophe, $iq, _, moment } = converse.env;
+    const u = converse.env.utils;
 
     const RSM_ATTRIBUTES = ['max', 'first', 'last', 'after', 'before', 'index', 'count'];
     // XEP-0313 Message Archive Management
@@ -128,7 +128,7 @@
             //
             // New functions which don't exist yet can also be added.
             ChatBox: {
-                getMessageAttributesFromStanza (message, delay, original_stanza) {
+                getMessageAttributesFromStanza (message, original_stanza) {
                     const attrs = this.__super__.getMessageAttributesFromStanza.apply(this, arguments);
                     const archive_id = getMessageArchiveID(original_stanza);
                     if (archive_id) {
@@ -153,7 +153,7 @@
                      */
                     if (this.disable_mam) { return; }
                     const { _converse } = this.__super__,
-                          most_recent_msg = utils.getMostRecentMessage(this.model);
+                          most_recent_msg = u.getMostRecentMessage(this.model);
 
                     if (_.isNil(most_recent_msg)) {
                         this.fetchArchivedMessages();

+ 9 - 8
src/converse-message-view.js

@@ -1,7 +1,7 @@
 // Converse.js
 // https://conversejs.org
 //
-// Copyright (c) 2012-2018, the Converse.js developers
+// Copyright (c) 2013-2018, the Converse.js developers
 // Licensed under the Mozilla Public License (MPLv2)
 
 (function (root, factory) {
@@ -10,12 +10,12 @@
         "xss",
         "emojione",
         "filesize",
-        "tpl!action",
-        "tpl!csn",
-        "tpl!file_progress",
-        "tpl!info",
-        "tpl!message",
-        "tpl!spoiler_message"
+        "templates/action.html",
+        "templates/csn.html",
+        "templates/file_progress.html",
+        "templates/info.html",
+        "templates/message.html",
+        "templates/spoiler_message.html"
     ], factory);
 }(this, function (
         converse,
@@ -145,6 +145,7 @@
                         msg_content.innerHTML = _.flow(
                             _.partial(u.geoUriToHttp, _, _converse.geouri_replacement),
                             u.addHyperlinks,
+                            u.renderNewLines,
                             _.partial(u.addEmoji, _converse, emojione, _)
                         )(text);
                     }
@@ -225,7 +226,7 @@
                 },
 
                 getExtraMessageClasses () {
-                    let extra_classes = this.model.get('delayed') && 'delayed' || '';
+                    let extra_classes = this.model.get('is_delayed') && 'delayed' || '';
                     if (this.model.get('type') === 'groupchat' && this.model.get('sender') === 'them') {
                         if (this.model.collection.chatbox.isUserMentioned(this.model.get('message'))) {
                             // Add special class to mark groupchat messages

+ 13 - 14
src/converse-minimize.js

@@ -8,10 +8,10 @@
 
 (function (root, factory) {
     define(["converse-core",
-            "tpl!chatbox_minimize",
-            "tpl!toggle_chats",
-            "tpl!trimmed_chat",
-            "tpl!chats_panel",
+            "templates/chatbox_minimize.html",
+            "templates/toggle_chats.html",
+            "templates/trimmed_chat.html",
+            "templates/chats_panel.html",
             "converse-chatview"
     ], factory);
 }(this, function (
@@ -52,16 +52,6 @@
             //
             // New functions which don't exist yet can also be added.
 
-            registerGlobalEventHandlers () {
-                const { _converse } = this.__super__;
-                window.addEventListener("resize", _.debounce(function (ev) {
-                    if (_converse.connection.connected) {
-                        _converse.chatboxviews.trimChats();
-                    }
-                }, 200));
-                return this.__super__.registerGlobalEventHandlers.apply(this, arguments);
-            },
-
             ChatBox: {
                 initialize () {
                     this.__super__.initialize.apply(this, arguments);
@@ -541,6 +531,15 @@
                 _converse.emit('minimizedChatsInitialized');
             }).catch(_.partial(_converse.log, _, Strophe.LogLevel.FATAL));
 
+
+            _converse.on('registeredGlobalEventHandlers', function () {
+                window.addEventListener("resize", _.debounce(function (ev) {
+                    if (_converse.connection.connected) {
+                        _converse.chatboxviews.trimChats();
+                    }
+                }, 200));
+            });
+
             _converse.on('controlBoxOpened', function (chatbox) {
                 // Wrapped in anon method because at scan time, chatboxviews
                 // attr not set yet.

Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.