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
+
+ + +
+
+ + +
+
+ + +
+ +
+ +
+ + +
+
+ + +
+ +
MQTT Client
+ + +
+
+
+
+ +
+ +
+
+
+ Advanced settings + +
+
+ + +
+
+ + +
+ + +
+ + +
+
+ + +
+
+
+ + +
+ +
+
+ +
+
+
+ Publish message + +
+ + +
+ + +
+
+ + +
+
+
+ + +
+ +
+
+
+ +
+
+
+ Subscribe to topic + +
+ +
    +
    No subscribed topics
    +
+
+ + +
+
+ + +
+
+ +
+
+ +
+
+ +
+
Terminal
+
+ + + +
+
+ +
+
+
+
+ +
+ +
+
+
+ Terminal settings + +
+ +
+ + +
+ + +
+
+
+
+ +
+
+ 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