diff --git a/CHANGES.txt b/CHANGES.txt
new file mode 100644
index 0000000..2e27163
--- /dev/null
+++ b/CHANGES.txt
@@ -0,0 +1,10 @@
+--------------------
+PRDC_MQTTWebClient
+MQTT Web Client by PR-DC
+--------------------
+
+Release 1.0.0, 12.12.2021.
+
+- Initial release
+
+--------------------
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..153d416
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc.
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..6a7afad
--- /dev/null
+++ b/README.md
@@ -0,0 +1,39 @@
+## PR-DC MQTT Web Client
+
+Fully featured MQTT Web Client.
+
+For example of MQTT Broker and Client implemented in Node.js checkout https://github.com/PR-DC/PRDC_MQTT_NodeJS
+
+## Installation
+
+Download the entire repository by clicking on `Code/Download ZIP` or using the` git` command:
+
+```bash
+git clone https://github.com/PR-DC/PRDC_MQTTWebClient folder # change folder
+```
+
+Then open `index.hmtl` in the browser.
+
+## User interface
+
+After opening `index.hmtl` in the browser you should get the user intefrace as in the following image.
+
+
+
+
+
+## License
+Copyright (C) 2021 PR-DC
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as
+published by the Free Software Foundation, either version 3 of the
+License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with this program. If not, see .
diff --git a/css/style.css b/css/style.css
new file mode 100644
index 0000000..58da852
--- /dev/null
+++ b/css/style.css
@@ -0,0 +1,1098 @@
+html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,embed,figure,figcaption,footer,header,hgroup,menu,nav,output,ruby,section,summary,time,mark,audio,video{border:0;font-size:100%;font:inherit;vertical-align:baseline;margin:0;padding:0}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}body{line-height:1}ol,ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:none}table{border-collapse:collapse;border-spacing:0}
+
+html {
+ overflow: hidden;
+}
+
+:focus {
+ outline: 0;
+}
+
+div {
+ z-index: 2;
+ box-sizing: border-box;
+}
+
+section {
+ position: relative;
+ z-index: 2;
+}
+
+body {
+ font-family: 'Roboto',Arial;
+ width: 100%;
+ background: #fff;
+ min-width: 540px;
+}
+
+sup {
+ vertical-align: super;
+ font-size: smaller;
+}
+
+sub {
+ vertical-align: sub;
+ font-size: smaller;
+}
+
+input, textarea, select, button {
+ font-family: 'Roboto' !important;
+}
+
+.disabled {
+ pointer-events: none;
+}
+
+.clear {
+ clear: both;
+}
+
+.hidden {
+ display:none;
+}
+
+#panels-container {
+ position: absolute;
+ bottom: 25px;
+ left: 0px;
+ right: 0px;
+ top: 71px;
+}
+
+.browser-app #panels-container {
+ top: 68px;
+}
+
+#tabs, .tab {
+ width: 100%;
+ height: 100%;
+}
+
+.container {
+ padding: 0 15px;
+}
+
+.tab {
+ overflow: auto;
+ padding: 0 15px;
+}
+
+header {
+ background: #fff;
+ border-bottom: 5px solid #ccc;
+ border-top: 3px solid #eee;
+ height: 58px;
+ background-image: linear-gradient(to right, #fff, #eee);
+ user-select: none;
+ -webkit-user-drag: none;
+ user-drag: none;
+}
+
+.browser-app header {
+ border-top: 0px;
+}
+
+header img {
+ -webkit-user-drag: none;
+}
+
+header #logo {
+ height: 45px;
+ padding-top: 10px;
+ padding-bottom: 5px;
+ padding-left: 5px;
+ padding-right: 5px;
+ margin: 0;
+ margin-top: -5px;
+ float: left;
+}
+
+#app-title {
+ float: right;
+ padding: 14px 10px;
+ font-weight: bold;
+ font-size: 30px;
+ color: #999;
+}
+
+#title {
+ background: #2e85c7;
+ color: #fff;
+ text-align: center;
+ font-size: 20px;
+ padding: 12px;
+}
+
+#nav-bar {
+ background: #2e85c7;
+ height: 5px;
+ width: 100%;
+}
+
+#tab-navigation {
+ float: left;
+ padding-left: 15px;
+ color: #2e85c7;
+ text-align: center;
+ font-size: 20px;
+}
+
+#tab-navigation li {
+ float: left;
+ padding: 20px 10px;
+ padding-bottom: 17px;
+ padding-top: 21px;
+ -webkit-transition: all .2s linear;
+ transition: all .2s linear;
+ border-bottom: 5px solid #ccc;
+ background: none;
+ cursor: pointer;
+}
+
+#tab-navigation li img {
+ width: 30px;
+ display: block;
+ float: left;
+ margin-right: 8px;
+ margin-top: -5px;
+ margin-bottom: -5px;
+ -webkit-transition: all .2s linear;
+ transition: all .2s linear;
+}
+
+#tab-navigation li.active img, #tab-navigation li:hover img {
+ filter: brightness(0) invert(1);
+}
+
+#tab-navigation li.active {
+ background: #2e85c7;
+ color: #fff;
+ border-bottom: 5px solid #2e85c7;
+}
+
+#tab-navigation li:hover {
+ background: #12568a;
+ border-bottom: 5px solid #12568a;
+ color: #fff;
+}
+
+#tab-navigation li.active:hover {
+ background: #2e85c7;
+ border-bottom: 5px solid #2e85c7;
+}
+
+#terminal-options {
+ float: right;
+ margin-right: 10px;
+ margin-top: -1px;
+}
+
+#terminal-options i {
+ width: 18px;
+ height: 18px;
+ display: block;
+ background-size: 18px!important;
+ float: left;
+ clear: none;
+ padding: 4px 5px;
+ opacity: 0.3;
+ cursor: pointer;
+}
+
+#terminal-options i.settings {
+ background: url(../img/settings.svg) no-repeat center;
+}
+
+#terminal-options i.timestamp {
+ background: url(../img/timestamp.svg) no-repeat center;
+}
+
+#terminal-options i.autoscroll {
+ background: url(../img/autoscroll.svg) no-repeat center;
+}
+
+#terminal-options i:hover {
+ opacity: 1;
+}
+
+#terminal-options i.active {
+ opacity: 0.8;
+}
+
+#terminal-title {
+ margin-top: 4px;
+ padding: 5px 10px 5px;
+ position: relative;
+ font-size: 12px;
+ margin-right: 2px;
+ border-bottom: none;
+ color: #12568a;
+ font-weight: bold;
+ display: block;
+ float: left;
+ background: #eee;
+ padding-bottom: 5px;
+ border-radius: 3px 3px 0 0;
+ margin-left: 6px;
+}
+
+#terminal-options-cont {
+ position: absolute!important;
+ left: 8px;
+ right: 8px;
+ top: 3px;
+ bottom: 8px;
+}
+
+#bottom-panel, #top-panel {
+ position: relative;
+}
+
+#settings {
+ position: absolute;
+ left: 0px;
+ right: 0px;
+ top: 0px;
+ bottom: 0px;
+ overflow: auto;
+}
+
+.settings-cont input[type="text"], .settings-cont input[type="number"], .settings-cont input[type="submit"], .settings-cont input[type="password"], .settings-cont textarea, .settings-cont select, .settings-cont button,
+.options-cont input[type="text"], .options-cont input[type="number"], .options-cont input[type="submit"], .options-cont input[type="password"], .options-cont textarea, .options-cont select, .options-cont button {
+ border: 2px solid #ccc;
+ color: #333;
+ font-size: 18px;
+ padding-left: 10px;
+ padding-right: 10px;
+ padding-top: 8px;
+ padding-bottom: 8px;
+ width: calc(100% - 24px);
+ margin-bottom: 10px;
+ transition: all 0.2s linear;
+ -webkit-transition: all 0.2s linear;
+ font-weight: bold;
+ border-radius: 3px;
+ -webkit-appearance: none;
+ background: #fff;
+ -webkit-box-sizing:content-box;
+ box-sizing:content-box;
+ cursor: pointer;
+ line-height: 22px;
+}
+
+.options-cont input[type="text"], .options-cont input[type="number"], .options-cont input[type="submit"], .options-cont input[type="password"], .options-cont textarea, .options-cont select, .options-cont button{
+ margin-bottom: 12px;
+}
+
+.settings-cont textarea, .options-cont textarea {
+ resize: vertical;
+}
+
+.settings-cont input[type="submit"], .options-cont input[type="submit"] {
+ color: #fff;
+ background: #2e85c7;
+ background-size: 30px 30px;
+ margin-left: 2px;
+ margin-bottom: 10px;
+ cursor: pointer;
+ text-transform: uppercase;
+ border: 2px solid #2e85c7;
+}
+
+.settings-cont input[type="text"]:focus, .settings-cont input[type="number"]:focus, .settings-cont textarea:focus, .settings-cont select:focus, .options-cont input[type="text"]:focus, .options-cont input[type="number"]:focus, .options-cont textarea:focus, .options-cont select:focus {
+ border: 2px solid #2e85c7;
+}
+
+.settings-cont input[type="text"]:read-only:focus, .settings-cont input[type="number"]:read-only:focus,
+.options-cont input[type="text"]:read-only:focus, .options-cont input[type="number"]:read-only:focus{
+ border: 2px solid #ccc;
+}
+
+.settings-cont input[type="text"]:read-only:hover, .settings-cont input[type="number"]:read-only:hover,
+.options-cont input[type="text"]:read-only:hover, .options-cont input[type="number"]:read-only:hover{
+ cursor: auto;
+}
+
+.settings-cont input[type="submit"]:hover, .options-cont input[type="submit"]:hover {
+ color: #2e85c7;
+ background: #fff;
+}
+
+.settings-cont input[type="submit"]:disabled,.options-cont input[type="submit"]:disabled {
+ background-image: linear-gradient(135deg, rgba(255, 255, 255, .15) 25%, transparent 25%,
+ transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%,
+ transparent 75%, transparent);
+ background-size: 30px 30px;
+ animation: animate-stripes 1s linear infinite;
+ -webkit-animation: animate-stripes 1s linear infinite;
+}
+
+.settings-cont input:disabled, .settings-cont textarea:disabled, .settings-cont select:disabled,
+.options-cont input:disabled, .options-cont textarea:disabled, .options-cont select:disabled{
+ opacity: 0.5;
+ pointer-events: none;
+}
+
+.settings-cont ::placeholder, .settings-cont ::-webkit-input-placeholder,
+.options-cont ::placeholder, .options-cont ::-webkit-input-placeholder{
+ color: #ccc;
+ font-weight: normal;
+ text-transform: none;
+}
+
+.settings-cont label, .options-cont label {
+ color: #12568a;
+ margin-bottom: 2px;
+ display: block;
+ margin-left: 3px;
+}
+
+.settings-cont label span, .options-cont label span {
+ color: #555;
+}
+
+.settings-cont label.checkcont, .options-cont label.checkcont {
+ margin: 15px 0;
+ font-size: 18px;
+ padding-top: 3px;
+ padding-bottom: 3px;
+}
+
+.options-cont label.checkcont {
+ padding-top: 6px;
+ color: #333;
+}
+
+.checkcont {
+ display: block;
+ position: relative;
+ padding-left: 35px;
+ margin-bottom: 12px;
+ cursor: pointer;
+ font-size: 22px;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
+ -webkit-user-drag: none;
+ user-drag: none;
+}
+
+.checkcont input {
+ position: absolute;
+ opacity: 0;
+ cursor: pointer;
+ height: 0;
+ width: 0;
+}
+
+.checkmark {
+ position: absolute;
+ top: 0;
+ left: 0;
+ height: 25px;
+ width: 25px;
+ background-color: #fff;
+ border: 2px solid #ccc;
+ border-radius: 3px;
+}
+
+.checkcont:hover input ~ .checkmark {
+ background-color: #ccc;
+}
+
+.checkcont input:checked ~ .checkmark {
+ background-color: #2e85c7;
+}
+
+.checkmark:after {
+ content: "";
+ position: absolute;
+ display: none;
+}
+
+.checkcont input:checked ~ .checkmark:after {
+ display: block;
+}
+
+.checkcont .checkmark:after {
+ left: 9px;
+ top: 5px;
+ width: 5px;
+ height: 10px;
+ border: solid white;
+ border-width: 0 3px 3px 0;
+ -webkit-transform: rotate(45deg);
+ -ms-transform: rotate(45deg);
+ transform: rotate(45deg);
+}
+
+.float-input, .float-select, .no-float-input {
+ position: relative;
+ margin-top: 5px;
+}
+
+label.float-label {
+ pointer-events: none;
+ position: absolute;
+ top: -13px;
+ margin-left: 12px!important;
+ padding: 1px 8px;
+ border-radius: 3px;
+ color: #777!important;
+ font-weight: bold;
+ background: #eee;
+}
+
+.float-select label.float-label {
+ color: #777;
+ font-weight: bold;
+ background: #eee;
+}
+
+label.float-label, .float-input input, .float-input textarea {
+ transition: all 0.2s;
+ touch-action: manipulation;
+}
+.float-input input:placeholder-shown + label.float-label, .float-input textarea:placeholder-shown + label.float-label {
+ cursor: text;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ transform-origin: left bottom;
+ transform: translate(0, 1.7rem) scale(1.2);
+ background: none;
+}
+
+.float-input input::-webkit-input-placeholder, .float-input input::placeholder, .float-input textarea::-webkit-input-placeholder, .float-input textarea::placeholder {
+ opacity: 0;
+ transition: inherit;
+}
+
+.float-input input:focus::-webkit-input-placeholder, .float-input textarea:focus::-webkit-input-placeholder {
+ opacity: 1;
+}
+
+.float-input input:not(:placeholder-shown) + label.float-label,
+.float-input input:focus + label.float-label,
+.float-input textarea:not(:placeholder-shown) + label.float-label,
+.float-input textarea:focus + label.float-label,
+.float-input input:-webkit-autofill + label.float-label
+.float-input textarea:-webkit-autofill + label.float-label {
+ transform: translate(0, 0) scale(1);
+ cursor: pointer;
+ background: #eee;
+}
+
+.float-input input:not(:placeholder-shown) + label.float-label,
+.float-input input:focus + label.float-label,
+.float-input textarea:not(:placeholder-shown) + label.float-label,
+.float-input textarea:focus + label.float-label,
+.float-input input:-webkit-autofill + label.float-label,
+.float-input textarea:-webkit-autofill + label.float-label{
+ color: #777!important;
+ font-weight: bold;
+ background: #eee;
+}
+
+.settings-cont {
+ margin: 0 auto;
+ width: 480px;
+ position: relative;
+ background: #eee;
+ border-radius: 0 0 10px 10px;
+ padding: 20px;
+ padding-bottom: 20px;
+ color: #777;
+ margin-bottom: 20px;
+}
+
+.settings-cont button:not([disabled]):hover, .options-cont button:not([disabled]):hover {
+ color: #2e85c7;
+ background: #fff;
+}
+
+.settings-cont button, .options-cont button {
+ color: #fff;
+ background: #2e85c7;
+ background-size: 30px 30px;
+ border: 0;
+ cursor: pointer;
+ text-transform: uppercase;
+ border: 2px solid #2e85c7;
+ margin-bottom: 0px;
+}
+
+.settings-cont button:disabled, .options-cont button:disabled {
+ background-image: linear-gradient(135deg, rgba(255, 255, 255, .15) 25%, transparent 25%,
+ transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%,
+ transparent 75%, transparent);
+ background-size: 30px 30px;
+}
+
+.settings-cont #toggle-connect.connected:hover {
+ color: #26a65b;
+ background: #fff;
+}
+
+.settings-cont #toggle-connect.connected {
+ background: #26a65b;
+ border: 2px solid #26a65b;
+}
+
+.settings-div {
+ border-top: 2px solid #ccc;
+ padding-bottom: 25px;
+ margin-top: 10px;
+ user-select: none;
+ -webkit-user-drag: none;
+ user-drag: none;
+}
+
+.settings-div span {
+ padding: 4px;
+ margin-left: 20px;
+ color: #aaa;
+ background: #eee;
+ margin-top: -17px;
+ display: block;
+ float: left;
+ font-weight: bold;
+ font-size: 20px;
+}
+
+#top-overlay-mask, #bottom-overlay-mask {
+ opacity: 0;
+ visibility: hidden;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ position: absolute;
+ -webkit-backdrop-filter: blur(5px);
+ backdrop-filter: blur(5px);
+ background-color: rgba(255, 255, 255, 0.7);
+ transition: opacity linear 0.3s;
+}
+
+#bottom-overlay-mask {
+ left: 8px;
+ right: 8px;
+ top: 3px;
+ bottom: 8px;
+}
+
+.overlay-cont {
+ opacity: 0;
+ visibility: hidden;
+ transition: opacity linear 0.3s;
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ height: 0;
+ overflow: hidden;
+}
+
+.options-cont {
+ margin: 0 auto;
+ width: 460px;
+ position: relative;
+ background: #ffffff6b;
+ box-shadow: 0 0 10px #00000026;
+ border-radius: 10px;
+ padding: 20px;
+ padding-bottom: 20px;
+ color: #777;
+ margin-bottom: 20px;
+ margin-top: 20px;
+}
+
+.options-header {
+ position: relative;
+ border-bottom: 1px solid #666;
+ margin-bottom: 25px;
+ padding-bottom: 10px;
+ user-select: none;
+ -webkit-user-drag: none;
+ user-drag: none;
+}
+
+.options-header span {
+ color: #666;
+ display: block;
+ font-weight: bold;
+ font-size: 24px;
+ border-radius: 3px;
+}
+
+.options-close {
+ opacity: 0.7;
+ position: absolute;
+ display: block;
+ top: 0px;
+ right: 0px;
+ cursor: pointer;
+}
+
+.options-close:hover {
+ opacity: 0.3;
+}
+
+#host-cont {
+ width: calc(100% - 81px);
+ float: left;
+ margin-right: 15px;
+}
+
+#port-cont {
+ width: 66px;
+ float: left;
+}
+
+#port-cont input {
+ padding-left: 10px;
+ padding-right: 10px;
+}
+
+#client-id-cont {
+ float: left;
+ width: calc(100% - 61px);
+}
+
+#username-cont, #password-cont {
+ float: left;
+ width: calc(50% - 7.5px);
+ margin-right: 15px;
+ display: block;
+}
+
+#password-cont {
+ margin-right: 0px;
+}
+
+#timeout-cont {
+ width: 204px;
+ float: left;
+ margin-right: 15px;
+ margin-top: 0px;
+}
+
+#timeout-cont input, #keep-alive-cont input {
+ padding-left: 10px;
+ padding-right: 10px;
+ width: 177px;
+ margin-bottom: 0px;
+}
+
+#lw-topic-cont, #topic-cont, #sub-topic-cont {
+ margin-top: 10px;
+ float: left;
+ margin-right: 15px;
+ width: calc(100% - 83px);
+}
+
+#lw-retain-cont, #retain-cont {
+ margin: 5px 0;
+}
+
+#retain-cont {
+ margin-bottom: 10px;
+}
+
+#lw-qos-cont, #qos-cont, #sub-qos-cont {
+ float: left;
+ margin-top: 10px;
+ width: 68px;
+}
+
+#lw-qos, #qos, #sub-qos {
+ text-align-last: center;
+}
+
+#no-sub-topics {
+ font-size: 20px;
+ text-align: center;
+ color: #333;
+}
+
+#subscribe-cont ul {
+ margin-top: -10px;
+ margin-bottom: 20px;
+ padding: 0 10px;
+}
+
+#subscribe-cont li {
+ padding: 10px;
+ font-size: 18px;
+ color: #333;
+ border-bottom: 1px solid #ccc;
+ position: relative;
+ padding-left: 0px;
+ cursor: pointer;
+ padding-right: 80px;
+ transition: all 0.2s linear;
+}
+
+#subscribe-cont li:hover {
+ padding-left: 20px;
+ padding-right: 50px;
+ border-bottom: 1px solid #2e85c7;
+}
+
+#subscribe-cont li span {
+ position: absolute;
+ top: 10px;
+ right: 0px;
+ padding: 3px 5px;
+ border-radius: 3px;
+ color: #999;
+ border: 1px solid #ccc;
+ transition: all 0.2s linear;
+ font-size: 12px;
+}
+
+#subscribe-cont li img {
+ transition: all 0.2s linear;
+ visibility: hidden;
+ position: absolute;
+ left: 0;
+ top: 10px;
+ opacity: 0;
+ width: 15px;
+}
+
+#subscribe-cont li:hover img {
+ visibility: visible;
+ opacity: 0.5;
+}
+
+#subscribe-cont li:hover img:hover {
+ opacity: 0.3;
+}
+
+#advanced-settings-open {
+float: left;
+ display: block;
+ margin-left: 15px;
+ height: 18px;
+ background: #ccc;
+ padding: 10px 18px;
+ border-radius: 3px;
+ margin-top: 5px;
+ transition: all 0.2s linear;
+ -webkit-transition: all 0.2s linear;
+ cursor: pointer;
+ border: 2px solid #ccc;
+ background: #fff;
+ width: 6px;
+}
+
+#advanced-settings-open.disabled {
+ background: #f6f6f6;
+ border: 2px solid #ddd;
+}
+
+#advanced-settings-open:not(.disabled):hover {
+ border-color: #2e85c7;
+}
+
+#toggle-connect {
+ margin-bottom: 15px;
+ margin-top: 5px;
+}
+
+#publish-btn, #subscribe-btn {
+ width: calc(50% - 31.5px);
+ float: left;
+ margin-right: 15px;
+}
+
+#subscribe-btn {
+ margin-right: 0px;
+}
+
+.panel::-webkit-scrollbar,
+.panel::-webkit-scrollbar-button,
+.panel::-webkit-scrollbar-track,
+.panel::-webkit-scrollbar-track-piece,
+.panel::-webkit-scrollbar-thumb,
+.panel::-webkit-scrollbar-corner,
+.panel::-webkit-resizer {
+ background: transparent;
+}
+.panel::-webkit-scrollbar {
+ width: 12px;
+ height: 12px;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+}
+.panel::-webkit-scrollbar-track-piece {
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+}
+.panel::-webkit-scrollbar-thumb {
+ background: #ddd;
+ border-radius: 5px;
+ background-clip: content-box;
+ border: 2px solid transparent;
+}
+.panel::-webkit-scrollbar-button {
+ width:0;
+ height:0;
+}
+
+#status-container {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ background: #f1f3f4;
+ padding: 5px 20px;
+ font-size: 14px;
+ line-height: 14px;
+ color: #5f6368;
+ border-top: 1px solid #fff;
+}
+
+#status {
+ height: 14px;
+ overflow: hidden;
+ float: left;
+}
+
+#status-icons img {
+ height: 14px;
+ width: 14px;
+ display: block;
+ float: right;
+ -webkit-user-select: none;
+ user-select: none;
+ -webkit-user-drag: none;
+ user-drag: none;
+ cursor: pointer;
+}
+
+#status-icons img:hover {
+ opacity: 0.5;
+}
+
+#messages-container {
+ position: absolute;
+ bottom: 30px;
+ top: 71px;
+ right: 0px;
+ transform: translateX(0px);
+ width: 400px;
+ z-index: 999;
+ transition: transform ease-in-out 0.1s;
+ -webkit-pointer-events: none;
+ pointer-events: none;
+ -webkit-user-select: none;
+ user-select: none;
+ -webkit-user-drag: none;
+ user-drag: none;
+ overflow: hidden;
+}
+
+#messages-container.inactive {
+ transform: translateX(420px);
+}
+
+#messages-container .message {
+ position: absolute;
+ bottom: 0px;
+ -webkit-backdrop-filter: blur(5px);
+ backdrop-filter: blur(5px);
+ background-color: rgba(255, 255, 255, 0.7);
+ transition: transform ease-in-out 0.1s, border linear 0.2s;
+ box-shadow: 0 0 10px #00000026;
+ border-radius: 5px;
+ -webkit-pointer-events: all;
+ pointer-events: all;
+ -webkit-user-select: auto;
+ user-select: text;
+ -webkit-user-drag: none;
+ user-drag: none;
+ margin: 10px;
+ margin-right: 15px;
+ display: block;
+ padding: 20px;
+ color: #666;
+ width: auto;
+ right: 0px;
+ left: 0px;
+ transform: translateX(0px);
+ cursor: pointer;
+ border: 2px solid #fff;
+ line-height: 18px;
+}
+
+#messages-container .message:hover {
+ border: 2px solid #2e85c7;
+}
+
+#messages-container .message.inactive {
+ transform: translateX(420px);
+}
+
+#panels-container .horizontal-separator {
+ height: 25px;
+ width: 100%;
+ background-image: url(../img/hdrag.svg);
+ background-repeat: no-repeat;
+ background-position: center center;
+ background-size: auto 6px;
+ cursor: n-resize;
+ user-select: none;
+ -webkit-user-drag: none;
+ user-drag: none;
+ border-top: 2px solid #eee;
+}
+
+#panels-container .panel {
+ overflow: auto;
+ overflow-x: hidden;
+}
+
+#messages-cont {
+ position: absolute!important;
+ top: 0px;
+ left: 6px;
+ right: 6px;
+ bottom: 6px;
+ border: 3px solid #eee;
+ border-radius: 3px;
+ overflow: auto;
+ overflow-x: hidden;
+}
+
+#messages p {
+ padding-bottom: 5px;
+ padding-top: 5px;
+ line-height: 22px;
+ padding-left: 110px;
+ position: relative;
+ width: calc(100% - 110px);
+ word-break: break-word;
+}
+
+#messages.no-timestamp p {
+ padding-left: 10px;
+ width: calc(100% - 10px);
+}
+
+#messages.no-timestamp span.timestamp {
+ display: none;
+}
+
+#messages p:hover {
+ background: #f9f9f9;
+}
+
+#messages p:hover span.timestamp {
+ color: #2e85c7
+}
+
+#messages p span.timestamp {
+ color: #999;
+ display: block;
+ position: absolute;
+ left: 5px;
+}
+
+#messages p span.topic {
+ color: #f5892c;
+}
+
+#messages p span.msg {
+ color: #12568a;
+}
+
+#messages p span.data {
+ color: #17d838;
+}
+
+#messages p span.error {
+ color: #cf000f;
+}
+
+#messages:hover p:hover {
+ filter: none;
+}
+
+#messages:hover p {
+ filter: grayscale(100%);
+}
+
+#loading-cont {
+ opacity: 0;
+ visibility: hidden;
+ position: absolute;
+ touch-action: none;
+ -webkit-user-select: none;
+ user-select: none;
+ -webkit-user-drag: none;
+ user-drag: none;
+ top: 0;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ -webkit-backdrop-filter: blur(5px);
+ backdrop-filter: blur(5px);
+ background-color: rgba(255, 255, 255, 0.7);
+ transition: all linear 0.5s;
+}
+
+
+#loading {
+ display: block;
+ height: 150px;
+ width: 150px;
+ position: absolute;
+ left: calc(50% - 75px);
+ top: calc(50% - 75px);
+ box-shadow: 0 0 20px rgba(0,0,0,0.3);
+ -webkit-box-shadow: 0 0 20px rgb(0 0 0 / 30%);
+ -moz-box-shadow: 0 0 20px rgba(0,0,0,0.3);
+ z-index: 996;
+ border-radius: 75px;
+ background: #ffffff0d;
+ transition: all linear 0.5s;
+ -webkit-user-select: none;
+ user-select: none;
+ -webkit-user-drag: none;
+ user-drag: none;
+}
+
+#loading div {
+ display: block;
+ height: 150px;
+ width: 150px;
+ background: url(../img/airplane-loading.svg);
+ -webkit-animation: spinner 3s linear infinite;
+ -moz-animation: spinner 3s linear infinite;
+ -ms-animation: spinner 3s linear infinite;
+ -o-animation: spinner 3s linear infinite;
+ animation: spinner 3s linear infinite;
+ background-size: 150px;
+}
+
+@-webkit-keyframes spinner {
+ 0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); }
+ 100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); }
+}
+@-moz-keyframes spinner {
+ 0% { -moz-transform: rotate(0deg); transform: rotate(0deg); }
+ 100% { -moz-transform: rotate(360deg); transform: rotate(360deg); }
+}
+@-o-keyframes spinner {
+ 0% { -o-transform: rotate(0deg); transform: rotate(0deg); }
+ 100% { -o-transform: rotate(360deg); transform: rotate(360deg); }
+}
+
+@keyframes spinner {
+ 0% { transform: rotate(0deg); transform: rotate(0deg); }
+ 100% { transform: rotate(360deg); transform: rotate(360deg); }
+}
\ No newline at end of file
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100.eot b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100.eot
new file mode 100644
index 0000000..3913f67
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100.eot differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100.svg b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100.svg
new file mode 100644
index 0000000..e8c8fc8
--- /dev/null
+++ b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100.svg
@@ -0,0 +1,313 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100.ttf b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100.ttf
new file mode 100644
index 0000000..3a4d7d3
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100.ttf differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100.woff b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100.woff
new file mode 100644
index 0000000..d34f535
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100.woff differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100.woff2 b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100.woff2
new file mode 100644
index 0000000..40ef29e
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100.woff2 differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100italic.eot b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100italic.eot
new file mode 100644
index 0000000..d8bf969
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100italic.eot differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100italic.svg b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100italic.svg
new file mode 100644
index 0000000..c51ce87
--- /dev/null
+++ b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100italic.svg
@@ -0,0 +1,332 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100italic.ttf b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100italic.ttf
new file mode 100644
index 0000000..e6a9aa8
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100italic.ttf differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100italic.woff b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100italic.woff
new file mode 100644
index 0000000..05f39d0
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100italic.woff differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100italic.woff2 b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100italic.woff2
new file mode 100644
index 0000000..f92e2d6
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100italic.woff2 differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300.eot b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300.eot
new file mode 100644
index 0000000..efa7695
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300.eot differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300.svg b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300.svg
new file mode 100644
index 0000000..4ded944
--- /dev/null
+++ b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300.svg
@@ -0,0 +1,312 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300.ttf b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300.ttf
new file mode 100644
index 0000000..89f0e46
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300.ttf differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300.woff b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300.woff
new file mode 100644
index 0000000..983083c
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300.woff differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300.woff2 b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300.woff2
new file mode 100644
index 0000000..7438dae
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300.woff2 differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300italic.eot b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300italic.eot
new file mode 100644
index 0000000..a431b11
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300italic.eot differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300italic.svg b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300italic.svg
new file mode 100644
index 0000000..758402b
--- /dev/null
+++ b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300italic.svg
@@ -0,0 +1,329 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300italic.ttf b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300italic.ttf
new file mode 100644
index 0000000..712f868
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300italic.ttf differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300italic.woff b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300italic.woff
new file mode 100644
index 0000000..1d4ce52
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300italic.woff differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300italic.woff2 b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300italic.woff2
new file mode 100644
index 0000000..2e45b86
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300italic.woff2 differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500.eot b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500.eot
new file mode 100644
index 0000000..5f9a95a
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500.eot differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500.svg b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500.svg
new file mode 100644
index 0000000..67eecf4
--- /dev/null
+++ b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500.svg
@@ -0,0 +1,305 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500.ttf b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500.ttf
new file mode 100644
index 0000000..c1ec6c7
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500.ttf differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500.woff b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500.woff
new file mode 100644
index 0000000..0bfe7b9
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500.woff differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500.woff2 b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500.woff2
new file mode 100644
index 0000000..d28c5da
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500.woff2 differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500italic.eot b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500italic.eot
new file mode 100644
index 0000000..c1e534a
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500italic.eot differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500italic.svg b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500italic.svg
new file mode 100644
index 0000000..bed50dc
--- /dev/null
+++ b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500italic.svg
@@ -0,0 +1,326 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500italic.ttf b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500italic.ttf
new file mode 100644
index 0000000..b8e8b34
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500italic.ttf differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500italic.woff b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500italic.woff
new file mode 100644
index 0000000..9fea1b4
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500italic.woff differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500italic.woff2 b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500italic.woff2
new file mode 100644
index 0000000..9dcfa25
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500italic.woff2 differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700.eot b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700.eot
new file mode 100644
index 0000000..f230765
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700.eot differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700.svg b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700.svg
new file mode 100644
index 0000000..11db87d
--- /dev/null
+++ b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700.svg
@@ -0,0 +1,309 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700.ttf b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700.ttf
new file mode 100644
index 0000000..333022d
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700.ttf differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700.woff b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700.woff
new file mode 100644
index 0000000..8c9b024
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700.woff differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700.woff2 b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700.woff2
new file mode 100644
index 0000000..3768f01
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700.woff2 differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700italic.eot b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700italic.eot
new file mode 100644
index 0000000..77866f2
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700italic.eot differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700italic.svg b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700italic.svg
new file mode 100644
index 0000000..050bee0
--- /dev/null
+++ b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700italic.svg
@@ -0,0 +1,325 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700italic.ttf b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700italic.ttf
new file mode 100644
index 0000000..51df877
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700italic.ttf differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700italic.woff b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700italic.woff
new file mode 100644
index 0000000..55befb6
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700italic.woff differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700italic.woff2 b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700italic.woff2
new file mode 100644
index 0000000..93ee346
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700italic.woff2 differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900.eot b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900.eot
new file mode 100644
index 0000000..e9b6bf4
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900.eot differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900.svg b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900.svg
new file mode 100644
index 0000000..9efdf4e
--- /dev/null
+++ b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900.svg
@@ -0,0 +1,302 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900.ttf b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900.ttf
new file mode 100644
index 0000000..c520b23
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900.ttf differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900.woff b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900.woff
new file mode 100644
index 0000000..55de95d
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900.woff differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900.woff2 b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900.woff2
new file mode 100644
index 0000000..2cd435f
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900.woff2 differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900italic.eot b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900italic.eot
new file mode 100644
index 0000000..5d3207e
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900italic.eot differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900italic.svg b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900italic.svg
new file mode 100644
index 0000000..f8f5ab3
--- /dev/null
+++ b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900italic.svg
@@ -0,0 +1,324 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900italic.ttf b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900italic.ttf
new file mode 100644
index 0000000..060ae73
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900italic.ttf differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900italic.woff b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900italic.woff
new file mode 100644
index 0000000..b0fd0a3
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900italic.woff differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900italic.woff2 b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900italic.woff2
new file mode 100644
index 0000000..31aa851
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900italic.woff2 differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-italic.eot b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-italic.eot
new file mode 100644
index 0000000..e25ecbe
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-italic.eot differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-italic.svg b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-italic.svg
new file mode 100644
index 0000000..4d59797
--- /dev/null
+++ b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-italic.svg
@@ -0,0 +1,323 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-italic.ttf b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-italic.ttf
new file mode 100644
index 0000000..0d21311
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-italic.ttf differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-italic.woff b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-italic.woff
new file mode 100644
index 0000000..cd91cce
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-italic.woff differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-italic.woff2 b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-italic.woff2
new file mode 100644
index 0000000..bdeb9f5
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-italic.woff2 differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-regular.eot b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-regular.eot
new file mode 100644
index 0000000..cdf3f00
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-regular.eot differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-regular.svg b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-regular.svg
new file mode 100644
index 0000000..627f5a3
--- /dev/null
+++ b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-regular.svg
@@ -0,0 +1,308 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-regular.ttf b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-regular.ttf
new file mode 100644
index 0000000..a36cdee
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-regular.ttf differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-regular.woff b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-regular.woff
new file mode 100644
index 0000000..7245f5c
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-regular.woff differ
diff --git a/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-regular.woff2 b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-regular.woff2
new file mode 100644
index 0000000..2e3eefc
Binary files /dev/null and b/font/roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-regular.woff2 differ
diff --git a/font/roboto.css b/font/roboto.css
new file mode 100644
index 0000000..f77e8ac
--- /dev/null
+++ b/font/roboto.css
@@ -0,0 +1,156 @@
+/* roboto-100 - latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 100;
+ src: url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100.eot'); /* IE9 Compat Modes */
+ src: local('Roboto Thin'), local('Roboto-Thin'),
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100.woff2') format('woff2'), /* Super Modern Browsers */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100.woff') format('woff'), /* Modern Browsers */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100.ttf') format('truetype'), /* Safari, Android, iOS */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100.svg#Roboto') format('svg'); /* Legacy iOS */
+}
+/* roboto-100italic - latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic */
+@font-face {
+ font-family: 'Roboto';
+ font-style: italic;
+ font-weight: 100;
+ src: url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100italic.eot'); /* IE9 Compat Modes */
+ src: local('Roboto Thin Italic'), local('Roboto-ThinItalic'),
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100italic.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100italic.woff2') format('woff2'), /* Super Modern Browsers */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100italic.woff') format('woff'), /* Modern Browsers */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100italic.ttf') format('truetype'), /* Safari, Android, iOS */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-100italic.svg#Roboto') format('svg'); /* Legacy iOS */
+}
+/* roboto-300 - latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 300;
+ src: url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300.eot'); /* IE9 Compat Modes */
+ src: local('Roboto Light'), local('Roboto-Light'),
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300.woff2') format('woff2'), /* Super Modern Browsers */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300.woff') format('woff'), /* Modern Browsers */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300.ttf') format('truetype'), /* Safari, Android, iOS */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300.svg#Roboto') format('svg'); /* Legacy iOS */
+}
+/* roboto-300italic - latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic */
+@font-face {
+ font-family: 'Roboto';
+ font-style: italic;
+ font-weight: 300;
+ src: url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300italic.eot'); /* IE9 Compat Modes */
+ src: local('Roboto Light Italic'), local('Roboto-LightItalic'),
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300italic.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300italic.woff2') format('woff2'), /* Super Modern Browsers */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300italic.woff') format('woff'), /* Modern Browsers */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300italic.ttf') format('truetype'), /* Safari, Android, iOS */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-300italic.svg#Roboto') format('svg'); /* Legacy iOS */
+}
+/* roboto-regular - latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 400;
+ src: url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-regular.eot'); /* IE9 Compat Modes */
+ src: local('Roboto'), local('Roboto-Regular'),
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-regular.woff2') format('woff2'), /* Super Modern Browsers */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-regular.woff') format('woff'), /* Modern Browsers */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-regular.ttf') format('truetype'), /* Safari, Android, iOS */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-regular.svg#Roboto') format('svg'); /* Legacy iOS */
+}
+/* roboto-italic - latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic */
+@font-face {
+ font-family: 'Roboto';
+ font-style: italic;
+ font-weight: 400;
+ src: url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-italic.eot'); /* IE9 Compat Modes */
+ src: local('Roboto Italic'), local('Roboto-Italic'),
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-italic.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-italic.woff2') format('woff2'), /* Super Modern Browsers */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-italic.woff') format('woff'), /* Modern Browsers */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-italic.ttf') format('truetype'), /* Safari, Android, iOS */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-italic.svg#Roboto') format('svg'); /* Legacy iOS */
+}
+/* roboto-500 - latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 500;
+ src: url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500.eot'); /* IE9 Compat Modes */
+ src: local('Roboto Medium'), local('Roboto-Medium'),
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500.woff2') format('woff2'), /* Super Modern Browsers */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500.woff') format('woff'), /* Modern Browsers */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500.ttf') format('truetype'), /* Safari, Android, iOS */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500.svg#Roboto') format('svg'); /* Legacy iOS */
+}
+/* roboto-500italic - latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic */
+@font-face {
+ font-family: 'Roboto';
+ font-style: italic;
+ font-weight: 500;
+ src: url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500italic.eot'); /* IE9 Compat Modes */
+ src: local('Roboto Medium Italic'), local('Roboto-MediumItalic'),
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500italic.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500italic.woff2') format('woff2'), /* Super Modern Browsers */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500italic.woff') format('woff'), /* Modern Browsers */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500italic.ttf') format('truetype'), /* Safari, Android, iOS */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-500italic.svg#Roboto') format('svg'); /* Legacy iOS */
+}
+/* roboto-700 - latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 700;
+ src: url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700.eot'); /* IE9 Compat Modes */
+ src: local('Roboto Bold'), local('Roboto-Bold'),
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700.woff2') format('woff2'), /* Super Modern Browsers */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700.woff') format('woff'), /* Modern Browsers */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700.ttf') format('truetype'), /* Safari, Android, iOS */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700.svg#Roboto') format('svg'); /* Legacy iOS */
+}
+/* roboto-700italic - latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic */
+@font-face {
+ font-family: 'Roboto';
+ font-style: italic;
+ font-weight: 700;
+ src: url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700italic.eot'); /* IE9 Compat Modes */
+ src: local('Roboto Bold Italic'), local('Roboto-BoldItalic'),
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700italic.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700italic.woff2') format('woff2'), /* Super Modern Browsers */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700italic.woff') format('woff'), /* Modern Browsers */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700italic.ttf') format('truetype'), /* Safari, Android, iOS */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-700italic.svg#Roboto') format('svg'); /* Legacy iOS */
+}
+/* roboto-900 - latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic */
+@font-face {
+ font-family: 'Roboto';
+ font-style: normal;
+ font-weight: 900;
+ src: url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900.eot'); /* IE9 Compat Modes */
+ src: local('Roboto Black'), local('Roboto-Black'),
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900.woff2') format('woff2'), /* Super Modern Browsers */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900.woff') format('woff'), /* Modern Browsers */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900.ttf') format('truetype'), /* Safari, Android, iOS */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900.svg#Roboto') format('svg'); /* Legacy iOS */
+}
+/* roboto-900italic - latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic */
+@font-face {
+ font-family: 'Roboto';
+ font-style: italic;
+ font-weight: 900;
+ src: url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900italic.eot'); /* IE9 Compat Modes */
+ src: local('Roboto Black Italic'), local('Roboto-BlackItalic'),
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900italic.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900italic.woff2') format('woff2'), /* Super Modern Browsers */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900italic.woff') format('woff'), /* Modern Browsers */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900italic.ttf') format('truetype'), /* Safari, Android, iOS */
+ url('roboto-v20-latin-ext_latin_greek-ext_greek_cyrillic-ext_cyrillic-900italic.svg#Roboto') format('svg'); /* Legacy iOS */
+}
\ No newline at end of file
diff --git a/img/airplane-loading.svg b/img/airplane-loading.svg
new file mode 100644
index 0000000..4aca05c
--- /dev/null
+++ b/img/airplane-loading.svg
@@ -0,0 +1,57 @@
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
diff --git a/img/autoscroll.svg b/img/autoscroll.svg
new file mode 100644
index 0000000..21637a0
--- /dev/null
+++ b/img/autoscroll.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/img/close-all.svg b/img/close-all.svg
new file mode 100644
index 0000000..19de7b0
--- /dev/null
+++ b/img/close-all.svg
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/img/close.svg b/img/close.svg
new file mode 100644
index 0000000..0c67914
--- /dev/null
+++ b/img/close.svg
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
diff --git a/img/connection.svg b/img/connection.svg
new file mode 100644
index 0000000..e9fb377
--- /dev/null
+++ b/img/connection.svg
@@ -0,0 +1,248 @@
+
+
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/img/favicon.png b/img/favicon.png
new file mode 100644
index 0000000..7b767f0
Binary files /dev/null and b/img/favicon.png differ
diff --git a/img/hdrag.svg b/img/hdrag.svg
new file mode 100644
index 0000000..75c5f03
--- /dev/null
+++ b/img/hdrag.svg
@@ -0,0 +1,100 @@
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/img/icons/android-icon-144x144.png b/img/icons/android-icon-144x144.png
new file mode 100644
index 0000000..22a2f88
Binary files /dev/null and b/img/icons/android-icon-144x144.png differ
diff --git a/img/icons/android-icon-192x192.png b/img/icons/android-icon-192x192.png
new file mode 100644
index 0000000..64b4d9c
Binary files /dev/null and b/img/icons/android-icon-192x192.png differ
diff --git a/img/icons/android-icon-36x36.png b/img/icons/android-icon-36x36.png
new file mode 100644
index 0000000..8c77021
Binary files /dev/null and b/img/icons/android-icon-36x36.png differ
diff --git a/img/icons/android-icon-48x48.png b/img/icons/android-icon-48x48.png
new file mode 100644
index 0000000..4f8b93b
Binary files /dev/null and b/img/icons/android-icon-48x48.png differ
diff --git a/img/icons/android-icon-72x72.png b/img/icons/android-icon-72x72.png
new file mode 100644
index 0000000..b5510d5
Binary files /dev/null and b/img/icons/android-icon-72x72.png differ
diff --git a/img/icons/android-icon-96x96.png b/img/icons/android-icon-96x96.png
new file mode 100644
index 0000000..3cccf92
Binary files /dev/null and b/img/icons/android-icon-96x96.png differ
diff --git a/img/icons/apple-icon-114x114.png b/img/icons/apple-icon-114x114.png
new file mode 100644
index 0000000..8b43e5f
Binary files /dev/null and b/img/icons/apple-icon-114x114.png differ
diff --git a/img/icons/apple-icon-120x120.png b/img/icons/apple-icon-120x120.png
new file mode 100644
index 0000000..3d50015
Binary files /dev/null and b/img/icons/apple-icon-120x120.png differ
diff --git a/img/icons/apple-icon-144x144.png b/img/icons/apple-icon-144x144.png
new file mode 100644
index 0000000..22a2f88
Binary files /dev/null and b/img/icons/apple-icon-144x144.png differ
diff --git a/img/icons/apple-icon-152x152.png b/img/icons/apple-icon-152x152.png
new file mode 100644
index 0000000..6501721
Binary files /dev/null and b/img/icons/apple-icon-152x152.png differ
diff --git a/img/icons/apple-icon-180x180.png b/img/icons/apple-icon-180x180.png
new file mode 100644
index 0000000..cb3086b
Binary files /dev/null and b/img/icons/apple-icon-180x180.png differ
diff --git a/img/icons/apple-icon-57x57.png b/img/icons/apple-icon-57x57.png
new file mode 100644
index 0000000..ec75c0c
Binary files /dev/null and b/img/icons/apple-icon-57x57.png differ
diff --git a/img/icons/apple-icon-60x60.png b/img/icons/apple-icon-60x60.png
new file mode 100644
index 0000000..61610ea
Binary files /dev/null and b/img/icons/apple-icon-60x60.png differ
diff --git a/img/icons/apple-icon-72x72.png b/img/icons/apple-icon-72x72.png
new file mode 100644
index 0000000..b5510d5
Binary files /dev/null and b/img/icons/apple-icon-72x72.png differ
diff --git a/img/icons/apple-icon-76x76.png b/img/icons/apple-icon-76x76.png
new file mode 100644
index 0000000..a11a3d8
Binary files /dev/null and b/img/icons/apple-icon-76x76.png differ
diff --git a/img/icons/apple-icon-precomposed.png b/img/icons/apple-icon-precomposed.png
new file mode 100644
index 0000000..6fd1661
Binary files /dev/null and b/img/icons/apple-icon-precomposed.png differ
diff --git a/img/icons/apple-icon.png b/img/icons/apple-icon.png
new file mode 100644
index 0000000..6fd1661
Binary files /dev/null and b/img/icons/apple-icon.png differ
diff --git a/img/icons/browserconfig.xml b/img/icons/browserconfig.xml
new file mode 100644
index 0000000..c554148
--- /dev/null
+++ b/img/icons/browserconfig.xml
@@ -0,0 +1,2 @@
+
+#ffffff
\ No newline at end of file
diff --git a/img/icons/favicon-16x16.png b/img/icons/favicon-16x16.png
new file mode 100644
index 0000000..fa4b16f
Binary files /dev/null and b/img/icons/favicon-16x16.png differ
diff --git a/img/icons/favicon-32x32.png b/img/icons/favicon-32x32.png
new file mode 100644
index 0000000..8b854df
Binary files /dev/null and b/img/icons/favicon-32x32.png differ
diff --git a/img/icons/favicon-96x96.png b/img/icons/favicon-96x96.png
new file mode 100644
index 0000000..3cccf92
Binary files /dev/null and b/img/icons/favicon-96x96.png differ
diff --git a/img/icons/favicon.ico b/img/icons/favicon.ico
new file mode 100644
index 0000000..8e0523f
Binary files /dev/null and b/img/icons/favicon.ico differ
diff --git a/img/icons/manifest.json b/img/icons/manifest.json
new file mode 100644
index 0000000..0f225a5
--- /dev/null
+++ b/img/icons/manifest.json
@@ -0,0 +1,41 @@
+{
+ "name": "App",
+ "icons": [
+ {
+ "src": ".\/android-icon-36x36.png",
+ "sizes": "36x36",
+ "type": "image\/png",
+ "density": "0.75"
+ },
+ {
+ "src": ".\/android-icon-48x48.png",
+ "sizes": "48x48",
+ "type": "image\/png",
+ "density": "1.0"
+ },
+ {
+ "src": ".\/android-icon-72x72.png",
+ "sizes": "72x72",
+ "type": "image\/png",
+ "density": "1.5"
+ },
+ {
+ "src": ".\/android-icon-96x96.png",
+ "sizes": "96x96",
+ "type": "image\/png",
+ "density": "2.0"
+ },
+ {
+ "src": ".\/android-icon-144x144.png",
+ "sizes": "144x144",
+ "type": "image\/png",
+ "density": "3.0"
+ },
+ {
+ "src": ".\/android-icon-192x192.png",
+ "sizes": "192x192",
+ "type": "image\/png",
+ "density": "4.0"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/img/icons/ms-icon-144x144.png b/img/icons/ms-icon-144x144.png
new file mode 100644
index 0000000..22a2f88
Binary files /dev/null and b/img/icons/ms-icon-144x144.png differ
diff --git a/img/icons/ms-icon-150x150.png b/img/icons/ms-icon-150x150.png
new file mode 100644
index 0000000..b3e198b
Binary files /dev/null and b/img/icons/ms-icon-150x150.png differ
diff --git a/img/icons/ms-icon-310x310.png b/img/icons/ms-icon-310x310.png
new file mode 100644
index 0000000..a1beb9f
Binary files /dev/null and b/img/icons/ms-icon-310x310.png differ
diff --git a/img/icons/ms-icon-70x70.png b/img/icons/ms-icon-70x70.png
new file mode 100644
index 0000000..7d3787a
Binary files /dev/null and b/img/icons/ms-icon-70x70.png differ
diff --git a/img/logo.svg b/img/logo.svg
new file mode 100644
index 0000000..b7968e0
--- /dev/null
+++ b/img/logo.svg
@@ -0,0 +1,73 @@
+
+
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/img/more.svg b/img/more.svg
new file mode 100644
index 0000000..d2e640d
--- /dev/null
+++ b/img/more.svg
@@ -0,0 +1,78 @@
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/img/notifications.svg b/img/notifications.svg
new file mode 100644
index 0000000..e775939
--- /dev/null
+++ b/img/notifications.svg
@@ -0,0 +1,86 @@
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/img/settings.svg b/img/settings.svg
new file mode 100644
index 0000000..abbe397
--- /dev/null
+++ b/img/settings.svg
@@ -0,0 +1,123 @@
+
+
+
+
+
+ image/svg+xml
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/img/timestamp.svg b/img/timestamp.svg
new file mode 100644
index 0000000..18c64e4
--- /dev/null
+++ b/img/timestamp.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..e617b4c
--- /dev/null
+++ b/index.html
@@ -0,0 +1,293 @@
+
+
+
+
+
+
+ MQTTWebClient | PR-DC
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ MQTT
+
+
+
+ MQTTWebClient
+
+
+
+
+
+
+
+
+
+
+
MQTT Broker connection
+
+
+ Host
+
+
+
+ Port
+
+
+
+ Client ID
+
+
+
+
+
+
+ Username
+
+
+
+ Password
+
+
Connect
+
MQTT Client
+
Publish
+
Subscribe
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Retain message
+
+
+
+
+ Message topic
+
+
+
+ 0
+ 1
+ 2
+
+ QoS
+
+
+
+
+ Message
+
+
Publish message
+
+
+
+
+
+
+
+
+
+
+
+ Topic
+
+
+
+ 0
+ 1
+ 2
+
+ QoS
+
+
+
Subscribe to topic
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Connect to broker...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/js/callbacks.js b/js/callbacks.js
new file mode 100644
index 0000000..039efbb
--- /dev/null
+++ b/js/callbacks.js
@@ -0,0 +1,389 @@
+/**
+ * MQTTWebClient - callbacks.js
+ * Author: Milos Petrasinovic
+ * PR-DC, Republic of Serbia
+ * info@pr-dc.com
+ *
+ * --------------------
+ * Copyright (C) 2021 PR-DC
+ *
+ * This file is part of PRDC_MQTTWebClient.
+ *
+ * PRDC_MQTTWebClient is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * PRDC_MQTTWebClient is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with PRDC_MQTTWebClient. If not, see .
+ *
+ */
+
+// initOptions() function
+// Initialize options
+// --------------------
+function initOptions() {
+ N_messages_max = Number(localStorage.getObj('N_messages_max'));
+ if(N_messages_max == 0) {
+ N_messages_max = Infinity;
+ }
+ $('#N-messages-max').val(N_messages_max);
+
+ show_timestamp = localStorage.getObj('show_timestamp');
+ if(show_timestamp == null) {
+ show_timestamp = true;
+ }
+ if(show_timestamp) {
+ $('#show-timestamp').prop('checked', true);
+ $('#messages').removeClass('no-timestamp');
+ $('#terminal-options .timestamp').addClass('active');
+ } else {
+ $('#show-timestamp').prop('checked', false);
+ $('#messages').addClass('no-timestamp');
+ $('#terminal-options .timestamp').removeClass('active');
+ }
+
+ autoscroll = localStorage.getObj('autoscroll');
+ if(autoscroll == null) {
+ autoscroll = true;
+ }
+ if(autoscroll) {
+ $('#autoscroll-on').prop('checked', true);
+ $('#terminal-options .autoscroll').addClass('active');
+ } else {
+ $('#autoscroll-on').prop('checked', false);
+ $('#terminal-options .autoscroll').removeClass('active');
+ }
+}
+
+// toggleShowTimestamp() function
+// Show timestamp toggle
+// --------------------
+function toggleShowTimestamp() {
+ if(show_timestamp) {
+ show_timestamp = false;
+ $('#show-timestamp').prop('checked', false);
+ $('#messages').addClass('no-timestamp');
+ $('#terminal-options .timestamp').removeClass('active');
+ } else {
+ show_timestamp = true;
+ $('#show-timestamp').prop('checked', true);
+ $('#messages').removeClass('no-timestamp');
+ $('#terminal-options .timestamp').addClass('active');
+ }
+ localStorage.setObj('show_timestamp', show_timestamp);
+}
+
+// toggleAutoscroll() function
+// Terminal autoscroll toggle
+// --------------------
+function toggleAutoscroll() {
+ if(autoscroll) {
+ autoscroll = false;
+ $('#autoscroll-on').prop('checked', false);
+ $('#terminal-options .autoscroll').removeClass('active');
+ } else {
+ autoscroll = true;
+ $('#autoscroll-on').prop('checked', true);
+ $('#terminal-options .autoscroll').addClass('active');
+ }
+ localStorage.setObj('autoscroll', autoscroll);
+}
+
+// toggleConnect() function
+// Connect or disconnect platform
+// --------------------
+function toggleConnect() {
+ if(connected) {
+ client.disconnect();
+ brokerDisconnect();
+ } else {
+ brokerConnect();
+ }
+}
+
+// changeMaxMessagesNum() function
+// Change max messages number
+// --------------------
+function changeMaxMessagesNum() {
+ N_messages_max = $(this).val();
+ if(N_messages_max < 5) {
+ N_messages_max = 5;
+ $(this).val(5);
+ }
+ localStorage.setObj('N_messages_max', N_messages_max);
+
+ if(N_messages > N_messages_max) {
+ while(N_messages > N_messages_max) {
+ $('#messages')[0].firstChild.remove();
+ N_messages -= 1;
+ }
+ }
+}
+
+// brokerConnect() function
+// Broker connect
+// --------------------
+function brokerConnect() {
+ $('#toggle-connect').text('Disconnect');
+ $('#toggle-connect').addClass('connected');
+ $('#host').prop('disabled', true);
+ $('#port').prop('disabled', true);
+ $('#username').prop('disabled', true);
+ $('#password').prop('disabled', true);
+ $('#client-id').prop('disabled', true);
+ $('#publish-msg-btn').prop('disabled', false);
+ $('#subscribe-msg-btn').prop('disabled', false);
+ $('#advanced-settings-open').addClass('disabled');
+
+ // Fetch the hostname/IP address and port number from the form
+ var host = $('#host').val();
+ var port = $('#port').val();
+ var username = $('#username').val();
+ var password = $('#password').val();
+ var client_id = $('#client-id').val();
+ var timeout = Number($('#timeout').val());
+ var keep_alive_interval = Number($('#keep-alive').val());
+ var clean_session = $('#clean-session').is(':checked');
+ var lw_flag = $('#last-will').is(':checked');
+ if(lw_flag) {
+ var lw_msg = $('#lw-message').val();
+ var lw_topic = $('#lw-topic').val();
+ var lw_qos = Number($('#lw-qos').val());
+ var lw_retain = $('#retain-last-will').is(':checked');
+ }
+
+ // Print output for the user in the messages div
+ showMessage('Connecting to: ' + host +
+ ' on port: ' + port +
+ ' , using the following client ID: ' +
+ client_id + ' ');
+
+ // Initialize new Paho client connection
+ // https://www.eclipse.org/paho/files/jsdoc/Paho.MQTT.Client.html
+ client = new Paho.MQTT.Client(host, Number(port), client_id);
+
+ var connect_options = {
+ timeout: timeout,
+ userName: username,
+ password: password,
+ cleanSession: clean_session,
+ keepAliveInterval: keep_alive_interval,
+ onSuccess: onConnect,
+ onFailure: onConnectFailed
+ };
+
+ if(lw_flag) {
+ var lw = new Paho.MQTT.Message(lw_msg);
+ lw.destinationName = lw_topic;
+ lw.qos = lw_qos;
+ lw.retained = lw_retain;
+ connect_options.willMessage = lw;
+ }
+
+ // Set callback handlers
+ client.onConnectionLost = onConnectionLost;
+ client.onMessageArrived = onMessageArrived;
+ client.onMessageDelivered = onMessageDelivered;
+
+ // Connect the client, if successful, call onConnect function
+ client.connect(connect_options);
+ showCont('loading-cont');
+}
+
+// brokerDisconnect() function
+// Broker disconnect
+// --------------------
+function brokerDisconnect() {
+ if(connected) {
+ connected = false;
+ setDisconnected();
+ showMessage('Disconnected.');
+
+ // Update status
+ updateStatus('Connect to broker...');
+ }
+}
+
+// onConnect() function
+// Called when the client connects
+// --------------------
+function onConnect() {
+ connected = true;
+ showMessage('Connected!');
+ hideCont('loading-cont');
+
+ // Update status
+ updateStatus('Connected to broker...');
+}
+
+// onConnectFailed() function
+// Called when the client connection failed
+// --------------------
+function onConnectFailed(res) {
+ setDisconnected();
+ hideCont('loading-cont');
+ showMessage('Failed to connect. Error [' +
+ res.errorCode + ' ]: ' +
+ res.errorMessage + ' ');
+ updateMessagesScroll();
+}
+
+// setDisconnected() function
+// Set disconnected state
+// --------------------
+function setDisconnected() {
+ $('#toggle-connect').text('Connect');
+ $('#toggle-connect').removeClass('connected');
+ $('#host').prop('disabled', false);
+ $('#port').prop('disabled', false);
+ $('#username').prop('disabled', false);
+ $('#password').prop('disabled', false);
+ $('#client-id').prop('disabled', false);
+ $('#publish-msg-btn').prop('disabled', true);
+ $('#subscribe-msg-btn').prop('disabled', true);
+ $('#advanced-settings-open').removeClass('disabled');
+}
+
+// onConnectionLost() function
+// Called when the client loses its connection
+// --------------------
+function onConnectionLost(res) {
+ if(connected) {
+ if(res.errorCode !== 0) {
+ showMessage('Connection lost. Error [' +
+ res.errorCode + ' ]: ' +
+ res.errorMessage + ' ');
+ }
+ brokerDisconnect();
+ }
+}
+
+// onMessageArrived() function
+// Called when a message arrives
+// --------------------
+function onMessageArrived(message) {
+ showMessage('Message received. Topic: ' +
+ message.destinationName + ' | Message: ' +
+ message.payloadString + ' ');
+}
+
+// onMessageDelivered() function
+// Called when a message is delivered
+// --------------------
+function onMessageDelivered(message) {
+ showMessage('Message delivered. Topic: ' +
+ message.destinationName + ' | Message: ' +
+ message.payloadString + ' ');
+}
+
+// publishMessage() function
+// Publish message
+// --------------------
+function publishMessage() {
+ if(connected) {
+ var topic = $('#topic').val();
+ var payload = $('#message').val();
+ var qos = Number($('#qos').val());
+ var retained = $('#retain').is(':checked');
+ showMessage('Message sent. Topic: ' + topic +
+ ' | Message: ' + payload + ' ');
+ client.publish(topic, payload, qos, retained);
+ } else {
+ showMessage('Please connect to the broker.');
+ }
+}
+
+// subTopic() function
+// Subscribe to topic
+// --------------------
+function subTopic() {
+ if(connected) {
+ var topic = $('#sub-topic').val();
+ var qos = Number($('#sub-qos').val());
+ if(topics_num > 0 && topic in topics_list) {
+ showMessage('Already subscribed to topic: ' +
+ topic + ' ');
+ } else {
+ subscribeOptions = {
+ qos: qos,
+ onSuccess: function(res) {
+ // Remove no topics
+ if(topics_num == 0) {
+ $('#no-sub-topics').hide();
+ }
+ topics_num = topics_num+1;
+
+ // Create node for topic
+ var node = document.createElement('li');
+ node.innerHTML = topic + 'QoS: ' + qos + ' ';
+
+ // Create unsubscribe button
+ var unsubButton = document.createElement('img');
+ unsubButton.src = 'img/close.svg';
+ unsubButton.addEventListener('click', function() {
+ unsubTopic(topic);
+ });
+ node.prepend(unsubButton);
+
+ // Add new topic to list
+ $('#topics-list')[0].appendChild(node);
+ topics_list[topic] = node;
+ showMessage('Subscribed to topic: ' +
+ topic + ' ');
+ },
+ onFailure: function(res) {
+ showMessage('Failed to subscribe to topic: ' +
+ '' + topic + ' ');
+ }
+ };
+ showMessage('Sent request to subscribe to topic: ' +
+ '' + topic + ' ');
+ client.subscribe(topic, subscribeOptions);
+ }
+ } else {
+ showMessage('Please connect to the broker.');
+ }
+}
+
+// unsubTopic() function
+// Unsubscribe to topic
+// --------------------
+function unsubTopic(topic) {
+ if(connected) {
+ if(topics_num > 0 && topic in topics_list) {
+ unsubscribeOptions = {
+ onSuccess: function(res) {
+ topics_num = topics_num-1;
+ if(topics_num == 0) {
+ $('#no-sub-topics').show();
+ }
+ showMessage('Unsubscribed from topic: ' +
+ '' + topic + ' ');
+
+ // Remove topic from lists
+ var node = topics_list[topic];
+ node.parentElement.removeChild(node);
+ delete topics_list[topic];
+ },
+ onFailure: function(res) {
+ showMessage('Failed to unsubscribe from topic: ' +
+ '' + topic + ' ');
+ }
+ };
+ showMessage('Sent request to unsubscribe from topic: ' +
+ '' + topic + ' ');
+ client.unsubscribe(topic, unsubscribeOptions);
+ } else {
+ showMessage('Topic: ' +
+ topic + ' is not subscribed.');
+ }
+ } else {
+ showMessage('Please connect to the broker.');
+ }
+}
\ No newline at end of file
diff --git a/js/frontend.js b/js/frontend.js
new file mode 100644
index 0000000..e3f7348
--- /dev/null
+++ b/js/frontend.js
@@ -0,0 +1,86 @@
+/**
+ * MQTTWebClient - frontend.js
+ * Author: Milos Petrasinovic
+ * PR-DC, Republic of Serbia
+ * info@pr-dc.com
+ *
+ * --------------------
+ * Copyright (C) 2021 PR-DC
+ *
+ * This file is part of PRDC_MQTTWebClient.
+ *
+ * PRDC_MQTTWebClient is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * PRDC_MQTTWebClient is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with PRDC_MQTTWebClient. If not, see .
+ *
+ */
+
+// Variables
+// --------------------
+var connected = false;
+
+var panel_t_height = 66.66; // [%]
+var panel_b_height = 33.33; // [%]
+var panels_top; // [px]
+var panels_left; // [px]
+var panels_width; // [px]
+var panels_height; // [px]
+
+var client;
+var topics_list = {};
+var topics_num = 0;
+var N_messages = 0;
+var N_messages_max;
+var show_timestamp;
+var autoscroll;
+var messages_dom = document.getElementById('messages');
+
+// Generate a random client ID
+var client_id = 'MQTTWebClient' + parseInt(Math.random() * 100000);
+
+// When document is ready
+// --------------------
+ready(function(){
+ // Jquery ready
+ $(document).ready(function() {
+ $('#client-id').val(client_id);
+
+ // Disable buttons
+ $('#publish-msg-btn').prop('disabled', true);
+ $('#subscribe-msg-btn').prop('disabled', true);
+
+ // Terminal settings
+ $(document.body).on('click', '#show-timestamp', toggleShowTimestamp);
+ $(document.body).on('click', '#autoscroll-on', toggleAutoscroll);
+ $(document.body).on('click', '#terminal-options .timestamp',
+ toggleShowTimestamp);
+ $(document.body).on('click', '#terminal-options .autoscroll',
+ toggleAutoscroll);
+ $(document.body).on('blur', '#nMsgMax', changeMaxMessagesNum);
+ });
+
+ // Initialize options
+ initOptions();
+
+ // Initialize panels resize
+ window.addEventListener('resize', getPanelsSize);
+ var panels_bcr = $('#panels-container')[0].getBoundingClientRect();
+ panels_top = panels_bcr.top;
+ panels_left = panels_bcr.left;
+ panels_width = panels_bcr.width;
+ panels_height = panels_bcr.height;
+ initPanelsSize();
+ initPanelsResize();
+
+ // Show welcome message
+ showMessage('Welcome to PR-DC MQTTWebClient...');
+});
\ No newline at end of file
diff --git a/js/functions.js b/js/functions.js
new file mode 100644
index 0000000..d36a0f8
--- /dev/null
+++ b/js/functions.js
@@ -0,0 +1,245 @@
+/**
+ * MQTTWebClient - functions.js
+ * Author: Milos Petrasinovic
+ * PR-DC, Republic of Serbia
+ * info@pr-dc.com
+ *
+ * --------------------
+ * Copyright (C) 2021 PR-DC
+ *
+ * This file is part of PRDC_MQTTWebClient.
+ *
+ * PRDC_MQTTWebClient is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * PRDC_MQTTWebClient is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with PRDC_MQTTWebClient. If not, see .
+ *
+ */
+
+// ready() function
+// Call function when document is ready
+// --------------------
+function ready(fn) {
+ if(document.readyState != 'loading') {
+ fn();
+ } else {
+ document.addEventListener('DOMContentLoaded', fn);
+ }
+}
+
+// getTimestamp() function
+// Returns current timestamp in format HH:mm:SS.ms
+// --------------------
+function getTimestamp() {
+ var date = new Date();
+ var pad = function(num, size) {
+ return ('000' + num).slice(size * -1);
+ };
+ var time = parseFloat(date.getTime()/1000).toFixed(3);
+ var hours = date.getHours();
+ var minutes = Math.floor(time / 60) % 60;
+ var seconds = Math.floor(time - minutes * 60);
+ var milliseconds = time.slice(-3);
+
+ return pad(hours, 2) + ':' + pad(minutes, 2) + ':' +
+ pad(seconds, 2) + '.' + pad(milliseconds, 3);
+}
+
+// showTopCont() function
+// Show top options container
+// --------------------
+function showTopCont(id) {
+ $('#settings').css({'overflow': 'hidden'});
+ showCont('top-overlay-mask');
+ $('#'+id).height('auto');
+ showCont(id);
+}
+
+// hideTopCont() function
+// Hide top options container
+// --------------------
+function hideTopCont(id) {
+ $('#settings').css({'overflow': 'auto'});
+ hideCont(id);
+ $('#'+id).height(0);
+ hideCont('top-overlay-mask');
+}
+
+// showBotCont() function
+// Show bottom options container
+// --------------------
+function showBotCont(id) {
+ $('#messages-cont').css({'overflow': 'hidden'});
+ showCont('bottom-overlay-mask');
+ $('#'+id).height('auto');
+ showCont(id);
+}
+
+// hideBotCont() function
+// Hide bottom options container
+// --------------------
+function hideBotCont(id) {
+ $('#messages-cont').css({'overflow': 'auto'});
+ hideCont(id);
+ $('#'+id).height(0);
+ hideCont('bottom-overlay-mask');
+}
+
+// showCont() function
+// Show container
+// --------------------
+function showCont(id) {
+ var cont = document.getElementById(id);
+ cont.style.visibility = 'visible';
+ cont.style.opacity = 1;
+}
+
+// hideCont() function
+// Hide container
+// --------------------
+function hideCont(id) {
+ var cont = document.getElementById(id);
+ setTimeout(function() {
+ cont.style.visibility = 'hidden';
+ }, 350);
+ cont.style.opacity = 0;
+}
+
+// getPanelsSize() function
+// Get panels size
+// --------------------
+function getPanelsSize() {
+ var panels_bcr = document.getElementById('panels-container')
+ .getBoundingClientRect();
+ panels_width = panels_bcr.width;
+ panels_height = panels_bcr.height;
+}
+
+// initPanelsSize() function
+// Initialize panels size
+// --------------------
+function initPanelsSize() {
+ var panel_t_height_t = localStorage.getItem('panel_t_height')
+ if(panel_t_height_t) {
+ panel_t_height = panel_t_height_t;
+ }
+ var panel_b_height_t = localStorage.getItem('panel_b_height')
+ if(panel_b_height_t !== null) {
+ panel_b_height = panel_b_height_t;
+ }
+
+ $('#top-panel').height('calc('+panel_t_height+'% - 12.5px)');
+ $('#bottom-panel').height('calc('+panel_b_height+'% - 12.5px)');
+}
+
+// initPanelsResize() function
+// Initialize panels resize
+// --------------------
+function initPanelsResize() {
+ onDrag(document.getElementById('middle'), resizeTopBottom);
+}
+
+// onDrag() function
+// On element drag call funciton
+// --------------------
+function onDrag(el, fun) {
+ el.addEventListener('mousedown', function() {
+ document.addEventListener('mousemove', fun, false);
+ document.addEventListener('mouseup', function mouseUp() {
+ document.removeEventListener('mousemove', fun, false);
+ document.removeEventListener('mousemove', mouseUp, false);
+ }, false);
+ }, false);
+}
+
+// resizeTopBottom() function
+// Resize top and bottom pannels
+// --------------------
+function resizeTopBottom(e) {
+ var panel_t_height_t = (e.y-panels_top)/panels_height*100;
+ var panel_b_height_t = 100-panel_t_height_t;
+ if(panel_t_height_t >= 15 && panel_b_height_t >= 15) {
+ panel_t_height = panel_t_height_t;
+ panel_b_height = panel_b_height_t;
+ $('#top-panel').height('calc('+panel_t_height+'% - 12.5px)');
+ $('#bottom-panel').height('calc('+panel_b_height+'% - 12.5px)');
+ localStorage.setItem('panel_t_height', panel_t_height);
+ localStorage.setItem('panel_b_height', panel_b_height);
+ }
+}
+
+// updateStatus() function
+// Update status
+// --------------------
+function updateStatus(txt) {
+ $('#status').text(txt);
+}
+
+// messagesShow() function
+// Show messages panel
+// --------------------
+function messagesShow() {
+ $('#messages-container').removeClass('inactive');
+}
+
+// messagesHide() function
+// Hide messages panel
+// --------------------
+function messagesHide() {
+ $('#messages-container').addClass('inactive');
+
+ // Remove all messages
+ setTimeout(function() {
+ $('#messages-container .message').each(function() {
+ $(this).remove();
+ });
+ }, 200)
+};
+
+// updateMessagesScroll() function
+// Go to bottom of messages container
+// --------------------
+function updateMessagesScroll() {
+ var bcr = messages_dom.getBoundingClientRect();
+ messages_dom.parentElement.scrollTop = bcr.height;
+}
+
+// showMessage() function
+// Show message
+// --------------------
+function showMessage(msg) {
+ var timestamp = getTimestamp();
+ if(N_messages < N_messages_max) {
+ N_messages += 1;
+ } else {
+ messages_dom.firstChild.remove();
+ }
+
+ messages_dom.innerHTML +=
+ '' + timestamp + ' ' + msg + '
';
+ if(autoscroll) {
+ updateMessagesScroll();
+ }
+}
+
+// localStorage.setObj(), sessionStorage.setObj() function
+// Functions to store object in localStorage or sessionStorage
+// --------------------
+Storage.prototype.setObj = function(key, obj) {
+ return this.setItem(key, JSON.stringify(obj))
+}
+
+// localStorage.getObj(), sessionStorage.getObj() function
+// Functions to retrieve object from localStorage or sessionStorage
+// --------------------
+Storage.prototype.getObj = function(key) {
+ return JSON.parse(this.getItem(key))
+}
\ No newline at end of file
diff --git a/lib/jquery-3.5.1.min.js b/lib/jquery-3.5.1.min.js
new file mode 100644
index 0000000..b061403
--- /dev/null
+++ b/lib/jquery-3.5.1.min.js
@@ -0,0 +1,2 @@
+/*! jQuery v3.5.1 | (c) JS Foundation and other contributors | jquery.org/license */
+!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],r=Object.getPrototypeOf,s=t.slice,g=t.flat?function(e){return t.flat.call(e)}:function(e){return t.concat.apply([],e)},u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},E=C.document,c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.5.1",S=function(e,t){return new S.fn.init(e,t)};function p(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp(F),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+F),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\[\\da-fA-F]{1,6}"+M+"?|\\\\([^\\r\\n\\f])","g"),ne=function(e,t){var n="0x"+e.slice(1)-65536;return t||(n<0?String.fromCharCode(n+65536):String.fromCharCode(n>>10|55296,1023&n|56320))},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(p.childNodes),p.childNodes),t[p.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&(T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!N[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&(U.test(t)||z.test(t))){(f=ee.test(t)&&ye(e.parentNode)||e)===e&&d.scope||((s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=S)),o=(l=h(t)).length;while(o--)l[o]=(s?"#"+s:":scope")+" "+xe(l[o]);c=l.join(",")}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){N(t,!0)}finally{s===S&&e.removeAttribute("id")}}}return g(t.replace($,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[S]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:p;return r!=C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),p!=C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.scope=ce(function(e){return a.appendChild(e).appendChild(C.createElement("div")),"undefined"!=typeof e.querySelectorAll&&!e.querySelectorAll(":scope fieldset div").length}),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=S,!C.getElementsByName||!C.getElementsByName(S).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){var t;a.appendChild(e).innerHTML=" ",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+S+"-]").length||v.push("~="),(t=C.createElement("input")).setAttribute("name",""),e.appendChild(t),e.querySelectorAll("[name='']").length||v.push("\\["+M+"*name"+M+"*="+M+"*(?:''|\"\")"),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+S+"+*").length||v.push(".#.+[+~]"),e.querySelectorAll("\\\f"),v.push("[\\r\\n\\f]")}),ce(function(e){e.innerHTML=" ";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",F)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)==(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e==C||e.ownerDocument==p&&y(p,e)?-1:t==C||t.ownerDocument==p&&y(p,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e==C?-1:t==C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]==p?-1:s[r]==p?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if(T(e),d.matchesSelector&&E&&!N[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){N(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=m[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&m(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function D(e,n,r){return m(n)?S.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?S.grep(e,function(e){return e===n!==r}):"string"!=typeof n?S.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(S.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||j,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:q.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof S?t[0]:t,S.merge(this,S.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),N.test(r[1])&&S.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(S):S.makeArray(e,this)}).prototype=S.fn,j=S(E);var L=/^(?:parents|prev(?:Until|All))/,H={children:!0,contents:!0,next:!0,prev:!0};function O(e,t){while((e=e[t])&&1!==e.nodeType);return e}S.fn.extend({has:function(e){var t=S(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i;ce=E.createDocumentFragment().appendChild(E.createElement("div")),(fe=E.createElement("input")).setAttribute("type","radio"),fe.setAttribute("checked","checked"),fe.setAttribute("name","t"),ce.appendChild(fe),y.checkClone=ce.cloneNode(!0).cloneNode(!0).lastChild.checked,ce.innerHTML="",y.noCloneChecked=!!ce.cloneNode(!0).lastChild.defaultValue,ce.innerHTML=" ",y.option=!!ce.lastChild;var ge={thead:[1,""],col:[2,""],tr:[2,""],td:[3,""],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?S.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;n",""]);var me=/<|?\w+;/;function xe(e,t,n,r,i){for(var o,a,s,u,l,c,f=t.createDocumentFragment(),p=[],d=0,h=e.length;d\s*$/g;function qe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&S(e).children("tbody")[0]||e}function Le(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function He(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Oe(e,t){var n,r,i,o,a,s;if(1===t.nodeType){if(Y.hasData(e)&&(s=Y.get(e).events))for(i in Y.remove(t,"handle events"),s)for(n=0,r=s[i].length;n").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Ut,Xt=[],Vt=/(=)\?(?=&|$)|\?\?/;S.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Xt.pop()||S.expando+"_"+Ct.guid++;return this[e]=!0,e}}),S.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Vt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Vt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Vt,"$1"+r):!1!==e.jsonp&&(e.url+=(Et.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||S.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?S(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Xt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Ut=E.implementation.createHTMLDocument("").body).innerHTML="",2===Ut.childNodes.length),S.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=N.exec(e))?[t.createElement(i[1])]:(i=xe([e],t,o),o&&o.length&&S(o).remove(),S.merge([],i.childNodes)));var r,i,o},S.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(S.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},S.expr.pseudos.animated=function(t){return S.grep(S.timers,function(e){return t===e.elem}).length},S.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=S.css(e,"position"),c=S(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=S.css(e,"top"),u=S.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,S.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):("number"==typeof f.top&&(f.top+="px"),"number"==typeof f.left&&(f.left+="px"),c.css(f))}},S.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){S.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===S.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===S.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=S(e).offset()).top+=S.css(e,"borderTopWidth",!0),i.left+=S.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-S.css(r,"marginTop",!0),left:t.left-i.left-S.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===S.css(e,"position"))e=e.offsetParent;return e||re})}}),S.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;S.fn[t]=function(e){return $(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),S.each(["top","left"],function(e,n){S.cssHooks[n]=$e(y.pixelPosition,function(e,t){if(t)return t=Be(e,n),Me.test(t)?S(e).position()[n]+"px":t})}),S.each({Height:"height",Width:"width"},function(a,s){S.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){S.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return $(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?S.css(e,t,i):S.style(e,t,n,i)},s,n?e:void 0,n)}})}),S.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){S.fn[t]=function(e){return this.on(t,e)}}),S.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),S.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){S.fn[n]=function(e,t){return 0>8;b[c++]=a%256;return c}function u(a,b,c,k){k=s(b,c,k);D(a,c,k);return k+b}function n(a){for(var b=0,c=0;c=k&&(c++,b++),b+=3):127=e){var g=a.charCodeAt(++k);if(isNaN(g))throw Error(f(h.MALFORMED_UNICODE,[e,g]));e=(e-55296<<10)+(g-56320)+65536}127>=e?b[c++]=e:(2047>=e?b[c++]=e>>6&31|192:(65535>=e?b[c++]=e>>12&15|224:(b[c++]=e>>18&7|240,b[c++]=e>>12&63|128),b[c++]=e>>6&63|128),b[c++]=e&63|128)}return b}function E(a,b,c){for(var k="",e,g=b;ge)){var m=a[g++]-128;if(0>m)throw Error(f(h.MALFORMED_UTF,[e.toString(16),m.toString(16),
+""]));if(224>e)e=64*(e-192)+m;else{var d=a[g++]-128;if(0>d)throw Error(f(h.MALFORMED_UTF,[e.toString(16),m.toString(16),d.toString(16)]));if(240>e)e=4096*(e-224)+64*m+d;else{var l=a[g++]-128;if(0>l)throw Error(f(h.MALFORMED_UTF,[e.toString(16),m.toString(16),d.toString(16),l.toString(16)]));if(248>e)e=262144*(e-240)+4096*m+64*d+l;else throw Error(f(h.MALFORMED_UTF,[e.toString(16),m.toString(16),d.toString(16),l.toString(16)]));}}}65535>10)),e=56320+(e&
+1023));k+=String.fromCharCode(e)}return k}var z=function(a,b){for(var c in a)if(a.hasOwnProperty(c))if(b.hasOwnProperty(c)){if(typeof a[c]!==b[c])throw Error(f(h.INVALID_TYPE,[typeof a[c],c]));}else{c="Unknown property, "+c+". Valid properties are:";for(var k in b)b.hasOwnProperty(k)&&(c=c+" "+k);throw Error(c);}},v=function(a,b){return function(){return a.apply(b,arguments)}},h={OK:{code:0,text:"AMQJSC0000I OK."},CONNECT_TIMEOUT:{code:1,text:"AMQJSC0001E Connect timed out."},SUBSCRIBE_TIMEOUT:{code:2,
+text:"AMQJS0002E Subscribe timed out."},UNSUBSCRIBE_TIMEOUT:{code:3,text:"AMQJS0003E Unsubscribe timed out."},PING_TIMEOUT:{code:4,text:"AMQJS0004E Ping timed out."},INTERNAL_ERROR:{code:5,text:"AMQJS0005E Internal error. Error Message: {0}, Stack trace: {1}"},CONNACK_RETURNCODE:{code:6,text:"AMQJS0006E Bad Connack return code:{0} {1}."},SOCKET_ERROR:{code:7,text:"AMQJS0007E Socket error:{0}."},SOCKET_CLOSE:{code:8,text:"AMQJS0008I Socket closed."},MALFORMED_UTF:{code:9,text:"AMQJS0009E Malformed UTF data:{0} {1} {2}."},
+UNSUPPORTED:{code:10,text:"AMQJS0010E {0} is not supported by this browser."},INVALID_STATE:{code:11,text:"AMQJS0011E Invalid state {0}."},INVALID_TYPE:{code:12,text:"AMQJS0012E Invalid type {0} for {1}."},INVALID_ARGUMENT:{code:13,text:"AMQJS0013E Invalid argument {0} for {1}."},UNSUPPORTED_OPERATION:{code:14,text:"AMQJS0014E Unsupported operation."},INVALID_STORED_DATA:{code:15,text:"AMQJS0015E Invalid data in local storage key\x3d{0} value\x3d{1}."},INVALID_MQTT_MESSAGE_TYPE:{code:16,text:"AMQJS0016E Invalid MQTT message type {0}."},
+MALFORMED_UNICODE:{code:17,text:"AMQJS0017E Malformed Unicode string:{0} {1}."},BUFFER_FULL:{code:18,text:"AMQJS0018E Message buffer is full, maximum buffer size: {0}."}},H={0:"Connection Accepted",1:"Connection Refused: unacceptable protocol version",2:"Connection Refused: identifier rejected",3:"Connection Refused: server unavailable",4:"Connection Refused: bad user name or password",5:"Connection Refused: not authorized"},f=function(a,b){var c=a.text;if(b)for(var k,e,g=0;g>7;0d);f=g.length+1;b=new ArrayBuffer(b+f);d=new Uint8Array(b);d[0]=a;d.set(g,1);if(3==this.type)f=u(this.payloadMessage.destinationName,k,d,f);else if(1==this.type){switch(this.mqttVersion){case 3:d.set(A,f);f+=A.length;
+break;case 4:d.set(B,f),f+=B.length}a=0;this.cleanSession&&(a=2);void 0!==this.willMessage&&(a=a|4|this.willMessage.qos<<3,this.willMessage.retained&&(a|=32));void 0!==this.userName&&(a|=128);void 0!==this.password&&(a|=64);d[f++]=a;f=s(this.keepAliveInterval,d,f)}void 0!==this.messageIdentifier&&(f=s(this.messageIdentifier,d,f));switch(this.type){case 1:f=u(this.clientId,n(this.clientId),d,f);void 0!==this.willMessage&&(f=u(this.willMessage.destinationName,n(this.willMessage.destinationName),d,f),
+f=s(e.byteLength,d,f),d.set(e,f),f+=e.byteLength);void 0!==this.userName&&(f=u(this.userName,n(this.userName),d,f));void 0!==this.password&&u(this.password,n(this.password),d,f);break;case 3:d.set(h,f);break;case 8:for(g=0;gthis.disconnectedBufferSize)throw Error(f(h.BUFFER_FULL,
+[this.disconnectedBufferSize]));0this.connectOptions.mqttVersion?new WebSocket(a,["mqttv3.1"]):new WebSocket(a,["mqtt"]);this.socket.binaryType="arraybuffer";this.socket.onopen=v(this._on_socket_open,this);this.socket.onmessage=v(this._on_socket_message,
+this);this.socket.onerror=v(this._on_socket_error,this);this.socket.onclose=v(this._on_socket_close,this);this.sendPinger=new F(this,window,this.connectOptions.keepAliveInterval);this.receivePinger=new F(this,window,this.connectOptions.keepAliveInterval);this._connectTimeout&&(this._connectTimeout.cancel(),this._connectTimeout=null);this._connectTimeout=new w(this,window,this.connectOptions.timeout,this._disconnected,[h.CONNECT_TIMEOUT.code,f(h.CONNECT_TIMEOUT)])};d.prototype._schedule_message=function(a){this._msg_queue.push(a);
+this.connected&&this._process_queue()};d.prototype.store=function(a,b){var c={type:b.type,messageIdentifier:b.messageIdentifier,version:1};switch(b.type){case 3:b.pubRecReceived&&(c.pubRecReceived=!0);c.payloadMessage={};for(var d="",e=b.payloadMessage.payloadBytes,g=0;g=e[g]?d+"0"+e[g].toString(16):d+e[g].toString(16);c.payloadMessage.payloadHex=d;c.payloadMessage.qos=b.payloadMessage.qos;c.payloadMessage.destinationName=b.payloadMessage.destinationName;b.payloadMessage.duplicate&&
+(c.payloadMessage.duplicate=!0);b.payloadMessage.retained&&(c.payloadMessage.retained=!0);0===a.indexOf("Sent:")&&(void 0===b.sequence&&(b.sequence=++this._sequence),c.sequence=b.sequence);break;default:throw Error(f(h.INVALID_STORED_DATA,[key,c]));}localStorage.setItem(a+this._localKey+b.messageIdentifier,JSON.stringify(c))};d.prototype.restore=function(a){var b=localStorage.getItem(a),c=JSON.parse(b),d=new q(c.type,c);switch(c.type){case 3:for(var b=c.payloadMessage.payloadHex,e=new ArrayBuffer(b.length/
+2),e=new Uint8Array(e),g=0;2<=b.length;){var m=parseInt(b.substring(0,2),16),b=b.substring(2,b.length);e[g++]=m}b=new Paho.MQTT.Message(e);b.qos=c.payloadMessage.qos;b.destinationName=c.payloadMessage.destinationName;c.payloadMessage.duplicate&&(b.duplicate=!0);c.payloadMessage.retained&&(b.retained=!0);d.payloadMessage=b;break;default:throw Error(f(h.INVALID_STORED_DATA,[a,b]));}0===a.indexOf("Sent:"+this._localKey)?(d.payloadMessage.duplicate=!0,this._sentMessages[d.messageIdentifier]=d):0===a.indexOf("Received:"+
+this._localKey)&&(this._receivedMessages[d.messageIdentifier]=d)};d.prototype._process_queue=function(){for(var a=null,b=this._msg_queue.reverse();a=b.pop();)this._socket_send(a),this._notify_msg_sent[a]&&(this._notify_msg_sent[a](),delete this._notify_msg_sent[a])};d.prototype._requires_ack=function(a){var b=Object.keys(this._sentMessages).length;if(b>this.maxMessageIdentifier)throw Error("Too many messages:"+b);for(;void 0!==this._sentMessages[this._message_identifier];)this._message_identifier++;
+a.messageIdentifier=this._message_identifier;this._sentMessages[a.messageIdentifier]=a;3===a.type&&this.store("Sent:",a);this._message_identifier===this.maxMessageIdentifier&&(this._message_identifier=1)};d.prototype._on_socket_open=function(){var a=new q(1,this.connectOptions);a.clientId=this.clientId;this._socket_send(a)};d.prototype._on_socket_message=function(a){this._trace("Client._on_socket_message",a.data);a=this._deframeMessages(a.data);for(var b=0;b>4,t=n&15,g=g+1,x=void 0,C=0,p=1;do{if(g==e.length){d=[null,m];break a}x=e[g++];C+=(x&127)*p;p*=128}while(0!==(x&128));x=g+C;if(x>e.length)d=[null,m];else{var y=new q(l);switch(l){case 2:e[g++]&1&&(y.sessionPresent=
+!0);y.returnCode=e[g++];break;case 3:var m=t>>1&3,s=256*e[g]+e[g+1],g=g+2,u=E(e,g,s),g=g+s;0this._reconnectInterval&&(this._reconnectInterval*=2),this.connectOptions.uris?(this.hostIndex=0,this._doConnect(this.connectOptions.uris[0])):this._doConnect(this.uri))};d.prototype._disconnected=function(a,b){this._trace("Client._disconnected",a,b);if(void 0!==a&&this._reconnecting)this._reconnectTimeout=new w(this,window,this._reconnectInterval,this._reconnect);
+else if(this.sendPinger.cancel(),this.receivePinger.cancel(),this._connectTimeout&&(this._connectTimeout.cancel(),this._connectTimeout=null),this._msg_queue=[],this._buffered_msg_queue=[],this._notify_msg_sent={},this.socket&&(this.socket.onopen=null,this.socket.onmessage=null,this.socket.onerror=null,this.socket.onclose=null,1===this.socket.readyState&&this.socket.close(),delete this.socket),this.connectOptions.uris&&this.hostIndexb)throw Error(f(h.INVALID_TYPE,[typeof b,"port"]));if("string"!==typeof c)throw Error(f(h.INVALID_TYPE,[typeof c,"path"]));e="ws://"+(-1!==a.indexOf(":")&&"["!==a.slice(0,1)&&"]"!==a.slice(-1)?"["+a+"]":a)+":"+b+c}for(var m=
+g=0;m=n&&m++;g++}if("string"!==typeof k||65535a.mqttVersion)throw Error(f(h.INVALID_ARGUMENT,[a.mqttVersion,"connectOptions.mqttVersion"]));void 0===
+a.mqttVersion?(a.mqttVersionExplicit=!1,a.mqttVersion=4):a.mqttVersionExplicit=!0;if(void 0!==a.password&&void 0===a.userName)throw Error(f(h.INVALID_ARGUMENT,[a.password,"connectOptions.password"]));if(a.willMessage){if(!(a.willMessage instanceof r))throw Error(f(h.INVALID_TYPE,[a.willMessage,"connectOptions.willMessage"]));a.willMessage.stringPayload=null;if("undefined"===typeof a.willMessage.destinationName)throw Error(f(h.INVALID_TYPE,[typeof a.willMessage.destinationName,"connectOptions.willMessage.destinationName"]));
+}"undefined"===typeof a.cleanSession&&(a.cleanSession=!0);if(a.hosts){if(!(a.hosts instanceof Array))throw Error(f(h.INVALID_ARGUMENT,[a.hosts,"connectOptions.hosts"]));if(1>a.hosts.length)throw Error(f(h.INVALID_ARGUMENT,[a.hosts,"connectOptions.hosts"]));for(var b=!1,d=0;da.ports[d])throw Error(f(h.INVALID_TYPE,[typeof a.ports[d],"connectOptions.ports["+d+"]"]));var b=a.hosts[d],g=a.ports[d];e="ws://"+(-1!==b.indexOf(":")?"["+b+"]":b)+":"+g+c;a.uris.push(e)}}}l.connect(a)};this.subscribe=function(a,b){if("string"!==typeof a)throw Error("Invalid argument:"+a);b=b||{};z(b,{qos:"number",invocationContext:"object",onSuccess:"function",onFailure:"function",timeout:"number"});if(b.timeout&&!b.onFailure)throw Error("subscribeOptions.timeout specified with no onFailure callback.");
+if("undefined"!==typeof b.qos&&0!==b.qos&&1!==b.qos&&2!==b.qos)throw Error(f(h.INVALID_ARGUMENT,[b.qos,"subscribeOptions.qos"]));l.subscribe(a,b)};this.unsubscribe=function(a,b){if("string"!==typeof a)throw Error("Invalid argument:"+a);b=b||{};z(b,{invocationContext:"object",onSuccess:"function",onFailure:"function",timeout:"number"});if(b.timeout&&!b.onFailure)throw Error("unsubscribeOptions.timeout specified with no onFailure callback.");l.unsubscribe(a,b)};this.send=function(a,b,c,d){var e;if(0===
+arguments.length)throw Error("Invalid argument.length");if(1==arguments.length){if(!(a instanceof r)&&"string"!==typeof a)throw Error("Invalid argument:"+typeof a);e=a;if("undefined"===typeof e.destinationName)throw Error(f(h.INVALID_ARGUMENT,[e.destinationName,"Message.destinationName"]));}else e=new r(b),e.destinationName=a,3<=arguments.length&&(e.qos=c),4<=arguments.length&&(e.retained=d);l.send(e)};this.publish=function(a,b,c,d){console.log("Publising message to: ",a);var e;if(0===arguments.length)throw Error("Invalid argument.length");
+if(1==arguments.length){if(!(a instanceof r)&&"string"!==typeof a)throw Error("Invalid argument:"+typeof a);e=a;if("undefined"===typeof e.destinationName)throw Error(f(h.INVALID_ARGUMENT,[e.destinationName,"Message.destinationName"]));}else e=new r(b),e.destinationName=a,3<=arguments.length&&(e.qos=c),4<=arguments.length&&(e.retained=d);l.send(e)};this.disconnect=function(){l.disconnect()};this.getTraceLog=function(){return l.getTraceLog()};this.startTrace=function(){l.startTrace()};this.stopTrace=
+function(){l.stopTrace()};this.isConnected=function(){return l.connected}};G.prototype={get host(){return this._getHost()},set host(a){this._setHost(a)},get port(){return this._getPort()},set port(a){this._setPort(a)},get path(){return this._getPath()},set path(a){this._setPath(a)},get clientId(){return this._getClientId()},set clientId(a){this._setClientId(a)},get onConnected(){return this._getOnConnected()},set onConnected(a){this._setOnConnected(a)},get disconnectedPublishing(){return this._getDisconnectedPublishing()},
+set disconnectedPublishing(a){this._setDisconnectedPublishing(a)},get disconnectedBufferSize(){return this._getDisconnectedBufferSize()},set disconnectedBufferSize(a){this._setDisconnectedBufferSize(a)},get onConnectionLost(){return this._getOnConnectionLost()},set onConnectionLost(a){this._setOnConnectionLost(a)},get onMessageDelivered(){return this._getOnMessageDelivered()},set onMessageDelivered(a){this._setOnMessageDelivered(a)},get onMessageArrived(){return this._getOnMessageArrived()},set onMessageArrived(a){this._setOnMessageArrived(a)},
+get trace(){return this._getTrace()},set trace(a){this._setTrace(a)}};var r=function(a){var b;if("string"===typeof a||a instanceof ArrayBuffer||a instanceof Int8Array||a instanceof Uint8Array||a instanceof Int16Array||a instanceof Uint16Array||a instanceof Int32Array||a instanceof Uint32Array||a instanceof Float32Array||a instanceof Float64Array)b=a;else throw f(h.INVALID_ARGUMENT,[a,"newPayload"]);this._getPayloadString=function(){return"string"===typeof b?b:E(b,0,b.length)};this._getPayloadBytes=
+function(){if("string"===typeof b){var a=new ArrayBuffer(n(b)),a=new Uint8Array(a);D(b,a,0);return a}return b};var c;this._getDestinationName=function(){return c};this._setDestinationName=function(a){if("string"===typeof a)c=a;else throw Error(f(h.INVALID_ARGUMENT,[a,"newDestinationName"]));};var d=0;this._getQos=function(){return d};this._setQos=function(a){if(0===a||1===a||2===a)d=a;else throw Error("Invalid argument:"+a);};var e=!1;this._getRetained=function(){return e};this._setRetained=function(a){if("boolean"===
+typeof a)e=a;else throw Error(f(h.INVALID_ARGUMENT,[a,"newRetained"]));};var g=!1;this._getDuplicate=function(){return g};this._setDuplicate=function(a){g=a}};r.prototype={get payloadString(){return this._getPayloadString()},get payloadBytes(){return this._getPayloadBytes()},get destinationName(){return this._getDestinationName()},set destinationName(a){this._setDestinationName(a)},get topic(){return this._getDestinationName()},set topic(a){this._setDestinationName(a)},get qos(){return this._getQos()},
+set qos(a){this._setQos(a)},get retained(){return this._getRetained()},set retained(a){this._setRetained(a)},get duplicate(){return this._getDuplicate()},set duplicate(a){this._setDuplicate(a)}};return{Client:G,Message:r}}(window)});
\ No newline at end of file