Fixed site minification.

Ylian Saint-Hilaire committed Mar 26, 2019 at 00:14 UTC d11210a8c873385f4e8da055c3ca47ba9c37be18
11 files changed +35 -17324
db.js
+1 -1
@@ -410,7 +410,7 @@ module.exports.CreateDB = function (parent) {
410 obj.file.count({ type: 'mesh' }, function (err, meshCount) {
411 obj.file.count({ type: 'user' }, function (err, userCount) {
412 obj.file.count({}, function (err, totalCount) {
413 - func({ nodes: nodeCount, meshes: meshCount, powerEvents: powerCount, users: userCount, nodeInterfaces: nodeInterfaceCount, notes: noteCount, connectEvent: nodeLastConnectCount, smbios: nodeSmbiosCount, total: totalCount });
413 + func({ nodes: nodeCount, meshes: meshCount, users: userCount, total: totalCount });
414 });
415 });
416 });
meshcentral.js
-3
@@ -818,9 +818,6 @@ function CreateMeshCentralServer(config, args) {
818 if (obj.mpsserver != null) { data.conn.am = Object.keys(obj.mpsserver.ciraConnections).length; }
819 obj.db.SetServerStats(data);
820 });
821 -
822 -
823 -
821 }, 300000);
822
823 //obj.debug(1, 'Server started');
package.json
+1 -1
@@ -1,6 +1,6 @@
1 {
2 "name": "meshcentral",
3 - "version": "0.3.1-c",
3 + "version": "0.3.1-e",
4 "keywords": [
5 "Remote Management",
6 "Intel AMT",
views/default-min.handlebars
+1 -13940
@@ -1,13940 +1 @@
1 -<!DOCTYPE html> <html dir="ltr" xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta content="text/html;charset=utf-8" http-equiv="Content-Type"> <meta name="viewport" content="user-scalable=1.0,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="format-detection" content="telephone=no"> <style>body{margin:0;padding:0;border:0;color:black;font-size:13px;font-family:"Trebuchet MS", Arial, Helvetica, sans-serif;background-color:#d3d9d6;}#container{background-color:#fff;width:960px;min-width:960px;margin:0 auto;border-top:0;border-right:1px solid #b7b7b7;border-bottom:0;border-left:1px solid #b7b7b7;padding:0;}#masthead{width:auto;margin:0;padding:0;overflow:auto;text-align:right;background-color:#036;width:960px;}#column_l{position:relative;float:left;width:930px;margin:0;padding:0 15px;background-color:#fff;}#footer{clear:both;overflow:auto;width:100%;text-align:center;background-color:#113962;padding-top:5px;padding-bottom:5px;}#masthead img{float:left;}#masthead p{font-size:11px;color:#fff;margin:10px 10px 0;}#footer a{color:#fff;text-decoration:underline;}#footer a:hover{color:#fff;text-decoration:none;}a{color:#036;text-decoration:underline;}.i1{background:url(../images/icons50.png) 0px 0px;height:50px;width:50px;cursor:pointer;border:none;}.i2{background:url(../images/icons50.png) -50px 0px;height:50px;width:50px;cursor:pointer;border:none;}.i3{background:url(../images/icons50.png) -100px 0px;height:50px;width:50px;cursor:pointer;border:none;}.i4{background:url(../images/icons50.png) -150px 0px;height:50px;width:50px;cursor:pointer;border:none;}.i5{background:url(../images/icons50.png) -200px 0px;height:50px;width:50px;cursor:pointer;border:none;}.i6{background:url(../images/icons50.png) -250px 0px;height:50px;width:50px;cursor:pointer;border:none;}.j1{background:url(../images/icons16.png) 0px 0px;height:16px;width:16px;cursor:pointer;border:none;}.j2{background:url(../images/icons16.png) -16px 0px;height:16px;width:16px;cursor:pointer;border:none;}.j3{background:url(../images/icons16.png) -32px 0px;height:16px;width:16px;cursor:pointer;border:none;}.j4{background:url(../images/icons16.png) -48px 0px;height:16px;width:16px;cursor:pointer;border:none;}.j5{background:url(../images/icons16.png) -64px 0px;height:16px;width:16px;cursor:pointer;border:none;}.j6{background:url(../images/icons16.png) -80px 0px;height:16px;width:16px;cursor:pointer;border:none;}.lbbutton{width:74px;height:74px;border-radius:5px;background-color:white;margin-left:8px;margin-top:8px;position:relative;cursor:pointer;opacity:0.5;}.lbbutton:hover{opacity:1;}.lbbuttonsel{opacity:0.9;}.lbbuttonsel2{width:82px;border-radius:5px 0px 0px 5px;opacity:1;}.lb1{background:url(../images/leftbar-62.jpg) -0px 0px;height:62px;width:62px;cursor:pointer;border:none;}.lb2{background:url(../images/leftbar-62.jpg) -75px 0px;height:62px;width:62px;cursor:pointer;border:none;}.lb3{background:url(../images/leftbar-62.jpg) -150px 0px;height:62px;width:62px;cursor:pointer;border:none;}.lb4{background:url(../images/leftbar-62.jpg) -225px 0px;height:62px;width:62px;cursor:pointer;border:none;}.lb5{background:url(../images/leftbar-62.jpg) -294px 0px;height:62px;width:62px;cursor:pointer;border:none;}.lb6{background:url(../images/leftbar-62.jpg) -360px 0px;height:62px;width:62px;cursor:pointer;border:none;}.m0{background :url(../images/images16.png) -32px 0px;height :16px;width :16px;border:none;float:left }.m1{background :url(../images/images16.png) -16px 0px;height :16px;width :16px;border:none;float:left }.m2{background :url(../images/images16.png) -96px 0px;height :16px;width :16px;border:none;float:left }.m3{background :url(../images/images16.png) -112px 0px;height :16px;width :16px;border:none;float:left }.si0{background :url(../images/icons16.png) 0px 0px;height :16px;width :16px;border:none;float:left }.si1{background :url(../images/icons16.png) -16px 0px;height :16px;width :16px;border:none;float:left }.si2{background :url(../images/icons16.png) -32px 0px;height :16px;width :16px;border:none;float:left }.si3{background :url(../images/icons16.png) -48px 0px;height :16px;width :16px;border:none;float:left }.si4{background :url(../images/icons16.png) -64px 0px;height :16px;width :16px;border:none;float:left }.mi{background :url(../images/meshicon50.png) 0px 0px;height:50px;width:50px;cursor:pointer;border:none }#floatframe{position:fixed;top:200px;height:300px;z-index:200;display:none;}.style1{text-align:center;}.style2{text-align:center;background-color:#808080;font-weight:bold;}.style3{text-align:center;color:white;background-color:#808080;font-weight:bold;}.style3x{text-align:center;color:white;background-color:#808080;font-weight:bold;}.style3x:hover{background-color:#606060;}.style3sel{text-align:center;color:white;background-color:#003366;font-weight:bold;}.style4{color:white;text-decoration:none;}.style5{text-align:center;background-color:#808080;font-weight:normal;}.style6{text-align:center;background-color:#D3D9D6;}.style7{font-size:large;background-color:#FFFFFF;}.style10{background-color:#C9C9C9;}.style11{font-size:large;background-color:#C9C9C9;}.style14{text-align:left;background-color:#D3D9D6;}.auto-style1{text-align:right;background-color:#D3D9D6;}.fileIcon1{background:url(data:image/gif;base64,R0lGODlhEAAQAJEDAPb49Y2Sj9LT2f///yH5BAEAAAMALAAAAAAQABAAAAImnI+py+1vhJwyUYAzHTL4D3qdlJWaIFJqmKod607sDKIiDUP63hQAOw==);height:16px;width:16px;cursor:pointer;border:none;float:left;margin-top:1px;}.fileIcon2{background:url(data:image/gif;base64,R0lGODlhEAAQAJEDAM2xV/Xur+XPgP///yH5BAEAAAMALAAAAAAQABAAAAJD3ISZIGHWUGihznesYDYATFVM+D2hJ4lgN1olxALAtAlmPCJvuMmJd6PJckDYwicrHhTD5o7plJmg0Uc0asNMkphHAQA7);height:16px;width:16px;cursor:pointer;border:none;float:left;margin-top:1px;}.fileIcon3{background:url(data:image/gif;base64,R0lGODlhEAAQAJEDAPb19IGBgbq6uv///yH5BAEAAAMALAAAAAAQABAAAAIy3ISpxgcPH2ouQgFEw1YmxnUXKEaaEZZnVWZk66JwzKpvuwZzwOgwb/C1gIOA8Yg8DgoAOw==);height:16px;width:16px;cursor:pointer;border:none;float:left;margin-top:1px;}.fileIcon4{background:url(../images/meshicon16.png);height:16px;width:16px;cursor:pointer;border:none;float:left;margin-top:1px;}.filelist{-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none;cursor:default;-khtml-user-drag:element;background-color:white;clear:both;}.noselect{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}.fsize{float:right;text-align:right;width:180px;}.g1{background-position:0% 0%;width:14px;height:100%;float:left; background-image:linear-gradient(to right, #ffffff 0%, #c9c9c9 100%);background-color:#c9c9c9;background-repeat:repeat;background-attachment:scroll;}.g1s{background-image:linear-gradient(to right, #ffffff 0%, #b9b9b9 100%);}.g2{background-position:0% 0%;width:14px;height:100%;float:right; background-image:linear-gradient(to right, #c9c9c9 0%, #ffffff 100%);background-color:#c9c9c9;background-repeat:repeat;background-attachment:scroll;}.g2s{background-image:linear-gradient(to right, #b9b9b9 0%, #ffffff 100%);}.h1{background-position:0% 0%;width:14px;height:100%; background-image:linear-gradient(to right, #ffffff 0%, #d3d9d6 100%);background-color:#d3d9d6;background-repeat:repeat;background-attachment:scroll;}.h2{background-position:0% 0%;width:14px;height:100%; background-image:linear-gradient(to right, #d3d9d6 0%, #ffffff 100%);background-color:#d3d9d6;background-repeat:repeat;background-attachment:scroll;}.e1{font-size:large;margin-top:4px;margin-bottom:3px;overflow:hidden;word-wrap:hyphenate;white-space:nowrap;text-overflow:ellipsis;}.e2{float:left;height:100%;background-color:#c9c9c9;}.e2s{background-color:#b9b9b9;}.bar{font-size:large;background-color:#C9C9C9;height:24px;float:left;margin-bottom:2px;}.bar2{font-size:large;height:24px;float:left;margin-bottom:2px;}.bar18{font-size:large;background-color:#C9C9C9;height:18px;float:left;margin-bottom:2px;}.bar182{font-size:large;height:18px;float:left;margin-bottom:2px;}.devHeaderx{color:lightgray;}.DevSt{border-bottom-style:solid;border-bottom-width:1px;border-bottom-color:#DDDDDD;}.contextMenu{background:#F9F9F9;box-shadow:0 0 12px rgba( 0, 0, 0, .3 );border:1px solid #ccc; display:none;position:absolute;top:0;left:0;list-style:none;margin:0;padding:5px;min-width:100px;max-width:150px;z-index:500;}.cmtext{color:#444;display:inline-block;padding-left:8px;padding-right:8px;padding-top:5px;padding-bottom:5px;text-decoration:none;width:85%;cursor:default;overflow:hidden;position:relative;}.cmtext:hover{color:#f9f9f9;background:#444;}.gray{ filter:gray; -webkit-filter:grayscale(100%) opacity(60%); }.unselectable{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}.notifiyBox{position:absolute;z-index:1000;top:50px;right:26px;width:300px;text-align:left;background-color:#F0ECCD;border:4px solid #666;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;-webkit-box-shadow:2px 2px 4px #888;-moz-box-shadow:2px 2px 4px #888;box-shadow:2px 2px 4px #888;max-height:200px;}.notifiyBox:before{content:' ';position:absolute;width:0;height:0;right:5px;top:-30px;border:15px solid;border-color:transparent #666 #666 transparent;}.notifiyBox:after{content:' ';position:absolute;width:0;height:0;right:7px;top:-24px;border:12px solid;border-color:transparent #F0ECCD #F0ECCD transparent;}.notification{width:100%;min-height:30px;}.notification:hover{background-color:#EFE8B6;}.deskToolsBar{padding:3px;}.deskToolsBar:hover{background-color:#EFE8B6;}.userTableHeader{border-bottom:1pt solid lightgray;padding-top:4px;padding-bottom:4px;}.viewSelector{width:32px;height:32px;background-color:#DDD;border-radius:3px;float:left;margin-left:5px;cursor:pointer;opacity:0.3;}.viewSelectorSel{background-color:#BBB;opacity:0.8;}.viewSelector:hover{opacity:0.5;background-color:#AAA;}.viewSelector1{margin-left:2px;margin-top:2px;background:url(../images/views.png) -0px 0px;height:28px;width:28px;}.viewSelector2{margin-left:2px;margin-top:2px;background:url(../images/views.png) -28px 0px;height:28px;width:28px;}.viewSelector3{margin-left:2px;margin-top:2px;background:url(../images/views.png) -56px 0px;height:28px;width:28px;}.viewSelector4{margin-left:2px;margin-top:2px;background:url(../images/views.png) -84px 0px;height:28px;width:28px;}.viewSelector5{margin-left:2px;margin-top:2px;background:url(../images/views.png) -112px 0px;height:28px;width:28px;}.backButtonEx{margin-left:2px;margin-top:2px;background:url(../images/views.png) -140px 0px;height:28px;width:28px;}.backButton{width:32px;height:32px;background-color:#DDD;border-radius:3px;float:left;margin-right:5px;cursor:pointer;opacity:0.3;}.backButton:hover{opacity:0.5;background-color:#AAA;}.hoverButton{opacity:0.5;}.hoverButton:hover{opacity:1;}</style> <style>.ol-box{box-sizing:border-box;border-radius:2px;border:2px solid #00f;}.ol-mouse-position{top:8px;right:8px;position:absolute;}.ol-scale-line{background:rgba(0,60,136,.3);border-radius:4px;bottom:8px;left:8px;padding:2px;position:absolute;}.ol-scale-line-inner{border:1px solid #eee;border-top:none;color:#eee;font-size:10px;text-align:center;margin:1px;will-change:contents,width;}.ol-overlay-container{will-change:left,right,top,bottom;}.ol-unsupported{display:none;}.ol-unselectable, .ol-viewport{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;}.ol-selectable{-webkit-touch-callout:default;-webkit-user-select:auto;-moz-user-select:auto;-ms-user-select:auto;user-select:auto;}.ol-grabbing{cursor:-webkit-grabbing;cursor:-moz-grabbing;cursor:grabbing;}.ol-grab{cursor:move;cursor:-webkit-grab;cursor:-moz-grab;cursor:grab;}.ol-control{position:absolute;background-color:rgba(255,255,255,.4);border-radius:4px;padding:2px;}.ol-control:hover{background-color:rgba(255,255,255,.6);}.ol-zoom{top:.5em;right:.5em;}.ol-rotate{top:.5em;right:.5em;transition:opacity .25s linear,visibility 0s linear;}.ol-rotate.ol-hidden{opacity:0;visibility:hidden;transition:opacity .25s linear,visibility 0s linear .25s;}.ol-zoom-extent{top:4.643em;left:.5em;}.ol-full-screen{right:.5em;top:.5em;}@media print{.ol-control{display:none;}}.ol-control button{display:block;margin:1px;padding:0;color:#fff;font-size:1.14em;font-weight:700;text-decoration:none;text-align:center;height:1.375em;width:1.375em;line-height:.4em;background-color:rgba(0,60,136,.5);border:none;border-radius:2px;}.ol-control button::-moz-focus-inner{border:none;padding:0;}.ol-zoom-extent button{line-height:1.4em;}.ol-compass{display:block;font-weight:400;font-size:1.2em;will-change:transform;}.ol-touch .ol-control button{font-size:1.5em;}.ol-touch .ol-zoom-extent{top:5.5em;}.ol-control button:focus, .ol-control button:hover{text-decoration:none;background-color:rgba(0,60,136,.7);}.ol-zoom .ol-zoom-in{border-radius:2px 2px 0 0;}.ol-zoom .ol-zoom-out{border-radius:0 0 2px 2px;}.ol-attribution{text-align:right;bottom:.5em;right:.5em;max-width:calc(100% - 1.3em);}.ol-attribution ul{margin:0;padding:0 .5em;font-size:.7rem;line-height:1.375em;color:#000;text-shadow:0 0 2px #fff;}.ol-attribution li{display:inline;list-style:none;line-height:inherit;}.ol-attribution li:not(:last-child):after{content:" ";}.ol-attribution img{max-height:2em;max-width:inherit;vertical-align:middle;}.ol-attribution button, .ol-attribution ul{display:inline-block;}.ol-attribution.ol-collapsed ul{display:none;}.ol-attribution.ol-logo-only ul{display:block;}.ol-attribution:not(.ol-collapsed){background:rgba(255,255,255,.8);}.ol-attribution.ol-uncollapsible{bottom:0;right:0;border-radius:4px 0 0;height:1.1em;line-height:1em;}.ol-attribution.ol-logo-only{background:0 0;bottom:.4em;height:1.1em;line-height:1em;}.ol-attribution.ol-uncollapsible img{margin-top:-.2em;max-height:1.6em;}.ol-attribution.ol-logo-only button, .ol-attribution.ol-uncollapsible button{display:none;}.ol-zoomslider{top:4.5em;left:.5em;height:200px;}.ol-zoomslider button{position:relative;height:10px;}.ol-touch .ol-zoomslider{top:5.5em;}.ol-overviewmap{left:.5em;bottom:.5em;}.ol-overviewmap.ol-uncollapsible{bottom:0;left:0;border-radius:0 4px 0 0;}.ol-overviewmap .ol-overviewmap-map, .ol-overviewmap button{display:inline-block;}.ol-overviewmap .ol-overviewmap-map{border:1px solid #7b98bc;height:150px;margin:2px;width:150px;}.ol-overviewmap:not(.ol-collapsed) button{bottom:1px;left:2px;position:absolute;}.ol-overviewmap.ol-collapsed .ol-overviewmap-map, .ol-overviewmap.ol-uncollapsible button{display:none;}.ol-overviewmap:not(.ol-collapsed){background:rgba(255,255,255,.8);}.ol-overviewmap-box{border:2px dotted rgba(0,60,136,.7);}.ol-overviewmap .ol-overviewmap-box:hover{cursor:move;}</style> <style> .ol-ctx-menu-container{position:absolute;padding:8px;background:#fff;color:#222;font-size:13px;border-radius:5px;box-shadow:3px 3px 5px rgba(0,0,0,.2);box-sizing:border-box}.ol-ctx-menu-container a,.ol-ctx-menu-container div,.ol-ctx-menu-container img,.ol-ctx-menu-container li,.ol-ctx-menu-container span,.ol-ctx-menu-container ul{margin:0;padding:0;border:0;font:inherit;font-size:100%;vertical-align:baseline}.ol-ctx-menu-container a img{border:none}.ol-ctx-menu-container *,.ol-ctx-menu-container :after,.ol-ctx-menu-container :before{box-sizing:inherit}.ol-ctx-menu-container.ol-ctx-menu-hidden{opacity:0;visibility:hidden;-webkit-transition:visibility 0s linear .3s,opacity .3s;transition:visibility 0s linear .3s,opacity .3s}.ol-ctx-menu-container ul{list-style:none}.ol-ctx-menu-container li{position:relative;line-height:20px;padding:2px 5px}.ol-ctx-menu-container li:not(.ol-ctx-menu-separator):hover{cursor:pointer;background-color:#333;color:#eee}.ol-ctx-menu-container li.ol-ctx-menu-submenu .ol-ctx-menu-container{border:1px solid #eee;padding:8px;top:0;opacity:0;visibility:hidden;-webkit-transition:visibility 0s linear .3s,opacity .3s;transition:visibility 0s linear .3s,opacity .3s}.ol-ctx-menu-container li.ol-ctx-menu-submenu:hover .ol-ctx-menu-container{opacity:1;visibility:visible;-webkit-transition-delay:0s;transition-delay:0s}.ol-ctx-menu-container li.ol-ctx-menu-submenu:after{position:absolute;top:7px;right:10px;content:"";display:inline-block;width:.6em;height:.6em;border-right:.3em solid #222;border-top:.3em solid #222;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.ol-ctx-menu-container li.ol-ctx-menu-submenu:hover:after{border-color:#eee}.ol-ctx-menu-container li.ol-ctx-menu-separator{padding:0}.ol-ctx-menu-container li.ol-ctx-menu-separator hr{border:0;height:1px;background-image:-webkit-linear-gradient(right,transparent,rgba(0,0,0,.75),transparent);background-image:linear-gradient(270deg,transparent,rgba(0,0,0,.75),transparent)}.ol-ctx-menu-icon{text-indent:20px;background-size:20px auto;background-repeat:no-repeat;background-position:0}.ol-ctx-menu-zoom-in{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAABaUlEQVQ4T72U7VHCQBCGn90GtAMuNGCswFiBWIFQgWMFxg6wArECsQKhArEBiB1Qwa1zgQn5IAYcxv13k71n3919L8KJQ07M47+BzgG9TRfZ/JBuWhS6BJFHRJICYrZGZIz3z5Ct2+B7gG6I6kt+wewdkQVwjtkAkR5mC8yu26A1oItR/cTsOweQBdgutD8G7jGm2PJ2n8oqUKIpIjd4HxTM8gvaT/F+AlmWnyWaIXKF95eNguFzTYFhNsdWu9kFgFlaFMANUH3D8wDLoLgSTSD2il8NCe2ZXQBxWDGwxmyUzzOMBZ7wy7Qb2K0wQfXjMOBuhlFpZtNty5sFaTQBuTusZdymeqs1SpYKcO9HkE3KbTd9WFijMHJQ5hBNEAYNq5Qd0dhyke0GiE4QzjqfW23mHT8Hl4DG4Lce3FPE7AtbBSdsbNqpoJLgYkRnNeUV+xwJDHTnUEkxHGbhBXUs5TjJjew/KPy94g+NRaIVRYmMXwAAAABJRU5ErkJggg==")}.ol-ctx-menu-container li:hover.ol-ctx-menu-zoom-in{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAABc0lEQVQ4T71U21ECQRDsJgGdvQDECMQIxAjECMQILCPwzAAjECIQI0AiEDPQAPaWCBhrcKHuCUcV5f7dY3v6tUscefHIePhfwBBCF8CZqRCReRs1tQxDCH1VfQLQz4EsSY4AvIjIsgm8AhhCGKrqa9zwrqoLAKckB5HtguR1E2gBMITQU9VPAD8GICIGtl3e+xHJBwBT59xtHcsCYJZlUwA3kcGHbfDep51OZywi3/acZZm9vyJ5WR5o38uACmDunNt6ZwAkUxFZDwghDFT1jeSjiJinhVUBVNVJkiTDKO8CQA+AsbNQ7s1Ps0VVn5MkSfcCtmBoDZi1Bdx4eJ7zbBolrwPy3o9J3rWSHPs3A1BbjVKlYBaIyDgvu9LDXDU2RTZmXVW1oKyLxRD+OrkOrJLy5mVM0iaftDhuhVbsvBzMglzKUNW6IV/OOWtCM8MmVvEkmbwt83LaB19fdgOtVquUZJeknaDdobTwbOcvBzPcN/AXH1DFFWP7u9oAAAAASUVORK5CYII=")}.ol-ctx-menu-zoom-out{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAABU0lEQVQ4T72U7VECMRRFz3sNaAdkacC1AtcKxApcKnCsQOwAK3CtQKxAqEBsANYOqCDPyTIC+8WCw5jfybn33dxEOPGSE/P4b6BzQG89RT47ZJoWhy5B5BGRZAMxWyEyxvtnyFdt8AagS1F9KQ6YvSMyB84xGyDSw2yO2XUbtAJ0MaqfmH0XAPIA2y7tj4F7jAm2uG1yWQZKNEHkBu+Dg2njWBJNEbnC+8uaIFRuWfuG2QxbbrOrUd0A1Tc8D7AIjkur7DAAsVf8MiWMZ3ZR2m02LPIMscATfjHqBnY7TFD9OAy4zTCCPG/MUKMM5O6wkXFr9dZq7FQqqHk/hDzbFa73cFONTZFDdRyiCcKg5rrSiLaXkiI6RjjrfG6VzDs+B5eAxuDXeYpmNRGzL2wZ/wof+du4GNFpBVqqz5HA4MM5VEYYDrOs+1I6Q9u/4Q8O9wN/AGgWjBVqQjjgAAAAAElFTkSuQmCC")}.ol-ctx-menu-container li:hover.ol-ctx-menu-zoom-out{background-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAABYklEQVQ4T72U4VHCQBCF36tA91KAWIFYgViBWIFYgWMFYgdYgVCBWAFSgdiBFpAsFWSdxcDkQoBkhnF/ZjbfvX377ogjF4/Mw/8CVbUD4MynEJF5k2lqFapqz8yeAPRKkCXJEYAXEVnugm8BVXVgZq/FD+9mtgBwSrJfqF2QvN4FjYCq2jWzTwA/DhARh20qTdMRyQcA0xDCbZ3KCJhl2RTATaHgo+6HLMv8+xXJy+qB3l8FGoB5CKHsXcRV1b6ZvZF8FBH3NKotoJlNkiQZFONdlLtJ3rufbouZPSdJMjwIbKDQEzBrClx7eC4i33Uepmk6JnnXaOQifzMAtdGoRApugYiMI1uqKkrRWAfZo9MxM1+UZzFewl8mN4nYdVM83L7BkwbXLUrF3sfBLQDQBbDy08x8vOohXyEE71lVq9emuEk+3gZa3XYroCvwFyjP8yHJDsnxwaU08GxvS2uFhw78BbzWrxXgMbsHAAAAAElFTkSuQmCC")}</style> <script type="text/javascript" src="scripts/charts.js"></script> <script type="text/javascript" src="scripts/filesaver.1.1.20151003.js"></script> <script type="text/javascript" src="scripts/ol.js"></script> <script type="text/javascript" src="scripts/ol3-contextmenu.js"></script> <title>MeshCentral</title> </head> <body id="body" onload="if (typeof(startup) !== 'undefined') startup();" oncontextmenu="handleContextMenu(event)" style="display:none"> <div id="contextMenu" class="contextMenu noselect" style="display:none"> <div id="cxinfo" class="cmtext" onclick="cmaction(1,event)"><b>Information</b></div> <div id="cxdesktop" class="cmtext" onclick="cmaction(3,event)">Desktop</div> <div id="cxterminal" class="cmtext" onclick="cmaction(2,event)">Terminal</div> <div id="cxfiles" class="cmtext" onclick="cmaction(4,event)">Files</div> <div id="cxevents" class="cmtext" onclick="cmaction(5,event)">Events</div> <div id="cxconsole" class="cmtext" onclick="cmaction(6,event)">Console</div> <hr id="cxmgroupsplit"> <div id="cxmdesktop" class="cmtext" onclick="cmaction(7,event)" style="display:none">Multi-Desktop</div> </div> <div id="meshContextMenu" class="contextMenu,noselect" style="display:none;min-width:0px"> <div id="cxselectall" class="cmtext" onclick="cmmeshaction(1,event)">Select All</div> <div id="cxselectnone" class="cmtext" onclick="cmmeshaction(2,event)">Select None</div> <hr id="cxmgroupsplit2" style="display:none"> <div id="cxmmdesktop" class="cmtext" style="display:none" onclick="cmmeshaction(3,event)">Multi-Desktop</div> </div> <div id="container" style="max-height:100vh;position:relative"> <div id="notifiyBox" class="notifiyBox" style="display:none"></div> <div id="mastheadx"></div> <div id="masthead" class="noselect" style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden"> <div style="float:left;height:66px;color:#c8c8c8;padding-left:20px;padding-top:8px"> <strong><font style="font-size:46px;font-family:Arial,Helvetica,sans-serif">{{{title}}}</font></strong> </div> <div style="float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px"> <strong><font style="font-size:14px;font-family:Arial,Helvetica,sans-serif">{{{title2}}}</font></strong> </div> <div style="float:right"> <div id="notificationCount" onclick="clickNotificationIcon()" class="unselectable" style="display:none;min-width:28px;font-size:20px;border-radius:5px;background-color:lightblue;text-align:center;margin:8px;cursor:pointer;padding:4px" title="Click to view current notifications">0</div> </div> <p id="logoutControl">{{{logoutControl}}}</p> </div> <div id="page_leftbar" style="height:calc(100vh - 66px);width:90px;position:absolute;z-index:1000;background:#113962;background:linear-gradient(to bottom, #104893 0%,#113962 100%);color:white;display:none"> <div style="height:16px"></div> <div id="LeftMenuMyDevices" class="lbbutton lbbuttonsel" title="My Devices" onclick="go(1)"> <div class="lb2" style="position:absolute;top:6px;left:6px"></div> </div> <div id="LeftMenuMyAccount" class="lbbutton" title="My Account" onclick="go(2)"> <div class="lb1" style="position:absolute;top:6px;left:6px"></div> </div> <div id="LeftMenuMyEvents" class="lbbutton" title="My Events" onclick="go(3)"> <div class="lb3" style="position:absolute;top:6px;left:6px"></div> </div> <div id="LeftMenuMyFiles" class="lbbutton" title="My Files" onclick="go(5)"> <div class="lb4" style="position:absolute;top:6px;left:6px"></div> </div> <div id="LeftMenuMyUsers" class="lbbutton" title="My Users" onclick="go(4)"> <div class="lb5" style="position:absolute;top:6px;left:6px"></div> </div> <div id="LeftMenuMyServer" class="lbbutton" title="My Server" onclick="go(6)" style="display:none"> <div class="lb6" style="position:absolute;top:6px;left:6px"></div> </div> </div> <div id="page_content" style="max-height:calc(100vh - 130px)"> <div id="topbarmaster"> <div id="topbar" class="noselect"> <div> <div style="position:relative"> <div style="position:absolute;top:3px;right:6px"> <span title="Toggle full width" style="cursor:pointer;color:white" onclick="toggleFullScreen(1)">&harr;</span> </div> <table id="MainMenuSpan" style="width:100%;height:22px" cellpadding="0" cellspacing="0" class="style1"> <tr> <td id="MainMenuMyDevices" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(1)">My Devices</td> <td id="MainMenuMyAccount" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(2)">My Account</td> <td id="MainMenuMyEvents" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(3)">My Events</td> <td id="MainMenuMyFiles" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(5)">My Files</td> <td id="MainMenuMyUsers" style="width:100px;height:24px;cursor:pointer;display:none" class="style3x" onclick="go(4)">My Users</td> <td id="MainMenuMyServer" style="width:100px;height:24px;cursor:pointer;display:none" class="style3x" onclick="go(6)">My Server</td> <td class="style3" style="text-align:right;height:24px">&nbsp;</td> </tr> </table> <div id="MainSubMenuSpan" style="display:none"> <table id="MainSubMenu" style="width:100%;height:22px" cellpadding="0" cellspacing="0" class="style1"> <tr> <td id="MainDev" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(10)">General</td> <td id="MainDevDesktop" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(11)">Desktop</td> <td id="MainDevTerminal" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(12)">Terminal</td> <td id="MainDevFiles" style="width:100px;height:24px;cursor:pointer;display:none" class="style3x" onclick="go(13)">Files</td> <td id="MainDevEvents" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(16)">Events</td> <td id="MainDevAmt" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(14)">Intel&reg; AMT</td> <td id="MainDevConsole" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(15)">Console</td> <td class="style3" style="height:24px">&nbsp;</td> </tr> </table> </div> <div id="MeshSubMenuSpan" style="display:none"> <table id="MeshSubMenu" style="width:100%;height:22px" cellpadding="0" cellspacing="0" class="style1"> <tr> <td id="MeshGeneral" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(20)">General</td> <td class="style3" style="height:24px">&nbsp;</td> </tr> </table> </div> <div id="UserSubMenuSpan" style="display:none"> <table id="UserSubMenu" style="width:100%;height:22px" cellpadding="0" cellspacing="0" class="style1"> <tr> <td id="UserGeneral" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(30)">General</td> <td id="UserEvents" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(31)">Events</td> <td class="style3" style="height:24px">&nbsp;</td> </tr> </table> </div> <div id="ServerSubMenuSpan" style="display:none"> <table id="ServerSubMenu" style="width:100%;height:22px" cellpadding="0" cellspacing="0" class="style1"> <tr> <td id="ServerGeneral" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(6)">General</td> <td id="ServerConsole" style="width:100px;height:24px;cursor:pointer" class="style3x" onclick="go(115)">Console</td> <td class="style3" style="height:24px">&nbsp;</td> </tr> </table> </div> <div id="UserDummyMenuSpan"> <table id="UserDummyMenu" style="width:100%;height:22px" cellpadding="0" cellspacing="0" class="style1"> <tr><td class="style3" style="text-align:right;height:24px">&nbsp;</td></tr> </table> </div> </div> </div> </div> </div> <div id="column_l"> <div id="p0" style="display:none"> <div id="p0message" style="margin:50px;text-align:center"><span id="p0span">Server disconnected</span>, <href onclick="reload()" style="cursor:pointer"><u>click to reconnect</u></href>.</div> </div> <div id="p1" style="display:none"> <div style="float:right;display:none" id="devListToolbarViewIcons"> <div id="devViewButton1" class="viewSelector" onclick="onDeviceViewChange(1)" title="Columns"><div class="viewSelector2"></div></div> <div id="devViewButton2" class="viewSelector" onclick="onDeviceViewChange(2)" title="List"><div class="viewSelector1"></div></div> <div id="devViewButton3" class="viewSelector" onclick="onDeviceViewChange(3)" title="Desktops"><div class="viewSelector3"></div></div> <div id="devViewButton4" class="viewSelector" onclick="onDeviceViewChange(4)" title="Map"><div class="viewSelector4"></div></div> </div><div><h1>My Devices</h1></div> <table class="noselect" style="width:100%;height:24px;background-color:#d3d9d6;vertical-align:middle;border-spacing:0"> <tr> <td class="h1"></td> <td id="devListToolbar" class="style14" style="display:none"> &nbsp;&nbsp;<input type="button" id="SelectAllButton" onclick="selectallButtonFunction();" value="Select All">&nbsp; <input type="button" id="GroupActionButton" disabled="disabled" value="Group Action" onclick="groupActionFunction()">&nbsp; <input id="SearchInput" type="text" style="width:120px" placeholder="Filter" onchange="masterUpdate(5)" onkeyup="masterUpdate(5)" autocomplete="off" onfocus="onSearchFocus(1)" onblur="onSearchFocus(0)">&nbsp; <label><input type="checkbox" id="RealNameCheckBox" onclick="onRealNameCheckBox()"><span title="Show devices operating system name">OS Name</span></label> </td> <td id="kvmListToolbar" class="style14" style="height:100%;display:none"> &nbsp;&nbsp;<input type="button" onclick="connectAllKvmFunction()" value="Connect All">&nbsp; <input type="button" onclick="disconnectAllKvmFunction()" value="Disconnect All">&nbsp; <label><input type="checkbox" id="autoConnectDesktopCheckbox" onclick="autoConnectDesktops(event)" title="Automatic connect">Auto&nbsp;</label> <input type="button" onclick="showMultiDesktopSettings()" value="Settings">&nbsp; </td> <td id="devMapToolbar" class="style14" style="height:100%;display:none"> &nbsp;&nbsp;<input type="text" id="mapSearchLocation" placeholder="Search Location" onfocus="onMapSearchFocus(1)" onblur="onMapSearchFocus(0)"> <input type="button" value="Search" title="Search for location" onclick="getSearchLocation()"> <input type="button" id="refreshmap" title="Reset map view" value="Reset" style="margin-left:5px" onclick="refreshMap(false,true)"> </td> <td class="auto-style1" style="height:100%"> <div style="float:right;display:none" id="devListToolbarView"> View <select id="viewselect" onchange="onDeviceViewChange()"> <option value="1">Columns <option value="2">List <option value="3">Desktops <option id="viewselectmapoption" value="4">Map </select> </div> <div style="float:right;display:none" id="devListToolbarSort"> Sort <select id="sortselect" onchange="masterUpdate(6)"> <option>Group <option>Power <option>Device <option>Tags </select> &nbsp; </div> <div style="float:right;display:none" id="devListToolbarSize"> Size <select id="sizeselect" onchange="onDeviceViewChange()"> <option value="0">Small <option value="1">Medium <option value="2">Large </select> &nbsp; </div> </td> <td class="h2"></td> </tr> </table> <div id="NoMeshesPanel" style="display:none"> <table style="width:100%;padding:20px"> <tr> <td valign="top" style="width:50px"> <img src="images/info.png" height="48" width="47"> </td> <td> To get started, <a onclick="account_createMesh()" style="cursor:pointer"><strong>click here to create a device group</strong></a>. </td> </tr> </table> </div> <div id="xdevices" class="noselect" style="max-height:calc(100vh - 239px);overflow-y:auto;overflow-x:hidden;-webkit-overflow-scrolling:touch;display:none"></div> <div id="xdevicesmap" style="height:calc(100vh - 239px);width:100%;overflow:hidden;position:relative;display:none"> <div id="xmapSearchResultsDlg" style="position:absolute;display:none;max-height:280px;left:5px;top:5px;max-width:250px;z-index:1000;background-color:#EEE;box-shadow:0px 0px 15px #666"> <div style="width:100%;background-color:#003366;color:#FFF;border-radius:5px 5px 0 0"> <div id="xmapSearchClose" style="float:right;padding:5px;cursor:pointer" onclick="mapCloseSearchWindow()"><b>X</b></div> <div style="padding:5px">Location Results</div> <div style="width:100%;margin:6px"></div> </div> <div id="xmapSearchResults" style="margin:6px"></div> </div> </div> <div id="xmap-info-window" style="text-shadow:0px 0px 15px #FFF"></div> </div> <div id="p2" style="display:none"> <h1>My Account</h1> <img id="p2AccountImage" alt="" width="150" height="103" src="images/mainaccount.jpg" style="margin-bottom:10px;margin-right:20px;float:right"> <div id="p2AccountSecurity" style="display:none"> <p><strong>Account security</strong></p> <div style="margin-left:25px"> <div id="manageAuthApp"><div style="width:15px;display:inline-block"><span id="authAppSetupCheck" style="color:green;font-size:10px"><strong>&#x2713;</strong></span></div><span><a onclick="account_manageAuthApp()" style="cursor:pointer">Manage authenticator app</a><br></span></div> <div id="manageHardwareOtp"><div style="width:15px;display:inline-block"><span id="authKeySetupCheck" style="color:green;font-size:10px"><strong>&#x2713;</strong></span></div><span><a onclick="account_manageHardwareOtp(0)" style="cursor:pointer">Manage security keys</a><br></span></div> <div id="manageOtp"><div style="width:15px;display:inline-block"><span id="authCodesSetupCheck" style="color:green;font-size:10px"><strong>&#x2713;</strong></span></div><span><a onclick="account_manageOtp(0)" style="cursor:pointer">Manage backup codes</a><br></span></div> </div> </div> <div id="p2AccountActions"> <p><strong>Account actions</strong></p> <p style="margin-left:40px"> <span id="verifyEmailId" style="display:none"><a onclick="account_showVerifyEmail()" style="cursor:pointer">Verify email</a><br></span> <a onclick="account_showChangeEmail()" style="cursor:pointer">Change email address</a><br> <a onclick="account_showChangePassword()" style="cursor:pointer">Change password</a><span id="p2nextPasswordUpdateTime"></span><br> <a onclick="account_showDeleteAccount()" style="cursor:pointer">Delete account</a><br> </p> <br style="clear:both"> </div> <strong>Device Groups</strong> ( <a onclick="account_createMesh()" style="cursor:pointer"><img height="12" src="images/icon-addnew.png" width="12" border="0"> New</a> ) <br><br> <div id="p2meshes"></div> <div id="p2noMeshFound" style="margin-left:40px;display:none">No device groups. <a onclick="account_createMesh()" style="cursor:pointer"><strong>Get started here!</strong></a></div> <br style="clear:both"> </div> <div id="p3" style="display:none"> <h1>My Events</h1> <table style="width:100%;height:24px;background-color:#d3d9d6;margin-bottom:4px;vertical-align:middle;border-spacing:0"> <tr> <td class="h1"></td> <td>&nbsp;<input id="p2deleteall" type="button" onclick="showDeleteAllEventsDialog()" style="display:none" value="Delete All..."></td> <td class="auto-style1"> Show <select id="p3limitdropdown" onchange="refreshEvents()"> <option value="60">Last 60 <option value="120">Last 120 <option value="250">Last 250 <option value="500">Last 500 <option value="1000">Last 1000 </select> </td> <td class="h2"></td> </tr> </table> <div id="p3events" style="height:calc(100vh - 243px);overflow-y:scroll"></div> </div> <div id="p4" style="display:none"> <h1>My Users</h1> <table style="width:100%;height:24px;background-color:#d3d9d6;margin-bottom:4px;vertical-align:middle;border-spacing:0"> <tr> <td class="h1"></td> <td class="style14"> <div style="float:right"> <input type="button" onclick="showUserBroadcastDialog()" style="margin-right:6px" value="Broadcast"> </div> <div> <input id="UserNewAccountButton" type="button" style="margin-left:6px" onclick="showCreateNewAccountDialog()" value="New Account..."> <input id="UserSearchInput" type="text" style="width:120px;margin-left:6px" placeholder="Filter" onchange="onUserSearchInputChanged()" onkeyup="onUserSearchInputChanged()" autocomplete="off" onfocus="onUserSearchFocus(1)" onblur="onUserSearchFocus(0)"> </div> </td> <td class="h2"></td> </tr> </table> <div id="p3users" style="max-height:calc(100vh - 243px);overflow-y:auto"></div> </div> <div id="p5" style="display:none"> <h1>My Files</h1> <table id="p5toolbar" style="width:100%" cellpadding="0" cellspacing="0"> <tr> <td style="width:100%;background-color:#d3d9d6;text-align:left;padding:4px" valign="bottom"> <div id="p5rightOfButtons" style="float:right;margin-top:3px"></div> <div> <input type="button" id="p5FolderUp" disabled="disabled" onclick="p5folderup();" value="Up">&nbsp; <input type="button" id="p5SelectAllButton" disabled="disabled" onclick="p5selectallfile();" value="Select All" onkeypress="return false;" onkeydown="return false;">&nbsp; <input type="button" id="p5RenameFileButton" disabled="disabled" value="Rename" onclick="p5renamefile();" onkeypress="return false;" onkeydown="return false;">&nbsp; <input type="button" id="p5DeleteFileButton" disabled="disabled" value="Delete" onclick="p5deletefile();" onkeypress="return false;" onkeydown="return false;">&nbsp; <input type="button" id="p5NewFolderButton" disabled="disabled" value="New Folder" onclick="p5createfolder();" onkeypress="return false;" onkeydown="return false;">&nbsp; <input type="button" id="p5UploadButton" disabled="disabled" value="Upload" onclick="p5uploadFile()" onkeypress="return false;" onkeydown="return false;">&nbsp; <input type="button" id="p5CutButton" disabled="disabled" value="Cut" onclick="p5copyFile(1)" onkeypress="return false" onkeydown="return false">&nbsp; <input type="button" id="p5CopyButton" disabled="disabled" value="Copy" onclick="p5copyFile(0)" onkeypress="return false" onkeydown="return false">&nbsp; <input type="button" id="p5PasteButton" disabled="disabled" value="Paste" onclick="p5pasteFile()" onkeypress="return false" onkeydown="return false">&nbsp; </div> </td> </tr> <tr> <td style="background-color:#E4E9E7;height:28px"> <div style="float:right"> <select id="p5sortdropdown" onchange="updateFiles()"> <option value="1" selected="selected">Sort by name <option value="2">Sort by size <option value="3">Sort by date <option value="4">Descend by name <option value="5">Descend by size <option value="6">Descend by date </select> </div> <div>&nbsp;&nbsp;<span id="p5currentpath"></span></div> </td> </tr> </table> <div id="p5filetable" style="width:100%;height:calc(100vh - 294px);overflow:auto;-webkit-user-select:none;position:relative"> <div id="p5PublicShare" style="display:none;width:100%;overflow:auto;-webkit-user-select:none;background-color:lightsteelblue"><div style="padding:4px">These files are shared publicly, click "link" to get public url.</div></div> <div id="bigok" style="width:256px;overflow:hidden;position:absolute;left:337px;top:20px;text-align:center;font-size:1600%;color:#AAAAAA;display:none"><b>&checkmark;</b></div> <div id="bigfail" style="width:256px;overflow:hidden;position:absolute;left:337px;top:20px;text-align:center;font-size:1600%;color:#AAAAAA;display:none"><b>&#10007;</b></div> <span id="p5files"></span> </div> <table id="p5toolbarBottom" style="width:100%" cellpadding="0" cellspacing="0"> <tr><td class="style6" style="text-align:left;padding:3px">&nbsp;<span id="p5bottomstatus"></span></td></tr> </table> </div> <div id="p6" style="display:none"> <img id="MainMeshImage" src="serverpic.ashx" style="border-width:0px;height:200px;width:200px;float:right"> <h1>My Server</h1> <p id="p2ServerActions"><strong>Server actions</strong></p> <p style="margin-left:40px"> <div id="p2ServerActionsBackup" style="margin-left:40px"><a href="/backup.zip" rel="noreferrer noopener" target="_blank" style="cursor:pointer">Download server backup</a></div> <div id="p2ServerActionsRestore" style="margin-left:40px"><a onclick="server_showRestoreDlg()" style="cursor:pointer">Restore server with backup</a></div> <div id="p2ServerActionsVersion" style="margin-left:40px"><a onclick="server_showVersionDlg()" style="cursor:pointer">Check server version</a></div> <div id="p2ServerActionsErrors" style="margin-left:40px"><a onclick="server_showErrorsDlg()" style="cursor:pointer">Show server error log</a></div> </p> <br><strong>Server Statistics</strong><br><br> <div id="serverStats" style="margin-left:40px"> <div id="serverCpuChartView" style="display:none"> <div style="width:60px;display:inline-block"><canvas id="serverCpuChart" style="width:60px;height:60px"></canvas></div> <div style="width:160px;display:inline-block" id="serverCpuChartText"></div> </div> <div id="serverMemoryChartView" style="display:none"> <div style="width:60px;display:inline-block"><canvas id="serverMemoryChart" style="width:60px;height:60px"></canvas></div> <div style="width:160px;display:inline-block" id="serverMemoryChartText"></div> </div><br><br> <div id="serverStatsTable"></div> </div> </div> <div id="p10" style="display:none"> <table style="width:100%" cellpadding="0" cellspacing="0"> <tr> <td style="width:auto" valign="top"> <div id="p10title"> <div id="p10BackButton" style="float:left"><div class="backButton" onclick="goBack()" title="Back"><div class="backButtonEx"></div></div></div> <h1>General - <span id="p10deviceName"></span></h1> </div> <div id="p10html"></div> </td> <td style="width:20px"></td> <td style="width:200px"> <a style="cursor:pointer" onclick="p10showiconselector()"><img id="MainComputerImage" style="border-width:0px;height:200px;width:200px"></a> <div style="width:100%;text-align:center"><strong><span id="MainComputerState"></span></strong></div> </td> </tr> </table><br> <div id="p10html2"></div> <div id="p10html3"></div> </div> <div id="p11" class="noselect" style="display:none"> <div id="p11title"> <div id="p11deviceNameHeader"> <div id="p11BackButton" style="float:left"><div class="backButton" onclick="goBack()" title="Back"><div class="backButtonEx"></div></div></div> <div style="float:right" id="devListToolbarViewIcons"><div class="viewSelector" onclick="deskToggleFull(event)" title="Full Screen. Hold shift to browser full screen."><div class="viewSelector5"></div></div></div> <h1>Desktop - <span id="p11deviceName"></span></h1> </div> </div> <div id="p14warning" style='max-width:100%;display:none;cursor:pointer;margin-bottom:5px' onclick="showFeaturesDlg()"> <div class="icon2" style="float:left;margin:7px"></div> <div style='width:auto;border-radius:8px;padding:8px;background-color:lightsalmon'>Intel&reg; AMT Redirection port or KVM feature is disabled<span id="p14warninga">, click here to enable it.</span></div> </div> <div id="p14warning2" style='max-width:100%;display:none;cursor:pointer;margin-bottom:5px' onclick="showPowerActionDlg()"> <div class="icon2" style="float:left;margin:7px"></div> <div style='width:auto;border-radius:8px;padding:8px;background-color:lightsalmon'>Remote computer is not powered on, click here to issue a power command.</div> </div> <table id="deskarea0" cellpadding="0" cellspacing="0" style="width:100%;padding:0px;padding:0px;margin-top:0px"> <tr id="deskarea1"> <td style="padding-top:2px;padding-bottom:2px;background:#C0C0C0"> <div style="float:right;text-align:right"> <span id="p14power"></span>&nbsp; <div style='cursor:pointer;border:none;float:right;font-size:130%;margin-right:4px' title="Rotate Left" onclick="drotate(-1)">&olarr;</div> <div style='cursor:pointer;border:none;float:right;font-size:130%;margin-right:4px' title="Rotate Right" onclick="drotate(1)">&orarr;</div> <input id="deskFocusBtn" type="button" title="Toggle focus mode, when active only the region around the mouse is updated" onkeypress="return false" onkeydown="return false" value="Focus All" onclick="deskToggleFocus()" style="margin-right:3px;display:none"> <input id="deskSaveBtn" type="button" title="Save a screenshot of the remote desktop" onkeypress="return false" onkeydown="return false" value="Save..." onclick="deskSaveImage()" style="margin-right:3px"> <input id="deskActionsBtn" type="button" title="Perform power actions on the device" onkeypress="return false" onkeydown="return false" value="Actions" onclick="deviceActionFunction()" style="margin-right:3px"> <input id="deskActionsSettings" type="button" value="Settings..." title="Edit remote desktop settings" onkeypress="return false" onkeydown="return false" onclick="showDesktopSettings()" style="margin-right:3px"> <input type="button" title="Change the power state of the remote machine" onkeypress="return false" onkeydown="return false" value="Power Actions..." onclick="showPowerActionDlg()" style="margin-right:3px;display:none"> </div> <div> <div id="idx_deskFullBtn2" onclick="deskToggleFull(event)" style="float:left;font-size:large;cursor:pointer;display:none">&nbsp;&#x2716;</div> <input type="button" id="autoconnectbutton1" value="AutoConnect" onclick="autoConnectDesktop(event)" onkeypress="return false" onkeydown="return false" style="display:none"> <span id="connectbutton1span">&nbsp;<input type="button" id="connectbutton1" value="Connect" onclick="connectDesktop(event,1)" onkeypress="return false" onkeydown="return false" disabled="disabled"></span> <span id="connectbutton1hspan">&nbsp;<input type="button" id="connectbutton1h" value="HW Connect" onclick="connectDesktop(event,2)" onkeypress="return false" onkeydown="return false" disabled="disabled"></span> <span id="disconnectbutton1span">&nbsp;<input type="button" id="disconnectbutton1" value="Disconnect" onclick="connectDesktop(event,0)" onkeypress="return false" onkeydown="return false"></span> &nbsp;<span id="deskstatus">Disconnected</span> </div> </td> </tr> <tr id="deskarea2"> <td> <div style="background-color:gray"><div id="progressbar" style="height:2px;width:0%;background-color:red"></div></div> </td> </tr> <tr id="deskarea3"> <td id="deskarea3x" style="background:black;text-align:center;position:relative;overflow:hidden"> <div id="DeskFocus" style="overflow:hidden;color:transparent;border:3px dotted rgba(255,0,0,.2);position:absolute;border-radius:5px" oncontextmenu="return false" onmousedown="dmousedown(event)" onmouseup="dmouseup(event)" onmousemove="dmousemove(event)"></div> <div id="DeskParent" style="overflow:hidden"> <canvas id="Desk" width="640" height="480" style="overflow:hidden;width:100%;-ms-touch-action:none;margin-left:0px" oncontextmenu="return false" onmousedown="dmousedown(event)" onmouseup="dmouseup(event)" onmousemove="dmousemove(event)" onmousewheel="dmousewheel(event)"></canvas> </div> <div id="DeskTools" style="position:absolute;width:400px;height:100%;background-color:gray;top:0;right:0;border-left:2px solid lightgray;display:none"> <a id="DeskToolsRefreshButton" style="float:right;padding:3px;cursor:pointer" onclick="refreshDeskTools()">Refresh</a> <div id="DeskToolsBar" style="position:absolute;padding:3px;border-radius:3px 3px 0px 0px;top:5px;left:4px;bottom:26px;background-color:lightgray;cursor:pointer">Processes</div> <div style="position:absolute;top:26px;left:4px;right:4px;bottom:4px;background-color:lightgray;text-align:left"> <div style="border-bottom:1px solid darkgray;padding:3px"><a style="width:50px;padding-right:5px;float:left;cursor:pointer" title="Sort by process id" onclick="sortProcess(0)">PID</a><a style="cursor:pointer" title="Sort by name" onclick="sortProcess(1)">Name</a></div> <div id="DeskToolsProcesses" style="overflow-y:scroll;position:absolute;top:24px;bottom:0px;width:100%"></div> </div> </div> </td> </tr> <tr id="deskarea4"> <td style="padding-top:2px;padding-bottom:2px;background:#C0C0C0"> <div style="float:right;text-align:right"> <select id="termdisplays" style="display:none" onchange="deskSetDisplay(event)" onclick="deskGetDisplayNumbers(event)"></select>&nbsp; <input id="DeskToolsButton" type="button" value="Tools" title="Toggle tools view" onkeypress="return false" onkeydown="return false" onclick="toggleDeskTools()">&nbsp; <span id="DeskChatButton" style="float:right;margin-top:1px;margin-right:4px;cursor:pointer" title="Open chat window to this computer"><img src='images/icon-chat.png' onclick="deviceChat()" height="16" width="16" style="padding-top:2px"></span> <span id="DeskNotifyButton" style="float:right;margin-top:1px;margin-right:4px;cursor:pointer" title="Display a notification on the remote computer"><img src='images/icon-notify.png' onclick="deviceToastFunction()" height="16" width="16" style="padding-top:2px"></span> <span id="DeskOpenWebButton" style="float:right;margin-top:1px;margin-right:4px;cursor:pointer" title="Open a web address on remote computer"><img src='images/icon-url2.png' onclick="deviceUrlFunction()" height="16" width="16" style="padding-top:2px"></span> </div> <div> <select style="margin-left:6px" id="deskkeys"> <option value="5">Win <option value="0">Win+Down <option value="1">Win+Up <option value="2">Win+L <option value="3">Win+M <option value="4">Shift+Win+M <option value="6">Win+R </select> <input id="DeskWD" type="button" value="Send" onkeypress="return false" onkeydown="return false" onclick="deskSendKeys()"> <input id="DeskClip" style="margin-left:6px;display:none" type="button" value="Clipboard" onkeypress="return false" onkeydown="return false" onclick="showDeskClip()"> <input id="DeskCAD" type="button" value="Ctrl-Alt-Del" onkeypress="return false" onkeydown="return false" onclick="sendCAD()"> <label><span id="DeskControlSpan" style="margin-left:6px" title="Toggle mouse and keyboard input"><input id="DeskControl" type="checkbox" onkeypress="return false" onkeydown="return false" onclick="toggleKvmControl()">Input</span></label>&nbsp; </div> </td> </tr> </table> </div> <div id="p12" style="display:none"> <div id="p12title"> <div id="p12BackButton" style="float:left"><div class="backButton" onclick="goBack()" title="Back"><div class="backButtonEx"></div></div></div> <h1>Terminal - <span id="p12deviceName"></span></h1> </div> <div id="p12warning" style='max-width:100%;display:none;cursor:pointer;margin-bottom:5px' onclick="showFeaturesDlg()"> <div class="icon2" style="float:left;margin:7px"></div> <div style='width:auto;border-radius:8px;padding:8px;background-color:lightsalmon'>Intel&reg; AMT Redirection port or KVM feature is disabled<span id="p14warninga">, click here to enable it.</span></div> </div> <div id="p12warning2" style='max-width:100%;display:none;cursor:pointer;margin-bottom:5px' onclick="showPowerActionDlg()"> <div class="icon2" style="float:left;margin:7px"></div> <div style='width:auto;border-radius:8px;padding:8px;background-color:lightsalmon'>Remote computer is not powered on, click here to issue a power command.</div> </div> <table cellpadding="0" cellspacing="0" style="width:100%;padding:0px;padding:0px;margin-top:0px"> <tr> <td style="padding-top:2px;padding-bottom:2px;background:#C0C0C0"> <div style="float:right;text-align:right"> <input id="termActionsBtn" type="button" title="Perform power actions on the device" onkeypress="return false" onkeydown="return false" value="Actions" onclick="deviceActionFunction()" style="margin-right:3px"> </div> <div> <input type="button" id="autoconnectbutton2" value="AutoConnect" onclick="autoConnectTerminal(event)" onkeypress="return false" onkeydown="return false" style="display:none"> <span id="connectbutton2span">&nbsp;<input type="button" id="connectbutton2" value="Connect" onclick="connectTerminal(event,1)" onkeypress="return false" onkeydown="return false" disabled="disabled"></span> <span id="connectbutton2hspan">&nbsp;<input type="button" id="connectbutton2h" value="HW Connect" onclick="connectTerminal(event,2)" onkeypress="return false" onkeydown="return false" disabled="disabled"></span> <span id="disconnectbutton2span">&nbsp;<input type="button" id="disconnectbutton2" value="Disconnect" onclick="connectTerminal(event,0)" onkeypress="return false" onkeydown="return false"></span> &nbsp;<span id="termstatus">Disconnected</span> </div> </td> </tr> <tr> <td> <div style="background-color:gray"><div id="termprogressbar" style="height:2px;width:0%;background-color:red"></div></div> </td> </tr> <tr> <td style="background:black;text-align:center;height:500px;position:relative"> <pre id="Term" style="background:black;margin:0;padding:0"></pre> </td> </tr> <tr> <td style="padding-top:2px;padding-bottom:2px;background:#C0C0C0"> <div style="float:right;text-align:right"> <span id="terminalSettingsButtons" style="display:none"> <input id="id_tcrbutton" type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" value="CR+LF" title="Toggle what the return key will send" onclick="termToggleCr()"> <input id="id_tfxkeysbutton" type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" value="Intel (F10 = ESC+[OM)" title="Toggle F1 to F10 keys emulation type" onclick="termToggleFx()"> <input id="id_ttypebutton" type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" value="Extended Ascii" title="Toggle terminal emulation type" onclick="termToggleType()"> </span> <select id="specialkeylist" onkeypress="return false" style="margin-left:5px"></select> <input id="specialkeylistinput" type="button" onkeypress="return false" class="bottombutton" value="Send" title="Send the selected special key" onclick="sendSpecialKey()"> </div> <div> &nbsp; <input type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" id="ctrlcbutton" value="Ctl-C" onclick="termSendKey(3,'ctrlcbutton')"> <input type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" id="ctrlxbutton" value="Ctl-X" onclick="termSendKey(24,'ctrlxbutton')"> <input type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" id="escbutton" value="ESC" onclick="termSendKey(27,'escbutton')"> <input type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" id="bsbutton" value="Backspace" onclick="termSendKey(8,'bsbutton')"> <input type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" id="pastebutton" value="Paste" title="Paste text into the terminal" onclick="showTermPasteDialog()"> </div> </td> </tr> </table> </div> <div id="p13" style="display:none"> <div id="p13title"> <div id="p13BackButton" style="float:left"><div class="backButton" onclick="goBack()" title="Back"><div class="backButtonEx"></div></div></div> <h1>Files - <span id="p13deviceName"></span></h1> </div> <table id="p13toolbar" style="width:100%" cellpadding="0" cellspacing="0"> <tr> <td style="background-color:#C0C0C0;border-bottom:2px solid black;padding:2px"> <div style="float:right;text-align:right"> <input id="filesActionsBtn" type="button" title="Perform power actions on the device" onkeypress="return false" onkeydown="return false" value="Actions" onclick="deviceActionFunction()" style="margin-right:3px"> </div> <div> <input id="p13AutoConnect" value="AutoConnect" onclick="autoConnectFiles(event)" onkeypress="return false" onkeydown="return false" type="button" style="display:none"> <input id="p13Connect" value="Connect" onclick="connectFiles(event)" onkeypress="return false" onkeydown="return false" type="button"> <span id="p13Status">Disconnected</span> </div> </td> </tr> <tr> <td style="width:100%;background-color:#d3d9d6;text-align:left;padding:4px" valign="bottom"> <div id="p13rightOfButtons" style="float:right;margin-top:3px"></div> <div> <input type="button" id="p13FolderUp" disabled="disabled" onclick="p13folderup()" value="Up">&nbsp; <input type="button" id="p13SelectAllButton" disabled="disabled" onclick="p13selectallfile()" value="Select All" onkeypress="return false" onkeydown="return false">&nbsp; <input type="button" id="p13RenameFileButton" disabled="disabled" value="Rename" onclick="p13renamefile()" onkeypress="return false" onkeydown="return false">&nbsp; <input type="button" id="p13DeleteFileButton" disabled="disabled" value="Delete" onclick="p13deletefile()" onkeypress="return false" onkeydown="return false">&nbsp; <input type="button" id="p13NewFolderButton" disabled="disabled" value="New Folder" onclick="p13createfolder()" onkeypress="return false" onkeydown="return false">&nbsp; <input type="button" id="p13UploadButton" disabled="disabled" value="Upload" onclick="p13uploadFile()" onkeypress="return false" onkeydown="return false">&nbsp; <input type="button" id="p13CutButton" disabled="disabled" value="Cut" onclick="p13copyFile(1)" onkeypress="return false" onkeydown="return false">&nbsp; <input type="button" id="p13CopyButton" disabled="disabled" value="Copy" onclick="p13copyFile(0)" onkeypress="return false" onkeydown="return false">&nbsp; <input type="button" id="p13PasteButton" disabled="disabled" value="Paste" onclick="p13pasteFile()" onkeypress="return false" onkeydown="return false">&nbsp; <input type="button" id="p13RefreshButton" disabled="disabled" value="Refresh" onclick="p13folderup(9999)" onkeypress="return false" onkeydown="return false">&nbsp; </div> </td> </tr> <tr> <td style="background-color:#E4E9E7;height:28px"> <div style="float:right"> <select id="p13sortdropdown" onchange="p13updateFiles()"> <option value="1" selected="selected">Sort by name <option value="2">Sort by size <option value="3">Sort by date <option value="4">Descend by name <option value="5">Descend by size <option value="6">Descend by date </select> </div> <div>&nbsp;&nbsp;<span id="p13currentpath"></span></div> </td> </tr> </table> <div id="p13filetable" style="width:100%;height:calc(100vh - 346px);overflow:auto;-webkit-user-select:none"> <div id="p13bigok" style="width:256px;overflow:hidden;position:absolute;left:337px;top:200px;text-align:center;font-size:1600%;color:#AAAAAA;display:none"><b>&checkmark;</b></div> <div id="p13bigfail" style="width:256px;overflow:hidden;position:absolute;left:337px;top:200px;text-align:center;font-size:1600%;color:#AAAAAA;display:none"><b>&#10007;</b></div> <span id="p13files"></span> </div> <table id="p13toolbarBottom" style="width:100%" cellpadding="0" cellspacing="0"> <tr><td class="style6" style="text-align:left;padding:3px">&nbsp;<span id="p13bottomstatus"></span></td></tr> </table> </div> <div id="p14" style="display:none"> <div id="p14title"> <div id="p14BackButton" style="float:left"><div class="backButton" onclick="goBack()" title="Back"><div class="backButtonEx"></div></div></div> <h1>Intel&reg; AMT - <span id="p14deviceName"></span></h1> </div> <iframe id="p14iframe" style="width:100%;height:calc(100vh - 242px);border:0;overflow:hidden" src="/commander.htm"></iframe> </div> <div id="p15" style="display:none"> <div id="p15title"> <div id="p15BackButton" style="float:left"><div class="backButton" onclick="goBack()" title="Back"><div class="backButtonEx"></div></div></div> <h1><span id="p15deviceName"></span></h1> </div> <table cellpadding="0" cellspacing="0" style="width:100%;padding:0px;padding:0px;margin-top:0px"> <tr> <td style="background:#C0C0C0"> <div style="float:right;padding-right:4px"> <div style="padding:4px;display:inline-block" id="p15coreName" title="Information about current core running on this agent"></div> <input type="button" id="p15uploadCore" value="Agent Action" onclick="p15uploadCore(event)" title="Change the agent Java Script code module"> </div> <div id="p15statetext" style="padding:4px"></div> </td> </tr> <tr> <td> <div style="background-color:gray"><div id="consoleprogressbar" style="height:2px;width:0%;background-color:red"></div></div> </td> </tr> <tr> <td id="p15agentConsole" style="background:black;margin:0;padding:0;color:lightgray;width:100%;height:calc(100vh - 296px);max-height:500px;position:relative"> <pre id="p15agentConsoleText" style="position:absolute;margin:0;padding:0;top:0;bottom:0;left:0;right:0;overflow-y:scroll;overflow-x:auto"></pre> </td> </tr> <tr> <td style="padding-top:2px;padding-bottom:2px;background:#C0C0C0"> <table style="width:100%"> <tr> <td style="width:99%"> <input id="p15consoleText" style="width:100%" onkeyup="p15consoleSend(event)" onfocus="onConsoleFocus(1)" onblur="onConsoleFocus(0)"> </td> <td>&nbsp;</td> <td style="width:1%"><input id="id_p15consoleClear" type="button" onkeypress="return false" onkeydown="return false" class="bottombutton" value="Clear" onclick="p15consoleClear()"></td> </tr> </table> </td> </tr> </table> </div> <div id="p16" style="display:none"> <div id="p16title"> <div id="p16BackButton" style="float:left"><div class="backButton" onclick="goBack()" title="Back"><div class="backButtonEx"></div></div></div> <h1>Events - <span id="p16deviceName"></span></h1> </div> <div style="width:100%;height:24px;background-color:#d3d9d6;margin-bottom:4px"> <div class="style7" style="width:16px;height:100%;float:left">&nbsp;</div> <div class="h1" style="height:100%;float:left">&nbsp;</div> <div class="style14" style="height:100%;float:left">&nbsp;&nbsp;<input type="button" value="Refresh" onclick="refreshDeviceEvents()">&nbsp;</div> <div class="auto-style1" style="height:100%;float:right"> Show <select id="p16limitdropdown" onchange="refreshDeviceEvents()"> <option value="60">Last 60 <option value="120">Last 120 <option value="250">Last 250 <option value="500">Last 500 <option value="1000">Last 1000 </select> <div style="height:100%;width:20px;float:right;background-color:#ffffff"></div> <div class="h2" style="height:100%;float:right">&nbsp;</div> </div> </div> <div id="p16events" style="max-height:calc(100vh - 267px);overflow-y:auto"></div> </div> <div id="p20" style="display:none"> <picture id="MainMeshImage" style="border-width:0px;height:200px;width:200px;float:right"> <source type="image/webp" width="200" height="200" srcset="images/webp/mesh-200.webp"> <img alt="" width="200" height="200" src="images/mesh-200.jpg"> </source></picture> <div style="float:left"><div class="backButton" onclick="goBack()" title="Back"><div class="backButtonEx"></div></div></div> <h1>General - <span id="p20meshName"></span></h1> <p id="p20info"> </div> <div id="p30" style="display:none"> <table style="width:100%" cellpadding="0" cellspacing="0"> <tr> <td style="width:auto" valign="top"> <div id="p30title"> <div style="float:left"><div class="backButton" onclick="goBack()" title="Back"><div class="backButtonEx"></div></div></div> <h1>General - <span id="p30userName"></span></h1> </div> <div id="p30html"></div> </td> <td style="width:20px"></td> <td style="width:200px"> <picture id="MainUserImage" style="border-width:0px;height:200px;width:200px;float:right"> <source type="image/webp" width="200" height="200" srcset="images/webp/user-200.webp"> <img alt="" width="200" height="200" src="images/user-200.jpg"> </source></picture> <div style="width:100%;text-align:center"><strong><span id="MainUserState"></span></strong></div> </td> </tr> </table><br> <div id="p30html2"></div> <div id="p30html3"></div> </div> <div id="p31" style="display:none"> <div style="float:left"><div class="backButton" onclick="goBack()" title="Back"><div class="backButtonEx"></div></div></div> <h1>Events - <span id="p31userName"></span></h1> <div style="width:100%;height:24px;background-color:#d3d9d6;margin-bottom:4px"> <div class="style7" style="width:16px;height:100%;float:left">&nbsp;</div> <div class="h1" style="height:100%;float:left">&nbsp;</div> <div class="style14" style="height:100%;float:left">&nbsp;&nbsp;<input type="button" value="Refresh" onclick="refreshUsersEvents()">&nbsp;</div> <div class="auto-style1" style="height:100%;float:right"> Show <select id="p31limitdropdown" onchange="refreshUsersEvents()"> <option value="60">Last 60 <option value="120">Last 120 <option value="250">Last 250 <option value="500">Last 500 <option value="1000">Last 1000 </select> <div style="height:100%;width:20px;float:right;background-color:#ffffff"></div> <div class="h2" style="height:100%;float:right;">&nbsp;</div> </div> </div> <div id="p31events" style="max-height:calc(100vh - 267px);overflow-y:scroll"></div> </div> <br id="column_l_bottomgap"> </div> <div id="footer" class="noselect"> <table cellpadding="0" cellspacing="10" style="width:100%"> <tr> <td style="text-align:left;color:white"> {{{footer}}} </td> <td style="text-align:right"> <a id="verifyEmailId2" style="color:yellow;margin-left:3px;cursor:pointer;display:none" onclick="account_showVerifyEmail()">Verify Email</a> <a style="margin-left:3px" href="terms">Terms &amp; Privacy</a> </td> </tr> </table> </div> <div id="dialog" style="z-index:1000;background-color:#EEE;box-shadow:0px 0px 15px #666;font-family:Arial,Helvetica,sans-serif;border-radius:5px;position:fixed;top:160px;width:400px;left:calc((100% / 2) - 200px);display:none"> <div style="width:100%;background-color:#003366;color:#FFF;border-radius:5px 5px 0 0"> <div id="id_dialogclose" style="float:right;padding:3px;margin-right:3px;cursor:pointer" onclick="setDialogMode()">&#x2716;</div> <div id="id_dialogtitle" style="padding:5px"></div> <div style="width:100%;margin:6px"></div> </div> <div style="margin-right:16px;margin-left:8px"> <div id="dialog1" style="margin:auto;text-align:center;margin:3px"> <div id="id_dialogMessage" style="padding:10px"></div> </div> <div id="dialog2" style="margin:auto;margin:3px"> <div id="id_dialogOptions"></div> </div> <div id="dialog3" style="margin:auto;margin:3px"> <div style="height:26px"> <select id="d3uploadMode" style="float:right;width:260px" onchange="d3modechange()"> <option value="1">Local file upload <option value="2">Server file selection </select> <div>File Selection</div> </div> <div id="d3localmode" style="height:26px;display:none"> <form id="d3localmodeform" method="post" enctype="multipart/form-data" action="uploadfile.ashx" target="fileUploadFrame"> <input type="text" id="d3attrib" name="attrib" style="display:none"> <input type="file" id="d3localFile" name="files" style="float:right;width:260px" onchange="d3setActions()"> <input type="submit" id="d3submit" style="display:none"> </form> <div>Upload File</div> </div> <div id="d3servermode"> <div style="width:100%;background-color:#d3d9d6;text-align:left;padding:3px" valign="bottom"> <input type="button" id="p3FolderUp" disabled="disabled" onclick="d3folderup()" value="Up">&nbsp; </div> <div id="d3serverfiles" style="width:100%;height:150px;background-color:white;padding:2px;border:1px solid gray;overflow-y:scroll"></div> </div> </div> <div id="dialog7" style="margin:auto;margin:3px"> <div id="d7meshkvm"> <h4 style="width:100%;border-bottom:1px solid gray">Agent Remote Desktop</h4> <div style="margin:3px 0 3px 0"> <select id="d7bitmapquality" style="float:right;width:200px;height:20px" dir="rtl"></select> <div style="height:20px">Quality</div> </div> <div style="margin:3px 0 3px 0"> <select id="d7bitmapscaling" style="float:right;width:200px;height:20px" dir="rtl"> <option selected="selected" value="1024">100% <option value="896">87.5% <option value="768">75% <option value="640">62.5% <option value="512">50% <option value="384">37.5% <option value="256">25% <option value="128">12.5% </select> <div style="height:20px">Scaling</div> </div> <div style="margin:3px 0 3px 0"> <select id="d7framelimiter" style="float:right;width:200px;height:20px" dir="rtl"> <option selected="selected" value="50">Fast <option value="100">Medium <option value="400">Slow <option value="1000">Very slow </select> <div style="height:20px">Frame rate</div> </div> </div> <div id="d7amtkvm"> <h4 style="width:100%;border-bottom:1px solid gray">Intel&reg; AMT Hardware KVM</h4> <div style='height:26px'> <select id="d7desktopmode" style="float:right;width:200px"> <option value="1">RLE8, Fastest <option value="2">RLE16, Recommended <option value="3">RAW8, Slow <option value="4">RAW16, Very Slow </select> <div>Image Encoding</div> </div> <div style="height:60px"> <div style="float:right;border:1px solid #666;width:200px;height:60px;overflow-y:scroll;background-color:white"> <label><input type="checkbox" id='d7showfocus'>Show Focus Tool<br></label> <label><input type="checkbox" id='d7showcursor'>Show Local Mouse Cursor<br></label> <label><input type="checkbox" id='d7localKeyMap'>Local Keyboard Map<br></label> </div> <div>Other Settings</div> </div> </div> </div> </div> <div id="idx_dlgButtonBar" style="padding:10px;margin-bottom:4px"> <input id="idx_dlgCancelButton" type="button" value="Cancel" style="float:right;width:80px;margin-left:5px" onclick="dialogclose(0)"> <input id="idx_dlgOkButton" type="button" value="OK" style="float:right;width:80px" onclick="dialogclose(1)"> <div style="height:25px"><input id="idx_dlgDeleteButton" type="button" value="Delete" style="width:80px;display:none" onclick="dialogclose(2)"></div> </div> </div> <iframe name="fileUploadFrame" style="display:none"></iframe> <form style="display:none" method="post" action="uploadfile.ashx" enctype="multipart/form-data" target="fileUploadFrame"><input id="p5fileDragName" name="name"><input id="p5fileDragSize" name="size"><input id="p5fileDragType" name="type"><input id="p5fileDragData" name="data"><input id="p5fileDragLink" name="link"><input type="submit" id="p5loginSubmit2" style="display:none"></form> <form style="display:none" method="post" action="uploadnodefile.ashx" enctype="multipart/form-data" target="fileUploadFrame"><input id="p13fileDragName" name="name"><input id="p13fileDragSize" name="size"><input id="p13fileDragType" name="type"><input id="p13fileDragData" name="data"><input id="p13fileDragLink" name="link"><input type="submit" id="p13loginSubmit2" style="display:none"></form> <audio id="chimes"><source src="sounds/chimes.mp3" type="audio/mp3"></source></audio> </div> </div> <script>/**
2 -* @description Set of short commonly used methods for handling HTML elements
3 -* @author Ylian Saint-Hilaire
4 -* @version v0.0.1b
5 -*/
6 -
7 -// Add startsWith for IE browser
8 -if (!String.prototype.startsWith) { String.prototype.startsWith = function (str) { return this.lastIndexOf(str, 0) === 0; }; }
9 -if (!String.prototype.endsWith) { String.prototype.endsWith = function (str) { return this.indexOf(str, this.length - str.length) !== -1; }; }
10 -
11 -// Quick UI functions, a bit of a replacement for jQuery
12 -//function Q(x) { if (document.getElementById(x) == null) { console.log('Invalid element: ' + x); } return document.getElementById(x); } // "Q"
13 -function Q(x) { return document.getElementById(x); } // "Q"
14 -function QS(x) { try { return Q(x).style; } catch (x) { } } // "Q" style
15 -function QE(x, y) { try { Q(x).disabled = !y; } catch (x) { } } // "Q" enable
16 -function QV(x, y) { try { QS(x).display = (y ? '' : 'none'); } catch (x) { } } // "Q" visible
17 -function QA(x, y) { Q(x).innerHTML += y; } // "Q" append
18 -function QH(x, y) { Q(x).innerHTML = y; } // "Q" html
19 -
20 -// Move cursor to end of input box
21 -function inputBoxFocus(x) { Q(x).focus(); var v = Q(x).value; Q(x).value = ''; Q(x).value = v; }
22 -
23 -// Binary encoding and decoding functions
24 -function ReadShort(v, p) { return (v.charCodeAt(p) << 8) + v.charCodeAt(p + 1); }
25 -function ReadShortX(v, p) { return (v.charCodeAt(p + 1) << 8) + v.charCodeAt(p); }
26 -function ReadInt(v, p) { return (v.charCodeAt(p) * 0x1000000) + (v.charCodeAt(p + 1) << 16) + (v.charCodeAt(p + 2) << 8) + v.charCodeAt(p + 3); } // We use "*0x1000000" instead of "<<24" because the shift converts the number to signed int32.
27 -function ReadSInt(v, p) { return (v.charCodeAt(p) << 24) + (v.charCodeAt(p + 1) << 16) + (v.charCodeAt(p + 2) << 8) + v.charCodeAt(p + 3); }
28 -function ReadIntX(v, p) { return (v.charCodeAt(p + 3) * 0x1000000) + (v.charCodeAt(p + 2) << 16) + (v.charCodeAt(p + 1) << 8) + v.charCodeAt(p); }
29 -function ShortToStr(v) { return String.fromCharCode((v >> 8) & 0xFF, v & 0xFF); }
30 -function ShortToStrX(v) { return String.fromCharCode(v & 0xFF, (v >> 8) & 0xFF); }
31 -function IntToStr(v) { return String.fromCharCode((v >> 24) & 0xFF, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF); }
32 -function IntToStrX(v) { return String.fromCharCode(v & 0xFF, (v >> 8) & 0xFF, (v >> 16) & 0xFF, (v >> 24) & 0xFF); }
33 -function MakeToArray(v) { if (!v || v == null || typeof v == 'object') return v; return [v]; }
34 -function SplitArray(v) { return v.split(','); }
35 -function Clone(v) { return JSON.parse(JSON.stringify(v)); }
36 -function EscapeHtml(x) { if (typeof x == "string") return x.replace(/&/g, '&amp;').replace(/>/g, '&gt;').replace(/</g, '&lt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;'); if (typeof x == "boolean") return x; if (typeof x == "number") return x; }
37 -function EscapeHtmlBreaks(x) { if (typeof x == "string") return x.replace(/&/g, '&amp;').replace(/>/g, '&gt;').replace(/</g, '&lt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;').replace(/\r/g, '<br />').replace(/\n/g, '').replace(/\t/g, '&nbsp;&nbsp;'); if (typeof x == "boolean") return x; if (typeof x == "number") return x; }
38 -
39 -// Move an element from one position in an array to a new position
40 -function ArrayElementMove(arr, from, to) { arr.splice(to, 0, arr.splice(from, 1)[0]); };
41 -
42 -// Print object for HTML
43 -function ObjectToStringEx(x, c) {
44 - var r = "";
45 - if (x != 0 && (!x || x == null)) return "(Null)";
46 - if (x instanceof Array) { for (var i in x) { r += '<br />' + gap(c) + "Item #" + i + ": " + ObjectToStringEx(x[i], c + 1); } }
47 - else if (x instanceof Object) { for (var i in x) { r += '<br />' + gap(c) + i + " = " + ObjectToStringEx(x[i], c + 1); } }
48 - else { r += EscapeHtml(x); }
49 - return r;
50 -}
51 -
52 -// Print object for console
53 -function ObjectToStringEx2(x, c) {
54 - var r = "";
55 - if (x != 0 && (!x || x == null)) return "(Null)";
56 - if (x instanceof Array) { for (var i in x) { r += '\r\n' + gap2(c) + "Item #" + i + ": " + ObjectToStringEx2(x[i], c + 1); } }
57 - else if (x instanceof Object) { for (var i in x) { r += '\r\n' + gap2(c) + i + " = " + ObjectToStringEx2(x[i], c + 1); } }
58 - else { r += EscapeHtml(x); }
59 - return r;
60 -}
61 -
62 -// Create an ident gap
63 -function gap(c) { var x = ''; for (var i = 0; i < (c * 4) ; i++) { x += '&nbsp;'; } return x; }
64 -function gap2(c) { var x = ''; for (var i = 0; i < (c * 4) ; i++) { x += ' '; } return x; }
65 -
66 -// Print an object in html
67 -function ObjectToString(x) { return ObjectToStringEx(x, 0); }
68 -function ObjectToString2(x) { return ObjectToStringEx2(x, 0); }
69 -
70 -// Convert a hex string to a raw string
71 -function hex2rstr(d) {
72 - if (typeof d != "string" || d.length == 0) return '';
73 - var r = '', m = ('' + d).match(/../g), t;
74 - while (t = m.shift()) r += String.fromCharCode('0x' + t);
75 - return r
76 -}
77 -
78 -// Convert decimal to hex
79 -function char2hex(i) { return (i + 0x100).toString(16).substr(-2).toUpperCase(); }
80 -
81 -// Convert a raw string to a hex string
82 -function rstr2hex(input) { var r = '', i; for (i = 0; i < input.length; i++) { r += char2hex(input.charCodeAt(i)); } return r; }
83 -
84 -// UTF-8 encoding & decoding functions
85 -function encode_utf8(s) { return unescape(encodeURIComponent(s)); }
86 -function decode_utf8(s) { return decodeURIComponent(escape(s)); }
87 -
88 -// Convert a string into a blob
89 -function data2blob(data) {
90 - var bytes = new Array(data.length);
91 - for (var i = 0; i < data.length; i++) bytes[i] = data.charCodeAt(i);
92 - var blob = new Blob([new Uint8Array(bytes)]);
93 - return blob;
94 -}
95 -
96 -// Generate random numbers
97 -function random(max) { return Math.floor(Math.random() * max); }
98 -
99 -// Trademarks
100 -function trademarks(x) { return x.replace(/\(R\)/g, '&reg;').replace(/\(TM\)/g, '&trade;'); }
101 -/**
102 -* @fileoverview Meshcentral.js
103 -* @author Ylian Saint-Hilaire
104 -* @version v0.0.1
105 -*/
106 -
107 -var MeshServerCreateControl = function (domain, authCookie) {
108 - var obj = {};
109 - obj.State = 0;
110 - obj.connectstate = 0;
111 - obj.pingTimer = null;
112 - obj.authCookie = authCookie;
113 -
114 - obj.xxStateChange = function (newstate, errCode) {
115 - if (obj.State == newstate) return;
116 - var previousState = obj.State;
117 - obj.State = newstate;
118 - if (obj.onStateChanged) obj.onStateChanged(obj, obj.State, previousState, errCode);
119 - }
120 -
121 - obj.Start = function () {
122 - if (obj.connectstate != 0) return;
123 - obj.connectstate = 0;
124 - var url = window.location.protocol.replace("http", "ws") + "//" + window.location.host + domain + "control.ashx";
125 - if (obj.authCookie && (obj.authCookie != '')) { url += '?auth=' + obj.authCookie; }
126 - obj.socket = new WebSocket(url);
127 - obj.socket.onopen = function (e) { obj.connectstate = 1; }
128 - obj.socket.onmessage = obj.xxOnMessage;
129 - obj.socket.onclose = function(e) { obj.Stop(e.code); }
130 - obj.xxStateChange(1, 0);
131 - if (obj.pingTimer != null) { clearInterval(obj.pingTimer); }
132 - obj.pingTimer = setInterval(function () { obj.send({ action: 'ping' }); }, 29000); // Ping the server every 29 seconds, stops corporate proxies from disconnecting.
133 - }
134 -
135 - obj.Stop = function (errCode) {
136 - obj.connectstate = 0;
137 - if (obj.socket) { obj.socket.close(); delete obj.socket; }
138 - if (obj.pingTimer != null) { clearInterval(obj.pingTimer); obj.pingTimer = null; }
139 - obj.xxStateChange(0, errCode);
140 - }
141 -
142 - obj.xxOnMessage = function (e) {
143 - if (obj.State == 1) { obj.xxStateChange(2); }
144 - //console.log('xxOnMessage', e.data);
145 - var message;
146 - try { message = JSON.parse(e.data); } catch (e) { return; }
147 - if ((typeof message != 'object') || (message.action == 'pong')) { return; }
148 - if (message.action == 'close') { if (message.msg) { console.log(message.msg); } obj.Stop(message.cause); return; }
149 - if (obj.onMessage) obj.onMessage(obj, message);
150 - };
151 -
152 - obj.send = function (x) { if (obj.socket != null && obj.connectstate == 1) { obj.socket.send(JSON.stringify(x)); } }
153 -
154 - return obj;
155 -}
156 -/**
157 -* @fileoverview Intel(r) AMT Communication Stack
158 -* @author Ylian Saint-Hilaire
159 -* @version v0.2.0b
160 -*/
161 -
162 -/**
163 - * Construct a AmtStackCreateService object, this ia the main Intel AMT communication stack.
164 - * @constructor
165 - */
166 -function AmtStackCreateService(wsmanStack) {
167 - var obj = new Object();
168 - obj.wsman = wsmanStack;
169 - obj.pfx = ["http://intel.com/wbem/wscim/1/amt-schema/1/", "http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/", "http://intel.com/wbem/wscim/1/ips-schema/1/"];
170 - obj.PendingEnums = [];
171 - obj.PendingBatchOperations = 0;
172 - obj.ActiveEnumsCount = 0;
173 - obj.MaxActiveEnumsCount = 1; // Maximum number of enumerations that can be done at the same time.
174 - obj.onProcessChanged = null;
175 - var _MaxProcess = 0;
176 - var _LastProcess = 0;
177 -
178 - // Return the number of pending actions
179 - obj.GetPendingActions = function () { return (obj.PendingEnums.length * 2) + (obj.ActiveEnumsCount) + obj.wsman.comm.PendingAjax.length + obj.wsman.comm.ActiveAjaxCount + obj.PendingBatchOperations; }
180 -
181 - // Private Method, Update the current processing status, this gives the application an idea of what progress is being done by the WSMAN stack
182 - function _up() {
183 - var x = obj.GetPendingActions();
184 - if (_MaxProcess < x) _MaxProcess = x;
185 - if (obj.onProcessChanged != null && _LastProcess != x) {
186 - //console.log("Process Old=" + _LastProcess + ", New=" + x + ", PEnums=" + obj.PendingEnums.length + ", AEnums=" + obj.ActiveEnumsCount + ", PAjax=" + obj.wsman.comm.PendingAjax.length + ", AAjax=" + obj.wsman.comm.ActiveAjaxCount + ", PBatch=" + obj.PendingBatchOperations);
187 - _LastProcess = x;
188 - obj.onProcessChanged(x, _MaxProcess);
189 - }
190 - if (x == 0) _MaxProcess = 0;
191 - }
192 -
193 - // Perform a WSMAN "SUBSCRIBE" operation.
194 - obj.Subscribe = function (name, delivery, url, callback, tag, pri, selectors, opaque, user, pass) { obj.wsman.ExecSubscribe(obj.CompleteName(name), delivery, url, function (ws, resuri, response, xstatus) { _up(); callback(obj, name, response, xstatus, tag); }, 0, pri, selectors, opaque, user, pass); _up(); }
195 -
196 - // Perform a WSMAN "UNSUBSCRIBE" operation.
197 - obj.UnSubscribe = function (name, callback, tag, pri, selectors) { obj.wsman.ExecUnSubscribe(obj.CompleteName(name), function (ws, resuri, response, xstatus) { _up(); callback(obj, name, response, xstatus, tag); }, 0, pri, selectors); _up(); }
198 -
199 - // Perform a WSMAN "GET" operation.
200 - obj.Get = function (name, callback, tag, pri) { obj.wsman.ExecGet(obj.CompleteName(name), function (ws, resuri, response, xstatus) { _up(); callback(obj, name, response, xstatus, tag); }, 0, pri); _up(); }
201 -
202 - // Perform a WSMAN "PUT" operation.
203 - obj.Put = function (name, putobj, callback, tag, pri, selectors) { obj.wsman.ExecPut(obj.CompleteName(name), putobj, function (ws, resuri, response, xstatus) { _up(); callback(obj, name, response, xstatus, tag); }, 0, pri, selectors); _up(); }
204 -
205 - // Perform a WSMAN "CREATE" operation.
206 - obj.Create = function (name, putobj, callback, tag, pri) { obj.wsman.ExecCreate(obj.CompleteName(name), putobj, function (ws, resuri, response, xstatus) { _up(); callback(obj, name, response, xstatus, tag); }, 0, pri); _up(); }
207 -
208 - // Perform a WSMAN "DELETE" operation.
209 - obj.Delete = function (name, putobj, callback, tag, pri) { obj.wsman.ExecDelete(obj.CompleteName(name), putobj, function (ws, resuri, response, xstatus) { _up(); callback(obj, name, response, xstatus, tag); }, 0, pri); _up(); }
210 -
211 - // Perform a WSMAN method call operation.
212 - obj.Exec = function (name, method, args, callback, tag, pri, selectors) { obj.wsman.ExecMethod(obj.CompleteName(name), method, args, function (ws, resuri, response, xstatus) { _up(); callback(obj, name, obj.CompleteExecResponse(response), xstatus, tag); }, 0, pri, selectors); _up(); }
213 -
214 - // Perform a WSMAN method call operation.
215 - obj.ExecWithXml = function (name, method, args, callback, tag, pri, selectors) { obj.wsman.ExecMethodXml(obj.CompleteName(name), method, execArgumentsToXml(args), function (ws, resuri, response, xstatus) { _up(); callback(obj, name, obj.CompleteExecResponse(response), xstatus, tag); }, 0, pri, selectors); _up(); }
216 -
217 - // Perform a WSMAN "ENUMERATE" operation.
218 - obj.Enum = function (name, callback, tag, pri) {
219 - if (obj.ActiveEnumsCount < obj.MaxActiveEnumsCount) {
220 - obj.ActiveEnumsCount++; obj.wsman.ExecEnum(obj.CompleteName(name), function (ws, resuri, response, xstatus, tag0) { _up(); _EnumStartSink(name, response, callback, resuri, xstatus, tag0); }, tag, pri);
221 - } else {
222 - obj.PendingEnums.push([name, callback, tag, pri]);
223 - }
224 - _up();
225 - }
226 -
227 - // Private method
228 - function _EnumStartSink(name, response, callback, resuri, status, tag, pri) {
229 - if (status != 200) { callback(obj, name, null, status, tag); _EnumDoNext(1); return; }
230 - if (response == null || response.Header["Method"] != "EnumerateResponse" || !response.Body["EnumerationContext"]) { callback(obj, name, null, 603, tag); _EnumDoNext(1); return; }
231 - var enumctx = response.Body["EnumerationContext"];
232 - obj.wsman.ExecPull(resuri, enumctx, function (ws, resuri, response, xstatus) { _EnumContinueSink(name, response, callback, resuri, [], xstatus, tag, pri); });
233 - }
234 -
235 - // Private method
236 - function _EnumContinueSink(name, response, callback, resuri, items, status, tag, pri) {
237 - if (status != 200) { callback(obj, name, null, status, tag); _EnumDoNext(1); return; }
238 - if (response == null || response.Header["Method"] != "PullResponse") { callback(obj, name, null, 604, tag); _EnumDoNext(1); return; }
239 - for (var i in response.Body["Items"]) {
240 - if (response.Body["Items"][i] instanceof Array) {
241 - for (var j in response.Body["Items"][i]) { items.push(response.Body["Items"][i][j]); }
242 - } else {
243 - items.push(response.Body["Items"][i]);
244 - }
245 - }
246 - if (response.Body["EnumerationContext"]) {
247 - var enumctx = response.Body["EnumerationContext"];
248 - obj.wsman.ExecPull(resuri, enumctx, function (ws, resuri, response, xstatus) { _EnumContinueSink(name, response, callback, resuri, items, xstatus, tag, 1); });
249 - } else {
250 - _EnumDoNext(1);
251 - callback(obj, name, items, status, tag);
252 - _up();
253 - }
254 - }
255 -
256 - // Private method
257 - function _EnumDoNext(dec) {
258 - obj.ActiveEnumsCount -= dec;
259 - if (obj.ActiveEnumsCount >= obj.MaxActiveEnumsCount || obj.PendingEnums.length == 0) return;
260 - var x = obj.PendingEnums.shift();
261 - obj.Enum(x[0], x[1], x[2]);
262 - _EnumDoNext(0);
263 - }
264 -
265 - // Perform a batch of WSMAN "ENUM" operations.
266 - obj.BatchEnum = function (batchname, names, callback, tag, continueOnError, pri) {
267 - obj.PendingBatchOperations += (names.length * 2);
268 - _BatchNextEnum(batchname, Clone(names), callback, tag, {}, continueOnError, pri); _up();
269 - }
270 -
271 - // Request each enum in the batch, stopping if something does not return status 200
272 - function _BatchNextEnum(batchname, names, callback, tag, results, continueOnError, pri) {
273 - obj.PendingBatchOperations -= 2;
274 - var n = names.shift(), f = obj.Enum;
275 - if (n[0] == '*') { f = obj.Get; n = n.substring(1); } // If the name starts with a star, do a GET instead of an ENUM. This will reduce round trips.
276 - //console.log((f == obj.Get?'Get ':'Enum ') + n);
277 - // Perform a GET/ENUM action
278 - f(n, function (stack, name, responses, status, tag0) {
279 - tag0[2][name] = { response: (responses==null?null:responses.Body), responses: responses, status: status };
280 - if (tag0[1].length == 0 || status == 401 || (continueOnError != true && status != 200 && status != 400)) { obj.PendingBatchOperations -= (names.length * 2); _up(); callback(obj, batchname, tag0[2], status, tag); }
281 - else { _up(); _BatchNextEnum(batchname, names, callback, tag, tag0[2], pri); }
282 - }, [batchname, names, results], pri);
283 - _up();
284 - }
285 -
286 - // Perform a batch of WSMAN "GET" operations.
287 - obj.BatchGet = function (batchname, names, callback, tag, pri) {
288 - _FetchNext({ name: batchname, names: names, callback: callback, current: 0, responses: {}, tag: tag, pri: pri }); _up();
289 - }
290 -
291 - // Private method
292 - function _FetchNext(batch) {
293 - if (batch.names.length <= batch.current) {
294 - batch.callback(obj, batch.name, batch.responses, 200, batch.tag);
295 - } else {
296 - obj.wsman.ExecGet(obj.CompleteName(batch.names[batch.current]), function (ws, resuri, response, xstatus) { _Fetched(batch, response, xstatus); }, batch.pri);
297 - batch.current++;
298 - }
299 - _up();
300 - }
301 -
302 - // Private method
303 - function _Fetched(batch, response, status) {
304 - if (response == null || status != 200) {
305 - batch.callback(obj, batch.name, null, status, batch.tag);
306 - } else {
307 - batch.responses[response.Header["Method"]] = response;
308 - _FetchNext(batch);
309 - }
310 - }
311 -
312 - // Private method
313 - obj.CompleteName = function(name) {
314 - if (name.indexOf("AMT_") == 0) return obj.pfx[0] + name;
315 - if (name.indexOf("CIM_") == 0) return obj.pfx[1] + name;
316 - if (name.indexOf("IPS_") == 0) return obj.pfx[2] + name;
317 - }
318 -
319 - obj.CompleteExecResponse = function (resp) {
320 - if (resp && resp != null && resp.Body && resp.Body["ReturnValue"]) resp.Body.ReturnValueStr = obj.AmtStatusToStr(resp.Body["ReturnValue"]);
321 - return resp;
322 - }
323 -
324 - obj.RequestPowerStateChange = function (PowerState, callback_func) {
325 - obj.CIM_PowerManagementService_RequestPowerStateChange(PowerState, "<Address xmlns=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\">http://schemas.xmlsoap.org/ws/2004/08/addressing</Address><ReferenceParameters xmlns=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\"><ResourceURI xmlns=\"http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd\">http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ComputerSystem</ResourceURI><SelectorSet xmlns=\"http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd\"><Selector Name=\"CreationClassName\">CIM_ComputerSystem</Selector><Selector Name=\"Name\">ManagedSystem</Selector></SelectorSet></ReferenceParameters>", null, null, callback_func);
326 - }
327 -
328 - obj.SetBootConfigRole = function (Role, callback_func) {
329 - obj.CIM_BootService_SetBootConfigRole("<Address xmlns=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\">http://schemas.xmlsoap.org/ws/2004/08/addressing</Address><ReferenceParameters xmlns=\"http://schemas.xmlsoap.org/ws/2004/08/addressing\"><ResourceURI xmlns=\"http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd\">http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_BootConfigSetting</ResourceURI><SelectorSet xmlns=\"http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd\"><Selector Name=\"InstanceID\">Intel(r) AMT: Boot Configuration 0</Selector></SelectorSet></ReferenceParameters>", Role, callback_func);
330 - }
331 -
332 - // Cancel all pending queries with given status
333 - obj.CancelAllQueries = function (s) {
334 - obj.wsman.CancelAllQueries(s);
335 - }
336 -
337 - // Auto generated methods
338 - obj.AMT_AgentPresenceWatchdog_RegisterAgent = function (callback_func) { obj.Exec("AMT_AgentPresenceWatchdog", "RegisterAgent", {}, callback_func); }
339 - obj.AMT_AgentPresenceWatchdog_AssertPresence = function (SequenceNumber, callback_func) { obj.Exec("AMT_AgentPresenceWatchdog", "AssertPresence", { "SequenceNumber": SequenceNumber }, callback_func); }
340 - obj.AMT_AgentPresenceWatchdog_AssertShutdown = function (SequenceNumber, callback_func) { obj.Exec("AMT_AgentPresenceWatchdog", "AssertShutdown", { "SequenceNumber": SequenceNumber }, callback_func); }
341 - obj.AMT_AgentPresenceWatchdog_AddAction = function (OldState, NewState, EventOnTransition, ActionSd, ActionEac, callback_func, tag, pri, selectors) { obj.Exec("AMT_AgentPresenceWatchdog", "AddAction", { "OldState": OldState, "NewState": NewState, "EventOnTransition": EventOnTransition, "ActionSd": ActionSd, "ActionEac": ActionEac }, callback_func, tag, pri, selectors); }
342 - obj.AMT_AgentPresenceWatchdog_DeleteAllActions = function (callback_func, tag, pri, selectors) { obj.Exec("AMT_AgentPresenceWatchdog", "DeleteAllActions", {}, callback_func, tag, pri, selectors); }
343 - obj.AMT_AgentPresenceWatchdogAction_GetActionEac = function (callback_func) { obj.Exec("AMT_AgentPresenceWatchdogAction", "GetActionEac", {}, callback_func); }
344 - obj.AMT_AgentPresenceWatchdogVA_RegisterAgent = function (callback_func) { obj.Exec("AMT_AgentPresenceWatchdogVA", "RegisterAgent", {}, callback_func); }
345 - obj.AMT_AgentPresenceWatchdogVA_AssertPresence = function (SequenceNumber, callback_func) { obj.Exec("AMT_AgentPresenceWatchdogVA", "AssertPresence", { "SequenceNumber": SequenceNumber }, callback_func); }
346 - obj.AMT_AgentPresenceWatchdogVA_AssertShutdown = function (SequenceNumber, callback_func) { obj.Exec("AMT_AgentPresenceWatchdogVA", "AssertShutdown", { "SequenceNumber": SequenceNumber }, callback_func); }
347 - obj.AMT_AgentPresenceWatchdogVA_AddAction = function (OldState, NewState, EventOnTransition, ActionSd, ActionEac, callback_func) { obj.Exec("AMT_AgentPresenceWatchdogVA", "AddAction", { "OldState": OldState, "NewState": NewState, "EventOnTransition": EventOnTransition, "ActionSd": ActionSd, "ActionEac": ActionEac }, callback_func); }
348 - obj.AMT_AgentPresenceWatchdogVA_DeleteAllActions = function (_method_dummy, callback_func) { obj.Exec("AMT_AgentPresenceWatchdogVA", "DeleteAllActions", { "_method_dummy": _method_dummy }, callback_func); }
349 - obj.AMT_AuditLog_ClearLog = function (callback_func) { obj.Exec("AMT_AuditLog", "ClearLog", {}, callback_func); }
350 - obj.AMT_AuditLog_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("AMT_AuditLog", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
351 - obj.AMT_AuditLog_ReadRecords = function (StartIndex, callback_func, tag) { obj.Exec("AMT_AuditLog", "ReadRecords", { "StartIndex": StartIndex }, callback_func, tag); }
352 - obj.AMT_AuditLog_SetAuditLock = function (LockTimeoutInSeconds, Flag, Handle, callback_func) { obj.Exec("AMT_AuditLog", "SetAuditLock", { "LockTimeoutInSeconds": LockTimeoutInSeconds, "Flag": Flag, "Handle": Handle }, callback_func); }
353 - obj.AMT_AuditLog_ExportAuditLogSignature = function (SigningMechanism, callback_func) { obj.Exec("AMT_AuditLog", "ExportAuditLogSignature", { "SigningMechanism": SigningMechanism }, callback_func); }
354 - obj.AMT_AuditLog_SetSigningKeyMaterial = function (SigningMechanismType, SigningKey, LengthOfCertificates, Certificates, callback_func) { obj.Exec("AMT_AuditLog", "SetSigningKeyMaterial", { "SigningMechanismType": SigningMechanismType, "SigningKey": SigningKey, "LengthOfCertificates": LengthOfCertificates, "Certificates": Certificates }, callback_func); }
355 - obj.AMT_AuditPolicyRule_SetAuditPolicy = function (Enable, AuditedAppID, EventID, PolicyType, callback_func) { obj.Exec("AMT_AuditPolicyRule", "SetAuditPolicy", { "Enable": Enable, "AuditedAppID": AuditedAppID, "EventID": EventID, "PolicyType": PolicyType }, callback_func); }
356 - obj.AMT_AuditPolicyRule_SetAuditPolicyBulk = function (Enable, AuditedAppID, EventID, PolicyType, callback_func) { obj.Exec("AMT_AuditPolicyRule", "SetAuditPolicyBulk", { "Enable": Enable, "AuditedAppID": AuditedAppID, "EventID": EventID, "PolicyType": PolicyType }, callback_func); }
357 - obj.AMT_AuthorizationService_AddUserAclEntryEx = function (DigestUsername, DigestPassword, KerberosUserSid, AccessPermission, Realms, callback_func) { obj.Exec("AMT_AuthorizationService", "AddUserAclEntryEx", { "DigestUsername": DigestUsername, "DigestPassword": DigestPassword, "KerberosUserSid": KerberosUserSid, "AccessPermission": AccessPermission, "Realms": Realms }, callback_func); }
358 - obj.AMT_AuthorizationService_EnumerateUserAclEntries = function (StartIndex, callback_func) { obj.Exec("AMT_AuthorizationService", "EnumerateUserAclEntries", { "StartIndex": StartIndex }, callback_func); }
359 - obj.AMT_AuthorizationService_GetUserAclEntryEx = function (Handle, callback_func, tag) { obj.Exec("AMT_AuthorizationService", "GetUserAclEntryEx", { "Handle": Handle }, callback_func, tag); }
360 - obj.AMT_AuthorizationService_UpdateUserAclEntryEx = function (Handle, DigestUsername, DigestPassword, KerberosUserSid, AccessPermission, Realms, callback_func) { obj.Exec("AMT_AuthorizationService", "UpdateUserAclEntryEx", { "Handle": Handle, "DigestUsername": DigestUsername, "DigestPassword": DigestPassword, "KerberosUserSid": KerberosUserSid, "AccessPermission": AccessPermission, "Realms": Realms }, callback_func); }
361 - obj.AMT_AuthorizationService_RemoveUserAclEntry = function (Handle, callback_func) { obj.Exec("AMT_AuthorizationService", "RemoveUserAclEntry", { "Handle": Handle }, callback_func); }
362 - obj.AMT_AuthorizationService_SetAdminAclEntryEx = function (Username, DigestPassword, callback_func) { obj.Exec("AMT_AuthorizationService", "SetAdminAclEntryEx", { "Username": Username, "DigestPassword": DigestPassword }, callback_func); }
363 - obj.AMT_AuthorizationService_GetAdminAclEntry = function (callback_func) { obj.Exec("AMT_AuthorizationService", "GetAdminAclEntry", {}, callback_func); }
364 - obj.AMT_AuthorizationService_GetAdminAclEntryStatus = function (callback_func) { obj.Exec("AMT_AuthorizationService", "GetAdminAclEntryStatus", {}, callback_func); }
365 - obj.AMT_AuthorizationService_GetAdminNetAclEntryStatus = function (callback_func) { obj.Exec("AMT_AuthorizationService", "GetAdminNetAclEntryStatus", {}, callback_func); }
366 - obj.AMT_AuthorizationService_SetAclEnabledState = function (Handle, Enabled, callback_func, tag) { obj.Exec("AMT_AuthorizationService", "SetAclEnabledState", { "Handle": Handle, "Enabled": Enabled }, callback_func, tag); }
367 - obj.AMT_AuthorizationService_GetAclEnabledState = function (Handle, callback_func, tag) { obj.Exec("AMT_AuthorizationService", "GetAclEnabledState", { "Handle": Handle }, callback_func, tag); }
368 - obj.AMT_EndpointAccessControlService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("AMT_EndpointAccessControlService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
369 - obj.AMT_EndpointAccessControlService_GetPosture = function (PostureType, callback_func) { obj.Exec("AMT_EndpointAccessControlService", "GetPosture", { "PostureType": PostureType }, callback_func); }
370 - obj.AMT_EndpointAccessControlService_GetPostureHash = function (PostureType, callback_func) { obj.Exec("AMT_EndpointAccessControlService", "GetPostureHash", { "PostureType": PostureType }, callback_func); }
371 - obj.AMT_EndpointAccessControlService_UpdatePostureState = function (UpdateType, callback_func) { obj.Exec("AMT_EndpointAccessControlService", "UpdatePostureState", { "UpdateType": UpdateType }, callback_func); }
372 - obj.AMT_EndpointAccessControlService_GetEacOptions = function (callback_func) { obj.Exec("AMT_EndpointAccessControlService", "GetEacOptions", {}, callback_func); }
373 - obj.AMT_EndpointAccessControlService_SetEacOptions = function (EacVendors, PostureHashAlgorithm, callback_func) { obj.Exec("AMT_EndpointAccessControlService", "SetEacOptions", { "EacVendors": EacVendors, "PostureHashAlgorithm": PostureHashAlgorithm }, callback_func); }
374 - obj.AMT_EnvironmentDetectionSettingData_SetSystemDefensePolicy = function (Policy, callback_func) { obj.Exec("AMT_EnvironmentDetectionSettingData", "SetSystemDefensePolicy", { "Policy": Policy }, callback_func); }
375 - obj.AMT_EnvironmentDetectionSettingData_EnableVpnRouting = function (Enable, callback_func) { obj.Exec("AMT_EnvironmentDetectionSettingData", "EnableVpnRouting", { "Enable": Enable }, callback_func); }
376 - obj.AMT_EthernetPortSettings_SetLinkPreference = function (LinkPreference, Timeout, callback_func) { obj.Exec("AMT_EthernetPortSettings", "SetLinkPreference", { "LinkPreference": LinkPreference, "Timeout": Timeout }, callback_func); }
377 - obj.AMT_HeuristicPacketFilterStatistics_ResetSelectedStats = function (SelectedStatistics, callback_func) { obj.Exec("AMT_HeuristicPacketFilterStatistics", "ResetSelectedStats", { "SelectedStatistics": SelectedStatistics }, callback_func); }
378 - obj.AMT_KerberosSettingData_GetCredentialCacheState = function (callback_func) { obj.Exec("AMT_KerberosSettingData", "GetCredentialCacheState", {}, callback_func); }
379 - obj.AMT_KerberosSettingData_SetCredentialCacheState = function (Enable, callback_func) { obj.Exec("AMT_KerberosSettingData", "SetCredentialCacheState", { "Enable": Enable }, callback_func); }
380 - obj.AMT_MessageLog_CancelIteration = function (IterationIdentifier, callback_func) { obj.Exec("AMT_MessageLog", "CancelIteration", { "IterationIdentifier": IterationIdentifier }, callback_func); }
381 - obj.AMT_MessageLog_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("AMT_MessageLog", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
382 - obj.AMT_MessageLog_ClearLog = function (callback_func) { obj.Exec("AMT_MessageLog", "ClearLog", { }, callback_func); }
383 - obj.AMT_MessageLog_GetRecords = function (IterationIdentifier, MaxReadRecords, callback_func, tag) { obj.Exec("AMT_MessageLog", "GetRecords", { "IterationIdentifier": IterationIdentifier, "MaxReadRecords": MaxReadRecords }, callback_func, tag); }
384 - obj.AMT_MessageLog_GetRecord = function (IterationIdentifier, PositionToNext, callback_func) { obj.Exec("AMT_MessageLog", "GetRecord", { "IterationIdentifier": IterationIdentifier, "PositionToNext": PositionToNext }, callback_func); }
385 - obj.AMT_MessageLog_PositionAtRecord = function (IterationIdentifier, MoveAbsolute, RecordNumber, callback_func) { obj.Exec("AMT_MessageLog", "PositionAtRecord", { "IterationIdentifier": IterationIdentifier, "MoveAbsolute": MoveAbsolute, "RecordNumber": RecordNumber }, callback_func); }
386 - obj.AMT_MessageLog_PositionToFirstRecord = function (callback_func, tag) { obj.Exec("AMT_MessageLog", "PositionToFirstRecord", {}, callback_func, tag); }
387 - obj.AMT_MessageLog_FreezeLog = function (Freeze, callback_func) { obj.Exec("AMT_MessageLog", "FreezeLog", { "Freeze": Freeze }, callback_func); }
388 - obj.AMT_PublicKeyManagementService_AddCRL = function (Url, SerialNumbers, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "AddCRL", { "Url": Url, "SerialNumbers": SerialNumbers }, callback_func); }
389 - obj.AMT_PublicKeyManagementService_ResetCRLList = function (_method_dummy, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "ResetCRLList", { "_method_dummy": _method_dummy }, callback_func); }
390 - obj.AMT_PublicKeyManagementService_AddCertificate = function (CertificateBlob, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "AddCertificate", { "CertificateBlob": CertificateBlob }, callback_func); }
391 - obj.AMT_PublicKeyManagementService_AddTrustedRootCertificate = function (CertificateBlob, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "AddTrustedRootCertificate", { "CertificateBlob": CertificateBlob }, callback_func); }
392 - obj.AMT_PublicKeyManagementService_AddKey = function (KeyBlob, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "AddKey", { "KeyBlob": KeyBlob }, callback_func); }
393 - obj.AMT_PublicKeyManagementService_GeneratePKCS10Request = function (KeyPair, DNName, Usage, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "GeneratePKCS10Request", { "KeyPair": KeyPair, "DNName": DNName, "Usage": Usage }, callback_func); }
394 - obj.AMT_PublicKeyManagementService_GeneratePKCS10RequestEx = function (KeyPair, SigningAlgorithm, NullSignedCertificateRequest, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "GeneratePKCS10RequestEx", { "KeyPair": KeyPair, "SigningAlgorithm": SigningAlgorithm, "NullSignedCertificateRequest": NullSignedCertificateRequest }, callback_func); }
395 - obj.AMT_PublicKeyManagementService_GenerateKeyPair = function (KeyAlgorithm, KeyLength, callback_func) { obj.Exec("AMT_PublicKeyManagementService", "GenerateKeyPair", { "KeyAlgorithm": KeyAlgorithm, "KeyLength": KeyLength }, callback_func); }
396 - obj.AMT_RedirectionService_RequestStateChange = function (RequestedState, callback_func) { obj.Exec("AMT_RedirectionService", "RequestStateChange", { "RequestedState": RequestedState }, callback_func); }
397 - obj.AMT_RedirectionService_TerminateSession = function (SessionType, callback_func) { obj.Exec("AMT_RedirectionService", "TerminateSession", { "SessionType": SessionType }, callback_func); }
398 - obj.AMT_RemoteAccessService_AddMpServer = function (AccessInfo, InfoFormat, Port, AuthMethod, Certificate, Username, Password, CN, callback_func) { obj.Exec("AMT_RemoteAccessService", "AddMpServer", { "AccessInfo": AccessInfo, "InfoFormat": InfoFormat, "Port": Port, "AuthMethod": AuthMethod, "Certificate": Certificate, "Username": Username, "Password": Password, "CN": CN }, callback_func); }
399 - obj.AMT_RemoteAccessService_AddRemoteAccessPolicyRule = function (Trigger, TunnelLifeTime, ExtendedData, MpServer, callback_func) { obj.Exec("AMT_RemoteAccessService", "AddRemoteAccessPolicyRule", { "Trigger": Trigger, "TunnelLifeTime": TunnelLifeTime, "ExtendedData": ExtendedData, "MpServer": MpServer }, callback_func); }
400 - obj.AMT_RemoteAccessService_CloseRemoteAccessConnection = function (_method_dummy, callback_func) { obj.Exec("AMT_RemoteAccessService", "CloseRemoteAccessConnection", { "_method_dummy": _method_dummy }, callback_func); }
401 - obj.AMT_SetupAndConfigurationService_CommitChanges = function (_method_dummy, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "CommitChanges", { "_method_dummy": _method_dummy }, callback_func); }
402 - obj.AMT_SetupAndConfigurationService_Unprovision = function (ProvisioningMode, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "Unprovision", { "ProvisioningMode": ProvisioningMode }, callback_func); }
403 - obj.AMT_SetupAndConfigurationService_PartialUnprovision = function (_method_dummy, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "PartialUnprovision", { "_method_dummy": _method_dummy }, callback_func); }
404 - obj.AMT_SetupAndConfigurationService_ResetFlashWearOutProtection = function (_method_dummy, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "ResetFlashWearOutProtection", { "_method_dummy": _method_dummy }, callback_func); }
405 - obj.AMT_SetupAndConfigurationService_ExtendProvisioningPeriod = function (Duration, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "ExtendProvisioningPeriod", { "Duration": Duration }, callback_func); }
406 - obj.AMT_SetupAndConfigurationService_SetMEBxPassword = function (Password, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "SetMEBxPassword", { "Password": Password }, callback_func); }
407 - obj.AMT_SetupAndConfigurationService_SetTLSPSK = function (PID, PPS, callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "SetTLSPSK", { "PID": PID, "PPS": PPS }, callback_func); }
408 - obj.AMT_SetupAndConfigurationService_GetProvisioningAuditRecord = function (callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "GetProvisioningAuditRecord", {}, callback_func); }
409 - obj.AMT_SetupAndConfigurationService_GetUuid = function (callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "GetUuid", {}, callback_func); }
410 - obj.AMT_SetupAndConfigurationService_GetUnprovisionBlockingComponents = function (callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "GetUnprovisionBlockingComponents", {}, callback_func); }
411 - obj.AMT_SetupAndConfigurationService_GetProvisioningAuditRecordV2 = function (callback_func) { obj.Exec("AMT_SetupAndConfigurationService", "GetProvisioningAuditRecordV2", {}, callback_func); }
412 - obj.AMT_SystemDefensePolicy_GetTimeout = function (callback_func) { obj.Exec("AMT_SystemDefensePolicy", "GetTimeout", {}, callback_func); }
413 - obj.AMT_SystemDefensePolicy_SetTimeout = function (Timeout, callback_func) { obj.Exec("AMT_SystemDefensePolicy", "SetTimeout", { "Timeout": Timeout }, callback_func); }
414 - obj.AMT_SystemDefensePolicy_UpdateStatistics = function (NetworkInterface, ResetOnRead, callback_func, tag, pri, selectors) { obj.Exec("AMT_SystemDefensePolicy", "UpdateStatistics", { "NetworkInterface": NetworkInterface, "ResetOnRead": ResetOnRead }, callback_func, tag, pri, selectors); }
415 - obj.AMT_SystemPowerScheme_SetPowerScheme = function (callback_func, schemeInstanceId, tag) { obj.Exec("AMT_SystemPowerScheme", "SetPowerScheme", {}, callback_func, tag, 0, { "InstanceID": schemeInstanceId }); }
416 - obj.AMT_TimeSynchronizationService_GetLowAccuracyTimeSynch = function (callback_func, tag) { obj.Exec("AMT_TimeSynchronizationService", "GetLowAccuracyTimeSynch", {}, callback_func, tag); }
417 - obj.AMT_TimeSynchronizationService_SetHighAccuracyTimeSynch = function (Ta0, Tm1, Tm2, callback_func, tag) { obj.Exec("AMT_TimeSynchronizationService", "SetHighAccuracyTimeSynch", { "Ta0": Ta0, "Tm1": Tm1, "Tm2": Tm2 }, callback_func, tag); }
418 - obj.AMT_UserInitiatedConnectionService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("AMT_UserInitiatedConnectionService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
419 - obj.AMT_WebUIService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("AMT_WebUIService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
420 - obj.AMT_WiFiPortConfigurationService_AddWiFiSettings = function (WiFiEndpoint, WiFiEndpointSettingsInput, IEEE8021xSettingsInput, ClientCredential, CACredential, callback_func) { obj.ExecWithXml("AMT_WiFiPortConfigurationService", "AddWiFiSettings", { "WiFiEndpoint": WiFiEndpoint, "WiFiEndpointSettingsInput": WiFiEndpointSettingsInput, "IEEE8021xSettingsInput": IEEE8021xSettingsInput, "ClientCredential": ClientCredential, "CACredential": CACredential }, callback_func); }
421 - obj.AMT_WiFiPortConfigurationService_UpdateWiFiSettings = function (WiFiEndpointSettings, WiFiEndpointSettingsInput, IEEE8021xSettingsInput, ClientCredential, CACredential, callback_func) { obj.ExecWithXml("AMT_WiFiPortConfigurationService", "UpdateWiFiSettings", { "WiFiEndpointSettings": WiFiEndpointSettings, "WiFiEndpointSettingsInput": WiFiEndpointSettingsInput, "IEEE8021xSettingsInput": IEEE8021xSettingsInput, "ClientCredential": ClientCredential, "CACredential": CACredential }, callback_func); }
422 - obj.AMT_WiFiPortConfigurationService_DeleteAllITProfiles = function (_method_dummy, callback_func) { obj.Exec("AMT_WiFiPortConfigurationService", "DeleteAllITProfiles", { "_method_dummy": _method_dummy }, callback_func); }
423 - obj.AMT_WiFiPortConfigurationService_DeleteAllUserProfiles = function (_method_dummy, callback_func) { obj.Exec("AMT_WiFiPortConfigurationService", "DeleteAllUserProfiles", { "_method_dummy": _method_dummy }, callback_func); }
424 - obj.CIM_Account_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_Account", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
425 - obj.CIM_AccountManagementService_CreateAccount = function (System, AccountTemplate, callback_func) { obj.Exec("CIM_AccountManagementService", "CreateAccount", { "System": System, "AccountTemplate": AccountTemplate }, callback_func); }
426 - obj.CIM_BootConfigSetting_ChangeBootOrder = function (Source, callback_func) { obj.Exec("CIM_BootConfigSetting", "ChangeBootOrder", { "Source": Source }, callback_func); }
427 - obj.CIM_BootService_SetBootConfigRole = function (BootConfigSetting, Role, callback_func) { obj.Exec("CIM_BootService", "SetBootConfigRole", { "BootConfigSetting": BootConfigSetting, "Role": Role }, callback_func, 0, 1); }
428 - obj.CIM_Card_ConnectorPower = function (Connector, PoweredOn, callback_func) { obj.Exec("CIM_Card", "ConnectorPower", { "Connector": Connector, "PoweredOn": PoweredOn }, callback_func); }
429 - obj.CIM_Card_IsCompatible = function (ElementToCheck, callback_func) { obj.Exec("CIM_Card", "IsCompatible", { "ElementToCheck": ElementToCheck }, callback_func); }
430 - obj.CIM_Chassis_IsCompatible = function (ElementToCheck, callback_func) { obj.Exec("CIM_Chassis", "IsCompatible", { "ElementToCheck": ElementToCheck }, callback_func); }
431 - obj.CIM_Fan_SetSpeed = function (DesiredSpeed, callback_func) { obj.Exec("CIM_Fan", "SetSpeed", { "DesiredSpeed": DesiredSpeed }, callback_func); }
432 - obj.CIM_KVMRedirectionSAP_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_KVMRedirectionSAP", "RequestStateChange", { "RequestedState": RequestedState/*, "TimeoutPeriod": TimeoutPeriod */}, callback_func); }
433 - obj.CIM_MediaAccessDevice_LockMedia = function (Lock, callback_func) { obj.Exec("CIM_MediaAccessDevice", "LockMedia", { "Lock": Lock }, callback_func); }
434 - obj.CIM_MediaAccessDevice_SetPowerState = function (PowerState, Time, callback_func) { obj.Exec("CIM_MediaAccessDevice", "SetPowerState", { "PowerState": PowerState, "Time": Time }, callback_func); }
435 - obj.CIM_MediaAccessDevice_Reset = function (callback_func) { obj.Exec("CIM_MediaAccessDevice", "Reset", {}, callback_func); }
436 - obj.CIM_MediaAccessDevice_EnableDevice = function (Enabled, callback_func) { obj.Exec("CIM_MediaAccessDevice", "EnableDevice", { "Enabled": Enabled }, callback_func); }
437 - obj.CIM_MediaAccessDevice_OnlineDevice = function (Online, callback_func) { obj.Exec("CIM_MediaAccessDevice", "OnlineDevice", { "Online": Online }, callback_func); }
438 - obj.CIM_MediaAccessDevice_QuiesceDevice = function (Quiesce, callback_func) { obj.Exec("CIM_MediaAccessDevice", "QuiesceDevice", { "Quiesce": Quiesce }, callback_func); }
439 - obj.CIM_MediaAccessDevice_SaveProperties = function (callback_func) { obj.Exec("CIM_MediaAccessDevice", "SaveProperties", {}, callback_func); }
440 - obj.CIM_MediaAccessDevice_RestoreProperties = function (callback_func) { obj.Exec("CIM_MediaAccessDevice", "RestoreProperties", {}, callback_func); }
441 - obj.CIM_MediaAccessDevice_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_MediaAccessDevice", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
442 - obj.CIM_PhysicalFrame_IsCompatible = function (ElementToCheck, callback_func) { obj.Exec("CIM_PhysicalFrame", "IsCompatible", { "ElementToCheck": ElementToCheck }, callback_func); }
443 - obj.CIM_PhysicalPackage_IsCompatible = function (ElementToCheck, callback_func) { obj.Exec("CIM_PhysicalPackage", "IsCompatible", { "ElementToCheck": ElementToCheck }, callback_func); }
444 - obj.CIM_PowerManagementService_RequestPowerStateChange = function (PowerState, ManagedElement, Time, TimeoutPeriod, callback_func) { obj.Exec("CIM_PowerManagementService", "RequestPowerStateChange", { "PowerState": PowerState, "ManagedElement": ManagedElement, "Time": Time, "TimeoutPeriod": TimeoutPeriod }, callback_func, 0, 1); }
445 - obj.CIM_PowerSupply_SetPowerState = function (PowerState, Time, callback_func) { obj.Exec("CIM_PowerSupply", "SetPowerState", { "PowerState": PowerState, "Time": Time }, callback_func); }
446 - obj.CIM_PowerSupply_Reset = function (callback_func) { obj.Exec("CIM_PowerSupply", "Reset", {}, callback_func); }
447 - obj.CIM_PowerSupply_EnableDevice = function (Enabled, callback_func) { obj.Exec("CIM_PowerSupply", "EnableDevice", { "Enabled": Enabled }, callback_func); }
448 - obj.CIM_PowerSupply_OnlineDevice = function (Online, callback_func) { obj.Exec("CIM_PowerSupply", "OnlineDevice", { "Online": Online }, callback_func); }
449 - obj.CIM_PowerSupply_QuiesceDevice = function (Quiesce, callback_func) { obj.Exec("CIM_PowerSupply", "QuiesceDevice", { "Quiesce": Quiesce }, callback_func); }
450 - obj.CIM_PowerSupply_SaveProperties = function (callback_func) { obj.Exec("CIM_PowerSupply", "SaveProperties", {}, callback_func); }
451 - obj.CIM_PowerSupply_RestoreProperties = function (callback_func) { obj.Exec("CIM_PowerSupply", "RestoreProperties", {}, callback_func); }
452 - obj.CIM_PowerSupply_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_PowerSupply", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
453 - obj.CIM_Processor_SetPowerState = function (PowerState, Time, callback_func) { obj.Exec("CIM_Processor", "SetPowerState", { "PowerState": PowerState, "Time": Time }, callback_func); }
454 - obj.CIM_Processor_Reset = function (callback_func) { obj.Exec("CIM_Processor", "Reset", {}, callback_func); }
455 - obj.CIM_Processor_EnableDevice = function (Enabled, callback_func) { obj.Exec("CIM_Processor", "EnableDevice", { "Enabled": Enabled }, callback_func); }
456 - obj.CIM_Processor_OnlineDevice = function (Online, callback_func) { obj.Exec("CIM_Processor", "OnlineDevice", { "Online": Online }, callback_func); }
457 - obj.CIM_Processor_QuiesceDevice = function (Quiesce, callback_func) { obj.Exec("CIM_Processor", "QuiesceDevice", { "Quiesce": Quiesce }, callback_func); }
458 - obj.CIM_Processor_SaveProperties = function (callback_func) { obj.Exec("CIM_Processor", "SaveProperties", {}, callback_func); }
459 - obj.CIM_Processor_RestoreProperties = function (callback_func) { obj.Exec("CIM_Processor", "RestoreProperties", {}, callback_func); }
460 - obj.CIM_Processor_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_Processor", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
461 - obj.CIM_RecordLog_ClearLog = function (callback_func) { obj.Exec("CIM_RecordLog", "ClearLog", {}, callback_func); }
462 - obj.CIM_RecordLog_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_RecordLog", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
463 - obj.CIM_RedirectionService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_RedirectionService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
464 - obj.CIM_Sensor_SetPowerState = function (PowerState, Time, callback_func) { obj.Exec("CIM_Sensor", "SetPowerState", { "PowerState": PowerState, "Time": Time }, callback_func); }
465 - obj.CIM_Sensor_Reset = function (callback_func) { obj.Exec("CIM_Sensor", "Reset", {}, callback_func); }
466 - obj.CIM_Sensor_EnableDevice = function (Enabled, callback_func) { obj.Exec("CIM_Sensor", "EnableDevice", { "Enabled": Enabled }, callback_func); }
467 - obj.CIM_Sensor_OnlineDevice = function (Online, callback_func) { obj.Exec("CIM_Sensor", "OnlineDevice", { "Online": Online }, callback_func); }
468 - obj.CIM_Sensor_QuiesceDevice = function (Quiesce, callback_func) { obj.Exec("CIM_Sensor", "QuiesceDevice", { "Quiesce": Quiesce }, callback_func); }
469 - obj.CIM_Sensor_SaveProperties = function (callback_func) { obj.Exec("CIM_Sensor", "SaveProperties", {}, callback_func); }
470 - obj.CIM_Sensor_RestoreProperties = function (callback_func) { obj.Exec("CIM_Sensor", "RestoreProperties", {}, callback_func); }
471 - obj.CIM_Sensor_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_Sensor", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
472 - obj.CIM_StatisticalData_ResetSelectedStats = function (SelectedStatistics, callback_func) { obj.Exec("CIM_StatisticalData", "ResetSelectedStats", { "SelectedStatistics": SelectedStatistics }, callback_func); }
473 - obj.CIM_Watchdog_KeepAlive = function (callback_func) { obj.Exec("CIM_Watchdog", "KeepAlive", {}, callback_func); }
474 - obj.CIM_Watchdog_SetPowerState = function (PowerState, Time, callback_func) { obj.Exec("CIM_Watchdog", "SetPowerState", { "PowerState": PowerState, "Time": Time }, callback_func); }
475 - obj.CIM_Watchdog_Reset = function (callback_func) { obj.Exec("CIM_Watchdog", "Reset", {}, callback_func); }
476 - obj.CIM_Watchdog_EnableDevice = function (Enabled, callback_func) { obj.Exec("CIM_Watchdog", "EnableDevice", { "Enabled": Enabled }, callback_func); }
477 - obj.CIM_Watchdog_OnlineDevice = function (Online, callback_func) { obj.Exec("CIM_Watchdog", "OnlineDevice", { "Online": Online }, callback_func); }
478 - obj.CIM_Watchdog_QuiesceDevice = function (Quiesce, callback_func) { obj.Exec("CIM_Watchdog", "QuiesceDevice", { "Quiesce": Quiesce }, callback_func); }
479 - obj.CIM_Watchdog_SaveProperties = function (callback_func) { obj.Exec("CIM_Watchdog", "SaveProperties", {}, callback_func); }
480 - obj.CIM_Watchdog_RestoreProperties = function (callback_func) { obj.Exec("CIM_Watchdog", "RestoreProperties", {}, callback_func); }
481 - obj.CIM_Watchdog_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_Watchdog", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
482 - obj.CIM_WiFiPort_SetPowerState = function (PowerState, Time, callback_func) { obj.Exec("CIM_WiFiPort", "SetPowerState", { "PowerState": PowerState, "Time": Time }, callback_func); }
483 - obj.CIM_WiFiPort_Reset = function (callback_func) { obj.Exec("CIM_WiFiPort", "Reset", {}, callback_func); }
484 - obj.CIM_WiFiPort_EnableDevice = function (Enabled, callback_func) { obj.Exec("CIM_WiFiPort", "EnableDevice", { "Enabled": Enabled }, callback_func); }
485 - obj.CIM_WiFiPort_OnlineDevice = function (Online, callback_func) { obj.Exec("CIM_WiFiPort", "OnlineDevice", { "Online": Online }, callback_func); }
486 - obj.CIM_WiFiPort_QuiesceDevice = function (Quiesce, callback_func) { obj.Exec("CIM_WiFiPort", "QuiesceDevice", { "Quiesce": Quiesce }, callback_func); }
487 - obj.CIM_WiFiPort_SaveProperties = function (callback_func) { obj.Exec("CIM_WiFiPort", "SaveProperties", {}, callback_func); }
488 - obj.CIM_WiFiPort_RestoreProperties = function (callback_func) { obj.Exec("CIM_WiFiPort", "RestoreProperties", {}, callback_func); }
489 - obj.CIM_WiFiPort_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("CIM_WiFiPort", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
490 - obj.IPS_HostBasedSetupService_Setup = function (NetAdminPassEncryptionType, NetworkAdminPassword, McNonce, Certificate, SigningAlgorithm, DigitalSignature, callback_func) { obj.Exec("IPS_HostBasedSetupService", "Setup", { "NetAdminPassEncryptionType": NetAdminPassEncryptionType, "NetworkAdminPassword": NetworkAdminPassword, "McNonce": McNonce, "Certificate": Certificate, "SigningAlgorithm": SigningAlgorithm, "DigitalSignature": DigitalSignature }, callback_func); }
491 - obj.IPS_HostBasedSetupService_AddNextCertInChain = function (NextCertificate, IsLeafCertificate, IsRootCertificate, callback_func) { obj.Exec("IPS_HostBasedSetupService", "AddNextCertInChain", { "NextCertificate": NextCertificate, "IsLeafCertificate": IsLeafCertificate, "IsRootCertificate": IsRootCertificate }, callback_func); }
492 - obj.IPS_HostBasedSetupService_AdminSetup = function (NetAdminPassEncryptionType, NetworkAdminPassword, McNonce, SigningAlgorithm, DigitalSignature, callback_func) { obj.Exec("IPS_HostBasedSetupService", "AdminSetup", { "NetAdminPassEncryptionType": NetAdminPassEncryptionType, "NetworkAdminPassword": NetworkAdminPassword, "McNonce": McNonce, "SigningAlgorithm": SigningAlgorithm, "DigitalSignature": DigitalSignature }, callback_func); }
493 - obj.IPS_HostBasedSetupService_UpgradeClientToAdmin = function (McNonce, SigningAlgorithm, DigitalSignature, callback_func) { obj.Exec("IPS_HostBasedSetupService", "UpgradeClientToAdmin", { "McNonce": McNonce, "SigningAlgorithm": SigningAlgorithm, "DigitalSignature": DigitalSignature }, callback_func); }
494 - obj.IPS_HostBasedSetupService_DisableClientControlMode = function (_method_dummy, callback_func) { obj.Exec("IPS_HostBasedSetupService", "DisableClientControlMode", { "_method_dummy": _method_dummy }, callback_func); }
495 - obj.IPS_KVMRedirectionSettingData_TerminateSession = function (callback_func) { obj.Exec("IPS_KVMRedirectionSettingData", "TerminateSession", {}, callback_func); }
496 - obj.IPS_OptInService_StartOptIn = function (callback_func) { obj.Exec("IPS_OptInService", "StartOptIn", {}, callback_func); }
497 - obj.IPS_OptInService_CancelOptIn = function (callback_func) { obj.Exec("IPS_OptInService", "CancelOptIn", {}, callback_func); }
498 - obj.IPS_OptInService_SendOptInCode = function (OptInCode, callback_func) { obj.Exec("IPS_OptInService", "SendOptInCode", { "OptInCode": OptInCode }, callback_func); }
499 - obj.IPS_OptInService_StartService = function (callback_func) { obj.Exec("IPS_OptInService", "StartService", {}, callback_func); }
500 - obj.IPS_OptInService_StopService = function (callback_func) { obj.Exec("IPS_OptInService", "StopService", {}, callback_func); }
501 - obj.IPS_OptInService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("IPS_OptInService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
502 - obj.IPS_ProvisioningRecordLog_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("IPS_ProvisioningRecordLog", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
503 - obj.IPS_ProvisioningRecordLog_ClearLog = function (_method_dummy, callback_func) { obj.Exec("IPS_ProvisioningRecordLog", "ClearLog", { "_method_dummy": _method_dummy }, callback_func); }
504 - obj.IPS_SecIOService_RequestStateChange = function (RequestedState, TimeoutPeriod, callback_func) { obj.Exec("IPS_SecIOService", "RequestStateChange", { "RequestedState": RequestedState, "TimeoutPeriod": TimeoutPeriod }, callback_func); }
505 -
506 - obj.AmtStatusToStr = function (code) { if (obj.AmtStatusCodes[code]) return obj.AmtStatusCodes[code]; else return "UNKNOWN_ERROR" }
507 - obj.AmtStatusCodes = {
508 - 0x0000: "SUCCESS",
509 - 0x0001: "INTERNAL_ERROR",
510 - 0x0002: "NOT_READY",
511 - 0x0003: "INVALID_PT_MODE",
512 - 0x0004: "INVALID_MESSAGE_LENGTH",
513 - 0x0005: "TABLE_FINGERPRINT_NOT_AVAILABLE",
514 - 0x0006: "INTEGRITY_CHECK_FAILED",
515 - 0x0007: "UNSUPPORTED_ISVS_VERSION",
516 - 0x0008: "APPLICATION_NOT_REGISTERED",
517 - 0x0009: "INVALID_REGISTRATION_DATA",
518 - 0x000A: "APPLICATION_DOES_NOT_EXIST",
519 - 0x000B: "NOT_ENOUGH_STORAGE",
520 - 0x000C: "INVALID_NAME",
521 - 0x000D: "BLOCK_DOES_NOT_EXIST",
522 - 0x000E: "INVALID_BYTE_OFFSET",
523 - 0x000F: "INVALID_BYTE_COUNT",
524 - 0x0010: "NOT_PERMITTED",
525 - 0x0011: "NOT_OWNER",
526 - 0x0012: "BLOCK_LOCKED_BY_OTHER",
527 - 0x0013: "BLOCK_NOT_LOCKED",
528 - 0x0014: "INVALID_GROUP_PERMISSIONS",
529 - 0x0015: "GROUP_DOES_NOT_EXIST",
530 - 0x0016: "INVALID_MEMBER_COUNT",
531 - 0x0017: "MAX_LIMIT_REACHED",
532 - 0x0018: "INVALID_AUTH_TYPE",
533 - 0x0019: "AUTHENTICATION_FAILED",
534 - 0x001A: "INVALID_DHCP_MODE",
535 - 0x001B: "INVALID_IP_ADDRESS",
536 - 0x001C: "INVALID_DOMAIN_NAME",
537 - 0x001D: "UNSUPPORTED_VERSION",
538 - 0x001E: "REQUEST_UNEXPECTED",
539 - 0x001F: "INVALID_TABLE_TYPE",
540 - 0x0020: "INVALID_PROVISIONING_STATE",
541 - 0x0021: "UNSUPPORTED_OBJECT",
542 - 0x0022: "INVALID_TIME",
543 - 0x0023: "INVALID_INDEX",
544 - 0x0024: "INVALID_PARAMETER",
545 - 0x0025: "INVALID_NETMASK",
546 - 0x0026: "FLASH_WRITE_LIMIT_EXCEEDED",
547 - 0x0027: "INVALID_IMAGE_LENGTH",
548 - 0x0028: "INVALID_IMAGE_SIGNATURE",
549 - 0x0029: "PROPOSE_ANOTHER_VERSION",
550 - 0x002A: "INVALID_PID_FORMAT",
551 - 0x002B: "INVALID_PPS_FORMAT",
552 - 0x002C: "BIST_COMMAND_BLOCKED",
553 - 0x002D: "CONNECTION_FAILED",
554 - 0x002E: "CONNECTION_TOO_MANY",
555 - 0x002F: "RNG_GENERATION_IN_PROGRESS",
556 - 0x0030: "RNG_NOT_READY",
557 - 0x0031: "CERTIFICATE_NOT_READY",
558 - 0x0400: "DISABLED_BY_POLICY",
559 - 0x0800: "NETWORK_IF_ERROR_BASE",
560 - 0x0801: "UNSUPPORTED_OEM_NUMBER",
561 - 0x0802: "UNSUPPORTED_BOOT_OPTION",
562 - 0x0803: "INVALID_COMMAND",
563 - 0x0804: "INVALID_SPECIAL_COMMAND",
564 - 0x0805: "INVALID_HANDLE",
565 - 0x0806: "INVALID_PASSWORD",
566 - 0x0807: "INVALID_REALM",
567 - 0x0808: "STORAGE_ACL_ENTRY_IN_USE",
568 - 0x0809: "DATA_MISSING",
569 - 0x080A: "DUPLICATE",
570 - 0x080B: "EVENTLOG_FROZEN",
571 - 0x080C: "PKI_MISSING_KEYS",
572 - 0x080D: "PKI_GENERATING_KEYS",
573 - 0x080E: "INVALID_KEY",
574 - 0x080F: "INVALID_CERT",
575 - 0x0810: "CERT_KEY_NOT_MATCH",
576 - 0x0811: "MAX_KERB_DOMAIN_REACHED",
577 - 0x0812: "UNSUPPORTED",
578 - 0x0813: "INVALID_PRIORITY",
579 - 0x0814: "NOT_FOUND",
580 - 0x0815: "INVALID_CREDENTIALS",
581 - 0x0816: "INVALID_PASSPHRASE",
582 - 0x0818: "NO_ASSOCIATION",
583 - 0x081B: "AUDIT_FAIL",
584 - 0x081C: "BLOCKING_COMPONENT",
585 - 0x0821: "USER_CONSENT_REQUIRED",
586 - 0x1000: "APP_INTERNAL_ERROR",
587 - 0x1001: "NOT_INITIALIZED",
588 - 0x1002: "LIB_VERSION_UNSUPPORTED",
589 - 0x1003: "INVALID_PARAM",
590 - 0x1004: "RESOURCES",
591 - 0x1005: "HARDWARE_ACCESS_ERROR",
592 - 0x1006: "REQUESTOR_NOT_REGISTERED",
593 - 0x1007: "NETWORK_ERROR",
594 - 0x1008: "PARAM_BUFFER_TOO_SHORT",
595 - 0x1009: "COM_NOT_INITIALIZED_IN_THREAD",
596 - 0x100A: "URL_REQUIRED"
597 - }
598 -
599 - //
600 - // Methods used for getting the event log
601 - //
602 -
603 - obj.GetMessageLog = function (func, tag) {
604 - obj.AMT_MessageLog_PositionToFirstRecord(_GetMessageLog0, [func, tag, []]);
605 - }
606 - function _GetMessageLog0(stack, name, responses, status, tag) {
607 - if (status != 200 || responses.Body["ReturnValue"] != '0') { tag[0](obj, null, tag[2]); return; }
608 - obj.AMT_MessageLog_GetRecords(responses.Body["IterationIdentifier"], 390, _GetMessageLog1, tag);
609 - }
610 - function _GetMessageLog1(stack, name, responses, status, tag) {
611 - if (status != 200 || responses.Body["ReturnValue"] != '0') { tag[0](obj, null, tag[2]); return; }
612 - var i, j, x, e, AmtMessages = tag[2], t = new Date(), TimeStamp, ra = responses.Body["RecordArray"];
613 - if (typeof ra === 'string') { responses.Body["RecordArray"] = [responses.Body["RecordArray"]]; }
614 -
615 - for (i in ra) {
616 - e = null;
617 - try { e = window.atob(ra[i]); } catch (ex) { }
618 - if (e != null) {
619 - TimeStamp = ReadIntX(e, 0);
620 - if ((TimeStamp > 0) && (TimeStamp < 0xFFFFFFFF)) {
621 - x = { 'DeviceAddress': e.charCodeAt(4), 'EventSensorType': e.charCodeAt(5), 'EventType': e.charCodeAt(6), 'EventOffset': e.charCodeAt(7), 'EventSourceType': e.charCodeAt(8), 'EventSeverity': e.charCodeAt(9), 'SensorNumber': e.charCodeAt(10), 'Entity': e.charCodeAt(11), 'EntityInstance': e.charCodeAt(12), 'EventData': [], 'Time': new Date((TimeStamp + (t.getTimezoneOffset() * 60)) * 1000) };
622 - for (j = 13; j < 21; j++) { x['EventData'].push(e.charCodeAt(j)); }
623 - x['EntityStr'] = _SystemEntityTypes[x['Entity']];
624 - x['Desc'] = _GetEventDetailStr(x['EventSensorType'], x['EventOffset'], x['EventData'], x['Entity']);
625 - if (!x['EntityStr']) x['EntityStr'] = "Unknown";
626 - AmtMessages.push(x);
627 - }
628 - }
629 - }
630 -
631 - if (responses.Body["NoMoreRecords"] != true) { obj.AMT_MessageLog_GetRecords(responses.Body["IterationIdentifier"], 390, _GetMessageLog1, [tag[0], AmtMessages, tag[2]]); } else { tag[0](obj, AmtMessages, tag[2]); }
632 - }
633 -
634 - var _EventTrapSourceTypes = "Platform firmware (e.g. BIOS)|SMI handler|ISV system management software|Alert ASIC|IPMI|BIOS vendor|System board set vendor|System integrator|Third party add-in|OSV|NIC|System management card".split('|');
635 - var _SystemFirmwareError = "Unspecified.|No system memory is physically installed in the system.|No usable system memory, all installed memory has experienced an unrecoverable failure.|Unrecoverable hard-disk/ATAPI/IDE device failure.|Unrecoverable system-board failure.|Unrecoverable diskette subsystem failure.|Unrecoverable hard-disk controller failure.|Unrecoverable PS/2 or USB keyboard failure.|Removable boot media not found.|Unrecoverable video controller failure.|No video device detected.|Firmware (BIOS) ROM corruption detected.|CPU voltage mismatch (processors that share same supply have mismatched voltage requirements)|CPU speed matching failure".split('|');
636 - var _SystemFirmwareProgress = "Unspecified.|Memory initialization.|Starting hard-disk initialization and test|Secondary processor(s) initialization|User authentication|User-initiated system setup|USB resource configuration|PCI resource configuration|Option ROM initialization|Video initialization|Cache initialization|SM Bus initialization|Keyboard controller initialization|Embedded controller/management controller initialization|Docking station attachment|Enabling docking station|Docking station ejection|Disabling docking station|Calling operating system wake-up vector|Starting operating system boot process|Baseboard or motherboard initialization|reserved|Floppy initialization|Keyboard test|Pointing device test|Primary processor initialization".split('|');
637 - var _SystemEntityTypes = "Unspecified|Other|Unknown|Processor|Disk|Peripheral|System management module|System board|Memory module|Processor module|Power supply|Add in card|Front panel board|Back panel board|Power system board|Drive backplane|System internal expansion board|Other system board|Processor board|Power unit|Power module|Power management board|Chassis back panel board|System chassis|Sub chassis|Other chassis board|Disk drive bay|Peripheral bay|Device bay|Fan cooling|Cooling unit|Cable interconnect|Memory device|System management software|BIOS|Intel(r) ME|System bus|Group|Intel(r) ME|External environment|Battery|Processing blade|Connectivity switch|Processor/memory module|I/O module|Processor I/O module|Management controller firmware|IPMI channel|PCI bus|PCI express bus|SCSI bus|SATA/SAS bus|Processor front side bus".split('|');
638 - obj.RealmNames = "||Redirection|PT Administration|Hardware Asset|Remote Control|Storage|Event Manager|Storage Admin|Agent Presence Local|Agent Presence Remote|Circuit Breaker|Network Time|General Information|Firmware Update|EIT|LocalUN|Endpoint Access Control|Endpoint Access Control Admin|Event Log Reader|Audit Log|ACL Realm|||Local System".split('|');
639 - obj.WatchdogCurrentStates = { 1: 'Not Started', 2: 'Stopped', 4: 'Running', 8: 'Expired', 16: 'Suspended' };
640 -
641 - function _GetEventDetailStr(eventSensorType, eventOffset, eventDataField, entity) {
642 -
643 - if (eventSensorType == 15)
644 - {
645 - if (eventDataField[0] == 235) return "Invalid Data";
646 - if (eventOffset == 0) return _SystemFirmwareError[eventDataField[1]];
647 - return _SystemFirmwareProgress[eventDataField[1]];
648 - }
649 -
650 - if (eventSensorType == 18 && eventDataField[0] == 170) // System watchdog event
651 - {
652 - return "Agent watchdog " + char2hex(eventDataField[4]) + char2hex(eventDataField[3]) + char2hex(eventDataField[2]) + char2hex(eventDataField[1]) + "-" + char2hex(eventDataField[6]) + char2hex(eventDataField[5]) + "-... changed to " + obj.WatchdogCurrentStates[eventDataField[7]];
653 - }
654 -
655 - /*
656 - if (eventSensorType == 5 && eventOffset == 0) // System chassis
657 - {
658 - return "Case intrusion";
659 - }
660 -
661 - if (eventSensorType == 192 && eventOffset == 0 && eventDataField[0] == 170 && eventDataField[1] == 48)
662 - {
663 - if (eventDataField[2] == 0) return "A remote Serial Over LAN session was established.";
664 - if (eventDataField[2] == 1) return "Remote Serial Over LAN session finished. User control was restored.";
665 - if (eventDataField[2] == 2) return "A remote IDE-Redirection session was established.";
666 - if (eventDataField[2] == 3) return "Remote IDE-Redirection session finished. User control was restored.";
667 - }
668 -
669 - if (eventSensorType == 36)
670 - {
671 - long handle = ((long)(eventDataField[1]) << 24) + ((long)(eventDataField[2]) << 16) + ((long)(eventDataField[3]) << 8) + (long)(eventDataField[4]);
672 - string nic = string.Format("#{0}", eventDataField[0]);
673 - if (eventDataField[0] == 0xAA) nic = "wired"; // TODO: Add wireless *****
674 - //if (eventDataField[0] == 0xAA) nic = "wireless";
675 -
676 - if (handle == 4294967293) { return string.Format("All received packet filter was matched on {0} interface.", nic); }
677 - if (handle == 4294967292) { return string.Format("All outbound packet filter was matched on {0} interface.", nic); }
678 - if (handle == 4294967290) { return string.Format("Spoofed packet filter was matched on {0} interface.", nic); }
679 - return string.Format("Filter {0} was matched on {1} interface.", handle, nic);
680 - }
681 -
682 - if (eventSensorType == 192)
683 - {
684 - if (eventDataField[2] == 0) return "Security policy invoked. Some or all network traffic (TX) was stopped.";
685 - if (eventDataField[2] == 2) return "Security policy invoked. Some or all network traffic (RX) was stopped.";
686 - return "Security policy invoked.";
687 - }
688 -
689 - if (eventSensorType == 193)
690 - {
691 - if (eventDataField[0] == 0xAA && eventDataField[1] == 0x30 && eventDataField[2] == 0x00 && eventDataField[3] == 0x00) { return "User request for remote connection."; }
692 - if (eventDataField[0] == 0xAA && eventDataField[1] == 0x20 && eventDataField[2] == 0x03 && eventDataField[3] == 0x01) { return "EAC error: attempt to get posture while NAC in Intel� AMT is disabled."; // eventDataField = 0xAA20030100000000 }
693 - if (eventDataField[0] == 0xAA && eventDataField[1] == 0x20 && eventDataField[2] == 0x04 && eventDataField[3] == 0x00) { return "Certificate revoked. "; }
694 - }
695 - */
696 -
697 - if (eventSensorType == 6) return "Authentication failed " + (eventDataField[1] + (eventDataField[2] << 8)) + " times. The system may be under attack.";
698 - if (eventSensorType == 30) return "No bootable media";
699 - if (eventSensorType == 32) return "Operating system lockup or power interrupt";
700 - if (eventSensorType == 35) return "System boot failure";
701 - if (eventSensorType == 37) return "System firmware started (at least one CPU is properly executing).";
702 - return "Unknown Sensor Type #" + eventSensorType;
703 - }
704 -
705 -
706 - return obj;
707 -}
708 -
709 -
710 -
711 -
712 -
713 -// TinyMD5 from https://github.com/jbt/js-crypto
714 -
715 -// Perform MD5 setup
716 -var md5_k = [];
717 -for (var i = 0; i < 64;) { md5_k[i] = 0 | (Math.abs(Math.sin(++i)) * 4294967296); }
718 -
719 -// Perform MD5 on raw string and return hex
720 -function hex_md5(str) {
721 - var b, c, d, j,
722 - x = [],
723 - str2 = unescape(encodeURI(str)),
724 - a = str2.length,
725 - h = [b = 1732584193, c = -271733879, ~b, ~c],
726 - i = 0;
727 -
728 - for (; i <= a;) x[i >> 2] |= (str2.charCodeAt(i) || 128) << 8 * (i++ % 4);
729 -
730 - x[str = (a + 8 >> 6) * 16 + 14] = a * 8;
731 - i = 0;
732 -
733 - for (; i < str; i += 16) {
734 - a = h; j = 0;
735 - for (; j < 64;) {
736 - a = [
737 - d = a[3],
738 - ((b = a[1] | 0) +
739 - ((d = (
740 - (a[0] +
741 - [
742 - b & (c = a[2]) | ~b & d,
743 - d & b | ~d & c,
744 - b ^ c ^ d,
745 - c ^ (b | ~d)
746 - ][a = j >> 4]
747 - ) +
748 - (md5_k[j] +
749 - (x[[
750 - j,
751 - 5 * j + 1,
752 - 3 * j + 5,
753 - 7 * j
754 - ][a] % 16 + i] | 0)
755 - )
756 - )) << (a = [
757 - 7, 12, 17, 22,
758 - 5, 9, 14, 20,
759 - 4, 11, 16, 23,
760 - 6, 10, 15, 21
761 - ][4 * a + j++ % 4]) | d >>> 32 - a)
762 - ),
763 - b,
764 - c
765 - ];
766 - }
767 - for (j = 4; j;) h[--j] = h[j] + a[j];
768 - }
769 -
770 - str = '';
771 - for (; j < 32;) str += ((h[j >> 3] >> ((1 ^ j++ & 7) * 4)) & 15).toString(16);
772 - return str;
773 -}
774 -
775 -
776 -// Perform MD5 on raw string and return raw string result
777 -function rstr_md5(str) { return hex2rstr(hex_md5(str)); }
778 -
779 -/*
780 -Convert arguments into selector set and body XML. Used by AMT_WiFiPortConfigurationService_UpdateWiFiSettings.
781 -args = {
782 - "WiFiEndpoint": {
783 - __parameterType: 'reference',
784 - __resourceUri: 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_WiFiEndpoint',
785 - Name: 'WiFi Endpoint 0'
786 - },
787 - "WiFiEndpointSettingsInput":
788 - {
789 - __parameterType: 'instance',
790 - __namespace: 'http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_WiFiEndpointSettings',
791 - ElementName: document.querySelector('#editProfile-profileName').value,
792 - InstanceID: 'Intel(r) AMT:WiFi Endpoint Settings ' + document.querySelector('#editProfile-profileName').value,
793 - AuthenticationMethod: document.querySelector('#editProfile-networkAuthentication').value,
794 - //BSSType: 3, // Intel(r) AMT supports only infrastructure networks
795 - EncryptionMethod: document.querySelector('#editProfile-encryption').value,
796 - SSID: document.querySelector('#editProfile-networkName').value,
797 - Priority: 100,
798 - PSKPassPhrase: document.querySelector('#editProfile-passPhrase').value
799 - },
800 - "IEEE8021xSettingsInput": null,
801 - "ClientCredential": null,
802 - "CACredential": null
803 -},
804 -*/
805 -function execArgumentsToXml(args) {
806 - if(args === undefined || args === null) return null;
807 -
808 - var result = '';
809 - for(var argName in args) {
810 - var arg = args[argName];
811 - if(!arg) continue;
812 - if(arg['__parameterType'] === 'reference') result += referenceToXml(argName, arg);
813 - else result += instanceToXml(argName, arg);
814 - //if(arg['__isInstance']) result += instanceToXml(argName, arg);
815 - }
816 - return result;
817 -}
818 -
819 -/**
820 - * Convert JavaScript object into XML
821 -
822 - <r:WiFiEndpointSettingsInput xmlns:q="http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_WiFiEndpointSettings">
823 - <q:ElementName>Wireless-Profile-Admin</q:ElementName>
824 - <q:InstanceID>Intel(r) AMT:WiFi Endpoint Settings Wireless-Profile-Admin</q:InstanceID>
825 - <q:AuthenticationMethod>6</q:AuthenticationMethod>
826 - <q:EncryptionMethod>4</q:EncryptionMethod>
827 - <q:Priority>100</q:Priority>
828 - <q:PSKPassPhrase>P@ssw0rd</q:PSKPassPhrase>
829 - </r:WiFiEndpointSettingsInput>
830 - */
831 -function instanceToXml(instanceName, inInstance) {
832 - if(inInstance === undefined || inInstance === null) return null;
833 -
834 - var hasNamespace = !!inInstance['__namespace'];
835 - var startTag = hasNamespace ? '<q:' : '<';
836 - var endTag = hasNamespace ? '</q:' : '</';
837 - var namespaceDef = hasNamespace ? (' xmlns:q="' + inInstance['__namespace'] + '"' ): '';
838 - var result = '<r:' + instanceName + namespaceDef + '>';
839 - for(var prop in inInstance) {
840 - if (!inInstance.hasOwnProperty(prop) || prop.indexOf('__') === 0) continue;
841 -
842 - if (typeof inInstance[prop] === 'function' || Array.isArray(inInstance[prop]) ) continue;
843 -
844 - if (typeof inInstance[prop] === 'object') {
845 - //result += startTag + prop +'>' + instanceToXml('prop', inInstance[prop]) + endTag + prop +'>';
846 - console.error('only convert one level down...');
847 - }
848 - else {
849 - result += startTag + prop +'>' + inInstance[prop].toString() + endTag + prop +'>';
850 - }
851 - }
852 - result += '</r:' + instanceName + '>';
853 - return result;
854 -}
855 -
856 -
857 -/**
858 - * Convert a selector set into XML. Expect no nesting.
859 - * {
860 - * selectorName : selectorValue,
861 - * selectorName : selectorValue,
862 - * ... ...
863 - * }
864 -
865 - <r:WiFiEndpoint>
866 - <a:Address>http://192.168.1.103:16992/wsman</a:Address>
867 - <a:ReferenceParameters>
868 - <w:ResourceURI>http://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_WiFiEndpoint</w:ResourceURI>
869 - <w:SelectorSet>
870 - <w:Selector Name="Name">WiFi Endpoint 0</w:Selector>
871 - </w:SelectorSet>
872 - </a:ReferenceParameters>
873 - </r:WiFiEndpoint>
874 -
875 - */
876 -function referenceToXml(referenceName, inReference) {
877 - if(inReference === undefined || inReference === null ) return null;
878 -
879 - var result = '<r:' + referenceName + '><a:Address>/wsman</a:Address><a:ReferenceParameters><w:ResourceURI>'+ inReference['__resourceUri']+'</w:ResourceURI><w:SelectorSet>';
880 - for(var selectorName in inReference) {
881 - if (!inReference.hasOwnProperty(selectorName) || selectorName.indexOf('__') === 0) continue;
882 -
883 - if (typeof inReference[selectorName] === 'function' ||
884 - typeof inReference[selectorName] === 'object' ||
885 - Array.isArray(inReference[selectorName]) )
886 - continue;
887 -
888 - result += '<w:Selector Name="' + selectorName +'">' + inReference[selectorName].toString() + '</w:Selector>';
889 - }
890 -
891 - result += '</w:SelectorSet></a:ReferenceParameters></r:' + referenceName + '>';
892 - return result;
893 -}
894 -
895 -// Convert a byte array of SID into string
896 -function GetSidString(sid) {
897 - var r = "S-" + sid.charCodeAt(0) + "-" + sid.charCodeAt(7);
898 - for (var i = 2; i < (sid.length / 4) ; i++) r += "-" + ReadIntX(sid, i * 4);
899 - return r;
900 -}
901 -
902 -// Convert a SID readable string into bytes
903 -function GetSidByteArray(sidString) {
904 - if (!sidString || sidString == null) return null;
905 - var sidParts = sidString.split('-');
906 -
907 - // Make sure the SID has at least 4 parts and starts with 'S'
908 - if (sidParts.length < 4 || (sidParts[0] != 's' && sidParts[0] != 'S')) return null;
909 -
910 - // Check that each part of the SID is really an integer
911 - for (var i = 1; i < sidParts.length; i++) { var y = parseInt(sidParts[i]); if (y != sidParts[i]) return null; sidParts[i] = y; }
912 -
913 - // Version (8 bit) + Id count (8 bit) + 48 bit in big endian -- DO NOT use bitwise right shift operator. JavaScript converts the number into a 32 bit integer before shifting. In real world, it's highly likely this part is always 0.
914 - var r = String.fromCharCode(sidParts[1]) + String.fromCharCode(sidParts.length - 3) + ShortToStr(Math.floor(sidParts[2] / Math.pow(2, 32))) + IntToStr((sidParts[2]) & 0xFFFF);
915 -
916 - // the rest are in 32 bit in little endian
917 - for (var i = 3; i < sidParts.length; i++) r += IntToStrX(sidParts[i]);
918 - return r;
919 -}
920 -/**
921 -* @description Intel(r) AMT WSMAN Stack
922 -* @author Ylian Saint-Hilaire
923 -* @version v0.2.0
924 -*/
925 -
926 -// Construct a MeshServer object
927 -var WsmanStackCreateService = function (host, port, user, pass, tls, extra) {
928 - var obj = {};
929 - //obj.onDebugMessage = null; // Set to a function if you want to get debug messages.
930 - obj.NextMessageId = 1; // Next message number, used to label WSMAN calls.
931 - obj.Address = '/wsman';
932 - obj.comm = CreateWsmanComm(host, port, user, pass, tls, extra);
933 -
934 - obj.PerformAjax = function (postdata, callback, tag, pri, namespaces) {
935 - if (namespaces == undefined) namespaces = '';
936 - obj.comm.PerformAjax('<?xml version=\"1.0\" encoding=\"utf-8\"?><Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing" xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" xmlns=\"http://www.w3.org/2003/05/soap-envelope\" ' + namespaces + '><Header><a:Action>' + postdata, function (data, status, tag) {
937 - if (status != 200) { callback(obj, null, { Header: { HttpError: status } }, status, tag); return; }
938 - var wsresponse = obj.ParseWsman(data);
939 - if (!wsresponse || wsresponse == null) { callback(obj, null, { Header: { HttpError: status } }, 601, tag); } else { callback(obj, wsresponse.Header["ResourceURI"], wsresponse, 200, tag); }
940 - }, tag, pri);
941 - }
942 -
943 - // Private method
944 - //obj.Debug = function (msg) { /*console.log(msg);*/ }
945 -
946 - // Cancel all pending queries with given status
947 - obj.CancelAllQueries = function (s) { obj.comm.CancelAllQueries(s); }
948 -
949 - // Get the last element of a URI string
950 - obj.GetNameFromUrl = function (resuri) {
951 - var x = resuri.lastIndexOf("/");
952 - return (x == -1)?resuri:resuri.substring(x + 1);
953 - }
954 -
955 - // Perform a WSMAN Subscribe operation
956 - obj.ExecSubscribe = function (resuri, delivery, url, callback, tag, pri, selectors, opaque, user, pass) {
957 - var digest = "", digest2 = "";
958 - if (user != undefined && pass != undefined) { digest = '<t:IssuedTokens><t:RequestSecurityTokenResponse><t:TokenType>http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#UsernameToken</t:TokenType><t:RequestedSecurityToken><se:UsernameToken><se:Username>' + user + '</se:Username><se:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd#PasswordText">' + pass + '</se:Password></se:UsernameToken></t:RequestedSecurityToken></t:RequestSecurityTokenResponse></t:IssuedTokens>'; digest2 = '<Auth Profile="http://schemas.xmlsoap.org/ws/2004/08/eventing/DeliveryModes/secprofile/http/digest"/>'; }
959 - if (opaque != undefined && opaque != null) { opaque = '<a:ReferenceParameters>' + opaque + '</a:ReferenceParameters>'; } else { opaque = ""; }
960 - var data = "http://schemas.xmlsoap.org/ws/2004/08/eventing/Subscribe</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo>" + _PutObjToSelectorsXml(selectors) + digest + '</Header><Body><e:Subscribe><e:Delivery Mode="http://schemas.dmtf.org/wbem/wsman/1/wsman/' + delivery + '"><e:NotifyTo><a:Address>' + url + '</a:Address></e:NotifyTo>' + digest2 + '</e:Delivery><e:Expires>PT0.000000S</e:Expires></e:Subscribe>';
961 - obj.PerformAjax(data + "</Body></Envelope>", callback, tag, pri, 'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing" xmlns:t="http://schemas.xmlsoap.org/ws/2005/02/trust" xmlns:se="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:m="http://x.com"');
962 - }
963 -
964 - // Perform a WSMAN UnSubscribe operation
965 - obj.ExecUnSubscribe = function (resuri, callback, tag, pri, selectors) {
966 - var data = "http://schemas.xmlsoap.org/ws/2004/08/eventing/Unsubscribe</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo>" + _PutObjToSelectorsXml(selectors) + '</Header><Body><e:Unsubscribe/>';
967 - obj.PerformAjax(data + "</Body></Envelope>", callback, tag, pri, 'xmlns:e="http://schemas.xmlsoap.org/ws/2004/08/eventing"');
968 - }
969 -
970 - // Perform a WSMAN PUT operation
971 - obj.ExecPut = function (resuri, putobj, callback, tag, pri, selectors) {
972 - var data = "http://schemas.xmlsoap.org/ws/2004/09/transfer/Put</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60.000S</w:OperationTimeout>" + _PutObjToSelectorsXml(selectors) + '</Header><Body>' + _PutObjToBodyXml(resuri, putobj);
973 - obj.PerformAjax(data + "</Body></Envelope>", callback, tag, pri);
974 - }
975 -
976 - // Perform a WSMAN CREATE operation
977 - obj.ExecCreate = function (resuri, putobj, callback, tag, pri, selectors) {
978 - var objname = obj.GetNameFromUrl(resuri);
979 - var data = "http://schemas.xmlsoap.org/ws/2004/09/transfer/Create</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout>" + _PutObjToSelectorsXml(selectors) + "</Header><Body><g:" + objname + " xmlns:g=\"" + resuri + "\">";
980 - for (var n in putobj) { data += "<g:" + n + ">" + putobj[n] + "</g:" + n + ">" }
981 - obj.PerformAjax(data + "</g:" + objname + "></Body></Envelope>", callback, tag, pri);
982 - }
983 -
984 - // Perform a WSMAN CREATE operation
985 - obj.ExecCreateXml = function (resuri, argsxml, callback, tag, pri) {
986 - var objname = obj.GetNameFromUrl(resuri), selector = "";
987 - obj.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/transfer/Create</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60.000S</w:OperationTimeout></Header><Body><r:" + objname + " xmlns:r=\"" + resuri + "\">" + argsxml + "</r:" + objname + "></Body></Envelope>", callback, tag, pri);
988 - }
989 -
990 - // Perform a WSMAN DELETE operation
991 - obj.ExecDelete = function (resuri, putobj, callback, tag, pri) {
992 - var data = "http://schemas.xmlsoap.org/ws/2004/09/transfer/Delete</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout>" + _PutObjToSelectorsXml(putobj) + "</Header><Body /></Envelope>";
993 - obj.PerformAjax(data, callback, tag, pri);
994 - }
995 -
996 - // Perform a WSMAN GET operation
997 - obj.ExecGet = function (resuri, callback, tag, pri) {
998 - obj.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/transfer/Get</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body /></Envelope>", callback, tag, pri);
999 - }
1000 -
1001 - // Perform a WSMAN method call operation
1002 - obj.ExecMethod = function (resuri, method, args, callback, tag, pri, selectors) {
1003 - var argsxml = "";
1004 - for (var i in args) { if (args[i] != null) { if (Array.isArray(args[i])) { for (var x in args[i]) { argsxml += "<r:" + i + ">" + args[i][x] + "</r:" + i + ">"; } } else { argsxml += "<r:" + i + ">" + args[i] + "</r:" + i + ">"; } } }
1005 - obj.ExecMethodXml(resuri, method, argsxml, callback, tag, pri, selectors);
1006 - }
1007 -
1008 - // Perform a WSMAN method call operation. The arguments are already formatted in XML.
1009 - obj.ExecMethodXml = function (resuri, method, argsxml, callback, tag, pri, selectors) {
1010 - obj.PerformAjax(resuri + "/" + method + "</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout>" + _PutObjToSelectorsXml(selectors) + "</Header><Body><r:" + method + '_INPUT' + " xmlns:r=\"" + resuri + "\">" + argsxml + "</r:" + method + "_INPUT></Body></Envelope>", callback, tag, pri);
1011 - }
1012 -
1013 - // Perform a WSMAN ENUM operation
1014 - obj.ExecEnum = function (resuri, callback, tag, pri) {
1015 - obj.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Enumerate</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body><Enumerate xmlns=\"http://schemas.xmlsoap.org/ws/2004/09/enumeration\" /></Body></Envelope>", callback, tag, pri);
1016 - }
1017 -
1018 - // Perform a WSMAN PULL operation
1019 - obj.ExecPull = function (resuri, enumctx, callback, tag, pri) {
1020 - obj.PerformAjax("http://schemas.xmlsoap.org/ws/2004/09/enumeration/Pull</a:Action><a:To>" + obj.Address + "</a:To><w:ResourceURI>" + resuri + "</w:ResourceURI><a:MessageID>" + (obj.NextMessageId++) + "</a:MessageID><a:ReplyTo><a:Address>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:Address></a:ReplyTo><w:OperationTimeout>PT60S</w:OperationTimeout></Header><Body><Pull xmlns=\"http://schemas.xmlsoap.org/ws/2004/09/enumeration\"><EnumerationContext>" + enumctx + "</EnumerationContext><MaxElements>999</MaxElements><MaxCharacters>99999</MaxCharacters></Pull></Body></Envelope>", callback, tag, pri);
1021 - }
1022 -
1023 - // Private method
1024 - obj.ParseWsman = function (xml) {
1025 - try {
1026 - if (!xml.childNodes) xml = _turnToXml(xml);
1027 - var r = { Header:{} }, header = xml.getElementsByTagName("Header")[0], t;
1028 - if (!header) header = xml.getElementsByTagName("a:Header")[0];
1029 - if (!header) return null;
1030 - for (var i = 0; i < header.childNodes.length; i++) {
1031 - var child = header.childNodes[i];
1032 - r.Header[child.localName] = child.textContent;
1033 - }
1034 - var body = xml.getElementsByTagName("Body")[0];
1035 - if (!body) body = xml.getElementsByTagName("a:Body")[0];
1036 - if (!body) return null;
1037 - if (body.childNodes.length > 0) {
1038 - t = body.childNodes[0].localName;
1039 - if (t.indexOf("_OUTPUT") == t.length - 7) { t = t.substring(0, t.length - 7); }
1040 - r.Header['Method'] = t;
1041 - r.Body = _ParseWsmanRec(body.childNodes[0]);
1042 - }
1043 - return r;
1044 - } catch (e) {
1045 - console.log("Unable to parse XML: " + xml);
1046 - return null;
1047 - }
1048 - }
1049 -
1050 - // Private method
1051 - function _ParseWsmanRec(node) {
1052 - var data, r = {};
1053 - for (var i = 0; i < node.childNodes.length; i++) {
1054 - var child = node.childNodes[i];
1055 - if (child.childElementCount == 0) { data = child.textContent; } else { data = _ParseWsmanRec(child); }
1056 - if (data == 'true') data = true; // Convert 'true' into true
1057 - if (data == 'false') data = false; // Convert 'false' into false
1058 -
1059 - var childObj = data;
1060 - if (child.attributes.length > 0) {
1061 - childObj = {'Value': data };
1062 - for(var j = 0; j < child.attributes.length; j++) {
1063 - childObj['@' + child.attributes[j].name] = child.attributes[j].value;
1064 - }
1065 - }
1066 -
1067 - if (r[child.localName] instanceof Array) { r[child.localName].push(childObj); }
1068 - else if (r[child.localName] == undefined) { r[child.localName] = childObj; }
1069 - else { r[child.localName] = [r[child.localName], childObj]; }
1070 - }
1071 - return r;
1072 - }
1073 -
1074 - function _PutObjToBodyXml(resuri, putObj) {
1075 - if(!resuri || putObj === undefined || putObj === null) return '';
1076 - var objname = obj.GetNameFromUrl(resuri);
1077 - var result = '<r:' + objname + ' xmlns:r="' + resuri + '">';
1078 -
1079 - for (var prop in putObj) {
1080 - if (!putObj.hasOwnProperty(prop) || prop.indexOf('__') === 0 || prop.indexOf('@') === 0) continue;
1081 - if (putObj[prop] === undefined || putObj[prop] === null || typeof putObj[prop] === 'function') continue;
1082 - if (typeof putObj[prop] === 'object' && putObj[prop]['ReferenceParameters']) {
1083 - result += '<r:' + prop + '><a:Address>' + putObj[prop].Address + '</a:Address><a:ReferenceParameters><w:ResourceURI>' + putObj[prop]['ReferenceParameters']["ResourceURI"] + '</w:ResourceURI><w:SelectorSet>';
1084 - var selectorArray = putObj[prop]['ReferenceParameters']['SelectorSet']['Selector'];
1085 - if (Array.isArray(selectorArray)) {
1086 - for (var i=0; i< selectorArray.length; i++) {
1087 - result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray[i]) + '>' + selectorArray[i]['Value'] + '</w:Selector>';
1088 - }
1089 - }
1090 - else {
1091 - result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray) + '>' + selectorArray['Value'] + '</w:Selector>';
1092 - }
1093 - result += '</w:SelectorSet></a:ReferenceParameters></r:' + prop + '>';
1094 - }
1095 - else {
1096 - if (Array.isArray(putObj[prop])) {
1097 - for (var i = 0; i < putObj[prop].length; i++) {
1098 - result += '<r:' + prop + '>' + putObj[prop][i].toString() + '</r:' + prop + '>';
1099 - }
1100 - } else {
1101 - result += '<r:' + prop + '>' + putObj[prop].toString() + '</r:' + prop + '>';
1102 - }
1103 - }
1104 - }
1105 -
1106 - result += '</r:' + objname + '>';
1107 - return result;
1108 - }
1109 -
1110 - /*
1111 - convert
1112 - { @Name: 'InstanceID', @AttrName: 'Attribute Value'}
1113 - into
1114 - ' Name="InstanceID" AttrName="Attribute Value" '
1115 - */
1116 - function _ObjectToXmlAttributes(objWithAttributes) {
1117 - if(!objWithAttributes) return '';
1118 - var result = ' ';
1119 - for (var propName in objWithAttributes) {
1120 - if (!objWithAttributes.hasOwnProperty(propName) || propName.indexOf('@') !== 0) continue;
1121 - result += propName.substring(1) + '="' + objWithAttributes[propName] + '" ';
1122 - }
1123 - return result;
1124 - }
1125 -
1126 - function _PutObjToSelectorsXml(selectorSet) {
1127 - if (!selectorSet) return '';
1128 - if (typeof selectorSet == 'string') return selectorSet;
1129 - if (selectorSet['InstanceID']) return "<w:SelectorSet><w:Selector Name=\"InstanceID\">" + selectorSet['InstanceID'] + "</w:Selector></w:SelectorSet>";
1130 - var result = '<w:SelectorSet>';
1131 - for(var propName in selectorSet) {
1132 - if (!selectorSet.hasOwnProperty(propName)) continue;
1133 - result += '<w:Selector Name="' + propName + '">';
1134 - if (selectorSet[propName]['ReferenceParameters']) {
1135 - result += '<a:EndpointReference>';
1136 - result += '<a:Address>' + selectorSet[propName]['Address'] + '</a:Address><a:ReferenceParameters><w:ResourceURI>' + selectorSet[propName]['ReferenceParameters']['ResourceURI'] + '</w:ResourceURI><w:SelectorSet>';
1137 - var selectorArray = selectorSet[propName]['ReferenceParameters']['SelectorSet']['Selector'];
1138 - if (Array.isArray(selectorArray)) {
1139 - for (var i = 0; i < selectorArray.length; i++) {
1140 - result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray[i]) + '>' + selectorArray[i]['Value'] + '</w:Selector>';
1141 - }
1142 - }
1143 - else {
1144 - result += '<w:Selector' + _ObjectToXmlAttributes(selectorArray) + '>' + selectorArray['Value'] + '</w:Selector>';
1145 - }
1146 - result += '</w:SelectorSet></a:ReferenceParameters></a:EndpointReference>';
1147 - } else {
1148 - result += selectorSet[propName];
1149 - }
1150 - result += '</w:Selector>';
1151 - }
1152 - result += '</w:SelectorSet>';
1153 - return result;
1154 - }
1155 -
1156 - function _turnToXml(text) {
1157 - if (window.DOMParser) {
1158 - return new DOMParser().parseFromString(text, "text/xml");
1159 - }
1160 - else // Internet Explorer
1161 - {
1162 - var xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
1163 - xmlDoc.async = false;
1164 - xmlDoc.loadXML(text);
1165 - return xmlDoc;
1166 - }
1167 - }
1168 -
1169 - return obj;
1170 -}
1171 -/**
1172 -* @description Remote Desktop
1173 -* @author Ylian Saint-Hilaire
1174 -* @version v0.0.2g
1175 -*/
1176 -
1177 -// Construct a MeshServer object
1178 -var CreateAmtRemoteDesktop = function (divid, scrolldiv) {
1179 - var obj = {};
1180 - obj.canvasid = divid;
1181 - obj.CanvasId = Q(divid);
1182 - obj.scrolldiv = scrolldiv;
1183 - obj.canvas = Q(divid).getContext("2d");
1184 - obj.protocol = 2; // KVM
1185 - obj.state = 0;
1186 - obj.acc = "";
1187 - obj.ScreenWidth = 960;
1188 - obj.ScreenHeight = 700;
1189 - obj.width = 0;
1190 - obj.height = 0;
1191 - obj.rwidth = 0;
1192 - obj.rheight = 0;
1193 - obj.bpp = 2; // Bytes per pixel (1 or 2 supported)
1194 - obj.useZRLE = true;
1195 - obj.showmouse = true;
1196 - obj.buttonmask = 0;
1197 - obj.localKeyMap = true;
1198 - //obj.inbytes = 0;
1199 - //obj.outbytes = 0;
1200 - obj.spare = null;
1201 - obj.sparew = 0;
1202 - obj.spareh = 0;
1203 - obj.sparew2 = 0;
1204 - obj.spareh2 = 0;
1205 - obj.sparecache = {};
1206 - obj.ZRLEfirst = 1;
1207 - obj.onScreenSizeChange = null;
1208 - obj.frameRateDelay = 0;
1209 - // ###BEGIN###{DesktopInband}
1210 - obj.kvmDataSupported = false;
1211 - obj.onKvmData = null;
1212 - obj.onKvmDataPending = [];
1213 - obj.onKvmDataAck = -1;
1214 - obj.holding = false;
1215 - obj.lastKeepAlive = Date.now();
1216 - // ###END###{DesktopInband}
1217 -
1218 -
1219 - // Private method
1220 - obj.Debug = function (msg) { console.log(msg); }
1221 -
1222 - obj.xxStateChange = function (newstate) {
1223 - if (newstate == 0) {
1224 - obj.canvas.fillStyle = '#000000';
1225 - obj.canvas.fillRect(0, 0, obj.width, obj.height);
1226 - obj.canvas.canvas.width = obj.rwidth = obj.width = 640;
1227 - obj.canvas.canvas.height = obj.rheight = obj.height = 400;
1228 - QS(obj.canvasid).cursor = 'default';
1229 - } else {
1230 - QS(obj.canvasid).cursor = obj.showmouse ?'default':'none';
1231 - }
1232 - }
1233 -
1234 - obj.ProcessData = function (data) {
1235 - if (!data) return;
1236 - // obj.Debug("KRecv(" + data.length + "): " + rstr2hex(data));
1237 - //obj.inbytes += data.length;
1238 - //obj.Debug("KRecv(" + obj.inbytes + ")");
1239 - obj.acc += data;
1240 - while (obj.acc.length > 0) {
1241 - //obj.Debug("KAcc(" + obj.acc.length + "): " + rstr2hex(obj.acc));
1242 - var cmdsize = 0;
1243 - if (obj.state == 0 && obj.acc.length >= 12) {
1244 - // Getting handshake & version
1245 - cmdsize = 12;
1246 - //if (obj.acc.substring(0, 4) != "RFB ") { return obj.Stop(); }
1247 - //var version = parseFloat(obj.acc.substring(4, 11));
1248 - //obj.Debug("KVersion: " + version);
1249 - obj.state = 1;
1250 - obj.send("RFB 003.008\n");
1251 - }
1252 - else if (obj.state == 1 && obj.acc.length >= 1) {
1253 - // Getting security options
1254 - cmdsize = obj.acc.charCodeAt(0) + 1;
1255 - obj.send(String.fromCharCode(1)); // Send the "None" security type. Since we already authenticated using redirection digest auth, we don't need to do this again.
1256 - obj.state = 2;
1257 - }
1258 - else if (obj.state == 2 && obj.acc.length >= 4) {
1259 - // Getting security response
1260 - cmdsize = 4;
1261 - if (ReadInt(obj.acc, 0) != 0) { return obj.Stop(); }
1262 - obj.send(String.fromCharCode(1)); // Send share desktop flag
1263 - obj.state = 3;
1264 - }
1265 - else if (obj.state == 3 && obj.acc.length >= 24) {
1266 - // Getting server init
1267 - var namelen = ReadInt(obj.acc, 20);
1268 - if (obj.acc.length < 24 + namelen) return;
1269 - cmdsize = 24 + namelen;
1270 - obj.canvas.canvas.width = obj.rwidth = obj.width = obj.ScreenWidth = ReadShort(obj.acc, 0);
1271 - obj.canvas.canvas.height = obj.rheight = obj.height = obj.ScreenHeight = ReadShort(obj.acc, 2);
1272 -
1273 - // These are all values we don't really need, we are going to only run in RGB565 or RGB332 and not use the flexibility provided by these settings.
1274 - // Makes the javascript code smaller and maybe a bit faster.
1275 - /*
1276 - obj.xbpp = obj.acc.charCodeAt(4);
1277 - obj.depth = obj.acc.charCodeAt(5);
1278 - obj.bigend = obj.acc.charCodeAt(6);
1279 - obj.truecolor = obj.acc.charCodeAt(7);
1280 - obj.rmax = ReadShort(obj.acc, 8);
1281 - obj.gmax = ReadShort(obj.acc, 10);
1282 - obj.bmax = ReadShort(obj.acc, 12);
1283 - obj.rsh = obj.acc.charCodeAt(14);
1284 - obj.gsh = obj.acc.charCodeAt(15);
1285 - obj.bsh = obj.acc.charCodeAt(16);
1286 - var name = obj.acc.substring(24, 24 + namelen);
1287 - obj.Debug("name: " + name);
1288 - obj.Debug("width: " + obj.width + ", height: " + obj.height);
1289 - obj.Debug("bits-per-pixel: " + obj.xbpp);
1290 - obj.Debug("depth: " + obj.depth);
1291 - obj.Debug("big-endian-flag: " + obj.bigend);
1292 - obj.Debug("true-colour-flag: " + obj.truecolor);
1293 - obj.Debug("rgb max: " + obj.rmax + "," + obj.gmax + "," + obj.bmax);
1294 - obj.Debug("rgb shift: " + obj.rsh + "," + obj.gsh + "," + obj.bsh);
1295 - */
1296 -
1297 - // SetEncodings, with AMT we can't omit RAW, must be specified.
1298 - // Intel AMT supports encodings: RAW (0), ZRLE (16), Desktop Size (0xFFFFFF21, -223)
1299 -
1300 - var supportedEncodings = '';
1301 - if (obj.useZRLE) supportedEncodings += IntToStr(16);
1302 - supportedEncodings += IntToStr(0);
1303 - // ###BEGIN###{DesktopInband}
1304 - supportedEncodings += IntToStr(1092);
1305 - // ###END###{DesktopInband}
1306 -
1307 - obj.send(String.fromCharCode(2, 0) + ShortToStr((supportedEncodings.length / 4) + 1) + supportedEncodings + IntToStr(-223)); // Supported Encodings + Desktop Size
1308 -
1309 - // Set the pixel encoding to something much smaller
1310 - // obj.send(String.fromCharCode(0, 0, 0, 0, 16, 16, 0, 1) + ShortToStr(31) + ShortToStr(63) + ShortToStr(31) + String.fromCharCode(11, 5, 0, 0, 0, 0)); // Setup 16 bit color RGB565 (This is the default, so we don't need to set it)
1311 - if (obj.bpp == 1) obj.send(String.fromCharCode(0, 0, 0, 0, 8, 8, 0, 1) + ShortToStr(7) + ShortToStr(7) + ShortToStr(3) + String.fromCharCode(5, 2, 0, 0, 0, 0)); // Setup 8 bit color RGB332
1312 -
1313 - obj.state = 4;
1314 - obj.parent.xxStateChange(3);
1315 - _SendRefresh();
1316 - //obj.timer = setInterval(obj.xxOnTimer, 50);
1317 -
1318 -
1319 - if (obj.onScreenSizeChange != null) { obj.onScreenSizeChange(obj, obj.ScreenWidth, obj.ScreenHeight); }
1320 - }
1321 - else if (obj.state == 4) {
1322 - switch (obj.acc.charCodeAt(0)) {
1323 - case 0: // FramebufferUpdate
1324 - if (obj.acc.length < 4) return;
1325 - obj.state = 100 + ReadShort(obj.acc, 2); // Read the number of tiles that are going to be sent, add 100 and use that as our protocol state.
1326 - cmdsize = 4;
1327 - break;
1328 - case 2: // This is the bell, do nothing.
1329 - cmdsize = 1;
1330 - break;
1331 - case 3: // This is ServerCutText
1332 - if (obj.acc.length < 8) return;
1333 - var len = ReadInt(obj.acc, 4) + 8;
1334 - if (obj.acc.length < len) return;
1335 - cmdsize = handleServerCutText(obj.acc);
1336 - break;
1337 - }
1338 - }
1339 - else if (obj.state > 100 && obj.acc.length >= 12) {
1340 - var x = ReadShort(obj.acc, 0),
1341 - y = ReadShort(obj.acc, 2),
1342 - width = ReadShort(obj.acc, 4),
1343 - height = ReadShort(obj.acc, 6),
1344 - s = width * height,
1345 - encoding = ReadInt(obj.acc, 8);
1346 -
1347 - if (encoding < 17) {
1348 - if (width < 1 || width > 64 || height < 1 || height > 64) { console.log("Invalid tile size (" + width + "," + height + "), disconnecting."); return obj.Stop(); }
1349 -
1350 - // Set the spare bitmap to the rigth size if it's not already. This allows us to recycle the spare most if not all the time.
1351 - if (obj.sparew != width || obj.spareh != height) {
1352 - obj.sparew = obj.sparew2 = width;
1353 - obj.spareh = obj.spareh2 = height;
1354 - var xspacecachename = obj.sparew2 + 'x' + obj.spareh2;
1355 - obj.spare = obj.sparecache[xspacecachename];
1356 - if (!obj.spare) { obj.sparecache[xspacecachename] = obj.spare = obj.canvas.createImageData(obj.sparew2, obj.spareh2); }
1357 - }
1358 -
1359 - }
1360 -
1361 - if (encoding == 0xFFFFFF21) {
1362 - // Desktop Size (0xFFFFFF21, -223)
1363 - obj.canvas.canvas.width = obj.rwidth = obj.width = width;
1364 - obj.canvas.canvas.height = obj.rheight = obj.height = height;
1365 - obj.send(String.fromCharCode(3, 0, 0, 0, 0, 0) + ShortToStr(obj.width) + ShortToStr(obj.height)); // FramebufferUpdateRequest
1366 - cmdsize = 12;
1367 - if (obj.onScreenSizeChange != null) { obj.onScreenSizeChange(obj, obj.ScreenWidth, obj.ScreenHeight); }
1368 - // obj.Debug("New desktop width: " + obj.width + ", height: " + obj.height);
1369 - }
1370 - else if (encoding == 0) {
1371 - // RAW encoding
1372 - var ptr = 12, cs = 12 + (s * obj.bpp);
1373 - if (obj.acc.length < cs) return; // Check we have all the data needed and we can only draw 64x64 tiles.
1374 - cmdsize = cs;
1375 -
1376 - // CRITICAL LOOP, optimize this as much as possible
1377 - for (var i = 0; i < s; i++) { _setPixel(obj.acc.charCodeAt(ptr++) + ((obj.bpp == 2) ? (obj.acc.charCodeAt(ptr++) << 8) : 0), i); }
1378 - _putImage(obj.spare, x, y);
1379 - }
1380 - else if (encoding == 16) {
1381 - // ZRLE encoding
1382 - if (obj.acc.length < 16) return;
1383 - var datalen = ReadInt(obj.acc, 12);
1384 - if (obj.acc.length < (16 + datalen)) return;
1385 - //obj.Debug("RECT ZRLE (" + x + "," + y + "," + width + "," + height + ") LEN = " + datalen);
1386 - //obj.Debug("RECT ZRLE LEN: " + ReadShortX(obj.acc, 17) + ", DATA: " + rstr2hex(obj.acc.substring(16)));
1387 -
1388 - // Process the ZLib header if this is the first block
1389 - var ptr = 16, delta = 5, dx = 0;
1390 -
1391 - if (datalen > 5 && obj.acc.charCodeAt(ptr) == 0 && ReadShortX(obj.acc, ptr + 1) == (datalen - delta)) {
1392 - // This is an uncompressed ZLib data block
1393 - _decodeLRE(obj.acc, ptr + 5, x, y, width, height, s, datalen);
1394 - }
1395 -
1396 - cmdsize = 16 + datalen;
1397 - }
1398 - else {
1399 - obj.Debug("Unknown Encoding: " + encoding);
1400 - return obj.Stop();
1401 - }
1402 - if (--obj.state == 100) {
1403 - obj.state = 4;
1404 - if (obj.frameRateDelay == 0) {
1405 - _SendRefresh(); // Ask for new frame
1406 - } else {
1407 - setTimeout(_SendRefresh, obj.frameRateDelay); // Hold x miliseconds before asking for a new frame
1408 - }
1409 - }
1410 - }
1411 -
1412 - if (cmdsize == 0) return;
1413 - obj.acc = obj.acc.substring(cmdsize);
1414 - }
1415 - }
1416 -
1417 - function _decodeLRE(data, ptr, x, y, width, height, s, datalen) {
1418 - var subencoding = data.charCodeAt(ptr++), index, v, runlengthdecode, palette = {}, rlecount = 0, runlength = 0, i;
1419 - // obj.Debug("RECT RLE (" + (datalen - 5) + ", " + subencoding + "):" + rstr2hex(data.substring(21, 21 + (datalen - 5))));
1420 - if (subencoding == 0) {
1421 - // RAW encoding
1422 - for (i = 0; i < s; i++) { _setPixel(data.charCodeAt(ptr++) + ((obj.bpp == 2) ? (data.charCodeAt(ptr++) << 8) : 0), i); }
1423 - _putImage(obj.spare, x, y);
1424 - }
1425 - else if (subencoding == 1) {
1426 - // Solid color tile
1427 - v = data.charCodeAt(ptr++) + ((obj.bpp == 2) ? (data.charCodeAt(ptr++) << 8) : 0);
1428 - obj.canvas.fillStyle = 'rgb(' + ((obj.bpp == 1) ? ((v & 224) + ',' + ((v & 28) << 3) + ',' + _fixColor((v & 3) << 6)) : (((v >> 8) & 248) + ',' + ((v >> 3) & 252) + ',' + ((v & 31) << 3))) + ')';
1429 -
1430 -
1431 - obj.canvas.fillRect(x, y, width, height);
1432 - }
1433 - else if (subencoding > 1 && subencoding < 17) { // Packed palette encoded tile
1434 - // Read the palette
1435 - var br = 4, bm = 15; // br is BitRead and bm is BitMask. By adjusting these two we can support all the variations in this encoding.
1436 - for (i = 0; i < subencoding; i++) { palette[i] = data.charCodeAt(ptr++) + ((obj.bpp == 2) ? (data.charCodeAt(ptr++) << 8) : 0); }
1437 -
1438 - // Compute bits to read & bit mark
1439 - if (subencoding == 2) { br = 1; bm = 1; } else if (subencoding <= 4) { br = 2; bm = 3; }
1440 -
1441 - // Display all the bits
1442 - while (rlecount < s && ptr < data.length) { v = data.charCodeAt(ptr++); for (i = (8 - br) ; i >= 0; i -= br) { _setPixel(palette[(v >> i) & bm], rlecount++); } }
1443 - _putImage(obj.spare, x, y);
1444 - }
1445 - else if (subencoding == 128) { // RLE encoded tile
1446 - while (rlecount < s && ptr < data.length) {
1447 - // Get the run color
1448 - v = data.charCodeAt(ptr++) + ((obj.bpp == 2) ? (data.charCodeAt(ptr++) << 8) : 0);
1449 -
1450 - // Decode the run length. This is the fastest and most compact way I found to do this.
1451 - runlength = 1; do { runlength += (runlengthdecode = data.charCodeAt(ptr++)); } while (runlengthdecode == 255);
1452 -
1453 - // Draw a run
1454 - while (--runlength >= 0) { _setPixel(v, rlecount++); }
1455 - }
1456 - _putImage(obj.spare, x, y);
1457 - }
1458 - else if (subencoding > 129) { // Palette RLE encoded tile
1459 - // Read the palette
1460 - for (i = 0; i < (subencoding - 128) ; i++) { palette[i] = data.charCodeAt(ptr++) + ((obj.bpp == 2) ? (data.charCodeAt(ptr++) << 8) : 0); }
1461 -
1462 - // Decode RLE on palette
1463 - while (rlecount < s && ptr < data.length) {
1464 - // Setup the run, get the color index and get the color from the palette.
1465 - runlength = 1; index = data.charCodeAt(ptr++); v = palette[index % 128];
1466 -
1467 - // If the index starts with high order bit 1, this is a run and decode the run length.
1468 - if (index > 127) { do { runlength += (runlengthdecode = data.charCodeAt(ptr++)); } while (runlengthdecode == 255); }
1469 -
1470 - // Draw a run
1471 - while (--runlength >= 0) { _setPixel(v, rlecount++); }
1472 - }
1473 - _putImage(obj.spare, x, y);
1474 - }
1475 - }
1476 -
1477 - // ###BEGIN###{DesktopInband}
1478 - obj.hold = function (holding) {
1479 - if (obj.holding == holding) return;
1480 - obj.holding = holding;
1481 - obj.canvas.fillStyle = '#000000';
1482 - obj.canvas.fillRect(0, 0, obj.width, obj.height); // Paint black
1483 - if (obj.holding == false) {
1484 - // Go back to normal operations
1485 - // Set canvas size and ask for full screen refresh
1486 - if ((obj.canvas.canvas.width != obj.width) || (obj.canvas.canvas.height != obj.height)) {
1487 - obj.canvas.canvas.width = obj.width; obj.canvas.canvas.height = obj.height;
1488 - if (obj.onScreenSizeChange != null) { obj.onScreenSizeChange(obj, obj.ScreenWidth, obj.ScreenHeight); } // ???
1489 - }
1490 - obj.Send(String.fromCharCode(3, 0, 0, 0, 0, 0) + ShortToStr(obj.width) + ShortToStr(obj.height)); // FramebufferUpdateRequest
1491 - } else {
1492 - obj.UnGrabMouseInput();
1493 - obj.UnGrabKeyInput();
1494 - }
1495 - }
1496 - // ###END###{DesktopInband}
1497 -
1498 - function _putImage(i, x, y) {
1499 - // ###BEGIN###{DesktopInband}
1500 - if (obj.holding == true) return;
1501 - // ###END###{DesktopInband}
1502 - obj.canvas.putImageData(i, x, y);
1503 - }
1504 -
1505 - function _setPixel(v, p) {
1506 - var pp = p * 4;
1507 -
1508 -
1509 - if (obj.bpp == 1) {
1510 - // Set 8bit color RGB332
1511 - obj.spare.data[pp++] = v & 224;
1512 - obj.spare.data[pp++] = (v & 28) << 3;
1513 - obj.spare.data[pp++] = _fixColor((v & 3) << 6);
1514 - } else {
1515 - // Set 16bit color RGB565
1516 - obj.spare.data[pp++] = (v >> 8) & 248;
1517 - obj.spare.data[pp++] = (v >> 3) & 252;
1518 - obj.spare.data[pp++] = (v & 31) << 3;
1519 - }
1520 - obj.spare.data[pp] = 0xFF; // Set alpha channel to opaque.
1521 - }
1522 -
1523 -
1524 - function _fixColor(c) { return (c > 127) ? (c + 32) : c; }
1525 -
1526 - function _SendRefresh() {
1527 - // ###BEGIN###{DesktopInband}
1528 - if (obj.holding == true) return;
1529 - // ###END###{DesktopInband}
1530 - // Request the entire screen
1531 - obj.send(String.fromCharCode(3, 1, 0, 0, 0, 0) + ShortToStr(obj.rwidth) + ShortToStr(obj.rheight)); // FramebufferUpdateRequest
1532 - }
1533 -
1534 - obj.Start = function () {
1535 - //obj.Debug("KVM-Start");
1536 - obj.state = 0;
1537 - obj.acc = "";
1538 - obj.ZRLEfirst = 1;
1539 - //obj.inbytes = 0;
1540 - //obj.outbytes = 0;
1541 - // ###BEGIN###{DesktopInband}
1542 - obj.onKvmDataPending = [];
1543 - obj.onKvmDataAck = -1;
1544 - obj.kvmDataSupported = false;
1545 - // ###END###{DesktopInband}
1546 - for (var i in obj.sparecache) { delete obj.sparecache[i]; }
1547 - }
1548 -
1549 - obj.Stop = function () {
1550 - obj.UnGrabMouseInput();
1551 - obj.UnGrabKeyInput();
1552 - obj.parent.Stop();
1553 - }
1554 -
1555 - obj.send = function (x) {
1556 - //obj.Debug("KSend(" + x.length + "): " + rstr2hex(x));
1557 - //obj.outbytes += x.length;
1558 - obj.parent.send(x);
1559 - }
1560 -
1561 - var convertAmtKeyCodeTable = {
1562 - "Pause": 19,
1563 - "CapsLock": 20,
1564 - "Space": 32,
1565 - "Quote": 39,
1566 - "Minus": 45,
1567 - "NumpadMultiply": 42,
1568 - "NumpadAdd": 43,
1569 - "PrintScreen": 44,
1570 - "Comma": 44,
1571 - "NumpadSubtract": 45,
1572 - "NumpadDecimal": 46,
1573 - "Period": 46,
1574 - "Slash": 47,
1575 - "NumpadDivide": 47,
1576 - "Semicolon": 59,
1577 - "Equal": 61,
1578 - "OSLeft": 91,
1579 - "BracketLeft": 91,
1580 - "OSRight": 91,
1581 - "Backslash": 92,
1582 - "BracketRight": 93,
1583 - "ContextMenu": 93,
1584 - "Backquote": 96,
1585 - "NumLock": 144,
1586 - "ScrollLock": 145,
1587 - "Backspace": 0xff08,
1588 - "Tab": 0xff09,
1589 - "Enter": 0xff0d,
1590 - "NumpadEnter": 0xff0d,
1591 - "Escape": 0xff1b,
1592 - "Delete": 0xffff,
1593 - "Home": 0xff50,
1594 - "PageUp": 0xff55,
1595 - "PageDown": 0xff56,
1596 - "ArrowLeft": 0xff51,
1597 - "ArrowUp": 0xff52,
1598 - "ArrowRight": 0xff53,
1599 - "ArrowDown": 0xff54,
1600 - "End": 0xff57,
1601 - "Insert": 0xff63,
1602 - "F1": 0xffbe,
1603 - "F2": 0xffbf,
1604 - "F3": 0xffc0,
1605 - "F4": 0xffc1,
1606 - "F5": 0xffc2,
1607 - "F6": 0xffc3,
1608 - "F7": 0xffc4,
1609 - "F8": 0xffc5,
1610 - "F9": 0xffc6,
1611 - "F10": 0xffc7,
1612 - "F11": 0xffc8,
1613 - "F12": 0xffc9,
1614 - "ShiftLeft": 0xffe1,
1615 - "ShiftRight": 0xffe2,
1616 - "ControlLeft": 0xffe3,
1617 - "ControlRight": 0xffe4,
1618 - "AltLeft": 0xffe9,
1619 - "AltRight": 0xffea,
1620 - "MetaLeft": 0xffe7,
1621 - "MetaRight": 0xffe8
1622 - }
1623 - function convertAmtKeyCode(e) {
1624 - if (e.code.startsWith('Key') && e.code.length == 4) { return e.code.charCodeAt(3) + ((e.shiftKey == false) ? 32 : 0); }
1625 - if (e.code.startsWith('Digit') && e.code.length == 6) { return e.code.charCodeAt(5); }
1626 - if (e.code.startsWith('Numpad') && e.code.length == 7) { return e.code.charCodeAt(6); }
1627 - return convertAmtKeyCodeTable[e.code];
1628 - }
1629 -
1630 - /*
1631 - Intel AMT only recognizes a small subset of keysym characters defined in the keysymdef.h so you don�t need to
1632 - implement all the languages (this is taken care by the USB Scancode Extension in RFB4.0 protocol).
1633 - The only subset recognized by the FW is the defined by the following sets : XK_LATIN1 , XK_MISCELLANY, XK_3270, XK_XKB_KEYS, XK_KATAKANA.
1634 - In addition to keysymdef.h symbols there are 6 japanese extra keys that we do support:
1635 -
1636 - #define XK_Intel_EU_102kbd_backslash_pipe_45 0x17170056 // European 102-key: 45 (backslash/pipe), usb Usage: 0x64
1637 - #define XK_Intel_JP_106kbd_yen_pipe 0x1717007d // Japanese 106-key: 14 (Yen/pipe), usb Usage: 0x89
1638 - #define XK_Intel_JP_106kbd_backslash_underbar 0x17170073 // Japanese 106-key: 56 (backslash/underbar), usb Usage: 0x87
1639 - #define XK_Intel_JP_106kbd_NoConvert 0x1717007b // Japanese 106-key: 131 (NoConvert), usb Usage: 0x8b
1640 - #define XK_Intel_JP_106kbd_Convert 0x17170079 // Japanese 106-key: 132 (Convert), usb Usage: 0x8a
1641 - #define XK_Intel_JP_106kbd_Hirigana_Katakana 0x17170070 // Japanese 106-key: 133 (Hirigana/Katakana), usb Usage: 0x88
1642 - */
1643 -
1644 - function _keyevent(d, e) {
1645 - if (!e) { e = window.event; }
1646 -
1647 - if (e.code && (obj.localKeyMap == false)) {
1648 - // For new browsers, this mapping is keyboard language independent
1649 - var k = convertAmtKeyCode(e);
1650 - if (k != null) { obj.sendkey(k, d); }
1651 - } else {
1652 - // For older browsers, this mapping works best for EN-US keyboard
1653 - var k = e.keyCode, kk = k;
1654 - if (e.shiftKey == false && k >= 65 && k <= 90) kk = k + 32;
1655 - if (k >= 112 && k <= 124) kk = k + 0xFF4E;
1656 - if (k == 8) kk = 0xff08; // Backspace
1657 - if (k == 9) kk = 0xff09; // Tab
1658 - if (k == 13) kk = 0xff0d; // Return
1659 - if (k == 16) kk = 0xffe1; // Shift (Left)
1660 - if (k == 17) kk = 0xffe3; // Ctrl (Left)
1661 - if (k == 18) kk = 0xffe9; // Alt (Left)
1662 - if (k == 27) kk = 0xff1b; // ESC
1663 - if (k == 33) kk = 0xff55; // PageUp
1664 - if (k == 34) kk = 0xff56; // PageDown
1665 - if (k == 35) kk = 0xff57; // End
1666 - if (k == 36) kk = 0xff50; // Home
1667 - if (k == 37) kk = 0xff51; // Left
1668 - if (k == 38) kk = 0xff52; // Up
1669 - if (k == 39) kk = 0xff53; // Right
1670 - if (k == 40) kk = 0xff54; // Down
1671 - if (k == 45) kk = 0xff63; // Insert
1672 - if (k == 46) kk = 0xffff; // Delete
1673 - if (k >= 96 && k <= 105) kk = k - 48; // Key pad numbers
1674 - if (k == 106) kk = 42; // Pad *
1675 - if (k == 107) kk = 43; // Pad +
1676 - if (k == 109) kk = 45; // Pad -
1677 - if (k == 110) kk = 46; // Pad .
1678 - if (k == 111) kk = 47; // Pad /
1679 - if (k == 186) kk = 59; // ;
1680 - if (k == 187) kk = 61; // =
1681 - if (k == 188) kk = 44; // ,
1682 - if (k == 189) kk = 45; // -
1683 - if (k == 190) kk = 46; // .
1684 - if (k == 191) kk = 47; // /
1685 - if (k == 192) kk = 96; // `
1686 - if (k == 219) kk = 91; // [
1687 - if (k == 220) kk = 92; // \
1688 - if (k == 221) kk = 93; // ]t
1689 - if (k == 222) kk = 39; // '
1690 - //console.log('Key' + d + ": " + k + " = " + kk);
1691 - obj.sendkey(kk, d);
1692 - }
1693 - return obj.haltEvent(e);
1694 - }
1695 -
1696 - obj.sendkey = function (k, d) {
1697 - if (typeof k == 'object') { for (var i in k) { obj.sendkey(k[i][0], k[i][1]); } }
1698 - else { obj.send(String.fromCharCode(4, d, 0, 0) + IntToStr(k)); }
1699 - }
1700 -
1701 - function handleServerCutText(acc) {
1702 - if (acc.length < 8) return 0;
1703 - var len = ReadInt(obj.acc, 4) + 8;
1704 - if (acc.length < len) return 0;
1705 - // ###BEGIN###{DesktopInband}
1706 - if (obj.onKvmData != null) {
1707 - var d = acc.substring(8, len);
1708 - if ((d.length >= 16) && (d.substring(0, 15) == '\0KvmDataChannel')) {
1709 - if (obj.kvmDataSupported == false) { obj.kvmDataSupported = true; console.log('KVM Data Channel Supported.'); }
1710 - if (((obj.onKvmDataAck == -1) && (d.length == 16)) || (d.charCodeAt(15) != 0)) { obj.onKvmDataAck = true; }
1711 - //if (urlvars && urlvars['kvmdatatrace']) { console.log('KVM-Recv(' + (d.length - 16) + '): ' + d.substring(16)); }
1712 - if (d.length >= 16) { obj.onKvmData(d.substring(16)); } // Event the data and ack
1713 - if ((obj.onKvmDataAck == true) && (obj.onKvmDataPending.length > 0)) { obj.sendKvmData(obj.onKvmDataPending.shift()); } // Send pending data
1714 - }
1715 - }
1716 - // ###END###{DesktopInband}
1717 - return len;
1718 - }
1719 -
1720 - // ###BEGIN###{DesktopInband}
1721 - obj.sendKvmData = function (x) {
1722 - if (obj.onKvmDataAck !== true) {
1723 - obj.onKvmDataPending.push(x);
1724 - } else {
1725 - //if (urlvars && urlvars['kvmdatatrace']) { console.log('KVM-Send(' + x.length + '): ' + x); }
1726 - x = '\0KvmDataChannel\0' + x;
1727 - obj.send(String.fromCharCode(6, 0, 0, 0) + IntToStr(x.length) + x);
1728 - obj.onKvmDataAck = false;
1729 - }
1730 - }
1731 -
1732 - // Send a HWKVM keep alive if it's not been sent in the last 5 seconds.
1733 - obj.sendKeepAlive = function () {
1734 - if (obj.lastKeepAlive < Date.now() - 5000) { obj.lastKeepAlive = Date.now(); obj.send(String.fromCharCode(6, 0, 0, 0) + IntToStr(16) + '\0KvmDataChannel\0'); }
1735 - }
1736 - // ###END###{DesktopInband}
1737 -
1738 - obj.SendCtrlAltDelMsg = function () { obj.sendcad(); }
1739 - obj.sendcad = function () { obj.sendkey([[0xFFE3, 1], [0xFFE9, 1], [0xFFFF, 1], [0xFFFF, 0], [0xFFE9, 0], [0xFFE3, 0]]); } // Control down, Alt down, Delete down, Delete up , Alt up , Control up
1740 -
1741 - var _MouseInputGrab = false;
1742 - var _KeyInputGrab = false;
1743 -
1744 - obj.GrabMouseInput = function () {
1745 - if (_MouseInputGrab == true) return;
1746 - var c = obj.canvas.canvas;
1747 - c.onmouseup = obj.mouseup;
1748 - c.onmousedown = obj.mousedown;
1749 - c.onmousemove = obj.mousemove;
1750 - //if (navigator.userAgent.match(/mozilla/i)) c.DOMMouseScroll = obj.xxDOMMouseScroll; else c.onmousewheel = obj.xxMouseWheel;
1751 - _MouseInputGrab = true;
1752 - }
1753 -
1754 - obj.UnGrabMouseInput = function () {
1755 - if (_MouseInputGrab == false) return;
1756 - var c = obj.canvas.canvas;
1757 - c.onmousemove = null;
1758 - c.onmouseup = null;
1759 - c.onmousedown = null;
1760 - //if (navigator.userAgent.match(/mozilla/i)) c.DOMMouseScroll = null; else c.onmousewheel = null;
1761 - _MouseInputGrab = false;
1762 - }
1763 -
1764 - obj.GrabKeyInput = function () {
1765 - if (_KeyInputGrab == true) return;
1766 - document.onkeyup = obj.handleKeyUp;
1767 - document.onkeydown = obj.handleKeyDown;
1768 - document.onkeypress = obj.handleKeys;
1769 - _KeyInputGrab = true;
1770 - }
1771 -
1772 - obj.UnGrabKeyInput = function () {
1773 - if (_KeyInputGrab == false) return;
1774 - document.onkeyup = null;
1775 - document.onkeydown = null;
1776 - document.onkeypress = null;
1777 - _KeyInputGrab = false;
1778 - }
1779 -
1780 - obj.handleKeys = function (e) { return obj.haltEvent(e); }
1781 - obj.handleKeyUp = function (e) { return _keyevent(0, e); }
1782 - obj.handleKeyDown = function (e) { return _keyevent(1, e); }
1783 - obj.haltEvent = function (e) { if (e.preventDefault) e.preventDefault(); if (e.stopPropagation) e.stopPropagation(); return false; }
1784 -
1785 - // RFB "PointerEvent" and mouse handlers
1786 - obj.mousedblclick = function (e) { }
1787 - obj.mousedown = function (e) { obj.buttonmask |= (1 << e.button); return obj.mousemove(e); }
1788 - obj.mouseup = function (e) { obj.buttonmask &= (0xFFFF - (1 << e.button)); return obj.mousemove(e); }
1789 - obj.mousemove = function (e) {
1790 - if (obj.state != 4) return true;
1791 - var pos = obj.getPositionOfControl(Q(obj.canvasid));
1792 - obj.mx = (e.pageX - pos[0]) * (obj.canvas.canvas.height / Q(obj.canvasid).offsetHeight);
1793 - obj.my = ((e.pageY - pos[1] + (scrolldiv ? scrolldiv.scrollTop : 0)) * (obj.canvas.canvas.width / Q(obj.canvasid).offsetWidth));
1794 -
1795 -
1796 - obj.send(String.fromCharCode(5, obj.buttonmask) + ShortToStr(obj.mx) + ShortToStr(obj.my));
1797 -
1798 -
1799 - return obj.haltEvent(e);
1800 - }
1801 -
1802 - obj.getPositionOfControl = function (Control) {
1803 - var Position = Array(2);
1804 - Position[0] = Position[1] = 0;
1805 - while (Control) {
1806 - Position[0] += Control.offsetLeft;
1807 - Position[1] += Control.offsetTop;
1808 - Control = Control.offsetParent;
1809 - }
1810 - return Position;
1811 - }
1812 -
1813 - return obj;
1814 -}
1815 -/**
1816 -* @description Remote Terminal
1817 -* @author Ylian Saint-Hilaire
1818 -* @version v0.0.2c
1819 -*/
1820 -
1821 -// Construct a MeshServer object
1822 -var CreateAmtRemoteTerminal = function (divid) {
1823 - var obj = {};
1824 - obj.DivId = divid;
1825 - obj.DivElement = document.getElementById(divid);
1826 - obj.protocol = 1; // SOL
1827 - obj.fxEmulation = 0;
1828 - obj.lineFeed = '\r\n';
1829 - obj.debugmode = 0;
1830 -
1831 - obj.width = 80; // 80 or 100
1832 - obj.height = 25; // 25 or 30
1833 -
1834 - var _Terminal_CellHeight = 21;
1835 - var _Terminal_CellWidth = 13;
1836 - var _TermColors = ['000000', 'BB0000', '00BB00', 'BBBB00', '0000BB', 'BB00BB', '00BBBB', 'BBBBBB', '555555', 'FF5555', '55FF55', 'FFFF55', '5555FF', 'FF55FF', '55FFFF', 'FFFFFF'];
1837 - var _TermCurrentReverse = 0;
1838 - var _TermCurrentFColor = 7;
1839 - var _TermCurrentBColor = 0;
1840 - var _TermLineWrap = true;
1841 - var _termx = 0;
1842 - var _termy = 0;
1843 - var _termstate = 0;
1844 - var _escNumber = [];
1845 - var _escNumberPtr = 0;
1846 - var _scratt = [];
1847 - var _tscreen = [];
1848 - var _VTUNDERLINE = 1;
1849 - var _VTREVERSE = 2;
1850 -
1851 - obj.Start = function () { }
1852 -
1853 - obj.Init = function (width, height) {
1854 - obj.width = width ? width : 80;
1855 - obj.height = height ? height : 25;
1856 - for (var y = 0; y < obj.height; y++) {
1857 - _tscreen[y] = [];
1858 - _scratt[y] = [];
1859 - for (var x = 0; x < obj.width; x++) { _tscreen[y][x] = ' '; _scratt[y][x] = (7 << 6); }
1860 - }
1861 - obj.TermInit();
1862 - obj.TermDraw();
1863 - }
1864 -
1865 - obj.xxStateChange = function(newstate) { }
1866 -
1867 - obj.ProcessData = function (str) {
1868 - if (obj.debugmode == 2) { console.log("TRecv(" + str.length + "): " + rstr2hex(str)); }
1869 - if (obj.capture != null) obj.capture += str; _ProcessVt100EscString(str); obj.TermDraw();
1870 - }
1871 -
1872 - function _ProcessVt100EscString(str) { for (var i = 0; i < str.length; i++) _ProcessVt100EscChar(String.fromCharCode(str.charCodeAt(i)), str.charCodeAt(i)); }
1873 -
1874 - function _ProcessVt100EscChar(b, c) {
1875 - switch (_termstate) {
1876 - case 0: // Normal Term State
1877 - switch (c) {
1878 - case 27: // ESC
1879 - _termstate = 1;
1880 - break;
1881 - default:
1882 - // Process a single char
1883 - _ProcessVt100Char(b);
1884 - break;
1885 - }
1886 - break;
1887 - case 1:
1888 - switch (b) {
1889 - case '[':
1890 - _escNumberPtr = 0;
1891 - _escNumber = [];
1892 - _termstate = 2;
1893 - break;
1894 - case '(':
1895 - _termstate = 4;
1896 - break;
1897 - case ')':
1898 - _termstate = 5;
1899 - break;
1900 - default:
1901 - _termstate = 0;
1902 - break;
1903 - }
1904 - break;
1905 - case 2:
1906 - if (b >= '0' && b <= '9') {
1907 - // This is a number
1908 - if (!_escNumber[_escNumberPtr]) {
1909 - _escNumber[_escNumberPtr] = (b - '0');
1910 - }
1911 - else {
1912 - _escNumber[_escNumberPtr] = ((_escNumber[_escNumberPtr] * 10) + (b - '0'));
1913 - }
1914 - break;
1915 - }
1916 - else if (b == ';') {
1917 - // New number
1918 - _escNumberPtr++;
1919 - break;
1920 - }
1921 - else {
1922 - // Process Escape Sequence
1923 - if (!_escNumber[0]) _escNumber[0] = 0;
1924 - _ProcessEscapeHandler(b, _escNumber, _escNumberPtr + 1);
1925 - _termstate = 0;
1926 - }
1927 - break;
1928 - case 4: // '(' Code
1929 - _termstate = 0;
1930 - break;
1931 - case 5: // ')' Code
1932 - _termstate = 0;
1933 - break;
1934 - }
1935 - }
1936 -
1937 - function _ProcessEscapeHandler(code, args, argslen) {
1938 - var i;
1939 - switch (code) {
1940 - case 'c': // ResetDevice
1941 - // Reset
1942 - obj.TermResetScreen();
1943 - break;
1944 - case 'A': // Move cursor up n lines
1945 - if (argslen == 1) {
1946 - _termy -= args[0];
1947 - if (_termy < 0) _termy = 0;
1948 - }
1949 - break;
1950 - case 'B': // Move cursor down n lines
1951 - if (argslen == 1) {
1952 - _termy += args[0];
1953 - if (_termy > obj.height) _termy = obj.height;
1954 - }
1955 - break;
1956 - case 'C': // Move cursor right n lines
1957 - if (argslen == 1) {
1958 - _termx += args[0];
1959 - if (_termx > obj.width) _termx = obj.width;
1960 - }
1961 - break;
1962 - case 'D': // Move cursor left n lines
1963 - if (argslen == 1) {
1964 - _termx -= args[0];
1965 - if (_termx < 0) _termx = 0;
1966 - }
1967 - break;
1968 - case 'd': // Set cursor to line n
1969 - if (argslen == 1) {
1970 - _termy = args[0] - 1;
1971 - if (_termy > obj.height) _termy = obj.height;
1972 - if (_termy < 0) _termy = 0;
1973 - }
1974 - break;
1975 - case 'G': // Set cursor to col n
1976 - if (argslen == 1) {
1977 - _termx = args[0] - 1;
1978 - if (_termx < 0) _termx = 0;
1979 - if (_termx > 79) _termx = 79;
1980 - }
1981 - break;
1982 - case 'J': // ClearScreen:
1983 - if (argslen == 1 && args[0] == 2) {
1984 - obj.TermClear((_TermCurrentBColor << 12) + (_TermCurrentFColor << 6)); // Erase entire screen
1985 - _termx = 0;
1986 - _termy = 0;
1987 - }
1988 - else if (argslen == 0 || argslen == 1 && args[0] == 0) // Erase cursor down
1989 - {
1990 - _EraseCursorToEol();
1991 - for (i = _termy + 1; i < obj.height; i++) _EraseLine(i);
1992 - }
1993 - else if (argslen == 1 && args[0] == 1) // Erase cursor up
1994 - {
1995 - _EraseCursorToEol();
1996 - for (i = 0; i < _termy - 1; i++) _EraseLine(i);
1997 - }
1998 - break;
1999 - case 'H': // MoveCursor:
2000 - if (argslen == 2) {
2001 - if (args[0] < 1) args[0] = 1;
2002 - if (args[1] < 1) args[1] = 1;
2003 - if (args[0] > obj.height) args[0] = obj.height;
2004 - if (args[1] > obj.width) args[1] = obj.width;
2005 - _termy = args[0] - 1;
2006 - _termx = args[1] - 1;
2007 - }
2008 - else {
2009 - _termy = 0;
2010 - _termx = 0;
2011 - }
2012 - break;
2013 - case 'm': // ScreenAttribs:
2014 - // Change attributes
2015 - for (i = 0; i < argslen; i++) {
2016 - if (!args[i] || args[i] == 0) {
2017 - // Reset Attributes
2018 - _TermCurrentBColor = 0;
2019 - _TermCurrentFColor = 7;
2020 - _TermCurrentReverse = 0;
2021 - }
2022 - else if (args[i] == 1) {
2023 - // Bright
2024 - if (_TermCurrentFColor < 8) _TermCurrentFColor += 8;
2025 - }
2026 - else if (args[i] == 2 || args[i] == 22) {
2027 - // Dim
2028 - if (_TermCurrentFColor >= 8) _TermCurrentFColor -= 8;
2029 - }
2030 - else if (args[i] == 7) {
2031 - // Set Reverse attribute true
2032 - _TermCurrentReverse = 2;
2033 - }
2034 - else if (args[i] == 27) {
2035 - // Set Reverse attribute false
2036 - _TermCurrentReverse = 0;
2037 - }
2038 - else if (args[i] >= 30 && args[i] <= 37) {
2039 - // Set Foreground Color
2040 - var bright = (_TermCurrentFColor >= 8);
2041 - _TermCurrentFColor = (args[i] - 30);
2042 - if (bright && _TermCurrentFColor <= 8) _TermCurrentFColor += 8;
2043 - }
2044 - else if (args[i] >= 40 && args[i] <= 47) {
2045 - // Set Background Color
2046 - _TermCurrentBColor = (args[i] - 40);
2047 - }
2048 - else if (args[i] >= 90 && args[i] <= 99) {
2049 - // Set Bright Foreground Color
2050 - _TermCurrentFColor = (args[i] - 82);
2051 - }
2052 - else if (args[i] >= 100 && args[i] <= 109) {
2053 - // Set Bright Background Color
2054 - _TermCurrentBColor = (args[i] - 92);
2055 - }
2056 - }
2057 - break;
2058 - case 'K': // EraseLine:
2059 - if (argslen == 0 || (argslen == 1 && (!args[0] || args[0] == 0))) {
2060 - _EraseCursorToEol(); // Erase from the cursor to the end of the line
2061 - }
2062 - else if (argslen == 1) {
2063 - if (args[0] == 1) // Erase from the beginning of the line to the cursor
2064 - {
2065 - _EraseBolToCursor();
2066 - }
2067 - else if (args[0] == 2) // Erase the line with the cursor
2068 - {
2069 - _EraseLine(_termy);
2070 - }
2071 - }
2072 - break;
2073 - case 'h': // EnableLineWrap:
2074 - _TermLineWrap = true;
2075 - break;
2076 - case 'l': // DisableLineWrap:
2077 - _TermLineWrap = false;
2078 - break;
2079 - default:
2080 - //if (code != '@') alert(code);
2081 - break;
2082 - }
2083 - }
2084 -
2085 - obj.ProcessVt100String = function (str) {
2086 - for (var i = 0; i < str.length; i++) _ProcessVt100Char(String.fromCharCode(str.charCodeAt(i)));
2087 - }
2088 -
2089 -
2090 -
2091 -
2092 - function _ProcessVt100Char(c) {
2093 - if (c == '\0' || c.charCodeAt() == 7) return; // Ignore null & bell
2094 - var ch = c.charCodeAt();
2095 -
2096 -
2097 -
2098 -
2099 - //if (ch < 32 && ch != 10 && ch != 13) alert(ch);
2100 - switch (ch) {
2101 - case 16: { c = ' '; break; } // This is an odd char that show up on Intel BIOS's.
2102 - case 24: { c = '↑'; break; }
2103 - case 25: { c = '↓'; break; }
2104 - }
2105 -
2106 - if (_termx > obj.width) _termx = obj.width;
2107 - if (_termy > (obj.height - 1)) _termy = (obj.height - 1);
2108 -
2109 - switch (c) {
2110 - case '\b': // Backspace
2111 - if (_termx > 0) {
2112 - _termx = _termx - 1;
2113 - _TermDrawChar(' ');
2114 - }
2115 - break;
2116 - case '\t': // tab
2117 - var tab = 8 - (_termx % 8)
2118 - for (var x = 0; x < tab; x++) _ProcessVt100Char(" ");
2119 - break;
2120 - case '\n': // Linefeed
2121 - _termy++;
2122 - if (_termy > (obj.height - 1)) {
2123 - // Move everything up one line
2124 - _TermMoveUp(1);
2125 - _termy = (obj.height - 1);
2126 - }
2127 - if (obj.lineFeed = '\n') { _termx = 0; } // *** If we are in Linux mode, \n will also return the cursor to the first col
2128 - break;
2129 - case '\r': // Carriage Return
2130 - _termx = 0;
2131 - break;
2132 - default:
2133 - if (_termx >= obj.width) {
2134 - _termx = 0;
2135 - if (_TermLineWrap) { _termy++; }
2136 - if (_termy >= (obj.height - 1)) { _TermMoveUp(1); _termy = (obj.height - 1); }
2137 - }
2138 - _TermDrawChar(c);
2139 - _termx++;
2140 - break;
2141 - }
2142 -
2143 - }
2144 -
2145 - function _TermDrawChar(c) {
2146 - _tscreen[_termy][_termx] = c;
2147 - _scratt[_termy][_termx] = (_TermCurrentFColor << 6) + (_TermCurrentBColor << 12) + _TermCurrentReverse;
2148 - }
2149 -
2150 - obj.TermClear = function(TermColor) {
2151 - for (var y = 0; y < obj.height; y++) {
2152 - for (var x = 0; x < obj.width; x++) {
2153 - _tscreen[y][x] = ' ';
2154 - _scratt[y][x] = TermColor;
2155 - }
2156 - }
2157 - }
2158 -
2159 - obj.TermResetScreen = function () {
2160 - _TermCurrentReverse = 0;
2161 - _TermCurrentFColor = 7;
2162 - _TermCurrentBColor = 0;
2163 - _TermLineWrap = true;
2164 - _termx = 0;
2165 - _termy = 0;
2166 - obj.TermClear(7 << 6);
2167 - }
2168 -
2169 - function _EraseCursorToEol() {
2170 - var t = (_TermCurrentBColor << 12);
2171 - for (var x = _termx; x < obj.width; x++) {
2172 - _tscreen[_termy][x] = ' ';
2173 - _scratt[_termy][x] = t;
2174 - }
2175 - }
2176 -
2177 - function _EraseBolToCursor() {
2178 - var t = (_TermCurrentBColor << 12);
2179 - for (var x = 0; x < _termx; x++) {
2180 - _tscreen[_termy][x] = ' ';
2181 - _scratt[_termy][x] = t;
2182 - }
2183 - }
2184 -
2185 - function _EraseLine(line) {
2186 - var t = (_TermCurrentBColor << 12);
2187 - for (var x = 0; x < obj.width; x++) {
2188 - _tscreen[line][x] = ' ';
2189 - _scratt[line][x] = t;
2190 - }
2191 - }
2192 -
2193 - obj.TermSendKeys = function (keys) { if (obj.debugmode == 2) { if (obj.debugmode == 2) { console.log("TSend(" + keys.length + "): " + rstr2hex(keys)); } } obj.parent.send(keys); }
2194 - obj.TermSendKey = function (key) { if (obj.debugmode == 2) { if (obj.debugmode == 2) { console.log("TSend(1): " + rstr2hex(String.fromCharCode(key))); } } obj.parent.send(String.fromCharCode(key)); }
2195 -
2196 - function _TermMoveUp(linecount) {
2197 - var x, y;
2198 - for (y = 0; y < obj.height - linecount; y++) {
2199 - _tscreen[y] = _tscreen[y + linecount];
2200 - _scratt[y] = _scratt[y + linecount];
2201 - }
2202 - for (y = obj.height - linecount; y < obj.height; y++) {
2203 - _tscreen[y] = [];
2204 - _scratt[y] = [];
2205 - for (x = 0; x < obj.width; x++) {
2206 - _tscreen[y][x] = ' ';
2207 - _scratt[y][x] = (7 << 6);
2208 - }
2209 - }
2210 - }
2211 -
2212 - obj.TermHandleKeys = function (e) {
2213 - if (!e.ctrlKey) {
2214 - if (e.which == 127) obj.TermSendKey(8);
2215 - else if (e.which == 13) obj.TermSendKeys(obj.lineFeed);
2216 - else if (e.which != 0) obj.TermSendKey(e.which);
2217 - return false;
2218 - }
2219 - if (e.preventDefault) e.preventDefault();
2220 - if (e.stopPropagation) e.stopPropagation();
2221 - }
2222 -
2223 - obj.TermHandleKeyUp = function (e) {
2224 - if ((e.which != 8) && (e.which != 32) && (e.which != 9)) return true;
2225 - if (e.preventDefault) e.preventDefault();
2226 - if (e.stopPropagation) e.stopPropagation();
2227 - return false;
2228 - }
2229 -
2230 - obj.TermHandleKeyDown = function (e) {
2231 - if ((e.which >= 65) && (e.which <= 90) && (e.ctrlKey == true)) {
2232 - obj.TermSendKey(e.which - 64);
2233 - if (e.preventDefault) e.preventDefault();
2234 - if (e.stopPropagation) e.stopPropagation();
2235 - return;
2236 - }
2237 - if (e.which == 27) { obj.TermSendKeys(String.fromCharCode(27)); return true; }; // ESC
2238 - if (e.which == 37) { obj.TermSendKeys(String.fromCharCode(27, 91, 68)); return true; }; // Left
2239 - if (e.which == 38) { obj.TermSendKeys(String.fromCharCode(27, 91, 65)); return true; }; // Up
2240 - if (e.which == 39) { obj.TermSendKeys(String.fromCharCode(27, 91, 67)); return true; }; // Right
2241 - if (e.which == 40) { obj.TermSendKeys(String.fromCharCode(27, 91, 66)); return true; }; // Down
2242 - if (e.which == 9) { obj.TermSendKeys("\t"); if (e.preventDefault) e.preventDefault(); if (e.stopPropagation) e.stopPropagation(); return true; }; // TAB
2243 -
2244 - // F1 to F12 keys
2245 -
2246 - if (e.which != 8 && e.which != 32 && e.which != 9) return true;
2247 - obj.TermSendKey(e.which);
2248 - if (e.preventDefault) e.preventDefault();
2249 - if (e.stopPropagation) e.stopPropagation();
2250 - return false;
2251 - }
2252 -
2253 - obj.TermDraw = function() {
2254 - var c, buf = '', closetag = '', newat, oldat = 1, x1, x2;
2255 - for (var y = 0; y < obj.height; ++y) {
2256 - for (var x = 0; x < obj.width; ++x) {
2257 - newat = _scratt[y][x];
2258 - if (_termx == x && _termy == y) { newat |= _VTREVERSE; } // If this is the cursor location, reverse the color.
2259 - if (newat != oldat) {
2260 - buf += closetag;
2261 - closetag = '';
2262 - x1 = 6; x2 = 12;
2263 - if (newat & _VTREVERSE) { x1 = 12; x2 = 6;}
2264 - buf += '<span style="color:#' + _TermColors[(newat >> x1) & 0x3F] + ';background-color:#' + _TermColors[(newat >> x2) & 0x3F];
2265 - if (newat & _VTUNDERLINE) buf += ';text-decoration:underline';
2266 - buf += ';">';
2267 - closetag = "</span>" + closetag;
2268 - oldat = newat;
2269 - }
2270 -
2271 - c = _tscreen[y][x];
2272 - switch (c) {
2273 - case '&':
2274 - buf += '&amp;'; break;
2275 - case '<':
2276 - buf += '&lt;'; break;
2277 - case '>':
2278 - buf += '&gt;'; break;
2279 - case ' ':
2280 - buf += '&nbsp;'; break;
2281 - default:
2282 - buf += c;
2283 - break;
2284 - }
2285 - }
2286 - if (y != (obj.height - 1)) buf += '<br>';
2287 - }
2288 - obj.DivElement.innerHTML = "<font size='4'><b>" + buf + closetag + "</b></font>";
2289 - }
2290 -
2291 - obj.TermInit = function () { obj.TermResetScreen(); }
2292 -
2293 - obj.Init();
2294 - return obj;
2295 -}/* zlib.js -- JavaScript implementation for the zlib.
2296 - Version: 0.2.0
2297 - LastModified: Apr 12 2012
2298 - Copyright (C) 2012 Masanao Izumo <iz@onicos.co.jp>
2299 -
2300 - The original copyright notice (zlib 1.2.6):
2301 -
2302 - Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler
2303 -
2304 - This software is provided 'as-is', without any express or implied
2305 - warranty. In no event will the authors be held liable for any damages
2306 - arising from the use of this software.
2307 -
2308 - Permission is granted to anyone to use this software for any purpose,
2309 - including commercial applications, and to alter it and redistribute it
2310 - freely, subject to the following restrictions:
2311 -
2312 - 1. The origin of this software must not be misrepresented; you must not
2313 - claim that you wrote the original software. If you use this software
2314 - in a product, an acknowledgment in the product documentation would be
2315 - appreciated but is not required.
2316 - 2. Altered source versions must be plainly marked as such, and must not be
2317 - misrepresented as being the original software.
2318 - 3. This notice may not be removed or altered from any source distribution.
2319 -
2320 - Jean-loup Gailly Mark Adler
2321 - jloup@gzip.org madler@alumni.caltech.edu
2322 -
2323 -
2324 - The data format used by the zlib library is described by RFCs (Request for
2325 - Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
2326 - (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
2327 -*/
2328 -
2329 -var ZLIB = ( ZLIB || {} ); // ZLIB namespace initialization
2330 -
2331 -// common definitions
2332 -if(typeof ZLIB.common_initialized === 'undefined') {
2333 - ZLIB.Z_NO_FLUSH = 0;
2334 - ZLIB.Z_PARTIAL_FLUSH = 1;
2335 - ZLIB.Z_SYNC_FLUSH = 2;
2336 - ZLIB.Z_FULL_FLUSH = 3;
2337 - ZLIB.Z_FINISH = 4;
2338 - ZLIB.Z_BLOCK = 5;
2339 - ZLIB.Z_TREES = 6;
2340 - /* Allowed flush values; see deflate() and inflate() below for details */
2341 -
2342 - ZLIB.Z_OK = 0;
2343 - ZLIB.Z_STREAM_END = 1;
2344 - ZLIB.Z_NEED_DICT = 2;
2345 - ZLIB.Z_ERRNO = (-1);
2346 - ZLIB.Z_STREAM_ERROR = (-2);
2347 - ZLIB.Z_DATA_ERROR = (-3);
2348 - ZLIB.Z_MEM_ERROR = (-4);
2349 - ZLIB.Z_BUF_ERROR = (-5);
2350 - ZLIB.Z_VERSION_ERROR = (-6);
2351 - /* Return codes for the compression/decompression functions. Negative values
2352 - * are errors, positive values are used for special but normal events.
2353 - */
2354 -
2355 - ZLIB.Z_DEFLATED = 8; /* The deflate compression method (the only one supported in this version) */
2356 -
2357 - /**
2358 - * z_stream constructor
2359 - * @constructor
2360 - */
2361 - ZLIB.z_stream = function() {
2362 - this.next_in = 0; /* next input byte */
2363 - this.avail_in = 0; /* number of bytes available in input_data */
2364 - this.total_in = 0; /* total number of input bytes read so far */
2365 -
2366 - this.next_out = 0; /* next output byte */
2367 - this.avail_out = 0; /* remaining free space at next_out */
2368 - this.total_out = 0; /* total number of bytes output so far */
2369 -
2370 - this.msg = null; /* last error message, null if no error */
2371 - this.state = null; /* not visible by applications */
2372 -
2373 - this.data_type = 0; /* best guess about the data type: binary or text */
2374 - this.adler = 0; /* TODO: adler32 value of the uncompressed data */
2375 -
2376 - // zlib.js
2377 - this.input_data = ''; /* input data */
2378 - this.output_data = ''; /* output data */
2379 - this.error = 0; /* error code */
2380 - this.checksum_function = null; /* crc32(for gzip) or adler32(for zlib) */
2381 - };
2382 -
2383 - /**
2384 - * TODO
2385 - * @constructor
2386 - */
2387 - ZLIB.gz_header = function() {
2388 - this.text = 0; /* true if compressed data believed to be text */
2389 - this.time = 0; /* modification time */
2390 - this.xflags = 0; /* extra flags (not used when writing a gzip file) */
2391 - this.os = 0xff; /* operating system */
2392 - this.extra = null; /* extra field string or null if none */
2393 - this.extra_len = 0; /* this.extra.length (only when reading header) */
2394 - this.extra_max = 0; /* space at extra (only when reading header) */
2395 - this.name = null; /* file name string or null if none */
2396 - this.name_max = 0; /* space at name (only when reading header) */
2397 - this.comment = null; /* comment string or null if none */
2398 - this.comm_max = 0; /* space at comment (only when reading header) */
2399 - this.hcrc = 0; /* true if there was or will be a header crc */
2400 - this.done = 0; /* true when done reading gzip header (not used
2401 - when writing a gzip file) */
2402 - };
2403 -
2404 - ZLIB.common_initialized = true;
2405 -} // common definitions
2406 -/* zlib-inflate.js -- JavaScript implementation for the zlib inflate.
2407 - Version: 0.2.0
2408 - LastModified: Apr 12 2012
2409 - Copyright (C) 2012 Masanao Izumo <iz@onicos.co.jp>
2410 -
2411 - This library is one of the JavaScript zlib implementation.
2412 - Some API's are modified from the original.
2413 - Only inflate API is implemented.
2414 -
2415 - The original copyright notice (zlib 1.2.6):
2416 -
2417 - Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler
2418 -
2419 - This software is provided 'as-is', without any express or implied
2420 - warranty. In no event will the authors be held liable for any damages
2421 - arising from the use of this software.
2422 -
2423 - Permission is granted to anyone to use this software for any purpose,
2424 - including commercial applications, and to alter it and redistribute it
2425 - freely, subject to the following restrictions:
2426 -
2427 - 1. The origin of this software must not be misrepresented; you must not
2428 - claim that you wrote the original software. If you use this software
2429 - in a product, an acknowledgment in the product documentation would be
2430 - appreciated but is not required.
2431 - 2. Altered source versions must be plainly marked as such, and must not be
2432 - misrepresented as being the original software.
2433 - 3. This notice may not be removed or altered from any source distribution.
2434 -
2435 - Jean-loup Gailly Mark Adler
2436 - jloup@gzip.org madler@alumni.caltech.edu
2437 -
2438 -
2439 - The data format used by the zlib library is described by RFCs (Request for
2440 - Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
2441 - (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
2442 -*/
2443 -
2444 -/*
2445 - API documentation
2446 -==============================================================================
2447 -Usage: z_stream = ZLIB.inflateInit([windowBits]);
2448 -
2449 - Create the stream object for decompression.
2450 - See zlib.h for windowBits information.
2451 -
2452 -==============================================================================
2453 -Usage: decoded_string = z_stream.inflate(encoded_string [, {OPTIONS...}]);
2454 -
2455 -OPTIONS:
2456 - next_in: decode start offset for encoded_string.
2457 -
2458 - avail_in: // TODO document. See zlib.h for the information.
2459 -
2460 - avail_out: // TODO document. See zlib.h for the information.
2461 -
2462 - flush: // TODO document. See zlib.h for the information.
2463 -
2464 -Ex: decoded_string = z_stream.inflate(encoded_string);
2465 - decoded_string = z_stream.inflate(encoded_string,
2466 - {next_in: 0,
2467 - avail_in: encoded_string.length,
2468 - avail_out: 1024,
2469 - flush: ZLIB.Z_NO_FLUSH});
2470 -
2471 - See zlib.h for more information.
2472 -
2473 -==============================================================================
2474 -Usage: z_stream.inflateReset();
2475 - TODO document
2476 -
2477 -*/
2478 -
2479 -if( typeof ZLIB === 'undefined' ) {
2480 - alert('ZLIB is not defined. SRC zlib.js before zlib-inflate.js')
2481 -}
2482 -
2483 -(function() {
2484 -
2485 -/* inflate.c -- zlib decompression
2486 - * Copyright (C) 1995-2011 Mark Adler
2487 - * For conditions of distribution and use, see copyright notice in zlib.h
2488 - */
2489 -
2490 -var DEF_WBITS = 15;
2491 -
2492 -// inflate_mode
2493 -var HEAD = 0; /* i: waiting for magic header */
2494 -var FLAGS = 1; /* i: waiting for method and flags (gzip) */
2495 -var TIME = 2; /* i: waiting for modification time (gzip) */
2496 -var OS = 3; /* i: waiting for extra flags and operating system (gzip) */
2497 -var EXLEN = 4; /* i: waiting for extra length (gzip) */
2498 -var EXTRA = 5; /* i: waiting for extra bytes (gzip) */
2499 -var NAME = 6; /* i: waiting for end of file name (gzip) */
2500 -var COMMENT = 7; /* i: waiting for end of comment (gzip) */
2501 -var HCRC = 8; /* i: waiting for header crc (gzip) */
2502 -var DICTID = 9; /* i: waiting for dictionary check value */
2503 -var DICT = 10; /* waiting for inflateSetDictionary() call */
2504 -var TYPE = 11; /* i: waiting for type bits, including last-flag bit */
2505 -var TYPEDO = 12; /* i: same, but skip check to exit inflate on new block */
2506 -var STORED = 13; /* i: waiting for stored size (length and complement) */
2507 -var COPY_ = 14; /* i/o: same as COPY below, but only first time in */
2508 -var COPY = 15; /* i/o: waiting for input or output to copy stored block */
2509 -var TABLE = 16; /* i: waiting for dynamic block table lengths */
2510 -var LENLENS = 17; /* i: waiting for code length code lengths */
2511 -var CODELENS = 18; /* i: waiting for length/lit and distance code lengths */
2512 -var LEN_ = 19; /* i: same as LEN below, but only first time in */
2513 -var LEN = 20; /* i: waiting for length/lit/eob code */
2514 -var LENEXT = 21; /* i: waiting for length extra bits */
2515 -var DIST = 22; /* i: waiting for distance code */
2516 -var DISTEXT = 23; /* i: waiting for distance extra bits */
2517 -var MATCH = 24; /* o: waiting for output space to copy string */
2518 -var LIT = 25; /* o: waiting for output space to write literal */
2519 -var CHECK = 26; /* i: waiting for 32-bit check value */
2520 -var LENGTH = 27; /* i: waiting for 32-bit length (gzip) */
2521 -var DONE = 28; /* finished check, done -- remain here until reset */
2522 -var BAD = 29; /* got a data error -- remain here until reset */
2523 -var MEM = 30; /* got an inflate() memory error -- remain here until reset */
2524 -var SYNC = 31; /* looking for synchronization bytes to restart inflate() */
2525 -
2526 -/* Maximum size of the dynamic table. The maximum number of code structures is
2527 - 1444, which is the sum of 852 for literal/length codes and 592 for distance
2528 - codes. These values were found by exhaustive searches using the program
2529 - examples/enough.c found in the zlib distribtution. The arguments to that
2530 - program are the number of symbols, the initial root table size, and the
2531 - maximum bit length of a code. "enough 286 9 15" for literal/length codes
2532 - returns returns 852, and "enough 30 6 15" for distance codes returns 592.
2533 - The initial root table size (9 or 6) is found in the fifth argument of the
2534 - inflate_table() calls in inflate.c and infback.c. If the root table size is
2535 - changed, then these maximum sizes would be need to be recalculated and
2536 - updated. */
2537 -var ENOUGH_LENS = 852;
2538 -var ENOUGH_DISTS = 592;
2539 -var ENOUGH = (ENOUGH_LENS + ENOUGH_DISTS);
2540 -
2541 -/* Type of code to build for inflate_table() */
2542 -var CODES = 0;
2543 -var LENS = 1;
2544 -var DISTS = 2;
2545 -
2546 -
2547 -
2548 -var inflate_table_lbase = [ /* Length codes 257..285 base */
2549 - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
2550 - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0];
2551 -var inflate_table_lext = [ /* Length codes 257..285 extra */
2552 - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
2553 - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 203, 69];
2554 -var inflate_table_dbase = [ /* Distance codes 0..29 base */
2555 - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
2556 - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
2557 - 8193, 12289, 16385, 24577, 0, 0];
2558 -var inflate_table_dext = [ /* Distance codes 0..29 extra */
2559 - 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
2560 - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
2561 - 28, 28, 29, 29, 64, 64];
2562 -
2563 -/* inftrees.c -- generate Huffman trees for efficient decoding
2564 - * Copyright (C) 1995-2012 Mark Adler
2565 - * For conditions of distribution and use, see copyright notice in zlib.h
2566 - */
2567 -
2568 -ZLIB.inflate_copyright =
2569 - ' inflate 1.2.6 Copyright 1995-2012 Mark Adler ';
2570 -/*
2571 - If you use the zlib library in a product, an acknowledgment is welcome
2572 - in the documentation of your product. If for some reason you cannot
2573 - include such an acknowledgment, I would appreciate that you keep this
2574 - copyright string in the executable of your product.
2575 - */
2576 -
2577 -/*
2578 - Build a set of tables to decode the provided canonical Huffman code.
2579 - The code lengths are lens[0..codes-1]. The result starts at *table,
2580 - whose indices are 0..2^bits-1. work is a writable array of at least
2581 - lens shorts, which is used as a work area. type is the type of code
2582 - to be generated, CODES, LENS, or DISTS. On return, zero is success,
2583 - -1 is an invalid code, and +1 means that ENOUGH isn't enough. table
2584 - on return points to the next available entry's address. bits is the
2585 - requested root table index bits, and on return it is the actual root
2586 - table index bits. It will differ if the request is greater than the
2587 - longest code or if it is less than the shortest code.
2588 -*/
2589 -function inflate_table(state, type)
2590 -{
2591 - var MAXBITS = 15;
2592 - var table = state.next;
2593 - var bits = (type == DISTS ? state.distbits : state.lenbits);
2594 - var work = state.work;
2595 - var lens = state.lens;
2596 - var lens_offset = (type == DISTS ? state.nlen : 0);
2597 - var state_codes = state.codes;
2598 - var codes;
2599 - if(type == LENS)
2600 - codes = state.nlen;
2601 - else if(type == DISTS)
2602 - codes = state.ndist;
2603 - else // CODES
2604 - codes = 19;
2605 -
2606 - var len; /* a code's length in bits */
2607 - var sym; /* index of code symbols */
2608 - var min, max; /* minimum and maximum code lengths */
2609 - var root; /* number of index bits for root table */
2610 - var curr; /* number of index bits for current table */
2611 - var drop; /* code bits to drop for sub-table */
2612 - var left; /* number of prefix codes available */
2613 - var used; /* code entries in table used */
2614 - var huff; /* Huffman code */
2615 - var incr; /* for incrementing code, index */
2616 - var fill; /* index for replicating entries */
2617 - var low; /* low bits for current root entry */
2618 - var mask; /* mask for low root bits */
2619 - var here; /* table entry for duplication */
2620 - var next; /* next available space in table */
2621 - var base; /* base value table to use */
2622 - var base_offset;
2623 - var extra; /* extra bits table to use */
2624 - var extra_offset;
2625 - var end; /* use base and extra for symbol > end */
2626 - var count = new Array(MAXBITS+1); /* number of codes of each length */
2627 - var offs = new Array(MAXBITS+1); /* offsets in table for each length */
2628 -
2629 - /*
2630 - Process a set of code lengths to create a canonical Huffman code. The
2631 - code lengths are lens[0..codes-1]. Each length corresponds to the
2632 - symbols 0..codes-1. The Huffman code is generated by first sorting the
2633 - symbols by length from short to long, and retaining the symbol order
2634 - for codes with equal lengths. Then the code starts with all zero bits
2635 - for the first code of the shortest length, and the codes are integer
2636 - increments for the same length, and zeros are appended as the length
2637 - increases. For the deflate format, these bits are stored backwards
2638 - from their more natural integer increment ordering, and so when the
2639 - decoding tables are built in the large loop below, the integer codes
2640 - are incremented backwards.
2641 -
2642 - This routine assumes, but does not check, that all of the entries in
2643 - lens[] are in the range 0..MAXBITS. The caller must assure this.
2644 - 1..MAXBITS is interpreted as that code length. zero means that that
2645 - symbol does not occur in this code.
2646 -
2647 - The codes are sorted by computing a count of codes for each length,
2648 - creating from that a table of starting indices for each length in the
2649 - sorted table, and then entering the symbols in order in the sorted
2650 - table. The sorted table is work[], with that space being provided by
2651 - the caller.
2652 -
2653 - The length counts are used for other purposes as well, i.e. finding
2654 - the minimum and maximum length codes, determining if there are any
2655 - codes at all, checking for a valid set of lengths, and looking ahead
2656 - at length counts to determine sub-table sizes when building the
2657 - decoding tables.
2658 - */
2659 -
2660 - /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
2661 - for (len = 0; len <= MAXBITS; len++)
2662 - count[len] = 0;
2663 - for (sym = 0; sym < codes; sym++)
2664 - count[lens[lens_offset + sym]]++;
2665 -
2666 - /* bound code lengths, force root to be within code lengths */
2667 - root = bits;
2668 -
2669 - for (max = MAXBITS; max >= 1; max--)
2670 - if (count[max] != 0) break;
2671 - if (root > max) root = max;
2672 - if (max == 0) {
2673 - /* no symbols to code at all */
2674 - /* invalid code marker */
2675 - here = {op:64, bits:1, val:0};
2676 - state_codes[table++] = here; /* make a table to force an error */
2677 - state_codes[table++] = here;
2678 - if(type == DISTS) state.distbits = 1; else state.lenbits = 1; // *bits = 1;
2679 - state.next = table;
2680 - return 0; /* no symbols, but wait for decoding to report error */
2681 - }
2682 - for (min = 1; min < max; min++)
2683 - if (count[min] != 0) break;
2684 - if (root < min) root = min;
2685 -
2686 - /* check for an over-subscribed or incomplete set of lengths */
2687 - left = 1;
2688 - for (len = 1; len <= MAXBITS; len++) {
2689 - left <<= 1;
2690 - left -= count[len];
2691 - if (left < 0) return -1; /* over-subscribed */
2692 - }
2693 - if (left > 0 && (type == CODES || max != 1)) {
2694 - state.next = table;
2695 - return -1; /* incomplete set */
2696 - }
2697 -
2698 - /* generate offsets into symbol table for each length for sorting */
2699 - offs[1] = 0;
2700 - for (len = 1; len < MAXBITS; len++)
2701 - offs[len + 1] = offs[len] + count[len];
2702 -
2703 - /* sort symbols by length, by symbol order within each length */
2704 - for (sym = 0; sym < codes; sym++)
2705 - if (lens[lens_offset + sym] != 0) work[offs[lens[lens_offset + sym]]++] = sym;
2706 -
2707 - /*
2708 - Create and fill in decoding tables. In this loop, the table being
2709 - filled is at next and has curr index bits. The code being used is huff
2710 - with length len. That code is converted to an index by dropping drop
2711 - bits off of the bottom. For codes where len is less than drop + curr,
2712 - those top drop + curr - len bits are incremented through all values to
2713 - fill the table with replicated entries.
2714 -
2715 - root is the number of index bits for the root table. When len exceeds
2716 - root, sub-tables are created pointed to by the root entry with an index
2717 - of the low root bits of huff. This is saved in low to check for when a
2718 - new sub-table should be started. drop is zero when the root table is
2719 - being filled, and drop is root when sub-tables are being filled.
2720 -
2721 - When a new sub-table is needed, it is necessary to look ahead in the
2722 - code lengths to determine what size sub-table is needed. The length
2723 - counts are used for this, and so count[] is decremented as codes are
2724 - entered in the tables.
2725 -
2726 - used keeps track of how many table entries have been allocated from the
2727 - provided *table space. It is checked for LENS and DIST tables against
2728 - the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
2729 - the initial root table size constants. See the comments in inftrees.h
2730 - for more information.
2731 -
2732 - sym increments through all symbols, and the loop terminates when
2733 - all codes of length max, i.e. all codes, have been processed. This
2734 - routine permits incomplete codes, so another loop after this one fills
2735 - in the rest of the decoding tables with invalid code markers.
2736 - */
2737 -
2738 - /* set up for code type */
2739 - switch (type) {
2740 - case CODES:
2741 - base = extra = work; /* dummy value--not used */
2742 - base_offset = 0;
2743 - extra_offset = 0;
2744 - end = 19;
2745 - break;
2746 - case LENS:
2747 - base = inflate_table_lbase;
2748 - base_offset = -257; // base -= 257;
2749 - extra = inflate_table_lext;
2750 - extra_offset = -257; // extra -= 257;
2751 - end = 256;
2752 - break;
2753 - default: /* DISTS */
2754 - base = inflate_table_dbase;
2755 - extra = inflate_table_dext;
2756 - base_offset = 0;
2757 - extra_offset = 0;
2758 - end = -1;
2759 - }
2760 -
2761 - /* initialize state for loop */
2762 - huff = 0; /* starting code */
2763 - sym = 0; /* starting code symbol */
2764 - len = min; /* starting code length */
2765 - next = table; /* current table to fill in */
2766 - curr = root; /* current table index bits */
2767 - drop = 0; /* current bits to drop from code for index */
2768 - low = -1; /* trigger new sub-table when len > root */
2769 - used = 1 << root; /* use root table entries */
2770 - mask = used - 1; /* mask for comparing low */
2771 -
2772 - /* check available table space */
2773 - if ((type == LENS && used >= ENOUGH_LENS) ||
2774 - (type == DISTS && used >= ENOUGH_DISTS)) {
2775 - state.next = table;
2776 - return 1;
2777 - }
2778 -
2779 - /* process all codes and make table entries */
2780 - for (;;) {
2781 - /* create table entry */
2782 - here = {op:0, bits:len - drop, val:0};
2783 - if (work[sym] < end) {
2784 - here.val = work[sym];
2785 - }
2786 - else if (work[sym] > end) {
2787 - here.op = extra[extra_offset + work[sym]];
2788 - here.val = base[base_offset + work[sym]];
2789 - }
2790 - else {
2791 - here.op = 32 + 64; /* end of block */
2792 - }
2793 -
2794 - /* replicate for those indices with low len bits equal to huff */
2795 - incr = 1 << (len - drop);
2796 - fill = 1 << curr;
2797 - min = fill; /* save offset to next table */
2798 - do {
2799 - fill -= incr;
2800 - state_codes[next + (huff >>> drop) + fill] = here;
2801 - } while (fill != 0);
2802 -
2803 - /* backwards increment the len-bit code huff */
2804 - incr = 1 << (len - 1);
2805 - while (huff & incr)
2806 - incr >>>= 1;
2807 - if (incr != 0) {
2808 - huff &= incr - 1;
2809 - huff += incr;
2810 - }
2811 - else
2812 - huff = 0;
2813 -
2814 - /* go to next symbol, update count, len */
2815 - sym++;
2816 - if (--(count[len]) == 0) {
2817 - if (len == max) break;
2818 - len = lens[lens_offset + work[sym]];
2819 - }
2820 -
2821 - /* create new sub-table if needed */
2822 - if (len > root && (huff & mask) != low) {
2823 - /* if first time, transition to sub-tables */
2824 - if (drop == 0)
2825 - drop = root;
2826 -
2827 - /* increment past last table */
2828 - next += min; /* here min is 1 << curr */
2829 -
2830 - /* determine length of next table */
2831 - curr = len - drop;
2832 - left = (1 << curr);
2833 - while (curr + drop < max) {
2834 - left -= count[curr + drop];
2835 - if (left <= 0) break;
2836 - curr++;
2837 - left <<= 1;
2838 - }
2839 -
2840 - /* check for enough space */
2841 - used += 1 << curr;
2842 - if ((type == LENS && used >= ENOUGH_LENS) ||
2843 - (type == DISTS && used >= ENOUGH_DISTS)) {
2844 - state.next = table;
2845 - return 1;
2846 - }
2847 -
2848 - /* point entry in root table to sub-table */
2849 - low = huff & mask;
2850 - state_codes[table + low] = {op:curr, bits:root, val:next - table};
2851 - }
2852 - }
2853 -
2854 - /* fill in remaining table entry if code is incomplete (guaranteed to have
2855 - at most one remaining entry, since if the code is incomplete, the
2856 - maximum code length that was allowed to get this far is one bit) */
2857 - if (huff != 0) {
2858 - state_codes[next + huff] = {op:64, bits:len - drop, val:0};
2859 - }
2860 -
2861 - /* set return parameters */
2862 - state.next = table + used;
2863 - if(type == DISTS) state.distbits = root; else state.lenbits = root; //*bits = root;
2864 - return 0;
2865 -}
2866 -
2867 -/* inffast.c -- fast decoding
2868 - * Copyright (C) 1995-2008, 2010 Mark Adler
2869 - * For conditions of distribution and use, see copyright notice in zlib.h
2870 - */
2871 -
2872 -/*
2873 - Decode literal, length, and distance codes and write out the resulting
2874 - literal and match bytes until either not enough input or output is
2875 - available, an end-of-block is encountered, or a data error is encountered.
2876 - When large enough input and output buffers are supplied to inflate(), for
2877 - example, a 16K input buffer and a 64K output buffer, more than 95% of the
2878 - inflate execution time is spent in this routine.
2879 -
2880 - Entry assumptions:
2881 -
2882 - state->mode == LEN
2883 - strm->avail_in >= 6
2884 - strm->avail_out >= 258
2885 - start >= strm->avail_out
2886 - state->bits < 8
2887 -
2888 - On return, state->mode is one of:
2889 -
2890 - LEN -- ran out of enough output space or enough available input
2891 - TYPE -- reached end of block code, inflate() to interpret next block
2892 - BAD -- error in block data
2893 -
2894 - Notes:
2895 -
2896 - - The maximum input bits used by a length/distance pair is 15 bits for the
2897 - length code, 5 bits for the length extra, 15 bits for the distance code,
2898 - and 13 bits for the distance extra. This totals 48 bits, or six bytes.
2899 - Therefore if strm->avail_in >= 6, then there is enough input to avoid
2900 - checking for available input while decoding.
2901 -
2902 - - The maximum bytes that a single length/distance pair can output is 258
2903 - bytes, which is the maximum length that can be coded. inflate_fast()
2904 - requires strm->avail_out >= 258 for each loop to avoid checking for
2905 - output space.
2906 - */
2907 -function inflate_fast(strm,
2908 - start) /* inflate()'s starting value for strm->avail_out */
2909 -{
2910 - var state;
2911 - var input_data; /* local strm->input_data */
2912 - var next_in; /* zlib.js: index of input_data */
2913 - var last; /* while next_in < last, enough input available */
2914 - var out; /* local strm.next_out */
2915 - var beg; /* inflate()'s initial strm.next_out */
2916 - var end; /* while out < end, enough space available */
2917 -//NOSPRT #ifdef INFLATE_STRICT
2918 -// unsigned dmax; /* maximum distance from zlib header */
2919 -//#endif
2920 - var wsize; /* window size or zero if not using window */
2921 - var whave; /* valid bytes in the window */
2922 - var wnext; /* window write index */
2923 - var window; /* allocated sliding window, if wsize != 0 */
2924 - var hold; /* local strm->hold */
2925 - var bits; /* local strm->bits */
2926 - var codes; /* zlib.js: local state.codes */
2927 - var lcode; /* local strm->lencode */
2928 - var dcode; /* local strm->distcode */
2929 - var lmask; /* mask for first level of length codes */
2930 - var dmask; /* mask for first level of distance codes */
2931 - var here; /* retrieved table entry */
2932 - var op; /* code bits, operation, extra bits, or */
2933 - /* window position, window bytes to copy */
2934 - var len; /* match length, unused bytes */
2935 - var dist; /* match distance */
2936 - // var from; /* where to copy match from */
2937 - var from_window_offset = -1; /* index of window[] */
2938 - var from_out_offset = -1; /* index of next_out[] */
2939 -
2940 - /* copy state to local variables */
2941 - state = strm.state;
2942 - input_data = strm.input_data;
2943 - next_in = strm.next_in;
2944 - last = next_in + strm.avail_in - 5;
2945 - out = strm.next_out;
2946 - beg = out - (start - strm.avail_out);
2947 - end = out + (strm.avail_out - 257);
2948 -//NOSPRT #ifdef INFLATE_STRICT
2949 -// dmax = state->dmax;
2950 -//#endif
2951 - wsize = state.wsize;
2952 - whave = state.whave;
2953 - wnext = state.wnext;
2954 - window = state.window;
2955 - hold = state.hold;
2956 - bits = state.bits;
2957 - codes = state.codes;
2958 - lcode = state.lencode;
2959 - dcode = state.distcode;
2960 - lmask = (1 << state.lenbits) - 1;
2961 - dmask = (1 << state.distbits) - 1;
2962 -
2963 - /* decode literals and length/distances until end-of-block or not enough
2964 - input data or output space */
2965 -loop: do {
2966 - if (bits < 15) {
2967 - hold += (input_data.charCodeAt(next_in++) & 0xff) << bits;
2968 - bits += 8;
2969 - hold += (input_data.charCodeAt(next_in++) & 0xff) << bits;
2970 - bits += 8;
2971 - }
2972 - here = codes[lcode + (hold & lmask)];
2973 - dolen: while(true) {
2974 - op = here.bits;
2975 - hold >>>= op;
2976 - bits -= op;
2977 - op = here.op;
2978 - if (op == 0) { /* literal */
2979 -// Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
2980 -// "inflate: literal '%c'\n" :
2981 -// "inflate: literal 0x%02x\n", here.val));
2982 - strm.output_data += String.fromCharCode(here.val);
2983 - out++;
2984 - }
2985 - else if (op & 16) { /* length base */
2986 - len = here.val;
2987 - op &= 15; /* number of extra bits */
2988 - if (op) {
2989 - if (bits < op) {
2990 - hold += (input_data.charCodeAt(next_in++) & 0xff) << bits;
2991 - bits += 8;
2992 - }
2993 - len += hold & ((1 << op) - 1);
2994 - hold >>>= op;
2995 - bits -= op;
2996 - }
2997 -// Tracevv((stderr, "inflate: length %u\n", len));
2998 - if (bits < 15) {
2999 - hold += (input_data.charCodeAt(next_in++) & 0xff) << bits;
3000 - bits += 8;
3001 - hold += (input_data.charCodeAt(next_in++) & 0xff) << bits;
3002 - bits += 8;
3003 - }
3004 - here = codes[dcode + (hold & dmask)];
3005 - dodist: while(true) {
3006 - op = here.bits;
3007 - hold >>>= op;
3008 - bits -= op;
3009 - op = here.op;
3010 - if (op & 16) { /* distance base */
3011 - dist = here.val;
3012 - op &= 15; /* number of extra bits */
3013 - if (bits < op) {
3014 - hold += (input_data.charCodeAt(next_in++) & 0xff) << bits;
3015 - bits += 8;
3016 - if (bits < op) {
3017 - hold += (input_data.charCodeAt(next_in++) & 0xff) << bits;
3018 - bits += 8;
3019 - }
3020 - }
3021 - dist += hold & ((1 << op) - 1);
3022 -//NOSPRT #ifdef INFLATE_STRICT
3023 -// if (dist > dmax) {
3024 -// strm->msg = (char *)"invalid distance too far back";
3025 -// state->mode = BAD;
3026 -// break loop;
3027 -// }
3028 -//#endif
3029 - hold >>>= op;
3030 - bits -= op;
3031 -// Tracevv((stderr, "inflate: distance %u\n", dist));
3032 - op = out - beg; /* max distance in output */
3033 - if (dist > op) { /* see if copy from window */
3034 - op = dist - op; /* distance back in window */
3035 - if (op > whave) {
3036 - if (state.sane) {
3037 - strm.msg = 'invalid distance too far back';
3038 - state.mode = BAD;
3039 - break loop;
3040 - }
3041 -//NOSPRT #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
3042 -// if (len <= op - whave) {
3043 -// do {
3044 -// PUP(out) = 0;
3045 -// } while (--len);
3046 -// continue;
3047 -// }
3048 -// len -= op - whave;
3049 -// do {
3050 -// PUP(out) = 0;
3051 -// } while (--op > whave);
3052 -// if (op == 0) {
3053 -// from = out - dist;
3054 -// do {
3055 -// PUP(out) = PUP(from);
3056 -// } while (--len);
3057 -// continue;
3058 -// }
3059 -//#endif
3060 - } // if (op > whave)
3061 -
3062 - from_window_offset = 0;
3063 - from_out_offset = -1;
3064 - if (wnext == 0) { /* very common case */
3065 - from_window_offset += wsize - op;
3066 - if (op < len) { /* some from window */
3067 - len -= op;
3068 - strm.output_data += window.substring(from_window_offset, from_window_offset + op);
3069 - out += op;
3070 - op = 0;
3071 - from_window_offset = -1;
3072 - from_out_offset = out - dist; /* rest from output */
3073 - }
3074 - }
3075 -//NOTREACHED else if (wnext < op) { /* wrap around window */
3076 -//NOTREACHED from += wsize + wnext - op;
3077 -//NOTREACHED op -= wnext;
3078 -//NOTREACHED if (op < len) { /* some from end of window */
3079 -//NOTREACHED len -= op;
3080 -//NOTREACHED do {
3081 -//NOTREACHED PUP(out) = PUP(from);
3082 -//NOTREACHED } while (--op);
3083 -//NOTREACHED from = window - OFF;
3084 -//NOTREACHED if (wnext < len) { /* some from start of window */
3085 -//NOTREACHED op = wnext;
3086 -//NOTREACHED len -= op;
3087 -//NOTREACHED do {
3088 -//NOTREACHED PUP(out) = PUP(from);
3089 -//NOTREACHED } while (--op);
3090 -//NOTREACHED from = out - dist; /* rest from output */
3091 -//NOTREACHED }
3092 -//NOTREACHED }
3093 -//NOTREACHED }
3094 - else { /* contiguous in window */
3095 - from_window_offset += wnext - op;
3096 - if (op < len) { /* some from window */
3097 - len -= op;
3098 - strm.output_data += window.substring(from_window_offset, from_window_offset + op);
3099 - out += op;
3100 - from_window_offset = -1;
3101 - from_out_offset = out - dist; /* rest from output */
3102 - }
3103 - }
3104 - }
3105 - else {
3106 - from_window_offset = -1;
3107 - from_out_offset = out - dist; /* copy direct from output */
3108 - }
3109 -
3110 - if (from_window_offset >= 0) {
3111 - strm.output_data += window.substring(from_window_offset, from_window_offset + len);
3112 - out += len;
3113 - from_window_offset += len;
3114 - } else {
3115 - var len_inner = len;
3116 - if(len_inner > out - from_out_offset)
3117 - len_inner = out - from_out_offset;
3118 - strm.output_data += strm.output_data.substring(
3119 - from_out_offset, from_out_offset + len_inner);
3120 - out += len_inner;
3121 - len -= len_inner;
3122 - from_out_offset += len_inner;
3123 - out += len;
3124 - while (len > 2) {
3125 - strm.output_data += strm.output_data.charAt(from_out_offset++);
3126 - strm.output_data += strm.output_data.charAt(from_out_offset++);
3127 - strm.output_data += strm.output_data.charAt(from_out_offset++);
3128 - len -= 3;
3129 - }
3130 - if (len) {
3131 - strm.output_data += strm.output_data.charAt(from_out_offset++);
3132 - if (len > 1)
3133 - strm.output_data += strm.output_data.charAt(from_out_offset++);
3134 - }
3135 - }
3136 - }
3137 - else if ((op & 64) == 0) { /* 2nd level distance code */
3138 - here = codes[dcode + (here.val + (hold & ((1 << op) - 1)))];
3139 - continue dodist; // goto dodist
3140 - }
3141 - else {
3142 - strm.msg = 'invalid distance code';
3143 - state.mode = BAD;
3144 - break loop;
3145 - }
3146 - break dodist; }
3147 - }
3148 - else if ((op & 64) == 0) { /* 2nd level length code */
3149 - here = codes[lcode + (here.val + (hold & ((1 << op) - 1)))];
3150 - continue dolen; // goto dolen;
3151 - }
3152 - else if (op & 32) { /* end-of-block */
3153 - // Tracevv((stderr, "inflate: end of block\n"));
3154 - state.mode = TYPE;
3155 - break loop;
3156 - }
3157 - else {
3158 - strm.msg = 'invalid literal/length code';
3159 - state.mode = BAD;
3160 - break loop;
3161 - }
3162 - break dolen; }
3163 - } while (next_in < last && out < end);
3164 -
3165 - /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
3166 - len = bits >>> 3;
3167 - next_in -= len;
3168 - bits -= len << 3;
3169 - hold &= (1 << bits) - 1;
3170 -
3171 - /* update state and return */
3172 - strm.next_in = next_in;
3173 - strm.next_out = out;
3174 - strm.avail_in = (next_in < last ? 5 + (last - next_in) : 5 - (next_in - last));
3175 - strm.avail_out = (out < end ?
3176 - 257 + (end - out) : 257 - (out - end));
3177 - state.hold = hold;
3178 - state.bits = bits;
3179 -}
3180 -
3181 -function new_array(size)
3182 -{
3183 - var i;
3184 - var ary = new Array(size);
3185 - for(i = 0; i < size; i++)
3186 - ary[i] = 0;
3187 - return ary;
3188 -}
3189 -
3190 -function getarg(opts, name, def_value)
3191 -{
3192 - return (opts && (name in opts)) ? opts[name] : def_value;
3193 -}
3194 -
3195 -function checksum_none()
3196 -{
3197 - return 0;
3198 -}
3199 -
3200 -/**
3201 - * z_stream constructor
3202 - * @constructor
3203 - */
3204 -function inflate_state()
3205 -{
3206 - var i;
3207 -
3208 - this.mode = 0; /* current inflate mode */
3209 - this.last = 0; /* true if processing last block */
3210 - this.wrap = 0; /* bit 0 true for zlib, bit 1 true for gzip */
3211 - this.havedict = 0; /* true if dictionary provided */
3212 - this.flags = 0; /* gzip header method and flags (0 if zlib) */
3213 - this.dmax = 0; /* zlib header max distance (INFLATE_STRICT) */
3214 - this.check = 0; /* protected copy of check value */
3215 - this.total = 0; /* protected copy of output count */
3216 - this.head = null; /* where to save gzip header information */
3217 - /* sliding window */
3218 - this.wbits = 0; /* log base 2 of requested window size */
3219 - this.wsize = 0; /* window size or zero if not using window */
3220 - this.whave = 0; /* valid bytes in the window */
3221 - this.wnext = 0; /* window write index (TODO remove) */
3222 - this.window = null; /* allocated sliding window, if needed */
3223 - /* bit accumulator */
3224 - this.hold = 0; /* input bit accumulator */
3225 - this.bits = 0; /* number of bits in "in" */
3226 - /* for string and stored block copying */
3227 - this.length = 0; /* literal or length of data to copy */
3228 - this.offset = 0; /* distance back to copy string from */
3229 - /* for table and code decoding */
3230 - this.extra = 0; /* extra bits needed */
3231 - /* fixed and dynamic code tables */
3232 -
3233 - /* zlib.js: modified implementation: lencode, distcode, next are offset of codes[] */
3234 - this.lencode = 0; /* starting table for length/literal codes */
3235 - this.distcode = 0; /* starting table for distance codes */
3236 - this.lenbits = 0; /* index bits for lencode */
3237 - this.distbits = 0; /* index bits for distcode */
3238 - /* dynamic table building */
3239 - this.ncode = 0; /* number of code length code lengths */
3240 - this.nlen = 0; /* number of length code lengths */
3241 - this.ndist = 0; /* number of distance code lengths */
3242 - this.have = 0; /* number of code lengths in lens[] */
3243 - this.next = 0; /* next available space in codes[] */
3244 - this.lens = new_array(320); /* temporary storage for code lengths */
3245 - this.work = new_array(288); /* work area for code table building */
3246 - this.codes = new Array(ENOUGH); /* space for code tables */
3247 - var c = {op:0, bits:0, val:0};
3248 - for(i = 0; i < ENOUGH; i++)
3249 - this.codes[i] = c;
3250 - this.sane = 0; /* if false, allow invalid distance too far */
3251 - this.back = 0; /* bits back of last unprocessed length/lit */
3252 - this.was = 0; /* initial length of match */
3253 -}
3254 -
3255 -ZLIB.inflateResetKeep = function(strm)
3256 -{
3257 - var state;
3258 -
3259 - if (!strm || !strm.state) return ZLIB.Z_STREAM_ERROR;
3260 - state = strm.state;
3261 - strm.total_in = strm.total_out = state.total = 0;
3262 - strm.msg = null;
3263 - if (state.wrap) { /* to support ill-conceived Java test suite */
3264 - strm.adler = state.wrap & 1;
3265 - }
3266 -
3267 - state.mode = HEAD;
3268 - state.last = 0;
3269 - state.havedict = 0;
3270 - state.dmax = 32768;
3271 - state.head = null;
3272 - state.hold = 0;
3273 - state.bits = 0;
3274 - state.lencode = 0;
3275 - state.distcode = 0;
3276 - state.next = 0;
3277 - state.sane = 1;
3278 - state.back = -1;
3279 - return ZLIB.Z_OK;
3280 -};
3281 -
3282 -// Usage: strm = ZLIB.inflateReset(z_stream [, windowBits]);
3283 -ZLIB.inflateReset = function(strm, windowBits)
3284 -{
3285 - var wrap;
3286 - var state;
3287 -
3288 - /* get the state */
3289 - if (!strm || !strm.state) return ZLIB.Z_STREAM_ERROR;
3290 - state = strm.state;
3291 -
3292 - if(typeof windowBits === "undefined")
3293 - windowBits = DEF_WBITS;
3294 -
3295 - /* extract wrap request from windowBits parameter */
3296 - if (windowBits < 0) {
3297 - wrap = 0;
3298 - windowBits = -windowBits;
3299 - }
3300 - else {
3301 - wrap = (windowBits >>> 4) + 1;
3302 - if (windowBits < 48)
3303 - windowBits &= 15;
3304 - }
3305 -
3306 - if(wrap == 1 && (typeof ZLIB.adler32 === 'function')) {
3307 - strm.checksum_function = ZLIB.adler32;
3308 - } else if(wrap == 2 && (typeof ZLIB.crc32 === 'function')) {
3309 - strm.checksum_function = ZLIB.crc32;
3310 - } else {
3311 - strm.checksum_function = checksum_none;
3312 - }
3313 -
3314 - /* set number of window bits, free window if different */
3315 - if (windowBits && (windowBits < 8 || windowBits > 15))
3316 - return ZLIB.Z_STREAM_ERROR;
3317 - if (state.window && state.wbits != windowBits) {
3318 - state.window = null;
3319 - }
3320 -
3321 - /* update state and reset the rest of it */
3322 - state.wrap = wrap;
3323 - state.wbits = windowBits;
3324 - state.wsize = 0;
3325 - state.whave = 0;
3326 - state.wnext = 0;
3327 - return ZLIB.inflateResetKeep(strm);
3328 -};
3329 -
3330 -// Usage: strm = ZLIB.inflateInit([windowBits]);
3331 -ZLIB.inflateInit = function(windowBits)
3332 -{
3333 - var strm = new ZLIB.z_stream();
3334 - strm.state = new inflate_state();
3335 - ZLIB.inflateReset(strm, windowBits);
3336 - return strm;
3337 -};
3338 -
3339 -ZLIB.inflatePrime = function(strm, bits, value)
3340 -{
3341 - var state;
3342 -
3343 - if (!strm || !strm.state) return ZLIB.Z_STREAM_ERROR;
3344 - state = strm.state;
3345 - if (bits < 0) {
3346 - state.hold = 0;
3347 - state.bits = 0;
3348 - return ZLIB.Z_OK;
3349 - }
3350 - if (bits > 16 || state.bits + bits > 32) return ZLIB.Z_STREAM_ERROR;
3351 - value &= (1 << bits) - 1;
3352 - state.hold += value << state.bits;
3353 - state.bits += bits;
3354 - return ZLIB.Z_OK;
3355 -};
3356 -
3357 -var lenfix_ary = null;
3358 -var distfix_ary = null;
3359 -function fixedtables(state)
3360 -{
3361 - var i;
3362 - if (!lenfix_ary) lenfix_ary = [ { op: 96, bits: 7, val: 0 }, { op: 0, bits: 8, val: 80 }, { op: 0, bits: 8, val: 16 }, { op: 20, bits: 8, val: 115 }, { op: 18, bits: 7, val: 31 }, { op: 0, bits: 8, val: 112 }, { op: 0, bits: 8, val: 48 }, { op: 0, bits: 9, val: 192 }, { op: 16, bits: 7, val: 10 }, { op: 0, bits: 8, val: 96 }, { op: 0, bits: 8, val: 32 }, { op: 0, bits: 9, val: 160 }, { op: 0, bits: 8, val: 0 }, { op: 0, bits: 8, val: 128 }, { op: 0, bits: 8, val: 64 }, { op: 0, bits: 9, val: 224 }, { op: 16, bits: 7, val: 6 }, { op: 0, bits: 8, val: 88 }, { op: 0, bits: 8, val: 24 }, { op: 0, bits: 9, val: 144 }, { op: 19, bits: 7, val: 59 }, { op: 0, bits: 8, val: 120 }, { op: 0, bits: 8, val: 56 }, { op: 0, bits: 9, val: 208 }, { op: 17, bits: 7, val: 17 }, { op: 0, bits: 8, val: 104 }, { op: 0, bits: 8, val: 40 }, { op: 0, bits: 9, val: 176 }, { op: 0, bits: 8, val: 8 }, { op: 0, bits: 8, val: 136 }, { op: 0, bits: 8, val: 72 }, { op: 0, bits: 9, val: 240 }, { op: 16, bits: 7, val: 4 }, { op: 0, bits: 8, val: 84 }, { op: 0, bits: 8, val: 20 }, { op: 21, bits: 8, val: 227 }, { op: 19, bits: 7, val: 43 }, { op: 0, bits: 8, val: 116 }, { op: 0, bits: 8, val: 52 }, { op: 0, bits: 9, val: 200 }, { op: 17, bits: 7, val: 13 }, { op: 0, bits: 8, val: 100 }, { op: 0, bits: 8, val: 36 }, { op: 0, bits: 9, val: 168 }, { op: 0, bits: 8, val: 4 }, { op: 0, bits: 8, val: 132 }, { op: 0, bits: 8, val: 68 }, { op: 0, bits: 9, val: 232 }, { op: 16, bits: 7, val: 8 }, { op: 0, bits: 8, val: 92 }, { op: 0, bits: 8, val: 28 }, { op: 0, bits: 9, val: 152 }, { op: 20, bits: 7, val: 83 }, { op: 0, bits: 8, val: 124 }, { op: 0, bits: 8, val: 60 }, { op: 0, bits: 9, val: 216 }, { op: 18, bits: 7, val: 23 }, { op: 0, bits: 8, val: 108 }, { op: 0, bits: 8, val: 44 }, { op: 0, bits: 9, val: 184 }, { op: 0, bits: 8, val: 12 }, { op: 0, bits: 8, val: 140 }, { op: 0, bits: 8, val: 76 }, { op: 0, bits: 9, val: 248 }, { op: 16, bits: 7, val: 3 }, { op: 0, bits: 8, val: 82 }, { op: 0, bits: 8, val: 18 }, { op: 21, bits: 8, val: 163 }, { op: 19, bits: 7, val: 35 }, { op: 0, bits: 8, val: 114 }, { op: 0, bits: 8, val: 50 }, { op: 0, bits: 9, val: 196 }, { op: 17, bits: 7, val: 11 }, { op: 0, bits: 8, val: 98 }, { op: 0, bits: 8, val: 34 }, { op: 0, bits: 9, val: 164 }, { op: 0, bits: 8, val: 2 }, { op: 0, bits: 8, val: 130 }, { op: 0, bits: 8, val: 66 }, { op: 0, bits: 9, val: 228 }, { op: 16, bits: 7, val: 7 }, { op: 0, bits: 8, val: 90 }, { op: 0, bits: 8, val: 26 }, { op: 0, bits: 9, val: 148 }, { op: 20, bits: 7, val: 67 }, { op: 0, bits: 8, val: 122 }, { op: 0, bits: 8, val: 58 }, { op: 0, bits: 9, val: 212 }, { op: 18, bits: 7, val: 19 }, { op: 0, bits: 8, val: 106 }, { op: 0, bits: 8, val: 42 }, { op: 0, bits: 9, val: 180 }, { op: 0, bits: 8, val: 10 }, { op: 0, bits: 8, val: 138 }, { op: 0, bits: 8, val: 74 }, { op: 0, bits: 9, val: 244 }, { op: 16, bits: 7, val: 5 }, { op: 0, bits: 8, val: 86 }, { op: 0, bits: 8, val: 22 }, { op: 64, bits: 8, val: 0 }, { op: 19, bits: 7, val: 51 }, { op: 0, bits: 8, val: 118 }, { op: 0, bits: 8, val: 54 }, { op: 0, bits: 9, val: 204 }, { op: 17, bits: 7, val: 15 }, { op: 0, bits: 8, val: 102 }, { op: 0, bits: 8, val: 38 }, { op: 0, bits: 9, val: 172 }, { op: 0, bits: 8, val: 6 }, { op: 0, bits: 8, val: 134 }, { op: 0, bits: 8, val: 70 }, { op: 0, bits: 9, val: 236 }, { op: 16, bits: 7, val: 9 }, { op: 0, bits: 8, val: 94 }, { op: 0, bits: 8, val: 30 }, { op: 0, bits: 9, val: 156 }, { op: 20, bits: 7, val: 99 }, { op: 0, bits: 8, val: 126 }, { op: 0, bits: 8, val: 62 }, { op: 0, bits: 9, val: 220 }, { op: 18, bits: 7, val: 27 }, { op: 0, bits: 8, val: 110 }, { op: 0, bits: 8, val: 46 }, { op: 0, bits: 9, val: 188 }, { op: 0, bits: 8, val: 14 }, { op: 0, bits: 8, val: 142 }, { op: 0, bits: 8, val: 78 }, { op: 0, bits: 9, val: 252 }, { op: 96, bits: 7, val: 0 }, { op: 0, bits: 8, val: 81 }, { op: 0, bits: 8, val: 17 }, { op: 21, bits: 8, val: 131 }, { op: 18, bits: 7, val: 31 }, { op: 0, bits: 8, val: 113 }, { op: 0, bits: 8, val: 49 }, { op: 0, bits: 9, val: 194 }, { op: 16, bits: 7, val: 10 }, { op: 0, bits: 8, val: 97 }, { op: 0, bits: 8, val: 33 }, { op: 0, bits: 9, val: 162 }, { op: 0, bits: 8, val: 1 }, { op: 0, bits: 8, val: 129 }, { op: 0, bits: 8, val: 65 }, { op: 0, bits: 9, val: 226 }, { op: 16, bits: 7, val: 6 }, { op: 0, bits: 8, val: 89 }, { op: 0, bits: 8, val: 25 }, { op: 0, bits: 9, val: 146 }, { op: 19, bits: 7, val: 59 }, { op: 0, bits: 8, val: 121 }, { op: 0, bits: 8, val: 57 }, { op: 0, bits: 9, val: 210 }, { op: 17, bits: 7, val: 17 }, { op: 0, bits: 8, val: 105 }, { op: 0, bits: 8, val: 41 }, { op: 0, bits: 9, val: 178 }, { op: 0, bits: 8, val: 9 }, { op: 0, bits: 8, val: 137 }, { op: 0, bits: 8, val: 73 }, { op: 0, bits: 9, val: 242 }, { op: 16, bits: 7, val: 4 }, { op: 0, bits: 8, val: 85 }, { op: 0, bits: 8, val: 21 }, { op: 16, bits: 8, val: 258 }, { op: 19, bits: 7, val: 43 }, { op: 0, bits: 8, val: 117 }, { op: 0, bits: 8, val: 53 }, { op: 0, bits: 9, val: 202 }, { op: 17, bits: 7, val: 13 }, { op: 0, bits: 8, val: 101 }, { op: 0, bits: 8, val: 37 }, { op: 0, bits: 9, val: 170 }, { op: 0, bits: 8, val: 5 }, { op: 0, bits: 8, val: 133 }, { op: 0, bits: 8, val: 69 }, { op: 0, bits: 9, val: 234 }, { op: 16, bits: 7, val: 8 }, { op: 0, bits: 8, val: 93 }, { op: 0, bits: 8, val: 29 }, { op: 0, bits: 9, val: 154 }, { op: 20, bits: 7, val: 83 }, { op: 0, bits: 8, val: 125 }, { op: 0, bits: 8, val: 61 }, { op: 0, bits: 9, val: 218 }, { op: 18, bits: 7, val: 23 }, { op: 0, bits: 8, val: 109 }, { op: 0, bits: 8, val: 45 }, { op: 0, bits: 9, val: 186 }, { op: 0, bits: 8, val: 13 }, { op: 0, bits: 8, val: 141 }, { op: 0, bits: 8, val: 77 }, { op: 0, bits: 9, val: 250 }, { op: 16, bits: 7, val: 3 }, { op: 0, bits: 8, val: 83 }, { op: 0, bits: 8, val: 19 }, { op: 21, bits: 8, val: 195 }, { op: 19, bits: 7, val: 35 }, { op: 0, bits: 8, val: 115 }, { op: 0, bits: 8, val: 51 }, { op: 0, bits: 9, val: 198 }, { op: 17, bits: 7, val: 11 }, { op: 0, bits: 8, val: 99 }, { op: 0, bits: 8, val: 35 }, { op: 0, bits: 9, val: 166 }, { op: 0, bits: 8, val: 3 }, { op: 0, bits: 8, val: 131 }, { op: 0, bits: 8, val: 67 }, { op: 0, bits: 9, val: 230 }, { op: 16, bits: 7, val: 7 }, { op: 0, bits: 8, val: 91 }, { op: 0, bits: 8, val: 27 }, { op: 0, bits: 9, val: 150 }, { op: 20, bits: 7, val: 67 }, { op: 0, bits: 8, val: 123 }, { op: 0, bits: 8, val: 59 }, { op: 0, bits: 9, val: 214 }, { op: 18, bits: 7, val: 19 }, { op: 0, bits: 8, val: 107 }, { op: 0, bits: 8, val: 43 }, { op: 0, bits: 9, val: 182 }, { op: 0, bits: 8, val: 11 }, { op: 0, bits: 8, val: 139 }, { op: 0, bits: 8, val: 75 }, { op: 0, bits: 9, val: 246 }, { op: 16, bits: 7, val: 5 }, { op: 0, bits: 8, val: 87 }, { op: 0, bits: 8, val: 23 }, { op: 64, bits: 8, val: 0 }, { op: 19, bits: 7, val: 51 }, { op: 0, bits: 8, val: 119 }, { op: 0, bits: 8, val: 55 }, { op: 0, bits: 9, val: 206 }, { op: 17, bits: 7, val: 15 }, { op: 0, bits: 8, val: 103 }, { op: 0, bits: 8, val: 39 }, { op: 0, bits: 9, val: 174 }, { op: 0, bits: 8, val: 7 }, { op: 0, bits: 8, val: 135 }, { op: 0, bits: 8, val: 71 }, { op: 0, bits: 9, val: 238 }, { op: 16, bits: 7, val: 9 }, { op: 0, bits: 8, val: 95 }, { op: 0, bits: 8, val: 31 }, { op: 0, bits: 9, val: 158 }, { op: 20, bits: 7, val: 99 }, { op: 0, bits: 8, val: 127 }, { op: 0, bits: 8, val: 63 }, { op: 0, bits: 9, val: 222 }, { op: 18, bits: 7, val: 27 }, { op: 0, bits: 8, val: 111 }, { op: 0, bits: 8, val: 47 }, { op: 0, bits: 9, val: 190 }, { op: 0, bits: 8, val: 15 }, { op: 0, bits: 8, val: 143 }, { op: 0, bits: 8, val: 79 }, { op: 0, bits: 9, val: 254 }, { op: 96, bits: 7, val: 0 }, { op: 0, bits: 8, val: 80 }, { op: 0, bits: 8, val: 16 }, { op: 20, bits: 8, val: 115 }, { op: 18, bits: 7, val: 31 }, { op: 0, bits: 8, val: 112 }, { op: 0, bits: 8, val: 48 }, { op: 0, bits: 9, val: 193 }, { op: 16, bits: 7, val: 10 }, { op: 0, bits: 8, val: 96 }, { op: 0, bits: 8, val: 32 }, { op: 0, bits: 9, val: 161 }, { op: 0, bits: 8, val: 0 }, { op: 0, bits: 8, val: 128 }, { op: 0, bits: 8, val: 64 }, { op: 0, bits: 9, val: 225 }, { op: 16, bits: 7, val: 6 }, { op: 0, bits: 8, val: 88 }, { op: 0, bits: 8, val: 24 }, { op: 0, bits: 9, val: 145 }, { op: 19, bits: 7, val: 59 }, { op: 0, bits: 8, val: 120 }, { op: 0, bits: 8, val: 56 }, { op: 0, bits: 9, val: 209 }, { op: 17, bits: 7, val: 17 }, { op: 0, bits: 8, val: 104 }, { op: 0, bits: 8, val: 40 }, { op: 0, bits: 9, val: 177 }, { op: 0, bits: 8, val: 8 }, { op: 0, bits: 8, val: 136 }, { op: 0, bits: 8, val: 72 }, { op: 0, bits: 9, val: 241 }, { op: 16, bits: 7, val: 4 }, { op: 0, bits: 8, val: 84 }, { op: 0, bits: 8, val: 20 }, { op: 21, bits: 8, val: 227 }, { op: 19, bits: 7, val: 43 }, { op: 0, bits: 8, val: 116 }, { op: 0, bits: 8, val: 52 }, { op: 0, bits: 9, val: 201 }, { op: 17, bits: 7, val: 13 }, { op: 0, bits: 8, val: 100 }, { op: 0, bits: 8, val: 36 }, { op: 0, bits: 9, val: 169 }, { op: 0, bits: 8, val: 4 }, { op: 0, bits: 8, val: 132 }, { op: 0, bits: 8, val: 68 }, { op: 0, bits: 9, val: 233 }, { op: 16, bits: 7, val: 8 }, { op: 0, bits: 8, val: 92 }, { op: 0, bits: 8, val: 28 }, { op: 0, bits: 9, val: 153 }, { op: 20, bits: 7, val: 83 }, { op: 0, bits: 8, val: 124 }, { op: 0, bits: 8, val: 60 }, { op: 0, bits: 9, val: 217 }, { op: 18, bits: 7, val: 23 }, { op: 0, bits: 8, val: 108 }, { op: 0, bits: 8, val: 44 }, { op: 0, bits: 9, val: 185 }, { op: 0, bits: 8, val: 12 }, { op: 0, bits: 8, val: 140 }, { op: 0, bits: 8, val: 76 }, { op: 0, bits: 9, val: 249 }, { op: 16, bits: 7, val: 3 }, { op: 0, bits: 8, val: 82 }, { op: 0, bits: 8, val: 18 }, { op: 21, bits: 8, val: 163 }, { op: 19, bits: 7, val: 35 }, { op: 0, bits: 8, val: 114 }, { op: 0, bits: 8, val: 50 }, { op: 0, bits: 9, val: 197 }, { op: 17, bits: 7, val: 11 }, { op: 0, bits: 8, val: 98 }, { op: 0, bits: 8, val: 34 }, { op: 0, bits: 9, val: 165 }, { op: 0, bits: 8, val: 2 }, { op: 0, bits: 8, val: 130 }, { op: 0, bits: 8, val: 66 }, { op: 0, bits: 9, val: 229 }, { op: 16, bits: 7, val: 7 }, { op: 0, bits: 8, val: 90 }, { op: 0, bits: 8, val: 26 }, { op: 0, bits: 9, val: 149 }, { op: 20, bits: 7, val: 67 }, { op: 0, bits: 8, val: 122 }, { op: 0, bits: 8, val: 58 },{ op: 0, bits: 9, val: 213 }, { op: 18, bits: 7, val: 19 }, { op: 0, bits: 8, val: 106 }, { op: 0, bits: 8, val: 42 }, { op: 0, bits: 9, val: 181 }, { op: 0, bits: 8, val: 10 }, { op: 0, bits: 8, val: 138 },{ op: 0, bits: 8, val: 74 }, { op: 0, bits: 9, val: 245 }, { op: 16, bits: 7, val: 5 }, { op: 0, bits: 8, val: 86 }, { op: 0, bits: 8, val: 22 }, { op: 64, bits: 8, val: 0 }, { op: 19, bits: 7, val: 51 },{ op: 0, bits: 8, val: 118 }, { op: 0, bits: 8, val: 54 }, { op: 0, bits: 9, val: 205 }, { op: 17, bits: 7, val: 15 }, { op: 0, bits: 8, val: 102 }, { op: 0, bits: 8, val: 38 }, { op: 0, bits: 9, val: 173 },{ op: 0, bits: 8, val: 6 }, { op: 0, bits: 8, val: 134 }, { op: 0, bits: 8, val: 70 }, { op: 0, bits: 9, val: 237 }, { op: 16, bits: 7, val: 9 }, { op: 0, bits: 8, val: 94 }, { op: 0, bits: 8, val: 30 },{ op: 0, bits: 9, val: 157 }, { op: 20, bits: 7, val: 99 }, { op: 0, bits: 8, val: 126 }, { op: 0, bits: 8, val: 62 }, { op: 0, bits: 9, val: 221 }, { op: 18, bits: 7, val: 27 }, { op: 0, bits: 8, val: 110 }, { op: 0, bits: 8, val: 46 }, { op: 0, bits: 9, val: 189 }, { op: 0, bits: 8, val: 14 }, { op: 0, bits: 8, val: 142 }, { op: 0, bits: 8, val: 78 }, { op: 0, bits: 9, val: 253 }, { op: 96, bits: 7, val: 0 }, { op: 0, bits: 8, val: 81 }, { op: 0, bits: 8, val: 17 }, { op: 21, bits: 8, val: 131 }, { op: 18, bits: 7, val: 31 }, { op: 0, bits: 8, val: 113 }, { op: 0, bits: 8, val: 49 }, { op: 0, bits: 9, val: 195 }, { op: 16, bits: 7, val: 10 }, { op: 0, bits: 8, val: 97 }, { op: 0, bits: 8, val: 33 }, { op: 0, bits: 9, val: 163 }, { op: 0, bits: 8, val: 1 }, { op: 0, bits: 8, val: 129 }, { op: 0, bits: 8, val: 65 }, { op: 0, bits: 9, val: 227 }, { op: 16, bits: 7, val: 6 }, { op: 0, bits: 8, val: 89 }, { op: 0, bits: 8, val: 25 }, { op: 0, bits: 9, val: 147 }, { op: 19, bits: 7, val: 59 }, { op: 0, bits: 8, val: 121 }, { op: 0, bits: 8, val: 57 }, { op: 0, bits: 9, val: 211 }, { op: 17, bits: 7, val: 17 }, { op: 0, bits: 8, val: 105 }, { op: 0, bits: 8, val: 41 }, { op: 0, bits: 9, val: 179 }, { op: 0, bits: 8, val: 9 },{ op: 0, bits: 8, val: 137 }, { op: 0, bits: 8, val: 73 }, { op: 0, bits: 9, val: 243 }, { op: 16, bits: 7, val: 4 }, { op: 0, bits: 8, val: 85 }, { op: 0, bits: 8, val: 21 }, { op: 16, bits: 8, val: 258 },{ op: 19, bits: 7, val: 43 }, { op: 0, bits: 8, val: 117 }, { op: 0, bits: 8, val: 53 }, { op: 0, bits: 9, val: 203 }, { op: 17, bits: 7, val: 13 }, { op: 0, bits: 8, val: 101 }, { op: 0, bits: 8, val: 37 },{ op: 0, bits: 9, val: 171 }, { op: 0, bits: 8, val: 5 }, { op: 0, bits: 8, val: 133 }, { op: 0, bits: 8, val: 69 }, { op: 0, bits: 9, val: 235 }, { op: 16, bits: 7, val: 8 }, { op: 0, bits: 8, val: 93 },{ op: 0, bits: 8, val: 29 }, { op: 0, bits: 9, val: 155 }, { op: 20, bits: 7, val: 83 }, { op: 0, bits: 8, val: 125 }, { op: 0, bits: 8, val: 61 }, { op: 0, bits: 9, val: 219 }, { op: 18, bits: 7, val: 23 },{ op: 0, bits: 8, val: 109 }, { op: 0, bits: 8, val: 45 }, { op: 0, bits: 9, val: 187 }, { op: 0, bits: 8, val: 13 }, { op: 0, bits: 8, val: 141 }, { op: 0, bits: 8, val: 77 }, { op: 0, bits: 9, val: 251 }, { op: 16, bits: 7, val: 3 }, { op: 0, bits: 8, val: 83 }, { op: 0, bits: 8, val: 19 }, { op: 21, bits: 8, val: 195 }, { op: 19, bits: 7, val: 35 }, { op: 0, bits: 8, val: 115 }, { op: 0, bits: 8, val: 51 }, { op: 0, bits: 9, val: 199 }, { op: 17, bits: 7, val: 11 }, { op: 0, bits: 8, val: 99 }, { op: 0, bits: 8, val: 35 }, { op: 0, bits: 9, val: 167 }, { op: 0, bits: 8, val: 3 }, { op: 0, bits: 8, val: 131 }, { op: 0, bits: 8, val: 67 }, { op: 0, bits: 9, val: 231 }, { op: 16, bits: 7, val: 7 }, { op: 0, bits: 8, val: 91 }, { op: 0, bits: 8, val: 27 }, { op: 0, bits: 9, val: 151 }, { op: 20, bits: 7, val: 67 }, { op: 0, bits: 8, val: 123 }, { op: 0, bits: 8, val: 59 }, { op: 0, bits: 9, val: 215 }, { op: 18, bits: 7, val: 19 }, { op: 0, bits: 8, val: 107 }, { op: 0, bits: 8, val: 43 }, { op: 0, bits: 9, val: 183 }, { op: 0, bits: 8, val: 11 }, { op: 0, bits: 8, val: 139 }, { op: 0, bits: 8, val: 75 }, { op: 0, bits: 9, val: 247 }, { op: 16, bits: 7, val: 5 }, { op: 0, bits: 8, val: 87 }, { op: 0, bits: 8, val: 23 }, { op: 64, bits: 8, val: 0 }, { op: 19, bits: 7, val: 51 }, { op: 0, bits: 8, val: 119 }, { op: 0, bits: 8, val: 55 }, { op: 0, bits: 9, val: 207 }, { op: 17, bits: 7, val: 15 }, { op: 0, bits: 8, val: 103 }, { op: 0, bits: 8, val: 39 }, { op: 0, bits: 9, val: 175 }, { op: 0, bits: 8, val: 7 }, { op: 0, bits: 8, val: 135 }, { op: 0, bits: 8, val: 71 }, { op: 0, bits: 9, val: 239 }, { op: 16, bits: 7, val: 9 }, { op: 0, bits: 8, val: 95 }, { op: 0, bits: 8, val: 31 }, { op: 0, bits: 9, val: 159 }, { op: 20, bits: 7, val: 99 }, { op: 0, bits: 8, val: 127 }, { op: 0, bits: 8, val: 63 }, { op: 0, bits: 9, val: 223 }, { op: 18, bits: 7, val: 27 }, { op: 0, bits: 8, val: 111 }, { op: 0, bits: 8, val: 47 }, { op: 0, bits: 9, val: 191 }, { op: 0, bits: 8, val: 15 }, { op: 0, bits: 8, val: 143 }, { op: 0, bits: 8, val: 79 }, { op: 0, bits: 9, val: 255 } ];
3363 - if (!distfix_ary) distfix_ary = [ { op: 16, bits: 5, val: 1 }, { op: 23, bits: 5, val: 257 }, { op: 19, bits: 5, val: 17 }, { op: 27, bits: 5, val: 4097 }, { op: 17, bits: 5, val: 5 }, { op: 25, bits: 5, val: 1025 }, { op: 21, bits: 5, val: 65 }, { op: 29, bits: 5, val: 16385 }, { op: 16, bits: 5, val: 3 }, { op: 24, bits: 5, val: 513 }, { op: 20, bits: 5, val: 33 }, { op: 28, bits: 5, val: 8193 }, { op: 18, bits: 5, val: 9 }, { op: 26, bits: 5, val: 2049 }, { op: 22, bits: 5, val: 129 }, { op: 64, bits: 5, val: 0 }, { op: 16, bits: 5, val: 2 }, { op: 23, bits: 5, val: 385 }, { op: 19, bits: 5, val: 25 }, { op: 27, bits: 5, val: 6145 }, { op: 17, bits: 5, val: 7 }, { op: 25, bits: 5, val: 1537 }, { op: 21, bits: 5, val: 97 }, { op: 29, bits: 5, val: 24577 }, { op: 16, bits: 5, val: 4 }, { op: 24, bits: 5, val: 769 }, { op: 20, bits: 5, val: 49 }, { op: 28, bits: 5, val: 12289 }, { op: 18, bits: 5, val: 13 }, { op: 26, bits: 5, val: 3073 }, { op: 22, bits: 5, val: 193 }, { op: 64, bits: 5, val: 0 } ];
3364 - state.lencode = 0;
3365 - state.distcode = 512;
3366 - for (i = 0; i < 512; i++) { state.codes[i] = lenfix_ary[i]; }
3367 - for (i = 0; i < 32; i++) { state.codes[i + 512] = distfix_ary[i]; }
3368 - state.lenbits = 9;
3369 - state.distbits = 5;
3370 -}
3371 -
3372 -/*
3373 - Update the window with the last wsize (normally 32K) bytes written before
3374 - returning. If window does not exist yet, create it. This is only called
3375 - when a window is already in use, or when output has been written during this
3376 - inflate call, but the end of the deflate stream has not been reached yet.
3377 - It is also called to create a window for dictionary data when a dictionary
3378 - is loaded.
3379 -
3380 - Providing output buffers larger than 32K to inflate() should provide a speed
3381 - advantage, since only the last 32K of output is copied to the sliding window
3382 - upon return from inflate(), and since all distances after the first 32K of
3383 - output will fall in the output data, making match copies simpler and faster.
3384 - The advantage may be dependent on the size of the processor's data caches.
3385 -*/
3386 -function updatewindow(strm)
3387 -{
3388 - var state = strm.state;
3389 - var out = strm.output_data.length;
3390 -
3391 - /* if it hasn't been done already, allocate space for the window */
3392 - if (state.window === null) {
3393 - state.window = '';
3394 - }
3395 -
3396 - /* if window not in use yet, initialize */
3397 - if (state.wsize == 0) {
3398 - state.wsize = 1 << state.wbits;
3399 - }
3400 -
3401 - // zlib.js: Sliding window
3402 - if (out >= state.wsize) {
3403 - state.window = strm.output_data.substring(out - state.wsize);
3404 - } else {
3405 - if(state.whave + out < state.wsize) {
3406 - state.window += strm.output_data;
3407 - } else {
3408 - state.window = state.window.substring(state.whave - (state.wsize - out)) + strm.output_data;
3409 - }
3410 - }
3411 - state.whave = state.window.length;
3412 - if(state.whave < state.wsize) {
3413 - state.wnext = state.whave;
3414 - } else {
3415 - state.wnext = 0;
3416 - }
3417 - return 0;
3418 -}
3419 -
3420 -
3421 -// #ifdef GUNZIP
3422 -function CRC2(strm, word)
3423 -{
3424 - var hbuf = [word & 0xff, (word >>> 8) & 0xff];
3425 - strm.state.check = strm.checksum_function(strm.state.check, hbuf, 0, 2);
3426 -}
3427 -
3428 -function CRC4(strm, word)
3429 -{
3430 - var hbuf = [word & 0xff,
3431 - (word >>> 8) & 0xff,
3432 - (word >>> 16) & 0xff,
3433 - (word >>> 24) & 0xff];
3434 - strm.state.check = strm.checksum_function(strm.state.check, hbuf, 0, 4);
3435 -}
3436 -
3437 -/* Load registers with state in inflate() for speed */
3438 -function LOAD(strm, s)
3439 -{
3440 - s.strm = strm; /* z_stream */
3441 - s.left = strm.avail_out; /* available output */
3442 - s.next = strm.next_in; /* next input */
3443 - s.have = strm.avail_in; /* available input */
3444 - s.hold = strm.state.hold; /* bit buffer */
3445 - s.bits = strm.state.bits; /* bits in bit buffer */
3446 - return s;
3447 -}
3448 -
3449 -/* Restore state from registers in inflate() */
3450 -function RESTORE(s)
3451 -{
3452 - var strm = s.strm;
3453 - strm.next_in = s.next;
3454 - strm.avail_out = s.left;
3455 - strm.avail_in = s.have;
3456 - strm.state.hold = s.hold;
3457 - strm.state.bits = s.bits;
3458 -}
3459 -
3460 -/* Clear the input bit accumulator */
3461 -function INITBITS(s)
3462 -{
3463 - s.hold = 0;
3464 - s.bits = 0;
3465 -}
3466 -
3467 -/* Get a byte of input into the bit accumulator, or return from inflate()
3468 - if there is no input available. */
3469 -function PULLBYTE(s)
3470 -{
3471 - if (s.have == 0) return false;
3472 - s.have--;
3473 - s.hold += (s.strm.input_data.charCodeAt(s.next++) & 0xff) << s.bits;
3474 - s.bits += 8;
3475 - return true;
3476 -}
3477 -
3478 -/* Assure that there are at least n bits in the bit accumulator. If there is
3479 - not enough available input to do that, then return from inflate(). */
3480 -function NEEDBITS(s, n)
3481 -{
3482 - // if(typeof n != 'number') throw 'ERROR';
3483 - while (s.bits < n) {
3484 - if(!PULLBYTE(s))
3485 - return false;
3486 - }
3487 - return true;
3488 -}
3489 -
3490 -/* Return the low n bits of the bit accumulator (n < 16) */
3491 -function BITS(s, n)
3492 -{
3493 - return s.hold & ((1 << n) - 1);
3494 -}
3495 -
3496 -/* Remove n bits from the bit accumulator */
3497 -function DROPBITS(s, n)
3498 -{
3499 - // if(typeof n != 'number') throw 'ERROR';
3500 - s.hold >>>= n;
3501 - s.bits -= n;
3502 -}
3503 -
3504 -/* Remove zero to seven bits as needed to go to a byte boundary */
3505 -function BYTEBITS(s)
3506 -{
3507 - s.hold >>>= s.bits & 7;
3508 - s.bits -= s.bits & 7;
3509 -}
3510 -
3511 -/* Reverse the bytes in a 32-bit value */
3512 -function REVERSE(q)
3513 -{
3514 - return ((q >>> 24) & 0xff) +
3515 - ((q >>> 8) & 0xff00) +
3516 - ((q & 0xff00) << 8) +
3517 - ((q & 0xff) << 24);
3518 -}
3519 -
3520 -/*
3521 - inflate() uses a state machine to process as much input data and generate as
3522 - much output data as possible before returning. The state machine is
3523 - structured roughly as follows:
3524 -
3525 - for (;;) switch (state) {
3526 - ...
3527 - case STATEn:
3528 - if (not enough input data or output space to make progress)
3529 - return;
3530 - ... make progress ...
3531 - state = STATEm;
3532 - break;
3533 - ...
3534 - }
3535 -
3536 - so when inflate() is called again, the same case is attempted again, and
3537 - if the appropriate resources are provided, the machine proceeds to the
3538 - next state. The NEEDBITS() macro is usually the way the state evaluates
3539 - whether it can proceed or should return. NEEDBITS() does the return if
3540 - the requested bits are not available. The typical use of the BITS macros
3541 - is:
3542 -
3543 - NEEDBITS(n);
3544 - ... do something with BITS(n) ...
3545 - DROPBITS(n);
3546 -
3547 - where NEEDBITS(n) either returns from inflate() if there isn't enough
3548 - input left to load n bits into the accumulator, or it continues. BITS(n)
3549 - gives the low n bits in the accumulator. When done, DROPBITS(n) drops
3550 - the low n bits off the accumulator. INITBITS() clears the accumulator
3551 - and sets the number of available bits to zero. BYTEBITS() discards just
3552 - enough bits to put the accumulator on a byte boundary. After BYTEBITS()
3553 - and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
3554 -
3555 - NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
3556 - if there is no input available. The decoding of variable length codes uses
3557 - PULLBYTE() directly in order to pull just enough bytes to decode the next
3558 - code, and no more.
3559 -
3560 - Some states loop until they get enough input, making sure that enough
3561 - state information is maintained to continue the loop where it left off
3562 - if NEEDBITS() returns in the loop. For example, want, need, and keep
3563 - would all have to actually be part of the saved state in case NEEDBITS()
3564 - returns:
3565 -
3566 - case STATEw:
3567 - while (want < need) {
3568 - NEEDBITS(n);
3569 - keep[want++] = BITS(n);
3570 - DROPBITS(n);
3571 - }
3572 - state = STATEx;
3573 - case STATEx:
3574 -
3575 - As shown above, if the next state is also the next case, then the break
3576 - is omitted.
3577 -
3578 - A state may also return if there is not enough output space available to
3579 - complete that state. Those states are copying stored data, writing a
3580 - literal byte, and copying a matching string.
3581 -
3582 - When returning, a "goto inf_leave" is used to update the total counters,
3583 - update the check value, and determine whether any progress has been made
3584 - during that inflate() call in order to return the proper return code.
3585 - Progress is defined as a change in either strm->avail_in or strm->avail_out.
3586 - When there is a window, goto inf_leave will update the window with the last
3587 - output written. If a goto inf_leave occurs in the middle of decompression
3588 - and there is no window currently, goto inf_leave will create one and copy
3589 - output to the window for the next call of inflate().
3590 -
3591 - In this implementation, the flush parameter of inflate() only affects the
3592 - return code (per zlib.h). inflate() always writes as much as possible to
3593 - strm->next_out, given the space available and the provided input--the effect
3594 - documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers
3595 - the allocation of and copying into a sliding window until necessary, which
3596 - provides the effect documented in zlib.h for Z_FINISH when the entire input
3597 - stream available. So the only thing the flush parameter actually does is:
3598 - when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it
3599 - will return Z_BUF_ERROR if it has not reached the end of the stream.
3600 - */
3601 -
3602 -/* permutation of code lengths */
3603 -var inflate_order = [
3604 - 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15];
3605 -ZLIB.inflate = function(strm, flush)
3606 -{
3607 - var state;
3608 - var s;
3609 - var _in, out; /* save starting available input and output */
3610 - var copy; /* number of stored or match bytes to copy */
3611 - var from_window_offset = -1; /* index of window[] */
3612 - var from_out_offset = -1; /* index of next_out[] */
3613 - var here; /* current decoding table entry */
3614 - var last; /* parent table entry */
3615 - var len; /* length to copy for repeats, bits to drop */
3616 - var ret; /* return code */
3617 -
3618 - if (!strm || !strm.state ||
3619 - (!strm.input_data && strm.avail_in != 0))
3620 - return ZLIB.Z_STREAM_ERROR;
3621 -
3622 - state = strm.state;
3623 - if (state.mode == TYPE) state.mode = TYPEDO; /* skip check */
3624 -
3625 - // LOAD
3626 - s = {};
3627 - LOAD(strm, s);
3628 -
3629 - _in = s.have;
3630 - out = s.left;
3631 - ret = ZLIB.Z_OK;
3632 -inf_leave: for (;;) {
3633 - switch (state.mode) {
3634 - case HEAD:
3635 - if (state.wrap == 0) {
3636 - state.mode = TYPEDO;
3637 - break;
3638 - }
3639 - if(!NEEDBITS(s, 16)) break inf_leave;
3640 -// #ifdef GUNZIP
3641 - if ((state.wrap & 2) && s.hold == 0x8b1f) { /* gzip header */
3642 - state.check = strm.checksum_function(0, null, 0, 0);
3643 - CRC2(strm, s.hold);
3644 - INITBITS(s);
3645 - state.mode = FLAGS;
3646 - break;
3647 - }
3648 - state.flags = 0; /* expect zlib header */
3649 - if (state.head !== null)
3650 - state.head.done = -1;
3651 - if (!(state.wrap & 1) || /* check if zlib header allowed */
3652 -//#else
3653 -// if (
3654 -//#endif
3655 - ((BITS(s, 8) << 8) + (s.hold >>> 8)) % 31) {
3656 - strm.msg = 'incorrect header check';
3657 - state.mode = BAD;
3658 - break;
3659 - }
3660 - if (BITS(s, 4) != ZLIB.Z_DEFLATED) {
3661 - strm.msg = 'unknown compression method';
3662 - state.mode = BAD;
3663 - break;
3664 - }
3665 -
3666 - DROPBITS(s, 4);
3667 - len = BITS(s, 4) + 8;
3668 - if (state.wbits == 0)
3669 - state.wbits = len;
3670 - else if (len > state.wbits) {
3671 - strm.msg = 'invalid window size';
3672 - state.mode = BAD;
3673 - break;
3674 - }
3675 - state.dmax = 1 << len;
3676 -// Tracev((stderr, "inflate: zlib header ok\n"));
3677 - strm.adler = state.check = strm.checksum_function(0, null, 0, 0);
3678 - state.mode = s.hold & 0x200 ? DICTID : TYPE;
3679 - INITBITS(s);
3680 - break;
3681 -// #ifdef GUNZIP
3682 - case FLAGS:
3683 - if(!NEEDBITS(s, 16)) break inf_leave;
3684 - state.flags = s.hold;
3685 - if ((state.flags & 0xff) != ZLIB.Z_DEFLATED) {
3686 - strm.msg = "unknown compression method";
3687 - state.mode = BAD;
3688 - break;
3689 - }
3690 - if (state.flags & 0xe000) {
3691 - strm.msg = "unknown header flags set";
3692 - state.mode = BAD;
3693 - break;
3694 - }
3695 - if (state.head !== null)
3696 - state.head.text = (s.hold >>> 8) & 1;
3697 - if (state.flags & 0x0200) {
3698 - CRC2(strm, s.hold);
3699 - }
3700 - INITBITS(s);
3701 - state.mode = TIME;
3702 - case TIME:
3703 - if(!NEEDBITS(s, 32)) break inf_leave;
3704 - if (state.head !== null)
3705 - state.head.time = s.hold;
3706 - if (state.flags & 0x0200) {
3707 - CRC4(strm, s.hold);
3708 - }
3709 - INITBITS(s);
3710 - state.mode = OS;
3711 - case OS:
3712 - if(!NEEDBITS(s, 16)) break inf_leave;
3713 - if (state.head !== null) {
3714 - state.head.xflags = s.hold & 0xff;
3715 - state.head.os = s.hold >>> 8;
3716 - }
3717 - if (state.flags & 0x0200) {
3718 - CRC2(strm, s.hold);
3719 - }
3720 - INITBITS(s);
3721 - state.mode = EXLEN;
3722 - case EXLEN:
3723 - if (state.flags & 0x0400) {
3724 - if(!NEEDBITS(s, 16)) break inf_leave;
3725 - state.length = s.hold;
3726 - if (state.head !== null) {
3727 - state.head.extra_len = s.hold;
3728 - }
3729 - if (state.flags & 0x0200) {
3730 - CRC2(strm, s.hold);
3731 - }
3732 - INITBITS(s);
3733 - state.head.extra = "";
3734 - }
3735 - else if (state.head !== null) {
3736 - state.head.extra = null;
3737 - }
3738 - state.mode = EXTRA;
3739 - case EXTRA:
3740 - if (state.flags & 0x0400) {
3741 - copy = state.length;
3742 - if (copy > s.have) copy = s.have;
3743 - if (copy) {
3744 - if (state.head !== null &&
3745 - state.head.extra !== null) {
3746 - len = state.head.extra_len - state.length;
3747 -/*
3748 - zmemcpy(state->head->extra + len, next,
3749 - len + copy > state->head->extra_max ?
3750 - state->head->extra_max - len : copy);
3751 -*/
3752 - state.head.extra += strm.input_data.substring(
3753 - s.next, s.next + (len + copy > state.head.extra_max ?
3754 - state.head.extra_max - len : copy));
3755 -
3756 - }
3757 - if (state.flags & 0x0200)
3758 - state.check = strm.checksum_function(state.check, strm.input_data, s.next, copy);
3759 - s.have -= copy;
3760 - s.next += copy;
3761 - state.length -= copy;
3762 - }
3763 - if (state.length) break inf_leave;
3764 - }
3765 - state.length = 0;
3766 - state.mode = NAME;
3767 - case NAME:
3768 - if (state.flags & 0x0800) {
3769 - if (s.have == 0) break inf_leave;
3770 - if (state.head !== null && state.head.name === null) {
3771 - state.head.name = "";
3772 - }
3773 - copy = 0;
3774 - // TODO end = strm.input_data.indexOf("\0", s.next);
3775 - // TODO state.length => state.head.name.length
3776 - do {
3777 - len = strm.input_data.charAt(s.next + copy); copy++;
3778 - if(len === "\0")
3779 - break;
3780 - if (state.head !== null &&
3781 - state.length < state.head.name_max) {
3782 - state.head.name += len;
3783 - state.length++;
3784 - }
3785 - } while (copy < s.have);
3786 - if (state.flags & 0x0200) {
3787 - state.check = strm.checksum_function(state.check, strm.input_data, s.next, copy);
3788 - }
3789 - s.have -= copy;
3790 - s.next += copy;
3791 - if (len !== "\0") break inf_leave;
3792 - }
3793 - else if (state.head !== null)
3794 - state.head.name = null;
3795 - state.length = 0;
3796 - state.mode = COMMENT;
3797 - case COMMENT:
3798 - if (state.flags & 0x1000) {
3799 - if (s.have == 0) break inf_leave;
3800 - copy = 0;
3801 - if (state.head !== null && state.head.comment === null) {
3802 - state.head.comment = "";
3803 - }
3804 - // TODO end = strm.input_data.indexOf("\0", s.next);
3805 - // TODO state.length => state.head.comment.length
3806 - do {
3807 - len = strm.input_data.charAt(s.next + copy); copy++;
3808 - if(len === "\0")
3809 - break;
3810 - if (state.head !== null &&
3811 - state.length < state.head.comm_max) {
3812 - state.head.comment += len;
3813 - state.length++;
3814 - }
3815 - } while (copy < s.have);
3816 - if (state.flags & 0x0200)
3817 - state.check = strm.checksum_function(state.check, strm.input_data, s.next, copy);
3818 - s.have -= copy;
3819 - s.next += copy;
3820 - if (len !== "\0") break inf_leave;
3821 - }
3822 - else if (state.head !== null)
3823 - state.head.comment = null;
3824 - state.mode = HCRC;
3825 - case HCRC:
3826 - if (state.flags & 0x0200) {
3827 - if(!NEEDBITS(s, 16)) break inf_leave;
3828 - if (s.hold != (state.check & 0xffff)) {
3829 - strm.msg = "header crc mismatch";
3830 - state.mode = BAD;
3831 - break;
3832 - }
3833 - INITBITS(s);
3834 - }
3835 - if (state.head !== null) {
3836 - state.head.hcrc = (state.flags >>> 9) & 1;
3837 - state.head.done = 1;
3838 - }
3839 - strm.adler = state.check = strm.checksum_function(0, null, 0, 0);
3840 - state.mode = TYPE;
3841 - break;
3842 -//#endif
3843 - case DICTID:
3844 - if(!NEEDBITS(s, 32)) break inf_leave;
3845 - strm.adler = state.check = REVERSE(s.hold);
3846 - INITBITS(s);
3847 - state.mode = DICT;
3848 - case DICT:
3849 - if (state.havedict == 0) {
3850 - RESTORE(s);
3851 - return ZLIB.Z_NEED_DICT;
3852 - }
3853 - strm.adler = state.check = strm.checksum_function(0, null, 0, 0);
3854 - state.mode = TYPE;
3855 - case TYPE:
3856 - if (flush == ZLIB.Z_BLOCK || flush == ZLIB.Z_TREES) break inf_leave;
3857 - case TYPEDO:
3858 - if (state.last) {
3859 - BYTEBITS(s);
3860 - state.mode = CHECK;
3861 - break;
3862 - }
3863 - if(!NEEDBITS(s, 3)) break inf_leave;
3864 - state.last = BITS(s, 1);
3865 - DROPBITS(s, 1);
3866 - switch (BITS(s, 2)) {
3867 - case 0: /* stored block */
3868 -// Tracev((stderr, "inflate: stored block%s\n",
3869 -// state->last ? " (last)" : ""));
3870 - state.mode = STORED;
3871 - break;
3872 - case 1: /* fixed block */
3873 - fixedtables(state);
3874 -// Tracev((stderr, "inflate: fixed codes block%s\n",
3875 -// state->last ? " (last)" : ""));
3876 - state.mode = LEN_; /* decode codes */
3877 - if (flush == ZLIB.Z_TREES) {
3878 - DROPBITS(s, 2);
3879 - break inf_leave;
3880 - }
3881 - break;
3882 - case 2: /* dynamic block */
3883 -// Tracev((stderr, "inflate: dynamic codes block%s\n",
3884 -// state->last ? " (last)" : ""));
3885 - state.mode = TABLE;
3886 - break;
3887 - case 3:
3888 - strm.msg = 'invalid block type';
3889 - state.mode = BAD;
3890 - }
3891 - DROPBITS(s, 2);
3892 - break;
3893 - case STORED:
3894 - BYTEBITS(s); /* go to byte boundary */
3895 - if(!NEEDBITS(s, 32)) break inf_leave;
3896 - if ((s.hold & 0xffff) != (((s.hold >>> 16) & 0xffff) ^ 0xffff)) {
3897 - strm.msg = 'invalid stored block lengths';
3898 - state.mode = BAD;
3899 - break;
3900 - }
3901 - state.length = s.hold & 0xffff;
3902 -// Tracev((stderr, "inflate: stored length %u\n",
3903 -// state->length));
3904 - INITBITS(s);
3905 - state.mode = COPY_;
3906 - if (flush == ZLIB.Z_TREES) break inf_leave;
3907 - case COPY_:
3908 - state.mode = COPY;
3909 - case COPY:
3910 - copy = state.length;
3911 - if (copy) {
3912 - if (copy > s.have) copy = s.have;
3913 - if (copy > s.left) copy = s.left;
3914 - if (copy == 0) break inf_leave;
3915 - strm.output_data += strm.input_data.substring(s.next, s.next + copy);
3916 - strm.next_out += copy;
3917 - s.have -= copy;
3918 - s.next += copy;
3919 - s.left -= copy;
3920 - state.length -= copy;
3921 - break;
3922 - }
3923 -// Tracev((stderr, "inflate: stored end\n"));
3924 - state.mode = TYPE;
3925 - break;
3926 - case TABLE:
3927 - if(!NEEDBITS(s, 14)) break inf_leave;
3928 - state.nlen = BITS(s, 5) + 257;
3929 - DROPBITS(s, 5);
3930 - state.ndist = BITS(s, 5) + 1;
3931 - DROPBITS(s, 5);
3932 - state.ncode = BITS(s, 4) + 4;
3933 - DROPBITS(s, 4);
3934 -//#ifndef PKZIP_BUG_WORKAROUND
3935 - if (state.nlen > 286 || state.ndist > 30) {
3936 - strm.msg = 'too many length or distance symbols';
3937 - state.mode = BAD;
3938 - break;
3939 - }
3940 -//#endif
3941 -// Tracev((stderr, "inflate: table sizes ok\n"));
3942 - state.have = 0;
3943 - state.mode = LENLENS;
3944 - case LENLENS:
3945 - while (state.have < state.ncode) {
3946 - if(!NEEDBITS(s, 3)) break inf_leave;
3947 - var tmp = BITS(s, 3);
3948 - state.lens[inflate_order[state.have++]] = tmp;
3949 - DROPBITS(s, 3);
3950 - }
3951 - while (state.have < 19)
3952 - state.lens[inflate_order[state.have++]] = 0;
3953 - state.next = 0;
3954 - state.lencode = 0;
3955 - state.lenbits = 7;
3956 -
3957 -// ret = inflate_table(CODES, state->lens, 19, &(state->next),
3958 -// &(state->lenbits), state->work);
3959 - ret = inflate_table(state, CODES);
3960 -
3961 - if (ret) {
3962 - strm.msg = 'invalid code lengths set';
3963 - state.mode = BAD;
3964 - break;
3965 - }
3966 -// Tracev((stderr, "inflate: code lengths ok\n"));
3967 - state.have = 0;
3968 - state.mode = CODELENS;
3969 - case CODELENS:
3970 - while (state.have < state.nlen + state.ndist) {
3971 - for (;;) {
3972 - here = state.codes[state.lencode + BITS(s, state.lenbits)];
3973 - if (here.bits <= s.bits) break;
3974 - if(!PULLBYTE(s)) break inf_leave;
3975 - }
3976 - if (here.val < 16) {
3977 - DROPBITS(s, here.bits);
3978 - state.lens[state.have++] = here.val;
3979 - }
3980 - else {
3981 - if (here.val == 16) {
3982 - if(!NEEDBITS(s, here.bits + 2)) break inf_leave;
3983 - DROPBITS(s, here.bits);
3984 - if (state.have == 0) {
3985 - strm.msg = 'invalid bit length repeat';
3986 - state.mode = BAD;
3987 - break;
3988 - }
3989 - len = state.lens[state.have - 1];
3990 - copy = 3 + BITS(s, 2);
3991 - DROPBITS(s, 2);
3992 - }
3993 - else if (here.val == 17) {
3994 - if(!NEEDBITS(s, here.bits + 3)) break inf_leave;
3995 - DROPBITS(s, here.bits);
3996 - len = 0;
3997 - copy = 3 + BITS(s, 3);
3998 - DROPBITS(s, 3);
3999 - }
4000 - else {
4001 - if(!NEEDBITS(s, here.bits + 7)) break inf_leave;
4002 - DROPBITS(s, here.bits);
4003 - len = 0;
4004 - copy = 11 + BITS(s, 7);
4005 - DROPBITS(s, 7);
4006 - }
4007 - if (state.have + copy > state.nlen + state.ndist) {
4008 - strm.msg = 'invalid bit length repeat';
4009 - state.mode = BAD;
4010 - break;
4011 - }
4012 - while (copy--)
4013 - state.lens[state.have++] = len;
4014 - }
4015 - }
4016 -
4017 - /* handle error breaks in while */
4018 - if (state.mode == BAD) break;
4019 -
4020 - /* check for end-of-block code (better have one) */
4021 - if (state.lens[256] == 0) {
4022 - strm.msg = 'invalid code -- missing end-of-block';
4023 - state.mode = BAD;
4024 - break;
4025 - }
4026 -
4027 - /* build code tables -- note: do not change the lenbits or distbits
4028 - values here (9 and 6) without reading the comments in inftrees.h
4029 - concerning the ENOUGH constants, which depend on those values */
4030 - state.next = 0;
4031 - state.lencode = state.next;
4032 - state.lenbits = 9;
4033 -// ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
4034 -// &(state->lenbits), state->work);
4035 - ret = inflate_table(state, LENS);
4036 - if (ret) {
4037 - strm.msg = 'invalid literal/lengths set';
4038 - state.mode = BAD;
4039 - break;
4040 - }
4041 - state.distcode = state.next;
4042 - state.distbits = 6;
4043 -// ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, &(state->next),
4044 -// &(state->distbits), state->work);
4045 - ret = inflate_table(state, DISTS);
4046 - if (ret) {
4047 - strm.msg = 'invalid distances set';
4048 - state.mode = BAD;
4049 - break;
4050 - }
4051 -// Tracev((stderr, "inflate: codes ok\n"));
4052 - state.mode = LEN_;
4053 - if (flush == ZLIB.Z_TREES) break inf_leave;
4054 - case LEN_:
4055 - state.mode = LEN;
4056 - case LEN:
4057 - if (s.have >= 6 && s.left >= 258) {
4058 - RESTORE(s);
4059 - inflate_fast(strm, out);
4060 - LOAD(strm, s);
4061 - if (state.mode == TYPE)
4062 - state.back = -1;
4063 - break;
4064 - }
4065 - state.back = 0;
4066 - for (;;) {
4067 - here = state.codes[state.lencode + BITS(s, state.lenbits)];
4068 - if (here.bits <= s.bits) break;
4069 - if(!PULLBYTE(s)) break inf_leave;
4070 - }
4071 - if (here.op && (here.op & 0xf0) == 0) {
4072 - last = here;
4073 - for (;;) {
4074 - here = state.codes[state.lencode + last.val +
4075 - (BITS(s, last.bits + last.op) >>> last.bits)];
4076 - if (last.bits + here.bits <= s.bits) break;
4077 - if(!PULLBYTE(s)) break inf_leave;
4078 - }
4079 - DROPBITS(s, last.bits);
4080 - state.back += last.bits;
4081 - }
4082 - DROPBITS(s, here.bits);
4083 - state.back += here.bits;
4084 - state.length = here.val;
4085 - if (here.op == 0) {
4086 -// Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
4087 -// "inflate: literal '%c'\n" :
4088 -// "inflate: literal 0x%02x\n", here.val));
4089 - state.mode = LIT;
4090 - break;
4091 - }
4092 - if (here.op & 32) {
4093 -// Tracevv((stderr, "inflate: end of block\n"));
4094 - state.back = -1;
4095 - state.mode = TYPE;
4096 - break;
4097 - }
4098 - if (here.op & 64) {
4099 - strm.msg = 'invalid literal/length code';
4100 - state.mode = BAD;
4101 - break;
4102 - }
4103 - state.extra = here.op & 15;
4104 - state.mode = LENEXT;
4105 - case LENEXT:
4106 - if (state.extra) {
4107 - if(!NEEDBITS(s, state.extra)) break inf_leave;
4108 - state.length += BITS(s, state.extra);
4109 - DROPBITS(s, state.extra);
4110 - state.back += state.extra;
4111 - }
4112 - //Tracevv((stderr, "inflate: length %u\n", state->length));
4113 - state.was = state.length;
4114 - state.mode = DIST;
4115 - case DIST:
4116 - for (;;) {
4117 - here = state.codes[state.distcode + BITS(s, state.distbits)];
4118 - if (here.bits <= s.bits) break;
4119 - if(!PULLBYTE(s)) break inf_leave;
4120 - }
4121 - if ((here.op & 0xf0) == 0) {
4122 - last = here;
4123 - for (;;) {
4124 - here = state.codes[state.distcode + last.val +
4125 - (BITS(s, last.bits + last.op) >>> last.bits)];
4126 - if ((last.bits + here.bits) <= s.bits) break;
4127 - if(!PULLBYTE(s)) break inf_leave;
4128 - }
4129 - DROPBITS(s, last.bits);
4130 - state.back += last.bits;
4131 - }
4132 - DROPBITS(s, here.bits);
4133 - state.back += here.bits;
4134 - if (here.op & 64) {
4135 - strm.msg = 'invalid distance code';
4136 - state.mode = BAD;
4137 - break;
4138 - }
4139 - state.offset = here.val;
4140 - state.extra = here.op & 15;
4141 - state.mode = DISTEXT;
4142 - case DISTEXT:
4143 - if (state.extra) {
4144 - if(!NEEDBITS(s, state.extra)) break inf_leave;
4145 - state.offset += BITS(s, state.extra);
4146 - DROPBITS(s, state.extra);
4147 - state.back += state.extra;
4148 - }
4149 -//NOSPRT #ifdef INFLATE_STRICT
4150 -// if (state->offset > state->dmax) {
4151 -// strm->msg = (char *)"invalid distance too far back";
4152 -// state->mode = BAD;
4153 -// break;
4154 -// }
4155 -//#endif
4156 -// Tracevv((stderr, "inflate: distance %u\n", state->offset));
4157 - state.mode = MATCH;
4158 - case MATCH:
4159 - if (s.left == 0) break inf_leave;
4160 - copy = out - s.left;
4161 - if (state.offset > copy) { /* copy from window */
4162 - copy = state.offset - copy;
4163 - if (copy > state.whave) {
4164 - if (state.sane) {
4165 - strm.msg = 'invalid distance too far back';
4166 - state.mode = BAD;
4167 - break;
4168 - }
4169 -//NOSPRT #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
4170 -// Trace((stderr, "inflate.c too far\n"));
4171 -// copy -= state->whave;
4172 -// if (copy > state->length) copy = state->length;
4173 -// if (copy > left) copy = left;
4174 -// left -= copy;
4175 -// state->length -= copy;
4176 -// do {
4177 -// *put++ = 0;
4178 -// } while (--copy);
4179 -// if (state->length == 0) state->mode = LEN;
4180 -// break;
4181 -//#endif
4182 - }
4183 - if (copy > state.wnext) {
4184 - copy -= state.wnext;
4185 - // from = state->window + (state->wsize - copy);
4186 - from_window_offset = state.wsize - copy;
4187 - from_out_offset = -1;
4188 - }
4189 - else {
4190 - // from = state->window + (state->wnext - copy);
4191 - from_window_offset = state.wnext - copy;
4192 - from_out_offset = -1;
4193 - }
4194 - if (copy > state.length) copy = state.length;
4195 - }
4196 - else { /* copy from output */
4197 - // from = put - state->offset;
4198 - from_window_offset = -1;
4199 - from_out_offset = strm.next_out - state.offset;
4200 - copy = state.length;
4201 - }
4202 - if (copy > s.left) copy = s.left;
4203 - s.left -= copy;
4204 - state.length -= copy;
4205 - if( from_window_offset >= 0 ) {
4206 - strm.output_data += state.window.substring(from_window_offset, from_window_offset + copy);
4207 - strm.next_out += copy;
4208 - copy = 0;
4209 - } else {
4210 - strm.next_out += copy;
4211 - do {
4212 - strm.output_data += strm.output_data.charAt(from_out_offset++);
4213 - } while (--copy);
4214 - }
4215 - if (state.length == 0) state.mode = LEN;
4216 - break;
4217 - case LIT:
4218 - if (s.left == 0) break inf_leave;
4219 -
4220 - strm.output_data += String.fromCharCode(state.length);
4221 - strm.next_out++;
4222 - //*put++ = (unsigned char)(state->length);
4223 -
4224 - s.left--;
4225 - state.mode = LEN;
4226 - break;
4227 - case CHECK:
4228 - if (state.wrap) {
4229 - if(!NEEDBITS(s, 32)) break inf_leave;
4230 - out -= s.left;
4231 - strm.total_out += out;
4232 - state.total += out;
4233 - if (out)
4234 - strm.adler = state.check =
4235 - strm.checksum_function(state.check, strm.output_data, strm.output_data.length - out, out);
4236 - out = s.left;
4237 - if ((
4238 -// #ifdef GUNZIP
4239 - state.flags ? s.hold :
4240 -//#endif
4241 - REVERSE(s.hold)) != state.check) {
4242 - strm.msg = "incorrect data check";
4243 - state.mode = BAD;
4244 - break;
4245 - }
4246 - INITBITS(s);
4247 -//debug("## inflate: check matches trailer\n");
4248 -// Tracev((stderr, "inflate: check matches trailer\n"));
4249 - }
4250 -//#ifdef GUNZIP
4251 - state.mode = LENGTH;
4252 - case LENGTH:
4253 - if (state.wrap && state.flags) {
4254 - if(!NEEDBITS(s, 32)) break inf_leave;
4255 - if (s.hold != (state.total & 0xffffffff)) {
4256 - strm.msg = 'incorrect length check';
4257 - state.mode = BAD;
4258 - break;
4259 - }
4260 - INITBITS(s);
4261 - //Tracev((stderr, "inflate: length matches trailer\n"));
4262 - }
4263 -//#endif
4264 - state.mode = DONE;
4265 - case DONE:
4266 - ret = ZLIB.Z_STREAM_END;
4267 - break inf_leave;
4268 - case BAD:
4269 - ret = ZLIB.Z_DATA_ERROR;
4270 - break inf_leave;
4271 - case MEM:
4272 - return ZLIB.Z_MEM_ERROR;
4273 - case SYNC:
4274 - default:
4275 - return ZLIB.Z_STREAM_ERROR;
4276 - } }
4277 -
4278 - /*
4279 - Return from inflate(), updating the total counts and the check value.
4280 - If there was no progress during the inflate() call, return a buffer
4281 - error. Call updatewindow() to create and/or update the window state.
4282 - Note: a memory error from inflate() is non-recoverable.
4283 - */
4284 -inf_leave:
4285 - RESTORE(s);
4286 - if (state.wsize || (out != strm.avail_out && state.mode < BAD &&
4287 - (state.mode < CHECK || flush != ZLIB.Z_FINISH)))
4288 - if (updatewindow(strm)) {
4289 - state.mode = MEM;
4290 - return ZLIB.Z_MEM_ERROR;
4291 - }
4292 - _in -= strm.avail_in;
4293 - out -= strm.avail_out;
4294 - strm.total_in += _in;
4295 - strm.total_out += out;
4296 - state.total += out;
4297 - if (state.wrap && out)
4298 - strm.adler = state.check = strm.checksum_function(state.check, strm.output_data, 0, strm.output_data.length);
4299 - strm.data_type = state.bits + (state.last ? 64 : 0) +
4300 - (state.mode == TYPE ? 128 : 0) +
4301 - (state.mode == LEN_ || state.mode == COPY_ ? 256 : 0);
4302 - if (((_in == 0 && out == 0) || flush == ZLIB.Z_FINISH) && ret == ZLIB.Z_OK)
4303 - ret = ZLIB.Z_BUF_ERROR;
4304 - return ret;
4305 -};
4306 -
4307 -ZLIB.inflateEnd = function(strm)
4308 -{
4309 - var state;
4310 - if (!strm || !strm.state )
4311 - return ZLIB.Z_STREAM_ERROR;
4312 - state = strm.state;
4313 - state.window = null;
4314 - strm.state = null;
4315 - // Tracev((stderr, "inflate: end\n"));
4316 - return ZLIB.Z_OK;
4317 -};
4318 -
4319 -ZLIB.z_stream.prototype.inflate = function(input_string, opts)
4320 -{
4321 - var flush;
4322 - var avail_out;
4323 - var DEFAULT_BUFFER_SIZE = 16384;
4324 -
4325 - this.input_data = input_string;
4326 - this.next_in = getarg(opts, 'next_in', 0);
4327 - this.avail_in = getarg(opts, 'avail_in', input_string.length - this.next_in);
4328 -
4329 - flush = getarg(opts, 'flush', ZLIB.Z_SYNC_FLUSH);
4330 - avail_out = getarg(opts, 'avail_out', -1);
4331 -
4332 - var result = '';
4333 - do {
4334 - this.avail_out = (avail_out >= 0 ? avail_out : DEFAULT_BUFFER_SIZE);
4335 - this.output_data = '';
4336 - this.next_out = 0;
4337 - this.error = ZLIB.inflate(this, flush);
4338 - if(avail_out >= 0) {
4339 - return this.output_data;
4340 - }
4341 - result += this.output_data;
4342 - if(this.avail_out > 0) {
4343 - break;
4344 - }
4345 - } while(this.error == ZLIB.Z_OK);
4346 -
4347 - return result;
4348 -};
4349 -
4350 -ZLIB.z_stream.prototype.inflateReset = function(windowBits)
4351 -{
4352 - return ZLIB.inflateReset(this, windowBits);
4353 -};
4354 -
4355 -}());
4356 -/* zlib-adler32.js -- JavaScript implementation for the zlib adler32.
4357 - Version: 0.2.0
4358 - LastModified: Apr 12 2012
4359 - Copyright (C) 2012 Masanao Izumo <iz@onicos.co.jp>
4360 -
4361 - API documentation
4362 -==============================================================================
4363 -Usage: adler = ZLIB.adler32(adler, buf, offset, len);
4364 -
4365 - Update a running Adler-32 checksum with the bytes buf[offset..offset+len-1] and
4366 - return the updated checksum. If buf is null, this function returns the
4367 - required initial value for the checksum.
4368 -
4369 - An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
4370 - much faster.
4371 -
4372 - Usage example:
4373 -
4374 - var adler = ZLIB.adler32(0, null, 0, 0);
4375 -
4376 - while (read_buffer(buffer, length) != EOF) {
4377 - adler = ZLIB.adler32(adler, buffer, 0, length);
4378 - }
4379 - if (adler != original_adler) error();
4380 -
4381 -==============================================================================
4382 -Usage: adler = ZLIB.adler32_combine(adler1, adler2, len2);
4383 -
4384 - Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
4385 - and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
4386 - each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
4387 - seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note
4388 - that the z_off_t type (like off_t) is a signed integer. If len2 is
4389 - negative, the result has no meaning or utility.
4390 -*/
4391 -
4392 -if( typeof ZLIB === 'undefined' ) {
4393 - alert('ZLIB is not defined. SRC zlib.js before zlib-adler32.js')
4394 -}
4395 -
4396 -(function() {
4397 -
4398 -/* adler32.c -- compute the Adler-32 checksum of a data stream
4399 - * Copyright (C) 1995-2011 Mark Adler
4400 - * For conditions of distribution and use, see copyright notice in zlib.h
4401 - */
4402 -
4403 -var BASE = 65521; /* largest prime smaller than 65536 */
4404 -var NMAX = 5552;
4405 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
4406 -
4407 -/* ========================================================================= */
4408 -function adler32_string(adler, buf, offset, len)
4409 -{
4410 - var sum2;
4411 - var n;
4412 -
4413 - /* split Adler-32 into component sums */
4414 - sum2 = (adler >>> 16) & 0xffff;
4415 - adler &= 0xffff;
4416 -
4417 - /* in case user likes doing a byte at a time, keep it fast */
4418 - if (len == 1) {
4419 - adler += buf.charCodeAt(offset) & 0xff;
4420 - if (adler >= BASE)
4421 - adler -= BASE;
4422 - sum2 += adler;
4423 - if (sum2 >= BASE)
4424 - sum2 -= BASE;
4425 - return adler | (sum2 << 16);
4426 - }
4427 -
4428 - /* initial Adler-32 value (deferred check for len == 1 speed) */
4429 - if (buf === null)
4430 - return 1;
4431 -
4432 - /* in case short lengths are provided, keep it somewhat fast */
4433 - if (len < 16) {
4434 - while (len--) {
4435 - adler += buf.charCodeAt(offset++) & 0xff;
4436 - sum2 += adler;
4437 - }
4438 - if (adler >= BASE)
4439 - adler -= BASE;
4440 - sum2 %= BASE; /* only added so many BASE's */
4441 - return adler | (sum2 << 16);
4442 - }
4443 -
4444 - /* do length NMAX blocks -- requires just one modulo operation */
4445 - while (len >= NMAX) {
4446 - len -= NMAX;
4447 - n = NMAX >> 4; /* NMAX is divisible by 16 */
4448 - do {
4449 - /* 16 sums unrolled */
4450 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4451 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4452 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4453 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4454 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4455 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4456 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4457 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4458 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4459 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4460 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4461 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4462 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4463 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4464 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4465 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4466 - } while (--n);
4467 - adler %= BASE;
4468 - sum2 %= BASE;
4469 - }
4470 -
4471 - /* do remaining bytes (less than NMAX, still just one modulo) */
4472 - if (len) { /* avoid modulos if none remaining */
4473 - while (len >= 16) {
4474 - len -= 16;
4475 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4476 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4477 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4478 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4479 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4480 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4481 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4482 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4483 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4484 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4485 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4486 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4487 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4488 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4489 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4490 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4491 - }
4492 - while (len--) {
4493 - adler += buf.charCodeAt(offset++) & 0xff; sum2 += adler;
4494 - }
4495 - adler %= BASE;
4496 - sum2 %= BASE;
4497 - }
4498 -
4499 - /* return recombined sums */
4500 - return adler | (sum2 << 16);
4501 -}
4502 -
4503 -/* ========================================================================= */
4504 -function adler32_array(adler, buf, offset, len)
4505 -{
4506 - var sum2;
4507 - var n;
4508 -
4509 - /* split Adler-32 into component sums */
4510 - sum2 = (adler >>> 16) & 0xffff;
4511 - adler &= 0xffff;
4512 -
4513 - /* in case user likes doing a byte at a time, keep it fast */
4514 - if (len == 1) {
4515 - adler += buf[offset];
4516 - if (adler >= BASE)
4517 - adler -= BASE;
4518 - sum2 += adler;
4519 - if (sum2 >= BASE)
4520 - sum2 -= BASE;
4521 - return adler | (sum2 << 16);
4522 - }
4523 -
4524 - /* initial Adler-32 value (deferred check for len == 1 speed) */
4525 - if (buf === null)
4526 - return 1;
4527 -
4528 - /* in case short lengths are provided, keep it somewhat fast */
4529 - if (len < 16) {
4530 - while (len--) {
4531 - adler += buf[offset++];
4532 - sum2 += adler;
4533 - }
4534 - if (adler >= BASE)
4535 - adler -= BASE;
4536 - sum2 %= BASE; /* only added so many BASE's */
4537 - return adler | (sum2 << 16);
4538 - }
4539 -
4540 - /* do length NMAX blocks -- requires just one modulo operation */
4541 - while (len >= NMAX) {
4542 - len -= NMAX;
4543 - n = NMAX >> 4; /* NMAX is divisible by 16 */
4544 - do {
4545 - /* 16 sums unrolled */
4546 - adler += buf[offset++]; sum2 += adler;
4547 - adler += buf[offset++]; sum2 += adler;
4548 - adler += buf[offset++]; sum2 += adler;
4549 - adler += buf[offset++]; sum2 += adler;
4550 - adler += buf[offset++]; sum2 += adler;
4551 - adler += buf[offset++]; sum2 += adler;
4552 - adler += buf[offset++]; sum2 += adler;
4553 - adler += buf[offset++]; sum2 += adler;
4554 - adler += buf[offset++]; sum2 += adler;
4555 - adler += buf[offset++]; sum2 += adler;
4556 - adler += buf[offset++]; sum2 += adler;
4557 - adler += buf[offset++]; sum2 += adler;
4558 - adler += buf[offset++]; sum2 += adler;
4559 - adler += buf[offset++]; sum2 += adler;
4560 - adler += buf[offset++]; sum2 += adler;
4561 - adler += buf[offset++]; sum2 += adler;
4562 - } while (--n);
4563 - adler %= BASE;
4564 - sum2 %= BASE;
4565 - }
4566 -
4567 - /* do remaining bytes (less than NMAX, still just one modulo) */
4568 - if (len) { /* avoid modulos if none remaining */
4569 - while (len >= 16) {
4570 - len -= 16;
4571 - adler += buf[offset++]; sum2 += adler;
4572 - adler += buf[offset++]; sum2 += adler;
4573 - adler += buf[offset++]; sum2 += adler;
4574 - adler += buf[offset++]; sum2 += adler;
4575 - adler += buf[offset++]; sum2 += adler;
4576 - adler += buf[offset++]; sum2 += adler;
4577 - adler += buf[offset++]; sum2 += adler;
4578 - adler += buf[offset++]; sum2 += adler;
4579 - adler += buf[offset++]; sum2 += adler;
4580 - adler += buf[offset++]; sum2 += adler;
4581 - adler += buf[offset++]; sum2 += adler;
4582 - adler += buf[offset++]; sum2 += adler;
4583 - adler += buf[offset++]; sum2 += adler;
4584 - adler += buf[offset++]; sum2 += adler;
4585 - adler += buf[offset++]; sum2 += adler;
4586 - adler += buf[offset++]; sum2 += adler;
4587 - }
4588 - while (len--) {
4589 - adler += buf[offset++]; sum2 += adler;
4590 - }
4591 - adler %= BASE;
4592 - sum2 %= BASE;
4593 - }
4594 -
4595 - /* return recombined sums */
4596 - return adler | (sum2 << 16);
4597 -}
4598 -
4599 -/* ========================================================================= */
4600 -ZLIB.adler32 = function(adler, buf, offset, len)
4601 -{
4602 - if(typeof buf === 'string') {
4603 - return adler32_string(adler, buf, offset, len);
4604 - } else {
4605 - return adler32_array(adler, buf, offset, len);
4606 - }
4607 -};
4608 -
4609 -ZLIB.adler32_combine = function(adler1, adler2, len2)
4610 -{
4611 - var sum1;
4612 - var sum2;
4613 - var rem;
4614 -
4615 - /* for negative len, return invalid adler32 as a clue for debugging */
4616 - if (len2 < 0)
4617 - return 0xffffffff;
4618 -
4619 - /* the derivation of this formula is left as an exercise for the reader */
4620 - len2 %= BASE; /* assumes len2 >= 0 */
4621 - rem = len2;
4622 - sum1 = adler1 & 0xffff;
4623 - sum2 = rem * sum1;
4624 - sum2 %= BASE;
4625 - sum1 += (adler2 & 0xffff) + BASE - 1;
4626 - sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
4627 - if (sum1 >= BASE) sum1 -= BASE;
4628 - if (sum1 >= BASE) sum1 -= BASE;
4629 - if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1);
4630 - if (sum2 >= BASE) sum2 -= BASE;
4631 - return sum1 | (sum2 << 16);
4632 -}
4633 -
4634 -}());
4635 -/* zlib-adler32.js -- JavaScript implementation for the zlib crc32.
4636 - Version: 0.2.0
4637 - LastModified: Apr 12 2012
4638 - Copyright (C) 2012 Masanao Izumo <iz@onicos.co.jp>
4639 -
4640 - API documentation
4641 -==============================================================================
4642 -Usage: crc = ZLIB.crc32(crc, buf, offset, len);
4643 -
4644 - Update a running CRC-32 with the bytes buf[offset..offset+len-1] and return the
4645 - updated CRC-32. If buf is null, this function returns the required
4646 - initial value for the for the crc. Pre- and post-conditioning (one's
4647 - complement) is performed within this function so it shouldn't be done by the
4648 - application.
4649 -
4650 - Usage example:
4651 -
4652 - var crc = ZLIB.crc32(0, null, 0, 0);
4653 -
4654 - while (read_buffer(buffer, length) != EOF) {
4655 - crc = ZLIB.crc32(crc, buffer, 0, length);
4656 - }
4657 - if (crc != original_crc) error();
4658 -
4659 -==============================================================================
4660 -Usage: crc = crc32_combine(crc1, crc2, len2);
4661 -
4662 - Combine two CRC-32 check values into one. For two sequences of bytes,
4663 - seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
4664 - calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
4665 - check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
4666 - len2.
4667 -*/
4668 -
4669 -if( typeof ZLIB === 'undefined' ) {
4670 - alert('ZLIB is not defined. SRC zlib.js before zlib-crc32.js')
4671 -}
4672 -
4673 -(function() {
4674 -
4675 -/* crc32.c -- compute the CRC-32 of a data stream
4676 - * Copyright (C) 1995-2006, 2010, 2011 Mark Adler
4677 - * For conditions of distribution and use, see copyright notice in zlib.h
4678 - *
4679 - * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
4680 - * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
4681 - * tables for updating the shift register in one step with three exclusive-ors
4682 - * instead of four steps with four exclusive-ors. This results in about a
4683 - * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
4684 - */
4685 -
4686 -var crc_table = [
4687 - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
4688 - 0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
4689 - 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
4690 - 0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
4691 - 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
4692 - 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
4693 - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
4694 - 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
4695 - 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
4696 - 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
4697 - 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
4698 - 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
4699 - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
4700 - 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
4701 - 0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
4702 - 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
4703 - 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
4704 - 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
4705 - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
4706 - 0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
4707 - 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
4708 - 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
4709 - 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
4710 - 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
4711 - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
4712 - 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
4713 - 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
4714 - 0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
4715 - 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
4716 - 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
4717 - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
4718 - 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
4719 - 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
4720 - 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
4721 - 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
4722 - 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
4723 - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
4724 - 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
4725 - 0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
4726 - 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
4727 - 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
4728 - 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
4729 - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
4730 - 0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
4731 - 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
4732 - 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
4733 - 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
4734 - 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
4735 - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
4736 - 0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
4737 - 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
4738 - 0x2d02ef8d ];
4739 -
4740 -/* ========================================================================= */
4741 -function crc32_string(crc, buf, offset, len)
4742 -{
4743 - if (buf == null) return 0;
4744 -
4745 - crc = crc ^ 0xffffffff;
4746 - while (len >= 8) {
4747 - crc = crc_table[(crc ^ buf.charCodeAt(offset++)) & 0xff] ^ (crc >>> 8)
4748 - crc = crc_table[(crc ^ buf.charCodeAt(offset++)) & 0xff] ^ (crc >>> 8)
4749 - crc = crc_table[(crc ^ buf.charCodeAt(offset++)) & 0xff] ^ (crc >>> 8)
4750 - crc = crc_table[(crc ^ buf.charCodeAt(offset++)) & 0xff] ^ (crc >>> 8)
4751 - crc = crc_table[(crc ^ buf.charCodeAt(offset++)) & 0xff] ^ (crc >>> 8)
4752 - crc = crc_table[(crc ^ buf.charCodeAt(offset++)) & 0xff] ^ (crc >>> 8)
4753 - crc = crc_table[(crc ^ buf.charCodeAt(offset++)) & 0xff] ^ (crc >>> 8)
4754 - crc = crc_table[(crc ^ buf.charCodeAt(offset++)) & 0xff] ^ (crc >>> 8)
4755 - len -= 8;
4756 - }
4757 - if (len) do {
4758 - crc = crc_table[(crc ^ buf.charCodeAt(offset++)) & 0xff] ^ (crc >>> 8)
4759 - } while (--len);
4760 - return crc ^ 0xffffffff;
4761 -}
4762 -
4763 -/* ========================================================================= */
4764 -function crc32_array(crc, buf, offset, len)
4765 -{
4766 - if (buf == null) return 0;
4767 -
4768 - crc = crc ^ 0xffffffff;
4769 - while (len >= 8) {
4770 - crc = crc_table[(crc ^ buf[offset++]) & 0xff] ^ (crc >>> 8)
4771 - crc = crc_table[(crc ^ buf[offset++]) & 0xff] ^ (crc >>> 8)
4772 - crc = crc_table[(crc ^ buf[offset++]) & 0xff] ^ (crc >>> 8)
4773 - crc = crc_table[(crc ^ buf[offset++]) & 0xff] ^ (crc >>> 8)
4774 - crc = crc_table[(crc ^ buf[offset++]) & 0xff] ^ (crc >>> 8)
4775 - crc = crc_table[(crc ^ buf[offset++]) & 0xff] ^ (crc >>> 8)
4776 - crc = crc_table[(crc ^ buf[offset++]) & 0xff] ^ (crc >>> 8)
4777 - crc = crc_table[(crc ^ buf[offset++]) & 0xff] ^ (crc >>> 8)
4778 - len -= 8;
4779 - }
4780 - if (len) do {
4781 - crc = crc_table[(crc ^ buf[offset++]) & 0xff] ^ (crc >>> 8)
4782 - } while (--len);
4783 - return crc ^ 0xffffffff;
4784 -}
4785 -
4786 -/* ========================================================================= */
4787 -ZLIB.crc32 = function(crc, buf, offset, len)
4788 -{
4789 - if(typeof buf === 'string') {
4790 - return crc32_string(crc, buf, offset, len);
4791 - } else {
4792 - return crc32_array(crc, buf, offset, len);
4793 - }
4794 -};
4795 -
4796 -/* ========================================================================= */
4797 -var GF2_DIM = 32; /* dimension of GF(2) vectors (length of CRC) */
4798 -
4799 -/* ========================================================================= */
4800 -function gf2_matrix_times(mat, vec)
4801 -{
4802 - var sum;
4803 - var mat_i = 0;
4804 -
4805 - sum = 0;
4806 - while (vec) {
4807 - if (vec & 1)
4808 - sum ^= mat[mat_i];
4809 - vec >>= 1;
4810 - mat_i++;
4811 - }
4812 - return sum;
4813 -}
4814 -
4815 -/* ========================================================================= */
4816 -function gf2_matrix_square(square, mat)
4817 -{
4818 - var n;
4819 -
4820 - for (n = 0; n < GF2_DIM; n++)
4821 - square[n] = gf2_matrix_times(mat, mat[n]);
4822 -}
4823 -
4824 -/* ========================================================================= */
4825 -ZLIB.crc32_combine = function(crc1, crc2, len2)
4826 -{
4827 - var n;
4828 - var row;
4829 - var even; /* even-power-of-two zeros operator */
4830 - var odd; /* odd-power-of-two zeros operator */
4831 -
4832 - /* degenerate case (also disallow negative lengths) */
4833 - if (len2 <= 0)
4834 - return crc1;
4835 -
4836 - even = new Array(GF2_DIM);
4837 - odd = new Array(GF2_DIM);
4838 -
4839 - /* put operator for one zero bit in odd */
4840 - odd[0] = 0xedb88320; /* CRC-32 polynomial */
4841 - row = 1;
4842 - for (n = 1; n < GF2_DIM; n++) {
4843 - odd[n] = row;
4844 - row <<= 1;
4845 - }
4846 -
4847 - /* put operator for two zero bits in even */
4848 - gf2_matrix_square(even, odd);
4849 -
4850 - /* put operator for four zero bits in odd */
4851 - gf2_matrix_square(odd, even);
4852 -
4853 - /* apply len2 zeros to crc1 (first square will put the operator for one
4854 - zero byte, eight zero bits, in even) */
4855 - do {
4856 - /* apply zeros operator for this bit of len2 */
4857 - gf2_matrix_square(even, odd);
4858 - if (len2 & 1)
4859 - crc1 = gf2_matrix_times(even, crc1);
4860 - len2 >>= 1;
4861 -
4862 - /* if no more bits set, then done */
4863 - if (len2 == 0)
4864 - break;
4865 -
4866 - /* another iteration of the loop with odd and even swapped */
4867 - gf2_matrix_square(odd, even);
4868 - if (len2 & 1)
4869 - crc1 = gf2_matrix_times(odd, crc1);
4870 - len2 >>= 1;
4871 -
4872 - /* if no more bits set, then done */
4873 - } while (len2 != 0);
4874 -
4875 - /* return combined crc */
4876 - crc1 ^= crc2;
4877 - return crc1;
4878 -};
4879 -
4880 -}());
4881 -/**
4882 -* @description Intel AMT Redirection Transport Module - using websocket relay
4883 -* @author Ylian Saint-Hilaire
4884 -* @version v0.0.1f
4885 -*/
4886 -
4887 -// Construct a MeshServer object
4888 -var CreateAmtRedirect = function (module, authCookie) {
4889 - var obj = {};
4890 - obj.m = module; // This is the inner module (Terminal or Desktop)
4891 - module.parent = obj;
4892 - obj.authCookie = authCookie;
4893 - obj.State = 0;
4894 - obj.socket = null;
4895 - // ###BEGIN###{!Mode-Firmware}
4896 - obj.host = null;
4897 - obj.port = 0;
4898 - obj.user = null;
4899 - obj.pass = null;
4900 - obj.authuri = "/RedirectionService";
4901 - obj.tlsv1only = 0;
4902 - obj.inDataCount = 0;
4903 - // ###END###{!Mode-Firmware}
4904 - obj.connectstate = 0;
4905 - obj.protocol = module.protocol; // 1 = SOL, 2 = KVM, 3 = IDER
4906 - obj.debugmode = 0;
4907 -
4908 - obj.amtaccumulator = "";
4909 - obj.amtsequence = 1;
4910 - obj.amtkeepalivetimer = null;
4911 -
4912 - obj.onStateChanged = null;
4913 -
4914 - // Private method
4915 - //obj.Debug = function (msg) { console.log(msg); }
4916 -
4917 - obj.Start = function (host, port, user, pass, tls) {
4918 - obj.host = host;
4919 - obj.port = port;
4920 - obj.user = user;
4921 - obj.pass = pass;
4922 - obj.connectstate = 0;
4923 - obj.inDataCount = 0;
4924 - var url = window.location.protocol.replace("http", "ws") + "//" + window.location.host + window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) + "/webrelay.ashx?p=2&host=" + host + "&port=" + port + "&tls=" + tls + ((user == '*') ? "&serverauth=1" : "") + ((typeof pass === "undefined") ? ("&serverauth=1&user=" + user) : ""); // The "p=2" indicates to the relay that this is a REDIRECTION session
4925 - if ((authCookie != null) && (authCookie != '')) { url += '&auth=' + authCookie; }
4926 - obj.socket = new WebSocket(url);
4927 - obj.socket.onopen = obj.xxOnSocketConnected;
4928 - obj.socket.onmessage = obj.xxOnMessage;
4929 - obj.socket.onclose = obj.xxOnSocketClosed;
4930 - obj.xxStateChange(1);
4931 - }
4932 -
4933 - obj.xxOnSocketConnected = function () {
4934 - //obj.Debug("Redir Socket Connected");
4935 - if (obj.debugmode == 1) { console.log('onSocketConnected'); }
4936 - obj.xxStateChange(2);
4937 - if (obj.protocol == 1) obj.xxSend(obj.RedirectStartSol); // TODO: Put these strings in higher level module to tighten code
4938 - if (obj.protocol == 2) obj.xxSend(obj.RedirectStartKvm); // Don't need these is the feature is not compiled-in.
4939 - if (obj.protocol == 3) obj.xxSend(obj.RedirectStartIder);
4940 - }
4941 -
4942 - // Setup the file reader
4943 - var fileReader = new FileReader();
4944 - var fileReaderInuse = false, fileReaderAcc = [];
4945 - if (fileReader.readAsBinaryString) {
4946 - // Chrome & Firefox (Draft)
4947 - fileReader.onload = function (e) { obj.xxOnSocketData(e.target.result); if (fileReaderAcc.length == 0) { fileReaderInuse = false; } else { fileReader.readAsBinaryString(new Blob([fileReaderAcc.shift()])); } }
4948 - } else if (fileReader.readAsArrayBuffer) {
4949 - // Chrome & Firefox (Spec)
4950 - fileReader.onloadend = function (e) { obj.xxOnSocketData(e.target.result); if (fileReaderAcc.length == 0) { fileReaderInuse = false; } else { fileReader.readAsArrayBuffer(fileReaderAcc.shift()); } }
4951 - }
4952 -
4953 - obj.xxOnMessage = function (e) {
4954 - //if (obj.debugmode == 1) { console.log('Recv', e.data); }
4955 - obj.inDataCount++;
4956 - if (typeof e.data == 'object') {
4957 - if (fileReaderInuse == true) { fileReaderAcc.push(e.data); return; }
4958 - if (fileReader.readAsBinaryString) {
4959 - // Chrome & Firefox (Draft)
4960 - fileReaderInuse = true;
4961 - fileReader.readAsBinaryString(new Blob([e.data]));
4962 - } else if (f.readAsArrayBuffer) {
4963 - // Chrome & Firefox (Spec)
4964 - fileReaderInuse = true;
4965 - fileReader.readAsArrayBuffer(e.data);
4966 - } else {
4967 - // IE10, readAsBinaryString does not exist, use an alternative.
4968 - var binary = "", bytes = new Uint8Array(e.data), length = bytes.byteLength;
4969 - for (var i = 0; i < length; i++) { binary += String.fromCharCode(bytes[i]); }
4970 - obj.xxOnSocketData(binary);
4971 - }
4972 - } else {
4973 - // If we get a string object, it maybe the WebRTC confirm. Ignore it.
4974 - // obj.debug("MeshDataChannel - OnData - " + typeof e.data + " - " + e.data.length);
4975 - obj.xxOnSocketData(e.data);
4976 - }
4977 - };
4978 -
4979 - obj.xxOnSocketData = function (data) {
4980 - if (!data || obj.connectstate == -1) return;
4981 -
4982 - if (typeof data === 'object') {
4983 - // This is an ArrayBuffer, convert it to a string array (used in IE)
4984 - var binary = "";
4985 - var bytes = new Uint8Array(data);
4986 - var length = bytes.byteLength;
4987 - for (var i = 0; i < length; i++) { binary += String.fromCharCode(bytes[i]); }
4988 - data = binary;
4989 - }
4990 - else if (typeof data !== 'string') { return; }
4991 -
4992 - if ((obj.protocol == 2 || obj.protocol == 3) && obj.connectstate == 1) { return obj.m.ProcessData(data); } // KVM traffic, forward it directly.
4993 - obj.amtaccumulator += data;
4994 - //obj.Debug("Redir Recv(" + obj.amtaccumulator.length + "): " + rstr2hex(obj.amtaccumulator));
4995 - while (obj.amtaccumulator.length >= 1) {
4996 - var cmdsize = 0;
4997 - switch (obj.amtaccumulator.charCodeAt(0)) {
4998 - case 0x11: // StartRedirectionSessionReply (17)
4999 - if (obj.amtaccumulator.length < 4) return;

This file is too large to show in full.

views/default.handlebars
+15 -13
@@ -25,7 +25,7 @@
25 <script type="text/javascript" src="scripts/agent-redir-rtc-0.1.0.js"></script>
26 <script type="text/javascript" src="scripts/agent-desktop-0.0.2.js"></script>
27 <script type="text/javascript" src="scripts/qrcode.min.js"></script>
28 - <script type="text/javascript" src="scripts/u2f-api.js"></script>
28 + <script keeplink=1 type="text/javascript" src="scripts/u2f-api.js"></script>
29 <script keeplink=1 type="text/javascript" src="scripts/charts.js"></script>
30 <script keeplink=1 type="text/javascript" src="scripts/filesaver.1.1.20151003.js"></script>
31 <script keeplink=1 type="text/javascript" src="scripts/ol.js"></script>
@@ -754,8 +754,8 @@
754 <option value=2>Database</option>
755 </select>&nbsp;
756 <select id=p40time onchange=updateServerTimelineHours()>
757 - <option value=1>Last hour</option>
758 - <option value=4>Last 3 hours</option>
757 + <option value=3>Last 3 hours</option>
758 + <option value=8>Last 8 hours</option>
759 <option value=24>Last day</option>
760 <option value=168>Last week</option>
761 <option value=5040>Last 30 days</option>
@@ -1569,15 +1569,15 @@
1569 setDialogMode(2, "Add Security Key", 2, null, x);
1570
1571 var publicKey = message.request;
1572 - message.request.challenge = Uint8Array.from(atob(message.request.challenge), c => c.charCodeAt(0))
1573 - message.request.user.id = Uint8Array.from(atob(message.request.user.id), c => c.charCodeAt(0))
1574 - navigator.credentials.create({ publicKey })
1575 - .then((newCredentialInfo) => {
1572 + message.request.challenge = Uint8Array.from(atob(message.request.challenge), function (c) { return c.charCodeAt(0) })
1573 + message.request.user.id = Uint8Array.from(atob(message.request.user.id), function (c) { return c.charCodeAt(0) })
1574 + navigator.credentials.create({ publicKey: publicKey })
1575 + .then(function(newCredentialInfo) {
1576 // Public key credential
1577 var r = { rawId: btoa(String.fromCharCode.apply(null, new Uint8Array(newCredentialInfo.rawId))), response: { attestationObject: btoa(String.fromCharCode.apply(null, new Uint8Array(newCredentialInfo.response.attestationObject))), clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(newCredentialInfo.response.clientDataJSON))) }, type: newCredentialInfo.type };
1578 meshserver.send({ action: 'webauthn-endregister', response: r });
1579 setDialogMode(0);
1580 - }).catch((error) => {
1580 + }, function(error) {
1581 // Error
1582 setDialogMode(2, "Add Security Key", 1, null, "ERROR: " + error);
1583 });
@@ -7269,15 +7269,16 @@
7269 function refreshServerTimelineStats(stats) { meshserver.send({ action: 'servertimelinestats', hours: 24 }); }
7270 function pastDate(hours) { var t = new Date(); t.setTime(t.getTime() - (60 * 60 * 1000 * hours)); return t; }
7271 function setServerTimelineStats(stats) { serverTimelineStats = stats; updateServerTimelineStats(); }
7272 - function updateServerTimelineHours() { serverTimelineConfig.data.labels = [pastDate(0), pastDate(Q('p40time').value)]; window.serverMainStats.update(); }
7272 + function updateServerTimelineHours() { serverTimelineConfig.options.scales.xAxes[0].time = { min: pastDate(Q('p40time').value) }; window.serverMainStats.update(); }
7273 function setupServerTimelineStats() { window.serverMainStats = new Chart(document.getElementById('serverMainStats').getContext('2d'), serverTimelineConfig); }
7274
7275 function updateServerTimelineStats() {
7276 - var data, chartType = Q('p40type').value;
7276 + var data, chartType = Q('p40type').value, timeAfter = pastDate(Q('p40time').value);
7277 + serverTimelineConfig.options.scales.xAxes[0].time = { min: timeAfter };
7278 if (chartType == 0) { // Connections
7279 serverTimelineConfig.options.scales.yAxes[0].scaleLabel.labelString = 'Connection Count';
7280 data = {
7280 - labels: [pastDate(0), pastDate(Q('p40time').value)],
7281 + labels: [pastDate(0), timeAfter],
7282 datasets: [
7283 { label: 'Agents', data: [], backgroundColor: 'rgba(158, 151, 16, .1)', borderColor: 'rgb(158, 151, 16)', fill: true },
7284 { label: 'Users', data: [], backgroundColor: 'rgba(16, 84, 158, .1)', borderColor: 'rgb(16, 84, 158)', fill: true },
@@ -7287,6 +7288,7 @@
7288 ]
7289 };
7290 for (var i = 0; i < serverTimelineStats.length; i++) {
7291 + var t = new Date(serverTimelineStats[i].time);
7292 if (serverTimelineStats[i].conn) {
7293 data.datasets[0].data.push({ x: serverTimelineStats[i].time, y: serverTimelineStats[i].conn.ca });
7294 data.datasets[1].data.push({ x: serverTimelineStats[i].time, y: serverTimelineStats[i].conn.cu });
@@ -7298,7 +7300,7 @@
7300 } else if (chartType == 1) { // Memory
7301 serverTimelineConfig.options.scales.yAxes[0].scaleLabel.labelString = 'Megabytes';
7302 data = {
7301 - labels: [pastDate(0), pastDate(Q('p40time').value)],
7303 + labels: [pastDate(0), timeAfter],
7304 datasets: [
7305 { label: 'External', data: [], backgroundColor: 'rgba(158, 151, 16, .1)', borderColor: 'rgb(158, 151, 16)', fill: true },
7306 { label: 'Heap Used', data: [], backgroundColor: 'rgba(16, 84, 158, .1)', borderColor: 'rgb(16, 84, 158)', fill: true },
@@ -7315,7 +7317,7 @@
7317 } else if (chartType == 2) { // Database
7318 serverTimelineConfig.options.scales.yAxes[0].scaleLabel.labelString = 'Records';
7319 data = {
7318 - labels: [pastDate(0), pastDate(Q('p40time').value)],
7320 + labels: [pastDate(0), timeAfter],
7321 datasets: [
7322 { label: 'Groups', data: [], backgroundColor: 'rgba(158, 151, 16, .1)', borderColor: 'rgb(158, 151, 16)', fill: true },
7323 { label: 'Devices', data: [], backgroundColor: 'rgba(16, 84, 158, .1)', borderColor: 'rgb(16, 84, 158)', fill: true },
views/login-min.handlebars
+1 -1287
@@ -1,1287 +1 @@
1 -<!DOCTYPE html> <html dir="ltr" xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta content="text/html; charset=utf-8" http-equiv="Content-Type"> <meta name="viewport" content="user-scalable=1.0,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="format-detection" content="telephone=no"> <style> body{margin:0;padding:0;border:0;color:black;font-size:13px;font-family:"Trebuchet MS", Arial, Helvetica, sans-serif;background-color:#d3d9d6;}#container{background-color:#fff;margin:0 auto;border-top:0;border-right:1px solid #b7b7b7;border-bottom:0;border-left:1px solid #b7b7b7;padding:0;}#masthead{width:auto;margin:0;padding:0;overflow:auto;text-align:right;background-color:#036;}#column_l{position:relative;float:left;margin:0;padding:0 15px;background-color:#fff;}#footer{clear:both;overflow:auto;width:100%;text-align:center;background-color:#113962;padding-top:5px;padding-bottom:5px;}.style3{text-align:center;color:white;background-color:#808080;font-weight:bold;}#footer{clear:both;overflow:auto;width:100%;text-align:center;background-color:#113962;padding-top:5px;padding-bottom:5px;}#footer a{color:#fff;text-decoration:underline;}#footer a:hover{color:#fff;text-decoration:none;}a{color:#036;text-decoration:underline;}</style> <title>MeshCentral - Login</title> </head> <body onload="if (typeof(startup) !== 'undefined') startup();"> <div id="container" style="max-height:100vh"> <div id="mastheadx"></div> <div id="masthead" style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden"> <div style="float:left;height:66px;color:#c8c8c8;padding-left:20px;padding-top:8px"> <strong><font style="font-size:46px;font-family:Arial,Helvetica,sans-serif">{{{title}}}</font></strong> </div> <div style="float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px"> <strong><font style="font-size:14px;font-family:Arial,Helvetica,sans-serif">{{{title2}}}</font></strong> </div> </div> <div id="page_content" style="max-height:calc(100vh-108px)"> <div id="topbar" class="noselect style3" style="height:24px;position:relative"> <div title="Toggle full width" style="cursor:pointer;color:white;position:absolute;top:3px;right:6px" onclick="toggleFullScreen(1)">&harr;</div> </div> <div id="column_l"> <h1>Welcome</h1> <div id="welcomeText" style="display:none">Connect to your home or office devices from anywhere in the world using <a href="http://www.meshcommander.com/meshcentral2">MeshCentral</a>, the real time, open source remote monitoring and management web site. You will need to download and install a management agent on your computers. Once installed, computers will show up in the &quot;My Devices&quot; section of this web site and you will be able to monitor them and take control of them.</div> <table id="centralTable" style="width:100%"> <tr> <td id="welcomeimage" align="right" style="display:none"> <picture> <img alt="" width="359" height="310" src="welcome.jpg"> </picture> </td> <td id="logincell" align="left"> <div id="loginpanel" style="background-color:#979797;border-radius:16px;width:300px;padding:16px;text-align:center;display:none"> <form action="login" method="post"> <div id="message1"> {{{message}}} </div> <div> <b>Log In</b> </div> <table> <tr> <td align="right" width="100">Username:</td> <td><input id="username" type="text" maxlength="64" name="username" onchange="validateLogin(1)" onkeyup="validateLogin(1,event)"></td> </tr> <tr> <td align="right">Password:</td> <td><input id="password" type="password" maxlength="256" name="password" autocomplete="off" onchange="validateLogin(2)" onkeyup="validateLogin(2,event)"></td> </tr> <tr> <td><div id="showPassHintLink" style="display:none"><a onclick="showPassHint()" style="cursor:pointer">Show Hint</a></div></td> <td align="right"><input id="loginButton" type="submit" value="Log In" disabled="disabled"></td> </tr> </table> <div id="hrAccountDiv" style="display:none"><hr></div> <div id="resetAccountDiv" style="display:none;padding:2px"> Forgot username/password? <a onclick="xgo(3)" style="cursor:pointer">Reset account</a>. </div> <div id="newAccountDiv" style="display:none;padding:2px"> Don&#39;t have an account? <a onclick="xgo(2)" style="cursor:pointer">Create one</a>. </div> </form> </div> <div id="createpanel" style="position:relative;background-color:#979797;border-radius:16px;width:300px;padding:16px;text-align:center;display:none"> <form action="createaccount" method="post"> <div id="message2"> {{{message}}} </div> <div> <b>Account Creation</b> </div> <div id="passwordPolicyCallout" style="left:-10px;width:100px;display:none;position:absolute;background-color:#FFC;border-radius:5px;padding:5px;box-shadow:0px 0px 15px #666;font-size:10px"></div> <table> <tr> <td id="nuUser" align="right" width="100">Username:</td> <td><input id="ausername" type="text" name="username" onchange="validateCreate(1)" maxlength="64" onkeydown="haltReturn(event)" onkeyup="validateCreate(1,event)"></td> </tr> <tr> <td id="nuEmail" align="right" width="100">Email:</td> <td><input id="aemail" type="text" name="email" onchange="validateCreate(2)" maxlength="256" onkeydown="haltReturn(event)" onkeyup="validateCreate(2,event)"></td> </tr> <tr> <td id="nuPass1" align="right">Password:</td> <td><input id="apassword1" type="password" name="password1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(3,event)" onkeyup="validateCreate(3,event)"></td> </tr> <tr> <td id="nuPass2" align="right">Password:</td> <td><input id="apassword2" type="password" name="password2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(4,event)" onkeyup="validateCreate(4,event)"></td> </tr> <tr id="createPanelHint" style="display:none"> <td id="nuHint" align="right">Password Hint:</td> <td><input id="apasswordhint" type="text" name="apasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(5,event)" onkeyup="validateCreate(5,event)"></td> </tr> <tr id="newAccountPass" title="Enter the account creation token"> <td id="nuToken" align="right">Creation Token:</td> <td><input id="anewaccountpass" type="password" name="anewaccountpass" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(6,event)" onkeyup="validateCreate(6,event)"></td> </tr> <tr> <td colspan="2"> <div style="float:right"><input id="createButton" type="submit" value="Create Account" disabled="disabled"></div> <div id="passWarning" style="padding-top:6px"></div> </td> </tr> </table> <hr><a onclick="xgo(1)" style="cursor:pointer">Back to login</a> </form> </div> <div id="resetpanel" style="background-color:#979797;border-radius:16px;width:300px;padding:16px;text-align:center;display:none"> <form action="resetaccount" method="post"> <div id="message3"> {{{message}}} </div> <div> <b>Account Reset</b> </div> <table> <tr> <td align="right" width="100">Email:</td> <td><input id="remail" type="text" name="email" maxlength="256" onchange="validateReset()" onkeyup="validateReset(event)"></td> </tr> <tr> <td colspan="2"> <div style="float:right"><input id="eresetButton" type="submit" value="Reset Account" disabled="disabled"></div> <div id="passWarning" style="padding-top:6px"></div> </td> </tr> </table> <hr><a onclick="xgo(1)" style="cursor:pointer">Back to login</a> </form> </div> <div id="tokenpanel" style="background-color:#979797;border-radius:16px;width:300px;padding:16px;text-align:center;display:none"> <form action="tokenlogin" method="post" autocomplete="off"> <div id="message4"> {{{message}}} </div> <table> <tr> <td align="right" width="100">Login token:</td> <td> <input id="tokenInput" type="text" name="token" maxlength="50" onchange="checkToken(event)" onpaste="resetCheckToken(event)" onkeyup="checkToken(event)" onkeydown="checkToken(event)"> <input id="hwtokenInput" type="text" name="hwtoken" style="display:none"> </td> </tr> <tr> <td colspan="2"> <div style="float:right"><input id="tokenOkButton" type="submit" value="Login" disabled="disabled"></div> </td> </tr> </table> <hr><a onclick="xgo(1)" style="cursor:pointer">Back to login</a> </form> </div> <div id="resettokenpanel" style="background-color:#979797;border-radius:16px;width:300px;padding:16px;text-align:center;display:none"> <form action="resetaccount" method="post"> <div id="message5"> {{{message}}} </div> <table> <tr> <td align="right" width="100">Login token:</td> <td> <input id="resetTokenInput" type="text" name="token" maxlength="50" onchange="resetCheckToken(event)" onkeyup="resetCheckToken(event)" onkeydown="resetCheckToken(event)"> <input id="resetHwtokenInput" type="text" name="hwtoken" style="display:none"> </td> </tr> <tr> <td colspan="2"> <div style="float:right"><input id="resetTokenOkButton" type="submit" value="Login" disabled="disabled"></div> </td> </tr> </table> <hr><a onclick="xgo(1)" style="cursor:pointer">Back to login</a> </form> </div> <div id="resetpasswordpanel" style="position:relative;background-color:#979797;border-radius:16px;width:300px;padding:16px;text-align:center;display:none"> <form action="resetpassword" method="post"> <div id="message6"> {{{message}}} </div> <div id="rpasswordPolicyCallout" style="left:-10px;width:100px;display:none;position:absolute;background-color:#FFC;border-radius:5px;padding:5px;box-shadow:0px 0px 15px #666;font-size:10px"></div> <table> <tr> <td id="rnuPass1" width="100" align="right">Password:</td> <td><input id="rapassword1" type="password" name="rpassword1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(3,event)" onkeyup="validatePassReset(3,event)"></td> </tr> <tr> <td id="rnuPass2" align="right">Password:</td> <td><input id="rapassword2" type="password" name="rpassword2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(4,event)" onkeyup="validatePassReset(4,event)"></td> </tr> <tr id="resetpasswordpanelHint" style="display:none"> <td id="rnuHint" align="right">Password Hint:</td> <td><input id="rapasswordhint" type="text" name="rpasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(5,event)" onkeyup="validatePassReset(5,event)"></td> </tr> <tr> <td colspan="2"> <div style="float:right"><input id="resetPassButton" type="submit" value="Reset Password" disabled="disabled"></div> <div id="rpassWarning" style="padding-top:6px"></div> </td> </tr> </table> <hr><a onclick="xgo(1)" style="cursor:pointer">Back to login</a> </form> </div> </td> </tr> </table> <br> </div> <div id="footer"> <table cellpadding="0" cellspacing="10" style="width:100%"> <tr> <td style="text-align:left;color:white"> {{{footer}}} </td> <td style="text-align:right"> {{{rootCertLink}}} &nbsp;<a href="terms">Terms &amp; Privacy</a> </td> </tr> </table> </div> </div> </div> <div id="dialog" style="z-index:1000;background-color:#EEE;box-shadow:0px 0px 15px #666;font-family:Arial,Helvetica,sans-serif;border-radius:5px;position:fixed;top:180px;width:400px;display:none"> <div style="width:100%;background-color:#003366;color:#FFF;border-radius:5px 5px 0 0"> <div id="id_dialogclose" style="float:right;padding:5px;cursor:pointer" onclick="setDialogMode()"><b>X</b></div> <div id="id_dialogtitle" style="padding:5px"></div> <div style="width:100%;margin:6px"></div> </div> <div style="margin-right:16px;margin-left:8px"> <div id="dialog1" style="margin:auto;text-align:center;margin:3px"> <div id="id_dialogMessage" style="padding:10px"></div> </div> <div id="dialog2" style="margin:auto;margin:3px"> <div id="id_dialogOptions"></div> </div> </div> <div id="idx_dlgButtonBar" style="padding:10px;margin-bottom:20px"> <input id="idx_dlgCancelButton" type="button" value="Cancel" style="float:right;width:80px;margin-left:5px" onclick="dialogclose(0)"> <input id="idx_dlgOkButton" type="button" value="OK" style="float:right;width:80px" onclick="dialogclose(1)"> </div> </div> <script>/**
2 -* @description Set of short commonly used methods for handling HTML elements
3 -* @author Ylian Saint-Hilaire
4 -* @version v0.0.1b
5 -*/
6 -
7 -// Add startsWith for IE browser
8 -if (!String.prototype.startsWith) { String.prototype.startsWith = function (str) { return this.lastIndexOf(str, 0) === 0; }; }
9 -if (!String.prototype.endsWith) { String.prototype.endsWith = function (str) { return this.indexOf(str, this.length - str.length) !== -1; }; }
10 -
11 -// Quick UI functions, a bit of a replacement for jQuery
12 -//function Q(x) { if (document.getElementById(x) == null) { console.log('Invalid element: ' + x); } return document.getElementById(x); } // "Q"
13 -function Q(x) { return document.getElementById(x); } // "Q"
14 -function QS(x) { try { return Q(x).style; } catch (x) { } } // "Q" style
15 -function QE(x, y) { try { Q(x).disabled = !y; } catch (x) { } } // "Q" enable
16 -function QV(x, y) { try { QS(x).display = (y ? '' : 'none'); } catch (x) { } } // "Q" visible
17 -function QA(x, y) { Q(x).innerHTML += y; } // "Q" append
18 -function QH(x, y) { Q(x).innerHTML = y; } // "Q" html
19 -
20 -// Move cursor to end of input box
21 -function inputBoxFocus(x) { Q(x).focus(); var v = Q(x).value; Q(x).value = ''; Q(x).value = v; }
22 -
23 -// Binary encoding and decoding functions
24 -function ReadShort(v, p) { return (v.charCodeAt(p) << 8) + v.charCodeAt(p + 1); }
25 -function ReadShortX(v, p) { return (v.charCodeAt(p + 1) << 8) + v.charCodeAt(p); }
26 -function ReadInt(v, p) { return (v.charCodeAt(p) * 0x1000000) + (v.charCodeAt(p + 1) << 16) + (v.charCodeAt(p + 2) << 8) + v.charCodeAt(p + 3); } // We use "*0x1000000" instead of "<<24" because the shift converts the number to signed int32.
27 -function ReadSInt(v, p) { return (v.charCodeAt(p) << 24) + (v.charCodeAt(p + 1) << 16) + (v.charCodeAt(p + 2) << 8) + v.charCodeAt(p + 3); }
28 -function ReadIntX(v, p) { return (v.charCodeAt(p + 3) * 0x1000000) + (v.charCodeAt(p + 2) << 16) + (v.charCodeAt(p + 1) << 8) + v.charCodeAt(p); }
29 -function ShortToStr(v) { return String.fromCharCode((v >> 8) & 0xFF, v & 0xFF); }
30 -function ShortToStrX(v) { return String.fromCharCode(v & 0xFF, (v >> 8) & 0xFF); }
31 -function IntToStr(v) { return String.fromCharCode((v >> 24) & 0xFF, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF); }
32 -function IntToStrX(v) { return String.fromCharCode(v & 0xFF, (v >> 8) & 0xFF, (v >> 16) & 0xFF, (v >> 24) & 0xFF); }
33 -function MakeToArray(v) { if (!v || v == null || typeof v == 'object') return v; return [v]; }
34 -function SplitArray(v) { return v.split(','); }
35 -function Clone(v) { return JSON.parse(JSON.stringify(v)); }
36 -function EscapeHtml(x) { if (typeof x == "string") return x.replace(/&/g, '&amp;').replace(/>/g, '&gt;').replace(/</g, '&lt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;'); if (typeof x == "boolean") return x; if (typeof x == "number") return x; }
37 -function EscapeHtmlBreaks(x) { if (typeof x == "string") return x.replace(/&/g, '&amp;').replace(/>/g, '&gt;').replace(/</g, '&lt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;').replace(/\r/g, '<br />').replace(/\n/g, '').replace(/\t/g, '&nbsp;&nbsp;'); if (typeof x == "boolean") return x; if (typeof x == "number") return x; }
38 -
39 -// Move an element from one position in an array to a new position
40 -function ArrayElementMove(arr, from, to) { arr.splice(to, 0, arr.splice(from, 1)[0]); };
41 -
42 -// Print object for HTML
43 -function ObjectToStringEx(x, c) {
44 - var r = "";
45 - if (x != 0 && (!x || x == null)) return "(Null)";
46 - if (x instanceof Array) { for (var i in x) { r += '<br />' + gap(c) + "Item #" + i + ": " + ObjectToStringEx(x[i], c + 1); } }
47 - else if (x instanceof Object) { for (var i in x) { r += '<br />' + gap(c) + i + " = " + ObjectToStringEx(x[i], c + 1); } }
48 - else { r += EscapeHtml(x); }
49 - return r;
50 -}
51 -
52 -// Print object for console
53 -function ObjectToStringEx2(x, c) {
54 - var r = "";
55 - if (x != 0 && (!x || x == null)) return "(Null)";
56 - if (x instanceof Array) { for (var i in x) { r += '\r\n' + gap2(c) + "Item #" + i + ": " + ObjectToStringEx2(x[i], c + 1); } }
57 - else if (x instanceof Object) { for (var i in x) { r += '\r\n' + gap2(c) + i + " = " + ObjectToStringEx2(x[i], c + 1); } }
58 - else { r += EscapeHtml(x); }
59 - return r;
60 -}
61 -
62 -// Create an ident gap
63 -function gap(c) { var x = ''; for (var i = 0; i < (c * 4) ; i++) { x += '&nbsp;'; } return x; }
64 -function gap2(c) { var x = ''; for (var i = 0; i < (c * 4) ; i++) { x += ' '; } return x; }
65 -
66 -// Print an object in html
67 -function ObjectToString(x) { return ObjectToStringEx(x, 0); }
68 -function ObjectToString2(x) { return ObjectToStringEx2(x, 0); }
69 -
70 -// Convert a hex string to a raw string
71 -function hex2rstr(d) {
72 - if (typeof d != "string" || d.length == 0) return '';
73 - var r = '', m = ('' + d).match(/../g), t;
74 - while (t = m.shift()) r += String.fromCharCode('0x' + t);
75 - return r
76 -}
77 -
78 -// Convert decimal to hex
79 -function char2hex(i) { return (i + 0x100).toString(16).substr(-2).toUpperCase(); }
80 -
81 -// Convert a raw string to a hex string
82 -function rstr2hex(input) { var r = '', i; for (i = 0; i < input.length; i++) { r += char2hex(input.charCodeAt(i)); } return r; }
83 -
84 -// UTF-8 encoding & decoding functions
85 -function encode_utf8(s) { return unescape(encodeURIComponent(s)); }
86 -function decode_utf8(s) { return decodeURIComponent(escape(s)); }
87 -
88 -// Convert a string into a blob
89 -function data2blob(data) {
90 - var bytes = new Array(data.length);
91 - for (var i = 0; i < data.length; i++) bytes[i] = data.charCodeAt(i);
92 - var blob = new Blob([new Uint8Array(bytes)]);
93 - return blob;
94 -}
95 -
96 -// Generate random numbers
97 -function random(max) { return Math.floor(Math.random() * max); }
98 -
99 -// Trademarks
100 -function trademarks(x) { return x.replace(/\(R\)/g, '&reg;').replace(/\(TM\)/g, '&trade;'); }
101 -//Copyright 2014-2015 Google Inc. All rights reserved.
102 -
103 -//Use of this source code is governed by a BSD-style
104 -//license that can be found in the LICENSE file or at
105 -//https://developers.google.com/open-source/licenses/bsd
106 -
107 -/**
108 - * @fileoverview The U2F api.
109 - */
110 -'use strict';
111 -if (!window.u2f) {
112 -
113 - /**
114 - * Namespace for the U2F api.
115 - * @type {Object}
116 - */
117 -var u2f = u2f || {};
118 -
119 - /**
120 - * FIDO U2F Javascript API Version
121 - * @number
122 - */
123 -var js_api_version;
124 -
125 - /**
126 - * The U2F extension id
127 - * @const {string}
128 - */
129 -// The Chrome packaged app extension ID.
130 -// Uncomment this if you want to deploy a server instance that uses
131 -// the package Chrome app and does not require installing the U2F Chrome extension.
132 - u2f.EXTENSION_ID = 'kmendfapggjehodndflmmgagdbamhnfd';
133 - // The U2F Chrome extension ID.
134 - // Uncomment this if you want to deploy a server instance that uses
135 - // the U2F Chrome extension to authenticate.
136 - // u2f.EXTENSION_ID = 'pfboblefjcgdjicmnffhdgionmgcdmne';
137 -
138 -
139 - /**
140 - * Message types for messsages to/from the extension
141 - * @const
142 - * @enum {string}
143 - */
144 -u2f.MessageTypes = {
145 - 'U2F_REGISTER_REQUEST': 'u2f_register_request',
146 - 'U2F_REGISTER_RESPONSE': 'u2f_register_response',
147 - 'U2F_SIGN_REQUEST': 'u2f_sign_request',
148 - 'U2F_SIGN_RESPONSE': 'u2f_sign_response',
149 - 'U2F_GET_API_VERSION_REQUEST': 'u2f_get_api_version_request',
150 - 'U2F_GET_API_VERSION_RESPONSE': 'u2f_get_api_version_response'
151 - };
152 -
153 -
154 - /**
155 - * Response status codes
156 - * @const
157 - * @enum {number}
158 - */
159 -u2f.ErrorCodes = {
160 - 'OK': 0,
161 - 'OTHER_ERROR': 1,
162 - 'BAD_REQUEST': 2,
163 - 'CONFIGURATION_UNSUPPORTED': 3,
164 - 'DEVICE_INELIGIBLE': 4,
165 - 'TIMEOUT': 5
166 - };
167 -
168 -
169 - /**
170 - * A message for registration requests
171 - * @typedef {{
172 - * type: u2f.MessageTypes,
173 - * appId: ?string,
174 - * timeoutSeconds: ?number,
175 - * requestId: ?number
176 - * }}
177 - */
178 -u2f.U2fRequest;
179 -
180 -
181 - /**
182 - * A message for registration responses
183 - * @typedef {{
184 - * type: u2f.MessageTypes,
185 - * responseData: (u2f.Error | u2f.RegisterResponse | u2f.SignResponse),
186 - * requestId: ?number
187 - * }}
188 - */
189 -u2f.U2fResponse;
190 -
191 -
192 - /**
193 - * An error object for responses
194 - * @typedef {{
195 - * errorCode: u2f.ErrorCodes,
196 - * errorMessage: ?string
197 - * }}
198 - */
199 -u2f.Error;
200 -
201 - /**
202 - * Data object for a single sign request.
203 - * @typedef {enum {BLUETOOTH_RADIO, BLUETOOTH_LOW_ENERGY, USB, NFC}}
204 - */
205 -u2f.Transport;
206 -
207 -
208 - /**
209 - * Data object for a single sign request.
210 - * @typedef {Array<u2f.Transport>}
211 - */
212 -u2f.Transports;
213 -
214 - /**
215 - * Data object for a single sign request.
216 - * @typedef {{
217 - * version: string,
218 - * challenge: string,
219 - * keyHandle: string,
220 - * appId: string
221 - * }}
222 - */
223 -u2f.SignRequest;
224 -
225 -
226 - /**
227 - * Data object for a sign response.
228 - * @typedef {{
229 - * keyHandle: string,
230 - * signatureData: string,
231 - * clientData: string
232 - * }}
233 - */
234 -u2f.SignResponse;
235 -
236 -
237 - /**
238 - * Data object for a registration request.
239 - * @typedef {{
240 - * version: string,
241 - * challenge: string
242 - * }}
243 - */
244 -u2f.RegisterRequest;
245 -
246 -
247 - /**
248 - * Data object for a registration response.
249 - * @typedef {{
250 - * version: string,
251 - * keyHandle: string,
252 - * transports: Transports,
253 - * appId: string
254 - * }}
255 - */
256 -u2f.RegisterResponse;
257 -
258 -
259 - /**
260 - * Data object for a registered key.
261 - * @typedef {{
262 - * version: string,
263 - * keyHandle: string,
264 - * transports: ?Transports,
265 - * appId: ?string
266 - * }}
267 - */
268 -u2f.RegisteredKey;
269 -
270 -
271 - /**
272 - * Data object for a get API register response.
273 - * @typedef {{
274 - * js_api_version: number
275 - * }}
276 - */
277 -u2f.GetJsApiVersionResponse;
278 -
279 -
280 - //Low level MessagePort API support
281 -
282 - /**
283 - * Sets up a MessagePort to the U2F extension using the
284 - * available mechanisms.
285 - * @param {function((MessagePort|u2f.WrappedChromeRuntimePort_))} callback
286 - */
287 -u2f.getMessagePort = function (callback) {
288 - if (typeof chrome != 'undefined' && chrome.runtime) {
289 - // The actual message here does not matter, but we need to get a reply
290 - // for the callback to run. Thus, send an empty signature request
291 - // in order to get a failure response.
292 - var msg = {
293 - type: u2f.MessageTypes.U2F_SIGN_REQUEST,
294 - signRequests: []
295 - };
296 - chrome.runtime.sendMessage(u2f.EXTENSION_ID, msg, function () {
297 - if (!chrome.runtime.lastError) {
298 - // We are on a whitelisted origin and can talk directly
299 - // with the extension.
300 - u2f.getChromeRuntimePort_(callback);
301 - } else {
302 - // chrome.runtime was available, but we couldn't message
303 - // the extension directly, use iframe
304 - u2f.getIframePort_(callback);
305 - }
306 - });
307 - } else if (u2f.isAndroidChrome_()) {
308 - u2f.getAuthenticatorPort_(callback);
309 - } else if (u2f.isIosChrome_()) {
310 - u2f.getIosPort_(callback);
311 - } else {
312 - // chrome.runtime was not available at all, which is normal
313 - // when this origin doesn't have access to any extensions.
314 - u2f.getIframePort_(callback);
315 - }
316 - };
317 -
318 - /**
319 - * Detect chrome running on android based on the browser's useragent.
320 - * @private
321 - */
322 -u2f.isAndroidChrome_ = function () {
323 - var userAgent = navigator.userAgent;
324 - return userAgent.indexOf('Chrome') != -1 &&
325 - userAgent.indexOf('Android') != -1;
326 - };
327 -
328 - /**
329 - * Detect chrome running on iOS based on the browser's platform.
330 - * @private
331 - */
332 -u2f.isIosChrome_ = function () {
333 - var r = ["iPhone", "iPad", "iPod"];
334 - for (var i in r) { if (navigator.platform == r[i]) { return true; } }
335 - return false;
336 - //return $.inArray(navigator.platform, ["iPhone", "iPad", "iPod"]) > -1;
337 - };
338 -
339 - /**
340 - * Connects directly to the extension via chrome.runtime.connect.
341 - * @param {function(u2f.WrappedChromeRuntimePort_)} callback
342 - * @private
343 - */
344 -u2f.getChromeRuntimePort_ = function (callback) {
345 - var port = chrome.runtime.connect(u2f.EXTENSION_ID,
346 - { 'includeTlsChannelId': true });
347 - setTimeout(function () {
348 - callback(new u2f.WrappedChromeRuntimePort_(port));
349 - }, 0);
350 - };
351 -
352 - /**
353 - * Return a 'port' abstraction to the Authenticator app.
354 - * @param {function(u2f.WrappedAuthenticatorPort_)} callback
355 - * @private
356 - */
357 -u2f.getAuthenticatorPort_ = function (callback) {
358 - setTimeout(function () {
359 - callback(new u2f.WrappedAuthenticatorPort_());
360 - }, 0);
361 - };
362 -
363 - /**
364 - * Return a 'port' abstraction to the iOS client app.
365 - * @param {function(u2f.WrappedIosPort_)} callback
366 - * @private
367 - */
368 -u2f.getIosPort_ = function (callback) {
369 - setTimeout(function () {
370 - callback(new u2f.WrappedIosPort_());
371 - }, 0);
372 - };
373 -
374 - /**
375 - * A wrapper for chrome.runtime.Port that is compatible with MessagePort.
376 - * @param {Port} port
377 - * @constructor
378 - * @private
379 - */
380 -u2f.WrappedChromeRuntimePort_ = function (port) {
381 - this.port_ = port;
382 - };
383 -
384 - /**
385 - * Format and return a sign request compliant with the JS API version supported by the extension.
386 - * @param {Array<u2f.SignRequest>} signRequests
387 - * @param {number} timeoutSeconds
388 - * @param {number} reqId
389 - * @return {Object}
390 - */
391 -u2f.formatSignRequest_ =
392 - function (appId, challenge, registeredKeys, timeoutSeconds, reqId) {
393 - if (js_api_version === undefined || js_api_version < 1.1) {
394 - // Adapt request to the 1.0 JS API
395 - var signRequests = [];
396 - for (var i = 0; i < registeredKeys.length; i++) {
397 - signRequests[i] = {
398 - version: registeredKeys[i].version,
399 - challenge: challenge,
400 - keyHandle: registeredKeys[i].keyHandle,
401 - appId: appId
402 - };
403 - }
404 - return {
405 - type: u2f.MessageTypes.U2F_SIGN_REQUEST,
406 - signRequests: signRequests,
407 - timeoutSeconds: timeoutSeconds,
408 - requestId: reqId
409 - };
410 - }
411 - // JS 1.1 API
412 - return {
413 - type: u2f.MessageTypes.U2F_SIGN_REQUEST,
414 - appId: appId,
415 - challenge: challenge,
416 - registeredKeys: registeredKeys,
417 - timeoutSeconds: timeoutSeconds,
418 - requestId: reqId
419 - };
420 - };
421 -
422 - /**
423 - * Format and return a register request compliant with the JS API version supported by the extension..
424 - * @param {Array<u2f.SignRequest>} signRequests
425 - * @param {Array<u2f.RegisterRequest>} signRequests
426 - * @param {number} timeoutSeconds
427 - * @param {number} reqId
428 - * @return {Object}
429 - */
430 -u2f.formatRegisterRequest_ =
431 - function (appId, registeredKeys, registerRequests, timeoutSeconds, reqId) {
432 - if (js_api_version === undefined || js_api_version < 1.1) {
433 - // Adapt request to the 1.0 JS API
434 - for (var i = 0; i < registerRequests.length; i++) {
435 - registerRequests[i].appId = appId;
436 - }
437 - var signRequests = [];
438 - for (var i = 0; i < registeredKeys.length; i++) {
439 - signRequests[i] = {
440 - version: registeredKeys[i].version,
441 - challenge: registerRequests[0],
442 - keyHandle: registeredKeys[i].keyHandle,
443 - appId: appId
444 - };
445 - }
446 - return {
447 - type: u2f.MessageTypes.U2F_REGISTER_REQUEST,
448 - signRequests: signRequests,
449 - registerRequests: registerRequests,
450 - timeoutSeconds: timeoutSeconds,
451 - requestId: reqId
452 - };
453 - }
454 - // JS 1.1 API
455 - return {
456 - type: u2f.MessageTypes.U2F_REGISTER_REQUEST,
457 - appId: appId,
458 - registerRequests: registerRequests,
459 - registeredKeys: registeredKeys,
460 - timeoutSeconds: timeoutSeconds,
461 - requestId: reqId
462 - };
463 - };
464 -
465 -
466 - /**
467 - * Posts a message on the underlying channel.
468 - * @param {Object} message
469 - */
470 -u2f.WrappedChromeRuntimePort_.prototype.postMessage = function (message) {
471 - this.port_.postMessage(message);
472 - };
473 -
474 -
475 - /**
476 - * Emulates the HTML 5 addEventListener interface. Works only for the
477 - * onmessage event, which is hooked up to the chrome.runtime.Port.onMessage.
478 - * @param {string} eventName
479 - * @param {function({data: Object})} handler
480 - */
481 -u2f.WrappedChromeRuntimePort_.prototype.addEventListener =
482 - function (eventName, handler) {
483 - var name = eventName.toLowerCase();
484 - if (name == 'message' || name == 'onmessage') {
485 - this.port_.onMessage.addListener(function (message) {
486 - // Emulate a minimal MessageEvent object
487 - handler({ 'data': message });
488 - });
489 - } else {
490 - console.error('WrappedChromeRuntimePort only supports onMessage');
491 - }
492 - };
493 -
494 - /**
495 - * Wrap the Authenticator app with a MessagePort interface.
496 - * @constructor
497 - * @private
498 - */
499 -u2f.WrappedAuthenticatorPort_ = function () {
500 - this.requestId_ = -1;
501 - this.requestObject_ = null;
502 - }
503 -
504 - /**
505 - * Launch the Authenticator intent.
506 - * @param {Object} message
507 - */
508 -u2f.WrappedAuthenticatorPort_.prototype.postMessage = function (message) {
509 - var intentUrl =
510 - u2f.WrappedAuthenticatorPort_.INTENT_URL_BASE_ +
511 - ';S.request=' + encodeURIComponent(JSON.stringify(message)) +
512 - ';end';
513 - document.location = intentUrl;
514 - };
515 -
516 - /**
517 - * Tells what type of port this is.
518 - * @return {String} port type
519 - */
520 -u2f.WrappedAuthenticatorPort_.prototype.getPortType = function () {
521 - return "WrappedAuthenticatorPort_";
522 - };
523 -
524 -
525 - /**
526 - * Emulates the HTML 5 addEventListener interface.
527 - * @param {string} eventName
528 - * @param {function({data: Object})} handler
529 - */
530 -u2f.WrappedAuthenticatorPort_.prototype.addEventListener = function (eventName, handler) {
531 - var name = eventName.toLowerCase();
532 - if (name == 'message') {
533 - var self = this;
534 - /* Register a callback to that executes when
535 - * chrome injects the response. */
536 - window.addEventListener(
537 - 'message', self.onRequestUpdate_.bind(self, handler), false);
538 - } else {
539 - console.error('WrappedAuthenticatorPort only supports message');
540 - }
541 - };
542 -
543 - /**
544 - * Callback invoked when a response is received from the Authenticator.
545 - * @param function({data: Object}) callback
546 - * @param {Object} message message Object
547 - */
548 -u2f.WrappedAuthenticatorPort_.prototype.onRequestUpdate_ =
549 - function (callback, message) {
550 - var messageObject = JSON.parse(message.data);
551 - var intentUrl = messageObject['intentURL'];
552 -
553 - var errorCode = messageObject['errorCode'];
554 - var responseObject = null;
555 - if (messageObject.hasOwnProperty('data')) {
556 - responseObject = /** @type {Object} */ (
557 - JSON.parse(messageObject['data']));
558 - }
559 -
560 - callback({ 'data': responseObject });
561 - };
562 -
563 - /**
564 - * Base URL for intents to Authenticator.
565 - * @const
566 - * @private
567 - */
568 -u2f.WrappedAuthenticatorPort_.INTENT_URL_BASE_ =
569 - 'intent:#Intent;action=com.google.android.apps.authenticator.AUTHENTICATE';
570 -
571 - /**
572 - * Wrap the iOS client app with a MessagePort interface.
573 - * @constructor
574 - * @private
575 - */
576 -u2f.WrappedIosPort_ = function () { };
577 -
578 - /**
579 - * Launch the iOS client app request
580 - * @param {Object} message
581 - */
582 -u2f.WrappedIosPort_.prototype.postMessage = function (message) {
583 - var str = JSON.stringify(message);
584 - var url = "u2f://auth?" + encodeURI(str);
585 - location.replace(url);
586 - };
587 -
588 - /**
589 - * Tells what type of port this is.
590 - * @return {String} port type
591 - */
592 -u2f.WrappedIosPort_.prototype.getPortType = function () {
593 - return "WrappedIosPort_";
594 - };
595 -
596 - /**
597 - * Emulates the HTML 5 addEventListener interface.
598 - * @param {string} eventName
599 - * @param {function({data: Object})} handler
600 - */
601 -u2f.WrappedIosPort_.prototype.addEventListener = function (eventName, handler) {
602 - var name = eventName.toLowerCase();
603 - if (name !== 'message') {
604 - console.error('WrappedIosPort only supports message');
605 - }
606 - };
607 -
608 - /**
609 - * Sets up an embedded trampoline iframe, sourced from the extension.
610 - * @param {function(MessagePort)} callback
611 - * @private
612 - */
613 -u2f.getIframePort_ = function (callback) {
614 - // Create the iframe
615 - var iframeOrigin = 'chrome-extension://' + u2f.EXTENSION_ID;
616 - var iframe = document.createElement('iframe');
617 - iframe.src = iframeOrigin + '/u2f-comms.html';
618 - iframe.setAttribute('style', 'display:none');
619 - document.body.appendChild(iframe);
620 -
621 - var channel = new MessageChannel();
622 - var ready = function (message) {
623 - if (message.data == 'ready') {
624 - channel.port1.removeEventListener('message', ready);
625 - callback(channel.port1);
626 - } else {
627 - console.error('First event on iframe port was not "ready"');
628 - }
629 - };
630 - channel.port1.addEventListener('message', ready);
631 - channel.port1.start();
632 -
633 - iframe.addEventListener('load', function () {
634 - // Deliver the port to the iframe and initialize
635 - iframe.contentWindow.postMessage('init', iframeOrigin, [channel.port2]);
636 - });
637 - };
638 -
639 -
640 - //High-level JS API
641 -
642 - /**
643 - * Default extension response timeout in seconds.
644 - * @const
645 - */
646 -u2f.EXTENSION_TIMEOUT_SEC = 30;
647 -
648 - /**
649 - * A singleton instance for a MessagePort to the extension.
650 - * @type {MessagePort|u2f.WrappedChromeRuntimePort_}
651 - * @private
652 - */
653 -u2f.port_ = null;
654 -
655 - /**
656 - * Callbacks waiting for a port
657 - * @type {Array<function((MessagePort|u2f.WrappedChromeRuntimePort_))>}
658 - * @private
659 - */
660 -u2f.waitingForPort_ = [];
661 -
662 - /**
663 - * A counter for requestIds.
664 - * @type {number}
665 - * @private
666 - */
667 -u2f.reqCounter_ = 0;
668 -
669 - /**
670 - * A map from requestIds to client callbacks
671 - * @type {Object.<number,(function((u2f.Error|u2f.RegisterResponse))
672 - * |function((u2f.Error|u2f.SignResponse)))>}
673 - * @private
674 - */
675 -u2f.callbackMap_ = {};
676 -
677 - /**
678 - * Creates or retrieves the MessagePort singleton to use.
679 - * @param {function((MessagePort|u2f.WrappedChromeRuntimePort_))} callback
680 - * @private
681 - */
682 -u2f.getPortSingleton_ = function (callback) {
683 - if (u2f.port_) {
684 - callback(u2f.port_);
685 - } else {
686 - if (u2f.waitingForPort_.length == 0) {
687 - u2f.getMessagePort(function (port) {
688 - u2f.port_ = port;
689 - u2f.port_.addEventListener('message',
690 - /** @type {function(Event)} */ (u2f.responseHandler_));
691 -
692 - // Careful, here be async callbacks. Maybe.
693 - while (u2f.waitingForPort_.length)
694 - u2f.waitingForPort_.shift()(u2f.port_);
695 - });
696 - }
697 - u2f.waitingForPort_.push(callback);
698 - }
699 - };
700 -
701 - /**
702 - * Handles response messages from the extension.
703 - * @param {MessageEvent.<u2f.Response>} message
704 - * @private
705 - */
706 -u2f.responseHandler_ = function (message) {
707 - var response = message.data;
708 - var reqId = response['requestId'];
709 - if (!reqId || !u2f.callbackMap_[reqId]) {
710 - console.error('Unknown or missing requestId in response.');
711 - return;
712 - }
713 - var cb = u2f.callbackMap_[reqId];
714 - delete u2f.callbackMap_[reqId];
715 - cb(response['responseData']);
716 - };
717 -
718 - /**
719 - * Dispatches an array of sign requests to available U2F tokens.
720 - * If the JS API version supported by the extension is unknown, it first sends a
721 - * message to the extension to find out the supported API version and then it sends
722 - * the sign request.
723 - * @param {string=} appId
724 - * @param {string=} challenge
725 - * @param {Array<u2f.RegisteredKey>} registeredKeys
726 - * @param {function((u2f.Error|u2f.SignResponse))} callback
727 - * @param {number=} opt_timeoutSeconds
728 - */
729 -u2f.sign = function (appId, challenge, registeredKeys, callback, opt_timeoutSeconds) {
730 - if (js_api_version === undefined) {
731 - // Send a message to get the extension to JS API version, then send the actual sign request.
732 - u2f.getApiVersion(
733 - function (response) {
734 - js_api_version = response['js_api_version'] === undefined ? 0 : response['js_api_version'];
735 - //console.log("Extension JS API Version: ", js_api_version);
736 - u2f.sendSignRequest(appId, challenge, registeredKeys, callback, opt_timeoutSeconds);
737 - });
738 - } else {
739 - // We know the JS API version. Send the actual sign request in the supported API version.
740 - u2f.sendSignRequest(appId, challenge, registeredKeys, callback, opt_timeoutSeconds);
741 - }
742 - };
743 -
744 - /**
745 - * Dispatches an array of sign requests to available U2F tokens.
746 - * @param {string=} appId
747 - * @param {string=} challenge
748 - * @param {Array<u2f.RegisteredKey>} registeredKeys
749 - * @param {function((u2f.Error|u2f.SignResponse))} callback
750 - * @param {number=} opt_timeoutSeconds
751 - */
752 -u2f.sendSignRequest = function (appId, challenge, registeredKeys, callback, opt_timeoutSeconds) {
753 - u2f.getPortSingleton_(function (port) {
754 - var reqId = ++u2f.reqCounter_;
755 - u2f.callbackMap_[reqId] = callback;
756 - var timeoutSeconds = (typeof opt_timeoutSeconds !== 'undefined' ?
757 - opt_timeoutSeconds : u2f.EXTENSION_TIMEOUT_SEC);
758 - var req = u2f.formatSignRequest_(appId, challenge, registeredKeys, timeoutSeconds, reqId);
759 - port.postMessage(req);
760 - });
761 - };
762 -
763 - /**
764 - * Dispatches register requests to available U2F tokens. An array of sign
765 - * requests identifies already registered tokens.
766 - * If the JS API version supported by the extension is unknown, it first sends a
767 - * message to the extension to find out the supported API version and then it sends
768 - * the register request.
769 - * @param {string=} appId
770 - * @param {Array<u2f.RegisterRequest>} registerRequests
771 - * @param {Array<u2f.RegisteredKey>} registeredKeys
772 - * @param {function((u2f.Error|u2f.RegisterResponse))} callback
773 - * @param {number=} opt_timeoutSeconds
774 - */
775 -u2f.register = function (appId, registerRequests, registeredKeys, callback, opt_timeoutSeconds) {
776 - if (js_api_version === undefined) {
777 - // Send a message to get the extension to JS API version, then send the actual register request.
778 - u2f.getApiVersion(
779 - function (response) {
780 - js_api_version = response['js_api_version'] === undefined ? 0: response['js_api_version'];
781 - //console.log("Extension JS API Version: ", js_api_version);
782 - u2f.sendRegisterRequest(appId, registerRequests, registeredKeys,
783 - callback, opt_timeoutSeconds);
784 - });
785 - } else {
786 - // We know the JS API version. Send the actual register request in the supported API version.
787 - u2f.sendRegisterRequest(appId, registerRequests, registeredKeys,
788 - callback, opt_timeoutSeconds);
789 - }
790 - };
791 -
792 - /**
793 - * Dispatches register requests to available U2F tokens. An array of sign
794 - * requests identifies already registered tokens.
795 - * @param {string=} appId
796 - * @param {Array<u2f.RegisterRequest>} registerRequests
797 - * @param {Array<u2f.RegisteredKey>} registeredKeys
798 - * @param {function((u2f.Error|u2f.RegisterResponse))} callback
799 - * @param {number=} opt_timeoutSeconds
800 - */
801 -u2f.sendRegisterRequest = function (appId, registerRequests, registeredKeys, callback, opt_timeoutSeconds) {
802 - u2f.getPortSingleton_(function (port) {
803 - var reqId = ++u2f.reqCounter_;
804 - u2f.callbackMap_[reqId] = callback;
805 - var timeoutSeconds = (typeof opt_timeoutSeconds !== 'undefined' ?
806 - opt_timeoutSeconds : u2f.EXTENSION_TIMEOUT_SEC);
807 - var req = u2f.formatRegisterRequest_(
808 - appId, registeredKeys, registerRequests, timeoutSeconds, reqId);
809 - port.postMessage(req);
810 - });
811 - };
812 -
813 -
814 - /**
815 - * Dispatches a message to the extension to find out the supported
816 - * JS API version.
817 - * If the user is on a mobile phone and is thus using Google Authenticator instead
818 - * of the Chrome extension, don't send the request and simply return 0.
819 - * @param {function((u2f.Error|u2f.GetJsApiVersionResponse))} callback
820 - * @param {number=} opt_timeoutSeconds
821 - */
822 -u2f.getApiVersion = function (callback, opt_timeoutSeconds) {
823 - u2f.getPortSingleton_(function (port) {
824 - // If we are using Android Google Authenticator or iOS client app,
825 - // do not fire an intent to ask which JS API version to use.
826 - if (port.getPortType) {
827 - var apiVersion;
828 - switch (port.getPortType()) {
829 - case 'WrappedIosPort_':
830 - case 'WrappedAuthenticatorPort_':
831 - apiVersion = 1.1;
832 - break;
833 -
834 - default:
835 - apiVersion = 0;
836 - break;
837 - }
838 - callback({ 'js_api_version': apiVersion });
839 - return;
840 - }
841 - var reqId = ++u2f.reqCounter_;
842 - u2f.callbackMap_[reqId] = callback;
843 - var req = {
844 - type: u2f.MessageTypes.U2F_GET_API_VERSION_REQUEST,
845 - timeoutSeconds: (typeof opt_timeoutSeconds !== 'undefined' ?
846 - opt_timeoutSeconds : u2f.EXTENSION_TIMEOUT_SEC),
847 - requestId: reqId
848 - };
849 - port.postMessage(req);
850 - });
851 - };
852 -
853 -}
854 - 'use strict';
855 - var passhint = "{{{passhint}}}";
856 - var newAccountPass = parseInt('{{{newAccountPass}}}');
857 - var emailCheck = ('{{{emailcheck}}}' == 'true');
858 - var passRequirements = "{{{passRequirements}}}";
859 - var hardwareKeyChallenge = decodeURIComponent('{{{hkey}}}');
860 - if (passRequirements != "") { passRequirements = JSON.parse(decodeURIComponent(passRequirements)); } else { passRequirements = {}; }
861 - var passRequirementsEx = ((passRequirements.min != null) || (passRequirements.max != null) || (passRequirements.upper != null) || (passRequirements.lower != null) || (passRequirements.numeric != null) || (passRequirements.nonalpha != null));
862 - var features = parseInt('{{{features}}}');
863 - var webPageFullScreen = getstore('webPageFullScreen', true);
864 - if (webPageFullScreen == 'false') { webPageFullScreen = false; }
865 - if (webPageFullScreen == 'true') { webPageFullScreen = true; }
866 - var welcomeText = decodeURIComponent("{{{welcometext}}}");
867 - var currentpanel = 0;
868 - toggleFullScreen();
869 -
870 - function startup() {
871 - if ((features & 32) == 0) {
872 - // Guard against other site's top frames (web bugs).
873 - var loc = null;
874 - try { loc = top.location.toString().toLowerCase(); } catch (e) { }
875 - if (top != self && (loc == null || top.active == false)) { top.location = self.location; return; }
876 - }
877 -
878 - QV('createPanelHint', passRequirements.hint === true);
879 - QV('resetpasswordpanelHint', passRequirements.hint === true);
880 -
881 - // Display the welcome text
882 - if (welcomeText) { QH('welcomeText', welcomeText); }
883 - QV('welcomeText', true);
884 -
885 - window.onresize = center;
886 - center();
887 -
888 - validateLogin();
889 - validateCreate();
890 - if ('{{loginmode}}' != '') { go(parseInt('{{loginmode}}')); } else { go(1); }
891 - QV('newAccountDiv', ('{{{newAccount}}}' != '0') && ('{{{newAccount}}}' != 'false')); // If new accounts are not allowed, don't display the new account link.
892 - if ((passhint != null) && (passhint.length > 0)) { QV("showPassHintLink", true); }
893 - QV("newAccountPass", (newAccountPass == 1));
894 - QV("resetAccountDiv", (emailCheck == true));
895 - QV("hrAccountDiv", (emailCheck == true) || (newAccountPass == 1));
896 -
897 - if ('{{loginmode}}' == '4') {
898 - try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
899 - if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
900 - hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), c => c.charCodeAt(0)).buffer;
901 -
902 - const publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
903 - for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
904 - publicKeyCredentialRequestOptions.allowCredentials.push(
905 - { id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), c => c.charCodeAt(0)), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
906 - );
907 - }
908 -
909 - // New WebAuthn hardware keys
910 - navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
911 - function (rawAssertion) {
912 - var assertion = {
913 - id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
914 - clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
915 - userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
916 - signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
917 - authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
918 - };
919 - Q('hwtokenInput').value = JSON.stringify(assertion);
920 - QE('tokenOkButton', true);
921 - Q('tokenOkButton').click();
922 - },
923 - function (error) { console.log('credentials-get error', error); }
924 - );
925 - } else if ((hardwareKeyChallenge != null) && u2fSupported()) {
926 - // Old U2F hardware keys
927 - window.u2f.sign(hardwareKeyChallenge.appId, hardwareKeyChallenge.challenge, hardwareKeyChallenge.registeredKeys, function (authResponse) {
928 - if ((currentpanel == 4) && authResponse.signatureData) {
929 - Q('hwtokenInput').value = JSON.stringify(authResponse);
930 - QE('tokenOkButton', true);
931 - Q('tokenOkButton').click();
932 - }
933 - }, hardwareKeyChallenge.timeoutSeconds);
934 - }
935 - }
936 -
937 - if ('{{loginmode}}' == '5') {
938 - try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
939 - if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
940 - hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), c => c.charCodeAt(0)).buffer;
941 -
942 - const publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
943 - for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
944 - publicKeyCredentialRequestOptions.allowCredentials.push(
945 - { id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), c => c.charCodeAt(0)), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
946 - );
947 - }
948 -
949 - // New WebAuthn hardware keys
950 - navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
951 - function (rawAssertion) {
952 - var assertion = {
953 - id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
954 - clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
955 - userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
956 - signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
957 - authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
958 - };
959 - Q('resetHwtokenInput').value = JSON.stringify(assertion);
960 - QE('resetTokenOkButton', true);
961 - Q('resetTokenOkButton').click();
962 - },
963 - function (error) { console.log('credentials-get error', error); }
964 - );
965 - } else if ((hardwareKeyChallenge != null) && u2fSupported()) {
966 - // Old U2F hardware keys
967 - window.u2f.sign(hardwareKeyChallenge.appId, hardwareKeyChallenge.challenge, hardwareKeyChallenge.registeredKeys, function (authResponse) {
968 - if ((currentpanel == 5) && authResponse.signatureData) {
969 - Q('resetHwtokenInput').value = JSON.stringify(authResponse);
970 - QE('resetTokenOkButton', true);
971 - Q('resetTokenOkButton').click();
972 - }
973 - }, hardwareKeyChallenge.timeoutSeconds);
974 - }
975 - }
976 - }
977 -
978 - function showPassHint() {
979 - messagebox("Password Hint", passhint);
980 - }
981 -
982 - function xgo(x) {
983 - QV('message1', false);
984 - QV('message2', false);
985 - QV('message3', false);
986 - QV('message4', false);
987 - QV('message5', false);
988 - QV('message6', false);
989 - go(x);
990 - }
991 -
992 - function go(x) {
993 - currentpanel = x;
994 - setDialogMode(0);
995 - QV("showPassHintLink", false);
996 - QV('loginpanel', x == 1);
997 - QV('createpanel', x == 2);
998 - QV('resetpanel', x == 3);
999 - QV('tokenpanel', x == 4);
1000 - QV('resettokenpanel', x == 5);
1001 - QV('resetpasswordpanel', x == 6);
1002 - if (x == 1) { Q('username').focus(); }
1003 - if (x == 2) { Q('ausername').focus(); }
1004 - if (x == 3) { Q('remail').focus(); }
1005 - if (x == 4) { Q('tokenInput').focus(); }
1006 - if (x == 5) { Q('resetTokenInput').focus(); }
1007 - if (x == 6) { Q('rapassword1').focus(); }
1008 - }
1009 -
1010 - function validateLogin(box, e) {
1011 - var ok = ((Q('username').value.length > 0) && (Q('username').value.indexOf(' ') == -1) && (Q('password').value.length > 0));
1012 - QE('loginButton', ok);
1013 - setDialogMode(0);
1014 - if ((e != null) && (e.keyCode == 13)) { if (box == 1) { Q('password').focus(); } else if (box == 2) { Q('loginButton').click(); } }
1015 - if (e != null) { haltEvent(e); }
1016 - }
1017 -
1018 - function validateCreate(box, e) {
1019 - setDialogMode(0);
1020 - var userok = (Q('ausername').value.length > 0) && (Q('ausername').value.indexOf(' ') == -1);
1021 - var emailok = (validateEmail(Q('aemail').value) == true);
1022 - var pass1ok = (Q('apassword1').value.length > 0);
1023 - var pass2ok = (Q('apassword2').value.length > 0) && (Q('apassword2').value == Q('apassword1').value);
1024 - var newAccOk = (newAccountPass == 0) || (Q('anewaccountpass').value.length > 0);
1025 - var ok = (userok && emailok && pass1ok && pass2ok && newAccOk);
1026 -
1027 - // Color the fields
1028 - QS('nuUser').color = userok?'black':'#7b241c';
1029 - QS('nuEmail').color = emailok?'black':'#7b241c';
1030 - QS('nuPass1').color = pass1ok?'black':'#7b241c';
1031 - QS('nuPass2').color = pass2ok?'black':'#7b241c';
1032 - QS('nuToken').color = newAccOk?'black':'#7b241c';
1033 -
1034 - if (Q('apassword1').value == '') {
1035 - QH('passWarning', '');
1036 - QV('passwordPolicyCallout', false);
1037 - } else {
1038 - if (!passRequirementsEx) {
1039 - // No password requirements, display password strength
1040 - var passStrength = checkPasswordStrength(Q('apassword1').value);
1041 - if (passStrength >= 80) { QH('passWarning', '<span style=color:green><b>Strong Password</b><span>'); }
1042 - else if (passStrength >= 60) { QH('passWarning', '<span style=color:blue><b>Good Password</b><span>'); }
1043 - else { QH('passWarning', '<span style=color:red><b>Weak Password</b><span>'); }
1044 - } else {
1045 - // Password requirements provided, use that
1046 - var passReq = checkPasswordRequirements(Q('apassword1').value, passRequirements);
1047 - if (passReq == false) {
1048 - ok = false;
1049 - QS('nuPass1').color = '#7b241c';
1050 - QS('nuPass2').color = '#7b241c';
1051 - QH('passWarning', '<div style=color:red;cursor:pointer onclick=showPasswordPolicy()><b>Password Policy</b><div>'); // This is also a link to the password policy
1052 - QV('passwordPolicyCallout', true);
1053 - QH('passwordPolicyCallout', passwordPolicyText(Q('apassword1').value));
1054 - } else {
1055 - QH('passWarning', '');
1056 - QV('passwordPolicyCallout', false);
1057 - }
1058 - }
1059 - }
1060 - if ((e != null) && (e.keyCode == 13)) {
1061 - if (box == 1) { Q('aemail').focus(); }
1062 - if (box == 2) { Q('apassword1').focus(); }
1063 - if (box == 3) { Q('apassword2').focus(); }
1064 - if (box == 4) { Q('apasswordhint').focus(); }
1065 - if (box == 5) { if (newAccountPass == 1) { Q('anewaccountpass').focus(); } else { Q('createButton').click(); } }
1066 - if (box == 6) { Q('createButton').click(); }
1067 - }
1068 - if (e != null) { haltEvent(e); }
1069 - QE('createButton', ok);
1070 - }
1071 -
1072 - function validatePassReset(box, e) {
1073 - setDialogMode(0);
1074 - var pass1ok = (Q('rapassword1').value.length > 0);
1075 - var pass2ok = (Q('rapassword2').value.length > 0) && (Q('rapassword2').value == Q('rapassword1').value);
1076 - var ok = (pass1ok && pass2ok);
1077 -
1078 - // Color the fields
1079 - QS('rnuPass1').color = pass1ok ? 'black' : '#7b241c';
1080 - QS('rnuPass2').color = pass2ok ? 'black' : '#7b241c';
1081 -
1082 - if (Q('rapassword1').value == '') {
1083 - QH('rpassWarning', '');
1084 - QV('rpasswordPolicyCallout', false);
1085 - } else {
1086 - if (!passRequirementsEx) {
1087 - // No password requirements, display password strength
1088 - var passStrength = checkPasswordStrength(Q('rapassword1').value);
1089 - if (passStrength >= 80) { QH('rpassWarning', '<span style=color:green><b>Strong Password</b><span>'); }
1090 - else if (passStrength >= 60) { QH('rpassWarning', '<span style=color:blue><b>Good Password</b><span>'); }
1091 - else { QH('rpassWarning', '<span style=color:red><b>Weak Password</b><span>'); }
1092 - } else {
1093 - // Password requirements provided, use that
1094 - var passReq = checkPasswordRequirements(Q('rapassword1').value, passRequirements);
1095 - if (passReq == false) {
1096 - ok = false;
1097 - QS('rnuPass1').color = '#7b241c';
1098 - QS('rnuPass2').color = '#7b241c';
1099 - QH('rpassWarning', '<div style=color:red;cursor:pointer onclick=showPasswordPolicy()><b>Password Policy</b><div>'); // This is also a link to the password policy
1100 - QV('rpasswordPolicyCallout', true);
1101 - QH('rpasswordPolicyCallout', passwordPolicyText(Q('rapassword1').value));
1102 - } else {
1103 - QH('rpassWarning', '');
1104 - QV('rpasswordPolicyCallout', false);
1105 - }
1106 - }
1107 - }
1108 - if ((e != null) && (e.keyCode == 13)) {
1109 - if (box == 2) { Q('rapassword1').focus(); }
1110 - if (box == 3) { Q('rapassword2').focus(); }
1111 - if (box == 4) { Q('rapasswordhint').focus(); }
1112 - if (box == 6) { Q('resetPassButton').click(); }
1113 - }
1114 - if (e != null) { haltEvent(e); }
1115 - QE('resetPassButton', ok);
1116 - }
1117 -
1118 - function passwordPolicyText(pass) {
1119 - var policy = '<div style=text-align:left>';
1120 - var counts = strCount(pass);
1121 - if (passRequirements.min && ((pass == null) || (pass.length < passRequirements.min))) { policy += 'Minimum length of ' + passRequirements.min + '<br />'; }
1122 - if (passRequirements.max && ((pass == null) || (pass.length > passRequirements.max))) { policy += 'Maximum length of ' + passRequirements.max + '<br />'; }
1123 - if (passRequirements.upper && ((pass == null) || (counts.upper < passRequirements.upper))) { policy += '' + passRequirements.upper + ' upper case<br />'; }
1124 - if (passRequirements.lower && ((pass == null) || (counts.lower < passRequirements.lower))) { policy += '' + passRequirements.lower + ' lower case<br />'; }
1125 - if (passRequirements.numeric && ((pass == null) || (counts.numeric < passRequirements.numeric))) { policy += '' + passRequirements.numeric + ' numeric<br />'; }
1126 - if (passRequirements.nonalpha && ((pass == null) || (counts.nonalpha < passRequirements.nonalpha))) { policy += passRequirements.nonalpha + ' non-alphanumeric<br />'; }
1127 - policy += '</div>';
1128 - return policy;
1129 - }
1130 -
1131 - function showPasswordPolicy() {
1132 - messagebox("Password Policy", passwordPolicyText());
1133 - }
1134 -
1135 - function validateReset(e) {
1136 - setDialogMode(0);
1137 - var x = validateEmail(Q('remail').value);
1138 - QE('eresetButton', x);
1139 - if ((e != null) && (e.keyCode == 13) && (x == true)) {
1140 - Q('eresetButton').click();
1141 - }
1142 - if (e != null) { haltEvent(e); }
1143 - }
1144 -
1145 - // Return a password strength score
1146 - function checkPasswordStrength(password) {
1147 - var r = 0, letters = {}, varCount = 0, variations = { digits: /\d/.test(password), lower: /[a-z]/.test(password), upper: /[A-Z]/.test(password), nonWords: /\W/.test(password) }
1148 - if (!password) return 0;
1149 - for (var i = 0; i< password.length; i++) { letters[password[i]] = (letters[password[i]] || 0) + 1; r += 5.0 / letters[password[i]]; }
1150 - for (var c in variations) { varCount += (variations[c] == true) ? 1 : 0; }
1151 - return parseInt(r + (varCount - 1) * 10);
1152 - }
1153 -
1154 - // Check password requirements
1155 - function checkPasswordRequirements(password, requirements) {
1156 - if ((requirements == null) || (requirements == '') || (typeof requirements != 'object')) return true;
1157 - if (requirements.min) { if (password.length < requirements.min) return false; }
1158 - if (requirements.max) { if (password.length > requirements.max) return false; }
1159 - var counts = strCount(password);
1160 - if (requirements.numeric && (counts.numeric < requirements.numeric)) return false;
1161 - if (requirements.lower && (counts.lower < requirements.lower)) return false;
1162 - if (requirements.upper && (counts.upper < requirements.upper)) return false;
1163 - if (requirements.nonalpha && (counts.nonalpha < requirements.nonalpha)) return false;
1164 - return true;
1165 - }
1166 -
1167 - function strCount(password) {
1168 - var counts = { numeric: 0, lower: 0, upper: 0, nonalpha: 0 };
1169 - if (typeof password != 'string') return counts;
1170 - for (var i = 0; i < password.length; i++) {
1171 - if (/\d/.test(password[i])) { counts.numeric++; }
1172 - if (/[a-z]/.test(password[i])) { counts.lower++; }
1173 - if (/[A-Z]/.test(password[i])) { counts.upper++; }
1174 - if (/\W/.test(password[i])) { counts.nonalpha++; }
1175 - }
1176 - return counts;
1177 - }
1178 -
1179 - function checkToken() {
1180 - var t1 = Q('tokenInput').value;
1181 - var t2 = t1.split(' ').join('');
1182 - if (t1 != t2) { Q('tokenInput').value = t2; }
1183 - QE('tokenOkButton', (Q('tokenInput').value.length == 6) || (Q('tokenInput').value.length == 8) || (Q('tokenInput').value.length == 44));
1184 - }
1185 -
1186 - function resetCheckToken() {
1187 - var t1 = Q('resetTokenInput').value;
1188 - var t2 = t1.split(' ').join('');
1189 - if (t1 != t2) { Q('resetTokenInput').value = t2; }
1190 - QE('resetTokenOkButton', (Q('resetTokenInput').value.length == 6) || (Q('resetTokenInput').value.length == 8) || (Q('resetTokenInput').value.length == 44));
1191 - }
1192 -
1193 - //
1194 - // POPUP DIALOG
1195 - //
1196 -
1197 - // undefined = Hidden, 1 = Generic Message
1198 - var xxdialogMode;
1199 - var xxdialogFunc;
1200 - var xxdialogButtons;
1201 - var xxdialogTag;
1202 - var xxcurrentView = 0;
1203 -
1204 - // Display a dialog box
1205 - // Parameters: Dialog Mode (0 = none), Dialog Title, Buttons (1 = OK, 2 = Cancel, 3 = OK & Cancel), Call back function(0 = Cancel, 1 = OK), Dialog Content (Mode 2 only)
1206 - function setDialogMode(x, y, b, f, c, tag) {
1207 - xxdialogMode = x;
1208 - xxdialogFunc = f;
1209 - xxdialogButtons = b;
1210 - xxdialogTag = tag;
1211 - QE('idx_dlgOkButton', true);
1212 - QV('idx_dlgOkButton', b & 1);
1213 - QV('idx_dlgCancelButton', b & 2);
1214 - QV('id_dialogclose', (b & 2) || (b & 8));
1215 - QV('idx_dlgButtonBar', b & 7);
1216 - if (y) QH('id_dialogtitle', y);
1217 - for (var i = 1; i < 24; i++) { QV('dialog' + i, i == x); } // Edit this line when more dialogs are added
1218 - QV('dialog', x);
1219 - if (c) { if (x == 2) { QH('id_dialogOptions', c); } else { QH('id_dialogMessage', c); } }
1220 - }
1221 -
1222 - function dialogclose(x) {
1223 - var f = xxdialogFunc;
1224 - var b = xxdialogButtons;
1225 - var t = xxdialogTag;
1226 - setDialogMode();
1227 - if (((b & 8) || x) && f) f(x, t);
1228 - }
1229 -
1230 - // Toggle the web page to full screen
1231 - function toggleFullScreen(toggle) {
1232 - if (toggle === 1) { webPageFullScreen = !webPageFullScreen; putstore('webPageFullScreen', webPageFullScreen); }
1233 - if (webPageFullScreen == false) {
1234 - QS('container').width = '960px';
1235 - QS('container')["min-width"] = '960px';
1236 - QS('container')['border-right'] = '1px solid #b7b7b7';
1237 - QS('container')['border-left'] = '1px solid #b7b7b7';
1238 - QS('container')['overflow'] = 'hidden';
1239 - QS('column_l').height = '';
1240 - QS('column_l').width = '930px';
1241 - QS('column_l')["overflow-y"] = '';
1242 - QS('column_l')["max-height"] = 'calc(100vh - 111px)';
1243 - QS('column_l')["min-width"] = '';
1244 - QS('masthead')["width"] = '960px';
1245 - } else {
1246 - QS('container').width = '100%';
1247 - QS('container')['min-width'] = '';
1248 - QS('container')['border-right'] = '0';
1249 - QS('container')['border-left'] = '0';
1250 - QS('container')['overflow'] = 'hidden';
1251 - QS('column_l').height = 'calc(100vh - 135px)';
1252 - QS('column_l').width = '';
1253 - QS('column_l')["overflow-y"] = 'auto';
1254 - QS('column_l')["max-height"] = 'calc(100vh - 111px)';
1255 - QS('column_l')["min-width"] = '';
1256 - QS('masthead')["width"] = '100%';
1257 - }
1258 - QV('body', true);
1259 - center();
1260 - }
1261 -
1262 - function center() {
1263 - var w = getDocWidth();
1264 - QS('dialog').left = ((((w - 400) / 2)) + "px");
1265 - var showimage = (webPageFullScreen == false) || (w > 800);
1266 - QV('welcomeimage', showimage);
1267 - Q('logincell').setAttribute('align', showimage?'left':'center');
1268 -
1269 - if (webPageFullScreen == false) {
1270 - QS('centralTable')['margin-top'] = '';
1271 - } else {
1272 - var h = (Q('column_l').clientHeight / 2) - 250;
1273 - if (h < 0) h = 0;
1274 - QS('centralTable')['margin-top'] = h + 'px';
1275 - }
1276 - }
1277 - function messagebox(t, m) { QH('id_dialogMessage', m); setDialogMode(1, t, 1); }
1278 - function statusbox(t, m) { QH('id_dialogMessage', m); setDialogMode(1, t); }
1279 - function getDocWidth() { if (window.innerWidth) return window.innerWidth; if (document.documentElement && document.documentElement.clientWidth && document.documentElement.clientWidth != 0) return document.documentElement.clientWidth; return document.getElementsByTagName('body')[0].clientWidth; }
1280 - function haltEvent(e) { if (e.preventDefault) e.preventDefault(); if (e.stopPropagation) e.stopPropagation(); return false; }
1281 - function haltReturn(e) { if (e.keyCode == 13) { haltEvent(e); } }
1282 - function validateEmail(v) { var emailReg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; return emailReg.test(v); } // New version
1283 - function putstore(name, val) { try { if (typeof (localStorage) === 'undefined') return; localStorage.setItem(name, val); } catch (e) { } }
1284 - function getstore(name, val) { try { if (typeof (localStorage) === 'undefined') return val; var v = localStorage.getItem(name); if ((v == null) || (v == null)) return val; return v; } catch (e) { return val; } }
1285 - function u2fSupported() { return (window.u2f && ((navigator.userAgent.indexOf('Chrome/') > 0) || (navigator.userAgent.indexOf('Firefox/') > 0) || (navigator.userAgent.indexOf('Opera/') > 0) || (navigator.userAgent.indexOf('Safari/') > 0))); }
1286 -
1287 - </script></body></html>
\ No newline at end of file
1 +<!DOCTYPE html> <html dir="ltr" xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta content="text/html; charset=utf-8" http-equiv="Content-Type"> <meta name="viewport" content="user-scalable=1.0,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="format-detection" content="telephone=no"> <style> body{margin:0;padding:0;border:0;color:black;font-size:13px;font-family:"Trebuchet MS", Arial, Helvetica, sans-serif;background-color:#d3d9d6;}#container{background-color:#fff;margin:0 auto;border-top:0;border-right:1px solid #b7b7b7;border-bottom:0;border-left:1px solid #b7b7b7;padding:0;}#masthead{width:auto;margin:0;padding:0;overflow:auto;text-align:right;background-color:#036;}#column_l{position:relative;float:left;margin:0;padding:0 15px;background-color:#fff;}#footer{clear:both;overflow:auto;width:100%;text-align:center;background-color:#113962;padding-top:5px;padding-bottom:5px;}.style3{text-align:center;color:white;background-color:#808080;font-weight:bold;}#footer{clear:both;overflow:auto;width:100%;text-align:center;background-color:#113962;padding-top:5px;padding-bottom:5px;}#footer a{color:#fff;text-decoration:underline;}#footer a:hover{color:#fff;text-decoration:none;}a{color:#036;text-decoration:underline;}</style> <script type="text/javascript" src="scripts/u2f-api.js"></script> <title>MeshCentral - Login</title> </head> <body onload="if (typeof(startup) !== 'undefined') startup();"> <div id="container" style="max-height:100vh"> <div id="mastheadx"></div> <div id="masthead" style="background:url(logo.png) 0px 0px;background-color:#036;background-repeat:no-repeat;height:66px;width:100%;overflow:hidden"> <div style="float:left;height:66px;color:#c8c8c8;padding-left:20px;padding-top:8px"> <strong><font style="font-size:46px;font-family:Arial,Helvetica,sans-serif">{{{title}}}</font></strong> </div> <div style="float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:14px"> <strong><font style="font-size:14px;font-family:Arial,Helvetica,sans-serif">{{{title2}}}</font></strong> </div> </div> <div id="page_content" style="max-height:calc(100vh-108px)"> <div id="topbar" class="noselect style3" style="height:24px;position:relative"> <div title="Toggle full width" style="cursor:pointer;color:white;position:absolute;top:3px;right:6px" onclick="toggleFullScreen(1)">&harr;</div> </div> <div id="column_l"> <h1>Welcome</h1> <div id="welcomeText" style="display:none">Connect to your home or office devices from anywhere in the world using <a href="http://www.meshcommander.com/meshcentral2">MeshCentral</a>, the real time, open source remote monitoring and management web site. You will need to download and install a management agent on your computers. Once installed, computers will show up in the &quot;My Devices&quot; section of this web site and you will be able to monitor them and take control of them.</div> <table id="centralTable" style="width:100%"> <tr> <td id="welcomeimage" align="right" style="display:none"> <picture> <img alt="" width="359" height="310" src="welcome.jpg"> </picture> </td> <td id="logincell" align="left"> <div id="loginpanel" style="background-color:#979797;border-radius:16px;width:300px;padding:16px;text-align:center;display:none"> <form action="login" method="post"> <div id="message1"> {{{message}}} </div> <div> <b>Log In</b> </div> <table> <tr> <td align="right" width="100">Username:</td> <td><input id="username" type="text" maxlength="64" name="username" onchange="validateLogin(1)" onkeyup="validateLogin(1,event)"></td> </tr> <tr> <td align="right">Password:</td> <td><input id="password" type="password" maxlength="256" name="password" autocomplete="off" onchange="validateLogin(2)" onkeyup="validateLogin(2,event)"></td> </tr> <tr> <td><div id="showPassHintLink" style="display:none"><a onclick="showPassHint()" style="cursor:pointer">Show Hint</a></div></td> <td align="right"><input id="loginButton" type="submit" value="Log In" disabled="disabled"></td> </tr> </table> <div id="hrAccountDiv" style="display:none"><hr></div> <div id="resetAccountDiv" style="display:none;padding:2px"> Forgot username/password? <a onclick="xgo(3)" style="cursor:pointer">Reset account</a>. </div> <div id="newAccountDiv" style="display:none;padding:2px"> Don&#39;t have an account? <a onclick="xgo(2)" style="cursor:pointer">Create one</a>. </div> </form> </div> <div id="createpanel" style="position:relative;background-color:#979797;border-radius:16px;width:300px;padding:16px;text-align:center;display:none"> <form action="createaccount" method="post"> <div id="message2"> {{{message}}} </div> <div> <b>Account Creation</b> </div> <div id="passwordPolicyCallout" style="left:-10px;width:100px;display:none;position:absolute;background-color:#FFC;border-radius:5px;padding:5px;box-shadow:0px 0px 15px #666;font-size:10px"></div> <table> <tr> <td id="nuUser" align="right" width="100">Username:</td> <td><input id="ausername" type="text" name="username" onchange="validateCreate(1)" maxlength="64" onkeydown="haltReturn(event)" onkeyup="validateCreate(1,event)"></td> </tr> <tr> <td id="nuEmail" align="right" width="100">Email:</td> <td><input id="aemail" type="text" name="email" onchange="validateCreate(2)" maxlength="256" onkeydown="haltReturn(event)" onkeyup="validateCreate(2,event)"></td> </tr> <tr> <td id="nuPass1" align="right">Password:</td> <td><input id="apassword1" type="password" name="password1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(3,event)" onkeyup="validateCreate(3,event)"></td> </tr> <tr> <td id="nuPass2" align="right">Password:</td> <td><input id="apassword2" type="password" name="password2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(4,event)" onkeyup="validateCreate(4,event)"></td> </tr> <tr id="createPanelHint" style="display:none"> <td id="nuHint" align="right">Password Hint:</td> <td><input id="apasswordhint" type="text" name="apasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(5,event)" onkeyup="validateCreate(5,event)"></td> </tr> <tr id="newAccountPass" title="Enter the account creation token"> <td id="nuToken" align="right">Creation Token:</td> <td><input id="anewaccountpass" type="password" name="anewaccountpass" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(6,event)" onkeyup="validateCreate(6,event)"></td> </tr> <tr> <td colspan="2"> <div style="float:right"><input id="createButton" type="submit" value="Create Account" disabled="disabled"></div> <div id="passWarning" style="padding-top:6px"></div> </td> </tr> </table> <hr><a onclick="xgo(1)" style="cursor:pointer">Back to login</a> </form> </div> <div id="resetpanel" style="background-color:#979797;border-radius:16px;width:300px;padding:16px;text-align:center;display:none"> <form action="resetaccount" method="post"> <div id="message3"> {{{message}}} </div> <div> <b>Account Reset</b> </div> <table> <tr> <td align="right" width="100">Email:</td> <td><input id="remail" type="text" name="email" maxlength="256" onchange="validateReset()" onkeyup="validateReset(event)"></td> </tr> <tr> <td colspan="2"> <div style="float:right"><input id="eresetButton" type="submit" value="Reset Account" disabled="disabled"></div> <div id="passWarning" style="padding-top:6px"></div> </td> </tr> </table> <hr><a onclick="xgo(1)" style="cursor:pointer">Back to login</a> </form> </div> <div id="tokenpanel" style="background-color:#979797;border-radius:16px;width:300px;padding:16px;text-align:center;display:none"> <form action="tokenlogin" method="post" autocomplete="off"> <div id="message4"> {{{message}}} </div> <table> <tr> <td align="right" width="100">Login token:</td> <td> <input id="tokenInput" type="text" name="token" maxlength="50" onchange="checkToken(event)" onpaste="resetCheckToken(event)" onkeyup="checkToken(event)" onkeydown="checkToken(event)"> <input id="hwtokenInput" type="text" name="hwtoken" style="display:none"> </td> </tr> <tr> <td colspan="2"> <div style="float:right"><input id="tokenOkButton" type="submit" value="Login" disabled="disabled"></div> </td> </tr> </table> <hr><a onclick="xgo(1)" style="cursor:pointer">Back to login</a> </form> </div> <div id="resettokenpanel" style="background-color:#979797;border-radius:16px;width:300px;padding:16px;text-align:center;display:none"> <form action="resetaccount" method="post"> <div id="message5"> {{{message}}} </div> <table> <tr> <td align="right" width="100">Login token:</td> <td> <input id="resetTokenInput" type="text" name="token" maxlength="50" onchange="resetCheckToken(event)" onkeyup="resetCheckToken(event)" onkeydown="resetCheckToken(event)"> <input id="resetHwtokenInput" type="text" name="hwtoken" style="display:none"> </td> </tr> <tr> <td colspan="2"> <div style="float:right"><input id="resetTokenOkButton" type="submit" value="Login" disabled="disabled"></div> </td> </tr> </table> <hr><a onclick="xgo(1)" style="cursor:pointer">Back to login</a> </form> </div> <div id="resetpasswordpanel" style="position:relative;background-color:#979797;border-radius:16px;width:300px;padding:16px;text-align:center;display:none"> <form action="resetpassword" method="post"> <div id="message6"> {{{message}}} </div> <div id="rpasswordPolicyCallout" style="left:-10px;width:100px;display:none;position:absolute;background-color:#FFC;border-radius:5px;padding:5px;box-shadow:0px 0px 15px #666;font-size:10px"></div> <table> <tr> <td id="rnuPass1" width="100" align="right">Password:</td> <td><input id="rapassword1" type="password" name="rpassword1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(3,event)" onkeyup="validatePassReset(3,event)"></td> </tr> <tr> <td id="rnuPass2" align="right">Password:</td> <td><input id="rapassword2" type="password" name="rpassword2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(4,event)" onkeyup="validatePassReset(4,event)"></td> </tr> <tr id="resetpasswordpanelHint" style="display:none"> <td id="rnuHint" align="right">Password Hint:</td> <td><input id="rapasswordhint" type="text" name="rpasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(5,event)" onkeyup="validatePassReset(5,event)"></td> </tr> <tr> <td colspan="2"> <div style="float:right"><input id="resetPassButton" type="submit" value="Reset Password" disabled="disabled"></div> <div id="rpassWarning" style="padding-top:6px"></div> </td> </tr> </table> <hr><a onclick="xgo(1)" style="cursor:pointer">Back to login</a> </form> </div> </td> </tr> </table> <br> </div> <div id="footer"> <table cellpadding="0" cellspacing="10" style="width:100%"> <tr> <td style="text-align:left;color:white"> {{{footer}}} </td> <td style="text-align:right"> {{{rootCertLink}}} &nbsp;<a href="terms">Terms &amp; Privacy</a> </td> </tr> </table> </div> </div> </div> <div id="dialog" style="z-index:1000;background-color:#EEE;box-shadow:0px 0px 15px #666;font-family:Arial,Helvetica,sans-serif;border-radius:5px;position:fixed;top:180px;width:400px;display:none"> <div style="width:100%;background-color:#003366;color:#FFF;border-radius:5px 5px 0 0"> <div id="id_dialogclose" style="float:right;padding:5px;cursor:pointer" onclick="setDialogMode()"><b>X</b></div> <div id="id_dialogtitle" style="padding:5px"></div> <div style="width:100%;margin:6px"></div> </div> <div style="margin-right:16px;margin-left:8px"> <div id="dialog1" style="margin:auto;text-align:center;margin:3px"> <div id="id_dialogMessage" style="padding:10px"></div> </div> <div id="dialog2" style="margin:auto;margin:3px"> <div id="id_dialogOptions"></div> </div> </div> <div id="idx_dlgButtonBar" style="padding:10px;margin-bottom:20px"> <input id="idx_dlgCancelButton" type="button" value="Cancel" style="float:right;width:80px;margin-left:5px" onclick="dialogclose(0)"> <input id="idx_dlgOkButton" type="button" value="OK" style="float:right;width:80px" onclick="dialogclose(1)"> </div> </div> <script>if(!String.prototype.startsWith){String.prototype.startsWith=function(a){return this.lastIndexOf(a,0)===0}}if(!String.prototype.endsWith){String.prototype.endsWith=function(a){return this.indexOf(a,this.length-a.length)!==-1}}function Q(a){return document.getElementById(a)}function QS(a){try{return Q(a).style}catch(a){}}function QE(a,b){try{Q(a).disabled=!b}catch(a){}}function QV(a,b){try{QS(a).display=(b?"":"none")}catch(a){}}function QA(a,b){Q(a).innerHTML+=b}function QH(a,b){Q(a).innerHTML=b}function inputBoxFocus(b){Q(b).focus();var a=Q(b).value;Q(b).value="";Q(b).value=a}function ReadShort(b,a){return(b.charCodeAt(a)<<8)+b.charCodeAt(a+1)}function ReadShortX(b,a){return(b.charCodeAt(a+1)<<8)+b.charCodeAt(a)}function ReadInt(b,a){return(b.charCodeAt(a)*16777216)+(b.charCodeAt(a+1)<<16)+(b.charCodeAt(a+2)<<8)+b.charCodeAt(a+3)}function ReadSInt(b,a){return(b.charCodeAt(a)<<24)+(b.charCodeAt(a+1)<<16)+(b.charCodeAt(a+2)<<8)+b.charCodeAt(a+3)}function ReadIntX(b,a){return(b.charCodeAt(a+3)*16777216)+(b.charCodeAt(a+2)<<16)+(b.charCodeAt(a+1)<<8)+b.charCodeAt(a)}function ShortToStr(a){return String.fromCharCode((a>>8)&255,a&255)}function ShortToStrX(a){return String.fromCharCode(a&255,(a>>8)&255)}function IntToStr(a){return String.fromCharCode((a>>24)&255,(a>>16)&255,(a>>8)&255,a&255)}function IntToStrX(a){return String.fromCharCode(a&255,(a>>8)&255,(a>>16)&255,(a>>24)&255)}function MakeToArray(a){if(!a||a==null||typeof a=="object"){return a}return[a]}function SplitArray(a){return a.split(",")}function Clone(a){return JSON.parse(JSON.stringify(a))}function EscapeHtml(a){if(typeof a=="string"){return a.replace(/&/g,"&amp;").replace(/>/g,"&gt;").replace(/</g,"&lt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}if(typeof a=="boolean"){return a}if(typeof a=="number"){return a}}function EscapeHtmlBreaks(a){if(typeof a=="string"){return a.replace(/&/g,"&amp;").replace(/>/g,"&gt;").replace(/</g,"&lt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;").replace(/\r/g,"<br />").replace(/\n/g,"").replace(/\t/g,"&nbsp;&nbsp;")}if(typeof a=="boolean"){return a}if(typeof a=="number"){return a}}function ArrayElementMove(a,b,c){a.splice(c,0,a.splice(b,1)[0])}function ObjectToStringEx(e,a){var d="";if(e!=0&&(!e||e==null)){return"(Null)"}if(e instanceof Array){for(var b in e){d+="<br />"+gap(a)+"Item #"+b+": "+ObjectToStringEx(e[b],a+1)}}else{if(e instanceof Object){for(var b in e){d+="<br />"+gap(a)+b+" = "+ObjectToStringEx(e[b],a+1)}}else{d+=EscapeHtml(e)}}return d}function ObjectToStringEx2(e,a){var d="";if(e!=0&&(!e||e==null)){return"(Null)"}if(e instanceof Array){for(var b in e){d+="\r\n"+gap2(a)+"Item #"+b+": "+ObjectToStringEx2(e[b],a+1)}}else{if(e instanceof Object){for(var b in e){d+="\r\n"+gap2(a)+b+" = "+ObjectToStringEx2(e[b],a+1)}}else{d+=EscapeHtml(e)}}return d}function gap(a){var d="";for(var b=0;b<(a*4);b++){d+="&nbsp;"}return d}function gap2(a){var d="";for(var b=0;b<(a*4);b++){d+=" "}return d}function ObjectToString(a){return ObjectToStringEx(a,0)}function ObjectToString2(a){return ObjectToStringEx2(a,0)}function hex2rstr(a){if(typeof a!="string"||a.length==0){return""}var c="",b=(""+a).match(/../g),e;while(e=b.shift()){c+=String.fromCharCode("0x"+e)}return c}function char2hex(a){return(a+256).toString(16).substr(-2).toUpperCase()}function rstr2hex(b){var c="",a;for(a=0;a<b.length;a++){c+=char2hex(b.charCodeAt(a))}return c}function encode_utf8(a){return unescape(encodeURIComponent(a))}function decode_utf8(a){return decodeURIComponent(escape(a))}function data2blob(c){var b=new Array(c.length);for(var d=0;d<c.length;d++){b[d]=c.charCodeAt(d)}var a=new Blob([new Uint8Array(b)]);return a}function random(a){return Math.floor(Math.random()*a)}function trademarks(a){return a.replace(/\(R\)/g,"&reg;").replace(/\(TM\)/g,"&trade;")}"use strict";var passhint="{{{passhint}}}";var newAccountPass=parseInt("{{{newAccountPass}}}");var emailCheck=("{{{emailcheck}}}"=="true");var passRequirements="{{{passRequirements}}}";var hardwareKeyChallenge=decodeURIComponent("{{{hkey}}}");if(passRequirements!=""){passRequirements=JSON.parse(decodeURIComponent(passRequirements))}else{passRequirements={}}var passRequirementsEx=((passRequirements.min!=null)||(passRequirements.max!=null)||(passRequirements.upper!=null)||(passRequirements.lower!=null)||(passRequirements.numeric!=null)||(passRequirements.nonalpha!=null));var features=parseInt("{{{features}}}");var webPageFullScreen=getstore("webPageFullScreen",true);if(webPageFullScreen=="false"){webPageFullScreen=false}if(webPageFullScreen=="true"){webPageFullScreen=true}var welcomeText=decodeURIComponent("{{{welcometext}}}");var currentpanel=0;toggleFullScreen();function startup(){if((features&32)==0){var d=null;try{d=top.location.toString().toLowerCase()}catch(a){}if(top!=self&&(d==null||top.active==false)){top.location=self.location;return}}QV("createPanelHint",passRequirements.hint===true);QV("resetpasswordpanelHint",passRequirements.hint===true);if(welcomeText){QH("welcomeText",welcomeText)}QV("welcomeText",true);window.onresize=center;center();validateLogin();validateCreate();if("{{loginmode}}"!=""){go(parseInt("{{loginmode}}"))}else{go(1)}QV("newAccountDiv",("{{{newAccount}}}"!="0")&&("{{{newAccount}}}"!="false"));if((passhint!=null)&&(passhint.length>0)){QV("showPassHintLink",true)}QV("newAccountPass",(newAccountPass==1));QV("resetAccountDiv",(emailCheck==true));QV("hrAccountDiv",(emailCheck==true)||(newAccountPass==1));if("{{loginmode}}"=="4"){try{if(hardwareKeyChallenge.length>0){hardwareKeyChallenge=JSON.parse(hardwareKeyChallenge)}else{hardwareKeyChallenge=null}}catch(b){hardwareKeyChallenge=null}if((hardwareKeyChallenge!=null)&&(hardwareKeyChallenge.type=="webAuthn")){hardwareKeyChallenge.challenge=Uint8Array.from(atob(hardwareKeyChallenge.challenge),function(e){return e.charCodeAt(0)}).buffer;var f={challenge:hardwareKeyChallenge.challenge,allowCredentials:[],timeout:hardwareKeyChallenge.timeout};for(var c=0;c<hardwareKeyChallenge.keyIds.length;c++){f.allowCredentials.push({id:Uint8Array.from(atob(hardwareKeyChallenge.keyIds[c]),function(e){return e.charCodeAt(0)}),type:"public-key",transports:["usb","ble","nfc"],})}navigator.credentials.get({publicKey:f}).then(function(g){var e={id:btoa(String.fromCharCode.apply(null,new Uint8Array(g.rawId))),clientDataJSON:btoa(String.fromCharCode.apply(null,new Uint8Array(g.response.clientDataJSON))),userHandle:btoa(String.fromCharCode.apply(null,new Uint8Array(g.response.userHandle))),signature:btoa(String.fromCharCode.apply(null,new Uint8Array(g.response.signature))),authenticatorData:btoa(String.fromCharCode.apply(null,new Uint8Array(g.response.authenticatorData))),};Q("hwtokenInput").value=JSON.stringify(e);QE("tokenOkButton",true);Q("tokenOkButton").click()},function(e){console.log("credentials-get error",e)})}else{if((hardwareKeyChallenge!=null)&&u2fSupported()){window.u2f.sign(hardwareKeyChallenge.appId,hardwareKeyChallenge.challenge,hardwareKeyChallenge.registeredKeys,function(e){if((currentpanel==4)&&e.signatureData){Q("hwtokenInput").value=JSON.stringify(e);QE("tokenOkButton",true);Q("tokenOkButton").click()}},hardwareKeyChallenge.timeoutSeconds)}}}if("{{loginmode}}"=="5"){try{if(hardwareKeyChallenge.length>0){hardwareKeyChallenge=JSON.parse(hardwareKeyChallenge)}else{hardwareKeyChallenge=null}}catch(b){hardwareKeyChallenge=null}if((hardwareKeyChallenge!=null)&&(hardwareKeyChallenge.type=="webAuthn")){hardwareKeyChallenge.challenge=Uint8Array.from(atob(hardwareKeyChallenge.challenge),function(e){return e.charCodeAt(0)}).buffer;var f={challenge:hardwareKeyChallenge.challenge,allowCredentials:[],timeout:hardwareKeyChallenge.timeout};for(var c=0;c<hardwareKeyChallenge.keyIds.length;c++){f.allowCredentials.push({id:Uint8Array.from(atob(hardwareKeyChallenge.keyIds[c]),function(e){return e.charCodeAt(0)}),type:"public-key",transports:["usb","ble","nfc"],})}navigator.credentials.get({publicKey:f}).then(function(g){var e={id:btoa(String.fromCharCode.apply(null,new Uint8Array(g.rawId))),clientDataJSON:btoa(String.fromCharCode.apply(null,new Uint8Array(g.response.clientDataJSON))),userHandle:btoa(String.fromCharCode.apply(null,new Uint8Array(g.response.userHandle))),signature:btoa(String.fromCharCode.apply(null,new Uint8Array(g.response.signature))),authenticatorData:btoa(String.fromCharCode.apply(null,new Uint8Array(g.response.authenticatorData))),};Q("resetHwtokenInput").value=JSON.stringify(e);QE("resetTokenOkButton",true);Q("resetTokenOkButton").click()},function(e){console.log("credentials-get error",e)})}else{if((hardwareKeyChallenge!=null)&&u2fSupported()){window.u2f.sign(hardwareKeyChallenge.appId,hardwareKeyChallenge.challenge,hardwareKeyChallenge.registeredKeys,function(e){if((currentpanel==5)&&e.signatureData){Q("resetHwtokenInput").value=JSON.stringify(e);QE("resetTokenOkButton",true);Q("resetTokenOkButton").click()}},hardwareKeyChallenge.timeoutSeconds)}}}}function showPassHint(){messagebox("Password Hint",passhint)}function xgo(a){QV("message1",false);QV("message2",false);QV("message3",false);QV("message4",false);QV("message5",false);QV("message6",false);go(a)}function go(a){currentpanel=a;setDialogMode(0);QV("showPassHintLink",false);QV("loginpanel",a==1);QV("createpanel",a==2);QV("resetpanel",a==3);QV("tokenpanel",a==4);QV("resettokenpanel",a==5);QV("resetpasswordpanel",a==6);if(a==1){Q("username").focus()}if(a==2){Q("ausername").focus()}if(a==3){Q("remail").focus()}if(a==4){Q("tokenInput").focus()}if(a==5){Q("resetTokenInput").focus()}if(a==6){Q("rapassword1").focus()}}function validateLogin(a,b){var c=((Q("username").value.length>0)&&(Q("username").value.indexOf(" ")==-1)&&(Q("password").value.length>0));QE("loginButton",c);setDialogMode(0);if((b!=null)&&(b.keyCode==13)){if(a==1){Q("password").focus()}else{if(a==2){Q("loginButton").click()}}}if(b!=null){haltEvent(b)}}function validateCreate(a,b){setDialogMode(0);var k=(Q("ausername").value.length>0)&&(Q("ausername").value.indexOf(" ")==-1);var c=(validateEmail(Q("aemail").value)==true);var g=(Q("apassword1").value.length>0);var h=(Q("apassword2").value.length>0)&&(Q("apassword2").value==Q("apassword1").value);var d=(newAccountPass==0)||(Q("anewaccountpass").value.length>0);var f=(k&&c&&g&&h&&d);QS("nuUser").color=k?"black":"#7b241c";QS("nuEmail").color=c?"black":"#7b241c";QS("nuPass1").color=g?"black":"#7b241c";QS("nuPass2").color=h?"black":"#7b241c";QS("nuToken").color=d?"black":"#7b241c";if(Q("apassword1").value==""){QH("passWarning","");QV("passwordPolicyCallout",false)}else{if(!passRequirementsEx){var j=checkPasswordStrength(Q("apassword1").value);if(j>=80){QH("passWarning","<span style=color:green><b>Strong Password</b><span>")}else{if(j>=60){QH("passWarning","<span style=color:blue><b>Good Password</b><span>")}else{QH("passWarning","<span style=color:red><b>Weak Password</b><span>")}}}else{var i=checkPasswordRequirements(Q("apassword1").value,passRequirements);if(i==false){f=false;QS("nuPass1").color="#7b241c";QS("nuPass2").color="#7b241c";QH("passWarning","<div style=color:red;cursor:pointer onclick=showPasswordPolicy()><b>Password Policy</b><div>");QV("passwordPolicyCallout",true);QH("passwordPolicyCallout",passwordPolicyText(Q("apassword1").value))}else{QH("passWarning","");QV("passwordPolicyCallout",false)}}}if((b!=null)&&(b.keyCode==13)){if(a==1){Q("aemail").focus()}if(a==2){Q("apassword1").focus()}if(a==3){Q("apassword2").focus()}if(a==4){Q("apasswordhint").focus()}if(a==5){if(newAccountPass==1){Q("anewaccountpass").focus()}else{Q("createButton").click()}}if(a==6){Q("createButton").click()}}if(b!=null){haltEvent(b)}QE("createButton",f)}function validatePassReset(a,b){setDialogMode(0);var d=(Q("rapassword1").value.length>0);var f=(Q("rapassword2").value.length>0)&&(Q("rapassword2").value==Q("rapassword1").value);var c=(d&&f);QS("rnuPass1").color=d?"black":"#7b241c";QS("rnuPass2").color=f?"black":"#7b241c";if(Q("rapassword1").value==""){QH("rpassWarning","");QV("rpasswordPolicyCallout",false)}else{if(!passRequirementsEx){var h=checkPasswordStrength(Q("rapassword1").value);if(h>=80){QH("rpassWarning","<span style=color:green><b>Strong Password</b><span>")}else{if(h>=60){QH("rpassWarning","<span style=color:blue><b>Good Password</b><span>")}else{QH("rpassWarning","<span style=color:red><b>Weak Password</b><span>")}}}else{var g=checkPasswordRequirements(Q("rapassword1").value,passRequirements);if(g==false){c=false;QS("rnuPass1").color="#7b241c";QS("rnuPass2").color="#7b241c";QH("rpassWarning","<div style=color:red;cursor:pointer onclick=showPasswordPolicy()><b>Password Policy</b><div>");QV("rpasswordPolicyCallout",true);QH("rpasswordPolicyCallout",passwordPolicyText(Q("rapassword1").value))}else{QH("rpassWarning","");QV("rpasswordPolicyCallout",false)}}}if((b!=null)&&(b.keyCode==13)){if(a==2){Q("rapassword1").focus()}if(a==3){Q("rapassword2").focus()}if(a==4){Q("rapasswordhint").focus()}if(a==6){Q("resetPassButton").click()}}if(b!=null){haltEvent(b)}QE("resetPassButton",c)}function passwordPolicyText(b){var c="<div style=text-align:left>";var a=strCount(b);if(passRequirements.min&&((b==null)||(b.length<passRequirements.min))){c+="Minimum length of "+passRequirements.min+"<br />"}if(passRequirements.max&&((b==null)||(b.length>passRequirements.max))){c+="Maximum length of "+passRequirements.max+"<br />"}if(passRequirements.upper&&((b==null)||(a.upper<passRequirements.upper))){c+=""+passRequirements.upper+" upper case<br />"}if(passRequirements.lower&&((b==null)||(a.lower<passRequirements.lower))){c+=""+passRequirements.lower+" lower case<br />"}if(passRequirements.numeric&&((b==null)||(a.numeric<passRequirements.numeric))){c+=""+passRequirements.numeric+" numeric<br />"}if(passRequirements.nonalpha&&((b==null)||(a.nonalpha<passRequirements.nonalpha))){c+=passRequirements.nonalpha+" non-alphanumeric<br />"}c+="</div>";return c}function showPasswordPolicy(){messagebox("Password Policy",passwordPolicyText())}function validateReset(a){setDialogMode(0);var b=validateEmail(Q("remail").value);QE("eresetButton",b);if((a!=null)&&(a.keyCode==13)&&(b==true)){Q("eresetButton").click()}if(a!=null){haltEvent(a)}}function checkPasswordStrength(e){var f=0,d={},g=0,h={digits:/\d/.test(e),lower:/[a-z]/.test(e),upper:/[A-Z]/.test(e),nonWords:/\W/.test(e)};if(!e){return 0}for(var b=0;b<e.length;b++){d[e[b]]=(d[e[b]]||0)+1;f+=5/d[e[b]]}for(var a in h){g+=(h[a]==true)?1:0}return parseInt(f+(g-1)*10)}function checkPasswordRequirements(b,c){if((c==null)||(c=="")||(typeof c!="object")){return true}if(c.min){if(b.length<c.min){return false}}if(c.max){if(b.length>c.max){return false}}var a=strCount(b);if(c.numeric&&(a.numeric<c.numeric)){return false}if(c.lower&&(a.lower<c.lower)){return false}if(c.upper&&(a.upper<c.upper)){return false}if(c.nonalpha&&(a.nonalpha<c.nonalpha)){return false}return true}function strCount(c){var a={numeric:0,lower:0,upper:0,nonalpha:0};if(typeof c!="string"){return a}for(var b=0;b<c.length;b++){if(/\d/.test(c[b])){a.numeric++}if(/[a-z]/.test(c[b])){a.lower++}if(/[A-Z]/.test(c[b])){a.upper++}if(/\W/.test(c[b])){a.nonalpha++}}return a}function checkToken(){var a=Q("tokenInput").value;var b=a.split(" ").join("");if(a!=b){Q("tokenInput").value=b}QE("tokenOkButton",(Q("tokenInput").value.length==6)||(Q("tokenInput").value.length==8)||(Q("tokenInput").value.length==44))}function resetCheckToken(){var a=Q("resetTokenInput").value;var b=a.split(" ").join("");if(a!=b){Q("resetTokenInput").value=b}QE("resetTokenOkButton",(Q("resetTokenInput").value.length==6)||(Q("resetTokenInput").value.length==8)||(Q("resetTokenInput").value.length==44))}var xxdialogMode;var xxdialogFunc;var xxdialogButtons;var xxdialogTag;var xxcurrentView=0;function setDialogMode(j,k,a,e,d,h){xxdialogMode=j;xxdialogFunc=e;xxdialogButtons=a;xxdialogTag=h;QE("idx_dlgOkButton",true);QV("idx_dlgOkButton",a&1);QV("idx_dlgCancelButton",a&2);QV("id_dialogclose",(a&2)||(a&8));QV("idx_dlgButtonBar",a&7);if(k){QH("id_dialogtitle",k)}for(var g=1;g<24;g++){QV("dialog"+g,g==j)}QV("dialog",j);if(d){if(j==2){QH("id_dialogOptions",d)}else{QH("id_dialogMessage",d)}}}function dialogclose(e){var c=xxdialogFunc;var a=xxdialogButtons;var d=xxdialogTag;setDialogMode();if(((a&8)||e)&&c){c(e,d)}}function toggleFullScreen(a){if(a===1){webPageFullScreen=!webPageFullScreen;putstore("webPageFullScreen",webPageFullScreen)}if(webPageFullScreen==false){QS("container").width="960px";QS("container")["min-width"]="960px";QS("container")["border-right"]="1px solid #b7b7b7";QS("container")["border-left"]="1px solid #b7b7b7";QS("container")["overflow"]="hidden";QS("column_l").height="";QS("column_l").width="930px";QS("column_l")["overflow-y"]="";QS("column_l")["max-height"]="calc(100vh - 111px)";QS("column_l")["min-width"]="";QS("masthead")["width"]="960px"}else{QS("container").width="100%";QS("container")["min-width"]="";QS("container")["border-right"]="0";QS("container")["border-left"]="0";QS("container")["overflow"]="hidden";QS("column_l").height="calc(100vh - 135px)";QS("column_l").width="";QS("column_l")["overflow-y"]="auto";QS("column_l")["max-height"]="calc(100vh - 111px)";QS("column_l")["min-width"]="";QS("masthead")["width"]="100%"}QV("body",true);center()}function center(){var c=getDocWidth();QS("dialog").left=((((c-400)/2))+"px");var b=(webPageFullScreen==false)||(c>800);QV("welcomeimage",b);Q("logincell").setAttribute("align",b?"left":"center");if(webPageFullScreen==false){QS("centralTable")["margin-top"]=""}else{var a=(Q("column_l").clientHeight/2)-250;if(a<0){a=0}QS("centralTable")["margin-top"]=a+"px"}}function messagebox(b,a){QH("id_dialogMessage",a);setDialogMode(1,b,1)}function statusbox(b,a){QH("id_dialogMessage",a);setDialogMode(1,b)}function getDocWidth(){if(window.innerWidth){return window.innerWidth}if(document.documentElement&&document.documentElement.clientWidth&&document.documentElement.clientWidth!=0){return document.documentElement.clientWidth}return document.getElementsByTagName("body")[0].clientWidth}function haltEvent(a){if(a.preventDefault){a.preventDefault()}if(a.stopPropagation){a.stopPropagation()}return false}function haltReturn(a){if(a.keyCode==13){haltEvent(a)}}function validateEmail(b){var a=/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;return a.test(b)}function putstore(b,c){try{if(typeof(localStorage)==="undefined"){return}localStorage.setItem(b,c)}catch(a){}}function getstore(b,d){try{if(typeof(localStorage)==="undefined"){return d}var c=localStorage.getItem(b);if((c==null)||(c==null)){return d}return c}catch(a){return d}}function u2fSupported(){return(window.u2f&&((navigator.userAgent.indexOf("Chrome/")>0)||(navigator.userAgent.indexOf("Firefox/")>0)||(navigator.userAgent.indexOf("Opera/")>0)||(navigator.userAgent.indexOf("Safari/")>0)))};</script></body></html>
\ No newline at end of file
views/login-mobile-min.handlebars
+1 -1217
@@ -1,1217 +1 @@
1 -<!DOCTYPE html> <html dir="ltr" xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta content="text/html; charset=utf-8" http-equiv="Content-Type"> <meta name="viewport" content="user-scalable=1.0,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="format-detection" content="telephone=no"> <title>MeshCentral - Login</title> <style> a{color:#036;text-decoration:underline;}#footer a{color:#fff;text-decoration:underline;}#footer a:hover{color:#fff;text-decoration:none;}</style> </head> <body onload="if (typeof(startup) !== 'undefined') startup();" style="overflow-y:hidden;margin:0;padding:0;border:0;color:black;font-size:13px;font-family:\'Trebuchet MS\', Arial, Helvetica, sans-serif"> <div id="container"> <div id="mastheadx"></div> <div id="masthead" style="background:url(logo.png) 0px 0px;background-size:341px 50px;background-color:#036;background-repeat:no-repeat;height:50px;width:100%;overflow:hidden"> <div style="float:left;height:66px;color:#c8c8c8;padding-left:10px;padding-top:6px"> <strong><font style="font-size:36px;font-family:Arial,Helvetica,sans-serif">{{{title}}}</font></strong> </div> <div style="float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:10px"> <strong><font style="font-size:12px;font-family:Arial,Helvetica,sans-serif">{{{title2}}}</font></strong> </div> </div> <div id="page_content" style="overflow-y:scroll;position:absolute;bottom:32px;top:50px;width:100%;display:flex;align-items:center"> <div id="column_l" style="padding:10px;width:100%"> <table style="width:100%"> <tr> <td align="center"> <div id="loginpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;clear:both;display:none"> <form action="login" method="post"> <div id="message1"> {{{message}}} </div> <div> <b>Log In</b> </div> <table> <tr> <td align="right" width="100">Username:</td> <td><input id="username" type="text" maxlength="64" name="username" onchange="validateLogin(1)" onkeyup="validateLogin(1,event)"></td> </tr> <tr> <td align="right">Password:</td> <td><input id="password" type="password" maxlength="256" name="password" autocomplete="off" onchange="validateLogin(2)" onkeyup="validateLogin(2,event)"></td> </tr> <tr> <td><div id="showPassHintLink" style="display:none"><a onclick="showPassHint()" style="cursor:pointer">Show Hint</a></div></td> <td align="right"><input id="loginButton" type="submit" value="Log In" disabled="disabled"></td> </tr> </table> <div id="hrAccountDiv" style="display:none"><hr></div> <div id="resetAccountDiv" style="display:none;padding:2px"> Forgot user/password? <a onclick="xgo(3)" style="cursor:pointer">Reset account</a>. </div> <div id="newAccountDiv" style="display:none;padding:2px"> Don&#39;t have an account? <a onclick="xgo(2)" style="cursor:pointer">Create one</a>. </div> </form> </div> <div id="createpanel" style="position:relative;display:none"> <div style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;clear:both"> <form action="createaccount" method="post"> <div id="message2"> {{{message}}} </div> <div> <b>Account Creation</b> </div> <div id="passwordPolicyCallout" style="left:-5px;top:10px;width:100px;position:absolute;background-color:#FFC;border-radius:5px;padding:5px;box-shadow:0px 0px 15px #666;font-size:10px"></div> <table> <tr> <td align="right" width="100">Username:</td> <td><input id="ausername" type="text" name="username" onchange="validateCreate(1)" maxlength="64" onkeydown="haltReturn(event)" onkeyup="validateCreate(1,event)"></td> </tr> <tr> <td align="right" width="100">Email:</td> <td><input id="aemail" type="text" name="email" onchange="validateCreate(2)" maxlength="256" onkeydown="haltReturn(event)" onkeyup="validateCreate(2,event)"></td> </tr> <tr> <td align="right">Password:</td> <td><input id="apassword1" type="password" name="password1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(3)" onkeyup="validateCreate(3,event)"></td> </tr> <tr> <td align="right">Password:</td> <td><input id="apassword2" type="password" name="password2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(4)" onkeyup="validateCreate(4,event)"></td> </tr> <tr id="createPanelHint" style="display:none"> <td align="right">Pass Hint:</td> <td><input id="apasswordhint" type="text" name="apasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(5)" onkeyup="validateCreate(5,event)"></td> </tr> <tr id="newAccountPass" title="Enter the account creation token"> <td align="right">Creation Token:</td> <td><input id="anewaccountpass" type="password" name="anewaccountpass" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(6)" onkeyup="validateCreate(6,event)"></td> </tr> <tr> <td colspan="2"> <div style="float:right"><input id="createButton" type="submit" value="Create Account" disabled="disabled"></div> <div id="passWarning" style="padding-top:6px"></div> </td> </tr> </table> <hr><a onclick="xgo(1)" style="cursor:pointer">Back to login</a> </form> </div> </div> <div id="resetpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;display:none;clear:both"> <form action="resetaccount" method="post"> <div id="message3"> {{{message}}} </div> <div> <b>Account Reset</b> </div> <table> <tr> <td align="right" width="100">Email:</td> <td><input id="remail" type="text" name="email" maxlength="256" onchange="validateReset()" onkeyup="validateReset(event)"></td> </tr> <tr> <td colspan="2"> <div style="float:right"><input id="eresetButton" type="submit" value="Reset Account" disabled="disabled"></div> <div id="passWarning" style="padding-top:6px"></div> </td> </tr> </table> <hr><a onclick="xgo(1)" style="cursor:pointer">Back to login</a> </form> </div> <div id="tokenpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;display:none;clear:both"> <form action="tokenlogin" method="post" autocomplete="off"> <div id="message4"> {{{message}}} </div> <table> <tr> <td align="right" width="100">Login token:</td> <td> <input id="tokenInput" type="text" name="token" maxlength="50" onchange="checkToken(event)" onkeyup="checkToken(event)" onkeydown="checkToken(event)" onfocus="checkTokenTimer(1)" onblur="checkTokenTimer(0)"> <input id="hwtokenInput" type="text" name="hwtoken" style="display:none"> </td> </tr> <tr> <td colspan="2"> <div style="float:right"><input id="tokenOkButton" type="submit" value="Login" disabled="disabled"></div> </td> </tr> </table> <hr><a onclick="xgo(1)" style="cursor:pointer">Back to login</a> </form> </div> <div id="resettokenpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;display:none;clear:both"> <form action="resetaccount" method="post" autocomplete="off"> <div id="message5"> {{{message}}} </div> <table> <tr> <td align="right" width="100">Login token:</td> <td> <input id="resetTokenInput" type="text" name="token" maxlength="50" onchange="resetCheckToken(event)" onpaste="resetCheckToken(event)" onkeyup="resetCheckToken(event)" onkeydown="resetCheckToken(event)"> <input id="resetHwtokenInput" type="text" name="hwtoken" style="display:none"> </td> </tr> <tr> <td colspan="2"> <div style="float:right"><input id="resetTokenOkButton" type="submit" value="Login" disabled="disabled"></div> </td> </tr> </table> <hr><a onclick="xgo(1)" style="cursor:pointer">Back to login</a> </form> </div> <div id="resetpasswordpanel" style="position:relative;background-color:#979797;border-radius:16px;width:300px;padding:16px;text-align:center;display:none"> <form action="resetpassword" method="post"> <div id="message6"> {{{message}}} </div> <div id="rpasswordPolicyCallout" style="left:-10px;width:100px;display:none;position:absolute;background-color:#FFC;border-radius:5px;padding:5px;box-shadow:0px 0px 15px #666;font-size:10px"></div> <table> <tr> <td id="rnuPass1" width="100" align="right">Password:</td> <td><input id="rapassword1" type="password" name="rpassword1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(3,event)" onkeyup="validatePassReset(3,event)"></td> </tr> <tr> <td id="rnuPass2" align="right">Password:</td> <td><input id="rapassword2" type="password" name="rpassword2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(4,event)" onkeyup="validatePassReset(4,event)"></td> </tr> <tr id="resetpasswordpanelHint" style="display:none"> <td id="rnuHint" align="right">Password Hint:</td> <td><input id="rapasswordhint" type="text" name="rpasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(5,event)" onkeyup="validatePassReset(5,event)"></td> </tr> <tr> <td colspan="2"> <div style="float:right"><input id="resetPassButton" type="submit" value="Reset Password" disabled="disabled"></div> <div id="rpassWarning" style="padding-top:6px"></div> </td> </tr> </table> <hr><a onclick="xgo(1)" style="cursor:pointer">Back to login</a> </form> </div> </td> </tr> </table> </div> </div> <div id="footer" style="height:32px;width:100%;text-align:center;background-color:#113962;position:absolute;bottom:0px"> <table cellpadding="0" cellspacing="6" style="width:100%"> <tr> <td style="text-align:left;color:white">{{{footer}}}</td> <td style="text-align:right">{{{rootCertLink}}}&nbsp;<a href="terms">Terms &amp; Privacy</a></td> </tr> </table> </div> </div> <div id="dialog" style="z-index:1000;background-color:#EEE;box-shadow:0px 0px 15px #666;font-family:Arial,Helvetica,sans-serif;border-radius:5px;position:fixed;top:180px;width:400px;display:none"> <div style="width:100%;background-color:#003366;color:#FFF;border-radius:5px 5px 0 0"> <div id="id_dialogclose" style="float:right;padding:5px;cursor:pointer" onclick="setDialogMode()"><b>X</b></div> <div id="id_dialogtitle" style="padding:5px"></div> <div style="width:100%;margin:6px"></div> </div> <div style="margin-right:16px;margin-left:8px"> <div id="dialog1" style="margin:auto;text-align:center;margin:3px"> <div id="id_dialogMessage" style="padding:10px"></div> </div> <div id="dialog2" style="margin:auto;margin:3px"> <div id="id_dialogOptions"></div> </div> </div> <div id="idx_dlgButtonBar" style="padding:10px;margin-bottom:20px"> <input id="idx_dlgCancelButton" type="button" value="Cancel" style="float:right;width:80px;margin-left:5px" onclick="dialogclose(0)"> <input id="idx_dlgOkButton" type="button" value="OK" style="float:right;width:80px" onclick="dialogclose(1)"> </div> </div> <script>/**
2 -* @description Set of short commonly used methods for handling HTML elements
3 -* @author Ylian Saint-Hilaire
4 -* @version v0.0.1b
5 -*/
6 -
7 -// Add startsWith for IE browser
8 -if (!String.prototype.startsWith) { String.prototype.startsWith = function (str) { return this.lastIndexOf(str, 0) === 0; }; }
9 -if (!String.prototype.endsWith) { String.prototype.endsWith = function (str) { return this.indexOf(str, this.length - str.length) !== -1; }; }
10 -
11 -// Quick UI functions, a bit of a replacement for jQuery
12 -//function Q(x) { if (document.getElementById(x) == null) { console.log('Invalid element: ' + x); } return document.getElementById(x); } // "Q"
13 -function Q(x) { return document.getElementById(x); } // "Q"
14 -function QS(x) { try { return Q(x).style; } catch (x) { } } // "Q" style
15 -function QE(x, y) { try { Q(x).disabled = !y; } catch (x) { } } // "Q" enable
16 -function QV(x, y) { try { QS(x).display = (y ? '' : 'none'); } catch (x) { } } // "Q" visible
17 -function QA(x, y) { Q(x).innerHTML += y; } // "Q" append
18 -function QH(x, y) { Q(x).innerHTML = y; } // "Q" html
19 -
20 -// Move cursor to end of input box
21 -function inputBoxFocus(x) { Q(x).focus(); var v = Q(x).value; Q(x).value = ''; Q(x).value = v; }
22 -
23 -// Binary encoding and decoding functions
24 -function ReadShort(v, p) { return (v.charCodeAt(p) << 8) + v.charCodeAt(p + 1); }
25 -function ReadShortX(v, p) { return (v.charCodeAt(p + 1) << 8) + v.charCodeAt(p); }
26 -function ReadInt(v, p) { return (v.charCodeAt(p) * 0x1000000) + (v.charCodeAt(p + 1) << 16) + (v.charCodeAt(p + 2) << 8) + v.charCodeAt(p + 3); } // We use "*0x1000000" instead of "<<24" because the shift converts the number to signed int32.
27 -function ReadSInt(v, p) { return (v.charCodeAt(p) << 24) + (v.charCodeAt(p + 1) << 16) + (v.charCodeAt(p + 2) << 8) + v.charCodeAt(p + 3); }
28 -function ReadIntX(v, p) { return (v.charCodeAt(p + 3) * 0x1000000) + (v.charCodeAt(p + 2) << 16) + (v.charCodeAt(p + 1) << 8) + v.charCodeAt(p); }
29 -function ShortToStr(v) { return String.fromCharCode((v >> 8) & 0xFF, v & 0xFF); }
30 -function ShortToStrX(v) { return String.fromCharCode(v & 0xFF, (v >> 8) & 0xFF); }
31 -function IntToStr(v) { return String.fromCharCode((v >> 24) & 0xFF, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF); }
32 -function IntToStrX(v) { return String.fromCharCode(v & 0xFF, (v >> 8) & 0xFF, (v >> 16) & 0xFF, (v >> 24) & 0xFF); }
33 -function MakeToArray(v) { if (!v || v == null || typeof v == 'object') return v; return [v]; }
34 -function SplitArray(v) { return v.split(','); }
35 -function Clone(v) { return JSON.parse(JSON.stringify(v)); }
36 -function EscapeHtml(x) { if (typeof x == "string") return x.replace(/&/g, '&amp;').replace(/>/g, '&gt;').replace(/</g, '&lt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;'); if (typeof x == "boolean") return x; if (typeof x == "number") return x; }
37 -function EscapeHtmlBreaks(x) { if (typeof x == "string") return x.replace(/&/g, '&amp;').replace(/>/g, '&gt;').replace(/</g, '&lt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;').replace(/\r/g, '<br />').replace(/\n/g, '').replace(/\t/g, '&nbsp;&nbsp;'); if (typeof x == "boolean") return x; if (typeof x == "number") return x; }
38 -
39 -// Move an element from one position in an array to a new position
40 -function ArrayElementMove(arr, from, to) { arr.splice(to, 0, arr.splice(from, 1)[0]); };
41 -
42 -// Print object for HTML
43 -function ObjectToStringEx(x, c) {
44 - var r = "";
45 - if (x != 0 && (!x || x == null)) return "(Null)";
46 - if (x instanceof Array) { for (var i in x) { r += '<br />' + gap(c) + "Item #" + i + ": " + ObjectToStringEx(x[i], c + 1); } }
47 - else if (x instanceof Object) { for (var i in x) { r += '<br />' + gap(c) + i + " = " + ObjectToStringEx(x[i], c + 1); } }
48 - else { r += EscapeHtml(x); }
49 - return r;
50 -}
51 -
52 -// Print object for console
53 -function ObjectToStringEx2(x, c) {
54 - var r = "";
55 - if (x != 0 && (!x || x == null)) return "(Null)";
56 - if (x instanceof Array) { for (var i in x) { r += '\r\n' + gap2(c) + "Item #" + i + ": " + ObjectToStringEx2(x[i], c + 1); } }
57 - else if (x instanceof Object) { for (var i in x) { r += '\r\n' + gap2(c) + i + " = " + ObjectToStringEx2(x[i], c + 1); } }
58 - else { r += EscapeHtml(x); }
59 - return r;
60 -}
61 -
62 -// Create an ident gap
63 -function gap(c) { var x = ''; for (var i = 0; i < (c * 4) ; i++) { x += '&nbsp;'; } return x; }
64 -function gap2(c) { var x = ''; for (var i = 0; i < (c * 4) ; i++) { x += ' '; } return x; }
65 -
66 -// Print an object in html
67 -function ObjectToString(x) { return ObjectToStringEx(x, 0); }
68 -function ObjectToString2(x) { return ObjectToStringEx2(x, 0); }
69 -
70 -// Convert a hex string to a raw string
71 -function hex2rstr(d) {
72 - if (typeof d != "string" || d.length == 0) return '';
73 - var r = '', m = ('' + d).match(/../g), t;
74 - while (t = m.shift()) r += String.fromCharCode('0x' + t);
75 - return r
76 -}
77 -
78 -// Convert decimal to hex
79 -function char2hex(i) { return (i + 0x100).toString(16).substr(-2).toUpperCase(); }
80 -
81 -// Convert a raw string to a hex string
82 -function rstr2hex(input) { var r = '', i; for (i = 0; i < input.length; i++) { r += char2hex(input.charCodeAt(i)); } return r; }
83 -
84 -// UTF-8 encoding & decoding functions
85 -function encode_utf8(s) { return unescape(encodeURIComponent(s)); }
86 -function decode_utf8(s) { return decodeURIComponent(escape(s)); }
87 -
88 -// Convert a string into a blob
89 -function data2blob(data) {
90 - var bytes = new Array(data.length);
91 - for (var i = 0; i < data.length; i++) bytes[i] = data.charCodeAt(i);
92 - var blob = new Blob([new Uint8Array(bytes)]);
93 - return blob;
94 -}
95 -
96 -// Generate random numbers
97 -function random(max) { return Math.floor(Math.random() * max); }
98 -
99 -// Trademarks
100 -function trademarks(x) { return x.replace(/\(R\)/g, '&reg;').replace(/\(TM\)/g, '&trade;'); }
101 -//Copyright 2014-2015 Google Inc. All rights reserved.
102 -
103 -//Use of this source code is governed by a BSD-style
104 -//license that can be found in the LICENSE file or at
105 -//https://developers.google.com/open-source/licenses/bsd
106 -
107 -/**
108 - * @fileoverview The U2F api.
109 - */
110 -'use strict';
111 -if (!window.u2f) {
112 -
113 - /**
114 - * Namespace for the U2F api.
115 - * @type {Object}
116 - */
117 -var u2f = u2f || {};
118 -
119 - /**
120 - * FIDO U2F Javascript API Version
121 - * @number
122 - */
123 -var js_api_version;
124 -
125 - /**
126 - * The U2F extension id
127 - * @const {string}
128 - */
129 -// The Chrome packaged app extension ID.
130 -// Uncomment this if you want to deploy a server instance that uses
131 -// the package Chrome app and does not require installing the U2F Chrome extension.
132 - u2f.EXTENSION_ID = 'kmendfapggjehodndflmmgagdbamhnfd';
133 - // The U2F Chrome extension ID.
134 - // Uncomment this if you want to deploy a server instance that uses
135 - // the U2F Chrome extension to authenticate.
136 - // u2f.EXTENSION_ID = 'pfboblefjcgdjicmnffhdgionmgcdmne';
137 -
138 -
139 - /**
140 - * Message types for messsages to/from the extension
141 - * @const
142 - * @enum {string}
143 - */
144 -u2f.MessageTypes = {
145 - 'U2F_REGISTER_REQUEST': 'u2f_register_request',
146 - 'U2F_REGISTER_RESPONSE': 'u2f_register_response',
147 - 'U2F_SIGN_REQUEST': 'u2f_sign_request',
148 - 'U2F_SIGN_RESPONSE': 'u2f_sign_response',
149 - 'U2F_GET_API_VERSION_REQUEST': 'u2f_get_api_version_request',
150 - 'U2F_GET_API_VERSION_RESPONSE': 'u2f_get_api_version_response'
151 - };
152 -
153 -
154 - /**
155 - * Response status codes
156 - * @const
157 - * @enum {number}
158 - */
159 -u2f.ErrorCodes = {
160 - 'OK': 0,
161 - 'OTHER_ERROR': 1,
162 - 'BAD_REQUEST': 2,
163 - 'CONFIGURATION_UNSUPPORTED': 3,
164 - 'DEVICE_INELIGIBLE': 4,
165 - 'TIMEOUT': 5
166 - };
167 -
168 -
169 - /**
170 - * A message for registration requests
171 - * @typedef {{
172 - * type: u2f.MessageTypes,
173 - * appId: ?string,
174 - * timeoutSeconds: ?number,
175 - * requestId: ?number
176 - * }}
177 - */
178 -u2f.U2fRequest;
179 -
180 -
181 - /**
182 - * A message for registration responses
183 - * @typedef {{
184 - * type: u2f.MessageTypes,
185 - * responseData: (u2f.Error | u2f.RegisterResponse | u2f.SignResponse),
186 - * requestId: ?number
187 - * }}
188 - */
189 -u2f.U2fResponse;
190 -
191 -
192 - /**
193 - * An error object for responses
194 - * @typedef {{
195 - * errorCode: u2f.ErrorCodes,
196 - * errorMessage: ?string
197 - * }}
198 - */
199 -u2f.Error;
200 -
201 - /**
202 - * Data object for a single sign request.
203 - * @typedef {enum {BLUETOOTH_RADIO, BLUETOOTH_LOW_ENERGY, USB, NFC}}
204 - */
205 -u2f.Transport;
206 -
207 -
208 - /**
209 - * Data object for a single sign request.
210 - * @typedef {Array<u2f.Transport>}
211 - */
212 -u2f.Transports;
213 -
214 - /**
215 - * Data object for a single sign request.
216 - * @typedef {{
217 - * version: string,
218 - * challenge: string,
219 - * keyHandle: string,
220 - * appId: string
221 - * }}
222 - */
223 -u2f.SignRequest;
224 -
225 -
226 - /**
227 - * Data object for a sign response.
228 - * @typedef {{
229 - * keyHandle: string,
230 - * signatureData: string,
231 - * clientData: string
232 - * }}
233 - */
234 -u2f.SignResponse;
235 -
236 -
237 - /**
238 - * Data object for a registration request.
239 - * @typedef {{
240 - * version: string,
241 - * challenge: string
242 - * }}
243 - */
244 -u2f.RegisterRequest;
245 -
246 -
247 - /**
248 - * Data object for a registration response.
249 - * @typedef {{
250 - * version: string,
251 - * keyHandle: string,
252 - * transports: Transports,
253 - * appId: string
254 - * }}
255 - */
256 -u2f.RegisterResponse;
257 -
258 -
259 - /**
260 - * Data object for a registered key.
261 - * @typedef {{
262 - * version: string,
263 - * keyHandle: string,
264 - * transports: ?Transports,
265 - * appId: ?string
266 - * }}
267 - */
268 -u2f.RegisteredKey;
269 -
270 -
271 - /**
272 - * Data object for a get API register response.
273 - * @typedef {{
274 - * js_api_version: number
275 - * }}
276 - */
277 -u2f.GetJsApiVersionResponse;
278 -
279 -
280 - //Low level MessagePort API support
281 -
282 - /**
283 - * Sets up a MessagePort to the U2F extension using the
284 - * available mechanisms.
285 - * @param {function((MessagePort|u2f.WrappedChromeRuntimePort_))} callback
286 - */
287 -u2f.getMessagePort = function (callback) {
288 - if (typeof chrome != 'undefined' && chrome.runtime) {
289 - // The actual message here does not matter, but we need to get a reply
290 - // for the callback to run. Thus, send an empty signature request
291 - // in order to get a failure response.
292 - var msg = {
293 - type: u2f.MessageTypes.U2F_SIGN_REQUEST,
294 - signRequests: []
295 - };
296 - chrome.runtime.sendMessage(u2f.EXTENSION_ID, msg, function () {
297 - if (!chrome.runtime.lastError) {
298 - // We are on a whitelisted origin and can talk directly
299 - // with the extension.
300 - u2f.getChromeRuntimePort_(callback);
301 - } else {
302 - // chrome.runtime was available, but we couldn't message
303 - // the extension directly, use iframe
304 - u2f.getIframePort_(callback);
305 - }
306 - });
307 - } else if (u2f.isAndroidChrome_()) {
308 - u2f.getAuthenticatorPort_(callback);
309 - } else if (u2f.isIosChrome_()) {
310 - u2f.getIosPort_(callback);
311 - } else {
312 - // chrome.runtime was not available at all, which is normal
313 - // when this origin doesn't have access to any extensions.
314 - u2f.getIframePort_(callback);
315 - }
316 - };
317 -
318 - /**
319 - * Detect chrome running on android based on the browser's useragent.
320 - * @private
321 - */
322 -u2f.isAndroidChrome_ = function () {
323 - var userAgent = navigator.userAgent;
324 - return userAgent.indexOf('Chrome') != -1 &&
325 - userAgent.indexOf('Android') != -1;
326 - };
327 -
328 - /**
329 - * Detect chrome running on iOS based on the browser's platform.
330 - * @private
331 - */
332 -u2f.isIosChrome_ = function () {
333 - var r = ["iPhone", "iPad", "iPod"];
334 - for (var i in r) { if (navigator.platform == r[i]) { return true; } }
335 - return false;
336 - //return $.inArray(navigator.platform, ["iPhone", "iPad", "iPod"]) > -1;
337 - };
338 -
339 - /**
340 - * Connects directly to the extension via chrome.runtime.connect.
341 - * @param {function(u2f.WrappedChromeRuntimePort_)} callback
342 - * @private
343 - */
344 -u2f.getChromeRuntimePort_ = function (callback) {
345 - var port = chrome.runtime.connect(u2f.EXTENSION_ID,
346 - { 'includeTlsChannelId': true });
347 - setTimeout(function () {
348 - callback(new u2f.WrappedChromeRuntimePort_(port));
349 - }, 0);
350 - };
351 -
352 - /**
353 - * Return a 'port' abstraction to the Authenticator app.
354 - * @param {function(u2f.WrappedAuthenticatorPort_)} callback
355 - * @private
356 - */
357 -u2f.getAuthenticatorPort_ = function (callback) {
358 - setTimeout(function () {
359 - callback(new u2f.WrappedAuthenticatorPort_());
360 - }, 0);
361 - };
362 -
363 - /**
364 - * Return a 'port' abstraction to the iOS client app.
365 - * @param {function(u2f.WrappedIosPort_)} callback
366 - * @private
367 - */
368 -u2f.getIosPort_ = function (callback) {
369 - setTimeout(function () {
370 - callback(new u2f.WrappedIosPort_());
371 - }, 0);
372 - };
373 -
374 - /**
375 - * A wrapper for chrome.runtime.Port that is compatible with MessagePort.
376 - * @param {Port} port
377 - * @constructor
378 - * @private
379 - */
380 -u2f.WrappedChromeRuntimePort_ = function (port) {
381 - this.port_ = port;
382 - };
383 -
384 - /**
385 - * Format and return a sign request compliant with the JS API version supported by the extension.
386 - * @param {Array<u2f.SignRequest>} signRequests
387 - * @param {number} timeoutSeconds
388 - * @param {number} reqId
389 - * @return {Object}
390 - */
391 -u2f.formatSignRequest_ =
392 - function (appId, challenge, registeredKeys, timeoutSeconds, reqId) {
393 - if (js_api_version === undefined || js_api_version < 1.1) {
394 - // Adapt request to the 1.0 JS API
395 - var signRequests = [];
396 - for (var i = 0; i < registeredKeys.length; i++) {
397 - signRequests[i] = {
398 - version: registeredKeys[i].version,
399 - challenge: challenge,
400 - keyHandle: registeredKeys[i].keyHandle,
401 - appId: appId
402 - };
403 - }
404 - return {
405 - type: u2f.MessageTypes.U2F_SIGN_REQUEST,
406 - signRequests: signRequests,
407 - timeoutSeconds: timeoutSeconds,
408 - requestId: reqId
409 - };
410 - }
411 - // JS 1.1 API
412 - return {
413 - type: u2f.MessageTypes.U2F_SIGN_REQUEST,
414 - appId: appId,
415 - challenge: challenge,
416 - registeredKeys: registeredKeys,
417 - timeoutSeconds: timeoutSeconds,
418 - requestId: reqId
419 - };
420 - };
421 -
422 - /**
423 - * Format and return a register request compliant with the JS API version supported by the extension..
424 - * @param {Array<u2f.SignRequest>} signRequests
425 - * @param {Array<u2f.RegisterRequest>} signRequests
426 - * @param {number} timeoutSeconds
427 - * @param {number} reqId
428 - * @return {Object}
429 - */
430 -u2f.formatRegisterRequest_ =
431 - function (appId, registeredKeys, registerRequests, timeoutSeconds, reqId) {
432 - if (js_api_version === undefined || js_api_version < 1.1) {
433 - // Adapt request to the 1.0 JS API
434 - for (var i = 0; i < registerRequests.length; i++) {
435 - registerRequests[i].appId = appId;
436 - }
437 - var signRequests = [];
438 - for (var i = 0; i < registeredKeys.length; i++) {
439 - signRequests[i] = {
440 - version: registeredKeys[i].version,
441 - challenge: registerRequests[0],
442 - keyHandle: registeredKeys[i].keyHandle,
443 - appId: appId
444 - };
445 - }
446 - return {
447 - type: u2f.MessageTypes.U2F_REGISTER_REQUEST,
448 - signRequests: signRequests,
449 - registerRequests: registerRequests,
450 - timeoutSeconds: timeoutSeconds,
451 - requestId: reqId
452 - };
453 - }
454 - // JS 1.1 API
455 - return {
456 - type: u2f.MessageTypes.U2F_REGISTER_REQUEST,
457 - appId: appId,
458 - registerRequests: registerRequests,
459 - registeredKeys: registeredKeys,
460 - timeoutSeconds: timeoutSeconds,
461 - requestId: reqId
462 - };
463 - };
464 -
465 -
466 - /**
467 - * Posts a message on the underlying channel.
468 - * @param {Object} message
469 - */
470 -u2f.WrappedChromeRuntimePort_.prototype.postMessage = function (message) {
471 - this.port_.postMessage(message);
472 - };
473 -
474 -
475 - /**
476 - * Emulates the HTML 5 addEventListener interface. Works only for the
477 - * onmessage event, which is hooked up to the chrome.runtime.Port.onMessage.
478 - * @param {string} eventName
479 - * @param {function({data: Object})} handler
480 - */
481 -u2f.WrappedChromeRuntimePort_.prototype.addEventListener =
482 - function (eventName, handler) {
483 - var name = eventName.toLowerCase();
484 - if (name == 'message' || name == 'onmessage') {
485 - this.port_.onMessage.addListener(function (message) {
486 - // Emulate a minimal MessageEvent object
487 - handler({ 'data': message });
488 - });
489 - } else {
490 - console.error('WrappedChromeRuntimePort only supports onMessage');
491 - }
492 - };
493 -
494 - /**
495 - * Wrap the Authenticator app with a MessagePort interface.
496 - * @constructor
497 - * @private
498 - */
499 -u2f.WrappedAuthenticatorPort_ = function () {
500 - this.requestId_ = -1;
501 - this.requestObject_ = null;
502 - }
503 -
504 - /**
505 - * Launch the Authenticator intent.
506 - * @param {Object} message
507 - */
508 -u2f.WrappedAuthenticatorPort_.prototype.postMessage = function (message) {
509 - var intentUrl =
510 - u2f.WrappedAuthenticatorPort_.INTENT_URL_BASE_ +
511 - ';S.request=' + encodeURIComponent(JSON.stringify(message)) +
512 - ';end';
513 - document.location = intentUrl;
514 - };
515 -
516 - /**
517 - * Tells what type of port this is.
518 - * @return {String} port type
519 - */
520 -u2f.WrappedAuthenticatorPort_.prototype.getPortType = function () {
521 - return "WrappedAuthenticatorPort_";
522 - };
523 -
524 -
525 - /**
526 - * Emulates the HTML 5 addEventListener interface.
527 - * @param {string} eventName
528 - * @param {function({data: Object})} handler
529 - */
530 -u2f.WrappedAuthenticatorPort_.prototype.addEventListener = function (eventName, handler) {
531 - var name = eventName.toLowerCase();
532 - if (name == 'message') {
533 - var self = this;
534 - /* Register a callback to that executes when
535 - * chrome injects the response. */
536 - window.addEventListener(
537 - 'message', self.onRequestUpdate_.bind(self, handler), false);
538 - } else {
539 - console.error('WrappedAuthenticatorPort only supports message');
540 - }
541 - };
542 -
543 - /**
544 - * Callback invoked when a response is received from the Authenticator.
545 - * @param function({data: Object}) callback
546 - * @param {Object} message message Object
547 - */
548 -u2f.WrappedAuthenticatorPort_.prototype.onRequestUpdate_ =
549 - function (callback, message) {
550 - var messageObject = JSON.parse(message.data);
551 - var intentUrl = messageObject['intentURL'];
552 -
553 - var errorCode = messageObject['errorCode'];
554 - var responseObject = null;
555 - if (messageObject.hasOwnProperty('data')) {
556 - responseObject = /** @type {Object} */ (
557 - JSON.parse(messageObject['data']));
558 - }
559 -
560 - callback({ 'data': responseObject });
561 - };
562 -
563 - /**
564 - * Base URL for intents to Authenticator.
565 - * @const
566 - * @private
567 - */
568 -u2f.WrappedAuthenticatorPort_.INTENT_URL_BASE_ =
569 - 'intent:#Intent;action=com.google.android.apps.authenticator.AUTHENTICATE';
570 -
571 - /**
572 - * Wrap the iOS client app with a MessagePort interface.
573 - * @constructor
574 - * @private
575 - */
576 -u2f.WrappedIosPort_ = function () { };
577 -
578 - /**
579 - * Launch the iOS client app request
580 - * @param {Object} message
581 - */
582 -u2f.WrappedIosPort_.prototype.postMessage = function (message) {
583 - var str = JSON.stringify(message);
584 - var url = "u2f://auth?" + encodeURI(str);
585 - location.replace(url);
586 - };
587 -
588 - /**
589 - * Tells what type of port this is.
590 - * @return {String} port type
591 - */
592 -u2f.WrappedIosPort_.prototype.getPortType = function () {
593 - return "WrappedIosPort_";
594 - };
595 -
596 - /**
597 - * Emulates the HTML 5 addEventListener interface.
598 - * @param {string} eventName
599 - * @param {function({data: Object})} handler
600 - */
601 -u2f.WrappedIosPort_.prototype.addEventListener = function (eventName, handler) {
602 - var name = eventName.toLowerCase();
603 - if (name !== 'message') {
604 - console.error('WrappedIosPort only supports message');
605 - }
606 - };
607 -
608 - /**
609 - * Sets up an embedded trampoline iframe, sourced from the extension.
610 - * @param {function(MessagePort)} callback
611 - * @private
612 - */
613 -u2f.getIframePort_ = function (callback) {
614 - // Create the iframe
615 - var iframeOrigin = 'chrome-extension://' + u2f.EXTENSION_ID;
616 - var iframe = document.createElement('iframe');
617 - iframe.src = iframeOrigin + '/u2f-comms.html';
618 - iframe.setAttribute('style', 'display:none');
619 - document.body.appendChild(iframe);
620 -
621 - var channel = new MessageChannel();
622 - var ready = function (message) {
623 - if (message.data == 'ready') {
624 - channel.port1.removeEventListener('message', ready);
625 - callback(channel.port1);
626 - } else {
627 - console.error('First event on iframe port was not "ready"');
628 - }
629 - };
630 - channel.port1.addEventListener('message', ready);
631 - channel.port1.start();
632 -
633 - iframe.addEventListener('load', function () {
634 - // Deliver the port to the iframe and initialize
635 - iframe.contentWindow.postMessage('init', iframeOrigin, [channel.port2]);
636 - });
637 - };
638 -
639 -
640 - //High-level JS API
641 -
642 - /**
643 - * Default extension response timeout in seconds.
644 - * @const
645 - */
646 -u2f.EXTENSION_TIMEOUT_SEC = 30;
647 -
648 - /**
649 - * A singleton instance for a MessagePort to the extension.
650 - * @type {MessagePort|u2f.WrappedChromeRuntimePort_}
651 - * @private
652 - */
653 -u2f.port_ = null;
654 -
655 - /**
656 - * Callbacks waiting for a port
657 - * @type {Array<function((MessagePort|u2f.WrappedChromeRuntimePort_))>}
658 - * @private
659 - */
660 -u2f.waitingForPort_ = [];
661 -
662 - /**
663 - * A counter for requestIds.
664 - * @type {number}
665 - * @private
666 - */
667 -u2f.reqCounter_ = 0;
668 -
669 - /**
670 - * A map from requestIds to client callbacks
671 - * @type {Object.<number,(function((u2f.Error|u2f.RegisterResponse))
672 - * |function((u2f.Error|u2f.SignResponse)))>}
673 - * @private
674 - */
675 -u2f.callbackMap_ = {};
676 -
677 - /**
678 - * Creates or retrieves the MessagePort singleton to use.
679 - * @param {function((MessagePort|u2f.WrappedChromeRuntimePort_))} callback
680 - * @private
681 - */
682 -u2f.getPortSingleton_ = function (callback) {
683 - if (u2f.port_) {
684 - callback(u2f.port_);
685 - } else {
686 - if (u2f.waitingForPort_.length == 0) {
687 - u2f.getMessagePort(function (port) {
688 - u2f.port_ = port;
689 - u2f.port_.addEventListener('message',
690 - /** @type {function(Event)} */ (u2f.responseHandler_));
691 -
692 - // Careful, here be async callbacks. Maybe.
693 - while (u2f.waitingForPort_.length)
694 - u2f.waitingForPort_.shift()(u2f.port_);
695 - });
696 - }
697 - u2f.waitingForPort_.push(callback);
698 - }
699 - };
700 -
701 - /**
702 - * Handles response messages from the extension.
703 - * @param {MessageEvent.<u2f.Response>} message
704 - * @private
705 - */
706 -u2f.responseHandler_ = function (message) {
707 - var response = message.data;
708 - var reqId = response['requestId'];
709 - if (!reqId || !u2f.callbackMap_[reqId]) {
710 - console.error('Unknown or missing requestId in response.');
711 - return;
712 - }
713 - var cb = u2f.callbackMap_[reqId];
714 - delete u2f.callbackMap_[reqId];
715 - cb(response['responseData']);
716 - };
717 -
718 - /**
719 - * Dispatches an array of sign requests to available U2F tokens.
720 - * If the JS API version supported by the extension is unknown, it first sends a
721 - * message to the extension to find out the supported API version and then it sends
722 - * the sign request.
723 - * @param {string=} appId
724 - * @param {string=} challenge
725 - * @param {Array<u2f.RegisteredKey>} registeredKeys
726 - * @param {function((u2f.Error|u2f.SignResponse))} callback
727 - * @param {number=} opt_timeoutSeconds
728 - */
729 -u2f.sign = function (appId, challenge, registeredKeys, callback, opt_timeoutSeconds) {
730 - if (js_api_version === undefined) {
731 - // Send a message to get the extension to JS API version, then send the actual sign request.
732 - u2f.getApiVersion(
733 - function (response) {
734 - js_api_version = response['js_api_version'] === undefined ? 0 : response['js_api_version'];
735 - //console.log("Extension JS API Version: ", js_api_version);
736 - u2f.sendSignRequest(appId, challenge, registeredKeys, callback, opt_timeoutSeconds);
737 - });
738 - } else {
739 - // We know the JS API version. Send the actual sign request in the supported API version.
740 - u2f.sendSignRequest(appId, challenge, registeredKeys, callback, opt_timeoutSeconds);
741 - }
742 - };
743 -
744 - /**
745 - * Dispatches an array of sign requests to available U2F tokens.
746 - * @param {string=} appId
747 - * @param {string=} challenge
748 - * @param {Array<u2f.RegisteredKey>} registeredKeys
749 - * @param {function((u2f.Error|u2f.SignResponse))} callback
750 - * @param {number=} opt_timeoutSeconds
751 - */
752 -u2f.sendSignRequest = function (appId, challenge, registeredKeys, callback, opt_timeoutSeconds) {
753 - u2f.getPortSingleton_(function (port) {
754 - var reqId = ++u2f.reqCounter_;
755 - u2f.callbackMap_[reqId] = callback;
756 - var timeoutSeconds = (typeof opt_timeoutSeconds !== 'undefined' ?
757 - opt_timeoutSeconds : u2f.EXTENSION_TIMEOUT_SEC);
758 - var req = u2f.formatSignRequest_(appId, challenge, registeredKeys, timeoutSeconds, reqId);
759 - port.postMessage(req);
760 - });
761 - };
762 -
763 - /**
764 - * Dispatches register requests to available U2F tokens. An array of sign
765 - * requests identifies already registered tokens.
766 - * If the JS API version supported by the extension is unknown, it first sends a
767 - * message to the extension to find out the supported API version and then it sends
768 - * the register request.
769 - * @param {string=} appId
770 - * @param {Array<u2f.RegisterRequest>} registerRequests
771 - * @param {Array<u2f.RegisteredKey>} registeredKeys
772 - * @param {function((u2f.Error|u2f.RegisterResponse))} callback
773 - * @param {number=} opt_timeoutSeconds
774 - */
775 -u2f.register = function (appId, registerRequests, registeredKeys, callback, opt_timeoutSeconds) {
776 - if (js_api_version === undefined) {
777 - // Send a message to get the extension to JS API version, then send the actual register request.
778 - u2f.getApiVersion(
779 - function (response) {
780 - js_api_version = response['js_api_version'] === undefined ? 0: response['js_api_version'];
781 - //console.log("Extension JS API Version: ", js_api_version);
782 - u2f.sendRegisterRequest(appId, registerRequests, registeredKeys,
783 - callback, opt_timeoutSeconds);
784 - });
785 - } else {
786 - // We know the JS API version. Send the actual register request in the supported API version.
787 - u2f.sendRegisterRequest(appId, registerRequests, registeredKeys,
788 - callback, opt_timeoutSeconds);
789 - }
790 - };
791 -
792 - /**
793 - * Dispatches register requests to available U2F tokens. An array of sign
794 - * requests identifies already registered tokens.
795 - * @param {string=} appId
796 - * @param {Array<u2f.RegisterRequest>} registerRequests
797 - * @param {Array<u2f.RegisteredKey>} registeredKeys
798 - * @param {function((u2f.Error|u2f.RegisterResponse))} callback
799 - * @param {number=} opt_timeoutSeconds
800 - */
801 -u2f.sendRegisterRequest = function (appId, registerRequests, registeredKeys, callback, opt_timeoutSeconds) {
802 - u2f.getPortSingleton_(function (port) {
803 - var reqId = ++u2f.reqCounter_;
804 - u2f.callbackMap_[reqId] = callback;
805 - var timeoutSeconds = (typeof opt_timeoutSeconds !== 'undefined' ?
806 - opt_timeoutSeconds : u2f.EXTENSION_TIMEOUT_SEC);
807 - var req = u2f.formatRegisterRequest_(
808 - appId, registeredKeys, registerRequests, timeoutSeconds, reqId);
809 - port.postMessage(req);
810 - });
811 - };
812 -
813 -
814 - /**
815 - * Dispatches a message to the extension to find out the supported
816 - * JS API version.
817 - * If the user is on a mobile phone and is thus using Google Authenticator instead
818 - * of the Chrome extension, don't send the request and simply return 0.
819 - * @param {function((u2f.Error|u2f.GetJsApiVersionResponse))} callback
820 - * @param {number=} opt_timeoutSeconds
821 - */
822 -u2f.getApiVersion = function (callback, opt_timeoutSeconds) {
823 - u2f.getPortSingleton_(function (port) {
824 - // If we are using Android Google Authenticator or iOS client app,
825 - // do not fire an intent to ask which JS API version to use.
826 - if (port.getPortType) {
827 - var apiVersion;
828 - switch (port.getPortType()) {
829 - case 'WrappedIosPort_':
830 - case 'WrappedAuthenticatorPort_':
831 - apiVersion = 1.1;
832 - break;
833 -
834 - default:
835 - apiVersion = 0;
836 - break;
837 - }
838 - callback({ 'js_api_version': apiVersion });
839 - return;
840 - }
841 - var reqId = ++u2f.reqCounter_;
842 - u2f.callbackMap_[reqId] = callback;
843 - var req = {
844 - type: u2f.MessageTypes.U2F_GET_API_VERSION_REQUEST,
845 - timeoutSeconds: (typeof opt_timeoutSeconds !== 'undefined' ?
846 - opt_timeoutSeconds : u2f.EXTENSION_TIMEOUT_SEC),
847 - requestId: reqId
848 - };
849 - port.postMessage(req);
850 - });
851 - };
852 -
853 -}
854 - 'use strict';
855 - var passhint = "{{{passhint}}}";
856 - var newAccountPass = parseInt('{{{newAccountPass}}}');
857 - var emailCheck = ('{{{emailcheck}}}' == 'true');
858 - var features = parseInt('{{{features}}}');
859 - var passRequirements = "{{{passRequirements}}}";
860 - if (passRequirements != "") { passRequirements = JSON.parse(decodeURIComponent(passRequirements)); } else { passRequirements = {}; }
861 - var passRequirementsEx = ((passRequirements.min != null) || (passRequirements.max != null) || (passRequirements.upper != null) || (passRequirements.lower != null) || (passRequirements.numeric != null) || (passRequirements.nonalpha != null));
862 - var hardwareKeyChallenge = decodeURIComponent('{{{hkey}}}');
863 - var currentpanel = 0;
864 -
865 - function startup() {
866 - if ((features & 32) == 0) {
867 - // Guard against other site's top frames (web bugs).
868 - var loc = null;
869 - try { loc = top.location.toString().toLowerCase(); } catch (e) { }
870 - if (top != self && (loc == null || top.active == false)) { top.location = self.location; return; }
871 - }
872 -
873 - QV('createPanelHint', passRequirements.hint === true);
874 - QV('resetpasswordpanelHint', passRequirements.hint === true);
875 -
876 - window.onresize = center;
877 - center();
878 - validateLogin();
879 - validateCreate();
880 - if ('{{loginmode}}' != '') { go(parseInt('{{loginmode}}')); } else { go(1); }
881 - QV('newAccountDiv', ('{{{newAccount}}}' != '0') && ('{{{newAccount}}}' != 'false')); // If new accounts are not allowed, don't display the new account link.
882 - if ((passRequirements.hint === true) && (passhint != null) && (passhint.length > 0)) { QV("showPassHintLink", true); }
883 - QV("newAccountPass", (newAccountPass == 1));
884 - QV("resetAccountDiv", (emailCheck == true));
885 - QV("hrAccountDiv", (emailCheck == true) || (newAccountPass == 1));
886 -
887 - if ('{{loginmode}}' == '4') {
888 - try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
889 - if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
890 - hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), c => c.charCodeAt(0)).buffer;
891 -
892 - const publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
893 - for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
894 - publicKeyCredentialRequestOptions.allowCredentials.push(
895 - { id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), c => c.charCodeAt(0)), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
896 - );
897 - }
898 -
899 - // New WebAuthn hardware keys
900 - navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
901 - function (rawAssertion) {
902 - var assertion = {
903 - id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
904 - clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
905 - userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
906 - signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
907 - authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
908 - };
909 - Q('hwtokenInput').value = JSON.stringify(assertion);
910 - QE('tokenOkButton', true);
911 - Q('tokenOkButton').click();
912 - },
913 - function (error) { console.log('credentials-get error', error); }
914 - );
915 - } else if ((hardwareKeyChallenge != null) && u2fSupported()) {
916 - // Old U2F hardware keys
917 - window.u2f.sign(hardwareKeyChallenge.appId, hardwareKeyChallenge.challenge, hardwareKeyChallenge.registeredKeys, function (authResponse) {
918 - if ((currentpanel == 4) && authResponse.signatureData) {
919 - Q('hwtokenInput').value = JSON.stringify(authResponse);
920 - QE('tokenOkButton', true);
921 - Q('tokenOkButton').click();
922 - }
923 - }, hardwareKeyChallenge.timeoutSeconds);
924 - }
925 - }
926 -
927 - if ('{{loginmode}}' == '5') {
928 - try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
929 - if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
930 - hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), c => c.charCodeAt(0)).buffer;
931 -
932 - const publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
933 - for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
934 - publicKeyCredentialRequestOptions.allowCredentials.push(
935 - { id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), c => c.charCodeAt(0)), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
936 - );
937 - }
938 -
939 - // New WebAuthn hardware keys
940 - navigator.credentials.get({ publicKey: publicKeyCredentialRequestOptions }).then(
941 - function (rawAssertion) {
942 - var assertion = {
943 - id: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.rawId))),
944 - clientDataJSON: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.clientDataJSON))),
945 - userHandle: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.userHandle))),
946 - signature: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.signature))),
947 - authenticatorData: btoa(String.fromCharCode.apply(null, new Uint8Array(rawAssertion.response.authenticatorData))),
948 - };
949 - Q('resetHwtokenInput').value = JSON.stringify(assertion);
950 - QE('resetTokenOkButton', true);
951 - Q('resetTokenOkButton').click();
952 - },
953 - function (error) { console.log('credentials-get error', error); }
954 - );
955 - } else if ((hardwareKeyChallenge != null) && u2fSupported()) {
956 - // Old U2F hardware keys
957 - window.u2f.sign(hardwareKeyChallenge.appId, hardwareKeyChallenge.challenge, hardwareKeyChallenge.registeredKeys, function (authResponse) {
958 - if ((currentpanel == 5) && authResponse.signatureData) {
959 - Q('resetHwtokenInput').value = JSON.stringify(authResponse);
960 - QE('resetTokenOkButton', true);
961 - Q('resetTokenOkButton').click();
962 - }
963 - }, hardwareKeyChallenge.timeoutSeconds);
964 - }
965 - }
966 - }
967 -
968 - function showPassHint() {
969 - if (passRequirements.hint === true) { messagebox("Password Hint", passhint); }
970 - }
971 -
972 - function xgo(x) {
973 - QV('message1', false);
974 - QV('message2', false);
975 - QV('message3', false);
976 - QV('message4', false);
977 - QV('message5', false);
978 - QV('message6', false);
979 - go(x);
980 - }
981 -
982 - function go(x) {
983 - currentpanel = x;
984 - setDialogMode(0);
985 - QV("showPassHintLink", false);
986 - QV('loginpanel', x == 1);
987 - QV('createpanel', x == 2);
988 - QV('resetpanel', x == 3);
989 - QV('tokenpanel', x == 4);
990 - QV('resettokenpanel', x == 5);
991 - QV('resetpasswordpanel', x == 6);
992 - if (x == 1) { Q('username').focus(); }
993 - if (x == 2) { Q('ausername').focus(); }
994 - if (x == 3) { Q('remail').focus(); }
995 - if (x == 4) { Q('tokenInput').focus(); }
996 - if (x == 5) { Q('resetTokenInput').focus(); }
997 - if (x == 6) { Q('rapassword1').focus(); }
998 - }
999 -
1000 - function validateLogin(box, e) {
1001 - var ok = ((Q('username').value.length > 0) && (Q('username').value.indexOf(' ') == -1) && (Q('password').value.length > 0));
1002 - QE('loginButton', ok);
1003 - setDialogMode(0);
1004 - if ((e != null) && (e.keyCode == 13)) { if (box == 1) { Q('password').focus(); } else if (box == 2) { Q('loginButton').click(); } }
1005 - if (e != null) { haltEvent(e); }
1006 - }
1007 -
1008 - function validateCreate(box,e) {
1009 - setDialogMode(0);
1010 - var ok = ((Q('ausername').value.length > 0) && (Q('ausername').value.indexOf(' ') == -1) && (validateEmail(Q('aemail').value) == true) && (Q('apassword1').value.length > 0) && (Q('apassword2').value == Q('apassword1').value));
1011 - if ((newAccountPass == 1) && (Q('anewaccountpass').value.length == 0)) { ok = false; }
1012 - if (Q('apassword1').value == '') {
1013 - QH('passWarning', '');
1014 - QV('passwordPolicyCallout', false);
1015 - } else {
1016 - if (!passRequirementsEx) {
1017 - // No password requirements, display password strength
1018 - var passStrength = checkPasswordStrength(Q('apassword1').value);
1019 - if (passStrength >= 80) { QH('passWarning', '<span style=color:green><b>Strong Password</b><span>'); }
1020 - else if (passStrength >= 60) { QH('passWarning', '<span style=color:blue><b>Good Password</b><span>'); }
1021 - else { QH('passWarning', '<span style=color:red><b>Weak Password</b><span>'); }
1022 - } else {
1023 - // Password requirements provided, use that
1024 - var passReq = checkPasswordRequirements(Q('apassword1').value, passRequirements);
1025 - if (passReq == false) {
1026 - ok = false;
1027 - //QS('nuPass1').color = '#7b241c';
1028 - //QS('nuPass2').color = '#7b241c';
1029 - QH('passWarning', '<span style=color:red><b>Password Policy</b><span>'); // TODO: Display problem hint
1030 - QV('passwordPolicyCallout', true);
1031 - QH('passwordPolicyCallout', passwordPolicyText(Q('apassword1').value));
1032 - } else {
1033 - QH('passWarning', '');
1034 - QV('passwordPolicyCallout', false);
1035 - }
1036 - }
1037 - }
1038 - QE('createButton', ok);
1039 - if ((e != null) && (e.keyCode == 13)) {
1040 - if (box == 1) { Q('aemail').focus(); }
1041 - if (box == 2) { Q('apassword1').focus(); }
1042 - if (box == 3) { Q('apassword2').focus(); }
1043 - if (box == 4) { Q('apasswordhint').focus(); }
1044 - if (box == 5) { if (newAccountPass == 1) { Q('anewaccountpass').focus(); } else { Q('createButton').click(); } }
1045 - if (box == 6) { Q('createButton').click(); }
1046 - }
1047 - if (e != null) { haltEvent(e); }
1048 - }
1049 -
1050 - function validatePassReset(box, e) {
1051 - setDialogMode(0);
1052 - var pass1ok = (Q('rapassword1').value.length > 0);
1053 - var pass2ok = (Q('rapassword2').value.length > 0) && (Q('rapassword2').value == Q('rapassword1').value);
1054 - var ok = (pass1ok && pass2ok);
1055 -
1056 - // Color the fields
1057 - QS('rnuPass1').color = pass1ok ? 'black' : '#7b241c';
1058 - QS('rnuPass2').color = pass2ok ? 'black' : '#7b241c';
1059 -
1060 - if (Q('rapassword1').value == '') {
1061 - QH('rpassWarning', '');
1062 - QV('rpasswordPolicyCallout', false);
1063 - } else {
1064 - if (!passRequirementsEx) {
1065 - // No password requirements, display password strength
1066 - var passStrength = checkPasswordStrength(Q('rapassword1').value);
1067 - if (passStrength >= 80) { QH('rpassWarning', '<span style=color:green><b>Strong Password</b><span>'); }
1068 - else if (passStrength >= 60) { QH('rpassWarning', '<span style=color:blue><b>Good Password</b><span>'); }
1069 - else { QH('rpassWarning', '<span style=color:red><b>Weak Password</b><span>'); }
1070 - } else {
1071 - // Password requirements provided, use that
1072 - var passReq = checkPasswordRequirements(Q('rapassword1').value, passRequirements);
1073 - if (passReq == false) {
1074 - ok = false;
1075 - QS('rnuPass1').color = '#7b241c';
1076 - QS('rnuPass2').color = '#7b241c';
1077 - QH('rpassWarning', '<div style=color:red;cursor:pointer onclick=showPasswordPolicy()><b>Password Policy</b><div>'); // This is also a link to the password policy
1078 - QV('rpasswordPolicyCallout', true);
1079 - QH('rpasswordPolicyCallout', passwordPolicyText(Q('rapassword1').value));
1080 - } else {
1081 - QH('rpassWarning', '');
1082 - QV('rpasswordPolicyCallout', false);
1083 - }
1084 - }
1085 - }
1086 - if ((e != null) && (e.keyCode == 13)) {
1087 - if (box == 2) { Q('rapassword1').focus(); }
1088 - if (box == 3) { Q('rapassword2').focus(); }
1089 - if (box == 4) { Q('rapasswordhint').focus(); }
1090 - if (box == 6) { Q('resetPassButton').click(); }
1091 - }
1092 - if (e != null) { haltEvent(e); }
1093 - QE('resetPassButton', ok);
1094 - }
1095 -
1096 - function validateReset(e) {
1097 - setDialogMode(0);
1098 - var x = validateEmail(Q('remail').value);
1099 - QE('eresetButton', x);
1100 - if ((e != null) && (e.keyCode == 13) && (x == true)) {
1101 - Q('eresetButton').click();
1102 - }
1103 - if (e != null) { haltEvent(e); }
1104 - }
1105 -
1106 - function passwordPolicyText(pass) {
1107 - var policy = '<div style=text-align:left>';
1108 - var counts = strCount(pass);
1109 - if (passRequirements.min && ((pass == null) || (pass.length < passRequirements.min))) { policy += 'Minimum length of ' + passRequirements.min + '<br />'; }
1110 - if (passRequirements.max && ((pass == null) || (pass.length > passRequirements.max))) { policy += 'Maximum length of ' + passRequirements.max + '<br />'; }
1111 - if (passRequirements.upper && ((pass == null) || (counts.upper < passRequirements.upper))) { policy += '' + passRequirements.upper + ' upper case<br />'; }
1112 - if (passRequirements.lower && ((pass == null) || (counts.lower < passRequirements.lower))) { policy += '' + passRequirements.lower + ' lower case<br />'; }
1113 - if (passRequirements.numeric && ((pass == null) || (counts.numeric < passRequirements.numeric))) { policy += '' + passRequirements.numeric + ' numeric<br />'; }
1114 - if (passRequirements.nonalpha && ((pass == null) || (counts.nonalpha < passRequirements.nonalpha))) { policy += passRequirements.nonalpha + ' non-alphanumeric<br />'; }
1115 - policy += '</div>';
1116 - return policy;
1117 - }
1118 -
1119 - // Return a password strength score
1120 - function checkPasswordStrength(password) {
1121 - var r = 0, letters = {}, varCount = 0, variations = { digits: /\d/.test(password), lower: /[a-z]/.test(password), upper: /[A-Z]/.test(password), nonWords: /\W/.test(password) }
1122 - if (!password) return 0;
1123 - for (var i = 0; i< password.length; i++) { letters[password[i]] = (letters[password[i]] || 0) + 1; r += 5.0 / letters[password[i]]; }
1124 - for (var c in variations) { varCount += (variations[c] == true) ? 1 : 0; }
1125 - return parseInt(r + (varCount - 1) * 10);
1126 - }
1127 -
1128 - // Check password requirements
1129 - function checkPasswordRequirements(password, requirements) {
1130 - if ((requirements == null) || (requirements == '') || (typeof requirements != 'object')) return true;
1131 - if (requirements.min) { if (password.length < requirements.min) return false; }
1132 - if (requirements.max) { if (password.length > requirements.max) return false; }
1133 - var counts = strCount(password);
1134 - if (requirements.numeric && (counts.numeric < requirements.numeric)) return false;
1135 - if (requirements.lower && (counts.lower < requirements.lower)) return false;
1136 - if (requirements.upper && (counts.upper < requirements.upper)) return false;
1137 - if (requirements.nonalpha && (counts.nonalpha < requirements.nonalpha)) return false;
1138 - return true;
1139 - }
1140 -
1141 - function strCount(password) {
1142 - var counts = { numeric: 0, lower: 0, upper: 0, nonalpha: 0 };
1143 - if (typeof password != 'string') return counts;
1144 - for (var i = 0; i < password.length; i++) {
1145 - if (/\d/.test(password[i])) { counts.numeric++; }
1146 - if (/[a-z]/.test(password[i])) { counts.lower++; }
1147 - if (/[A-Z]/.test(password[i])) { counts.upper++; }
1148 - if (/\W/.test(password[i])) { counts.nonalpha++; }
1149 - }
1150 - return counts;
1151 - }
1152 -
1153 - var xcheckTokenTimer = null;
1154 - function checkTokenTimer(enter) {
1155 - if ((enter == 0) && (xcheckTokenTimer != null)) { clearInterval(xcheckTokenTimer); xcheckTokenTimer = null; }
1156 - if ((enter == 1) && (xcheckTokenTimer == null)) { xcheckTokenTimer = setInterval(checkToken, 200); }
1157 - }
1158 -
1159 - function checkToken() {
1160 - var t1 = Q('tokenInput').value, t2 = t1.split(' ').join('');
1161 - if (t1 != t2) { Q('tokenInput').value = t2; }
1162 - QE('tokenOkButton', (Q('tokenInput').value.length == 6) || (Q('tokenInput').value.length == 8) || (Q('tokenInput').value.length == 44));
1163 - }
1164 -
1165 - function resetCheckToken() {
1166 - var t1 = Q('resetTokenInput').value, t2 = t1.split(' ').join('');
1167 - if (t1 != t2) { Q('resetTokenInput').value = t2; }
1168 - QE('resetTokenOkButton', (Q('resetTokenInput').value.length == 6) || (Q('resetTokenInput').value.length == 8) || (Q('resetTokenInput').value.length == 44));
1169 - }
1170 -
1171 - //
1172 - // POPUP DIALOG
1173 - //
1174 -
1175 - // undefined = Hidden, 1 = Generic Message
1176 - var xxdialogMode;
1177 - var xxdialogFunc;
1178 - var xxdialogButtons;
1179 - var xxdialogTag;
1180 - var xxcurrentView = 0;
1181 -
1182 - // Display a dialog box
1183 - // Parameters: Dialog Mode (0 = none), Dialog Title, Buttons (1 = OK, 2 = Cancel, 3 = OK & Cancel), Call back function(0 = Cancel, 1 = OK), Dialog Content (Mode 2 only)
1184 - function setDialogMode(x, y, b, f, c, tag) {
1185 - xxdialogMode = x;
1186 - xxdialogFunc = f;
1187 - xxdialogButtons = b;
1188 - xxdialogTag = tag;
1189 - QE('idx_dlgOkButton', true);
1190 - QV('idx_dlgOkButton', b & 1);
1191 - QV('idx_dlgCancelButton', b & 2);
1192 - QV('id_dialogclose', (b & 2) || (b & 8));
1193 - QV('idx_dlgButtonBar', b & 7);
1194 - if (y) QH('id_dialogtitle', y);
1195 - for (var i = 1; i < 24; i++) { QV('dialog' + i, i == x); } // Edit this line when more dialogs are added
1196 - QV('dialog', x);
1197 - if (c) { if (x == 2) { QH('id_dialogOptions', c); } else { QH('id_dialogMessage', c); } }
1198 - }
1199 -
1200 - function dialogclose(x) {
1201 - var f = xxdialogFunc;
1202 - var b = xxdialogButtons;
1203 - var t = xxdialogTag;
1204 - setDialogMode();
1205 - if (((b & 8) || x) && f) f(x, t);
1206 - }
1207 -
1208 - function center() { QS('dialog').left = ((((getDocWidth() - 400) / 2)) + "px"); }
1209 - function messagebox(t, m) { QH('id_dialogMessage', m); setDialogMode(1, t, 1); }
1210 - function statusbox(t, m) { QH('id_dialogMessage', m); setDialogMode(1, t); }
1211 - function getDocWidth() { if (window.innerWidth) return window.innerWidth; if (document.documentElement && document.documentElement.clientWidth && document.documentElement.clientWidth != 0) return document.documentElement.clientWidth; return document.getElementsByTagName('body')[0].clientWidth; }
1212 - function haltEvent(e) { if (e.preventDefault) e.preventDefault(); if (e.stopPropagation) e.stopPropagation(); return false; }
1213 - function haltReturn(e) { if (e.keyCode == 13) { haltEvent(e); } }
1214 - function validateEmail(v) { var emailReg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; return emailReg.test(v); } // New version
1215 - function u2fSupported() { return (window.u2f && ((navigator.userAgent.indexOf('Chrome/') > 0) || (navigator.userAgent.indexOf('Firefox/') > 0) || (navigator.userAgent.indexOf('Opera/') > 0) || (navigator.userAgent.indexOf('Safari/') > 0))); }
1216 -
1217 - </script></body></html>
\ No newline at end of file
1 +<!DOCTYPE html> <html dir="ltr" xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta content="text/html; charset=utf-8" http-equiv="Content-Type"> <meta name="viewport" content="user-scalable=1.0,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0"> <meta name="apple-mobile-web-app-capable" content="yes"> <meta name="format-detection" content="telephone=no"> <title>MeshCentral - Login</title> <style> a{color:#036;text-decoration:underline;}#footer a{color:#fff;text-decoration:underline;}#footer a:hover{color:#fff;text-decoration:none;}</style> </head> <body onload="if (typeof(startup) !== 'undefined') startup();" style="overflow-y:hidden;margin:0;padding:0;border:0;color:black;font-size:13px;font-family:\'Trebuchet MS\', Arial, Helvetica, sans-serif"> <div id="container"> <div id="mastheadx"></div> <div id="masthead" style="background:url(logo.png) 0px 0px;background-size:341px 50px;background-color:#036;background-repeat:no-repeat;height:50px;width:100%;overflow:hidden"> <div style="float:left;height:66px;color:#c8c8c8;padding-left:10px;padding-top:6px"> <strong><font style="font-size:36px;font-family:Arial,Helvetica,sans-serif">{{{title}}}</font></strong> </div> <div style="float:left;height:66px;color:#c8c8c8;padding-left:5px;padding-top:10px"> <strong><font style="font-size:12px;font-family:Arial,Helvetica,sans-serif">{{{title2}}}</font></strong> </div> </div> <div id="page_content" style="overflow-y:scroll;position:absolute;bottom:32px;top:50px;width:100%;display:flex;align-items:center"> <div id="column_l" style="padding:10px;width:100%"> <table style="width:100%"> <tr> <td align="center"> <div id="loginpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;clear:both;display:none"> <form action="login" method="post"> <div id="message1"> {{{message}}} </div> <div> <b>Log In</b> </div> <table> <tr> <td align="right" width="100">Username:</td> <td><input id="username" type="text" maxlength="64" name="username" onchange="validateLogin(1)" onkeyup="validateLogin(1,event)"></td> </tr> <tr> <td align="right">Password:</td> <td><input id="password" type="password" maxlength="256" name="password" autocomplete="off" onchange="validateLogin(2)" onkeyup="validateLogin(2,event)"></td> </tr> <tr> <td><div id="showPassHintLink" style="display:none"><a onclick="showPassHint()" style="cursor:pointer">Show Hint</a></div></td> <td align="right"><input id="loginButton" type="submit" value="Log In" disabled="disabled"></td> </tr> </table> <div id="hrAccountDiv" style="display:none"><hr></div> <div id="resetAccountDiv" style="display:none;padding:2px"> Forgot user/password? <a onclick="xgo(3)" style="cursor:pointer">Reset account</a>. </div> <div id="newAccountDiv" style="display:none;padding:2px"> Don&#39;t have an account? <a onclick="xgo(2)" style="cursor:pointer">Create one</a>. </div> </form> </div> <div id="createpanel" style="position:relative;display:none"> <div style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;clear:both"> <form action="createaccount" method="post"> <div id="message2"> {{{message}}} </div> <div> <b>Account Creation</b> </div> <div id="passwordPolicyCallout" style="left:-5px;top:10px;width:100px;position:absolute;background-color:#FFC;border-radius:5px;padding:5px;box-shadow:0px 0px 15px #666;font-size:10px"></div> <table> <tr> <td align="right" width="100">Username:</td> <td><input id="ausername" type="text" name="username" onchange="validateCreate(1)" maxlength="64" onkeydown="haltReturn(event)" onkeyup="validateCreate(1,event)"></td> </tr> <tr> <td align="right" width="100">Email:</td> <td><input id="aemail" type="text" name="email" onchange="validateCreate(2)" maxlength="256" onkeydown="haltReturn(event)" onkeyup="validateCreate(2,event)"></td> </tr> <tr> <td align="right">Password:</td> <td><input id="apassword1" type="password" name="password1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(3)" onkeyup="validateCreate(3,event)"></td> </tr> <tr> <td align="right">Password:</td> <td><input id="apassword2" type="password" name="password2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(4)" onkeyup="validateCreate(4,event)"></td> </tr> <tr id="createPanelHint" style="display:none"> <td align="right">Pass Hint:</td> <td><input id="apasswordhint" type="text" name="apasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(5)" onkeyup="validateCreate(5,event)"></td> </tr> <tr id="newAccountPass" title="Enter the account creation token"> <td align="right">Creation Token:</td> <td><input id="anewaccountpass" type="password" name="anewaccountpass" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validateCreate(6)" onkeyup="validateCreate(6,event)"></td> </tr> <tr> <td colspan="2"> <div style="float:right"><input id="createButton" type="submit" value="Create Account" disabled="disabled"></div> <div id="passWarning" style="padding-top:6px"></div> </td> </tr> </table> <hr><a onclick="xgo(1)" style="cursor:pointer">Back to login</a> </form> </div> </div> <div id="resetpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;display:none;clear:both"> <form action="resetaccount" method="post"> <div id="message3"> {{{message}}} </div> <div> <b>Account Reset</b> </div> <table> <tr> <td align="right" width="100">Email:</td> <td><input id="remail" type="text" name="email" maxlength="256" onchange="validateReset()" onkeyup="validateReset(event)"></td> </tr> <tr> <td colspan="2"> <div style="float:right"><input id="eresetButton" type="submit" value="Reset Account" disabled="disabled"></div> <div id="passWarning" style="padding-top:6px"></div> </td> </tr> </table> <hr><a onclick="xgo(1)" style="cursor:pointer">Back to login</a> </form> </div> <div id="tokenpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;display:none;clear:both"> <form action="tokenlogin" method="post" autocomplete="off"> <div id="message4"> {{{message}}} </div> <table> <tr> <td align="right" width="100">Login token:</td> <td> <input id="tokenInput" type="text" name="token" maxlength="50" onchange="checkToken(event)" onkeyup="checkToken(event)" onkeydown="checkToken(event)" onfocus="checkTokenTimer(1)" onblur="checkTokenTimer(0)"> <input id="hwtokenInput" type="text" name="hwtoken" style="display:none"> </td> </tr> <tr> <td colspan="2"> <div style="float:right"><input id="tokenOkButton" type="submit" value="Login" disabled="disabled"></div> </td> </tr> </table> <hr><a onclick="xgo(1)" style="cursor:pointer">Back to login</a> </form> </div> <div id="resettokenpanel" style="background-color:#979797;border-radius:16px;width:260px;padding:16px;text-align:center;display:none;clear:both"> <form action="resetaccount" method="post" autocomplete="off"> <div id="message5"> {{{message}}} </div> <table> <tr> <td align="right" width="100">Login token:</td> <td> <input id="resetTokenInput" type="text" name="token" maxlength="50" onchange="resetCheckToken(event)" onpaste="resetCheckToken(event)" onkeyup="resetCheckToken(event)" onkeydown="resetCheckToken(event)"> <input id="resetHwtokenInput" type="text" name="hwtoken" style="display:none"> </td> </tr> <tr> <td colspan="2"> <div style="float:right"><input id="resetTokenOkButton" type="submit" value="Login" disabled="disabled"></div> </td> </tr> </table> <hr><a onclick="xgo(1)" style="cursor:pointer">Back to login</a> </form> </div> <div id="resetpasswordpanel" style="position:relative;background-color:#979797;border-radius:16px;width:300px;padding:16px;text-align:center;display:none"> <form action="resetpassword" method="post"> <div id="message6"> {{{message}}} </div> <div id="rpasswordPolicyCallout" style="left:-10px;width:100px;display:none;position:absolute;background-color:#FFC;border-radius:5px;padding:5px;box-shadow:0px 0px 15px #666;font-size:10px"></div> <table> <tr> <td id="rnuPass1" width="100" align="right">Password:</td> <td><input id="rapassword1" type="password" name="rpassword1" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(3,event)" onkeyup="validatePassReset(3,event)"></td> </tr> <tr> <td id="rnuPass2" align="right">Password:</td> <td><input id="rapassword2" type="password" name="rpassword2" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(4,event)" onkeyup="validatePassReset(4,event)"></td> </tr> <tr id="resetpasswordpanelHint" style="display:none"> <td id="rnuHint" align="right">Password Hint:</td> <td><input id="rapasswordhint" type="text" name="rpasswordhint" autocomplete="off" maxlength="256" onkeydown="haltReturn(event)" onchange="validatePassReset(5,event)" onkeyup="validatePassReset(5,event)"></td> </tr> <tr> <td colspan="2"> <div style="float:right"><input id="resetPassButton" type="submit" value="Reset Password" disabled="disabled"></div> <div id="rpassWarning" style="padding-top:6px"></div> </td> </tr> </table> <hr><a onclick="xgo(1)" style="cursor:pointer">Back to login</a> </form> </div> </td> </tr> </table> </div> </div> <div id="footer" style="height:32px;width:100%;text-align:center;background-color:#113962;position:absolute;bottom:0px"> <table cellpadding="0" cellspacing="6" style="width:100%"> <tr> <td style="text-align:left;color:white">{{{footer}}}</td> <td style="text-align:right">{{{rootCertLink}}}&nbsp;<a href="terms">Terms &amp; Privacy</a></td> </tr> </table> </div> </div> <div id="dialog" style="z-index:1000;background-color:#EEE;box-shadow:0px 0px 15px #666;font-family:Arial,Helvetica,sans-serif;border-radius:5px;position:fixed;top:180px;width:400px;display:none"> <div style="width:100%;background-color:#003366;color:#FFF;border-radius:5px 5px 0 0"> <div id="id_dialogclose" style="float:right;padding:5px;cursor:pointer" onclick="setDialogMode()"><b>X</b></div> <div id="id_dialogtitle" style="padding:5px"></div> <div style="width:100%;margin:6px"></div> </div> <div style="margin-right:16px;margin-left:8px"> <div id="dialog1" style="margin:auto;text-align:center;margin:3px"> <div id="id_dialogMessage" style="padding:10px"></div> </div> <div id="dialog2" style="margin:auto;margin:3px"> <div id="id_dialogOptions"></div> </div> </div> <div id="idx_dlgButtonBar" style="padding:10px;margin-bottom:20px"> <input id="idx_dlgCancelButton" type="button" value="Cancel" style="float:right;width:80px;margin-left:5px" onclick="dialogclose(0)"> <input id="idx_dlgOkButton" type="button" value="OK" style="float:right;width:80px" onclick="dialogclose(1)"> </div> </div> <script>if(!String.prototype.startsWith){String.prototype.startsWith=function(a){return this.lastIndexOf(a,0)===0}}if(!String.prototype.endsWith){String.prototype.endsWith=function(a){return this.indexOf(a,this.length-a.length)!==-1}}function Q(a){return document.getElementById(a)}function QS(a){try{return Q(a).style}catch(a){}}function QE(a,b){try{Q(a).disabled=!b}catch(a){}}function QV(a,b){try{QS(a).display=(b?"":"none")}catch(a){}}function QA(a,b){Q(a).innerHTML+=b}function QH(a,b){Q(a).innerHTML=b}function inputBoxFocus(b){Q(b).focus();var a=Q(b).value;Q(b).value="";Q(b).value=a}function ReadShort(b,a){return(b.charCodeAt(a)<<8)+b.charCodeAt(a+1)}function ReadShortX(b,a){return(b.charCodeAt(a+1)<<8)+b.charCodeAt(a)}function ReadInt(b,a){return(b.charCodeAt(a)*16777216)+(b.charCodeAt(a+1)<<16)+(b.charCodeAt(a+2)<<8)+b.charCodeAt(a+3)}function ReadSInt(b,a){return(b.charCodeAt(a)<<24)+(b.charCodeAt(a+1)<<16)+(b.charCodeAt(a+2)<<8)+b.charCodeAt(a+3)}function ReadIntX(b,a){return(b.charCodeAt(a+3)*16777216)+(b.charCodeAt(a+2)<<16)+(b.charCodeAt(a+1)<<8)+b.charCodeAt(a)}function ShortToStr(a){return String.fromCharCode((a>>8)&255,a&255)}function ShortToStrX(a){return String.fromCharCode(a&255,(a>>8)&255)}function IntToStr(a){return String.fromCharCode((a>>24)&255,(a>>16)&255,(a>>8)&255,a&255)}function IntToStrX(a){return String.fromCharCode(a&255,(a>>8)&255,(a>>16)&255,(a>>24)&255)}function MakeToArray(a){if(!a||a==null||typeof a=="object"){return a}return[a]}function SplitArray(a){return a.split(",")}function Clone(a){return JSON.parse(JSON.stringify(a))}function EscapeHtml(a){if(typeof a=="string"){return a.replace(/&/g,"&amp;").replace(/>/g,"&gt;").replace(/</g,"&lt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}if(typeof a=="boolean"){return a}if(typeof a=="number"){return a}}function EscapeHtmlBreaks(a){if(typeof a=="string"){return a.replace(/&/g,"&amp;").replace(/>/g,"&gt;").replace(/</g,"&lt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;").replace(/\r/g,"<br />").replace(/\n/g,"").replace(/\t/g,"&nbsp;&nbsp;")}if(typeof a=="boolean"){return a}if(typeof a=="number"){return a}}function ArrayElementMove(a,b,c){a.splice(c,0,a.splice(b,1)[0])}function ObjectToStringEx(e,a){var d="";if(e!=0&&(!e||e==null)){return"(Null)"}if(e instanceof Array){for(var b in e){d+="<br />"+gap(a)+"Item #"+b+": "+ObjectToStringEx(e[b],a+1)}}else{if(e instanceof Object){for(var b in e){d+="<br />"+gap(a)+b+" = "+ObjectToStringEx(e[b],a+1)}}else{d+=EscapeHtml(e)}}return d}function ObjectToStringEx2(e,a){var d="";if(e!=0&&(!e||e==null)){return"(Null)"}if(e instanceof Array){for(var b in e){d+="\r\n"+gap2(a)+"Item #"+b+": "+ObjectToStringEx2(e[b],a+1)}}else{if(e instanceof Object){for(var b in e){d+="\r\n"+gap2(a)+b+" = "+ObjectToStringEx2(e[b],a+1)}}else{d+=EscapeHtml(e)}}return d}function gap(a){var d="";for(var b=0;b<(a*4);b++){d+="&nbsp;"}return d}function gap2(a){var d="";for(var b=0;b<(a*4);b++){d+=" "}return d}function ObjectToString(a){return ObjectToStringEx(a,0)}function ObjectToString2(a){return ObjectToStringEx2(a,0)}function hex2rstr(a){if(typeof a!="string"||a.length==0){return""}var c="",b=(""+a).match(/../g),e;while(e=b.shift()){c+=String.fromCharCode("0x"+e)}return c}function char2hex(a){return(a+256).toString(16).substr(-2).toUpperCase()}function rstr2hex(b){var c="",a;for(a=0;a<b.length;a++){c+=char2hex(b.charCodeAt(a))}return c}function encode_utf8(a){return unescape(encodeURIComponent(a))}function decode_utf8(a){return decodeURIComponent(escape(a))}function data2blob(c){var b=new Array(c.length);for(var d=0;d<c.length;d++){b[d]=c.charCodeAt(d)}var a=new Blob([new Uint8Array(b)]);return a}function random(a){return Math.floor(Math.random()*a)}function trademarks(a){return a.replace(/\(R\)/g,"&reg;").replace(/\(TM\)/g,"&trade;")}"use strict";if(!window.u2f){var u2f=u2f||{};var js_api_version;u2f.EXTENSION_ID="kmendfapggjehodndflmmgagdbamhnfd";u2f.MessageTypes={U2F_REGISTER_REQUEST:"u2f_register_request",U2F_REGISTER_RESPONSE:"u2f_register_response",U2F_SIGN_REQUEST:"u2f_sign_request",U2F_SIGN_RESPONSE:"u2f_sign_response",U2F_GET_API_VERSION_REQUEST:"u2f_get_api_version_request",U2F_GET_API_VERSION_RESPONSE:"u2f_get_api_version_response"};u2f.ErrorCodes={OK:0,OTHER_ERROR:1,BAD_REQUEST:2,CONFIGURATION_UNSUPPORTED:3,DEVICE_INELIGIBLE:4,TIMEOUT:5};u2f.U2fRequest;u2f.U2fResponse;u2f.Error;u2f.Transport;u2f.Transports;u2f.SignRequest;u2f.SignResponse;u2f.RegisterRequest;u2f.RegisterResponse;u2f.RegisteredKey;u2f.GetJsApiVersionResponse;u2f.getMessagePort=function(a){if(typeof chrome!="undefined"&&chrome.runtime){var b={type:u2f.MessageTypes.U2F_SIGN_REQUEST,signRequests:[]};chrome.runtime.sendMessage(u2f.EXTENSION_ID,b,function(){if(!chrome.runtime.lastError){u2f.getChromeRuntimePort_(a)}else{u2f.getIframePort_(a)}})}else{if(u2f.isAndroidChrome_()){u2f.getAuthenticatorPort_(a)}else{if(u2f.isIosChrome_()){u2f.getIosPort_(a)}else{u2f.getIframePort_(a)}}}};u2f.isAndroidChrome_=function(){var a=navigator.userAgent;return a.indexOf("Chrome")!=-1&&a.indexOf("Android")!=-1};u2f.isIosChrome_=function(){var b=["iPhone","iPad","iPod"];for(var a in b){if(navigator.platform==b[a]){return true}}return false};u2f.getChromeRuntimePort_=function(a){var b=chrome.runtime.connect(u2f.EXTENSION_ID,{includeTlsChannelId:true});setTimeout(function(){a(new u2f.WrappedChromeRuntimePort_(b))},0)};u2f.getAuthenticatorPort_=function(a){setTimeout(function(){a(new u2f.WrappedAuthenticatorPort_())},0)};u2f.getIosPort_=function(a){setTimeout(function(){a(new u2f.WrappedIosPort_())},0)};u2f.WrappedChromeRuntimePort_=function(a){this.port_=a};u2f.formatSignRequest_=function(a,b,d,g,e){if(js_api_version===undefined||js_api_version<1.1){var f=[];for(var c=0;c<d.length;c++){f[c]={version:d[c].version,challenge:b,keyHandle:d[c].keyHandle,appId:a}}return{type:u2f.MessageTypes.U2F_SIGN_REQUEST,signRequests:f,timeoutSeconds:g,requestId:e}}return{type:u2f.MessageTypes.U2F_SIGN_REQUEST,appId:a,challenge:b,registeredKeys:d,timeoutSeconds:g,requestId:e}};u2f.formatRegisterRequest_=function(a,c,d,g,e){if(js_api_version===undefined||js_api_version<1.1){for(var b=0;b<d.length;b++){d[b].appId=a}var f=[];for(var b=0;b<c.length;b++){f[b]={version:c[b].version,challenge:d[0],keyHandle:c[b].keyHandle,appId:a}}return{type:u2f.MessageTypes.U2F_REGISTER_REQUEST,signRequests:f,registerRequests:d,timeoutSeconds:g,requestId:e}}return{type:u2f.MessageTypes.U2F_REGISTER_REQUEST,appId:a,registerRequests:d,registeredKeys:c,timeoutSeconds:g,requestId:e}};u2f.WrappedChromeRuntimePort_.prototype.postMessage=function(a){this.port_.postMessage(a)};u2f.WrappedChromeRuntimePort_.prototype.addEventListener=function(a,b){var c=a.toLowerCase();if(c=="message"||c=="onmessage"){this.port_.onMessage.addListener(function(d){b({data:d})})}else{console.error("WrappedChromeRuntimePort only supports onMessage")}};u2f.WrappedAuthenticatorPort_=function(){this.requestId_=-1;this.requestObject_=null};u2f.WrappedAuthenticatorPort_.prototype.postMessage=function(b){var a=u2f.WrappedAuthenticatorPort_.INTENT_URL_BASE_+";S.request="+encodeURIComponent(JSON.stringify(b))+";end";document.location=a};u2f.WrappedAuthenticatorPort_.prototype.getPortType=function(){return"WrappedAuthenticatorPort_"};u2f.WrappedAuthenticatorPort_.prototype.addEventListener=function(a,b){var c=a.toLowerCase();if(c=="message"){var d=this;window.addEventListener("message",d.onRequestUpdate_.bind(d,b),false)}else{console.error("WrappedAuthenticatorPort only supports message")}};u2f.WrappedAuthenticatorPort_.prototype.onRequestUpdate_=function(a,d){var e=JSON.parse(d.data);var c=e.intentURL;var b=e.errorCode;var f=null;if(e.hasOwnProperty("data")){f=(JSON.parse(e.data))}a({data:f})};u2f.WrappedAuthenticatorPort_.INTENT_URL_BASE_="intent:#Intent;action=com.google.android.apps.authenticator.AUTHENTICATE";u2f.WrappedIosPort_=function(){};u2f.WrappedIosPort_.prototype.postMessage=function(a){var b=JSON.stringify(a);var c="u2f://auth?"+encodeURI(b);location.replace(c)};u2f.WrappedIosPort_.prototype.getPortType=function(){return"WrappedIosPort_"};u2f.WrappedIosPort_.prototype.addEventListener=function(a,b){var c=a.toLowerCase();if(c!=="message"){console.error("WrappedIosPort only supports message")}};u2f.getIframePort_=function(a){var d="chrome-extension://"+u2f.EXTENSION_ID;var c=document.createElement("iframe");c.src=d+"/u2f-comms.html";c.setAttribute("style","display:none");document.body.appendChild(c);var b=new MessageChannel();var e=function(f){if(f.data=="ready"){b.port1.removeEventListener("message",e);a(b.port1)}else{console.error('First event on iframe port was not "ready"')}};b.port1.addEventListener("message",e);b.port1.start();c.addEventListener("load",function(){c.contentWindow.postMessage("init",d,[b.port2])})};u2f.EXTENSION_TIMEOUT_SEC=30;u2f.port_=null;u2f.waitingForPort_=[];u2f.reqCounter_=0;u2f.callbackMap_={};u2f.getPortSingleton_=function(a){if(u2f.port_){a(u2f.port_)}else{if(u2f.waitingForPort_.length==0){u2f.getMessagePort(function(b){u2f.port_=b;u2f.port_.addEventListener("message",(u2f.responseHandler_));while(u2f.waitingForPort_.length){u2f.waitingForPort_.shift()(u2f.port_)}})}u2f.waitingForPort_.push(a)}};u2f.responseHandler_=function(b){var d=b.data;var c=d.requestId;if(!c||!u2f.callbackMap_[c]){console.error("Unknown or missing requestId in response.");return}var a=u2f.callbackMap_[c];delete u2f.callbackMap_[c];a(d.responseData)};u2f.sign=function(a,c,e,b,d){if(js_api_version===undefined){u2f.getApiVersion(function(f){js_api_version=f.js_api_version===undefined?0:f.js_api_version;u2f.sendSignRequest(a,c,e,b,d)})}else{u2f.sendSignRequest(a,c,e,b,d)}};u2f.sendSignRequest=function(a,c,e,b,d){u2f.getPortSingleton_(function(f){var h=++u2f.reqCounter_;u2f.callbackMap_[h]=b;var i=(typeof d!=="undefined"?d:u2f.EXTENSION_TIMEOUT_SEC);var g=u2f.formatSignRequest_(a,c,e,i,h);f.postMessage(g)})};u2f.register=function(a,e,d,b,c){if(js_api_version===undefined){u2f.getApiVersion(function(f){js_api_version=f.js_api_version===undefined?0:f.js_api_version;u2f.sendRegisterRequest(a,e,d,b,c)})}else{u2f.sendRegisterRequest(a,e,d,b,c)}};u2f.sendRegisterRequest=function(a,e,d,b,c){u2f.getPortSingleton_(function(f){var h=++u2f.reqCounter_;u2f.callbackMap_[h]=b;var i=(typeof c!=="undefined"?c:u2f.EXTENSION_TIMEOUT_SEC);var g=u2f.formatRegisterRequest_(a,d,e,i,h);f.postMessage(g)})};u2f.getApiVersion=function(a,b){u2f.getPortSingleton_(function(d){if(d.getPortType){var c;switch(d.getPortType()){case"WrappedIosPort_":case"WrappedAuthenticatorPort_":c=1.1;break;default:c=0;break}a({js_api_version:c});return}var f=++u2f.reqCounter_;u2f.callbackMap_[f]=a;var e={type:u2f.MessageTypes.U2F_GET_API_VERSION_REQUEST,timeoutSeconds:(typeof b!=="undefined"?b:u2f.EXTENSION_TIMEOUT_SEC),requestId:f};d.postMessage(e)})}}"use strict";var passhint="{{{passhint}}}";var newAccountPass=parseInt("{{{newAccountPass}}}");var emailCheck=("{{{emailcheck}}}"=="true");var features=parseInt("{{{features}}}");var passRequirements="{{{passRequirements}}}";if(passRequirements!=""){passRequirements=JSON.parse(decodeURIComponent(passRequirements))}else{passRequirements={}}var passRequirementsEx=((passRequirements.min!=null)||(passRequirements.max!=null)||(passRequirements.upper!=null)||(passRequirements.lower!=null)||(passRequirements.numeric!=null)||(passRequirements.nonalpha!=null));var hardwareKeyChallenge=decodeURIComponent("{{{hkey}}}");var currentpanel=0;function startup(){if((features&32)==0){var d=null;try{d=top.location.toString().toLowerCase()}catch(a){}if(top!=self&&(d==null||top.active==false)){top.location=self.location;return}}QV("createPanelHint",passRequirements.hint===true);QV("resetpasswordpanelHint",passRequirements.hint===true);window.onresize=center;center();validateLogin();validateCreate();if("{{loginmode}}"!=""){go(parseInt("{{loginmode}}"))}else{go(1)}QV("newAccountDiv",("{{{newAccount}}}"!="0")&&("{{{newAccount}}}"!="false"));if((passRequirements.hint===true)&&(passhint!=null)&&(passhint.length>0)){QV("showPassHintLink",true)}QV("newAccountPass",(newAccountPass==1));QV("resetAccountDiv",(emailCheck==true));QV("hrAccountDiv",(emailCheck==true)||(newAccountPass==1));if("{{loginmode}}"=="4"){try{if(hardwareKeyChallenge.length>0){hardwareKeyChallenge=JSON.parse(hardwareKeyChallenge)}else{hardwareKeyChallenge=null}}catch(b){hardwareKeyChallenge=null}if((hardwareKeyChallenge!=null)&&(hardwareKeyChallenge.type=="webAuthn")){hardwareKeyChallenge.challenge=Uint8Array.from(atob(hardwareKeyChallenge.challenge),function(e){return e.charCodeAt(0)}).buffer;var f={challenge:hardwareKeyChallenge.challenge,allowCredentials:[],timeout:hardwareKeyChallenge.timeout};for(var c=0;c<hardwareKeyChallenge.keyIds.length;c++){f.allowCredentials.push({id:Uint8Array.from(atob(hardwareKeyChallenge.keyIds[c]),function(e){return e.charCodeAt(0)}),type:"public-key",transports:["usb","ble","nfc"],})}navigator.credentials.get({publicKey:f}).then(function(g){var e={id:btoa(String.fromCharCode.apply(null,new Uint8Array(g.rawId))),clientDataJSON:btoa(String.fromCharCode.apply(null,new Uint8Array(g.response.clientDataJSON))),userHandle:btoa(String.fromCharCode.apply(null,new Uint8Array(g.response.userHandle))),signature:btoa(String.fromCharCode.apply(null,new Uint8Array(g.response.signature))),authenticatorData:btoa(String.fromCharCode.apply(null,new Uint8Array(g.response.authenticatorData))),};Q("hwtokenInput").value=JSON.stringify(e);QE("tokenOkButton",true);Q("tokenOkButton").click()},function(e){console.log("credentials-get error",e)})}else{if((hardwareKeyChallenge!=null)&&u2fSupported()){window.u2f.sign(hardwareKeyChallenge.appId,hardwareKeyChallenge.challenge,hardwareKeyChallenge.registeredKeys,function(e){if((currentpanel==4)&&e.signatureData){Q("hwtokenInput").value=JSON.stringify(e);QE("tokenOkButton",true);Q("tokenOkButton").click()}},hardwareKeyChallenge.timeoutSeconds)}}}if("{{loginmode}}"=="5"){try{if(hardwareKeyChallenge.length>0){hardwareKeyChallenge=JSON.parse(hardwareKeyChallenge)}else{hardwareKeyChallenge=null}}catch(b){hardwareKeyChallenge=null}if((hardwareKeyChallenge!=null)&&(hardwareKeyChallenge.type=="webAuthn")){hardwareKeyChallenge.challenge=Uint8Array.from(atob(hardwareKeyChallenge.challenge),function(e){return e.charCodeAt(0)}).buffer;var f={challenge:hardwareKeyChallenge.challenge,allowCredentials:[],timeout:hardwareKeyChallenge.timeout};for(var c=0;c<hardwareKeyChallenge.keyIds.length;c++){f.allowCredentials.push({id:Uint8Array.from(atob(hardwareKeyChallenge.keyIds[c]),function(e){return e.charCodeAt(0)}),type:"public-key",transports:["usb","ble","nfc"],})}navigator.credentials.get({publicKey:f}).then(function(g){var e={id:btoa(String.fromCharCode.apply(null,new Uint8Array(g.rawId))),clientDataJSON:btoa(String.fromCharCode.apply(null,new Uint8Array(g.response.clientDataJSON))),userHandle:btoa(String.fromCharCode.apply(null,new Uint8Array(g.response.userHandle))),signature:btoa(String.fromCharCode.apply(null,new Uint8Array(g.response.signature))),authenticatorData:btoa(String.fromCharCode.apply(null,new Uint8Array(g.response.authenticatorData))),};Q("resetHwtokenInput").value=JSON.stringify(e);QE("resetTokenOkButton",true);Q("resetTokenOkButton").click()},function(e){console.log("credentials-get error",e)})}else{if((hardwareKeyChallenge!=null)&&u2fSupported()){window.u2f.sign(hardwareKeyChallenge.appId,hardwareKeyChallenge.challenge,hardwareKeyChallenge.registeredKeys,function(e){if((currentpanel==5)&&e.signatureData){Q("resetHwtokenInput").value=JSON.stringify(e);QE("resetTokenOkButton",true);Q("resetTokenOkButton").click()}},hardwareKeyChallenge.timeoutSeconds)}}}}function showPassHint(){if(passRequirements.hint===true){messagebox("Password Hint",passhint)}}function xgo(a){QV("message1",false);QV("message2",false);QV("message3",false);QV("message4",false);QV("message5",false);QV("message6",false);go(a)}function go(a){currentpanel=a;setDialogMode(0);QV("showPassHintLink",false);QV("loginpanel",a==1);QV("createpanel",a==2);QV("resetpanel",a==3);QV("tokenpanel",a==4);QV("resettokenpanel",a==5);QV("resetpasswordpanel",a==6);if(a==1){Q("username").focus()}if(a==2){Q("ausername").focus()}if(a==3){Q("remail").focus()}if(a==4){Q("tokenInput").focus()}if(a==5){Q("resetTokenInput").focus()}if(a==6){Q("rapassword1").focus()}}function validateLogin(a,b){var c=((Q("username").value.length>0)&&(Q("username").value.indexOf(" ")==-1)&&(Q("password").value.length>0));QE("loginButton",c);setDialogMode(0);if((b!=null)&&(b.keyCode==13)){if(a==1){Q("password").focus()}else{if(a==2){Q("loginButton").click()}}}if(b!=null){haltEvent(b)}}function validateCreate(a,b){setDialogMode(0);var c=((Q("ausername").value.length>0)&&(Q("ausername").value.indexOf(" ")==-1)&&(validateEmail(Q("aemail").value)==true)&&(Q("apassword1").value.length>0)&&(Q("apassword2").value==Q("apassword1").value));if((newAccountPass==1)&&(Q("anewaccountpass").value.length==0)){c=false}if(Q("apassword1").value==""){QH("passWarning","");QV("passwordPolicyCallout",false)}else{if(!passRequirementsEx){var f=checkPasswordStrength(Q("apassword1").value);if(f>=80){QH("passWarning","<span style=color:green><b>Strong Password</b><span>")}else{if(f>=60){QH("passWarning","<span style=color:blue><b>Good Password</b><span>")}else{QH("passWarning","<span style=color:red><b>Weak Password</b><span>")}}}else{var d=checkPasswordRequirements(Q("apassword1").value,passRequirements);if(d==false){c=false;QH("passWarning","<span style=color:red><b>Password Policy</b><span>");QV("passwordPolicyCallout",true);QH("passwordPolicyCallout",passwordPolicyText(Q("apassword1").value))}else{QH("passWarning","");QV("passwordPolicyCallout",false)}}}QE("createButton",c);if((b!=null)&&(b.keyCode==13)){if(a==1){Q("aemail").focus()}if(a==2){Q("apassword1").focus()}if(a==3){Q("apassword2").focus()}if(a==4){Q("apasswordhint").focus()}if(a==5){if(newAccountPass==1){Q("anewaccountpass").focus()}else{Q("createButton").click()}}if(a==6){Q("createButton").click()}}if(b!=null){haltEvent(b)}}function validatePassReset(a,b){setDialogMode(0);var d=(Q("rapassword1").value.length>0);var f=(Q("rapassword2").value.length>0)&&(Q("rapassword2").value==Q("rapassword1").value);var c=(d&&f);QS("rnuPass1").color=d?"black":"#7b241c";QS("rnuPass2").color=f?"black":"#7b241c";if(Q("rapassword1").value==""){QH("rpassWarning","");QV("rpasswordPolicyCallout",false)}else{if(!passRequirementsEx){var h=checkPasswordStrength(Q("rapassword1").value);if(h>=80){QH("rpassWarning","<span style=color:green><b>Strong Password</b><span>")}else{if(h>=60){QH("rpassWarning","<span style=color:blue><b>Good Password</b><span>")}else{QH("rpassWarning","<span style=color:red><b>Weak Password</b><span>")}}}else{var g=checkPasswordRequirements(Q("rapassword1").value,passRequirements);if(g==false){c=false;QS("rnuPass1").color="#7b241c";QS("rnuPass2").color="#7b241c";QH("rpassWarning","<div style=color:red;cursor:pointer onclick=showPasswordPolicy()><b>Password Policy</b><div>");QV("rpasswordPolicyCallout",true);QH("rpasswordPolicyCallout",passwordPolicyText(Q("rapassword1").value))}else{QH("rpassWarning","");QV("rpasswordPolicyCallout",false)}}}if((b!=null)&&(b.keyCode==13)){if(a==2){Q("rapassword1").focus()}if(a==3){Q("rapassword2").focus()}if(a==4){Q("rapasswordhint").focus()}if(a==6){Q("resetPassButton").click()}}if(b!=null){haltEvent(b)}QE("resetPassButton",c)}function validateReset(a){setDialogMode(0);var b=validateEmail(Q("remail").value);QE("eresetButton",b);if((a!=null)&&(a.keyCode==13)&&(b==true)){Q("eresetButton").click()}if(a!=null){haltEvent(a)}}function passwordPolicyText(b){var c="<div style=text-align:left>";var a=strCount(b);if(passRequirements.min&&((b==null)||(b.length<passRequirements.min))){c+="Minimum length of "+passRequirements.min+"<br />"}if(passRequirements.max&&((b==null)||(b.length>passRequirements.max))){c+="Maximum length of "+passRequirements.max+"<br />"}if(passRequirements.upper&&((b==null)||(a.upper<passRequirements.upper))){c+=""+passRequirements.upper+" upper case<br />"}if(passRequirements.lower&&((b==null)||(a.lower<passRequirements.lower))){c+=""+passRequirements.lower+" lower case<br />"}if(passRequirements.numeric&&((b==null)||(a.numeric<passRequirements.numeric))){c+=""+passRequirements.numeric+" numeric<br />"}if(passRequirements.nonalpha&&((b==null)||(a.nonalpha<passRequirements.nonalpha))){c+=passRequirements.nonalpha+" non-alphanumeric<br />"}c+="</div>";return c}function checkPasswordStrength(e){var f=0,d={},g=0,h={digits:/\d/.test(e),lower:/[a-z]/.test(e),upper:/[A-Z]/.test(e),nonWords:/\W/.test(e)};if(!e){return 0}for(var b=0;b<e.length;b++){d[e[b]]=(d[e[b]]||0)+1;f+=5/d[e[b]]}for(var a in h){g+=(h[a]==true)?1:0}return parseInt(f+(g-1)*10)}function checkPasswordRequirements(b,c){if((c==null)||(c=="")||(typeof c!="object")){return true}if(c.min){if(b.length<c.min){return false}}if(c.max){if(b.length>c.max){return false}}var a=strCount(b);if(c.numeric&&(a.numeric<c.numeric)){return false}if(c.lower&&(a.lower<c.lower)){return false}if(c.upper&&(a.upper<c.upper)){return false}if(c.nonalpha&&(a.nonalpha<c.nonalpha)){return false}return true}function strCount(c){var a={numeric:0,lower:0,upper:0,nonalpha:0};if(typeof c!="string"){return a}for(var b=0;b<c.length;b++){if(/\d/.test(c[b])){a.numeric++}if(/[a-z]/.test(c[b])){a.lower++}if(/[A-Z]/.test(c[b])){a.upper++}if(/\W/.test(c[b])){a.nonalpha++}}return a}var xcheckTokenTimer=null;function checkTokenTimer(a){if((a==0)&&(xcheckTokenTimer!=null)){clearInterval(xcheckTokenTimer);xcheckTokenTimer=null}if((a==1)&&(xcheckTokenTimer==null)){xcheckTokenTimer=setInterval(checkToken,200)}}function checkToken(){var a=Q("tokenInput").value,b=a.split(" ").join("");if(a!=b){Q("tokenInput").value=b}QE("tokenOkButton",(Q("tokenInput").value.length==6)||(Q("tokenInput").value.length==8)||(Q("tokenInput").value.length==44))}function resetCheckToken(){var a=Q("resetTokenInput").value,b=a.split(" ").join("");if(a!=b){Q("resetTokenInput").value=b}QE("resetTokenOkButton",(Q("resetTokenInput").value.length==6)||(Q("resetTokenInput").value.length==8)||(Q("resetTokenInput").value.length==44))}var xxdialogMode;var xxdialogFunc;var xxdialogButtons;var xxdialogTag;var xxcurrentView=0;function setDialogMode(j,k,a,e,d,h){xxdialogMode=j;xxdialogFunc=e;xxdialogButtons=a;xxdialogTag=h;QE("idx_dlgOkButton",true);QV("idx_dlgOkButton",a&1);QV("idx_dlgCancelButton",a&2);QV("id_dialogclose",(a&2)||(a&8));QV("idx_dlgButtonBar",a&7);if(k){QH("id_dialogtitle",k)}for(var g=1;g<24;g++){QV("dialog"+g,g==j)}QV("dialog",j);if(d){if(j==2){QH("id_dialogOptions",d)}else{QH("id_dialogMessage",d)}}}function dialogclose(e){var c=xxdialogFunc;var a=xxdialogButtons;var d=xxdialogTag;setDialogMode();if(((a&8)||e)&&c){c(e,d)}}function center(){QS("dialog").left=((((getDocWidth()-400)/2))+"px")}function messagebox(b,a){QH("id_dialogMessage",a);setDialogMode(1,b,1)}function statusbox(b,a){QH("id_dialogMessage",a);setDialogMode(1,b)}function getDocWidth(){if(window.innerWidth){return window.innerWidth}if(document.documentElement&&document.documentElement.clientWidth&&document.documentElement.clientWidth!=0){return document.documentElement.clientWidth}return document.getElementsByTagName("body")[0].clientWidth}function haltEvent(a){if(a.preventDefault){a.preventDefault()}if(a.stopPropagation){a.stopPropagation()}return false}function haltReturn(a){if(a.keyCode==13){haltEvent(a)}}function validateEmail(b){var a=/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;return a.test(b)}function u2fSupported(){return(window.u2f&&((navigator.userAgent.indexOf("Chrome/")>0)||(navigator.userAgent.indexOf("Firefox/")>0)||(navigator.userAgent.indexOf("Opera/")>0)||(navigator.userAgent.indexOf("Safari/")>0)))};</script></body></html>
\ No newline at end of file
views/login-mobile.handlebars
+6 -6
@@ -288,12 +288,12 @@
288 if ('{{loginmode}}' == '4') {
289 try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
290 if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
291 - hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), c => c.charCodeAt(0)).buffer;
291 + hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer;
292
293 - const publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
293 + var publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
294 for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
295 publicKeyCredentialRequestOptions.allowCredentials.push(
296 - { id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), c => c.charCodeAt(0)), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
296 + { id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
297 );
298 }
299
@@ -328,12 +328,12 @@
328 if ('{{loginmode}}' == '5') {
329 try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
330 if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
331 - hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), c => c.charCodeAt(0)).buffer;
331 + hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer;
332
333 - const publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
333 + var publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
334 for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
335 publicKeyCredentialRequestOptions.allowCredentials.push(
336 - { id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), c => c.charCodeAt(0)), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
336 + { id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
337 );
338 }
339
views/login.handlebars
+7 -7
@@ -87,7 +87,7 @@
87 }
88 </style>
89 <script type="text/javascript" src="scripts/common-0.0.1.js"></script>
90 - <script type="text/javascript" src="scripts/u2f-api.js"></script>
90 + <script keeplink=1 type="text/javascript" src="scripts/u2f-api.js"></script>
91 <title>MeshCentral - Login</title>
92 </head>
93 <body onload="if (typeof(startup) !== 'undefined') startup();">
@@ -373,12 +373,12 @@
373 if ('{{loginmode}}' == '4') {
374 try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
375 if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
376 - hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), c => c.charCodeAt(0)).buffer;
376 + hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer;
377
378 - const publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
378 + var publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
379 for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
380 publicKeyCredentialRequestOptions.allowCredentials.push(
381 - { id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), c => c.charCodeAt(0)), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
381 + { id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
382 );
383 }
384
@@ -413,12 +413,12 @@
413 if ('{{loginmode}}' == '5') {
414 try { if (hardwareKeyChallenge.length > 0) { hardwareKeyChallenge = JSON.parse(hardwareKeyChallenge); } else { hardwareKeyChallenge = null; } } catch (ex) { hardwareKeyChallenge = null }
415 if ((hardwareKeyChallenge != null) && (hardwareKeyChallenge.type == 'webAuthn')) {
416 - hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), c => c.charCodeAt(0)).buffer;
416 + hardwareKeyChallenge.challenge = Uint8Array.from(atob(hardwareKeyChallenge.challenge), function (c) { return c.charCodeAt(0) }).buffer;
417
418 - const publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
418 + var publicKeyCredentialRequestOptions = { challenge: hardwareKeyChallenge.challenge, allowCredentials: [], timeout: hardwareKeyChallenge.timeout }
419 for (var i = 0; i < hardwareKeyChallenge.keyIds.length; i++) {
420 publicKeyCredentialRequestOptions.allowCredentials.push(
421 - { id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), c => c.charCodeAt(0)), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
421 + { id: Uint8Array.from(atob(hardwareKeyChallenge.keyIds[i]), function (c) { return c.charCodeAt(0) }), type: 'public-key', transports: ['usb', 'ble', 'nfc'], }
422 );
423 }
424
views/messenger-min.handlebars
+1 -847
@@ -1,847 +1 @@
1 -<!DOCTYPE html> <html style="height:100%"> <head> <title>MeshMessenger</title> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta content="text/html;charset=utf-8" http-equiv="Content-Type"> <meta name="format-detection" content="telephone=no"> <style>body{margin:0;padding:0;border:0;color:black;font-size:13px;font-family:"Trebuchet MS", Arial, Helvetica, sans-serif;background-color:#d3d9d6;}#container{background-color:#fff;width:960px;min-width:960px;margin:0 auto;border-top:0;border-right:1px solid #b7b7b7;border-bottom:0;border-left:1px solid #b7b7b7;padding:0;}#masthead{width:auto;margin:0;padding:0;overflow:auto;text-align:right;background-color:#036;width:960px;}#column_l{position:relative;float:left;width:930px;margin:0;padding:0 15px;background-color:#fff;}#footer{clear:both;overflow:auto;width:100%;text-align:center;background-color:#113962;padding-top:5px;padding-bottom:5px;}#masthead img{float:left;}#masthead p{font-size:11px;color:#fff;margin:10px 10px 0;}#footer a{color:#fff;text-decoration:underline;}#footer a:hover{color:#fff;text-decoration:none;}a{color:#036;text-decoration:underline;}.i1{background:url(../images/icons50.png) 0px 0px;height:50px;width:50px;cursor:pointer;border:none;}.i2{background:url(../images/icons50.png) -50px 0px;height:50px;width:50px;cursor:pointer;border:none;}.i3{background:url(../images/icons50.png) -100px 0px;height:50px;width:50px;cursor:pointer;border:none;}.i4{background:url(../images/icons50.png) -150px 0px;height:50px;width:50px;cursor:pointer;border:none;}.i5{background:url(../images/icons50.png) -200px 0px;height:50px;width:50px;cursor:pointer;border:none;}.i6{background:url(../images/icons50.png) -250px 0px;height:50px;width:50px;cursor:pointer;border:none;}.j1{background:url(../images/icons16.png) 0px 0px;height:16px;width:16px;cursor:pointer;border:none;}.j2{background:url(../images/icons16.png) -16px 0px;height:16px;width:16px;cursor:pointer;border:none;}.j3{background:url(../images/icons16.png) -32px 0px;height:16px;width:16px;cursor:pointer;border:none;}.j4{background:url(../images/icons16.png) -48px 0px;height:16px;width:16px;cursor:pointer;border:none;}.j5{background:url(../images/icons16.png) -64px 0px;height:16px;width:16px;cursor:pointer;border:none;}.j6{background:url(../images/icons16.png) -80px 0px;height:16px;width:16px;cursor:pointer;border:none;}.lbbutton{width:74px;height:74px;border-radius:5px;background-color:white;margin-left:8px;margin-top:8px;position:relative;cursor:pointer;opacity:0.5;}.lbbutton:hover{opacity:1;}.lbbuttonsel{opacity:0.9;}.lbbuttonsel2{width:82px;border-radius:5px 0px 0px 5px;opacity:1;}.lb1{background:url(../images/leftbar-62.jpg) -0px 0px;height:62px;width:62px;cursor:pointer;border:none;}.lb2{background:url(../images/leftbar-62.jpg) -75px 0px;height:62px;width:62px;cursor:pointer;border:none;}.lb3{background:url(../images/leftbar-62.jpg) -150px 0px;height:62px;width:62px;cursor:pointer;border:none;}.lb4{background:url(../images/leftbar-62.jpg) -225px 0px;height:62px;width:62px;cursor:pointer;border:none;}.lb5{background:url(../images/leftbar-62.jpg) -294px 0px;height:62px;width:62px;cursor:pointer;border:none;}.lb6{background:url(../images/leftbar-62.jpg) -360px 0px;height:62px;width:62px;cursor:pointer;border:none;}.m0{background :url(../images/images16.png) -32px 0px;height :16px;width :16px;border:none;float:left }.m1{background :url(../images/images16.png) -16px 0px;height :16px;width :16px;border:none;float:left }.m2{background :url(../images/images16.png) -96px 0px;height :16px;width :16px;border:none;float:left }.m3{background :url(../images/images16.png) -112px 0px;height :16px;width :16px;border:none;float:left }.si0{background :url(../images/icons16.png) 0px 0px;height :16px;width :16px;border:none;float:left }.si1{background :url(../images/icons16.png) -16px 0px;height :16px;width :16px;border:none;float:left }.si2{background :url(../images/icons16.png) -32px 0px;height :16px;width :16px;border:none;float:left }.si3{background :url(../images/icons16.png) -48px 0px;height :16px;width :16px;border:none;float:left }.si4{background :url(../images/icons16.png) -64px 0px;height :16px;width :16px;border:none;float:left }.mi{background :url(../images/meshicon50.png) 0px 0px;height:50px;width:50px;cursor:pointer;border:none }#floatframe{position:fixed;top:200px;height:300px;z-index:200;display:none;}.style1{text-align:center;}.style2{text-align:center;background-color:#808080;font-weight:bold;}.style3{text-align:center;color:white;background-color:#808080;font-weight:bold;}.style3x{text-align:center;color:white;background-color:#808080;font-weight:bold;}.style3x:hover{background-color:#606060;}.style3sel{text-align:center;color:white;background-color:#003366;font-weight:bold;}.style4{color:white;text-decoration:none;}.style5{text-align:center;background-color:#808080;font-weight:normal;}.style6{text-align:center;background-color:#D3D9D6;}.style7{font-size:large;background-color:#FFFFFF;}.style10{background-color:#C9C9C9;}.style11{font-size:large;background-color:#C9C9C9;}.style14{text-align:left;background-color:#D3D9D6;}.auto-style1{text-align:right;background-color:#D3D9D6;}.fileIcon1{background:url(data:image/gif;base64,R0lGODlhEAAQAJEDAPb49Y2Sj9LT2f///yH5BAEAAAMALAAAAAAQABAAAAImnI+py+1vhJwyUYAzHTL4D3qdlJWaIFJqmKod607sDKIiDUP63hQAOw==);height:16px;width:16px;cursor:pointer;border:none;float:left;margin-top:1px;}.fileIcon2{background:url(data:image/gif;base64,R0lGODlhEAAQAJEDAM2xV/Xur+XPgP///yH5BAEAAAMALAAAAAAQABAAAAJD3ISZIGHWUGihznesYDYATFVM+D2hJ4lgN1olxALAtAlmPCJvuMmJd6PJckDYwicrHhTD5o7plJmg0Uc0asNMkphHAQA7);height:16px;width:16px;cursor:pointer;border:none;float:left;margin-top:1px;}.fileIcon3{background:url(data:image/gif;base64,R0lGODlhEAAQAJEDAPb19IGBgbq6uv///yH5BAEAAAMALAAAAAAQABAAAAIy3ISpxgcPH2ouQgFEw1YmxnUXKEaaEZZnVWZk66JwzKpvuwZzwOgwb/C1gIOA8Yg8DgoAOw==);height:16px;width:16px;cursor:pointer;border:none;float:left;margin-top:1px;}.fileIcon4{background:url(../images/meshicon16.png);height:16px;width:16px;cursor:pointer;border:none;float:left;margin-top:1px;}.filelist{-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none;cursor:default;-khtml-user-drag:element;background-color:white;clear:both;}.noselect{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}.fsize{float:right;text-align:right;width:180px;}.g1{background-position:0% 0%;width:14px;height:100%;float:left; background-image:linear-gradient(to right, #ffffff 0%, #c9c9c9 100%);background-color:#c9c9c9;background-repeat:repeat;background-attachment:scroll;}.g1s{background-image:linear-gradient(to right, #ffffff 0%, #b9b9b9 100%);}.g2{background-position:0% 0%;width:14px;height:100%;float:right; background-image:linear-gradient(to right, #c9c9c9 0%, #ffffff 100%);background-color:#c9c9c9;background-repeat:repeat;background-attachment:scroll;}.g2s{background-image:linear-gradient(to right, #b9b9b9 0%, #ffffff 100%);}.h1{background-position:0% 0%;width:14px;height:100%; background-image:linear-gradient(to right, #ffffff 0%, #d3d9d6 100%);background-color:#d3d9d6;background-repeat:repeat;background-attachment:scroll;}.h2{background-position:0% 0%;width:14px;height:100%; background-image:linear-gradient(to right, #d3d9d6 0%, #ffffff 100%);background-color:#d3d9d6;background-repeat:repeat;background-attachment:scroll;}.e1{font-size:large;margin-top:4px;margin-bottom:3px;overflow:hidden;word-wrap:hyphenate;white-space:nowrap;text-overflow:ellipsis;}.e2{float:left;height:100%;background-color:#c9c9c9;}.e2s{background-color:#b9b9b9;}.bar{font-size:large;background-color:#C9C9C9;height:24px;float:left;margin-bottom:2px;}.bar2{font-size:large;height:24px;float:left;margin-bottom:2px;}.bar18{font-size:large;background-color:#C9C9C9;height:18px;float:left;margin-bottom:2px;}.bar182{font-size:large;height:18px;float:left;margin-bottom:2px;}.devHeaderx{color:lightgray;}.DevSt{border-bottom-style:solid;border-bottom-width:1px;border-bottom-color:#DDDDDD;}.contextMenu{background:#F9F9F9;box-shadow:0 0 12px rgba( 0, 0, 0, .3 );border:1px solid #ccc; display:none;position:absolute;top:0;left:0;list-style:none;margin:0;padding:5px;min-width:100px;max-width:150px;z-index:500;}.cmtext{color:#444;display:inline-block;padding-left:8px;padding-right:8px;padding-top:5px;padding-bottom:5px;text-decoration:none;width:85%;cursor:default;overflow:hidden;position:relative;}.cmtext:hover{color:#f9f9f9;background:#444;}.gray{ filter:gray; -webkit-filter:grayscale(100%) opacity(60%); }.unselectable{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}.notifiyBox{position:absolute;z-index:1000;top:50px;right:26px;width:300px;text-align:left;background-color:#F0ECCD;border:4px solid #666;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;-webkit-box-shadow:2px 2px 4px #888;-moz-box-shadow:2px 2px 4px #888;box-shadow:2px 2px 4px #888;max-height:200px;}.notifiyBox:before{content:' ';position:absolute;width:0;height:0;right:5px;top:-30px;border:15px solid;border-color:transparent #666 #666 transparent;}.notifiyBox:after{content:' ';position:absolute;width:0;height:0;right:7px;top:-24px;border:12px solid;border-color:transparent #F0ECCD #F0ECCD transparent;}.notification{width:100%;min-height:30px;}.notification:hover{background-color:#EFE8B6;}.deskToolsBar{padding:3px;}.deskToolsBar:hover{background-color:#EFE8B6;}.userTableHeader{border-bottom:1pt solid lightgray;padding-top:4px;padding-bottom:4px;}.viewSelector{width:32px;height:32px;background-color:#DDD;border-radius:3px;float:left;margin-left:5px;cursor:pointer;opacity:0.3;}.viewSelectorSel{background-color:#BBB;opacity:0.8;}.viewSelector:hover{opacity:0.5;background-color:#AAA;}.viewSelector1{margin-left:2px;margin-top:2px;background:url(../images/views.png) -0px 0px;height:28px;width:28px;}.viewSelector2{margin-left:2px;margin-top:2px;background:url(../images/views.png) -28px 0px;height:28px;width:28px;}.viewSelector3{margin-left:2px;margin-top:2px;background:url(../images/views.png) -56px 0px;height:28px;width:28px;}.viewSelector4{margin-left:2px;margin-top:2px;background:url(../images/views.png) -84px 0px;height:28px;width:28px;}.viewSelector5{margin-left:2px;margin-top:2px;background:url(../images/views.png) -112px 0px;height:28px;width:28px;}.backButtonEx{margin-left:2px;margin-top:2px;background:url(../images/views.png) -140px 0px;height:28px;width:28px;}.backButton{width:32px;height:32px;background-color:#DDD;border-radius:3px;float:left;margin-right:5px;cursor:pointer;opacity:0.3;}.backButton:hover{opacity:0.5;background-color:#AAA;}.hoverButton{opacity:0.5;}.hoverButton:hover{opacity:1;}</style> <style>.topButton{cursor:pointer;border:none;margin:2px;margin-top:3px;float:right;border-radius:3px;height:32px;width:32px;}.topButton:hover{background-color:lightgray;}.topRedButton{cursor:pointer;border:none;margin:2px;float:right;border-radius:3px;height:32px;width:32px;}.topRedButton:hover{background-color:orangered;}.remoteBubble{background-color:#00cc99;color:black;border-radius:5px;padding:5px;float:left;margin-bottom:5px;margin-right:20px;box-shadow:3px 3px 10px gray;}.localBubble{background-color:#0099ff;color:black;border-radius:5px;padding:5px;float:right;margin-bottom:5px;margin-left:20px;box-shadow:3px 3px 10px gray;}.icon1{background:url(../images/messenger32.png) 0px 0px;background-color:gray;}.icon2{background:url(../images/messenger32.png) -32px 0px;background-color:gray;}.icon3{background:url(../images/messenger32.png) -64px 0px;background-color:gray;}.icon4{background:url(../images/messenger32.png) -96px 0px;background-color:gray;}.icon5{background:url(../images/messenger32.png) -128px 0px;background-color:gray;}.icon6{background:url(../images/messenger32.png) -160px 0px;background-color:gray;}.icon7{background:url(../images/messenger32.png) -192px 0px;background-color:gray;}.icon8{background:url(../images/messenger32.png) -224px 0px;background-color:gray;}.icon9{background:url(images/messenger32.png) -256px 0px;background-color:gray;}.icon10{background:url(../images/messenger32.png) -288px 0px;background-color:gray;}.icon11{background:url(../images/messenger32.png) -320px 0px;background-color:orange;}.fileicon{background:url(../images/messenger32.png) -96px 0px;height:32px;width:32px;}.fileiconx{background:url(../images/messenger32.png) -352px 0px;height:32px;width:32px;}.fileicontransfer{background:url(../images/messenger32.png) -288px 0px;height:32px;width:32px;}.fileicondone{background:url(../images/messenger32.png) -256px 0px;height:32px;width:32px;}</style> </head> <body style="font-family:Arial,Helvetica,sans-serif"> <div id="xtop" style="position:absolute;left:0;right:0;top:0;height:38px;background-color:#036;color:#c8c8c8;box-shadow:3px 3px 10px gray"> <div id="fileButton" class="icon4 topButton" title="Share a file" style="display:none" onclick="fileButtonClick()"></div> <div id="camButton" class="icon2 topButton" title="Activate camera & microphone" style="display:none" onclick="camButtonClick()"></div> <div id="micButton" class="icon6 topButton" title="Activate microphone" style="display:none" onclick="micButtonClick()"></div> <div id="hangupButton" class="icon11 topRedButton" title="Hang up" style="display:none" onclick="hangUpButtonClick(1)"></div> <div style="display:inline-block;width:2px"></div> <div style="padding-top:9px;padding-left:6px;font-size:20px;display:inline-block"><b>MeshMessenger<span id="xtitle"></span></b></div> </div> <div id="xmiddle" style="position:absolute;left:0;right:0;top:38px;bottom:30px"> <div style="position:absolute;left:0;right:0;top:0;bottom:0;overflow-y:scroll"> <div id="xmsg" style="position:absolute;left:0;right:0;bottom:0;padding:5px"></div> </div> </div> <div id="xbottom" style="position:absolute;left:0;right:0;bottom:0px;height:30px;background-color:#036"> <div style="position:absolute;left:5px;right:215px;bottom:4px;top:4px;background-color:aliceblue"><input id="xouttext" type="text" style="width:calc(100% - 5px)" onfocus="onUserInputFocus(1)" onblur="onUserInputFocus(0)"></div> <input type="button" id="sendButton" value="Send" style="position:absolute;right:110px;width:100px;top:4px;" onclick="xsend(event)"> <input type="button" id="clearButton" value="Clear" style="position:absolute;right:5px;width:100px;top:4px;" onclick="displayClear()"> </div> <div id="remoteVideo" style="position:absolute;right:24px;top:45px;width:320px;height:calc(240px + 30px);background-color:gray;border-radius:12px 12px 12px 12px;box-shadow:3px 3px 10px gray;display:none"> <div style="position:absolute;right:0;left:0;top:2.5px;text-align:center">Remote</div> <video id="remoteVideoCanvas" autoplay="" style="position:absolute;top:20px;left:0;width:100%;height:calc(100% - 30px);background-color:black"></video> </div> <div id="localVideo" style="position:absolute;right:24px;top:320px;width:160px;height:calc(120px + 30px);background-color:gray;border-radius:12px 12px 12px 12px;box-shadow:3px 3px 10px gray;display:none"> <div style="position:absolute;right:0;left:0;top:2.5px;text-align:center">Local</div> <video id="localVideoCanvas" autoplay="" muted="" style="position:absolute;top:20px;left:0;width:100%;height:calc(100% - 30px);background-color:black"></video> </div> <input id="uploadFileInput" type="file" multiple="" style="display:none"> <script>/**
2 -* @description Set of short commonly used methods for handling HTML elements
3 -* @author Ylian Saint-Hilaire
4 -* @version v0.0.1b
5 -*/
6 -
7 -// Add startsWith for IE browser
8 -if (!String.prototype.startsWith) { String.prototype.startsWith = function (str) { return this.lastIndexOf(str, 0) === 0; }; }
9 -if (!String.prototype.endsWith) { String.prototype.endsWith = function (str) { return this.indexOf(str, this.length - str.length) !== -1; }; }
10 -
11 -// Quick UI functions, a bit of a replacement for jQuery
12 -//function Q(x) { if (document.getElementById(x) == null) { console.log('Invalid element: ' + x); } return document.getElementById(x); } // "Q"
13 -function Q(x) { return document.getElementById(x); } // "Q"
14 -function QS(x) { try { return Q(x).style; } catch (x) { } } // "Q" style
15 -function QE(x, y) { try { Q(x).disabled = !y; } catch (x) { } } // "Q" enable
16 -function QV(x, y) { try { QS(x).display = (y ? '' : 'none'); } catch (x) { } } // "Q" visible
17 -function QA(x, y) { Q(x).innerHTML += y; } // "Q" append
18 -function QH(x, y) { Q(x).innerHTML = y; } // "Q" html
19 -
20 -// Move cursor to end of input box
21 -function inputBoxFocus(x) { Q(x).focus(); var v = Q(x).value; Q(x).value = ''; Q(x).value = v; }
22 -
23 -// Binary encoding and decoding functions
24 -function ReadShort(v, p) { return (v.charCodeAt(p) << 8) + v.charCodeAt(p + 1); }
25 -function ReadShortX(v, p) { return (v.charCodeAt(p + 1) << 8) + v.charCodeAt(p); }
26 -function ReadInt(v, p) { return (v.charCodeAt(p) * 0x1000000) + (v.charCodeAt(p + 1) << 16) + (v.charCodeAt(p + 2) << 8) + v.charCodeAt(p + 3); } // We use "*0x1000000" instead of "<<24" because the shift converts the number to signed int32.
27 -function ReadSInt(v, p) { return (v.charCodeAt(p) << 24) + (v.charCodeAt(p + 1) << 16) + (v.charCodeAt(p + 2) << 8) + v.charCodeAt(p + 3); }
28 -function ReadIntX(v, p) { return (v.charCodeAt(p + 3) * 0x1000000) + (v.charCodeAt(p + 2) << 16) + (v.charCodeAt(p + 1) << 8) + v.charCodeAt(p); }
29 -function ShortToStr(v) { return String.fromCharCode((v >> 8) & 0xFF, v & 0xFF); }
30 -function ShortToStrX(v) { return String.fromCharCode(v & 0xFF, (v >> 8) & 0xFF); }
31 -function IntToStr(v) { return String.fromCharCode((v >> 24) & 0xFF, (v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF); }
32 -function IntToStrX(v) { return String.fromCharCode(v & 0xFF, (v >> 8) & 0xFF, (v >> 16) & 0xFF, (v >> 24) & 0xFF); }
33 -function MakeToArray(v) { if (!v || v == null || typeof v == 'object') return v; return [v]; }
34 -function SplitArray(v) { return v.split(','); }
35 -function Clone(v) { return JSON.parse(JSON.stringify(v)); }
36 -function EscapeHtml(x) { if (typeof x == "string") return x.replace(/&/g, '&amp;').replace(/>/g, '&gt;').replace(/</g, '&lt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;'); if (typeof x == "boolean") return x; if (typeof x == "number") return x; }
37 -function EscapeHtmlBreaks(x) { if (typeof x == "string") return x.replace(/&/g, '&amp;').replace(/>/g, '&gt;').replace(/</g, '&lt;').replace(/"/g, '&quot;').replace(/'/g, '&apos;').replace(/\r/g, '<br />').replace(/\n/g, '').replace(/\t/g, '&nbsp;&nbsp;'); if (typeof x == "boolean") return x; if (typeof x == "number") return x; }
38 -
39 -// Move an element from one position in an array to a new position
40 -function ArrayElementMove(arr, from, to) { arr.splice(to, 0, arr.splice(from, 1)[0]); };
41 -
42 -// Print object for HTML
43 -function ObjectToStringEx(x, c) {
44 - var r = "";
45 - if (x != 0 && (!x || x == null)) return "(Null)";
46 - if (x instanceof Array) { for (var i in x) { r += '<br />' + gap(c) + "Item #" + i + ": " + ObjectToStringEx(x[i], c + 1); } }
47 - else if (x instanceof Object) { for (var i in x) { r += '<br />' + gap(c) + i + " = " + ObjectToStringEx(x[i], c + 1); } }
48 - else { r += EscapeHtml(x); }
49 - return r;
50 -}
51 -
52 -// Print object for console
53 -function ObjectToStringEx2(x, c) {
54 - var r = "";
55 - if (x != 0 && (!x || x == null)) return "(Null)";
56 - if (x instanceof Array) { for (var i in x) { r += '\r\n' + gap2(c) + "Item #" + i + ": " + ObjectToStringEx2(x[i], c + 1); } }
57 - else if (x instanceof Object) { for (var i in x) { r += '\r\n' + gap2(c) + i + " = " + ObjectToStringEx2(x[i], c + 1); } }
58 - else { r += EscapeHtml(x); }
59 - return r;
60 -}
61 -
62 -// Create an ident gap
63 -function gap(c) { var x = ''; for (var i = 0; i < (c * 4) ; i++) { x += '&nbsp;'; } return x; }
64 -function gap2(c) { var x = ''; for (var i = 0; i < (c * 4) ; i++) { x += ' '; } return x; }
65 -
66 -// Print an object in html
67 -function ObjectToString(x) { return ObjectToStringEx(x, 0); }
68 -function ObjectToString2(x) { return ObjectToStringEx2(x, 0); }
69 -
70 -// Convert a hex string to a raw string
71 -function hex2rstr(d) {
72 - if (typeof d != "string" || d.length == 0) return '';
73 - var r = '', m = ('' + d).match(/../g), t;
74 - while (t = m.shift()) r += String.fromCharCode('0x' + t);
75 - return r
76 -}
77 -
78 -// Convert decimal to hex
79 -function char2hex(i) { return (i + 0x100).toString(16).substr(-2).toUpperCase(); }
80 -
81 -// Convert a raw string to a hex string
82 -function rstr2hex(input) { var r = '', i; for (i = 0; i < input.length; i++) { r += char2hex(input.charCodeAt(i)); } return r; }
83 -
84 -// UTF-8 encoding & decoding functions
85 -function encode_utf8(s) { return unescape(encodeURIComponent(s)); }
86 -function decode_utf8(s) { return decodeURIComponent(escape(s)); }
87 -
88 -// Convert a string into a blob
89 -function data2blob(data) {
90 - var bytes = new Array(data.length);
91 - for (var i = 0; i < data.length; i++) bytes[i] = data.charCodeAt(i);
92 - var blob = new Blob([new Uint8Array(bytes)]);
93 - return blob;
94 -}
95 -
96 -// Generate random numbers
97 -function random(max) { return Math.floor(Math.random() * max); }
98 -
99 -// Trademarks
100 -function trademarks(x) { return x.replace(/\(R\)/g, '&reg;').replace(/\(TM\)/g, '&trade;'); }
101 -(function (global, factory) {
102 - if (typeof define === "function" && define.amd) {
103 - define([], factory);
104 - } else if (typeof exports !== "undefined") {
105 - factory();
106 - } else {
107 - var mod = {
108 - exports: {}
109 - };
110 - factory();
111 - global.FileSaver = mod.exports;
112 - }
113 -})(this, function () {
114 - "use strict";
115 -
116 - /*
117 - * FileSaver.js
118 - * A saveAs() FileSaver implementation.
119 - *
120 - * By Eli Grey, http://eligrey.com
121 - *
122 - * License : https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md (MIT)
123 - * source : http://purl.eligrey.com/github/FileSaver.js
124 - */
125 - // The one and only way of getting global scope in all environments
126 - // https://stackoverflow.com/q/3277182/1008999
127 - var _global = typeof window === 'object' && window.window === window ? window : typeof self === 'object' && self.self === self ? self : typeof global === 'object' && global.global === global ? global : void 0;
128 -
129 - function bom(blob, opts) {
130 - if (typeof opts === 'undefined') opts = {
131 - autoBom: false
132 - };else if (typeof opts !== 'object') {
133 - console.warn('Depricated: Expected third argument to be a object');
134 - opts = {
135 - autoBom: !opts
136 - };
137 - } // prepend BOM for UTF-8 XML and text/* types (including HTML)
138 - // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF
139 -
140 - if (opts.autoBom && /^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(blob.type)) {
141 - return new Blob([String.fromCharCode(0xFEFF), blob], {
142 - type: blob.type
143 - });
144 - }
145 -
146 - return blob;
147 - }
148 -
149 - function download(url, name, opts) {
150 - var xhr = new XMLHttpRequest();
151 - xhr.open('GET', url);
152 - xhr.responseType = 'blob';
153 -
154 - xhr.onload = function () {
155 - saveAs(xhr.response, name, opts);
156 - };
157 -
158 - xhr.onerror = function () {
159 - console.error('could not download file');
160 - };
161 -
162 - xhr.send();
163 - }
164 -
165 - function corsEnabled(url) {
166 - var xhr = new XMLHttpRequest(); // use sync to avoid popup blocker
167 -
168 - xhr.open('HEAD', url, false);
169 - xhr.send();
170 - return xhr.status >= 200 && xhr.status <= 299;
171 - } // `a.click()` doesn't work for all browsers (#465)
172 -
173 -
174 - function click(node) {
175 - try {
176 - node.dispatchEvent(new MouseEvent('click'));
177 - } catch (e) {
178 - var evt = document.createEvent('MouseEvents');
179 - evt.initMouseEvent('click', true, true, window, 0, 0, 0, 80, 20, false, false, false, false, 0, null);
180 - node.dispatchEvent(evt);
181 - }
182 - }
183 -
184 - var saveAs = _global.saveAs || // probably in some web worker
185 - typeof window !== 'object' || window !== _global ? function saveAs() {}
186 - /* noop */
187 - // Use download attribute first if possible (#193 Lumia mobile)
188 - : 'download' in HTMLAnchorElement.prototype ? function saveAs(blob, name, opts) {
189 - var URL = _global.URL || _global.webkitURL;
190 - var a = document.createElement('a');
191 - name = name || blob.name || 'download';
192 - a.download = name;
193 - a.rel = 'noopener'; // tabnabbing
194 - // TODO: detect chrome extensions & packaged apps
195 - // a.target = '_blank'
196 -
197 - if (typeof blob === 'string') {
198 - // Support regular links
199 - a.href = blob;
200 -
201 - if (a.origin !== location.origin) {
202 - corsEnabled(a.href) ? download(blob, name, opts) : click(a, a.target = '_blank');
203 - } else {
204 - click(a);
205 - }
206 - } else {
207 - // Support blobs
208 - a.href = URL.createObjectURL(blob);
209 - setTimeout(function () {
210 - URL.revokeObjectURL(a.href);
211 - }, 4E4); // 40s
212 -
213 - setTimeout(function () {
214 - click(a);
215 - }, 0);
216 - }
217 - } // Use msSaveOrOpenBlob as a second approach
218 - : 'msSaveOrOpenBlob' in navigator ? function saveAs(blob, name, opts) {
219 - name = name || blob.name || 'download';
220 -
221 - if (typeof blob === 'string') {
222 - if (corsEnabled(blob)) {
223 - download(blob, name, opts);
224 - } else {
225 - var a = document.createElement('a');
226 - a.href = blob;
227 - a.target = '_blank';
228 - setTimeout(function () {
229 - click(a);
230 - });
231 - }
232 - } else {
233 - navigator.msSaveOrOpenBlob(bom(blob, opts), name);
234 - }
235 - } // Fallback to using FileReader and a popup
236 - : function saveAs(blob, name, opts, popup) {
237 - // Open a popup immediately do go around popup blocker
238 - // Mostly only avalible on user interaction and the fileReader is async so...
239 - popup = popup || open('', '_blank');
240 -
241 - if (popup) {
242 - popup.document.title = popup.document.body.innerText = 'downloading...';
243 - }
244 -
245 - if (typeof blob === 'string') return download(blob, name, opts);
246 - var force = blob.type === 'application/octet-stream';
247 -
248 - var isSafari = /constructor/i.test(_global.HTMLElement) || _global.safari;
249 -
250 - var isChromeIOS = /CriOS\/[\d]+/.test(navigator.userAgent);
251 -
252 - if ((isChromeIOS || force && isSafari) && typeof FileReader === 'object') {
253 - // Safari doesn't allow downloading of blob urls
254 - var reader = new FileReader();
255 -
256 - reader.onloadend = function () {
257 - var url = reader.result;
258 - url = isChromeIOS ? url : url.replace(/^data:[^;]*;/, 'data:attachment/file;');
259 - if (popup) popup.location.href = url;else location = url;
260 - popup = null; // reverse-tabnabbing #460
261 - };
262 -
263 - reader.readAsDataURL(blob);
264 - } else {
265 - var URL = _global.URL || _global.webkitURL;
266 - var url = URL.createObjectURL(blob);
267 - if (popup) popup.location = url;else location.href = url;
268 - popup = null; // reverse-tabnabbing #460
269 -
270 - setTimeout(function () {
271 - URL.revokeObjectURL(url);
272 - }, 4E4); // 40s
273 - }
274 - };
275 - _global.saveAs = saveAs.saveAs = saveAs;
276 -
277 - if (typeof module !== 'undefined') {
278 - module.exports = saveAs;
279 - }
280 -});
281 -
282 - var userInputFocus = 0;
283 - var args = parseUriArgs();
284 - var socket = null; // Websocket object
285 - var state = 0; // Connection state. 0 = Disconnected, 1 = Connecting, 2 = Connected.
286 -
287 - // WebRTC sessions and data, audio and video channels
288 - var random = Math.random(); // Selected random, larger value initiates WebRTC.
289 - var webrtcSessions = { }; // WebRTC objects: 0 for data, 1 for outbound audio/video, 2 for inbound audio/video
290 - var webchannel = null; // WebRTC data channel
291 - var localStream = null;
292 - var remoteStream = null;
293 - var multiWebRtc = true; // if set to true, multiple WebRTC sessions will be setup. If false, everything uses one session.
294 - var userMediaSupport = 0;
295 - getUserMediaSupport(function (x) { userMediaSupport = x; })
296 - var webrtcconfiguration = "{{{webrtconfig}}}";
297 - if (webrtcconfiguration == '') { webrtcconfiguration = null; } else { try { webrtcconfiguration = JSON.parse(decodeURIComponent(webrtcconfiguration)); } catch (ex) { console.log('Invalid WebRTC config: \"' + webrtcconfiguration + '\".'); webrtcconfiguration = null; } }
298 -
299 - // File transfer state
300 - var fileUploads = [];
301 - var fileDownloads = {};
302 - var currentFileUpload = null;
303 - var currentFileDownload = null;
304 -
305 - // Set the title
306 - if (args.title) { QH('xtitle', ' - ' + args.title); document.title = document.title + ' - ' + args.title; }
307 -
308 - // Listen to drag & drop events
309 - document.addEventListener('dragover', haltEvent, false);
310 - document.addEventListener('dragleave', haltEvent, false);
311 - document.addEventListener('drop', fileDrop, false);
312 -
313 - // Trap document key up events
314 - document.onkeyup = function ondockeypress(e) {
315 - if (state == 2) {
316 - if ((e.keyCode == 8) && (userInputFocus == 0)) {
317 - // Backspace
318 - var outtext = Q('xouttext').value;
319 - if (outtext.length > 0) { Q('xouttext').value = outtext.substring(0, outtext.length - 1); }
320 - }
321 - }
322 - if (userInputFocus == 0) { haltEvent(e); return false; }
323 - }
324 -
325 - // Trap document key presses
326 - document.onkeypress = function ondockeypress(e) {
327 - if (state == 2) {
328 - if (e.keyCode == 13) {
329 - // Return
330 - xsend(e);
331 - } else {
332 - // Any other key
333 - if ((userInputFocus == 0) && (e.key.length == 1)) { Q('xouttext').value = Q('xouttext').value + e.key; }
334 - }
335 - }
336 - if (userInputFocus == 0) { haltEvent(e); return false; }
337 - }
338 -
339 - function onUserInputFocus(x) { userInputFocus = x; }
340 - function displayClear() { QH('xmsg', ''); cancelAllFileTransfers(); fileUploads = [], fileDownloads = {}; }
341 -
342 - // Polyfill FileReader if needed
343 - if (!FileReader.prototype.readAsBinaryString) {
344 - FileReader.prototype.readAsBinaryString = function (fileData) {
345 - var binary = '', self = this, reader = new FileReader();
346 - reader.onload = function (e) {
347 - var bytes = new Uint8Array(reader.result);
348 - for (var i = 0; i < bytes.byteLength; i++) { binary += String.fromCharCode(bytes[i]); }
349 - self.onload({ target: { result: binary } });
350 - }
351 - reader.readAsArrayBuffer(fileData);
352 - }
353 - }
354 -
355 - // Detect if microphone & camera are present
356 - // 0 = nomedia, 1 = miconly, 2 = mic&cam
357 - function getUserMediaSupport(func) {
358 - try {
359 - navigator.mediaDevices.enumerateDevices().then(function (devices) {
360 - try {
361 - var mic = 0, cam = 0;
362 - devices.forEach(function (device) {
363 - if (device.kind === 'audioinput') { mic = 1; }
364 - if (device.kind === 'videoinput') { cam = 1; }
365 - });
366 - if (mic == 0) { func(0); }
367 - func(mic + cam);
368 - } catch (ex) { }
369 - })
370 - } catch (ex) { }
371 - }
372 -
373 - // Display a control message
374 - function displayControl(msg) {
375 - QA('xmsg', '<div style="clear:both"><div style="color:gray;float:left;margin-bottom:2px">' + msg + '</div><div></div></div>');
376 - Q('xmsg').scrollTop = Q('xmsg').scrollHeight;
377 - }
378 -
379 - function displayLocalVideo(active) { QV('localVideo', active); adjustVideoWindows(); }
380 - function displayRemoteVideo(active) { QV('remoteVideo', active); adjustVideoWindows(); }
381 - function adjustVideoWindows() {
382 - //var lv = (QS('localVideo')['display'] != 'none');
383 - var rv = (QS('remoteVideo')['display'] != 'none');
384 - QS('localVideo')['top'] = rv ? '320px' : '45px';
385 - }
386 -
387 - // Display a message from the remote user
388 - function displayRemote(msg) {
389 - QA('xmsg', '<div style="clear:both"><div class="remoteBubble">' + msg + '</div><div></div></div>');
390 - Q('xmsg').scrollTop = Q('xmsg').scrollHeight;
391 - }
392 -
393 - // Display and send a message from the local user
394 - function xsend(event) {
395 - var outtext = Q('xouttext').value;
396 - if (outtext.length > 0) {
397 - Q('xouttext').value = '';
398 - QA('xmsg', '<div style="clear:both"><div class="localBubble">' + outtext + '</div><div></div></div>');
399 - Q('xmsg').scrollTop = Q('xmsg').scrollHeight;
400 - send({ action: 'chat', msg: outtext });
401 - }
402 - }
403 -
404 - function haltEvent(e) { if (e.preventDefault) e.preventDefault(); if (e.stopPropagation) e.stopPropagation(); return false; }
405 - function parseUriArgs() { var name, r = {}, parsedUri = window.document.location.href.split(/[\?&|\=]/); parsedUri.splice(0, 1); for (x in parsedUri) { switch (x % 2) { case 0: { name = decodeURIComponent(parsedUri[x]); break; } case 1: { r[name] = decodeURIComponent(parsedUri[x]); var x = parseInt(r[name]); if (x == r[name]) { r[name] = x; } break; } default: { break; } } } return r; }
406 -
407 - // Update user controls
408 - function updateControls() {
409 - QE('sendButton', state == 2);
410 - QE('clearButton', state == 2);
411 - QE('xouttext', state == 2);
412 - QV('fileButton', state == 2);
413 - QV('camButton', webchannel && webchannel.ok && !localStream && (userMediaSupport == 2));
414 - QV('micButton', webchannel && webchannel.ok && !localStream && (userMediaSupport > 0));
415 - QV('hangupButton', webchannel && webchannel.ok && localStream);
416 - }
417 -
418 - // This is the WebRTC setup
419 - function startWebRTC(id, startDataChannel) {
420 - if ((webrtcSessions[0] != null) && (multiWebRtc == false)) { return webrtcSessions[0]; };
421 -
422 - // Setup the WebRTC object
423 - var webrtc = null;
424 - if (typeof RTCPeerConnection !== 'undefined') { webrtc = new RTCPeerConnection(webrtcconfiguration); }
425 - else if (typeof webkitRTCPeerConnection !== 'undefined') { webrtc = new webkitRTCPeerConnection(webrtcconfiguration); }
426 - if (webrtc == null) return null; // No WebRTC support.
427 -
428 - webrtc.id = id;
429 - webrtc.onicecandidate = function (e) { try { if (e.candidate != null) { sendws({ action: 'webRtcIce', ice: e.candidate, id: this.id }); } } catch (ex) { } }
430 - webrtc.oniceconnectionstatechange = function () { if (webrtc && webrtc.iceConnectionState == 'failed') { webrtc.close(); if (webrtcSessions[webrtc.id]) { delete webrtcSessions[webrtc.id]; } } }
431 - webrtc.ondatachannel = function (ev) {
432 - //console.log('ondatachannel');
433 - webchannel = ev.channel;
434 - webchannel.onmessage = function (event) { processMessage(event.data, 2); };
435 - webchannel.onopen = function () { webchannel.ok = true; updateControls(); sendws({ action: 'rtcSwitch', v: 0 }); };
436 - webchannel.onclose = function (event) { if (webchannel && webchannel.ok) { disconnect(); } else { hangUpButtonClick(0); } }
437 - }
438 - webrtc.onnegotiationneeded = function (event) {
439 - if (webrtc.holdTimer != null) return;
440 - webrtc.holdTimer = setTimeout(function () { // This time is needed to keep Chrome from being to excited. Wait until we add all tracks before kicking this off.
441 - //console.log('onnegotiationneeded', id);
442 - webrtc.holdTimer = null;
443 - webrtc.createOffer(function (offer) { /*console.log('offer', offer.sdp.length);*/ webrtc.setLocalDescription(offer, function () { sendws({ action: 'webRtcSdp', sdp: offer, id: id }); }, function () { hangUpButtonClick(id); }); }, function () { hangUpButtonClick(id); });
444 - }, 20);
445 - }
446 - webrtc.ontrack = function (event) {
447 - //console.log('ontrack', id);
448 - var video = Q('remoteVideoCanvas');
449 - video.srcObject = remoteStream = event.streams[0];
450 - video.onloadedmetadata = function (e) { video.play(); };
451 - displayRemoteVideo(true);
452 - }
453 - //webrtc.onremovetrack = function (event) { console.log('onremovetrack'); }
454 - //webrtc.onicegatheringstatechange = function (event) { console.log('onicegatheringstatechange', event); }
455 - //webrtc.onsignalingstatechange = function (event) { console.log('onsignalingstatechange', event); }
456 -
457 - // Initiate the WebRTC offer or handle the offer from the peer.
458 - if (startDataChannel == true) {
459 - webchannel = webrtc.createDataChannel("DataChannel", {}); // { ordered: false, maxRetransmits: 2 }
460 - webchannel.onmessage = function (event) { processMessage(event.data, 2); };
461 - webchannel.onopen = function () { webchannel.ok = true; updateControls(); sendws({ action: 'rtcSwitch', v: 0 }); };
462 - webchannel.onclose = function (event) { if (webchannel && webchannel.ok) { disconnect(); } else { hangUpButtonClick(0); } }
463 - }
464 -
465 - webrtcSessions[id] = webrtc;
466 - return webrtc;
467 - }
468 -
469 - function webRtcHandleOffer(id, description) {
470 - //console.log('webRtcHandleOffer', description.sdp.length);
471 - var webrtc = webrtcSessions[id];
472 - if (webrtc) {
473 - webrtc.setRemoteDescription(new RTCSessionDescription(description), function () {
474 - if (description.type == 'offer') {
475 - webrtc.createAnswer(function (answer) {
476 - webrtc.setLocalDescription(answer, function (a, b) {
477 - try { sendws({ action: 'webRtcSdp', sdp: answer, id: id }); } catch (ex) { }
478 - }, function () { hangUpButtonClick(id); });
479 - }, function () { hangUpButtonClick(id); });
480 - }
481 - }, function () { hangUpButtonClick(id); });
482 - }
483 - }
484 -
485 - // Indicate to peer that data traffic will no longer be sent over websocket and start holding traffic.
486 - function performWebRtcSwitch() {
487 - if (webchannel && webchannel.ok) { sendws({ action: 'rtcSwitch', v: 1 }); webchannel.xoutBuffer = []; }
488 - }
489 -
490 - // Disconnect everything
491 - function disconnect() {
492 - if (state > 0) { displayControl('Connection closed.'); }
493 - if (state > 1) { setTimeout(start, 500); }
494 - cancelAllFileTransfers();
495 - hangUpButtonClick(0, true); // Data channel
496 - hangUpButtonClick(1, true); // Local audio/video
497 - hangUpButtonClick(2, true); // Remote audio/video
498 - if (socket != null) { socket.close(); socket = null; }
499 - updateControls();
500 - state = 0;
501 - }
502 -
503 - // Send data over the current transport (WebRTC first)
504 - function send(data) {
505 - if (state != 2) return; // If not in connected state, ignore this.
506 - if (typeof data == 'object') { data = JSON.stringify(data); } // If this is an object, convert it to a string.
507 - if (webchannel && webchannel.ok) { if (webchannel.xoutBuffer != null) { webchannel.xoutBuffer.push(data); } else { webchannel.send(data); } } // If WebRTC channel is possible, use it or hold until we can use it.
508 - else { if (socket != null) { try { socket.send(data); } catch (ex) { } } } // If a websocket channel is present, use that.
509 - }
510 -
511 - // Send data over the websocket transport (WebSocket only)
512 - function sendws(data) {
513 - if (state != 2) return;
514 - //console.log('SEND', data);
515 - if (typeof data == 'object') { data = JSON.stringify(data); }
516 - if (socket != null) { socket.send(data); }
517 - }
518 -
519 - // WebRTC id switcher (0 -> 0, 1 -> 2, 2 -> 1)
520 - function webRtcIdSwitch(id) { if (id == 0) { return 0; } return 3 - id; }
521 -
522 - // Process incoming messages
523 - function processMessage(data, transport) {
524 - if (typeof data == 'string') {
525 - try { data = JSON.parse(data); } catch (ex) { console.log('Unable to parse', data); return; }
526 - //console.log('RECV', data);
527 - switch (data.action) {
528 - case 'chat': { displayRemote(data.msg); break; } // Incoming chat message.
529 - case 'random': { if (random > data.random) { startWebRTC(0, true); } break; } // If we have a larger random value, we start WebRTC.
530 - case 'webRtcSdp': { if (!webrtcSessions[webRtcIdSwitch(data.id)]) { startWebRTC(webRtcIdSwitch(data.id), false); } webRtcHandleOffer(webRtcIdSwitch(data.id), data.sdp); break; } // Remote WebRTC offer or answer.
531 - case 'webRtcIce': { var webrtc = webrtcSessions[webRtcIdSwitch(data.id)]; if (webrtc) { try { webrtc.addIceCandidate(new RTCIceCandidate(data.ice)); } catch (ex) { } } break; } // Remote ICE candidate
532 - case 'videoStop': { hangUpButtonClick(webRtcIdSwitch(data.id), true); break; }
533 - case 'rtcSwitch': { // WebRTC switch over commands.
534 - switch (data.v) {
535 - case 0: { performWebRtcSwitch(); break; } // Other side is ready for switch over to WebRTC
536 - case 1: { sendws({ action: 'rtcSwitch', v: 2 }); break; } // Other side no longer sending data on websocket, confirm we got the end marker
537 - case 2: { for (var i in webchannel.xoutBuffer) { webchannel.send(webchannel.xoutBuffer[i]); } delete webchannel.xoutBuffer; break; } // Send any pending data over WebRTC and start using WebRTC with all traffic
538 - default: { console.log('Unknown rtcSwitch value: ' + data.action); break; } //
539 - }
540 - break;
541 - }
542 - case 'file': { startFileDownload(data); break; }
543 - case 'fileUploadCancel': { cancelFileTransfer(data.id); break; }
544 - case 'fileUploadStart': {
545 - if (fileDownloads[data.id]) {
546 - currentFileDownload = fileDownloads[data.id];
547 - currentFileDownload.data = '';
548 - changeFileInfo(data.id, 2, 0);
549 - continueFileDownload(data);
550 - send({ action: 'fileUploadAck', id: data.id });
551 - } break;
552 - }
553 - case 'fileUploadEnd': {
554 - if (currentFileDownload && (currentFileDownload.id == data.id)) {
555 - changeFileInfo(data.id, 3, 200);
556 - currentFileDownload.done = 1;
557 - currentFileDownload = null;
558 - send({ action: 'fileUploadAck', id: data.id });
559 - }
560 - currentFileDownload = null;
561 - break;
562 - }
563 - case 'fileUploadAck': {
564 - continueFileUpload();
565 - break;
566 - }
567 - case 'fileData': {
568 - if (currentFileDownload && (currentFileDownload.id == data.id)) {
569 - currentFileDownload.data += data.data;
570 - changeFileInfo(data.id, 2, (currentFileDownload.data.length * 200 / currentFileDownload.size));
571 - send({ action: 'fileUploadAck', id: data.id });
572 - }
573 - break;
574 - }
575 - default: { console.log('Unhandled object data', data); break; }
576 - }
577 - } else {
578 - console.log('Unhandled data', typeof data, data);
579 - }
580 - }
581 -
582 - // File sharing button
583 - function fileButtonClick() {
584 - var chooser = Q('uploadFileInput');
585 - if (chooser.getAttribute("eventset") != 1) {
586 - chooser.setAttribute("eventset", "1");
587 - chooser.addEventListener("change", fileSelect, false);
588 - }
589 - chooser.value = null;
590 - chooser.click();
591 - }
592 -
593 - // User selected one or more files to upload to remote user.
594 - function fileSelect() {
595 - if (state != 2) return;
596 - var x = Q('uploadFileInput');
597 - if (x.files.length > 10) {
598 - displayControl('Limit of 10 file uploads at the same time.');
599 - } else {
600 - for (var i = 0; i < x.files.length; i++) {
601 - if (x.files[i].size > 0) {
602 - var reader = new FileReader();
603 - reader.onload = function (e) { this.xfile.data = e.target.result; startFileUpload(this.xfile); };
604 - reader.xfile = x.files[i];
605 - reader.readAsBinaryString(x.files[i]);
606 - }
607 - }
608 - }
609 - }
610 -
611 - // User drag & droped one or more files to upload to remote user.
612 - function fileDrop(e) {
613 - haltEvent(e);
614 - if ((state != 2) || (e.dataTransfer == null)) return;
615 - if (e.dataTransfer.files.length > 10) {
616 - displayControl('Limit of 10 file uploads at the same time.');
617 - } else {
618 - for (var i = 0; i < e.dataTransfer.files.length; i++) {
619 - if (e.dataTransfer.files[i].size > 0) {
620 - var reader = new FileReader();
621 - reader.onload = function (e) { this.xfile.data = e.target.result; startFileUpload(this.xfile); };
622 - reader.xfile = e.dataTransfer.files[i];
623 - reader.readAsBinaryString(e.dataTransfer.files[i]);
624 - }
625 - }
626 - }
627 - }
628 -
629 - function startFileUpload(file) {
630 - if (state != 2) return;
631 - file.id = Math.random();
632 - fileUploads.push(file);
633 - QA('xmsg', '<div style="clear:both"></div><div id="FILEUP-' + file.id + '" class="localBubble" style="width:240px;cursor:pointer" onclick="cancelFileTransfer(\'' + file.id + '\')"><div id="FILEUP-ICON-' + file.id + '" class="fileicon" style="float:left;width:32px;height:32px"></div><div><div id="FILEUP-NAME-' + file.id + '" style="height:16px;overflow:hidden;white-space:nowrap;" title="' + file.name + '">' + file.name + '</div><div style="width:200px;background-color:lightgray;margin-left:32px;border-radius:3px;margin-top:3px;height:11px"><div id="FILEUP-PROGRESS-' + file.id + '" style="width:0px;background-color:green;border-radius:3px;height:11px">&nbsp;</div></div></div></div>');
634 - Q('xmsg').scrollTop = Q('xmsg').scrollHeight;
635 - send({ action: 'file', size: file.size, id: file.id, type: file.type, name: file.name });
636 - if (currentFileUpload == null) continueFileUpload();
637 - }
638 -
639 - function startFileDownload(file) {
640 - if (state != 2) return;
641 - fileDownloads[file.id] = file;
642 - QA('xmsg', '<div style="clear:both"></div><div id="FILEUP-' + file.id + '" class="remoteBubble" style="width:240px;cursor:pointer" onclick="saveFileTransfer(\'' + file.id + '\')"><div id="FILEUP-ICON-' + file.id + '" class="fileicon" style="float:left;width:32px;height:32px"></div><div><div id="FILEUP-NAME-' + file.id + '" style="height:16px;overflow:hidden;white-space:nowrap;" title="' + file.name + '">' + file.name + '</div><div style="width:200px;background-color:lightgray;margin-left:32px;border-radius:3px;margin-top:3px;height:11px"><div id="FILEUP-PROGRESS-' + file.id + '" style="width:0px;background-color:green;border-radius:3px;height:11px">&nbsp;</div></div></div></div>');
643 - Q('xmsg').scrollTop = Q('xmsg').scrollHeight;
644 - }
645 -
646 - // Change the file icon and progress
647 - function changeFileInfo(id, icon, progress, progressColor) {
648 - if (icon) {
649 - Q('FILEUP-ICON-' + id).classList.remove('fileicon');
650 - Q('FILEUP-ICON-' + id).classList.remove('fileiconx');
651 - Q('FILEUP-ICON-' + id).classList.remove('fileicontransfer');
652 - Q('FILEUP-ICON-' + id).classList.remove('fileicondone');
653 - Q('FILEUP-ICON-' + id).classList.add(['fileicon', 'fileiconx', 'fileicontransfer', 'fileicondone'][icon]);
654 - }
655 - if (progress) { QS('FILEUP-PROGRESS-' + id)['width'] = progress + 'px'; }
656 - if (progressColor) { QS('FILEUP-PROGRESS-' + id)['background-color'] = progressColor; }
657 - }
658 -
659 - // Convert a string into a blob
660 - function data2blob(data) {
661 - var bytes = new Array(data.length);
662 - for (var i = 0; i < data.length; i++) bytes[i] = data.charCodeAt(i);
663 - return new Blob([new Uint8Array(bytes)]);
664 - };
665 -
666 - function saveFileTransfer(id) {
667 - var f = fileDownloads[id];
668 - if (f && f.done == 1) { saveAs(data2blob(f.data), f.name); }
669 - }
670 -
671 - function cancelFileTransfer(id) {
672 - if ((currentFileUpload != null) && (currentFileUpload.id == id)) { currentFileUpload = null; }
673 - if ((currentFileDownload != null) && (currentFileDownload.id == id)) { currentFileDownload = null; }
674 -
675 - var found = false;
676 - if (fileDownloads[id] && (fileDownloads[id].done != 1)) {
677 - delete fileDownloads[id];
678 - found = true;
679 - } else {
680 - for (var i in fileUploads) {
681 - if (fileUploads[i].id == id) {
682 - send({ action: 'fileUploadCancel', id: id });
683 - fileUploads.splice(i, 1);
684 - found = true;
685 - break;
686 - }
687 - }
688 - }
689 - if (found) { changeFileInfo(id, 1, 200, 'gray'); } // Only cancel a file if it was in the file queue.
690 - }
691 -
692 - function cancelAllFileTransfers() {
693 - for (var i in fileDownloads) { cancelFileTransfer(fileDownloads[i].id); }
694 - for (var i in fileUploads) { cancelFileTransfer(fileUploads[i].id); }
695 - }
696 -
697 - function continueFileUpload() {
698 - if (currentFileUpload == null) {
699 - // Select the next file to upload
700 - if (fileUploads.length == 0) { return; } // Nothing to do
701 - currentFileUpload = fileUploads[0];
702 - currentFileUpload.ptr = 0;
703 -
704 - // Indicate that we are sending this file
705 - send({ action: 'fileUploadStart', size: currentFileUpload.size, id: currentFileUpload.id, type: currentFileUpload.type, name: currentFileUpload.name });
706 - } else {
707 - if (currentFileUpload.size <= currentFileUpload.ptr) {
708 - // If we are done, send the end marker
709 - send({ action: 'fileUploadEnd', size: currentFileUpload.size, id: currentFileUpload.id, type: currentFileUpload.type, name: currentFileUpload.name });
710 - changeFileInfo(currentFileUpload.id, 3, 200);
711 - fileUploads.splice(0, 1);
712 - currentFileUpload = null;
713 - continueFileUpload(); // Send the next file
714 - } else {
715 - // Send the next block
716 - var nextBlockLen = Math.min(4000, currentFileUpload.data.length - currentFileUpload.ptr);
717 - var data = currentFileUpload.data.substring(currentFileUpload.ptr, currentFileUpload.ptr + nextBlockLen);
718 - send({ action: 'fileData', id: currentFileUpload.id, data: data });
719 - currentFileUpload.ptr += nextBlockLen;
720 - changeFileInfo(currentFileUpload.id, 0, (currentFileUpload.ptr * 200 / currentFileUpload.size));
721 - }
722 - }
723 - }
724 -
725 - function continueFileDownload(msg) {
726 - send({ action: 'fileUploadAck', id: msg.id });
727 - }
728 -
729 - // Camera button
730 - function camButtonClick() {
731 - if (localStream == null) { startLocalStream({ video: true, audio: true }); }
732 - }
733 -
734 - // Microphone
735 - function micButtonClick() {
736 - if (localStream == null) { startLocalStream({ video: false, audio: true }); }
737 - }
738 -
739 - function hangUpButtonClick(id, fromRemote) {
740 - //console.log('hangUpButtonClick', id);
741 - var localVideo = Q('localVideoCanvas');
742 - var remoteVideo = Q('remoteVideoCanvas');
743 - var webrtc = webrtcSessions[(multiWebRtc == true)? id : 0];
744 -
745 - if ((id == 0) && (webchannel != null)) { try { webchannel.close(); } catch (e) { } webchannel = null; }
746 -
747 - if (webrtc) {
748 - if ((multiWebRtc == true) || (id == 0)) {
749 - webrtc.ontrack = null;
750 - webrtc.onremovetrack = null;
751 - webrtc.onremovestream = null;
752 - webrtc.onnicecandidate = null;
753 - webrtc.oniceconnectionstatechange = null;
754 - webrtc.onsignalingstatechange = null;
755 - webrtc.onicegatheringstatechange = null;
756 - webrtc.onnotificationneeded = null;
757 - }
758 -
759 - if ((id == 1) && localStream) { var tracks = localStream.getTracks(); for (var i in tracks) { tracks[i].stop(); } localStream = null; }
760 - if ((id == 2) && remoteStream) { var tracks = remoteStream.getTracks(); for (var i in tracks) { tracks[i].stop(); } remoteStream = null; }
761 -
762 - if ((multiWebRtc == true) || (id == 0)) {
763 - webrtc.close();
764 - delete webrtcSessions[id];
765 - }
766 - }
767 -
768 - if (id == 1) {
769 - localVideo.removeAttribute("src");
770 - localVideo.removeAttribute("srcObject");
771 - if (localStream != null) { localStream = null; }
772 - displayLocalVideo(false);
773 - } else if (id == 2) {
774 - remoteVideo.removeAttribute("src");
775 - remoteVideo.removeAttribute("srcObject");
776 - displayRemoteVideo(false);
777 - }
778 -
779 - if (fromRemote != true) { send({ action: 'videoStop', id: id }); }
780 - updateControls();
781 - }
782 -
783 - // Setup local audio/video
784 - function startLocalStream(constraints) {
785 - var channel = (multiWebRtc == true) ? 1 : 0;
786 - if (localStream != null) return;
787 - if ((multiWebRtc == true) && (webrtcSessions[1] != null)) return;
788 - if (navigator.mediaDevices.getUserMedia) {
789 - localStream = 1;
790 - updateControls();
791 - navigator.mediaDevices.getUserMedia(constraints)
792 - .then(function (stream) {
793 - localStream = stream;
794 - var tracks = localStream.getTracks();
795 - var webrtc = startWebRTC(channel);
796 - if (constraints.video == true) {
797 - var video = Q('localVideoCanvas');
798 - video.srcObject = stream;
799 - video.onloadedmetadata = function (e) { video.play(); };
800 - displayLocalVideo(true);
801 - }
802 - for (var i in tracks) { webrtc.addTrack(tracks[i], localStream); }
803 - })
804 - .catch(function (err) {
805 - displayControl(err.message + '.');
806 - hangUpButtonClick(1);
807 - });
808 - }
809 - }
810 -
811 - // This is the main start
812 - function start() {
813 - // Get started
814 - updateControls();
815 - if ((typeof args.id == 'string') && (args.id.length > 0)) {
816 - var url = window.location.protocol.replace("http", "ws") + "//" + window.location.host + window.location.pathname.substring(0, window.location.pathname.lastIndexOf('/')) + '/meshrelay.ashx?id=' + args.id;
817 - if ((args.auth != null) && (args.auth != '')) { url += '&auth=' + args.auth; }
818 - socket = new WebSocket(url);
819 - socket.onopen = function () { state = 1; displayControl('Waiting for other user...'); }
820 - socket.onerror = function (e) { /*console.error(e);*/ }
821 - socket.onclose = function () { disconnect(); }
822 - socket.onmessage = function (msg) {
823 - if ((state < 2) && (typeof msg.data == 'string') && (msg.data == 'c')) {
824 - hangUpButtonClick(0, true);
825 - hangUpButtonClick(1, true);
826 - hangUpButtonClick(2, true);
827 - displayControl('Connected.');
828 - state = 2;
829 - updateControls();
830 - sendws({ action: 'random', random: random }); // Send a random number. Higher number starts the WebRTC session.
831 - return;
832 - }
833 - if (state == 2) { processMessage(msg.data, 1); }
834 - }
835 - } else {
836 - displayControl('Error: No connection key specified.');
837 - }
838 - }
839 -
840 - start();
841 -
842 - function onUnLoad() {
843 - for (var i = 0; i < 3; i++) { if (webrtcSessions[i]) { webrtcSessions[i].close(); delete webrtcSessions[i]; } }
844 - if (webchannel != null) { try { webchannel.close(); } catch (e) { } webchannel = null; }
845 - if (socket != null) { try { socket.close(); } catch (e) { } socket = null; }
846 - }
847 - </script></body></html>
\ No newline at end of file
1 +<!DOCTYPE html> <html style="height:100%"> <head> <title>MeshMessenger</title> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta content="text/html;charset=utf-8" http-equiv="Content-Type"> <meta name="format-detection" content="telephone=no"> <style>body{margin:0;padding:0;border:0;color:black;font-size:13px;font-family:"Trebuchet MS", Arial, Helvetica, sans-serif;background-color:#d3d9d6;}#container{background-color:#fff;width:960px;min-width:960px;margin:0 auto;border-top:0;border-right:1px solid #b7b7b7;border-bottom:0;border-left:1px solid #b7b7b7;padding:0;}#masthead{width:auto;margin:0;padding:0;overflow:auto;text-align:right;background-color:#036;width:960px;}#column_l{position:relative;float:left;width:930px;margin:0;padding:0 15px;background-color:#fff;}#footer{clear:both;overflow:auto;width:100%;text-align:center;background-color:#113962;padding-top:5px;padding-bottom:5px;}#masthead img{float:left;}#masthead p{font-size:11px;color:#fff;margin:10px 10px 0;}#footer a{color:#fff;text-decoration:underline;}#footer a:hover{color:#fff;text-decoration:none;}a{color:#036;text-decoration:underline;}.i1{background:url(../images/icons50.png) 0px 0px;height:50px;width:50px;cursor:pointer;border:none;}.i2{background:url(../images/icons50.png) -50px 0px;height:50px;width:50px;cursor:pointer;border:none;}.i3{background:url(../images/icons50.png) -100px 0px;height:50px;width:50px;cursor:pointer;border:none;}.i4{background:url(../images/icons50.png) -150px 0px;height:50px;width:50px;cursor:pointer;border:none;}.i5{background:url(../images/icons50.png) -200px 0px;height:50px;width:50px;cursor:pointer;border:none;}.i6{background:url(../images/icons50.png) -250px 0px;height:50px;width:50px;cursor:pointer;border:none;}.j1{background:url(../images/icons16.png) 0px 0px;height:16px;width:16px;cursor:pointer;border:none;}.j2{background:url(../images/icons16.png) -16px 0px;height:16px;width:16px;cursor:pointer;border:none;}.j3{background:url(../images/icons16.png) -32px 0px;height:16px;width:16px;cursor:pointer;border:none;}.j4{background:url(../images/icons16.png) -48px 0px;height:16px;width:16px;cursor:pointer;border:none;}.j5{background:url(../images/icons16.png) -64px 0px;height:16px;width:16px;cursor:pointer;border:none;}.j6{background:url(../images/icons16.png) -80px 0px;height:16px;width:16px;cursor:pointer;border:none;}.lbbutton{width:74px;height:74px;border-radius:5px;background-color:white;margin-left:8px;margin-top:8px;position:relative;cursor:pointer;opacity:0.5;}.lbbutton:hover{opacity:1;}.lbbuttonsel{opacity:0.9;}.lbbuttonsel2{width:82px;border-radius:5px 0px 0px 5px;opacity:1;}.lb1{background:url(../images/leftbar-62.jpg) -0px 0px;height:62px;width:62px;cursor:pointer;border:none;}.lb2{background:url(../images/leftbar-62.jpg) -75px 0px;height:62px;width:62px;cursor:pointer;border:none;}.lb3{background:url(../images/leftbar-62.jpg) -150px 0px;height:62px;width:62px;cursor:pointer;border:none;}.lb4{background:url(../images/leftbar-62.jpg) -225px 0px;height:62px;width:62px;cursor:pointer;border:none;}.lb5{background:url(../images/leftbar-62.jpg) -294px 0px;height:62px;width:62px;cursor:pointer;border:none;}.lb6{background:url(../images/leftbar-62.jpg) -360px 0px;height:62px;width:62px;cursor:pointer;border:none;}.m0{background :url(../images/images16.png) -32px 0px;height :16px;width :16px;border:none;float:left }.m1{background :url(../images/images16.png) -16px 0px;height :16px;width :16px;border:none;float:left }.m2{background :url(../images/images16.png) -96px 0px;height :16px;width :16px;border:none;float:left }.m3{background :url(../images/images16.png) -112px 0px;height :16px;width :16px;border:none;float:left }.si0{background :url(../images/icons16.png) 0px 0px;height :16px;width :16px;border:none;float:left }.si1{background :url(../images/icons16.png) -16px 0px;height :16px;width :16px;border:none;float:left }.si2{background :url(../images/icons16.png) -32px 0px;height :16px;width :16px;border:none;float:left }.si3{background :url(../images/icons16.png) -48px 0px;height :16px;width :16px;border:none;float:left }.si4{background :url(../images/icons16.png) -64px 0px;height :16px;width :16px;border:none;float:left }.mi{background :url(../images/meshicon50.png) 0px 0px;height:50px;width:50px;cursor:pointer;border:none }#floatframe{position:fixed;top:200px;height:300px;z-index:200;display:none;}.style1{text-align:center;}.style2{text-align:center;background-color:#808080;font-weight:bold;}.style3{text-align:center;color:white;background-color:#808080;font-weight:bold;}.style3x{text-align:center;color:white;background-color:#808080;font-weight:bold;}.style3x:hover{background-color:#606060;}.style3sel{text-align:center;color:white;background-color:#003366;font-weight:bold;}.style4{color:white;text-decoration:none;}.style5{text-align:center;background-color:#808080;font-weight:normal;}.style6{text-align:center;background-color:#D3D9D6;}.style7{font-size:large;background-color:#FFFFFF;}.style10{background-color:#C9C9C9;}.style11{font-size:large;background-color:#C9C9C9;}.style14{text-align:left;background-color:#D3D9D6;}.auto-style1{text-align:right;background-color:#D3D9D6;}.fileIcon1{background:url(data:image/gif;base64,R0lGODlhEAAQAJEDAPb49Y2Sj9LT2f///yH5BAEAAAMALAAAAAAQABAAAAImnI+py+1vhJwyUYAzHTL4D3qdlJWaIFJqmKod607sDKIiDUP63hQAOw==);height:16px;width:16px;cursor:pointer;border:none;float:left;margin-top:1px;}.fileIcon2{background:url(data:image/gif;base64,R0lGODlhEAAQAJEDAM2xV/Xur+XPgP///yH5BAEAAAMALAAAAAAQABAAAAJD3ISZIGHWUGihznesYDYATFVM+D2hJ4lgN1olxALAtAlmPCJvuMmJd6PJckDYwicrHhTD5o7plJmg0Uc0asNMkphHAQA7);height:16px;width:16px;cursor:pointer;border:none;float:left;margin-top:1px;}.fileIcon3{background:url(data:image/gif;base64,R0lGODlhEAAQAJEDAPb19IGBgbq6uv///yH5BAEAAAMALAAAAAAQABAAAAIy3ISpxgcPH2ouQgFEw1YmxnUXKEaaEZZnVWZk66JwzKpvuwZzwOgwb/C1gIOA8Yg8DgoAOw==);height:16px;width:16px;cursor:pointer;border:none;float:left;margin-top:1px;}.fileIcon4{background:url(../images/meshicon16.png);height:16px;width:16px;cursor:pointer;border:none;float:left;margin-top:1px;}.filelist{-moz-user-select:none;-khtml-user-select:none;-webkit-user-select:none;-o-user-select:none;cursor:default;-khtml-user-drag:element;background-color:white;clear:both;}.noselect{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}.fsize{float:right;text-align:right;width:180px;}.g1{background-position:0% 0%;width:14px;height:100%;float:left; background-image:linear-gradient(to right, #ffffff 0%, #c9c9c9 100%);background-color:#c9c9c9;background-repeat:repeat;background-attachment:scroll;}.g1s{background-image:linear-gradient(to right, #ffffff 0%, #b9b9b9 100%);}.g2{background-position:0% 0%;width:14px;height:100%;float:right; background-image:linear-gradient(to right, #c9c9c9 0%, #ffffff 100%);background-color:#c9c9c9;background-repeat:repeat;background-attachment:scroll;}.g2s{background-image:linear-gradient(to right, #b9b9b9 0%, #ffffff 100%);}.h1{background-position:0% 0%;width:14px;height:100%; background-image:linear-gradient(to right, #ffffff 0%, #d3d9d6 100%);background-color:#d3d9d6;background-repeat:repeat;background-attachment:scroll;}.h2{background-position:0% 0%;width:14px;height:100%; background-image:linear-gradient(to right, #d3d9d6 0%, #ffffff 100%);background-color:#d3d9d6;background-repeat:repeat;background-attachment:scroll;}.e1{font-size:large;margin-top:4px;margin-bottom:3px;overflow:hidden;word-wrap:hyphenate;white-space:nowrap;text-overflow:ellipsis;}.e2{float:left;height:100%;background-color:#c9c9c9;}.e2s{background-color:#b9b9b9;}.bar{font-size:large;background-color:#C9C9C9;height:24px;float:left;margin-bottom:2px;}.bar2{font-size:large;height:24px;float:left;margin-bottom:2px;}.bar18{font-size:large;background-color:#C9C9C9;height:18px;float:left;margin-bottom:2px;}.bar182{font-size:large;height:18px;float:left;margin-bottom:2px;}.devHeaderx{color:lightgray;}.DevSt{border-bottom-style:solid;border-bottom-width:1px;border-bottom-color:#DDDDDD;}.contextMenu{background:#F9F9F9;box-shadow:0 0 12px rgba( 0, 0, 0, .3 );border:1px solid #ccc; display:none;position:absolute;top:0;left:0;list-style:none;margin:0;padding:5px;min-width:100px;max-width:150px;z-index:500;}.cmtext{color:#444;display:inline-block;padding-left:8px;padding-right:8px;padding-top:5px;padding-bottom:5px;text-decoration:none;width:85%;cursor:default;overflow:hidden;position:relative;}.cmtext:hover{color:#f9f9f9;background:#444;}.gray{ filter:gray; -webkit-filter:grayscale(100%) opacity(60%); }.unselectable{-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;}.notifiyBox{position:absolute;z-index:1000;top:50px;right:26px;width:300px;text-align:left;background-color:#F0ECCD;border:4px solid #666;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;-webkit-box-shadow:2px 2px 4px #888;-moz-box-shadow:2px 2px 4px #888;box-shadow:2px 2px 4px #888;max-height:200px;}.notifiyBox:before{content:' ';position:absolute;width:0;height:0;right:5px;top:-30px;border:15px solid;border-color:transparent #666 #666 transparent;}.notifiyBox:after{content:' ';position:absolute;width:0;height:0;right:7px;top:-24px;border:12px solid;border-color:transparent #F0ECCD #F0ECCD transparent;}.notification{width:100%;min-height:30px;}.notification:hover{background-color:#EFE8B6;}.deskToolsBar{padding:3px;}.deskToolsBar:hover{background-color:#EFE8B6;}.userTableHeader{border-bottom:1pt solid lightgray;padding-top:4px;padding-bottom:4px;}.viewSelector{width:32px;height:32px;background-color:#DDD;border-radius:3px;float:left;margin-left:5px;cursor:pointer;opacity:0.3;}.viewSelectorSel{background-color:#BBB;opacity:0.8;}.viewSelector:hover{opacity:0.5;background-color:#AAA;}.viewSelector1{margin-left:2px;margin-top:2px;background:url(../images/views.png) -0px 0px;height:28px;width:28px;}.viewSelector2{margin-left:2px;margin-top:2px;background:url(../images/views.png) -28px 0px;height:28px;width:28px;}.viewSelector3{margin-left:2px;margin-top:2px;background:url(../images/views.png) -56px 0px;height:28px;width:28px;}.viewSelector4{margin-left:2px;margin-top:2px;background:url(../images/views.png) -84px 0px;height:28px;width:28px;}.viewSelector5{margin-left:2px;margin-top:2px;background:url(../images/views.png) -112px 0px;height:28px;width:28px;}.backButtonEx{margin-left:2px;margin-top:2px;background:url(../images/views.png) -140px 0px;height:28px;width:28px;}.backButton{width:32px;height:32px;background-color:#DDD;border-radius:3px;float:left;margin-right:5px;cursor:pointer;opacity:0.3;}.backButton:hover{opacity:0.5;background-color:#AAA;}.hoverButton{opacity:0.5;}.hoverButton:hover{opacity:1;}</style> <style>.topButton{cursor:pointer;border:none;margin:2px;margin-top:3px;float:right;border-radius:3px;height:32px;width:32px;}.topButton:hover{background-color:lightgray;}.topRedButton{cursor:pointer;border:none;margin:2px;float:right;border-radius:3px;height:32px;width:32px;}.topRedButton:hover{background-color:orangered;}.remoteBubble{background-color:#00cc99;color:black;border-radius:5px;padding:5px;float:left;margin-bottom:5px;margin-right:20px;box-shadow:3px 3px 10px gray;}.localBubble{background-color:#0099ff;color:black;border-radius:5px;padding:5px;float:right;margin-bottom:5px;margin-left:20px;box-shadow:3px 3px 10px gray;}.icon1{background:url(../images/messenger32.png) 0px 0px;background-color:gray;}.icon2{background:url(../images/messenger32.png) -32px 0px;background-color:gray;}.icon3{background:url(../images/messenger32.png) -64px 0px;background-color:gray;}.icon4{background:url(../images/messenger32.png) -96px 0px;background-color:gray;}.icon5{background:url(../images/messenger32.png) -128px 0px;background-color:gray;}.icon6{background:url(../images/messenger32.png) -160px 0px;background-color:gray;}.icon7{background:url(../images/messenger32.png) -192px 0px;background-color:gray;}.icon8{background:url(../images/messenger32.png) -224px 0px;background-color:gray;}.icon9{background:url(images/messenger32.png) -256px 0px;background-color:gray;}.icon10{background:url(../images/messenger32.png) -288px 0px;background-color:gray;}.icon11{background:url(../images/messenger32.png) -320px 0px;background-color:orange;}.fileicon{background:url(../images/messenger32.png) -96px 0px;height:32px;width:32px;}.fileiconx{background:url(../images/messenger32.png) -352px 0px;height:32px;width:32px;}.fileicontransfer{background:url(../images/messenger32.png) -288px 0px;height:32px;width:32px;}.fileicondone{background:url(../images/messenger32.png) -256px 0px;height:32px;width:32px;}</style> </head> <body style="font-family:Arial,Helvetica,sans-serif"> <div id="xtop" style="position:absolute;left:0;right:0;top:0;height:38px;background-color:#036;color:#c8c8c8;box-shadow:3px 3px 10px gray"> <div id="fileButton" class="icon4 topButton" title="Share a file" style="display:none" onclick="fileButtonClick()"></div> <div id="camButton" class="icon2 topButton" title="Activate camera & microphone" style="display:none" onclick="camButtonClick()"></div> <div id="micButton" class="icon6 topButton" title="Activate microphone" style="display:none" onclick="micButtonClick()"></div> <div id="hangupButton" class="icon11 topRedButton" title="Hang up" style="display:none" onclick="hangUpButtonClick(1)"></div> <div style="display:inline-block;width:2px"></div> <div style="padding-top:9px;padding-left:6px;font-size:20px;display:inline-block"><b>MeshMessenger<span id="xtitle"></span></b></div> </div> <div id="xmiddle" style="position:absolute;left:0;right:0;top:38px;bottom:30px"> <div style="position:absolute;left:0;right:0;top:0;bottom:0;overflow-y:scroll"> <div id="xmsg" style="position:absolute;left:0;right:0;bottom:0;padding:5px"></div> </div> </div> <div id="xbottom" style="position:absolute;left:0;right:0;bottom:0px;height:30px;background-color:#036"> <div style="position:absolute;left:5px;right:215px;bottom:4px;top:4px;background-color:aliceblue"><input id="xouttext" type="text" style="width:calc(100% - 5px)" onfocus="onUserInputFocus(1)" onblur="onUserInputFocus(0)"></div> <input type="button" id="sendButton" value="Send" style="position:absolute;right:110px;width:100px;top:4px;" onclick="xsend(event)"> <input type="button" id="clearButton" value="Clear" style="position:absolute;right:5px;width:100px;top:4px;" onclick="displayClear()"> </div> <div id="remoteVideo" style="position:absolute;right:24px;top:45px;width:320px;height:calc(240px + 30px);background-color:gray;border-radius:12px 12px 12px 12px;box-shadow:3px 3px 10px gray;display:none"> <div style="position:absolute;right:0;left:0;top:2.5px;text-align:center">Remote</div> <video id="remoteVideoCanvas" autoplay="" style="position:absolute;top:20px;left:0;width:100%;height:calc(100% - 30px);background-color:black"></video> </div> <div id="localVideo" style="position:absolute;right:24px;top:320px;width:160px;height:calc(120px + 30px);background-color:gray;border-radius:12px 12px 12px 12px;box-shadow:3px 3px 10px gray;display:none"> <div style="position:absolute;right:0;left:0;top:2.5px;text-align:center">Local</div> <video id="localVideoCanvas" autoplay="" muted="" style="position:absolute;top:20px;left:0;width:100%;height:calc(100% - 30px);background-color:black"></video> </div> <input id="uploadFileInput" type="file" multiple="" style="display:none"> <script>if(!String.prototype.startsWith){String.prototype.startsWith=function(a){return this.lastIndexOf(a,0)===0}}if(!String.prototype.endsWith){String.prototype.endsWith=function(a){return this.indexOf(a,this.length-a.length)!==-1}}function Q(a){return document.getElementById(a)}function QS(a){try{return Q(a).style}catch(a){}}function QE(a,b){try{Q(a).disabled=!b}catch(a){}}function QV(a,b){try{QS(a).display=(b?"":"none")}catch(a){}}function QA(a,b){Q(a).innerHTML+=b}function QH(a,b){Q(a).innerHTML=b}function inputBoxFocus(b){Q(b).focus();var a=Q(b).value;Q(b).value="";Q(b).value=a}function ReadShort(b,a){return(b.charCodeAt(a)<<8)+b.charCodeAt(a+1)}function ReadShortX(b,a){return(b.charCodeAt(a+1)<<8)+b.charCodeAt(a)}function ReadInt(b,a){return(b.charCodeAt(a)*16777216)+(b.charCodeAt(a+1)<<16)+(b.charCodeAt(a+2)<<8)+b.charCodeAt(a+3)}function ReadSInt(b,a){return(b.charCodeAt(a)<<24)+(b.charCodeAt(a+1)<<16)+(b.charCodeAt(a+2)<<8)+b.charCodeAt(a+3)}function ReadIntX(b,a){return(b.charCodeAt(a+3)*16777216)+(b.charCodeAt(a+2)<<16)+(b.charCodeAt(a+1)<<8)+b.charCodeAt(a)}function ShortToStr(a){return String.fromCharCode((a>>8)&255,a&255)}function ShortToStrX(a){return String.fromCharCode(a&255,(a>>8)&255)}function IntToStr(a){return String.fromCharCode((a>>24)&255,(a>>16)&255,(a>>8)&255,a&255)}function IntToStrX(a){return String.fromCharCode(a&255,(a>>8)&255,(a>>16)&255,(a>>24)&255)}function MakeToArray(a){if(!a||a==null||typeof a=="object"){return a}return[a]}function SplitArray(a){return a.split(",")}function Clone(a){return JSON.parse(JSON.stringify(a))}function EscapeHtml(a){if(typeof a=="string"){return a.replace(/&/g,"&amp;").replace(/>/g,"&gt;").replace(/</g,"&lt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}if(typeof a=="boolean"){return a}if(typeof a=="number"){return a}}function EscapeHtmlBreaks(a){if(typeof a=="string"){return a.replace(/&/g,"&amp;").replace(/>/g,"&gt;").replace(/</g,"&lt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;").replace(/\r/g,"<br />").replace(/\n/g,"").replace(/\t/g,"&nbsp;&nbsp;")}if(typeof a=="boolean"){return a}if(typeof a=="number"){return a}}function ArrayElementMove(a,b,c){a.splice(c,0,a.splice(b,1)[0])}function ObjectToStringEx(e,a){var d="";if(e!=0&&(!e||e==null)){return"(Null)"}if(e instanceof Array){for(var b in e){d+="<br />"+gap(a)+"Item #"+b+": "+ObjectToStringEx(e[b],a+1)}}else{if(e instanceof Object){for(var b in e){d+="<br />"+gap(a)+b+" = "+ObjectToStringEx(e[b],a+1)}}else{d+=EscapeHtml(e)}}return d}function ObjectToStringEx2(e,a){var d="";if(e!=0&&(!e||e==null)){return"(Null)"}if(e instanceof Array){for(var b in e){d+="\r\n"+gap2(a)+"Item #"+b+": "+ObjectToStringEx2(e[b],a+1)}}else{if(e instanceof Object){for(var b in e){d+="\r\n"+gap2(a)+b+" = "+ObjectToStringEx2(e[b],a+1)}}else{d+=EscapeHtml(e)}}return d}function gap(a){var d="";for(var b=0;b<(a*4);b++){d+="&nbsp;"}return d}function gap2(a){var d="";for(var b=0;b<(a*4);b++){d+=" "}return d}function ObjectToString(a){return ObjectToStringEx(a,0)}function ObjectToString2(a){return ObjectToStringEx2(a,0)}function hex2rstr(a){if(typeof a!="string"||a.length==0){return""}var c="",b=(""+a).match(/../g),e;while(e=b.shift()){c+=String.fromCharCode("0x"+e)}return c}function char2hex(a){return(a+256).toString(16).substr(-2).toUpperCase()}function rstr2hex(b){var c="",a;for(a=0;a<b.length;a++){c+=char2hex(b.charCodeAt(a))}return c}function encode_utf8(a){return unescape(encodeURIComponent(a))}function decode_utf8(a){return decodeURIComponent(escape(a))}function data2blob(c){var b=new Array(c.length);for(var d=0;d<c.length;d++){b[d]=c.charCodeAt(d)}var a=new Blob([new Uint8Array(b)]);return a}function random(a){return Math.floor(Math.random()*a)}function trademarks(a){return a.replace(/\(R\)/g,"&reg;").replace(/\(TM\)/g,"&trade;")}(function(b,a){if(typeof define==="function"&&define.amd){define([],a)}else{if(typeof exports!=="undefined"){a()}else{var c={exports:{}};a();b.FileSaver=c.exports}}})(this,function(){var a=typeof window==="object"&&window.window===window?window:typeof self==="object"&&self.self===self?self:typeof global==="object"&&global.global===global?global:void 0;function b(g,h){if(typeof h==="undefined"){h={autoBom:false}}else{if(typeof h!=="object"){console.warn("Depricated: Expected third argument to be a object");h={autoBom:!h}}}if(h.autoBom&&/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(g.type)){return new Blob([String.fromCharCode(65279),g],{type:g.type})}return g}function e(i,g,h){var j=new XMLHttpRequest();j.open("GET",i);j.responseType="blob";j.onload=function(){f(j.response,g,h)};j.onerror=function(){console.error("could not download file")};j.send()}function d(g){var h=new XMLHttpRequest();h.open("HEAD",g,false);h.send();return h.status>=200&&h.status<=299}function c(i){try{i.dispatchEvent(new MouseEvent("click"))}catch(g){var h=document.createEvent("MouseEvents");h.initMouseEvent("click",true,true,window,0,0,0,80,20,false,false,false,false,0,null);i.dispatchEvent(h)}}var f=a.saveAs||typeof window!=="object"||window!==a?function f(){}:"download" in HTMLAnchorElement.prototype?function f(h,i,j){var k=a.URL||a.webkitURL;var g=document.createElement("a");i=i||h.name||"download";g.download=i;g.rel="noopener";if(typeof h==="string"){g.href=h;if(g.origin!==location.origin){d(g.href)?e(h,i,j):c(g,g.target="_blank")}else{c(g)}}else{g.href=k.createObjectURL(h);setTimeout(function(){k.revokeObjectURL(g.href)},40000);setTimeout(function(){c(g)},0)}}:"msSaveOrOpenBlob" in navigator?function f(h,i,j){i=i||h.name||"download";if(typeof h==="string"){if(d(h)){e(h,i,j)}else{var g=document.createElement("a");g.href=h;g.target="_blank";setTimeout(function(){c(g)})}}else{navigator.msSaveOrOpenBlob(b(h,j),i)}}:function f(g,k,l,m){m=m||open("","_blank");if(m){m.document.title=m.document.body.innerText="downloading..."}if(typeof g==="string"){return e(g,k,l)}var h=g.type==="application/octet-stream";var j=/constructor/i.test(a.HTMLElement)||a.safari;var i=/CriOS\/[\d]+/.test(navigator.userAgent);if((i||h&&j)&&typeof FileReader==="object"){var n=new FileReader();n.onloadend=function(){var q=n.result;q=i?q:q.replace(/^data:[^;]*;/,"data:attachment/file;");if(m){m.location.href=q}else{location=q}m=null};n.readAsDataURL(g)}else{var p=a.URL||a.webkitURL;var o=p.createObjectURL(g);if(m){m.location=o}else{location.href=o}m=null;setTimeout(function(){p.revokeObjectURL(o)},40000)}};a.saveAs=f.saveAs=f;if(typeof module!=="undefined"){module.exports=f}});var userInputFocus=0;var args=parseUriArgs();var socket=null;var state=0;var random=Math.random();var webrtcSessions={};var webchannel=null;var localStream=null;var remoteStream=null;var multiWebRtc=true;var userMediaSupport=0;getUserMediaSupport(function(a){userMediaSupport=a});var webrtcconfiguration="{{{webrtconfig}}}";if(webrtcconfiguration==""){webrtcconfiguration=null}else{try{webrtcconfiguration=JSON.parse(decodeURIComponent(webrtcconfiguration))}catch(ex){console.log('Invalid WebRTC config: "'+webrtcconfiguration+'".');webrtcconfiguration=null}}var fileUploads=[];var fileDownloads={};var currentFileUpload=null;var currentFileDownload=null;if(args.title){QH("xtitle"," - "+args.title);document.title=document.title+" - "+args.title}document.addEventListener("dragover",haltEvent,false);document.addEventListener("dragleave",haltEvent,false);document.addEventListener("drop",fileDrop,false);document.onkeyup=function ondockeypress(a){if(state==2){if((a.keyCode==8)&&(userInputFocus==0)){var b=Q("xouttext").value;if(b.length>0){Q("xouttext").value=b.substring(0,b.length-1)}}}if(userInputFocus==0){haltEvent(a);return false}};document.onkeypress=function ondockeypress(a){if(state==2){if(a.keyCode==13){xsend(a)}else{if((userInputFocus==0)&&(a.key.length==1)){Q("xouttext").value=Q("xouttext").value+a.key}}}if(userInputFocus==0){haltEvent(a);return false}};function onUserInputFocus(a){userInputFocus=a}function displayClear(){QH("xmsg","");cancelAllFileTransfers();fileUploads=[],fileDownloads={}}if(!FileReader.prototype.readAsBinaryString){FileReader.prototype.readAsBinaryString=function(b){var a="",d=this,c=new FileReader();c.onload=function(g){var f=new Uint8Array(c.result);for(var h=0;h<f.byteLength;h++){a+=String.fromCharCode(f[h])}d.onload({target:{result:a}})};c.readAsArrayBuffer(b)}}function getUserMediaSupport(b){try{navigator.mediaDevices.enumerateDevices().then(function(d){try{var f=0,c=0;d.forEach(function(g){if(g.kind==="audioinput"){f=1}if(g.kind==="videoinput"){c=1}});if(f==0){b(0)}b(f+c)}catch(e){}})}catch(a){}}function displayControl(a){QA("xmsg",'<div style="clear:both"><div style="color:gray;float:left;margin-bottom:2px">'+a+"</div><div></div></div>");Q("xmsg").scrollTop=Q("xmsg").scrollHeight}function displayLocalVideo(a){QV("localVideo",a);adjustVideoWindows()}function displayRemoteVideo(a){QV("remoteVideo",a);adjustVideoWindows()}function adjustVideoWindows(){var a=(QS("remoteVideo")["display"]!="none");QS("localVideo")["top"]=a?"320px":"45px"}function displayRemote(a){QA("xmsg",'<div style="clear:both"><div class="remoteBubble">'+a+"</div><div></div></div>");Q("xmsg").scrollTop=Q("xmsg").scrollHeight}function xsend(a){var b=Q("xouttext").value;if(b.length>0){Q("xouttext").value="";QA("xmsg",'<div style="clear:both"><div class="localBubble">'+b+"</div><div></div></div>");Q("xmsg").scrollTop=Q("xmsg").scrollHeight;send({action:"chat",msg:b})}}function haltEvent(a){if(a.preventDefault){a.preventDefault()}if(a.stopPropagation){a.stopPropagation()}return false}function parseUriArgs(){var a,c={},b=window.document.location.href.split(/[\?&|\=]/);b.splice(0,1);for(d in b){switch(d%2){case 0:a=decodeURIComponent(b[d]);break;case 1:c[a]=decodeURIComponent(b[d]);var d=parseInt(c[a]);if(d==c[a]){c[a]=d}break;default:break}}return c}function updateControls(){QE("sendButton",state==2);QE("clearButton",state==2);QE("xouttext",state==2);QV("fileButton",state==2);QV("camButton",webchannel&&webchannel.ok&&!localStream&&(userMediaSupport==2));QV("micButton",webchannel&&webchannel.ok&&!localStream&&(userMediaSupport>0));QV("hangupButton",webchannel&&webchannel.ok&&localStream)}function startWebRTC(a,b){if((webrtcSessions[0]!=null)&&(multiWebRtc==false)){return webrtcSessions[0]}var c=null;if(typeof RTCPeerConnection!=="undefined"){c=new RTCPeerConnection(webrtcconfiguration)}else{if(typeof webkitRTCPeerConnection!=="undefined"){c=new webkitRTCPeerConnection(webrtcconfiguration)}}if(c==null){return null}c.id=a;c.onicecandidate=function(d){try{if(d.candidate!=null){sendws({action:"webRtcIce",ice:d.candidate,id:this.id})}}catch(f){}};c.oniceconnectionstatechange=function(){if(c&&c.iceConnectionState=="failed"){c.close();if(webrtcSessions[c.id]){delete webrtcSessions[c.id]}}};c.ondatachannel=function(d){webchannel=d.channel;webchannel.onmessage=function(e){processMessage(e.data,2)};webchannel.onopen=function(){webchannel.ok=true;updateControls();sendws({action:"rtcSwitch",v:0})};webchannel.onclose=function(e){if(webchannel&&webchannel.ok){disconnect()}else{hangUpButtonClick(0)}}};c.onnegotiationneeded=function(d){if(c.holdTimer!=null){return}c.holdTimer=setTimeout(function(){c.holdTimer=null;c.createOffer(function(e){c.setLocalDescription(e,function(){sendws({action:"webRtcSdp",sdp:e,id:a})},function(){hangUpButtonClick(a)})},function(){hangUpButtonClick(a)})},20)};c.ontrack=function(d){var e=Q("remoteVideoCanvas");e.srcObject=remoteStream=d.streams[0];e.onloadedmetadata=function(f){e.play()};displayRemoteVideo(true)};if(b==true){webchannel=c.createDataChannel("DataChannel",{});webchannel.onmessage=function(d){processMessage(d.data,2)};webchannel.onopen=function(){webchannel.ok=true;updateControls();sendws({action:"rtcSwitch",v:0})};webchannel.onclose=function(d){if(webchannel&&webchannel.ok){disconnect()}else{hangUpButtonClick(0)}}}webrtcSessions[a]=c;return c}function webRtcHandleOffer(b,a){var c=webrtcSessions[b];if(c){c.setRemoteDescription(new RTCSessionDescription(a),function(){if(a.type=="offer"){c.createAnswer(function(d){c.setLocalDescription(d,function(e,f){try{sendws({action:"webRtcSdp",sdp:d,id:b})}catch(g){}},function(){hangUpButtonClick(b)})},function(){hangUpButtonClick(b)})}},function(){hangUpButtonClick(b)})}}function performWebRtcSwitch(){if(webchannel&&webchannel.ok){sendws({action:"rtcSwitch",v:1});webchannel.xoutBuffer=[]}}function disconnect(){if(state>0){displayControl("Connection closed.")}if(state>1){setTimeout(start,500)}cancelAllFileTransfers();hangUpButtonClick(0,true);hangUpButtonClick(1,true);hangUpButtonClick(2,true);if(socket!=null){socket.close();socket=null}updateControls();state=0}function send(a){if(state!=2){return}if(typeof a=="object"){a=JSON.stringify(a)}if(webchannel&&webchannel.ok){if(webchannel.xoutBuffer!=null){webchannel.xoutBuffer.push(a)}else{webchannel.send(a)}}else{if(socket!=null){try{socket.send(a)}catch(b){}}}}function sendws(a){if(state!=2){return}if(typeof a=="object"){a=JSON.stringify(a)}if(socket!=null){socket.send(a)}}function webRtcIdSwitch(a){if(a==0){return 0}return 3-a}function processMessage(a,d){if(typeof a=="string"){try{a=JSON.parse(a)}catch(b){console.log("Unable to parse",a);return}switch(a.action){case"chat":displayRemote(a.msg);break;case"random":if(random>a.random){startWebRTC(0,true)}break;case"webRtcSdp":if(!webrtcSessions[webRtcIdSwitch(a.id)]){startWebRTC(webRtcIdSwitch(a.id),false)}webRtcHandleOffer(webRtcIdSwitch(a.id),a.sdp);break;case"webRtcIce":var e=webrtcSessions[webRtcIdSwitch(a.id)];if(e){try{e.addIceCandidate(new RTCIceCandidate(a.ice))}catch(b){}}break;case"videoStop":hangUpButtonClick(webRtcIdSwitch(a.id),true);break;case"rtcSwitch":switch(a.v){case 0:performWebRtcSwitch();break;case 1:sendws({action:"rtcSwitch",v:2});break;case 2:for(var c in webchannel.xoutBuffer){webchannel.send(webchannel.xoutBuffer[c])}delete webchannel.xoutBuffer;break;default:console.log("Unknown rtcSwitch value: "+a.action);break}break;case"file":startFileDownload(a);break;case"fileUploadCancel":cancelFileTransfer(a.id);break;case"fileUploadStart":if(fileDownloads[a.id]){currentFileDownload=fileDownloads[a.id];currentFileDownload.data="";changeFileInfo(a.id,2,0);continueFileDownload(a);send({action:"fileUploadAck",id:a.id})}break;case"fileUploadEnd":if(currentFileDownload&&(currentFileDownload.id==a.id)){changeFileInfo(a.id,3,200);currentFileDownload.done=1;currentFileDownload=null;send({action:"fileUploadAck",id:a.id})}currentFileDownload=null;break;case"fileUploadAck":continueFileUpload();break;case"fileData":if(currentFileDownload&&(currentFileDownload.id==a.id)){currentFileDownload.data+=a.data;changeFileInfo(a.id,2,(currentFileDownload.data.length*200/currentFileDownload.size));send({action:"fileUploadAck",id:a.id})}break;default:console.log("Unhandled object data",a);break}}else{console.log("Unhandled data",typeof a,a)}}function fileButtonClick(){var a=Q("uploadFileInput");if(a.getAttribute("eventset")!=1){a.setAttribute("eventset","1");a.addEventListener("change",fileSelect,false)}a.value=null;a.click()}function fileSelect(){if(state!=2){return}var c=Q("uploadFileInput");if(c.files.length>10){displayControl("Limit of 10 file uploads at the same time.")}else{for(var a=0;a<c.files.length;a++){if(c.files[a].size>0){var b=new FileReader();b.onload=function(d){this.xfile.data=d.target.result;startFileUpload(this.xfile)};b.xfile=c.files[a];b.readAsBinaryString(c.files[a])}}}}function fileDrop(a){haltEvent(a);if((state!=2)||(a.dataTransfer==null)){return}if(a.dataTransfer.files.length>10){displayControl("Limit of 10 file uploads at the same time.")}else{for(var b=0;b<a.dataTransfer.files.length;b++){if(a.dataTransfer.files[b].size>0){var c=new FileReader();c.onload=function(d){this.xfile.data=d.target.result;startFileUpload(this.xfile)};c.xfile=a.dataTransfer.files[b];c.readAsBinaryString(a.dataTransfer.files[b])}}}}function startFileUpload(a){if(state!=2){return}a.id=Math.random();fileUploads.push(a);QA("xmsg",'<div style="clear:both"></div><div id="FILEUP-'+a.id+'" class="localBubble" style="width:240px;cursor:pointer" onclick="cancelFileTransfer(\''+a.id+'\')"><div id="FILEUP-ICON-'+a.id+'" class="fileicon" style="float:left;width:32px;height:32px"></div><div><div id="FILEUP-NAME-'+a.id+'" style="height:16px;overflow:hidden;white-space:nowrap;" title="'+a.name+'">'+a.name+'</div><div style="width:200px;background-color:lightgray;margin-left:32px;border-radius:3px;margin-top:3px;height:11px"><div id="FILEUP-PROGRESS-'+a.id+'" style="width:0px;background-color:green;border-radius:3px;height:11px">&nbsp;</div></div></div></div>');Q("xmsg").scrollTop=Q("xmsg").scrollHeight;send({action:"file",size:a.size,id:a.id,type:a.type,name:a.name});if(currentFileUpload==null){continueFileUpload()}}function startFileDownload(a){if(state!=2){return}fileDownloads[a.id]=a;QA("xmsg",'<div style="clear:both"></div><div id="FILEUP-'+a.id+'" class="remoteBubble" style="width:240px;cursor:pointer" onclick="saveFileTransfer(\''+a.id+'\')"><div id="FILEUP-ICON-'+a.id+'" class="fileicon" style="float:left;width:32px;height:32px"></div><div><div id="FILEUP-NAME-'+a.id+'" style="height:16px;overflow:hidden;white-space:nowrap;" title="'+a.name+'">'+a.name+'</div><div style="width:200px;background-color:lightgray;margin-left:32px;border-radius:3px;margin-top:3px;height:11px"><div id="FILEUP-PROGRESS-'+a.id+'" style="width:0px;background-color:green;border-radius:3px;height:11px">&nbsp;</div></div></div></div>');Q("xmsg").scrollTop=Q("xmsg").scrollHeight}function changeFileInfo(b,a,c,d){if(a){Q("FILEUP-ICON-"+b).classList.remove("fileicon");Q("FILEUP-ICON-"+b).classList.remove("fileiconx");Q("FILEUP-ICON-"+b).classList.remove("fileicontransfer");Q("FILEUP-ICON-"+b).classList.remove("fileicondone");Q("FILEUP-ICON-"+b).classList.add(["fileicon","fileiconx","fileicontransfer","fileicondone"][a])}if(c){QS("FILEUP-PROGRESS-"+b)["width"]=c+"px"}if(d){QS("FILEUP-PROGRESS-"+b)["background-color"]=d}}function data2blob(b){var a=new Array(b.length);for(var c=0;c<b.length;c++){a[c]=b.charCodeAt(c)}return new Blob([new Uint8Array(a)])}function saveFileTransfer(b){var a=fileDownloads[b];if(a&&a.done==1){saveAs(data2blob(a.data),a.name)}}function cancelFileTransfer(c){if((currentFileUpload!=null)&&(currentFileUpload.id==c)){currentFileUpload=null}if((currentFileDownload!=null)&&(currentFileDownload.id==c)){currentFileDownload=null}var a=false;if(fileDownloads[c]&&(fileDownloads[c].done!=1)){delete fileDownloads[c];a=true}else{for(var b in fileUploads){if(fileUploads[b].id==c){send({action:"fileUploadCancel",id:c});fileUploads.splice(b,1);a=true;break}}}if(a){changeFileInfo(c,1,200,"gray")}}function cancelAllFileTransfers(){for(var a in fileDownloads){cancelFileTransfer(fileDownloads[a].id)}for(var a in fileUploads){cancelFileTransfer(fileUploads[a].id)}}function continueFileUpload(){if(currentFileUpload==null){if(fileUploads.length==0){return}currentFileUpload=fileUploads[0];currentFileUpload.ptr=0;send({action:"fileUploadStart",size:currentFileUpload.size,id:currentFileUpload.id,type:currentFileUpload.type,name:currentFileUpload.name})}else{if(currentFileUpload.size<=currentFileUpload.ptr){send({action:"fileUploadEnd",size:currentFileUpload.size,id:currentFileUpload.id,type:currentFileUpload.type,name:currentFileUpload.name});changeFileInfo(currentFileUpload.id,3,200);fileUploads.splice(0,1);currentFileUpload=null;continueFileUpload()}else{var b=Math.min(4000,currentFileUpload.data.length-currentFileUpload.ptr);var a=currentFileUpload.data.substring(currentFileUpload.ptr,currentFileUpload.ptr+b);send({action:"fileData",id:currentFileUpload.id,data:a});currentFileUpload.ptr+=b;changeFileInfo(currentFileUpload.id,0,(currentFileUpload.ptr*200/currentFileUpload.size))}}}function continueFileDownload(a){send({action:"fileUploadAck",id:a.id})}function camButtonClick(){if(localStream==null){startLocalStream({video:true,audio:true})}}function micButtonClick(){if(localStream==null){startLocalStream({video:false,audio:true})}}function hangUpButtonClick(d,b){var f=Q("localVideoCanvas");var g=Q("remoteVideoCanvas");var j=webrtcSessions[(multiWebRtc==true)?d:0];if((d==0)&&(webchannel!=null)){try{webchannel.close()}catch(a){}webchannel=null}if(j){if((multiWebRtc==true)||(d==0)){j.ontrack=null;j.onremovetrack=null;j.onremovestream=null;j.onnicecandidate=null;j.oniceconnectionstatechange=null;j.onsignalingstatechange=null;j.onicegatheringstatechange=null;j.onnotificationneeded=null}if((d==1)&&localStream){var h=localStream.getTracks();for(var c in h){h[c].stop()}localStream=null}if((d==2)&&remoteStream){var h=remoteStream.getTracks();for(var c in h){h[c].stop()}remoteStream=null}if((multiWebRtc==true)||(d==0)){j.close();delete webrtcSessions[d]}}if(d==1){f.removeAttribute("src");f.removeAttribute("srcObject");if(localStream!=null){localStream=null}displayLocalVideo(false)}else{if(d==2){g.removeAttribute("src");g.removeAttribute("srcObject");displayRemoteVideo(false)}}if(b!=true){send({action:"videoStop",id:d})}updateControls()}function startLocalStream(b){var a=(multiWebRtc==true)?1:0;if(localStream!=null){return}if((multiWebRtc==true)&&(webrtcSessions[1]!=null)){return}if(navigator.mediaDevices.getUserMedia){localStream=1;updateControls();navigator.mediaDevices.getUserMedia(b).then(function(d){localStream=d;var e=localStream.getTracks();var g=startWebRTC(a);if(b.video==true){var f=Q("localVideoCanvas");f.srcObject=d;f.onloadedmetadata=function(h){f.play()};displayLocalVideo(true)}for(var c in e){g.addTrack(e[c],localStream)}},function(c){displayControl(c.message+".");hangUpButtonClick(1)})}}function start(){updateControls();if((typeof args.id=="string")&&(args.id.length>0)){var a=window.location.protocol.replace("http","ws")+"//"+window.location.host+window.location.pathname.substring(0,window.location.pathname.lastIndexOf("/"))+"/meshrelay.ashx?id="+args.id;if((args.auth!=null)&&(args.auth!="")){a+="&auth="+args.auth}socket=new WebSocket(a);socket.onopen=function(){state=1;displayControl("Waiting for other user...")};socket.onerror=function(b){};socket.onclose=function(){disconnect()};socket.onmessage=function(b){if((state<2)&&(typeof b.data=="string")&&(b.data=="c")){hangUpButtonClick(0,true);hangUpButtonClick(1,true);hangUpButtonClick(2,true);displayControl("Connected.");state=2;updateControls();sendws({action:"random",random:random});return}if(state==2){processMessage(b.data,1)}}}else{displayControl("Error: No connection key specified.")}}start();function onUnLoad(){for(var b=0;b<3;b++){if(webrtcSessions[b]){webrtcSessions[b].close();delete webrtcSessions[b]}}if(webchannel!=null){try{webchannel.close()}catch(a){}webchannel=null}if(socket!=null){try{socket.close()}catch(a){}socket=null}};</script></body></html>
\ No newline at end of file
views/messenger.handlebars
+1 -2
@@ -560,8 +560,7 @@
560 displayLocalVideo(true);
561 }
562 for (var i in tracks) { webrtc.addTrack(tracks[i], localStream); }
563 - })
564 - .catch(function (err) {
563 + }, function (err) {
564 displayControl(err.message + '.');
565 hangUpButtonClick(1);
566 });