1(function($, keylog) { 2 3 var keyNames = [ 4 ,,,,,,,,'Backspace','Tab',,,,'Enter',,, 5 ,,,'Pause','CapsLock',,,,,,,'Esc',,,,, 6 'Space','PgUp','PgDn','End','Home','â','â','â','â',,,,'PrtSc','Insert','Delete',, 7 ,,,,,,,,,,,,,,,, 8 ,,,,,,,,,,,,,,,, 9 ,,,,,,,,,,,'Win','Win','Apps',,, 10 ,,,,,,,,,,,,,,,, 11 'F1','F2','F3','F4','F5','F6','F7','F8','F9','F10','F11','F12',,,,, 12 ,,,,,,,,,,,,,,,, 13 ,'ScrLk',,,,,,,,,,,,,,, 14 'Shift','Shift','Ctrl','Ctrl','Alt','Alt',,,,,,,,,,, 15 ,,,,,,,,,,';','=',',','-','.','/', 16 '`',,,,,,,,,,,,,,,, 17 ,,,,,,,,,,,'[','\\',']','\'',, 18 ,,,,,,,,,,,,,,,, 19 ,,,,,,,,,,,,,,,, 20 ], shiftKeyNames = [ 21 ,,,,,,,,,,,,,,,, 22 ,,,,,,,,,,,,,,,, 23 ,,,,,,,,,,,,,,,, 24 ')','!','@','#','$','%','^','&','*','(',,,,,,, 25 ,,,,,,,,,,,,,,,, 26 ,,,,,,,,,,,,,,,, 27 ,,,,,,,,,,,,,,,, 28 ,,,,,,,,,,,,,,,, 29 ,,,,,,,,,,,,,,,, 30 ,,,,,,,,,,,,,,,, 31 ,,,,,,,,,,,,,,,, 32 ,,,,,,,,,,':','+','<','_','>','?', 33 '~',,,,,,,,,,,,,,,, 34 ,,,,,,,,,,,'{','|','}','"',, 35 ,,,,,,,,,,,,,,,, 36 ,,,,,,,,,,,,,,,, 37 ], ease = [ 38 ,,,,,,,,72,88,,,,87,,, 39 ,,,,93,,,,,,,,,,,, 40 100,,,,,,,,,,,,,,,, 41 87,88,89,89,88,83,83,88,89,89,,,,,,, 42 ,98,88,94,99,94,98,93,93,94,98,99,99,93,88,94, 43 92,93,93,99,88,93,93,94,94,88,94,100,100,83,,, 44 ,,,,,,,,,,,,,,,, 45 ,,,,,,,,,,,,,,,, 46 ,,,,,,,,,,,,,,,, 47 ,,,,,,,,,,,,,,,, 48 100,100,100,100,100,100,,,,,,,,,,, 49 ,,,,,,,,,,97,85,94,87,94,92, 50 84,,,,,,,,,,,,,,,, 51 ,,,,,,,,,,,91,82,87,92,, 52 ,,,,,,,,,,,,,,,, 53 ,,,,,,,,,,,,,,,, 54 ], Width = 60, visibleKeyIds; 55 56 (function() { 57 var i, a = []; 58 keylog[0x1c0] = keylog[0x119] || 0; 59 delete keylog[0x119]; 60 for(var k in keylog) { 61 if((k / 256 & 5) === 5 || (k / 256 & 12) === 12) 62 a.push(k); 63 } 64 for(i = 0; i < a.length; ++i) { 65 if(keylog[(a[i] / 256 & ~4) * 256 + a[i] % 256]) { 66 keylog[(a[i] / 256 & ~4) * 256 + a[i] % 256] += keylog[a[i]]; 67 } else { 68 keylog[(a[i] / 256 & ~4) * 256 + a[i] % 256] = keylog[a[i]]; 69 } 70 delete keylog[a[i]]; 71 } 72 }()); 73 74 function setKeyNames(c, d) { 75 var i; 76 for(i = c.charCodeAt(0); i <= d.charCodeAt(0); ++i) 77 keyNames[i] = String.fromCharCode(i); 78 } 79 setKeyNames('A', 'Z'); 80 setKeyNames('0', '9'); 81 82 var frequentOrder = function() { 83 var a = []; 84 for(var k in keylog) 85 a.push({ keyId: k, count: keylog[k] }); 86 a.sort(function(p, q) { return q.count - p.count; }); 87 return a; 88 }(); 89 90 function modifiersName(m) { 91 var s = ''; 92 if((m & 2) === 2) 93 s += 'Ctrl + '; 94 if((m & 1) === 1) 95 s += 'Alt + '; 96 if((m & 8) === 8) 97 s += 'Win + '; 98 if((m & 4) === 4) 99 s += 'Shift + '; 100 return s; 101 } 102 103 function shortcutName(k) { 104 if(parseInt(k / 256) === 4 && shiftKeyNames[k % 256]) { 105 return shiftKeyNames[k % 256]; 106 } else { 107 return modifiersName(k / 256) + (keyNames[k % 256] || k % 256); 108 } 109 } 110 111 function modifiers() { 112 var i, a = ['alt', 'ctrl', 'shift', 'win'], sm = 0; 113 for(i = 0; i < a.length; ++i) 114 sm += $('.modifiers > .' + a[i]).hasClass('btn-primary') ? Math.pow(2, i) : 0; 115 return sm; 116 } 117 118 function isShift() { 119 return $('#tab-keyboard').hasClass('active') && modifiers() === 4; 120 } 121 122 function keyName(cd) { 123 return isShift() && shiftKeyNames[cd] ? shiftKeyNames[cd] : keyNames[cd] || cd; 124 } 125 126 function count(cd) { 127 var i, ct = 0; 128 if(!$('.modifiers > .total').hasClass('btn-primary')) 129 return keylog[modifiers() * 256 + cd] || 0; 130 for(i = 0; i < 16; ++i) 131 ct += keylog[i * 256 + cd] || 0; 132 return ct; 133 } 134 135 function popover(cd) { 136 var i, a = [0, 4, 2, 6, 1, 5, 8, 12, 3, 7, 10, 14, 9, 13, 11, 15], 137 t = $('<table class="table table-striped">').css('width', 350 + 'px'); 138 for(i = 0; i < a.length; ++i) { 139 if(keylog[a[i] * 256 + cd] !== undefined) 140 t.append('<tr><th>' + shortcutName(a[i] * 256 + cd) + '</th><td class="col-xs-2">' + keylog[a[i] * 256 + cd] + '</td></tr>'); 141 } 142 return t; 143 } 144 145 function key(x, y, cd, w) { 146 var i, ct = count(cd); 147 visibleKeyIds.push(cd); 148 return $('<a class="key" href="#">') 149 .attr('data-count', ct)
150 .css('left', x * Width).css('top', y * Width) 151 .css('width', w === undefined ? Width - 2 : w * Width - 2) 152 .css('height', Width - 2) 153 .css('line-height', (Width / 2) + 'px') 154 .html(keyName(cd) + '<br>' + (ct < 1000 ? ct : parseInt(ct / 1000) + 'K')) 155 .popover({ 156 content: popover(cd)[0].outerHTML, 157 html: true, 158 placement: 'bottom', 159 //trigger: 'focus', 160 }); 161 } 162 163 function keys(x, y, cds, w) { 164 var i, a = $(); 165 for(i = 0; i < cds.length; ++i) 166 a = a.add(key(x + i * (w || 1), y, cds[i], w)); 167 return a; 168 } 169 170 function ints(s) { 171 var i, a = []; 172 for(i = 0; i < s.length; ++i) 173 a.push(s.charCodeAt(i)); 174 return a; 175 } 176 177 function uniqueCounts() { 178 var i, a = []; 179 for(i = 0; i < visibleKeyIds.length; ++i) { 180 var ct = count(visibleKeyIds[i]); 181 if(ct > 0) 182 a.push(ct); 183 } 184 a.sort(function(p, q) { return p - q; }); 185 var b = [a[0]]; 186 for(i = 1; i < a.length; ++i) { 187 if(b[b.length - 1] !== a[i]) 188 b.push(a[i]); 189 } 190 return b; 191 } 192 193 function setKeyboard() { 194 visibleKeyIds = []; 195 var i, a = [ 196 key(0, 0, 0x1b), keys(2, 0, [0x70, 0x71, 0x72, 0x73]), keys(6.5, 0, [0x74, 0x75, 0x76, 0x77]), keys(11, 0, [0x78, 0x79, 0x7a, 0x7b]), 197 keys(0, 1.5, [0xc0].concat(ints('1234567890')).concat([0xbd, 0xbb])), key(13, 1.5, 0x8, 2), 198 key(0, 2.5, 0x9, 1.5), keys(1.5, 2.5, ints('QWERTYUIOP').concat([0xdb, 0xdd])), key(13.5, 2.5, 0xdc, 1.5), 199 key(0, 3.5, 0x14, 1.75), keys(1.75, 3.5, ints('ASDFGHJKL').concat([0xba, 0xde])), key(12.75, 3.5, 0xd, 2.25), 200 key(0, 4.5, 0xa0, 2.25), keys(2.25, 4.5, ints('ZXCVBNM').concat([0xbc, 0xbe, 0xbf])), key(12.25, 4.5, 0xa1, 2.75), 201 keys(0, 5.5, [0xa2, 0x5b, 0xa4], 1.25), key(3.75, 5.5, 0x20, 6.25), keys(10, 5.5, [0xa5, 0x5c, 0x5d, 0xa3], 1.25), 202 keys(15.5, 0, [0x2c, 0x91, 0x13]), 203 keys(15.5, 1.5, [0x2d, 0x24, 0x21]), keys(15.5, 2.5, [0x2e ,0x23 , 0x22]), 204 key(16.5, 4.5, 0x26), keys(15.5, 5.5, [0x25, 0x28, 0x27]), 205 ], b = $(); 206 visibleKeyIds.sort(function(p, q) { return p - q; }); 207 var c = uniqueCounts(); 208 for(i = 0; i < a.length; ++i) { 209 a[i].each(function() { 210 if(parseInt($(this).attr('data-count')) === 0) return; 211 var l = 0, r = c.length; 212 while(r - l > 1) { 213 if(c[parseInt((l + r) / 2)] > $(this).attr('data-count')) { 214 r = parseInt((l + r) / 2); 215 } else { 216 l = parseInt((l + r) / 2); 217 } 218 } 219 $(this).css('background-color', 'hsl(' + parseInt(360 - (c.length - l - 1) / c.length * 120) + ', 50%, ' + parseInt((c.length - l - 1) / c.length * 35 + 65) + '%)'); 220 }); 221 b = b.add(a[i]); 222 } 223 $('.keyboard').css('width', Width * 18.5 - 2).css('height', Width * 6.5 - 2).empty().append(b); 224 } 225 226 function setFrequent() { 227 var i; 228 $('.frequent').empty(); 229 for(i = 0; i < Math.min(50, frequentOrder.length); ++i) 230 $('.frequent').append('<tr><th>' + shortcutName(frequentOrder[i].keyId) + '</th><td class="col-xs-2">' + frequentOrder[i].count + '</td></tr>'); 231 } 232 233 function setSupplyAndDemand() { 234 var i, j, a = {}; 235 for(i = 0; i < visibleKeyIds.length; ++i) { 236 for(j = 0; j < 16; ++j) { 237 if(j === 0 || visibleKeyIds[i] !== 0x5b && visibleKeyIds[i] !== 0x5c && 238 (visibleKeyIds[i] < 0xa0 || 0xa5 < visibleKeyIds[i])) { 239 a[j * 256 + visibleKeyIds[i]] = { frequent: -1 }; 240 } 241 } 242 } 243 for(i = 0; i < frequentOrder.length; ++i) { 244 if(a[frequentOrder[i].keyId] !== undefined) 245 a[frequentOrder[i].keyId].frequent = i; 246 } 247 for(var k in a) { 248 if(a[k].frequent === -1) 249 a[k].frequent = frequentOrder.length; 250 } 251 252 var b = []; 253 for(i = 0; i < visibleKeyIds.length; ++i) { 254 for(j = 0; j < 16; ++j) { 255 if(j === 0 || visibleKeyIds[i] !== 0x5b && visibleKeyIds[i] !== 0x5c && 256 (visibleKeyIds[i] < 0xa0 || 0xa5 < visibleKeyIds[i])) { 257 var sm = 0; 258 if((j & 4) === 4) 259 sm += 5; 260 if((j & 2) === 2) 261 sm += 10; 262 if((j & 1) === 1) 263 sm += 15; 264 if((j & 8) === 8) 265 sm += 20; 266 b.push({ keyId: j * 256 + visibleKeyIds[i], ease: Math.max(0, (ease[visibleKeyIds[i]] || 0) - sm) }); 267 } 268 } 269 } 270 b.sort(function(p, q) { return q.ease - p.ease; }); 271 for(i = 0; i < b.length && b[i].ease > 0; ++i) 272 a[b[i].keyId].ease = i; 273 for(j = i; j < b.length; ++j) 274 a[b[j].keyId].ease = i; 275 276 var c = []; 277 for(var k in a) 278 c.push({ keyId: k, diff: a[k].frequent - a[k].ease }); 279 c.sort(function(p, q) { return p.diff - q.diff; }); 280 281 var t = $('.excessive-demand').css('width', 350 + 'px'); 282 for(i = 0; i < 15; ++i) 283 t.append('<tr><th>' + shortcutName(c[i].keyId) + '</th></tr>'); 284 t = $('.excessive-supply').css('width', 350 + 'px'); 285 for(i = 0; i < 15; ++i) 286 t.append('<tr><th>' + shortcutName(c[c.length - i - 1].keyId) + '</th></tr>'); 287 } 288 289 $(function() { 290 $('.modifiers > button').on('click', function() { 291 $(this).toggleClass('btn-primary'); 292 if($(this).hasClass('total')) { 293 $('.modifiers > :not(.total)').removeClass('btn-primary'); 294 } else { 295 $('.modifiers > .total').removeClass('btn-primary'); 296 } 297 setKeyboard(); 298 }); 299 300 setKeyboard(); 301 setFrequent(); 302 setSupplyAndDemand(); 303 }); 304}(jQuery, keylog));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.