Commit b48705c19ff030c941e3593c504df782a76dcc04
1 parent
0f43a038
Exists in
master
Integrating the qdclient
Showing
37 changed files
with
2007 additions
and
32 deletions
Show diff stats
chrome/app/main.js
| 1 | -var glosa = undefined; | ||
| 2 | -var loaded = false; | 1 | +var app = { |
| 2 | + chooser: null, | ||
| 3 | + glosa: undefined, | ||
| 4 | + loaded: false, | ||
| 5 | + lastReq: { | ||
| 6 | + url: null, | ||
| 7 | + millis: null, | ||
| 8 | + response: null | ||
| 9 | + } | ||
| 10 | +}; | ||
| 3 | 11 | ||
| 4 | function onLoadPlayer() { | 12 | function onLoadPlayer() { |
| 5 | - console.log('onLoadPlayer glosa:' + glosa); | ||
| 6 | - if ( glosa !== undefined ) { | ||
| 7 | - SendMessage('Avatar', 'catchGlosa', glosa); | 13 | + if ( app.glosa !== undefined ) { |
| 14 | + SendMessage('Avatar', 'catchGlosa', app.glosa); | ||
| 8 | } | 15 | } |
| 9 | 16 | ||
| 10 | - loaded = true; | 17 | + app.loaded = true; |
| 11 | } | 18 | } |
| 12 | 19 | ||
| 13 | chrome.runtime.onMessage.addListener( | 20 | chrome.runtime.onMessage.addListener( |
| 14 | function(request, sender, sendResponse) { | 21 | function(request, sender, sendResponse) { |
| 15 | - req = new XMLHttpRequest(); | ||
| 16 | - req.open('GET', 'http://150.165.204.30:9000/glosa?texto=' + request.selectedText, true); | 22 | + app.chooser = app.chooser || new qdClient.Chooser(); |
| 17 | 23 | ||
| 18 | document.getElementById('loading-screen').style.display = 'block'; | 24 | document.getElementById('loading-screen').style.display = 'block'; |
| 19 | - req.onreadystatechange = function () { | ||
| 20 | - if (req.readyState == 4) { | ||
| 21 | - console.log('Translate callback: loaded: ' + loaded); | ||
| 22 | - glosa = req.responseText; | ||
| 23 | - | ||
| 24 | - document.getElementById('loading-screen').style.display = 'none'; | ||
| 25 | - if (loaded == true) { | ||
| 26 | - SendMessage('Avatar', 'catchGlosa', glosa); | ||
| 27 | - } | ||
| 28 | - } | ||
| 29 | - }; | ||
| 30 | - | ||
| 31 | - req.send(); | 25 | + app.chooser.choose( |
| 26 | + app.lastReq.url, | ||
| 27 | + app.lastReq.millis, | ||
| 28 | + app.lastReq.response, | ||
| 29 | + function (url) { | ||
| 30 | + var start = new Date().getTime(); | ||
| 31 | + | ||
| 32 | + qdClient.request(url + '?texto=' + request.selectedText, "GET", {}, | ||
| 33 | + function(status, response) { | ||
| 34 | + app.lastReq.response = status === 404 ? -1 : status; | ||
| 35 | + app.lastReq.millis = (new Date().getTime() - start); | ||
| 36 | + app.lastReq.url = url; | ||
| 37 | + | ||
| 38 | + app.glosa = response; | ||
| 39 | + | ||
| 40 | + document.getElementById('loading-screen').style.display = 'none'; | ||
| 41 | + if (app.loaded == true) { | ||
| 42 | + SendMessage('Avatar', 'catchGlosa', app.glosa); | ||
| 43 | + } | ||
| 44 | + }); | ||
| 45 | + }); | ||
| 32 | }); | 46 | }); |
| 33 | 47 | ||
| 34 | chrome.runtime.sendMessage({ready: true}); | 48 | chrome.runtime.sendMessage({ready: true}); |
| @@ -0,0 +1,27 @@ | @@ -0,0 +1,27 @@ | ||
| 1 | +{ | ||
| 2 | + "name": "qdclient", | ||
| 3 | + "main": [ | ||
| 4 | + "qdclient.js" | ||
| 5 | + ], | ||
| 6 | + "ignore": [ | ||
| 7 | + "**/.*", | ||
| 8 | + "Gulpfile.js", | ||
| 9 | + "demo", | ||
| 10 | + "node_modules", | ||
| 11 | + "vendor", | ||
| 12 | + "tests" | ||
| 13 | + ], | ||
| 14 | + "devDependencies": { | ||
| 15 | + "mocha": "~2.2.5", | ||
| 16 | + "chai": "~3.0.0" | ||
| 17 | + }, | ||
| 18 | + "_release": "fab153cf1a", | ||
| 19 | + "_resolution": { | ||
| 20 | + "type": "branch", | ||
| 21 | + "branch": "master", | ||
| 22 | + "commit": "fab153cf1a708cab90a72e4654d65d654f11370e" | ||
| 23 | + }, | ||
| 24 | + "_source": "git@git.lavid.ufpb.br:qdclient.git", | ||
| 25 | + "_target": "*", | ||
| 26 | + "_originalSource": "git@git.lavid.ufpb.br:qdclient.git" | ||
| 27 | +} | ||
| 0 | \ No newline at end of file | 28 | \ No newline at end of file |
| @@ -0,0 +1,32 @@ | @@ -0,0 +1,32 @@ | ||
| 1 | +qdClient | ||
| 2 | +========= | ||
| 3 | + | ||
| 4 | +1. Tools | ||
| 5 | +---------------- | ||
| 6 | + | ||
| 7 | +1. NodeJS | ||
| 8 | +2. NPM - Node Package Manager | ||
| 9 | +3. Bower - Frontend dependencies | ||
| 10 | +4. Gulp - Build tools | ||
| 11 | + | ||
| 12 | +2. Installing dependencies | ||
| 13 | +---------------- | ||
| 14 | + | ||
| 15 | +```bash | ||
| 16 | +$ npm install | ||
| 17 | +$ bower install | ||
| 18 | +``` | ||
| 19 | + | ||
| 20 | +3. Demo | ||
| 21 | +---------------- | ||
| 22 | +```bash | ||
| 23 | +$ gulp demo | ||
| 24 | +``` | ||
| 25 | + | ||
| 26 | +4. Building | ||
| 27 | +---------------- | ||
| 28 | +```bash | ||
| 29 | +$ gulp build | ||
| 30 | +``` | ||
| 31 | + | ||
| 32 | +**Enjoy** |
| @@ -0,0 +1,19 @@ | @@ -0,0 +1,19 @@ | ||
| 1 | +{ | ||
| 2 | + "name": "qdclient", | ||
| 3 | + "version": "0.0.1", | ||
| 4 | + "main": [ | ||
| 5 | + "qdclient.js" | ||
| 6 | + ], | ||
| 7 | + "ignore": [ | ||
| 8 | + "**/.*", | ||
| 9 | + "Gulpfile.js", | ||
| 10 | + "demo", | ||
| 11 | + "node_modules", | ||
| 12 | + "vendor", | ||
| 13 | + "tests" | ||
| 14 | + ], | ||
| 15 | + "devDependencies": { | ||
| 16 | + "mocha": "~2.2.5", | ||
| 17 | + "chai": "~3.0.0" | ||
| 18 | + } | ||
| 19 | +} |
| @@ -0,0 +1,224 @@ | @@ -0,0 +1,224 @@ | ||
| 1 | +(function(window, localStorage, undefined) { | ||
| 2 | + 'use strict'; | ||
| 3 | + | ||
| 4 | + function Chooser() { | ||
| 5 | + this.server = 'http://150.165.204.39/vlibras-cloud/get_servers.php'; | ||
| 6 | + | ||
| 7 | + this.options = { | ||
| 8 | + THRESHOLDSLOW: 2000, | ||
| 9 | + SLOWLIMITTRIES: 5, | ||
| 10 | + NBESTHEURISTIC1: 2, | ||
| 11 | + QUANTITYPREVIOUSTIMESSTORED: 10 | ||
| 12 | + }; | ||
| 13 | + | ||
| 14 | + this.mirrors = []; | ||
| 15 | + | ||
| 16 | + this.heuristics = { | ||
| 17 | + FIRSTHEURISTIC: { | ||
| 18 | + FIRSTRANDOM : {value: 0, name: "Random"}, | ||
| 19 | + FIRSTRANDOMNBEST: {value: 1, name: "Random Among N Best"}, | ||
| 20 | + FIRSTBEST : {value: 2, name: "Best"} | ||
| 21 | + }, | ||
| 22 | + SECONDHEURISTIC: { | ||
| 23 | + SECONDRANDOM : {value: 0, name: "Random"}, | ||
| 24 | + SECONDCLOSEST: {value: 1, name: "Closest"} | ||
| 25 | + }, | ||
| 26 | + THIRDHEURISTIC: { | ||
| 27 | + THIRDSIMPLEAVERAGE : {value: 0, name: "Simple Average"}, | ||
| 28 | + THIRDWEIGHTEDAVERAGE: {value: 1, name: "Weighted Average"} | ||
| 29 | + } | ||
| 30 | + }; | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + // Exports | ||
| 34 | + qdClient.Chooser = Chooser; | ||
| 35 | + | ||
| 36 | + Chooser.prototype.choose = function(urlLast, millisLast, response, callback) { | ||
| 37 | + var $this = this; | ||
| 38 | + | ||
| 39 | + if (this.mirrors.length === 0) { | ||
| 40 | + this.loadMirrors_(function() { | ||
| 41 | + $this.chooseServer_(urlLast, millisLast, response, callback); | ||
| 42 | + }); | ||
| 43 | + } else { | ||
| 44 | + this.chooseServer_(urlLast, millisLast, response, callback); | ||
| 45 | + } | ||
| 46 | + }; | ||
| 47 | + | ||
| 48 | + Chooser.prototype.chooseServer_ = function(urlLast, millisLast, response, callback) { | ||
| 49 | + var firstHeuristic = this.heuristics.FIRSTHEURISTIC.FIRSTBEST; | ||
| 50 | + var secondHeuristic = this.heuristics.SECONDHEURISTIC.SECONDRANDOM; | ||
| 51 | + var thirdHeuristic = this.heuristics.THIRDHEURISTIC.THIRDWEIGHTEDAVERAGE; | ||
| 52 | + | ||
| 53 | + var j = 0, i = 0; /* Fix JSHint */ | ||
| 54 | + | ||
| 55 | + var sizeBest = this.options.NBESTHEURISTIC1; | ||
| 56 | + if (firstHeuristic == this.heuristics.FIRSTHEURISTIC.FIRSTBEST) { | ||
| 57 | + sizeBest = 1; | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + if (urlLast && urlLast.length > 0) { | ||
| 61 | + for (i = 0; i < this.mirrors.length; i++) { | ||
| 62 | + if (this.mirrors[i].url.toLowerCase() == urlLast.toLowerCase()) { | ||
| 63 | + if (this.mirrors[i].previousTimes.length < this.options.QUANTITYPREVIOUSTIMESSTORED) { | ||
| 64 | + this.mirrors[i].previousTimes[this.mirrors[i].previousTimes.length] = millisLast; | ||
| 65 | + | ||
| 66 | + } else { | ||
| 67 | + for (j = this.options.QUANTITYPREVIOUSTIMESSTORED-1; j > 0; j--) { | ||
| 68 | + this.mirrors[i].previousTimes[j-1] = this.mirrors[i].previousTimes[j]; | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + this.mirrors[i].previousTimes[this.options.QUANTITYPREVIOUSTIMESSTORED-1] = millisLast; | ||
| 72 | + | ||
| 73 | + } | ||
| 74 | + | ||
| 75 | + if (thirdHeuristic == this.heuristics.THIRDHEURISTIC.THIRDSIMPLEAVERAGE) { | ||
| 76 | + var totalMillis = 0; | ||
| 77 | + for (j = 0; j < this.mirrors[i].previousTimes.length; j++) { | ||
| 78 | + totalMillis += this.mirrors[i].previousTimes[j]; | ||
| 79 | + } | ||
| 80 | + | ||
| 81 | + this.mirrors[i].averageTime = totalMillis/this.mirrors[i].previousTimes.length; | ||
| 82 | + | ||
| 83 | + } else if (thirdHeuristic == this.heuristics.THIRDHEURISTIC.THIRDWEIGHTEDAVERAGE) { | ||
| 84 | + var totalMillisAndWeights = 0; | ||
| 85 | + var totalWeights = 0; | ||
| 86 | + for (j = 0; j < this.mirrors[i].previousTimes.length; j++) { | ||
| 87 | + totalMillisAndWeights += this.mirrors[i].previousTimes[j]*(j+1); | ||
| 88 | + totalWeights += (j+1); | ||
| 89 | + } | ||
| 90 | + | ||
| 91 | + this.mirrors[i].averageTime = totalMillisAndWeights/totalWeights; | ||
| 92 | + | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + if (millisLast > this.options.THRESHOLDSLOW || response == -1) { | ||
| 96 | + this.mirrors[i].isSlow = true; | ||
| 97 | + this.mirrors[i].remainingSlow = this.options.SLOWLIMITTRIES; | ||
| 98 | + } | ||
| 99 | + | ||
| 100 | + localStorage.setItem("servers", JSON.stringify(this.mirrors)); | ||
| 101 | + break; | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + } | ||
| 105 | + | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + var position = Math.floor((Math.random() * this.mirrors.length)); | ||
| 109 | + var closestPosition; | ||
| 110 | + | ||
| 111 | + if (firstHeuristic != this.heuristics.FIRSTHEURISTIC.FIRSTRANDOM) { | ||
| 112 | + position = -1; | ||
| 113 | + closestPosition = -1; | ||
| 114 | + } | ||
| 115 | + | ||
| 116 | + var vectorBest = []; | ||
| 117 | + var k = 0, z = 0; /* JSHint Fix */ | ||
| 118 | + | ||
| 119 | + for (j = 0; j < this.mirrors.length; j++) { | ||
| 120 | + if (this.mirrors[j].remainingSlow > 0) { | ||
| 121 | + this.mirrors[j].remainingSlow = this.mirrors[j].remainingSlow - 1; | ||
| 122 | + } | ||
| 123 | + | ||
| 124 | + if (this.mirrors[j].remainingSlow === 0) { | ||
| 125 | + this.mirrors[j].isSlow = false; | ||
| 126 | + } | ||
| 127 | + | ||
| 128 | + if (firstHeuristic != this.heuristics.FIRSTHEURISTIC.FIRSTRANDOM && this.mirrors[j].isSlow === false) { | ||
| 129 | + if (closestPosition == -1) { | ||
| 130 | + closestPosition = j; | ||
| 131 | + } | ||
| 132 | + | ||
| 133 | + var added = false; | ||
| 134 | + | ||
| 135 | + for (k = 0; k < vectorBest.length; k++) { | ||
| 136 | + if (this.mirrors[j].averageTime < vectorBest[k].averageTime || (this.mirrors[j].averageTime == vectorBest[k].averageTime && (Math.floor(Math.random()) < 0.5) )) { | ||
| 137 | + | ||
| 138 | + added = true; | ||
| 139 | + | ||
| 140 | + if (vectorBest.length < sizeBest) { | ||
| 141 | + for (z = vectorBest.length-1; z >= k; z--) { | ||
| 142 | + vectorBest[z+1] = vectorBest[z]; | ||
| 143 | + } | ||
| 144 | + } else { | ||
| 145 | + for (z = vectorBest.length-2; z >= k; z--) { | ||
| 146 | + vectorBest[z+1] = vectorBest[z]; | ||
| 147 | + } | ||
| 148 | + } | ||
| 149 | + | ||
| 150 | + vectorBest[k] = this.mirrors[j]; | ||
| 151 | + | ||
| 152 | + break; | ||
| 153 | + } | ||
| 154 | + } | ||
| 155 | + | ||
| 156 | + if (added === false && vectorBest.length < sizeBest) { | ||
| 157 | + vectorBest[vectorBest.length] = this.mirrors[j]; | ||
| 158 | + } | ||
| 159 | + | ||
| 160 | + } | ||
| 161 | + | ||
| 162 | + } | ||
| 163 | + | ||
| 164 | + // pega aleatorio entre as N posicoes dos melhores (se for guloso, tera apenas um elemento no vetor) | ||
| 165 | + if (firstHeuristic != this.heuristics.FIRSTHEURISTIC.FIRSTRANDOM && vectorBest.length > 0) { | ||
| 166 | + position = Math.floor((Math.random() * vectorBest.length)); | ||
| 167 | + } | ||
| 168 | + | ||
| 169 | + if (position == -1) { | ||
| 170 | + if (secondHeuristic == this.heuristics.SECONDHEURISTIC.SECONDCLOSEST) { | ||
| 171 | + // escolhendo o mais proximo, no caso, o vetor já está ordenado | ||
| 172 | + if (closestPosition != -1) { | ||
| 173 | + position = closestPosition; | ||
| 174 | + } else { | ||
| 175 | + // se nao marcou nenhum como closest, todos devem estar como slow, nesse caso seleciona o primeiro que é o mais próximo | ||
| 176 | + position = 0; | ||
| 177 | + } | ||
| 178 | + | ||
| 179 | + } else { | ||
| 180 | + position = Math.floor((Math.random() * this.mirrors.length)); | ||
| 181 | + } | ||
| 182 | + } | ||
| 183 | + | ||
| 184 | + callback(this.mirrors[position].url); | ||
| 185 | + }; | ||
| 186 | + | ||
| 187 | + Chooser.prototype.loadMirrors_ = function(callback) { | ||
| 188 | + var $this = this; | ||
| 189 | + | ||
| 190 | + var localServers = JSON.parse(localStorage.getItem("servers")) || []; | ||
| 191 | + | ||
| 192 | + qdClient.getJSON(this.server, function (status, response) { | ||
| 193 | + var servers = status === 200 ? response : []; | ||
| 194 | + | ||
| 195 | + for (var i = 0; i < servers.length; i++){ | ||
| 196 | + var mirror = { | ||
| 197 | + name: servers[i].nome, | ||
| 198 | + url: servers[i].url, | ||
| 199 | + averageTime: 99999999, | ||
| 200 | + isSlow: false, | ||
| 201 | + previousTimes: [], | ||
| 202 | + remainingSlow: 0, | ||
| 203 | + type: servers[i].type | ||
| 204 | + }; | ||
| 205 | + | ||
| 206 | + for (var localServer in localServers) { | ||
| 207 | + if (mirror.url == localServer.url) { | ||
| 208 | + mirror.averageTime = localServer.averageTime; | ||
| 209 | + mirror.isSlow = localServer.isSlow; | ||
| 210 | + mirror.previousTimes = localServer.previousTimes; | ||
| 211 | + mirror.remainingSlow = localServer.remainingSlow; | ||
| 212 | + | ||
| 213 | + break; | ||
| 214 | + } | ||
| 215 | + } | ||
| 216 | + | ||
| 217 | + $this.mirrors.push(mirror); | ||
| 218 | + } | ||
| 219 | + | ||
| 220 | + if (callback instanceof Function) callback(); | ||
| 221 | + }); | ||
| 222 | + }; | ||
| 223 | + | ||
| 224 | +}(window, localStorage)); |
| @@ -0,0 +1,34 @@ | @@ -0,0 +1,34 @@ | ||
| 1 | +(function(window, undefined) { | ||
| 2 | + 'use strict'; | ||
| 3 | + | ||
| 4 | + window.qdClient = window.qdClient || {}; | ||
| 5 | + | ||
| 6 | + qdClient.request = function request(url, method, params, callback) { | ||
| 7 | + var xhr = new XMLHttpRequest(); | ||
| 8 | + var raw_params = ""; | ||
| 9 | + | ||
| 10 | + xhr.open(method, url, true); | ||
| 11 | + | ||
| 12 | + xhr.onload = function() { | ||
| 13 | + callback(xhr.status, xhr.responseText); | ||
| 14 | + }; | ||
| 15 | + | ||
| 16 | + if (method == "POST" && params instanceof Object) { | ||
| 17 | + | ||
| 18 | + for(var param in params) { | ||
| 19 | + raw_params += param + '=' + params[param] + '&'; | ||
| 20 | + } | ||
| 21 | + | ||
| 22 | + if (params.length > 1) raw_params.slice(0, -1); | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + xhr.send(raw_params); | ||
| 26 | + }; | ||
| 27 | + | ||
| 28 | + qdClient.getJSON = function getJSON(url, callback) { | ||
| 29 | + qdClient.request(url, "GET", {}, function(status, response) { | ||
| 30 | + callback(status, JSON.parse(response)); | ||
| 31 | + }); | ||
| 32 | + }; | ||
| 33 | + | ||
| 34 | +}(window)); |
| @@ -0,0 +1,209 @@ | @@ -0,0 +1,209 @@ | ||
| 1 | +var THRESHOLDSLOW = 2000; | ||
| 2 | +var SLOWLIMITTRIES = 5; | ||
| 3 | +var NBESTHEURISTIC1 = 2; | ||
| 4 | +var QUANTITYPREVIOUSTIMESSTORED = 10; | ||
| 5 | + | ||
| 6 | +var mirrors = []; | ||
| 7 | + | ||
| 8 | +var FIRSTHEURISTIC = { | ||
| 9 | + FIRSTRANDOM : {value: 0, name: "Random"}, | ||
| 10 | + FIRSTRANDOMNBEST: {value: 1, name: "Random Among N Best"}, | ||
| 11 | + FIRSTBEST : {value: 2, name: "Best"} | ||
| 12 | +}; | ||
| 13 | + | ||
| 14 | +var SECONDHEURISTIC = { | ||
| 15 | + SECONDRANDOM : {value: 0, name: "Random"}, | ||
| 16 | + SECONDCLOSEST: {value: 1, name: "Closest"} | ||
| 17 | +}; | ||
| 18 | + | ||
| 19 | +var THIRDHEURISTIC = { | ||
| 20 | + THIRDSIMPLEAVERAGE : {value: 0, name: "Simple Average"}, | ||
| 21 | + THIRDWEIGHTEDAVERAGE: {value: 1, name: "Weighted Average"} | ||
| 22 | +}; | ||
| 23 | + | ||
| 24 | +function httpGet(theUrl){ | ||
| 25 | + var xmlHttp = null; | ||
| 26 | + xmlHttp = new XMLHttpRequest(); | ||
| 27 | + xmlHttp.open( "GET", theUrl, false ); | ||
| 28 | + xmlHttp.send( null ); | ||
| 29 | + return JSON.parse(xmlHttp.responseText); | ||
| 30 | +} | ||
| 31 | + | ||
| 32 | + | ||
| 33 | + | ||
| 34 | +function loadMirrors() { | ||
| 35 | + var localServersArray = JSON.parse(localStorage.getItem("serversDatabase")); | ||
| 36 | + if(localServersArray == null){ | ||
| 37 | + localServersArray = []; | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + var servers = httpGet('http://fuze.cc/sobreApps/teste_lavid/get_servers.php'); | ||
| 41 | + for (var i = 0; i < servers.length; i++){ | ||
| 42 | + var mirror = {}; | ||
| 43 | + mirror.name = servers[i].nome; | ||
| 44 | + mirror.url = servers[i].url; | ||
| 45 | + mirror.averageTime = 99999999; | ||
| 46 | + mirror.isSlow = false; | ||
| 47 | + mirror.previousTimes = []; | ||
| 48 | + mirror.remainingSlow = 0; | ||
| 49 | + mirror.type = servers[i].type; | ||
| 50 | + | ||
| 51 | + for (var j = 0; j < localServersArray.length; j++) { | ||
| 52 | + if (mirror.url == localServersArray[j].url) { | ||
| 53 | + mirror.averageTime = localServersArray[j].averageTime; | ||
| 54 | + mirror.isSlow = localServersArray[j].isSlow; | ||
| 55 | + mirror.previousTimes = localServersArray[j].previousTimes; | ||
| 56 | + mirror.remainingSlow = localServersArray[j].remainingSlow; | ||
| 57 | + | ||
| 58 | + break; | ||
| 59 | + } | ||
| 60 | + } | ||
| 61 | + | ||
| 62 | + mirrors.push(mirror); | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | +} | ||
| 66 | + | ||
| 67 | +function chooseServer(urlLast, millisLast, response) { | ||
| 68 | + if (mirrors.length == 0) { | ||
| 69 | + loadMirrors(); | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + if (mirrors.length == 0) { | ||
| 73 | + alert("Sem mirrors disponíveis"); | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + var firstHeuristic = FIRSTHEURISTIC.FIRSTBEST; | ||
| 77 | + var secondHeuristic = SECONDHEURISTIC.SECONDRANDOM; | ||
| 78 | + var thirdHeuristic = THIRDHEURISTIC.THIRDWEIGHTEDAVERAGE; | ||
| 79 | + | ||
| 80 | + var sizeBest = NBESTHEURISTIC1; | ||
| 81 | + if (firstHeuristic == FIRSTHEURISTIC.FIRSTBEST) { | ||
| 82 | + sizeBest = 1; | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + if (urlLast.length > 0) { | ||
| 86 | + for (var i = 0; i < mirrors.length; i++) { | ||
| 87 | + if (mirrors[i].url.toLowerCase() == urlLast.toLowerCase()) { | ||
| 88 | + if (mirrors[i].previousTimes.length < QUANTITYPREVIOUSTIMESSTORED) { | ||
| 89 | + mirrors[i].previousTimes[mirrors[i].previousTimes.length] = millisLast; | ||
| 90 | + | ||
| 91 | + } else { | ||
| 92 | + for (var j = QUANTITYPREVIOUSTIMESSTORED-1; j > 0; j--) { | ||
| 93 | + mirrors[i].previousTimes[j-1] = mirrors[i].previousTimes[j]; | ||
| 94 | + } | ||
| 95 | + | ||
| 96 | + mirrors[i].previousTimes[QUANTITYPREVIOUSTIMESSTORED-1] = millisLast; | ||
| 97 | + | ||
| 98 | + } | ||
| 99 | + | ||
| 100 | + if (thirdHeuristic == THIRDHEURISTIC.THIRDSIMPLEAVERAGE) { | ||
| 101 | + var totalMillis = 0; | ||
| 102 | + for (var j = 0; j < mirrors[i].previousTimes.length; j++) { | ||
| 103 | + totalMillis += mirrors[i].previousTimes[j]; | ||
| 104 | + } | ||
| 105 | + | ||
| 106 | + mirrors[i].averageTime = totalMillis/mirrors[i].previousTimes.length; | ||
| 107 | + | ||
| 108 | + } else if (thirdHeuristic == THIRDHEURISTIC.THIRDWEIGHTEDAVERAGE) { | ||
| 109 | + var totalMillisAndWeights = 0; | ||
| 110 | + var totalWeights = 0; | ||
| 111 | + for (var j = 0; j < mirrors[i].previousTimes.length; j++) { | ||
| 112 | + totalMillisAndWeights += mirrors[i].previousTimes[j]*(j+1); | ||
| 113 | + totalWeights += (j+1); | ||
| 114 | + } | ||
| 115 | + | ||
| 116 | + mirrors[i].averageTime = totalMillisAndWeights/totalWeights; | ||
| 117 | + | ||
| 118 | + } | ||
| 119 | + | ||
| 120 | + if (millisLast > THRESHOLDSLOW || response == "-1") { | ||
| 121 | + mirrors[i].isSlow = true; | ||
| 122 | + mirrors[i].remainingSlow = SLOWLIMITTRIES; | ||
| 123 | + } | ||
| 124 | + | ||
| 125 | + localStorage.setItem("serversDatabase", JSON.stringify(mirrors)); | ||
| 126 | + break; | ||
| 127 | + } | ||
| 128 | + | ||
| 129 | + } | ||
| 130 | + | ||
| 131 | + } | ||
| 132 | + | ||
| 133 | + var position = Math.floor((Math.random() * mirrors.length)); | ||
| 134 | + var closestPosition; | ||
| 135 | + | ||
| 136 | + if (firstHeuristic != FIRSTHEURISTIC.FIRSTRANDOM) { | ||
| 137 | + position = -1; | ||
| 138 | + closestPosition = -1; | ||
| 139 | + } | ||
| 140 | + | ||
| 141 | + var vectorBest = []; | ||
| 142 | + | ||
| 143 | + for (var j = 0; j < mirrors.length; j++) { | ||
| 144 | + if (mirrors[j].remainingSlow > 0) { | ||
| 145 | + mirrors[j].remainingSlow = mirrors[j].remainingSlow - 1; | ||
| 146 | + } | ||
| 147 | + | ||
| 148 | + if (mirrors[j].remainingSlow == 0) { | ||
| 149 | + mirrors[j].isSlow = false; | ||
| 150 | + } | ||
| 151 | + | ||
| 152 | + if (firstHeuristic != FIRSTHEURISTIC.FIRSTRANDOM && mirrors[j].isSlow == false) { | ||
| 153 | + if (closestPosition == -1) { | ||
| 154 | + closestPosition = j; | ||
| 155 | + } | ||
| 156 | + | ||
| 157 | + var added = false; | ||
| 158 | + | ||
| 159 | + for (var k = 0; k < vectorBest.length; k++) { | ||
| 160 | + if (mirrors[j].averageTime < vectorBest[k].averageTime || (mirrors[j].averageTime == vectorBest[k].averageTime && (Math.floor(Math.random()) < 0.5) )) { | ||
| 161 | + | ||
| 162 | + added = true; | ||
| 163 | + | ||
| 164 | + if (vectorBest.length < sizeBest) { | ||
| 165 | + for (var z = vectorBest.length-1; z >= k; z--) { | ||
| 166 | + vectorBest[z+1] = vectorBest[z]; | ||
| 167 | + } | ||
| 168 | + } else { | ||
| 169 | + for (var z = vectorBest.length-2; z >= k; z--) { | ||
| 170 | + vectorBest[z+1] = vectorBest[z]; | ||
| 171 | + } | ||
| 172 | + } | ||
| 173 | + | ||
| 174 | + vectorBest[k] = mirrors[j]; | ||
| 175 | + | ||
| 176 | + break; | ||
| 177 | + } | ||
| 178 | + } | ||
| 179 | + | ||
| 180 | + if (added == false && vectorBest.length < sizeBest) { | ||
| 181 | + vectorBest[vectorBest.length] = mirrors[j]; | ||
| 182 | + } | ||
| 183 | + | ||
| 184 | + } | ||
| 185 | + | ||
| 186 | + } | ||
| 187 | + | ||
| 188 | + // pega aleatorio entre as N posicoes dos melhores (se for guloso, tera apenas um elemento no vetor) | ||
| 189 | + if (firstHeuristic != FIRSTHEURISTIC.FIRSTRANDOM && vectorBest.length > 0) { | ||
| 190 | + position = Math.floor((Math.random() * vectorBest.length)); | ||
| 191 | + } | ||
| 192 | + | ||
| 193 | + if (position == -1) { | ||
| 194 | + if (secondHeuristic == SECONDHEURISTIC.SECONDCLOSEST) { | ||
| 195 | + // escolhendo o mais proximo, no caso, o vetor já está ordenado | ||
| 196 | + if (closestPosition != -1) { | ||
| 197 | + position = closestPosition; | ||
| 198 | + } else { | ||
| 199 | + // se nao marcou nenhum como closest, todos devem estar como slow, nesse caso seleciona o primeiro que é o mais próximo | ||
| 200 | + position = 0; | ||
| 201 | + } | ||
| 202 | + | ||
| 203 | + } else { | ||
| 204 | + position = Math.floor((Math.random() * mirrors.length)); | ||
| 205 | + } | ||
| 206 | + } | ||
| 207 | + | ||
| 208 | + return mirrors[position].url; | ||
| 209 | +} |
| @@ -0,0 +1,18 @@ | @@ -0,0 +1,18 @@ | ||
| 1 | +{ | ||
| 2 | + "name": "qdclient", | ||
| 3 | + "version": "0.0.1", | ||
| 4 | + "description": "", | ||
| 5 | + "scripts": { | ||
| 6 | + "test": "echo \"Error: no test specified\" && exit 1" | ||
| 7 | + }, | ||
| 8 | + "devDependencies": { | ||
| 9 | + "browser-sync": "^2.7.13", | ||
| 10 | + "gulp": "^3.9.0", | ||
| 11 | + "gulp-concat": "^2.6.0", | ||
| 12 | + "gulp-jshint": "^1.11.2", | ||
| 13 | + "gulp-rename": "^1.2.2", | ||
| 14 | + "gulp-rimraf": "^0.1.1", | ||
| 15 | + "gulp-uglify": "^1.2.0", | ||
| 16 | + "run-sequence": "^1.1.1" | ||
| 17 | + } | ||
| 18 | +} |
| @@ -0,0 +1,259 @@ | @@ -0,0 +1,259 @@ | ||
| 1 | +(function(window, undefined) { | ||
| 2 | + 'use strict'; | ||
| 3 | + | ||
| 4 | + window.qdClient = window.qdClient || {}; | ||
| 5 | + | ||
| 6 | + qdClient.request = function request(url, method, params, callback) { | ||
| 7 | + var xhr = new XMLHttpRequest(); | ||
| 8 | + var raw_params = ""; | ||
| 9 | + | ||
| 10 | + xhr.open(method, url, true); | ||
| 11 | + | ||
| 12 | + xhr.onload = function() { | ||
| 13 | + callback(xhr.status, xhr.responseText); | ||
| 14 | + }; | ||
| 15 | + | ||
| 16 | + if (method == "POST" && params instanceof Object) { | ||
| 17 | + | ||
| 18 | + for(var param in params) { | ||
| 19 | + raw_params += param + '=' + params[param] + '&'; | ||
| 20 | + } | ||
| 21 | + | ||
| 22 | + if (params.length > 1) raw_params.slice(0, -1); | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + xhr.send(raw_params); | ||
| 26 | + }; | ||
| 27 | + | ||
| 28 | + qdClient.getJSON = function getJSON(url, callback) { | ||
| 29 | + qdClient.request(url, "GET", {}, function(status, response) { | ||
| 30 | + callback(status, JSON.parse(response)); | ||
| 31 | + }); | ||
| 32 | + }; | ||
| 33 | + | ||
| 34 | +}(window)); | ||
| 35 | + | ||
| 36 | +(function(window, localStorage, undefined) { | ||
| 37 | + 'use strict'; | ||
| 38 | + | ||
| 39 | + function Chooser() { | ||
| 40 | + this.server = 'http://150.165.204.39/vlibras-cloud/get_servers.php'; | ||
| 41 | + | ||
| 42 | + this.options = { | ||
| 43 | + THRESHOLDSLOW: 2000, | ||
| 44 | + SLOWLIMITTRIES: 5, | ||
| 45 | + NBESTHEURISTIC1: 2, | ||
| 46 | + QUANTITYPREVIOUSTIMESSTORED: 10 | ||
| 47 | + }; | ||
| 48 | + | ||
| 49 | + this.mirrors = []; | ||
| 50 | + | ||
| 51 | + this.heuristics = { | ||
| 52 | + FIRSTHEURISTIC: { | ||
| 53 | + FIRSTRANDOM : {value: 0, name: "Random"}, | ||
| 54 | + FIRSTRANDOMNBEST: {value: 1, name: "Random Among N Best"}, | ||
| 55 | + FIRSTBEST : {value: 2, name: "Best"} | ||
| 56 | + }, | ||
| 57 | + SECONDHEURISTIC: { | ||
| 58 | + SECONDRANDOM : {value: 0, name: "Random"}, | ||
| 59 | + SECONDCLOSEST: {value: 1, name: "Closest"} | ||
| 60 | + }, | ||
| 61 | + THIRDHEURISTIC: { | ||
| 62 | + THIRDSIMPLEAVERAGE : {value: 0, name: "Simple Average"}, | ||
| 63 | + THIRDWEIGHTEDAVERAGE: {value: 1, name: "Weighted Average"} | ||
| 64 | + } | ||
| 65 | + }; | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + // Exports | ||
| 69 | + qdClient.Chooser = Chooser; | ||
| 70 | + | ||
| 71 | + Chooser.prototype.choose = function(urlLast, millisLast, response, callback) { | ||
| 72 | + var $this = this; | ||
| 73 | + | ||
| 74 | + if (this.mirrors.length === 0) { | ||
| 75 | + this.loadMirrors_(function() { | ||
| 76 | + $this.chooseServer_(urlLast, millisLast, response, callback); | ||
| 77 | + }); | ||
| 78 | + } else { | ||
| 79 | + this.chooseServer_(urlLast, millisLast, response, callback); | ||
| 80 | + } | ||
| 81 | + }; | ||
| 82 | + | ||
| 83 | + Chooser.prototype.chooseServer_ = function(urlLast, millisLast, response, callback) { | ||
| 84 | + var firstHeuristic = this.heuristics.FIRSTHEURISTIC.FIRSTBEST; | ||
| 85 | + var secondHeuristic = this.heuristics.SECONDHEURISTIC.SECONDRANDOM; | ||
| 86 | + var thirdHeuristic = this.heuristics.THIRDHEURISTIC.THIRDWEIGHTEDAVERAGE; | ||
| 87 | + | ||
| 88 | + var j = 0, i = 0; /* Fix JSHint */ | ||
| 89 | + | ||
| 90 | + var sizeBest = this.options.NBESTHEURISTIC1; | ||
| 91 | + if (firstHeuristic == this.heuristics.FIRSTHEURISTIC.FIRSTBEST) { | ||
| 92 | + sizeBest = 1; | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + if (urlLast && urlLast.length > 0) { | ||
| 96 | + for (i = 0; i < this.mirrors.length; i++) { | ||
| 97 | + if (this.mirrors[i].url.toLowerCase() == urlLast.toLowerCase()) { | ||
| 98 | + if (this.mirrors[i].previousTimes.length < this.options.QUANTITYPREVIOUSTIMESSTORED) { | ||
| 99 | + this.mirrors[i].previousTimes[this.mirrors[i].previousTimes.length] = millisLast; | ||
| 100 | + | ||
| 101 | + } else { | ||
| 102 | + for (j = this.options.QUANTITYPREVIOUSTIMESSTORED-1; j > 0; j--) { | ||
| 103 | + this.mirrors[i].previousTimes[j-1] = this.mirrors[i].previousTimes[j]; | ||
| 104 | + } | ||
| 105 | + | ||
| 106 | + this.mirrors[i].previousTimes[this.options.QUANTITYPREVIOUSTIMESSTORED-1] = millisLast; | ||
| 107 | + | ||
| 108 | + } | ||
| 109 | + | ||
| 110 | + if (thirdHeuristic == this.heuristics.THIRDHEURISTIC.THIRDSIMPLEAVERAGE) { | ||
| 111 | + var totalMillis = 0; | ||
| 112 | + for (j = 0; j < this.mirrors[i].previousTimes.length; j++) { | ||
| 113 | + totalMillis += this.mirrors[i].previousTimes[j]; | ||
| 114 | + } | ||
| 115 | + | ||
| 116 | + this.mirrors[i].averageTime = totalMillis/this.mirrors[i].previousTimes.length; | ||
| 117 | + | ||
| 118 | + } else if (thirdHeuristic == this.heuristics.THIRDHEURISTIC.THIRDWEIGHTEDAVERAGE) { | ||
| 119 | + var totalMillisAndWeights = 0; | ||
| 120 | + var totalWeights = 0; | ||
| 121 | + for (j = 0; j < this.mirrors[i].previousTimes.length; j++) { | ||
| 122 | + totalMillisAndWeights += this.mirrors[i].previousTimes[j]*(j+1); | ||
| 123 | + totalWeights += (j+1); | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + this.mirrors[i].averageTime = totalMillisAndWeights/totalWeights; | ||
| 127 | + | ||
| 128 | + } | ||
| 129 | + | ||
| 130 | + if (millisLast > this.options.THRESHOLDSLOW || response == -1) { | ||
| 131 | + this.mirrors[i].isSlow = true; | ||
| 132 | + this.mirrors[i].remainingSlow = this.options.SLOWLIMITTRIES; | ||
| 133 | + } | ||
| 134 | + | ||
| 135 | + localStorage.setItem("servers", JSON.stringify(this.mirrors)); | ||
| 136 | + break; | ||
| 137 | + } | ||
| 138 | + | ||
| 139 | + } | ||
| 140 | + | ||
| 141 | + } | ||
| 142 | + | ||
| 143 | + var position = Math.floor((Math.random() * this.mirrors.length)); | ||
| 144 | + var closestPosition; | ||
| 145 | + | ||
| 146 | + if (firstHeuristic != this.heuristics.FIRSTHEURISTIC.FIRSTRANDOM) { | ||
| 147 | + position = -1; | ||
| 148 | + closestPosition = -1; | ||
| 149 | + } | ||
| 150 | + | ||
| 151 | + var vectorBest = []; | ||
| 152 | + var k = 0, z = 0; /* JSHint Fix */ | ||
| 153 | + | ||
| 154 | + for (j = 0; j < this.mirrors.length; j++) { | ||
| 155 | + if (this.mirrors[j].remainingSlow > 0) { | ||
| 156 | + this.mirrors[j].remainingSlow = this.mirrors[j].remainingSlow - 1; | ||
| 157 | + } | ||
| 158 | + | ||
| 159 | + if (this.mirrors[j].remainingSlow === 0) { | ||
| 160 | + this.mirrors[j].isSlow = false; | ||
| 161 | + } | ||
| 162 | + | ||
| 163 | + if (firstHeuristic != this.heuristics.FIRSTHEURISTIC.FIRSTRANDOM && this.mirrors[j].isSlow === false) { | ||
| 164 | + if (closestPosition == -1) { | ||
| 165 | + closestPosition = j; | ||
| 166 | + } | ||
| 167 | + | ||
| 168 | + var added = false; | ||
| 169 | + | ||
| 170 | + for (k = 0; k < vectorBest.length; k++) { | ||
| 171 | + if (this.mirrors[j].averageTime < vectorBest[k].averageTime || (this.mirrors[j].averageTime == vectorBest[k].averageTime && (Math.floor(Math.random()) < 0.5) )) { | ||
| 172 | + | ||
| 173 | + added = true; | ||
| 174 | + | ||
| 175 | + if (vectorBest.length < sizeBest) { | ||
| 176 | + for (z = vectorBest.length-1; z >= k; z--) { | ||
| 177 | + vectorBest[z+1] = vectorBest[z]; | ||
| 178 | + } | ||
| 179 | + } else { | ||
| 180 | + for (z = vectorBest.length-2; z >= k; z--) { | ||
| 181 | + vectorBest[z+1] = vectorBest[z]; | ||
| 182 | + } | ||
| 183 | + } | ||
| 184 | + | ||
| 185 | + vectorBest[k] = this.mirrors[j]; | ||
| 186 | + | ||
| 187 | + break; | ||
| 188 | + } | ||
| 189 | + } | ||
| 190 | + | ||
| 191 | + if (added === false && vectorBest.length < sizeBest) { | ||
| 192 | + vectorBest[vectorBest.length] = this.mirrors[j]; | ||
| 193 | + } | ||
| 194 | + | ||
| 195 | + } | ||
| 196 | + | ||
| 197 | + } | ||
| 198 | + | ||
| 199 | + // pega aleatorio entre as N posicoes dos melhores (se for guloso, tera apenas um elemento no vetor) | ||
| 200 | + if (firstHeuristic != this.heuristics.FIRSTHEURISTIC.FIRSTRANDOM && vectorBest.length > 0) { | ||
| 201 | + position = Math.floor((Math.random() * vectorBest.length)); | ||
| 202 | + } | ||
| 203 | + | ||
| 204 | + if (position == -1) { | ||
| 205 | + if (secondHeuristic == this.heuristics.SECONDHEURISTIC.SECONDCLOSEST) { | ||
| 206 | + // escolhendo o mais proximo, no caso, o vetor já está ordenado | ||
| 207 | + if (closestPosition != -1) { | ||
| 208 | + position = closestPosition; | ||
| 209 | + } else { | ||
| 210 | + // se nao marcou nenhum como closest, todos devem estar como slow, nesse caso seleciona o primeiro que é o mais próximo | ||
| 211 | + position = 0; | ||
| 212 | + } | ||
| 213 | + | ||
| 214 | + } else { | ||
| 215 | + position = Math.floor((Math.random() * this.mirrors.length)); | ||
| 216 | + } | ||
| 217 | + } | ||
| 218 | + | ||
| 219 | + callback(this.mirrors[position].url); | ||
| 220 | + }; | ||
| 221 | + | ||
| 222 | + Chooser.prototype.loadMirrors_ = function(callback) { | ||
| 223 | + var $this = this; | ||
| 224 | + | ||
| 225 | + var localServers = JSON.parse(localStorage.getItem("servers")) || []; | ||
| 226 | + | ||
| 227 | + qdClient.getJSON(this.server, function (status, response) { | ||
| 228 | + var servers = status === 200 ? response : []; | ||
| 229 | + | ||
| 230 | + for (var i = 0; i < servers.length; i++){ | ||
| 231 | + var mirror = { | ||
| 232 | + name: servers[i].nome, | ||
| 233 | + url: servers[i].url, | ||
| 234 | + averageTime: 99999999, | ||
| 235 | + isSlow: false, | ||
| 236 | + previousTimes: [], | ||
| 237 | + remainingSlow: 0, | ||
| 238 | + type: servers[i].type | ||
| 239 | + }; | ||
| 240 | + | ||
| 241 | + for (var localServer in localServers) { | ||
| 242 | + if (mirror.url == localServer.url) { | ||
| 243 | + mirror.averageTime = localServer.averageTime; | ||
| 244 | + mirror.isSlow = localServer.isSlow; | ||
| 245 | + mirror.previousTimes = localServer.previousTimes; | ||
| 246 | + mirror.remainingSlow = localServer.remainingSlow; | ||
| 247 | + | ||
| 248 | + break; | ||
| 249 | + } | ||
| 250 | + } | ||
| 251 | + | ||
| 252 | + $this.mirrors.push(mirror); | ||
| 253 | + } | ||
| 254 | + | ||
| 255 | + if (callback instanceof Function) callback(); | ||
| 256 | + }); | ||
| 257 | + }; | ||
| 258 | + | ||
| 259 | +}(window, localStorage)); |
| @@ -0,0 +1 @@ | @@ -0,0 +1 @@ | ||
| 1 | +!function(r,i){"use strict";r.qdClient=r.qdClient||{},qdClient.request=function(r,i,s,e){var t=new XMLHttpRequest,o="";if(t.open(i,r,!0),t.onload=function(){e(t.status,t.responseText)},"POST"==i&&s instanceof Object){for(var n in s)o+=n+"="+s[n]+"&";s.length>1&&o.slice(0,-1)}t.send(o)},qdClient.getJSON=function(r,i){qdClient.request(r,"GET",{},function(r,s){i(r,JSON.parse(s))})}}(window),function(r,i,s){"use strict";function e(){this.server="http://150.165.204.39/vlibras-cloud/get_servers.php",this.options={THRESHOLDSLOW:2e3,SLOWLIMITTRIES:5,NBESTHEURISTIC1:2,QUANTITYPREVIOUSTIMESSTORED:10},this.mirrors=[],this.heuristics={FIRSTHEURISTIC:{FIRSTRANDOM:{value:0,name:"Random"},FIRSTRANDOMNBEST:{value:1,name:"Random Among N Best"},FIRSTBEST:{value:2,name:"Best"}},SECONDHEURISTIC:{SECONDRANDOM:{value:0,name:"Random"},SECONDCLOSEST:{value:1,name:"Closest"}},THIRDHEURISTIC:{THIRDSIMPLEAVERAGE:{value:0,name:"Simple Average"},THIRDWEIGHTEDAVERAGE:{value:1,name:"Weighted Average"}}}}qdClient.Chooser=e,e.prototype.choose=function(r,i,s,e){var t=this;0===this.mirrors.length?this.loadMirrors_(function(){t.chooseServer_(r,i,s,e)}):this.chooseServer_(r,i,s,e)},e.prototype.chooseServer_=function(r,s,e,t){var o=this.heuristics.FIRSTHEURISTIC.FIRSTBEST,n=this.heuristics.SECONDHEURISTIC.SECONDRANDOM,h=this.heuristics.THIRDHEURISTIC.THIRDWEIGHTEDAVERAGE,T=0,S=0,a=this.options.NBESTHEURISTIC1;if(o==this.heuristics.FIRSTHEURISTIC.FIRSTBEST&&(a=1),r&&r.length>0)for(S=0;S<this.mirrors.length;S++)if(this.mirrors[S].url.toLowerCase()==r.toLowerCase()){if(this.mirrors[S].previousTimes.length<this.options.QUANTITYPREVIOUSTIMESSTORED)this.mirrors[S].previousTimes[this.mirrors[S].previousTimes.length]=s;else{for(T=this.options.QUANTITYPREVIOUSTIMESSTORED-1;T>0;T--)this.mirrors[S].previousTimes[T-1]=this.mirrors[S].previousTimes[T];this.mirrors[S].previousTimes[this.options.QUANTITYPREVIOUSTIMESSTORED-1]=s}if(h==this.heuristics.THIRDHEURISTIC.THIRDSIMPLEAVERAGE){var m=0;for(T=0;T<this.mirrors[S].previousTimes.length;T++)m+=this.mirrors[S].previousTimes[T];this.mirrors[S].averageTime=m/this.mirrors[S].previousTimes.length}else if(h==this.heuristics.THIRDHEURISTIC.THIRDWEIGHTEDAVERAGE){var I=0,l=0;for(T=0;T<this.mirrors[S].previousTimes.length;T++)I+=this.mirrors[S].previousTimes[T]*(T+1),l+=T+1;this.mirrors[S].averageTime=I/l}(s>this.options.THRESHOLDSLOW||-1==e)&&(this.mirrors[S].isSlow=!0,this.mirrors[S].remainingSlow=this.options.SLOWLIMITTRIES),i.setItem("servers",JSON.stringify(this.mirrors));break}var R,E=Math.floor(Math.random()*this.mirrors.length);o!=this.heuristics.FIRSTHEURISTIC.FIRSTRANDOM&&(E=-1,R=-1);var u=[],v=0,g=0;for(T=0;T<this.mirrors.length;T++)if(this.mirrors[T].remainingSlow>0&&(this.mirrors[T].remainingSlow=this.mirrors[T].remainingSlow-1),0===this.mirrors[T].remainingSlow&&(this.mirrors[T].isSlow=!1),o!=this.heuristics.FIRSTHEURISTIC.FIRSTRANDOM&&this.mirrors[T].isSlow===!1){-1==R&&(R=T);var f=!1;for(v=0;v<u.length;v++)if(this.mirrors[T].averageTime<u[v].averageTime||this.mirrors[T].averageTime==u[v].averageTime&&Math.floor(Math.random())<.5){if(f=!0,u.length<a)for(g=u.length-1;g>=v;g--)u[g+1]=u[g];else for(g=u.length-2;g>=v;g--)u[g+1]=u[g];u[v]=this.mirrors[T];break}f===!1&&u.length<a&&(u[u.length]=this.mirrors[T])}o!=this.heuristics.FIRSTHEURISTIC.FIRSTRANDOM&&u.length>0&&(E=Math.floor(Math.random()*u.length)),-1==E&&(E=n==this.heuristics.SECONDHEURISTIC.SECONDCLOSEST?-1!=R?R:0:Math.floor(Math.random()*this.mirrors.length)),t(this.mirrors[E].url)},e.prototype.loadMirrors_=function(r){var s=this,e=JSON.parse(i.getItem("servers"))||[];qdClient.getJSON(this.server,function(i,t){for(var o=200===i?t:[],n=0;n<o.length;n++){var h={name:o[n].nome,url:o[n].url,averageTime:99999999,isSlow:!1,previousTimes:[],remainingSlow:0,type:o[n].type};for(var T in e)if(h.url==T.url){h.averageTime=T.averageTime,h.isSlow=T.isSlow,h.previousTimes=T.previousTimes,h.remainingSlow=T.remainingSlow;break}s.mirrors.push(h)}r instanceof Function&&r()})}}(window,localStorage); | ||
| 0 | \ No newline at end of file | 2 | \ No newline at end of file |
chrome/app/window.html
| @@ -7,6 +7,8 @@ | @@ -7,6 +7,8 @@ | ||
| 7 | <link rel="stylesheet" href="TemplateData/style.css"> | 7 | <link rel="stylesheet" href="TemplateData/style.css"> |
| 8 | <link rel="shortcut icon" href="TemplateData/favicon.ico?v=2" /> | 8 | <link rel="shortcut icon" href="TemplateData/favicon.ico?v=2" /> |
| 9 | <script src="TemplateData/UnityProgress.js"></script> | 9 | <script src="TemplateData/UnityProgress.js"></script> |
| 10 | + | ||
| 11 | + <script src="vendors/qdclient/qdclient.js"></script> | ||
| 10 | <script src="main.js"></script> | 12 | <script src="main.js"></script> |
| 11 | 13 | ||
| 12 | <style type="text/css"> | 14 | <style type="text/css"> |
chrome/manifest.json
| @@ -12,7 +12,8 @@ | @@ -12,7 +12,8 @@ | ||
| 12 | 12 | ||
| 13 | "permissions": [ | 13 | "permissions": [ |
| 14 | "contextMenus", | 14 | "contextMenus", |
| 15 | - "http://150.165.204.30:9000/" | 15 | + "http://150.165.204.30:5000/", |
| 16 | + "http://150.165.204.39/" | ||
| 16 | ], | 17 | ], |
| 17 | 18 | ||
| 18 | "icons": { | 19 | "icons": { |
| @@ -22,4 +23,4 @@ | @@ -22,4 +23,4 @@ | ||
| 22 | }, | 23 | }, |
| 23 | 24 | ||
| 24 | "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'" | 25 | "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'" |
| 25 | -} | ||
| 26 | \ No newline at end of file | 26 | \ No newline at end of file |
| 27 | +} |
No preview for this file type
| @@ -0,0 +1,97 @@ | @@ -0,0 +1,97 @@ | ||
| 1 | +function UnityProgress (dom) { | ||
| 2 | + this.progress = 0.0; | ||
| 3 | + this.message = ""; | ||
| 4 | + this.dom = dom; | ||
| 5 | + | ||
| 6 | + var parent = dom.parentNode; | ||
| 7 | + | ||
| 8 | + var background = document.createElement("div"); | ||
| 9 | + background.style.background = "#FFFFFF"; | ||
| 10 | + background.style.position = "absolute"; | ||
| 11 | + parent.appendChild(background); | ||
| 12 | + this.background = background; | ||
| 13 | + | ||
| 14 | + var logoImage = document.createElement("img"); | ||
| 15 | + logoImage.src = "TemplateData/progresslogo.png"; | ||
| 16 | + logoImage.style.position = "absolute"; | ||
| 17 | + parent.appendChild(logoImage); | ||
| 18 | + this.logoImage = logoImage; | ||
| 19 | + | ||
| 20 | + var progressFrame = document.createElement("img"); | ||
| 21 | + progressFrame.src = "TemplateData/loadingbar.png"; | ||
| 22 | + progressFrame.style.position = "absolute"; | ||
| 23 | + parent.appendChild(progressFrame); | ||
| 24 | + this.progressFrame = progressFrame; | ||
| 25 | + | ||
| 26 | + var progressBar = document.createElement("img"); | ||
| 27 | + progressBar.src = "TemplateData/fullbar.png"; | ||
| 28 | + progressBar.style.position = "absolute"; | ||
| 29 | + parent.appendChild(progressBar); | ||
| 30 | + this.progressBar = progressBar; | ||
| 31 | + | ||
| 32 | + var messageArea = document.createElement("p"); | ||
| 33 | + messageArea.style.position = "absolute"; | ||
| 34 | + parent.appendChild(messageArea); | ||
| 35 | + this.messageArea = messageArea; | ||
| 36 | + | ||
| 37 | + | ||
| 38 | + this.SetProgress = function (progress) { | ||
| 39 | + if (this.progress < progress) | ||
| 40 | + this.progress = progress; | ||
| 41 | + this.messageArea.style.display = "none"; | ||
| 42 | + this.progressFrame.style.display = "inline"; | ||
| 43 | + this.progressBar.style.display = "inline"; | ||
| 44 | + this.Update(); | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + this.SetMessage = function (message) { | ||
| 48 | + this.message = message; | ||
| 49 | + this.background.style.display = "inline"; | ||
| 50 | + this.logoImage.style.display = "inline"; | ||
| 51 | + this.progressFrame.style.display = "none"; | ||
| 52 | + this.progressBar.style.display = "none"; | ||
| 53 | + this.Update(); | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + this.Clear = function() { | ||
| 57 | + this.background.style.display = "none"; | ||
| 58 | + this.logoImage.style.display = "none"; | ||
| 59 | + this.progressFrame.style.display = "none"; | ||
| 60 | + this.progressBar.style.display = "none"; | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + this.Update = function() { | ||
| 64 | + this.background.style.top = this.dom.offsetTop + 'px'; | ||
| 65 | + this.background.style.left = this.dom.offsetLeft + 'px'; | ||
| 66 | + this.background.style.width = this.dom.offsetWidth + 'px'; | ||
| 67 | + this.background.style.height = this.dom.offsetHeight + 'px'; | ||
| 68 | + | ||
| 69 | + var logoImg = new Image(); | ||
| 70 | + logoImg.src = this.logoImage.src; | ||
| 71 | + var progressFrameImg = new Image(); | ||
| 72 | + progressFrameImg.src = this.progressFrame.src; | ||
| 73 | + | ||
| 74 | + this.logoImage.style.top = this.dom.offsetTop + (this.dom.offsetHeight * 0.5 - logoImg.height * 0.5) + 'px'; | ||
| 75 | + this.logoImage.style.left = this.dom.offsetLeft + (this.dom.offsetWidth * 0.5 - logoImg.width * 0.5) + 'px'; | ||
| 76 | + this.logoImage.style.width = logoImg.width+'px'; | ||
| 77 | + this.logoImage.style.height = logoImg.height+'px'; | ||
| 78 | + | ||
| 79 | + this.progressFrame.style.top = this.dom.offsetTop + (this.dom.offsetHeight * 0.5 + logoImg.height * 0.5 + 10) + 'px'; | ||
| 80 | + this.progressFrame.style.left = this.dom.offsetLeft + (this.dom.offsetWidth * 0.5 - progressFrameImg.width * 0.5) + 'px'; | ||
| 81 | + this.progressFrame.width = progressFrameImg.width; | ||
| 82 | + this.progressFrame.height = progressFrameImg.height; | ||
| 83 | + | ||
| 84 | + this.progressBar.style.top = this.progressFrame.style.top; | ||
| 85 | + this.progressBar.style.left = this.progressFrame.style.left; | ||
| 86 | + this.progressBar.width = progressFrameImg.width * Math.min(this.progress, 1); | ||
| 87 | + this.progressBar.height = progressFrameImg.height; | ||
| 88 | + | ||
| 89 | + this.messageArea.style.top = this.progressFrame.style.top; | ||
| 90 | + this.messageArea.style.left = 0; | ||
| 91 | + this.messageArea.style.width = '100%'; | ||
| 92 | + this.messageArea.style.textAlign = 'center'; | ||
| 93 | + this.messageArea.innerHTML = this.message; | ||
| 94 | + } | ||
| 95 | + | ||
| 96 | + this.Update (); | ||
| 97 | +} | ||
| 0 | \ No newline at end of file | 98 | \ No newline at end of file |
51.6 KB
18.4 KB
2.71 KB
2.78 KB
20.7 KB
| @@ -0,0 +1,28 @@ | @@ -0,0 +1,28 @@ | ||
| 1 | + | ||
| 2 | +/**************************************** | ||
| 3 | + ==== RESETS | ||
| 4 | +****************************************/ | ||
| 5 | + | ||
| 6 | +html,body,div,canvas { margin: 0; padding: 0; } | ||
| 7 | +::-moz-selection { color: #333; text-shadow: none; } | ||
| 8 | +::selection { color: #333; text-shadow: none; } | ||
| 9 | +.clear:after { visibility: hidden; display: block; font-size: 0; content: " "; clear: both; height: 0; } | ||
| 10 | +.clear { display: inline-table; clear: both; } | ||
| 11 | +/* Hides from IE-mac \*/ * html .clear { height: 1%; } .clear { display: block; } /* End hide from IE-mac */ | ||
| 12 | + | ||
| 13 | +/**************************************** | ||
| 14 | + ==== LAYOUT | ||
| 15 | +****************************************/ | ||
| 16 | + | ||
| 17 | +html, body { width: 100%; height: 100%; font-family: Helvetica, Verdana, Arial, sans-serif; } | ||
| 18 | +body { } | ||
| 19 | +p.header, p.footer { display: none; } | ||
| 20 | +div.logo { width: 196px; height: 38px; float: left; background: url(logo.png) 0 0 no-repeat; position: relative; z-index: 10; } | ||
| 21 | +div.title { height: 38px; line-height: 38px; padding: 0 10px; margin: 0 1px 0 0; float: right; color: #333; text-align: right; font-size: 18px; position: relative; z-index: 10; } | ||
| 22 | +.template-wrap { position: absolute; top: 50%; left: 50%; -webkit-transform: translate(-50%, -50%); transform: translate(-50%, -50%); } | ||
| 23 | +.template-wrap canvas { margin: 0 0 10px 0; position: relative; z-index: 9; box-shadow: 0 10px 30px rgba(0,0,0,0.2); -moz-box-shadow: 0 10px 30px rgba(0,0,0,0.2); } | ||
| 24 | +.fullscreen { float: right; position: relative; z-index: 10; } | ||
| 25 | + | ||
| 26 | +body.template { } | ||
| 27 | +.template .template-wrap { } | ||
| 28 | +.template .template-wrap canvas { } |
| @@ -0,0 +1,39 @@ | @@ -0,0 +1,39 @@ | ||
| 1 | +// connect to canvas | ||
| 2 | + var Module = { | ||
| 3 | + filePackagePrefixURL: "Release/", | ||
| 4 | + memoryInitializerPrefixURL: "Release/", | ||
| 5 | + preRun: [], | ||
| 6 | + postRun: [], | ||
| 7 | + print: (function() { | ||
| 8 | + return function(text) { | ||
| 9 | + console.log (text); | ||
| 10 | + }; | ||
| 11 | + })(), | ||
| 12 | + printErr: function(text) { | ||
| 13 | + console.error (text); | ||
| 14 | + }, | ||
| 15 | + canvas: document.getElementById('canvas'), | ||
| 16 | + progress: null, | ||
| 17 | + setStatus: function(text) { | ||
| 18 | + if (this.progress == null) | ||
| 19 | + { | ||
| 20 | + if (typeof UnityProgress != 'function') | ||
| 21 | + return; | ||
| 22 | + this.progress = new UnityProgress (canvas); | ||
| 23 | + } | ||
| 24 | + if (!Module.setStatus.last) Module.setStatus.last = { time: Date.now(), text: '' }; | ||
| 25 | + if (text === Module.setStatus.text) return; | ||
| 26 | + this.progress.SetMessage (text); | ||
| 27 | + var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/); | ||
| 28 | + if (m) | ||
| 29 | + this.progress.SetProgress (parseInt(m[2])/parseInt(m[4])); | ||
| 30 | + if (text === "") | ||
| 31 | + this.progress.Clear() | ||
| 32 | + }, | ||
| 33 | + totalDependencies: 0, | ||
| 34 | + monitorRunDependencies: function(left) { | ||
| 35 | + this.totalDependencies = Math.max(this.totalDependencies, left); | ||
| 36 | + Module.setStatus(left ? 'Preparing... (' + (this.totalDependencies-left) + '/' + this.totalDependencies + ')' : 'All downloads complete.'); | ||
| 37 | + } | ||
| 38 | + }; | ||
| 39 | + Module.setStatus('Downloading (0.0/1)'); | ||
| 0 | \ No newline at end of file | 40 | \ No newline at end of file |
| @@ -0,0 +1,26 @@ | @@ -0,0 +1,26 @@ | ||
| 1 | +if (!(!Math.fround)) { | ||
| 2 | + var script = document.createElement('script'); | ||
| 3 | + script.src = "Release/VLibrasWebPlayer.js"; | ||
| 4 | + document.body.appendChild(script); | ||
| 5 | +} else { | ||
| 6 | + var codeXHR = new XMLHttpRequest(); | ||
| 7 | + codeXHR.open('GET', 'Release/VLibrasWebPlayer.js', true); | ||
| 8 | + codeXHR.onload = function() { | ||
| 9 | + var code = codeXHR.responseText; | ||
| 10 | + if (!Math.fround) { | ||
| 11 | +console.log('optimizing out Math.fround calls'); | ||
| 12 | +code = code.replace(/Math_fround\(/g, '(').replace("'use asm'", "'almost asm'") | ||
| 13 | + } | ||
| 14 | + | ||
| 15 | + var blob = new Blob([code], { type: 'text/javascript' }); | ||
| 16 | + codeXHR = null; | ||
| 17 | + var src = URL.createObjectURL(blob); | ||
| 18 | + var script = document.createElement('script'); | ||
| 19 | + script.src = URL.createObjectURL(blob); | ||
| 20 | + script.onload = function() { | ||
| 21 | + URL.revokeObjectURL(script.src); | ||
| 22 | + }; | ||
| 23 | + document.body.appendChild(script); | ||
| 24 | + }; | ||
| 25 | + codeXHR.send(null); | ||
| 26 | +} | ||
| 0 | \ No newline at end of file | 27 | \ No newline at end of file |
| @@ -0,0 +1,45 @@ | @@ -0,0 +1,45 @@ | ||
| 1 | +var app = { | ||
| 2 | + chooser: null, | ||
| 3 | + glosa: undefined, | ||
| 4 | + loaded: false, | ||
| 5 | + lastReq: { | ||
| 6 | + url: null, | ||
| 7 | + millis: null, | ||
| 8 | + response: null | ||
| 9 | + } | ||
| 10 | +}; | ||
| 11 | + | ||
| 12 | +function onLoadPlayer() { | ||
| 13 | + if ( app.glosa !== undefined ) { | ||
| 14 | + SendMessage('Avatar', 'catchGlosa', app.glosa); | ||
| 15 | + } | ||
| 16 | + | ||
| 17 | + app.loaded = true; | ||
| 18 | +} | ||
| 19 | + | ||
| 20 | +document.addEventListener('plugin:selectedText', function(e) { | ||
| 21 | + app.chooser = app.chooser || new qdClient.Chooser(); | ||
| 22 | + | ||
| 23 | + document.getElementById('loading-screen').style.display = 'block'; | ||
| 24 | + app.chooser.choose( | ||
| 25 | + app.lastReq.url, | ||
| 26 | + app.lastReq.millis, | ||
| 27 | + app.lastReq.response, | ||
| 28 | + function (url) { | ||
| 29 | + var start = new Date().getTime(); | ||
| 30 | + | ||
| 31 | + qdClient.request(url + '?texto=' + e.detail, "GET", {}, | ||
| 32 | + function(status, response) { | ||
| 33 | + app.lastReq.response = status === 404 ? -1 : status; | ||
| 34 | + app.lastReq.millis = (new Date().getTime() - start); | ||
| 35 | + app.lastReq.url = url; | ||
| 36 | + | ||
| 37 | + app.glosa = response; | ||
| 38 | + | ||
| 39 | + document.getElementById('loading-screen').style.display = 'none'; | ||
| 40 | + if (app.loaded == true) { | ||
| 41 | + SendMessage('Avatar', 'catchGlosa', app.glosa); | ||
| 42 | + } | ||
| 43 | + }); | ||
| 44 | + }); | ||
| 45 | +}); |
| @@ -0,0 +1,27 @@ | @@ -0,0 +1,27 @@ | ||
| 1 | +{ | ||
| 2 | + "name": "qdclient", | ||
| 3 | + "main": [ | ||
| 4 | + "qdclient.js" | ||
| 5 | + ], | ||
| 6 | + "ignore": [ | ||
| 7 | + "**/.*", | ||
| 8 | + "Gulpfile.js", | ||
| 9 | + "demo", | ||
| 10 | + "node_modules", | ||
| 11 | + "vendor", | ||
| 12 | + "tests" | ||
| 13 | + ], | ||
| 14 | + "devDependencies": { | ||
| 15 | + "mocha": "~2.2.5", | ||
| 16 | + "chai": "~3.0.0" | ||
| 17 | + }, | ||
| 18 | + "_release": "fab153cf1a", | ||
| 19 | + "_resolution": { | ||
| 20 | + "type": "branch", | ||
| 21 | + "branch": "master", | ||
| 22 | + "commit": "fab153cf1a708cab90a72e4654d65d654f11370e" | ||
| 23 | + }, | ||
| 24 | + "_source": "git@git.lavid.ufpb.br:qdclient.git", | ||
| 25 | + "_target": "*", | ||
| 26 | + "_originalSource": "git@git.lavid.ufpb.br:qdclient.git" | ||
| 27 | +} | ||
| 0 | \ No newline at end of file | 28 | \ No newline at end of file |
| @@ -0,0 +1,32 @@ | @@ -0,0 +1,32 @@ | ||
| 1 | +qdClient | ||
| 2 | +========= | ||
| 3 | + | ||
| 4 | +1. Tools | ||
| 5 | +---------------- | ||
| 6 | + | ||
| 7 | +1. NodeJS | ||
| 8 | +2. NPM - Node Package Manager | ||
| 9 | +3. Bower - Frontend dependencies | ||
| 10 | +4. Gulp - Build tools | ||
| 11 | + | ||
| 12 | +2. Installing dependencies | ||
| 13 | +---------------- | ||
| 14 | + | ||
| 15 | +```bash | ||
| 16 | +$ npm install | ||
| 17 | +$ bower install | ||
| 18 | +``` | ||
| 19 | + | ||
| 20 | +3. Demo | ||
| 21 | +---------------- | ||
| 22 | +```bash | ||
| 23 | +$ gulp demo | ||
| 24 | +``` | ||
| 25 | + | ||
| 26 | +4. Building | ||
| 27 | +---------------- | ||
| 28 | +```bash | ||
| 29 | +$ gulp build | ||
| 30 | +``` | ||
| 31 | + | ||
| 32 | +**Enjoy** |
| @@ -0,0 +1,19 @@ | @@ -0,0 +1,19 @@ | ||
| 1 | +{ | ||
| 2 | + "name": "qdclient", | ||
| 3 | + "version": "0.0.1", | ||
| 4 | + "main": [ | ||
| 5 | + "qdclient.js" | ||
| 6 | + ], | ||
| 7 | + "ignore": [ | ||
| 8 | + "**/.*", | ||
| 9 | + "Gulpfile.js", | ||
| 10 | + "demo", | ||
| 11 | + "node_modules", | ||
| 12 | + "vendor", | ||
| 13 | + "tests" | ||
| 14 | + ], | ||
| 15 | + "devDependencies": { | ||
| 16 | + "mocha": "~2.2.5", | ||
| 17 | + "chai": "~3.0.0" | ||
| 18 | + } | ||
| 19 | +} |
| @@ -0,0 +1,224 @@ | @@ -0,0 +1,224 @@ | ||
| 1 | +(function(window, localStorage, undefined) { | ||
| 2 | + 'use strict'; | ||
| 3 | + | ||
| 4 | + function Chooser() { | ||
| 5 | + this.server = 'http://150.165.204.39/vlibras-cloud/get_servers.php'; | ||
| 6 | + | ||
| 7 | + this.options = { | ||
| 8 | + THRESHOLDSLOW: 2000, | ||
| 9 | + SLOWLIMITTRIES: 5, | ||
| 10 | + NBESTHEURISTIC1: 2, | ||
| 11 | + QUANTITYPREVIOUSTIMESSTORED: 10 | ||
| 12 | + }; | ||
| 13 | + | ||
| 14 | + this.mirrors = []; | ||
| 15 | + | ||
| 16 | + this.heuristics = { | ||
| 17 | + FIRSTHEURISTIC: { | ||
| 18 | + FIRSTRANDOM : {value: 0, name: "Random"}, | ||
| 19 | + FIRSTRANDOMNBEST: {value: 1, name: "Random Among N Best"}, | ||
| 20 | + FIRSTBEST : {value: 2, name: "Best"} | ||
| 21 | + }, | ||
| 22 | + SECONDHEURISTIC: { | ||
| 23 | + SECONDRANDOM : {value: 0, name: "Random"}, | ||
| 24 | + SECONDCLOSEST: {value: 1, name: "Closest"} | ||
| 25 | + }, | ||
| 26 | + THIRDHEURISTIC: { | ||
| 27 | + THIRDSIMPLEAVERAGE : {value: 0, name: "Simple Average"}, | ||
| 28 | + THIRDWEIGHTEDAVERAGE: {value: 1, name: "Weighted Average"} | ||
| 29 | + } | ||
| 30 | + }; | ||
| 31 | + } | ||
| 32 | + | ||
| 33 | + // Exports | ||
| 34 | + qdClient.Chooser = Chooser; | ||
| 35 | + | ||
| 36 | + Chooser.prototype.choose = function(urlLast, millisLast, response, callback) { | ||
| 37 | + var $this = this; | ||
| 38 | + | ||
| 39 | + if (this.mirrors.length === 0) { | ||
| 40 | + this.loadMirrors_(function() { | ||
| 41 | + $this.chooseServer_(urlLast, millisLast, response, callback); | ||
| 42 | + }); | ||
| 43 | + } else { | ||
| 44 | + this.chooseServer_(urlLast, millisLast, response, callback); | ||
| 45 | + } | ||
| 46 | + }; | ||
| 47 | + | ||
| 48 | + Chooser.prototype.chooseServer_ = function(urlLast, millisLast, response, callback) { | ||
| 49 | + var firstHeuristic = this.heuristics.FIRSTHEURISTIC.FIRSTBEST; | ||
| 50 | + var secondHeuristic = this.heuristics.SECONDHEURISTIC.SECONDRANDOM; | ||
| 51 | + var thirdHeuristic = this.heuristics.THIRDHEURISTIC.THIRDWEIGHTEDAVERAGE; | ||
| 52 | + | ||
| 53 | + var j = 0, i = 0; /* Fix JSHint */ | ||
| 54 | + | ||
| 55 | + var sizeBest = this.options.NBESTHEURISTIC1; | ||
| 56 | + if (firstHeuristic == this.heuristics.FIRSTHEURISTIC.FIRSTBEST) { | ||
| 57 | + sizeBest = 1; | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + if (urlLast && urlLast.length > 0) { | ||
| 61 | + for (i = 0; i < this.mirrors.length; i++) { | ||
| 62 | + if (this.mirrors[i].url.toLowerCase() == urlLast.toLowerCase()) { | ||
| 63 | + if (this.mirrors[i].previousTimes.length < this.options.QUANTITYPREVIOUSTIMESSTORED) { | ||
| 64 | + this.mirrors[i].previousTimes[this.mirrors[i].previousTimes.length] = millisLast; | ||
| 65 | + | ||
| 66 | + } else { | ||
| 67 | + for (j = this.options.QUANTITYPREVIOUSTIMESSTORED-1; j > 0; j--) { | ||
| 68 | + this.mirrors[i].previousTimes[j-1] = this.mirrors[i].previousTimes[j]; | ||
| 69 | + } | ||
| 70 | + | ||
| 71 | + this.mirrors[i].previousTimes[this.options.QUANTITYPREVIOUSTIMESSTORED-1] = millisLast; | ||
| 72 | + | ||
| 73 | + } | ||
| 74 | + | ||
| 75 | + if (thirdHeuristic == this.heuristics.THIRDHEURISTIC.THIRDSIMPLEAVERAGE) { | ||
| 76 | + var totalMillis = 0; | ||
| 77 | + for (j = 0; j < this.mirrors[i].previousTimes.length; j++) { | ||
| 78 | + totalMillis += this.mirrors[i].previousTimes[j]; | ||
| 79 | + } | ||
| 80 | + | ||
| 81 | + this.mirrors[i].averageTime = totalMillis/this.mirrors[i].previousTimes.length; | ||
| 82 | + | ||
| 83 | + } else if (thirdHeuristic == this.heuristics.THIRDHEURISTIC.THIRDWEIGHTEDAVERAGE) { | ||
| 84 | + var totalMillisAndWeights = 0; | ||
| 85 | + var totalWeights = 0; | ||
| 86 | + for (j = 0; j < this.mirrors[i].previousTimes.length; j++) { | ||
| 87 | + totalMillisAndWeights += this.mirrors[i].previousTimes[j]*(j+1); | ||
| 88 | + totalWeights += (j+1); | ||
| 89 | + } | ||
| 90 | + | ||
| 91 | + this.mirrors[i].averageTime = totalMillisAndWeights/totalWeights; | ||
| 92 | + | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + if (millisLast > this.options.THRESHOLDSLOW || response == -1) { | ||
| 96 | + this.mirrors[i].isSlow = true; | ||
| 97 | + this.mirrors[i].remainingSlow = this.options.SLOWLIMITTRIES; | ||
| 98 | + } | ||
| 99 | + | ||
| 100 | + localStorage.setItem("servers", JSON.stringify(this.mirrors)); | ||
| 101 | + break; | ||
| 102 | + } | ||
| 103 | + | ||
| 104 | + } | ||
| 105 | + | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + var position = Math.floor((Math.random() * this.mirrors.length)); | ||
| 109 | + var closestPosition; | ||
| 110 | + | ||
| 111 | + if (firstHeuristic != this.heuristics.FIRSTHEURISTIC.FIRSTRANDOM) { | ||
| 112 | + position = -1; | ||
| 113 | + closestPosition = -1; | ||
| 114 | + } | ||
| 115 | + | ||
| 116 | + var vectorBest = []; | ||
| 117 | + var k = 0, z = 0; /* JSHint Fix */ | ||
| 118 | + | ||
| 119 | + for (j = 0; j < this.mirrors.length; j++) { | ||
| 120 | + if (this.mirrors[j].remainingSlow > 0) { | ||
| 121 | + this.mirrors[j].remainingSlow = this.mirrors[j].remainingSlow - 1; | ||
| 122 | + } | ||
| 123 | + | ||
| 124 | + if (this.mirrors[j].remainingSlow === 0) { | ||
| 125 | + this.mirrors[j].isSlow = false; | ||
| 126 | + } | ||
| 127 | + | ||
| 128 | + if (firstHeuristic != this.heuristics.FIRSTHEURISTIC.FIRSTRANDOM && this.mirrors[j].isSlow === false) { | ||
| 129 | + if (closestPosition == -1) { | ||
| 130 | + closestPosition = j; | ||
| 131 | + } | ||
| 132 | + | ||
| 133 | + var added = false; | ||
| 134 | + | ||
| 135 | + for (k = 0; k < vectorBest.length; k++) { | ||
| 136 | + if (this.mirrors[j].averageTime < vectorBest[k].averageTime || (this.mirrors[j].averageTime == vectorBest[k].averageTime && (Math.floor(Math.random()) < 0.5) )) { | ||
| 137 | + | ||
| 138 | + added = true; | ||
| 139 | + | ||
| 140 | + if (vectorBest.length < sizeBest) { | ||
| 141 | + for (z = vectorBest.length-1; z >= k; z--) { | ||
| 142 | + vectorBest[z+1] = vectorBest[z]; | ||
| 143 | + } | ||
| 144 | + } else { | ||
| 145 | + for (z = vectorBest.length-2; z >= k; z--) { | ||
| 146 | + vectorBest[z+1] = vectorBest[z]; | ||
| 147 | + } | ||
| 148 | + } | ||
| 149 | + | ||
| 150 | + vectorBest[k] = this.mirrors[j]; | ||
| 151 | + | ||
| 152 | + break; | ||
| 153 | + } | ||
| 154 | + } | ||
| 155 | + | ||
| 156 | + if (added === false && vectorBest.length < sizeBest) { | ||
| 157 | + vectorBest[vectorBest.length] = this.mirrors[j]; | ||
| 158 | + } | ||
| 159 | + | ||
| 160 | + } | ||
| 161 | + | ||
| 162 | + } | ||
| 163 | + | ||
| 164 | + // pega aleatorio entre as N posicoes dos melhores (se for guloso, tera apenas um elemento no vetor) | ||
| 165 | + if (firstHeuristic != this.heuristics.FIRSTHEURISTIC.FIRSTRANDOM && vectorBest.length > 0) { | ||
| 166 | + position = Math.floor((Math.random() * vectorBest.length)); | ||
| 167 | + } | ||
| 168 | + | ||
| 169 | + if (position == -1) { | ||
| 170 | + if (secondHeuristic == this.heuristics.SECONDHEURISTIC.SECONDCLOSEST) { | ||
| 171 | + // escolhendo o mais proximo, no caso, o vetor já está ordenado | ||
| 172 | + if (closestPosition != -1) { | ||
| 173 | + position = closestPosition; | ||
| 174 | + } else { | ||
| 175 | + // se nao marcou nenhum como closest, todos devem estar como slow, nesse caso seleciona o primeiro que é o mais próximo | ||
| 176 | + position = 0; | ||
| 177 | + } | ||
| 178 | + | ||
| 179 | + } else { | ||
| 180 | + position = Math.floor((Math.random() * this.mirrors.length)); | ||
| 181 | + } | ||
| 182 | + } | ||
| 183 | + | ||
| 184 | + callback(this.mirrors[position].url); | ||
| 185 | + }; | ||
| 186 | + | ||
| 187 | + Chooser.prototype.loadMirrors_ = function(callback) { | ||
| 188 | + var $this = this; | ||
| 189 | + | ||
| 190 | + var localServers = JSON.parse(localStorage.getItem("servers")) || []; | ||
| 191 | + | ||
| 192 | + qdClient.getJSON(this.server, function (status, response) { | ||
| 193 | + var servers = status === 200 ? response : []; | ||
| 194 | + | ||
| 195 | + for (var i = 0; i < servers.length; i++){ | ||
| 196 | + var mirror = { | ||
| 197 | + name: servers[i].nome, | ||
| 198 | + url: servers[i].url, | ||
| 199 | + averageTime: 99999999, | ||
| 200 | + isSlow: false, | ||
| 201 | + previousTimes: [], | ||
| 202 | + remainingSlow: 0, | ||
| 203 | + type: servers[i].type | ||
| 204 | + }; | ||
| 205 | + | ||
| 206 | + for (var localServer in localServers) { | ||
| 207 | + if (mirror.url == localServer.url) { | ||
| 208 | + mirror.averageTime = localServer.averageTime; | ||
| 209 | + mirror.isSlow = localServer.isSlow; | ||
| 210 | + mirror.previousTimes = localServer.previousTimes; | ||
| 211 | + mirror.remainingSlow = localServer.remainingSlow; | ||
| 212 | + | ||
| 213 | + break; | ||
| 214 | + } | ||
| 215 | + } | ||
| 216 | + | ||
| 217 | + $this.mirrors.push(mirror); | ||
| 218 | + } | ||
| 219 | + | ||
| 220 | + if (callback instanceof Function) callback(); | ||
| 221 | + }); | ||
| 222 | + }; | ||
| 223 | + | ||
| 224 | +}(window, localStorage)); |
| @@ -0,0 +1,34 @@ | @@ -0,0 +1,34 @@ | ||
| 1 | +(function(window, undefined) { | ||
| 2 | + 'use strict'; | ||
| 3 | + | ||
| 4 | + window.qdClient = window.qdClient || {}; | ||
| 5 | + | ||
| 6 | + qdClient.request = function request(url, method, params, callback) { | ||
| 7 | + var xhr = new XMLHttpRequest(); | ||
| 8 | + var raw_params = ""; | ||
| 9 | + | ||
| 10 | + xhr.open(method, url, true); | ||
| 11 | + | ||
| 12 | + xhr.onload = function() { | ||
| 13 | + callback(xhr.status, xhr.responseText); | ||
| 14 | + }; | ||
| 15 | + | ||
| 16 | + if (method == "POST" && params instanceof Object) { | ||
| 17 | + | ||
| 18 | + for(var param in params) { | ||
| 19 | + raw_params += param + '=' + params[param] + '&'; | ||
| 20 | + } | ||
| 21 | + | ||
| 22 | + if (params.length > 1) raw_params.slice(0, -1); | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + xhr.send(raw_params); | ||
| 26 | + }; | ||
| 27 | + | ||
| 28 | + qdClient.getJSON = function getJSON(url, callback) { | ||
| 29 | + qdClient.request(url, "GET", {}, function(status, response) { | ||
| 30 | + callback(status, JSON.parse(response)); | ||
| 31 | + }); | ||
| 32 | + }; | ||
| 33 | + | ||
| 34 | +}(window)); |
| @@ -0,0 +1,209 @@ | @@ -0,0 +1,209 @@ | ||
| 1 | +var THRESHOLDSLOW = 2000; | ||
| 2 | +var SLOWLIMITTRIES = 5; | ||
| 3 | +var NBESTHEURISTIC1 = 2; | ||
| 4 | +var QUANTITYPREVIOUSTIMESSTORED = 10; | ||
| 5 | + | ||
| 6 | +var mirrors = []; | ||
| 7 | + | ||
| 8 | +var FIRSTHEURISTIC = { | ||
| 9 | + FIRSTRANDOM : {value: 0, name: "Random"}, | ||
| 10 | + FIRSTRANDOMNBEST: {value: 1, name: "Random Among N Best"}, | ||
| 11 | + FIRSTBEST : {value: 2, name: "Best"} | ||
| 12 | +}; | ||
| 13 | + | ||
| 14 | +var SECONDHEURISTIC = { | ||
| 15 | + SECONDRANDOM : {value: 0, name: "Random"}, | ||
| 16 | + SECONDCLOSEST: {value: 1, name: "Closest"} | ||
| 17 | +}; | ||
| 18 | + | ||
| 19 | +var THIRDHEURISTIC = { | ||
| 20 | + THIRDSIMPLEAVERAGE : {value: 0, name: "Simple Average"}, | ||
| 21 | + THIRDWEIGHTEDAVERAGE: {value: 1, name: "Weighted Average"} | ||
| 22 | +}; | ||
| 23 | + | ||
| 24 | +function httpGet(theUrl){ | ||
| 25 | + var xmlHttp = null; | ||
| 26 | + xmlHttp = new XMLHttpRequest(); | ||
| 27 | + xmlHttp.open( "GET", theUrl, false ); | ||
| 28 | + xmlHttp.send( null ); | ||
| 29 | + return JSON.parse(xmlHttp.responseText); | ||
| 30 | +} | ||
| 31 | + | ||
| 32 | + | ||
| 33 | + | ||
| 34 | +function loadMirrors() { | ||
| 35 | + var localServersArray = JSON.parse(localStorage.getItem("serversDatabase")); | ||
| 36 | + if(localServersArray == null){ | ||
| 37 | + localServersArray = []; | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + var servers = httpGet('http://fuze.cc/sobreApps/teste_lavid/get_servers.php'); | ||
| 41 | + for (var i = 0; i < servers.length; i++){ | ||
| 42 | + var mirror = {}; | ||
| 43 | + mirror.name = servers[i].nome; | ||
| 44 | + mirror.url = servers[i].url; | ||
| 45 | + mirror.averageTime = 99999999; | ||
| 46 | + mirror.isSlow = false; | ||
| 47 | + mirror.previousTimes = []; | ||
| 48 | + mirror.remainingSlow = 0; | ||
| 49 | + mirror.type = servers[i].type; | ||
| 50 | + | ||
| 51 | + for (var j = 0; j < localServersArray.length; j++) { | ||
| 52 | + if (mirror.url == localServersArray[j].url) { | ||
| 53 | + mirror.averageTime = localServersArray[j].averageTime; | ||
| 54 | + mirror.isSlow = localServersArray[j].isSlow; | ||
| 55 | + mirror.previousTimes = localServersArray[j].previousTimes; | ||
| 56 | + mirror.remainingSlow = localServersArray[j].remainingSlow; | ||
| 57 | + | ||
| 58 | + break; | ||
| 59 | + } | ||
| 60 | + } | ||
| 61 | + | ||
| 62 | + mirrors.push(mirror); | ||
| 63 | + } | ||
| 64 | + | ||
| 65 | +} | ||
| 66 | + | ||
| 67 | +function chooseServer(urlLast, millisLast, response) { | ||
| 68 | + if (mirrors.length == 0) { | ||
| 69 | + loadMirrors(); | ||
| 70 | + } | ||
| 71 | + | ||
| 72 | + if (mirrors.length == 0) { | ||
| 73 | + alert("Sem mirrors disponíveis"); | ||
| 74 | + } | ||
| 75 | + | ||
| 76 | + var firstHeuristic = FIRSTHEURISTIC.FIRSTBEST; | ||
| 77 | + var secondHeuristic = SECONDHEURISTIC.SECONDRANDOM; | ||
| 78 | + var thirdHeuristic = THIRDHEURISTIC.THIRDWEIGHTEDAVERAGE; | ||
| 79 | + | ||
| 80 | + var sizeBest = NBESTHEURISTIC1; | ||
| 81 | + if (firstHeuristic == FIRSTHEURISTIC.FIRSTBEST) { | ||
| 82 | + sizeBest = 1; | ||
| 83 | + } | ||
| 84 | + | ||
| 85 | + if (urlLast.length > 0) { | ||
| 86 | + for (var i = 0; i < mirrors.length; i++) { | ||
| 87 | + if (mirrors[i].url.toLowerCase() == urlLast.toLowerCase()) { | ||
| 88 | + if (mirrors[i].previousTimes.length < QUANTITYPREVIOUSTIMESSTORED) { | ||
| 89 | + mirrors[i].previousTimes[mirrors[i].previousTimes.length] = millisLast; | ||
| 90 | + | ||
| 91 | + } else { | ||
| 92 | + for (var j = QUANTITYPREVIOUSTIMESSTORED-1; j > 0; j--) { | ||
| 93 | + mirrors[i].previousTimes[j-1] = mirrors[i].previousTimes[j]; | ||
| 94 | + } | ||
| 95 | + | ||
| 96 | + mirrors[i].previousTimes[QUANTITYPREVIOUSTIMESSTORED-1] = millisLast; | ||
| 97 | + | ||
| 98 | + } | ||
| 99 | + | ||
| 100 | + if (thirdHeuristic == THIRDHEURISTIC.THIRDSIMPLEAVERAGE) { | ||
| 101 | + var totalMillis = 0; | ||
| 102 | + for (var j = 0; j < mirrors[i].previousTimes.length; j++) { | ||
| 103 | + totalMillis += mirrors[i].previousTimes[j]; | ||
| 104 | + } | ||
| 105 | + | ||
| 106 | + mirrors[i].averageTime = totalMillis/mirrors[i].previousTimes.length; | ||
| 107 | + | ||
| 108 | + } else if (thirdHeuristic == THIRDHEURISTIC.THIRDWEIGHTEDAVERAGE) { | ||
| 109 | + var totalMillisAndWeights = 0; | ||
| 110 | + var totalWeights = 0; | ||
| 111 | + for (var j = 0; j < mirrors[i].previousTimes.length; j++) { | ||
| 112 | + totalMillisAndWeights += mirrors[i].previousTimes[j]*(j+1); | ||
| 113 | + totalWeights += (j+1); | ||
| 114 | + } | ||
| 115 | + | ||
| 116 | + mirrors[i].averageTime = totalMillisAndWeights/totalWeights; | ||
| 117 | + | ||
| 118 | + } | ||
| 119 | + | ||
| 120 | + if (millisLast > THRESHOLDSLOW || response == "-1") { | ||
| 121 | + mirrors[i].isSlow = true; | ||
| 122 | + mirrors[i].remainingSlow = SLOWLIMITTRIES; | ||
| 123 | + } | ||
| 124 | + | ||
| 125 | + localStorage.setItem("serversDatabase", JSON.stringify(mirrors)); | ||
| 126 | + break; | ||
| 127 | + } | ||
| 128 | + | ||
| 129 | + } | ||
| 130 | + | ||
| 131 | + } | ||
| 132 | + | ||
| 133 | + var position = Math.floor((Math.random() * mirrors.length)); | ||
| 134 | + var closestPosition; | ||
| 135 | + | ||
| 136 | + if (firstHeuristic != FIRSTHEURISTIC.FIRSTRANDOM) { | ||
| 137 | + position = -1; | ||
| 138 | + closestPosition = -1; | ||
| 139 | + } | ||
| 140 | + | ||
| 141 | + var vectorBest = []; | ||
| 142 | + | ||
| 143 | + for (var j = 0; j < mirrors.length; j++) { | ||
| 144 | + if (mirrors[j].remainingSlow > 0) { | ||
| 145 | + mirrors[j].remainingSlow = mirrors[j].remainingSlow - 1; | ||
| 146 | + } | ||
| 147 | + | ||
| 148 | + if (mirrors[j].remainingSlow == 0) { | ||
| 149 | + mirrors[j].isSlow = false; | ||
| 150 | + } | ||
| 151 | + | ||
| 152 | + if (firstHeuristic != FIRSTHEURISTIC.FIRSTRANDOM && mirrors[j].isSlow == false) { | ||
| 153 | + if (closestPosition == -1) { | ||
| 154 | + closestPosition = j; | ||
| 155 | + } | ||
| 156 | + | ||
| 157 | + var added = false; | ||
| 158 | + | ||
| 159 | + for (var k = 0; k < vectorBest.length; k++) { | ||
| 160 | + if (mirrors[j].averageTime < vectorBest[k].averageTime || (mirrors[j].averageTime == vectorBest[k].averageTime && (Math.floor(Math.random()) < 0.5) )) { | ||
| 161 | + | ||
| 162 | + added = true; | ||
| 163 | + | ||
| 164 | + if (vectorBest.length < sizeBest) { | ||
| 165 | + for (var z = vectorBest.length-1; z >= k; z--) { | ||
| 166 | + vectorBest[z+1] = vectorBest[z]; | ||
| 167 | + } | ||
| 168 | + } else { | ||
| 169 | + for (var z = vectorBest.length-2; z >= k; z--) { | ||
| 170 | + vectorBest[z+1] = vectorBest[z]; | ||
| 171 | + } | ||
| 172 | + } | ||
| 173 | + | ||
| 174 | + vectorBest[k] = mirrors[j]; | ||
| 175 | + | ||
| 176 | + break; | ||
| 177 | + } | ||
| 178 | + } | ||
| 179 | + | ||
| 180 | + if (added == false && vectorBest.length < sizeBest) { | ||
| 181 | + vectorBest[vectorBest.length] = mirrors[j]; | ||
| 182 | + } | ||
| 183 | + | ||
| 184 | + } | ||
| 185 | + | ||
| 186 | + } | ||
| 187 | + | ||
| 188 | + // pega aleatorio entre as N posicoes dos melhores (se for guloso, tera apenas um elemento no vetor) | ||
| 189 | + if (firstHeuristic != FIRSTHEURISTIC.FIRSTRANDOM && vectorBest.length > 0) { | ||
| 190 | + position = Math.floor((Math.random() * vectorBest.length)); | ||
| 191 | + } | ||
| 192 | + | ||
| 193 | + if (position == -1) { | ||
| 194 | + if (secondHeuristic == SECONDHEURISTIC.SECONDCLOSEST) { | ||
| 195 | + // escolhendo o mais proximo, no caso, o vetor já está ordenado | ||
| 196 | + if (closestPosition != -1) { | ||
| 197 | + position = closestPosition; | ||
| 198 | + } else { | ||
| 199 | + // se nao marcou nenhum como closest, todos devem estar como slow, nesse caso seleciona o primeiro que é o mais próximo | ||
| 200 | + position = 0; | ||
| 201 | + } | ||
| 202 | + | ||
| 203 | + } else { | ||
| 204 | + position = Math.floor((Math.random() * mirrors.length)); | ||
| 205 | + } | ||
| 206 | + } | ||
| 207 | + | ||
| 208 | + return mirrors[position].url; | ||
| 209 | +} |
| @@ -0,0 +1,18 @@ | @@ -0,0 +1,18 @@ | ||
| 1 | +{ | ||
| 2 | + "name": "qdclient", | ||
| 3 | + "version": "0.0.1", | ||
| 4 | + "description": "", | ||
| 5 | + "scripts": { | ||
| 6 | + "test": "echo \"Error: no test specified\" && exit 1" | ||
| 7 | + }, | ||
| 8 | + "devDependencies": { | ||
| 9 | + "browser-sync": "^2.7.13", | ||
| 10 | + "gulp": "^3.9.0", | ||
| 11 | + "gulp-concat": "^2.6.0", | ||
| 12 | + "gulp-jshint": "^1.11.2", | ||
| 13 | + "gulp-rename": "^1.2.2", | ||
| 14 | + "gulp-rimraf": "^0.1.1", | ||
| 15 | + "gulp-uglify": "^1.2.0", | ||
| 16 | + "run-sequence": "^1.1.1" | ||
| 17 | + } | ||
| 18 | +} |
| @@ -0,0 +1,259 @@ | @@ -0,0 +1,259 @@ | ||
| 1 | +(function(window, undefined) { | ||
| 2 | + 'use strict'; | ||
| 3 | + | ||
| 4 | + window.qdClient = window.qdClient || {}; | ||
| 5 | + | ||
| 6 | + qdClient.request = function request(url, method, params, callback) { | ||
| 7 | + var xhr = new XMLHttpRequest(); | ||
| 8 | + var raw_params = ""; | ||
| 9 | + | ||
| 10 | + xhr.open(method, url, true); | ||
| 11 | + | ||
| 12 | + xhr.onload = function() { | ||
| 13 | + callback(xhr.status, xhr.responseText); | ||
| 14 | + }; | ||
| 15 | + | ||
| 16 | + if (method == "POST" && params instanceof Object) { | ||
| 17 | + | ||
| 18 | + for(var param in params) { | ||
| 19 | + raw_params += param + '=' + params[param] + '&'; | ||
| 20 | + } | ||
| 21 | + | ||
| 22 | + if (params.length > 1) raw_params.slice(0, -1); | ||
| 23 | + } | ||
| 24 | + | ||
| 25 | + xhr.send(raw_params); | ||
| 26 | + }; | ||
| 27 | + | ||
| 28 | + qdClient.getJSON = function getJSON(url, callback) { | ||
| 29 | + qdClient.request(url, "GET", {}, function(status, response) { | ||
| 30 | + callback(status, JSON.parse(response)); | ||
| 31 | + }); | ||
| 32 | + }; | ||
| 33 | + | ||
| 34 | +}(window)); | ||
| 35 | + | ||
| 36 | +(function(window, localStorage, undefined) { | ||
| 37 | + 'use strict'; | ||
| 38 | + | ||
| 39 | + function Chooser() { | ||
| 40 | + this.server = 'http://150.165.204.39/vlibras-cloud/get_servers.php'; | ||
| 41 | + | ||
| 42 | + this.options = { | ||
| 43 | + THRESHOLDSLOW: 2000, | ||
| 44 | + SLOWLIMITTRIES: 5, | ||
| 45 | + NBESTHEURISTIC1: 2, | ||
| 46 | + QUANTITYPREVIOUSTIMESSTORED: 10 | ||
| 47 | + }; | ||
| 48 | + | ||
| 49 | + this.mirrors = []; | ||
| 50 | + | ||
| 51 | + this.heuristics = { | ||
| 52 | + FIRSTHEURISTIC: { | ||
| 53 | + FIRSTRANDOM : {value: 0, name: "Random"}, | ||
| 54 | + FIRSTRANDOMNBEST: {value: 1, name: "Random Among N Best"}, | ||
| 55 | + FIRSTBEST : {value: 2, name: "Best"} | ||
| 56 | + }, | ||
| 57 | + SECONDHEURISTIC: { | ||
| 58 | + SECONDRANDOM : {value: 0, name: "Random"}, | ||
| 59 | + SECONDCLOSEST: {value: 1, name: "Closest"} | ||
| 60 | + }, | ||
| 61 | + THIRDHEURISTIC: { | ||
| 62 | + THIRDSIMPLEAVERAGE : {value: 0, name: "Simple Average"}, | ||
| 63 | + THIRDWEIGHTEDAVERAGE: {value: 1, name: "Weighted Average"} | ||
| 64 | + } | ||
| 65 | + }; | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + // Exports | ||
| 69 | + qdClient.Chooser = Chooser; | ||
| 70 | + | ||
| 71 | + Chooser.prototype.choose = function(urlLast, millisLast, response, callback) { | ||
| 72 | + var $this = this; | ||
| 73 | + | ||
| 74 | + if (this.mirrors.length === 0) { | ||
| 75 | + this.loadMirrors_(function() { | ||
| 76 | + $this.chooseServer_(urlLast, millisLast, response, callback); | ||
| 77 | + }); | ||
| 78 | + } else { | ||
| 79 | + this.chooseServer_(urlLast, millisLast, response, callback); | ||
| 80 | + } | ||
| 81 | + }; | ||
| 82 | + | ||
| 83 | + Chooser.prototype.chooseServer_ = function(urlLast, millisLast, response, callback) { | ||
| 84 | + var firstHeuristic = this.heuristics.FIRSTHEURISTIC.FIRSTBEST; | ||
| 85 | + var secondHeuristic = this.heuristics.SECONDHEURISTIC.SECONDRANDOM; | ||
| 86 | + var thirdHeuristic = this.heuristics.THIRDHEURISTIC.THIRDWEIGHTEDAVERAGE; | ||
| 87 | + | ||
| 88 | + var j = 0, i = 0; /* Fix JSHint */ | ||
| 89 | + | ||
| 90 | + var sizeBest = this.options.NBESTHEURISTIC1; | ||
| 91 | + if (firstHeuristic == this.heuristics.FIRSTHEURISTIC.FIRSTBEST) { | ||
| 92 | + sizeBest = 1; | ||
| 93 | + } | ||
| 94 | + | ||
| 95 | + if (urlLast && urlLast.length > 0) { | ||
| 96 | + for (i = 0; i < this.mirrors.length; i++) { | ||
| 97 | + if (this.mirrors[i].url.toLowerCase() == urlLast.toLowerCase()) { | ||
| 98 | + if (this.mirrors[i].previousTimes.length < this.options.QUANTITYPREVIOUSTIMESSTORED) { | ||
| 99 | + this.mirrors[i].previousTimes[this.mirrors[i].previousTimes.length] = millisLast; | ||
| 100 | + | ||
| 101 | + } else { | ||
| 102 | + for (j = this.options.QUANTITYPREVIOUSTIMESSTORED-1; j > 0; j--) { | ||
| 103 | + this.mirrors[i].previousTimes[j-1] = this.mirrors[i].previousTimes[j]; | ||
| 104 | + } | ||
| 105 | + | ||
| 106 | + this.mirrors[i].previousTimes[this.options.QUANTITYPREVIOUSTIMESSTORED-1] = millisLast; | ||
| 107 | + | ||
| 108 | + } | ||
| 109 | + | ||
| 110 | + if (thirdHeuristic == this.heuristics.THIRDHEURISTIC.THIRDSIMPLEAVERAGE) { | ||
| 111 | + var totalMillis = 0; | ||
| 112 | + for (j = 0; j < this.mirrors[i].previousTimes.length; j++) { | ||
| 113 | + totalMillis += this.mirrors[i].previousTimes[j]; | ||
| 114 | + } | ||
| 115 | + | ||
| 116 | + this.mirrors[i].averageTime = totalMillis/this.mirrors[i].previousTimes.length; | ||
| 117 | + | ||
| 118 | + } else if (thirdHeuristic == this.heuristics.THIRDHEURISTIC.THIRDWEIGHTEDAVERAGE) { | ||
| 119 | + var totalMillisAndWeights = 0; | ||
| 120 | + var totalWeights = 0; | ||
| 121 | + for (j = 0; j < this.mirrors[i].previousTimes.length; j++) { | ||
| 122 | + totalMillisAndWeights += this.mirrors[i].previousTimes[j]*(j+1); | ||
| 123 | + totalWeights += (j+1); | ||
| 124 | + } | ||
| 125 | + | ||
| 126 | + this.mirrors[i].averageTime = totalMillisAndWeights/totalWeights; | ||
| 127 | + | ||
| 128 | + } | ||
| 129 | + | ||
| 130 | + if (millisLast > this.options.THRESHOLDSLOW || response == -1) { | ||
| 131 | + this.mirrors[i].isSlow = true; | ||
| 132 | + this.mirrors[i].remainingSlow = this.options.SLOWLIMITTRIES; | ||
| 133 | + } | ||
| 134 | + | ||
| 135 | + localStorage.setItem("servers", JSON.stringify(this.mirrors)); | ||
| 136 | + break; | ||
| 137 | + } | ||
| 138 | + | ||
| 139 | + } | ||
| 140 | + | ||
| 141 | + } | ||
| 142 | + | ||
| 143 | + var position = Math.floor((Math.random() * this.mirrors.length)); | ||
| 144 | + var closestPosition; | ||
| 145 | + | ||
| 146 | + if (firstHeuristic != this.heuristics.FIRSTHEURISTIC.FIRSTRANDOM) { | ||
| 147 | + position = -1; | ||
| 148 | + closestPosition = -1; | ||
| 149 | + } | ||
| 150 | + | ||
| 151 | + var vectorBest = []; | ||
| 152 | + var k = 0, z = 0; /* JSHint Fix */ | ||
| 153 | + | ||
| 154 | + for (j = 0; j < this.mirrors.length; j++) { | ||
| 155 | + if (this.mirrors[j].remainingSlow > 0) { | ||
| 156 | + this.mirrors[j].remainingSlow = this.mirrors[j].remainingSlow - 1; | ||
| 157 | + } | ||
| 158 | + | ||
| 159 | + if (this.mirrors[j].remainingSlow === 0) { | ||
| 160 | + this.mirrors[j].isSlow = false; | ||
| 161 | + } | ||
| 162 | + | ||
| 163 | + if (firstHeuristic != this.heuristics.FIRSTHEURISTIC.FIRSTRANDOM && this.mirrors[j].isSlow === false) { | ||
| 164 | + if (closestPosition == -1) { | ||
| 165 | + closestPosition = j; | ||
| 166 | + } | ||
| 167 | + | ||
| 168 | + var added = false; | ||
| 169 | + | ||
| 170 | + for (k = 0; k < vectorBest.length; k++) { | ||
| 171 | + if (this.mirrors[j].averageTime < vectorBest[k].averageTime || (this.mirrors[j].averageTime == vectorBest[k].averageTime && (Math.floor(Math.random()) < 0.5) )) { | ||
| 172 | + | ||
| 173 | + added = true; | ||
| 174 | + | ||
| 175 | + if (vectorBest.length < sizeBest) { | ||
| 176 | + for (z = vectorBest.length-1; z >= k; z--) { | ||
| 177 | + vectorBest[z+1] = vectorBest[z]; | ||
| 178 | + } | ||
| 179 | + } else { | ||
| 180 | + for (z = vectorBest.length-2; z >= k; z--) { | ||
| 181 | + vectorBest[z+1] = vectorBest[z]; | ||
| 182 | + } | ||
| 183 | + } | ||
| 184 | + | ||
| 185 | + vectorBest[k] = this.mirrors[j]; | ||
| 186 | + | ||
| 187 | + break; | ||
| 188 | + } | ||
| 189 | + } | ||
| 190 | + | ||
| 191 | + if (added === false && vectorBest.length < sizeBest) { | ||
| 192 | + vectorBest[vectorBest.length] = this.mirrors[j]; | ||
| 193 | + } | ||
| 194 | + | ||
| 195 | + } | ||
| 196 | + | ||
| 197 | + } | ||
| 198 | + | ||
| 199 | + // pega aleatorio entre as N posicoes dos melhores (se for guloso, tera apenas um elemento no vetor) | ||
| 200 | + if (firstHeuristic != this.heuristics.FIRSTHEURISTIC.FIRSTRANDOM && vectorBest.length > 0) { | ||
| 201 | + position = Math.floor((Math.random() * vectorBest.length)); | ||
| 202 | + } | ||
| 203 | + | ||
| 204 | + if (position == -1) { | ||
| 205 | + if (secondHeuristic == this.heuristics.SECONDHEURISTIC.SECONDCLOSEST) { | ||
| 206 | + // escolhendo o mais proximo, no caso, o vetor já está ordenado | ||
| 207 | + if (closestPosition != -1) { | ||
| 208 | + position = closestPosition; | ||
| 209 | + } else { | ||
| 210 | + // se nao marcou nenhum como closest, todos devem estar como slow, nesse caso seleciona o primeiro que é o mais próximo | ||
| 211 | + position = 0; | ||
| 212 | + } | ||
| 213 | + | ||
| 214 | + } else { | ||
| 215 | + position = Math.floor((Math.random() * this.mirrors.length)); | ||
| 216 | + } | ||
| 217 | + } | ||
| 218 | + | ||
| 219 | + callback(this.mirrors[position].url); | ||
| 220 | + }; | ||
| 221 | + | ||
| 222 | + Chooser.prototype.loadMirrors_ = function(callback) { | ||
| 223 | + var $this = this; | ||
| 224 | + | ||
| 225 | + var localServers = JSON.parse(localStorage.getItem("servers")) || []; | ||
| 226 | + | ||
| 227 | + qdClient.getJSON(this.server, function (status, response) { | ||
| 228 | + var servers = status === 200 ? response : []; | ||
| 229 | + | ||
| 230 | + for (var i = 0; i < servers.length; i++){ | ||
| 231 | + var mirror = { | ||
| 232 | + name: servers[i].nome, | ||
| 233 | + url: servers[i].url, | ||
| 234 | + averageTime: 99999999, | ||
| 235 | + isSlow: false, | ||
| 236 | + previousTimes: [], | ||
| 237 | + remainingSlow: 0, | ||
| 238 | + type: servers[i].type | ||
| 239 | + }; | ||
| 240 | + | ||
| 241 | + for (var localServer in localServers) { | ||
| 242 | + if (mirror.url == localServer.url) { | ||
| 243 | + mirror.averageTime = localServer.averageTime; | ||
| 244 | + mirror.isSlow = localServer.isSlow; | ||
| 245 | + mirror.previousTimes = localServer.previousTimes; | ||
| 246 | + mirror.remainingSlow = localServer.remainingSlow; | ||
| 247 | + | ||
| 248 | + break; | ||
| 249 | + } | ||
| 250 | + } | ||
| 251 | + | ||
| 252 | + $this.mirrors.push(mirror); | ||
| 253 | + } | ||
| 254 | + | ||
| 255 | + if (callback instanceof Function) callback(); | ||
| 256 | + }); | ||
| 257 | + }; | ||
| 258 | + | ||
| 259 | +}(window, localStorage)); |
| @@ -0,0 +1 @@ | @@ -0,0 +1 @@ | ||
| 1 | +!function(r,i){"use strict";r.qdClient=r.qdClient||{},qdClient.request=function(r,i,s,e){var t=new XMLHttpRequest,o="";if(t.open(i,r,!0),t.onload=function(){e(t.status,t.responseText)},"POST"==i&&s instanceof Object){for(var n in s)o+=n+"="+s[n]+"&";s.length>1&&o.slice(0,-1)}t.send(o)},qdClient.getJSON=function(r,i){qdClient.request(r,"GET",{},function(r,s){i(r,JSON.parse(s))})}}(window),function(r,i,s){"use strict";function e(){this.server="http://150.165.204.39/vlibras-cloud/get_servers.php",this.options={THRESHOLDSLOW:2e3,SLOWLIMITTRIES:5,NBESTHEURISTIC1:2,QUANTITYPREVIOUSTIMESSTORED:10},this.mirrors=[],this.heuristics={FIRSTHEURISTIC:{FIRSTRANDOM:{value:0,name:"Random"},FIRSTRANDOMNBEST:{value:1,name:"Random Among N Best"},FIRSTBEST:{value:2,name:"Best"}},SECONDHEURISTIC:{SECONDRANDOM:{value:0,name:"Random"},SECONDCLOSEST:{value:1,name:"Closest"}},THIRDHEURISTIC:{THIRDSIMPLEAVERAGE:{value:0,name:"Simple Average"},THIRDWEIGHTEDAVERAGE:{value:1,name:"Weighted Average"}}}}qdClient.Chooser=e,e.prototype.choose=function(r,i,s,e){var t=this;0===this.mirrors.length?this.loadMirrors_(function(){t.chooseServer_(r,i,s,e)}):this.chooseServer_(r,i,s,e)},e.prototype.chooseServer_=function(r,s,e,t){var o=this.heuristics.FIRSTHEURISTIC.FIRSTBEST,n=this.heuristics.SECONDHEURISTIC.SECONDRANDOM,h=this.heuristics.THIRDHEURISTIC.THIRDWEIGHTEDAVERAGE,T=0,S=0,a=this.options.NBESTHEURISTIC1;if(o==this.heuristics.FIRSTHEURISTIC.FIRSTBEST&&(a=1),r&&r.length>0)for(S=0;S<this.mirrors.length;S++)if(this.mirrors[S].url.toLowerCase()==r.toLowerCase()){if(this.mirrors[S].previousTimes.length<this.options.QUANTITYPREVIOUSTIMESSTORED)this.mirrors[S].previousTimes[this.mirrors[S].previousTimes.length]=s;else{for(T=this.options.QUANTITYPREVIOUSTIMESSTORED-1;T>0;T--)this.mirrors[S].previousTimes[T-1]=this.mirrors[S].previousTimes[T];this.mirrors[S].previousTimes[this.options.QUANTITYPREVIOUSTIMESSTORED-1]=s}if(h==this.heuristics.THIRDHEURISTIC.THIRDSIMPLEAVERAGE){var m=0;for(T=0;T<this.mirrors[S].previousTimes.length;T++)m+=this.mirrors[S].previousTimes[T];this.mirrors[S].averageTime=m/this.mirrors[S].previousTimes.length}else if(h==this.heuristics.THIRDHEURISTIC.THIRDWEIGHTEDAVERAGE){var I=0,l=0;for(T=0;T<this.mirrors[S].previousTimes.length;T++)I+=this.mirrors[S].previousTimes[T]*(T+1),l+=T+1;this.mirrors[S].averageTime=I/l}(s>this.options.THRESHOLDSLOW||-1==e)&&(this.mirrors[S].isSlow=!0,this.mirrors[S].remainingSlow=this.options.SLOWLIMITTRIES),i.setItem("servers",JSON.stringify(this.mirrors));break}var R,E=Math.floor(Math.random()*this.mirrors.length);o!=this.heuristics.FIRSTHEURISTIC.FIRSTRANDOM&&(E=-1,R=-1);var u=[],v=0,g=0;for(T=0;T<this.mirrors.length;T++)if(this.mirrors[T].remainingSlow>0&&(this.mirrors[T].remainingSlow=this.mirrors[T].remainingSlow-1),0===this.mirrors[T].remainingSlow&&(this.mirrors[T].isSlow=!1),o!=this.heuristics.FIRSTHEURISTIC.FIRSTRANDOM&&this.mirrors[T].isSlow===!1){-1==R&&(R=T);var f=!1;for(v=0;v<u.length;v++)if(this.mirrors[T].averageTime<u[v].averageTime||this.mirrors[T].averageTime==u[v].averageTime&&Math.floor(Math.random())<.5){if(f=!0,u.length<a)for(g=u.length-1;g>=v;g--)u[g+1]=u[g];else for(g=u.length-2;g>=v;g--)u[g+1]=u[g];u[v]=this.mirrors[T];break}f===!1&&u.length<a&&(u[u.length]=this.mirrors[T])}o!=this.heuristics.FIRSTHEURISTIC.FIRSTRANDOM&&u.length>0&&(E=Math.floor(Math.random()*u.length)),-1==E&&(E=n==this.heuristics.SECONDHEURISTIC.SECONDCLOSEST?-1!=R?R:0:Math.floor(Math.random()*this.mirrors.length)),t(this.mirrors[E].url)},e.prototype.loadMirrors_=function(r){var s=this,e=JSON.parse(i.getItem("servers"))||[];qdClient.getJSON(this.server,function(i,t){for(var o=200===i?t:[],n=0;n<o.length;n++){var h={name:o[n].nome,url:o[n].url,averageTime:99999999,isSlow:!1,previousTimes:[],remainingSlow:0,type:o[n].type};for(var T in e)if(h.url==T.url){h.averageTime=T.averageTime,h.isSlow=T.isSlow,h.previousTimes=T.previousTimes,h.remainingSlow=T.remainingSlow;break}s.mirrors.push(h)}r instanceof Function&&r()})}}(window,localStorage); | ||
| 0 | \ No newline at end of file | 2 | \ No newline at end of file |
firefox/data/app/window.html
| 1 | -<html> | 1 | +<!doctype html> |
| 2 | +<html lang="en-us"> | ||
| 2 | <head> | 3 | <head> |
| 3 | - <meta charset="UTF-8" /> | 4 | + <meta charset="utf-8"> |
| 5 | + <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> | ||
| 4 | <title>VLibras Plugin</title> | 6 | <title>VLibras Plugin</title> |
| 7 | + <link rel="stylesheet" href="TemplateData/style.css"> | ||
| 8 | + <link rel="shortcut icon" href="TemplateData/favicon.ico?v=2" /> | ||
| 9 | + <script src="TemplateData/UnityProgress.js"></script> | ||
| 10 | + | ||
| 11 | + <script src="vendors/qdclient/qdclient.js"></script> | ||
| 12 | + <script src="main.js"></script> | ||
| 13 | + | ||
| 14 | + <style type="text/css"> | ||
| 15 | + html, #canvas, .template, .template-wrap { | ||
| 16 | + width: 100%; | ||
| 17 | + height: 100%; | ||
| 18 | + margin: 0; | ||
| 19 | + overflow: hidden; | ||
| 20 | + } | ||
| 21 | + | ||
| 22 | + #loading-screen span { | ||
| 23 | + position: absolute; | ||
| 24 | + top: 5px; | ||
| 25 | + right: 40px; | ||
| 26 | + padding: 15px 10px; | ||
| 27 | + background: #000; | ||
| 28 | + color: #FFF; | ||
| 29 | + | ||
| 30 | + font-size: 1.2em; | ||
| 31 | + -webkit-border-radius: 20px; | ||
| 32 | + -moz-border-radius: 20px; | ||
| 33 | + border-radius: 20px; | ||
| 34 | + } | ||
| 35 | + | ||
| 36 | + #loading-screen { | ||
| 37 | + position: absolute; | ||
| 38 | + top: 0; | ||
| 39 | + left: 0; | ||
| 40 | + display: none; | ||
| 41 | + width: 100%; | ||
| 42 | + height: 100%; | ||
| 43 | + z-index: 9999; | ||
| 44 | + } | ||
| 45 | + </style> | ||
| 5 | </head> | 46 | </head> |
| 6 | - <body> | ||
| 7 | - <h1>Hello World</h1> | ||
| 8 | - <script> | ||
| 9 | - document.addEventListener('plugin:selectedText', function(e) { | ||
| 10 | - console.log(e.detail); | ||
| 11 | - }); | ||
| 12 | - </script> | 47 | + <body class="template"> |
| 48 | + <div id="loading-screen"><span>Carregando...</span></div> | ||
| 49 | + <div class="template-wrap clear"> | ||
| 50 | + <canvas class="emscripten" id="canvas"></canvas> | ||
| 51 | + </div> | ||
| 52 | + <script src="connect.js"></script> | ||
| 53 | +<script src="Release/UnityConfig.js"></script> | ||
| 54 | +<script src="Release/fileloader.js"></script> | ||
| 55 | +<script src="load.js"></script> | ||
| 13 | </body> | 56 | </body> |
| 14 | </html> | 57 | </html> |