mirror of
https://github.com/BorysLevytskyi/BitwiseCmd.git
synced 2026-01-06 03:52:39 +01:00
Published minifed version of application.
This commit is contained in:
22
LICENSE
22
LICENSE
@@ -1,22 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 Borys Levytskyi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
# BitwiseCmd
|
||||
[Bitwise Operations Visualised](http://bitwisecmd.com/)
|
||||
|
||||
Web App that rolls on wheels that I most certainly had to reinvent myself. Nuff said.
|
||||
|
||||
It helps better understand how bitwise operations are pefromed by displaying bytes in a way you can actually see what is going on there during AND, OR, XOR or shift operations.
|
||||
@@ -1,33 +0,0 @@
|
||||
app.compose(function(){
|
||||
var trackedDomains = { 'bitwisecmd.com': 'UA-61569164-1', 'borislevitskiy.github.io': 'UA-61569164-1' };
|
||||
|
||||
var host = window.location.host.toLowerCase();
|
||||
|
||||
if(trackedDomains.hasOwnProperty(host)) {
|
||||
var trackingCode = trackedDomains[host];
|
||||
setTimeout(doTrackAsync, 300);
|
||||
}
|
||||
|
||||
function doTrackAsync() {
|
||||
try
|
||||
{
|
||||
doTrack(trackingCode);
|
||||
console.info('View tracked successfully');
|
||||
}
|
||||
catch(err) {
|
||||
console.error('Failed to start tracking:', err);
|
||||
}
|
||||
}
|
||||
|
||||
function doTrack(trackingCode) {
|
||||
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
|
||||
var ga = window.ga;
|
||||
ga('create', trackingCode, 'auto');
|
||||
ga('send', 'pageview');
|
||||
}
|
||||
});
|
||||
23
app/app.js
23
app/app.js
@@ -1,23 +0,0 @@
|
||||
(function (core) {
|
||||
"use strict";
|
||||
|
||||
var di = new core.Container();
|
||||
|
||||
var app = new core.AppShell(di);
|
||||
|
||||
app.set('cmdConfig', core.ObservableObject.create({
|
||||
emphasizeBytes: true
|
||||
}));
|
||||
|
||||
app.debugMode = false;
|
||||
|
||||
app.bootstrap = function(rootViewElement) {
|
||||
this.rootViewElement = rootViewElement;
|
||||
this.set('rootView', rootViewElement)
|
||||
this.initialize();
|
||||
};
|
||||
|
||||
|
||||
window.app = app;
|
||||
|
||||
})(window.core);
|
||||
@@ -1,24 +0,0 @@
|
||||
app.compose(function() {
|
||||
"use strict";
|
||||
|
||||
var should = app.get('should')
|
||||
app.set('calc', {
|
||||
|
||||
numberOfBits: function (num) {
|
||||
should.bePositiveInteger(num);
|
||||
return Math.floor(Math.log(num) / Math.log(2)) + 1;
|
||||
},
|
||||
|
||||
maxNumberOfBits: function (arr) {
|
||||
|
||||
var counts = [], num;
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
num = arr[i];
|
||||
counts.push(this.numberOfBits(num));
|
||||
}
|
||||
|
||||
return Math.max.apply(null, counts);
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
@@ -1,52 +0,0 @@
|
||||
app.compose(function() {
|
||||
"use strict";
|
||||
|
||||
var twoOperandsRegex = /^(\d+)\s*(<<|>>|\||\&|\^)\s*(\d+)$/;
|
||||
var numbersList = /^((\d*)+\s?)+$/;
|
||||
|
||||
app.set('expression', {
|
||||
canParse: function(string) {
|
||||
return twoOperandsRegex.test(string) || numbersList.test(string);
|
||||
},
|
||||
parse: function(string) {
|
||||
var trimmed = string.replace(/^\s+|\s+$/, '');
|
||||
var matches = twoOperandsRegex.exec(trimmed);
|
||||
|
||||
if(matches != null) {
|
||||
return createCalculableExpression(matches);
|
||||
}
|
||||
|
||||
matches = numbersList.exec(string);
|
||||
if(matches != null) {
|
||||
return createListOfNumbersExpression(string)
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function createCalculableExpression(matches) {
|
||||
|
||||
var o1 = parseInt(matches[1], 10);
|
||||
var o2 = parseInt(matches[3], 10);
|
||||
|
||||
var m = new app.models.BitwiseOperation();
|
||||
m.operand1 = o1;
|
||||
m.operand2 = o2;
|
||||
m.sign = matches[2];
|
||||
m.string = matches.input;
|
||||
m.result = eval(matches.input);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
function createListOfNumbersExpression(input) {
|
||||
var numbers = [];
|
||||
input.split(' ').forEach(function(n){
|
||||
if(n.trim().length > 0) {
|
||||
numbers.push(parseInt(n));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return new app.models.BitwiseNumbers(numbers);
|
||||
}
|
||||
});
|
||||
@@ -1,27 +0,0 @@
|
||||
app.compose(function() {
|
||||
"use strict";
|
||||
|
||||
var should = app.get('should');
|
||||
app.set("formatter", {
|
||||
toBinaryString: function(num, totalLength) {
|
||||
|
||||
var binaryStr = num.toString(2),
|
||||
formatted = [],
|
||||
i;
|
||||
|
||||
if(totalLength != null) {
|
||||
should.bePositiveInteger(totalLength);
|
||||
}
|
||||
|
||||
for(i = 0; i<binaryStr.length; i++) {
|
||||
formatted.push(binaryStr[i]);
|
||||
}
|
||||
|
||||
while(totalLength > formatted.length) {
|
||||
formatted.unshift('0');
|
||||
}
|
||||
|
||||
return formatted.join('');
|
||||
}
|
||||
});
|
||||
})
|
||||
@@ -1,94 +0,0 @@
|
||||
app.compose(function() {
|
||||
"use strict";
|
||||
|
||||
app.set('cmd', function() {
|
||||
var handlers = [];
|
||||
var is = app.get('is');
|
||||
var cmdController = app.controller('cmdController');
|
||||
|
||||
return {
|
||||
execute: function(rawInput) {
|
||||
var input = rawInput.trim().toLowerCase();
|
||||
var handler = findHandler(input);
|
||||
|
||||
if(handler != null) {
|
||||
if(app.debugMode) {
|
||||
invokeHandler(input, handler);
|
||||
} else {
|
||||
try {
|
||||
invokeHandler(input, handler);
|
||||
} catch (e) {
|
||||
displayCommandError(input, "Error: " + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
displayCommandError(input, "Unsupported expression: " + input.trim());
|
||||
}
|
||||
},
|
||||
commands: function(catalog) {
|
||||
for(var key in catalog) {
|
||||
if(catalog.hasOwnProperty(key)) {
|
||||
this.command(key, catalog[key]);
|
||||
}
|
||||
}
|
||||
},
|
||||
command: function(cmd, handler) {
|
||||
var h = createHandler(cmd, handler);
|
||||
if(h == null){
|
||||
console.warn('unexpected set of arguments: ', Array.prototype.splice.call(arguments));
|
||||
return;
|
||||
}
|
||||
|
||||
if(!is.aFunction(h.canHandle)) {
|
||||
console.warn('handler is missing "canHandle" function. registration denied.');
|
||||
return;
|
||||
}
|
||||
|
||||
if(!is.aFunction(h.handle)) {
|
||||
console.warn('handler is missing "handle" function. registration denied.');
|
||||
return;
|
||||
}
|
||||
|
||||
handlers.push(h);
|
||||
},
|
||||
clear: function() {
|
||||
cmdController.clear();
|
||||
}
|
||||
};
|
||||
|
||||
function displayCommandError(input, message) {
|
||||
var error = new app.models.ErrorResult(message);
|
||||
cmdController.display(new app.models.DisplayResult(input, error));
|
||||
}
|
||||
|
||||
function invokeHandler (input, handler) {
|
||||
var cmdResult = handler.handle(input);
|
||||
if(cmdResult != null) {
|
||||
var r = new app.models.DisplayResult(input, cmdResult);
|
||||
cmdController.display(r);
|
||||
}
|
||||
}
|
||||
|
||||
function createHandler (cmd, handler) {
|
||||
if(is.plainObject(cmd)) {
|
||||
return cmd;
|
||||
}
|
||||
|
||||
if(is.string(cmd)) {
|
||||
return { canHandle: function (input) { return input === cmd; }, handle: handler };
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function findHandler (input) {
|
||||
var i= 0;
|
||||
for(i;i<handlers.length; i++) {
|
||||
if(handlers[i].canHandle(input)) {
|
||||
return handlers[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,59 +0,0 @@
|
||||
app.run(function() {
|
||||
"use strict";
|
||||
|
||||
var cmd = app.get('cmd');
|
||||
var cmdConfig = app.get('cmdConfig');
|
||||
var rootView = app.get('rootView');
|
||||
var shell = app.get('shell');
|
||||
|
||||
cmd.commands({
|
||||
'help': function() {
|
||||
var helpResult = document.querySelector('.result .helpResultTpl');
|
||||
if(helpResult != null) {
|
||||
moveResultUp(helpResult);
|
||||
return;
|
||||
}
|
||||
return new app.models.ViewResult('helpResultTpl');
|
||||
},
|
||||
'clear': function() {
|
||||
cmd.clear();
|
||||
},
|
||||
'em': function() {
|
||||
cmdConfig.emphasizeBytes = !cmdConfig.emphasizeBytes;
|
||||
},
|
||||
'dark': function() {
|
||||
shell.setDarkTheme();
|
||||
},
|
||||
light: function () {
|
||||
shell.setLightTheme();
|
||||
},
|
||||
about: function() {
|
||||
var aboutResult = document.querySelector('.result .aboutTpl');
|
||||
if(aboutResult != null) {
|
||||
moveResultUp(aboutResult);
|
||||
return;
|
||||
}
|
||||
return new app.models.ViewResult('aboutTpl');
|
||||
}
|
||||
});
|
||||
|
||||
// TODO: Make as function
|
||||
cmd.command({
|
||||
canHandle: function(input) { return app.get('expression').canParse(input); },
|
||||
handle: function(input) {
|
||||
return app.get('expression').parse(input);
|
||||
}
|
||||
});
|
||||
|
||||
function moveResultUp(helpResult) {
|
||||
var container = helpResult.parentNode.parentNode;
|
||||
if(container.parentNode.firstChild != container) {
|
||||
|
||||
var out = container.parentNode;
|
||||
out.removeChild(container);
|
||||
out.insertBefore(container, out.firstChild);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
@@ -1,98 +0,0 @@
|
||||
app.compose(function() {
|
||||
"use strict";
|
||||
|
||||
app.controller('expressionInputCtrl', function (){
|
||||
var cmd = app.get('cmd');
|
||||
|
||||
return {
|
||||
onViewAttached: function () {
|
||||
var self = this;
|
||||
self.history =[];
|
||||
self.historyIndex = 0;
|
||||
|
||||
this.viewElement.focus();
|
||||
|
||||
this.viewElement.addEventListener('keyup', function (args) {
|
||||
var inpt = args.target;
|
||||
|
||||
if (args.keyCode != 13 || inpt.value.trim().length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Enter
|
||||
cmd.execute(inpt.value);
|
||||
self.history.unshift(inpt.value);
|
||||
self.historyIndex = 0;
|
||||
inpt.value = '';
|
||||
});
|
||||
|
||||
this.viewElement.addEventListener('keydown', function(args){
|
||||
if(args.keyCode == 38) {
|
||||
|
||||
if (self.history.length > self.historyIndex) { // up
|
||||
args.target.value = self.history[self.historyIndex++];
|
||||
|
||||
}
|
||||
|
||||
args.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
if(args.keyCode == 40) {
|
||||
|
||||
if(self.historyIndex > 0) { // up
|
||||
args.target.value = self.history[--self.historyIndex];
|
||||
}
|
||||
|
||||
args.preventDefault();
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
app.controller('cmdController', function() {
|
||||
var html = app.get('html');
|
||||
|
||||
return {
|
||||
clear: function () {
|
||||
this.viewElement.innerHTML = '';
|
||||
},
|
||||
display: function ( model) {
|
||||
var view = app.buildViewFor(model);
|
||||
|
||||
var vw = this.viewElement;
|
||||
if(vw.childNodes.length == 0) {
|
||||
vw.appendChild(view);
|
||||
}
|
||||
else {
|
||||
vw.insertBefore(view, vw.childNodes[0]);
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
app.controller('configPanelCtrl', {
|
||||
onViewAttached: function (){
|
||||
var self = this;
|
||||
var cfg = app.get('cmdConfig');
|
||||
self.update(cfg);
|
||||
|
||||
cfg.observe(function(){
|
||||
self.update(cfg);
|
||||
});
|
||||
},
|
||||
update: function (cfg) {
|
||||
var emIndicator = this.viewElement.querySelector('#emphasizeBytes');
|
||||
var reg = /\son/g;
|
||||
|
||||
if(cfg.emphasizeBytes) {
|
||||
emIndicator.classList.add("on");
|
||||
} else {
|
||||
emIndicator.classList.remove("on");
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
// Expression View
|
||||
app.compose(function () {
|
||||
"use strict";
|
||||
|
||||
var formatter = app.get('formatter');
|
||||
var calc = app.get('calc');
|
||||
var html = app.get('html');
|
||||
var cmdConfig = app.get('cmdConfig');
|
||||
|
||||
app.modelView(app.models.BitwiseOperation, {
|
||||
renderView: function(expr) {
|
||||
var maxLen = getBinaryLength([expr.operand1, expr.operand2, expr.result]);
|
||||
|
||||
expr.operand1Binary = formatter.toBinaryString(expr.operand1, maxLen);
|
||||
expr.operand2Binary = formatter.toBinaryString(expr.operand2, maxLen);
|
||||
expr.resultBinary = formatter.toBinaryString(expr.result, maxLen);
|
||||
|
||||
var templateId = /<<|>>/.test(expr.sign) ? 'shiftExpressionView' : 'binaryExpressionView';
|
||||
var template = app.template(templateId)
|
||||
|
||||
var el = template.render(expr);
|
||||
colorizeBits(el);
|
||||
return el;
|
||||
}
|
||||
});
|
||||
|
||||
app.modelView(app.models.BitwiseNumbers, {
|
||||
renderView: function(model) {
|
||||
var maxLen = getBinaryLength(model.numbers);
|
||||
var table = html.element('<table class="expression"></table>');
|
||||
|
||||
model.numbers.forEach(function(o){
|
||||
|
||||
var row = table.insertRow();
|
||||
var decCell = row.insertCell();
|
||||
|
||||
decCell.className = 'label';
|
||||
|
||||
var binCell = row.insertCell();
|
||||
binCell.className = 'bin';
|
||||
|
||||
decCell.textContent = o;
|
||||
binCell.textContent = formatter.toBinaryString(o, maxLen);
|
||||
});
|
||||
|
||||
colorizeBits(table);
|
||||
return table;
|
||||
}
|
||||
});
|
||||
|
||||
app.modelView(app.models.ViewResult, {
|
||||
renderView: function(model) {
|
||||
var template = app.template(model.template);
|
||||
return template.render();
|
||||
}
|
||||
});
|
||||
|
||||
app.modelView(app.models.ErrorResult, {
|
||||
renderView: function(model) {
|
||||
return html.element('<div class="error">{message}</div>', model);
|
||||
}
|
||||
});
|
||||
|
||||
app.modelView(app.models.DisplayResult, {
|
||||
renderView: function(model) {
|
||||
var resultView = app.template('resultView').render(model);
|
||||
var contentView = app.buildViewFor(model.content);
|
||||
resultView.querySelector('.content').appendChild(contentView);
|
||||
return resultView;
|
||||
}
|
||||
});
|
||||
|
||||
function getBinaryLength(arr) {
|
||||
var bits = calc.maxNumberOfBits(arr);
|
||||
if(cmdConfig.emphasizeBytes && bits % 8 != 0) {
|
||||
if(bits < 8) {
|
||||
return 8;
|
||||
}
|
||||
|
||||
var n = bits - (bits % 8);
|
||||
return n + 8;
|
||||
}
|
||||
return bits;
|
||||
}
|
||||
|
||||
function colorizeBits(container) {
|
||||
var list = container.querySelectorAll('.bin');
|
||||
Array.prototype.forEach.call(list, function(el){
|
||||
var bin = el.textContent;
|
||||
|
||||
el.innerHTML = bin
|
||||
.replace(/(\d{8})/g, '<span class="byte">$1</span>')
|
||||
.replace(/0/g, '<span class="zero">0</span>')
|
||||
.replace(/1/g, '<span class="one">1</span>');
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
(function(app) {
|
||||
"use strict";
|
||||
|
||||
function BitwiseOperation () {
|
||||
}
|
||||
|
||||
BitwiseOperation.prototype.calculate = function () {
|
||||
return eval(this.string);
|
||||
};
|
||||
|
||||
function BitwiseNumbers(numbers) {
|
||||
this.numbers = numbers;
|
||||
}
|
||||
|
||||
function ErrorResult(message) {
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
function ViewResult (template) {
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
function DisplayResult (input, content) {
|
||||
this.input = input;
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
app.models.BitwiseOperation = BitwiseOperation;
|
||||
app.models.BitwiseNumbers = BitwiseNumbers;
|
||||
app.models.ErrorResult = ErrorResult;
|
||||
app.models.ViewResult = ViewResult;
|
||||
app.models.DisplayResult = DisplayResult;
|
||||
|
||||
})(window.app);
|
||||
@@ -1,85 +0,0 @@
|
||||
(function(app, core){
|
||||
"use strict";
|
||||
|
||||
app.set('html', core.HtmlBuilder);
|
||||
app.set('is', core.is);
|
||||
app.set('should', core.should);
|
||||
app.set('bindr', core.bindr);
|
||||
|
||||
// Save config in local store
|
||||
app.run(function() {
|
||||
var cfg = app.get('cmdConfig');
|
||||
var storeKey = 'cmdConfig';
|
||||
|
||||
load();
|
||||
|
||||
cfg.observe(function(property, value){
|
||||
save();
|
||||
});
|
||||
|
||||
function save() {
|
||||
localStorage.setItem(storeKey, JSON.stringify(cfg.store()));
|
||||
}
|
||||
|
||||
function load() {
|
||||
var json = localStorage.getItem(storeKey), stored;
|
||||
if(core.is.string(json)) {
|
||||
stored = JSON.parse(json);
|
||||
for(var key in stored) {
|
||||
cfg[key] = stored[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
app.set('shell', function(){
|
||||
var rootView = app.get('rootView');
|
||||
|
||||
return {
|
||||
setDarkTheme: function() {
|
||||
rootView.classList.remove('light');
|
||||
rootView.classList.add('dark');
|
||||
},
|
||||
setLightTheme: function() {
|
||||
rootView.classList.remove('dark');
|
||||
rootView.classList.add('light');
|
||||
}
|
||||
}
|
||||
});
|
||||
/*
|
||||
var template = {
|
||||
compile: function (template) {
|
||||
var regex = /(?:{([^}]+)})/g;
|
||||
|
||||
var sb = [];
|
||||
|
||||
sb.push('(function() {')
|
||||
sb.push('return function (model) { ')
|
||||
sb.push('\tvar html = [];')
|
||||
sb.push('\twith (model) { ')
|
||||
var m, index = 0;
|
||||
while ((m = regex.exec(template)) !== null) {
|
||||
if(m.index > index) {
|
||||
sb.push("\t\thtml.push('" + normalize(template.substr(index, m.index - index)) + "');");
|
||||
}
|
||||
sb.push('\t\thtml.push(' + m[1] + ');');
|
||||
index = m.index + m[0].length;
|
||||
}
|
||||
|
||||
if(index < template.length - 1) {
|
||||
sb.push("\t\thtml.push('" + normalize(template.substr(index, template.length - index)) + "');");
|
||||
}
|
||||
sb.push('\t}');
|
||||
sb.push("\treturn html.join('');");
|
||||
sb.push('}');
|
||||
sb.push('})()')
|
||||
console.log(sb.join('\r\n'));
|
||||
return eval(sb.join('\r\n'));
|
||||
}
|
||||
};
|
||||
|
||||
function normalize(str) {
|
||||
return str.replace(/(\r|\n)+/g, '').replace("'", "\\\'");
|
||||
}
|
||||
*/
|
||||
})(window.app, window.core);
|
||||
@@ -1,57 +0,0 @@
|
||||
(function(app, core){
|
||||
"use strict";
|
||||
|
||||
var should = core.should;
|
||||
|
||||
function Command(name) {
|
||||
this.name = name;
|
||||
this.executionHandlers = [];
|
||||
}
|
||||
|
||||
Command.prototype.execute = function (cmdArgs) {
|
||||
cmdArgs = cmdArgs || {};
|
||||
cmdArgs.commandHandled = false;
|
||||
|
||||
for(var i=0; i<this.executionHandlers.length; i++) {
|
||||
this.executionHandlers[i](cmdArgs);
|
||||
if(cmdArgs.commandHandled === true) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Command.prototype.subscribe = function (handler) {
|
||||
this.executionHandlers.push(handler);
|
||||
// TODO: unsubcribe
|
||||
};
|
||||
|
||||
app.commandHandlers = {};
|
||||
|
||||
app.command = function(name, handler) {
|
||||
var cmd = this.commandHandlers[name];
|
||||
|
||||
if(cmd == null) {
|
||||
cmd = this.commandHandlers[name] = new commandr.Command(name);
|
||||
}
|
||||
|
||||
if(typeof handler == "function") {
|
||||
cmd.subscribe(handler);
|
||||
}
|
||||
|
||||
if (typeof handler == "object") {
|
||||
|
||||
if(typeof handler.execute != "function"){
|
||||
console.warn('Given handler is an object, but doesn\'t have "execute" function');
|
||||
return cmd;
|
||||
}
|
||||
|
||||
this.di.resolveProperties(handler);
|
||||
cmd.subscribe(handler.execute.bind(handler));
|
||||
}
|
||||
|
||||
return cmd;
|
||||
};
|
||||
|
||||
window.commandr = commandr;
|
||||
|
||||
})(window.app, window.core);
|
||||
@@ -1,80 +0,0 @@
|
||||
(function(app, core) {
|
||||
"use strict";
|
||||
|
||||
var should = core.should;
|
||||
|
||||
app.controller = function(name, instOrFactory) {
|
||||
should.beString(name, "name");
|
||||
if(instOrFactory == null) {
|
||||
return this.get(name);
|
||||
}
|
||||
|
||||
var reg = new core.Container.Registration(instOrFactory);
|
||||
|
||||
reg.onFirstTimeResolve = function (inst) {
|
||||
addControllerMixin(inst);
|
||||
};
|
||||
|
||||
this.set(name, reg);
|
||||
};
|
||||
|
||||
app.run(function(){
|
||||
attachControllers(app.get('rootView'), app.di);
|
||||
});
|
||||
|
||||
function addControllerMixin(ctrl) {
|
||||
ctrl.attachView = function(viewElement) {
|
||||
|
||||
this.viewElement = viewElement;
|
||||
|
||||
if(typeof ctrl.onViewAttached == 'function') {
|
||||
ctrl.onViewAttached(viewElement);
|
||||
}
|
||||
};
|
||||
|
||||
ctrl.detachView = function() {
|
||||
|
||||
this.viewElement = null;
|
||||
|
||||
if(typeof ctrl.onViewDetached == 'function') {
|
||||
ctrl.onViewDetached(viewElement);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function attachControllers(rootViewElement) {
|
||||
var elements = rootViewElement.querySelectorAll('[data-controller]'),
|
||||
i = 0, l = elements.length,
|
||||
ctrlName,
|
||||
ctrl, element;
|
||||
|
||||
for(;i<l;i++){
|
||||
element = elements[i];
|
||||
ctrlName = element.getAttribute('data-controller');
|
||||
ctrl = app.controller(ctrlName);
|
||||
|
||||
if(ctrl == null) {
|
||||
console.warn(ctrlName + ' controller wasn\'t found');
|
||||
continue;
|
||||
}
|
||||
|
||||
ctrl.attachView(element);
|
||||
|
||||
// console.log(ctrlName + ' Controller: view attached');
|
||||
|
||||
if(typeof ctrl.detachView != "function") {
|
||||
continue;
|
||||
}
|
||||
|
||||
// TODO: get rid from closure
|
||||
element.addEventListener('DOMNodeRemoved', function (evt) {
|
||||
if(element === evt.target) {
|
||||
ctrl.detachView();
|
||||
}
|
||||
|
||||
// console.log(ctrlName + ' Controller: view detached');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
})(window.app, window.core);
|
||||
@@ -1,42 +0,0 @@
|
||||
(function(app) {
|
||||
"use strict";
|
||||
|
||||
function Template(html) {
|
||||
this.html = html;
|
||||
}
|
||||
|
||||
Template.prototype.render = function (model) {
|
||||
return app.get('html').element(this.html, model);
|
||||
};
|
||||
|
||||
app.templates = [];
|
||||
app.template = function (key) {
|
||||
var tpl = this.templates[key];
|
||||
if(tpl == null) {
|
||||
throw new Error(key + ' template is not found');
|
||||
}
|
||||
return tpl;
|
||||
}
|
||||
|
||||
app.run(function() {
|
||||
readTemplates(app.get('rootView'));
|
||||
})
|
||||
|
||||
function readTemplates(containerEl) {
|
||||
var els = containerEl.querySelectorAll('[data-template]');
|
||||
var store = app.templates;
|
||||
|
||||
Array.prototype.forEach.call(els, function(element) {
|
||||
var key = element.getAttribute('data-template');
|
||||
|
||||
if(store[key] instanceof Template) {
|
||||
console.warn(key + ' templates already registered');
|
||||
return;
|
||||
}
|
||||
|
||||
store[key] = new Template(element.innerHTML);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
})(window.app);
|
||||
@@ -1,24 +0,0 @@
|
||||
(function(app, is){
|
||||
"use strict";
|
||||
|
||||
app.modelView = function (modelCtor, builder) {
|
||||
var name = getKey(modelCtor);
|
||||
app.di.register(name, builder);
|
||||
};
|
||||
|
||||
app.buildViewFor = function(model) {
|
||||
var key = getKey(model.constructor);
|
||||
var builder = this.di.resolve(key);
|
||||
return builder.renderView(model);
|
||||
};
|
||||
|
||||
function getKey(modelCtor) {
|
||||
return getFunctionName(modelCtor) + "ViewBuilder";
|
||||
}
|
||||
|
||||
function getFunctionName(func) {
|
||||
var str = func.toString();
|
||||
return str.substr(8, str.indexOf('(') - 8).trim();
|
||||
}
|
||||
|
||||
})(window.app, window.is);
|
||||
@@ -1,37 +0,0 @@
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
function AppShell(diContainer) {
|
||||
this.models = {};
|
||||
this.di = diContainer;
|
||||
this.runList = [];
|
||||
this.compositionList = [];
|
||||
}
|
||||
|
||||
AppShell.prototype.get = function(name) {
|
||||
return this.di.resolve(name);
|
||||
};
|
||||
|
||||
AppShell.prototype.set = function(name, def) {
|
||||
this.di.register(name, def);
|
||||
};
|
||||
|
||||
AppShell.prototype.run = function(func) {
|
||||
this.runList.push(func);
|
||||
};
|
||||
|
||||
AppShell.prototype.compose = function (func) {
|
||||
this.compositionList.push(func);
|
||||
};
|
||||
|
||||
AppShell.prototype.initialize = function () {
|
||||
callInvocationList(this.compositionList);
|
||||
callInvocationList(this.runList);
|
||||
};
|
||||
|
||||
function callInvocationList(functions) {
|
||||
functions.forEach(function(o){ o(); });
|
||||
}
|
||||
|
||||
window.core.AppShell = AppShell;
|
||||
})();
|
||||
@@ -1,72 +0,0 @@
|
||||
(function(){
|
||||
"use strict";
|
||||
|
||||
var bindr = {};
|
||||
|
||||
bindr.bindChildren = function(container, model) {
|
||||
var elements = container.querySelectorAll('[data-bind]');
|
||||
Array.prototype.call(elements, function(el){
|
||||
});
|
||||
};
|
||||
|
||||
bindr.bind = function(element, model, propertyName) {
|
||||
};
|
||||
|
||||
bindr.attachView = function(viewElement, model) {
|
||||
var elements = viewElement.querySelectorAll('[data-bindr]'),
|
||||
count = elements.length,
|
||||
i =0, el;
|
||||
|
||||
for(;i<count; i++){
|
||||
el = elements[i];
|
||||
this.bindElement(el, model, el.getAttribute('data-bindr'))
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
function bindInput(model, intput, propertyName) {
|
||||
bindTextInput(intput, model, propertyName);
|
||||
}
|
||||
|
||||
function bindCheckBox(element, model, propertyName) {
|
||||
element.checked = model[propertyName];
|
||||
|
||||
element.addEventListener('changed', function (e) {
|
||||
model[propertyName] = e.target.checked == true;
|
||||
});
|
||||
|
||||
model.observe(propertyName, function (property, value) {
|
||||
if (window.event && window.event.target == element) {
|
||||
return;
|
||||
}
|
||||
|
||||
element.checked = value;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function bindTextInput(input, model, propertyName) {
|
||||
input.value = model[propertyName];
|
||||
|
||||
input.addEventListener('keyup', function (e) {
|
||||
model[propertyName] = e.target.value;
|
||||
});
|
||||
|
||||
model.observe(propertyName, function (property, value) {
|
||||
if (window.event && window.event.target == input) {
|
||||
return;
|
||||
}
|
||||
|
||||
input.value = value;
|
||||
});
|
||||
}
|
||||
|
||||
function bindHtmlElement(model, el, propertyName) {
|
||||
model.observe(propertyName, function(propery, value){
|
||||
el.innerHTML = value;
|
||||
});
|
||||
}
|
||||
|
||||
window.core.bindr = bindr;
|
||||
})();
|
||||
@@ -1 +0,0 @@
|
||||
window.core = {};
|
||||
93
core/di.js
93
core/di.js
@@ -1,93 +0,0 @@
|
||||
(function(core){
|
||||
|
||||
"use strict";
|
||||
var is = core.is;
|
||||
|
||||
function Container(store) {
|
||||
this.store = {};
|
||||
this.resolutionStack = [];
|
||||
}
|
||||
|
||||
Container.prototype.register = function(name, def) {
|
||||
var reg = this.store[name];
|
||||
if(reg == null) {
|
||||
if(def instanceof Registration) {
|
||||
reg = def;
|
||||
}
|
||||
else {
|
||||
reg = new Registration(def);
|
||||
}
|
||||
|
||||
reg.name = name;
|
||||
this.store[name] = reg;
|
||||
}
|
||||
|
||||
// console.log('[' + name + '] component registered');
|
||||
return reg;
|
||||
};
|
||||
|
||||
Container.prototype.resolve = function(name) {
|
||||
return resolveInternal.call(this, name);
|
||||
};
|
||||
|
||||
function resolveInternal(name) {
|
||||
if(contains(this.resolutionStack, name)) {
|
||||
throw new Error("Failed to resolve service: " + name + ". Circular reference: " + this.resolutionStack.join(' < '));
|
||||
}
|
||||
|
||||
this.resolutionStack.unshift(name);
|
||||
|
||||
// console.log('\tresolution path:' + this.resolutionStack.join(' < '));
|
||||
|
||||
var reg = this.store[name];
|
||||
if(reg == null) {
|
||||
throw new Error(name + ' component is not registered');
|
||||
}
|
||||
|
||||
if(reg.resolved == null) {
|
||||
reg.createInstance();
|
||||
}
|
||||
|
||||
this.resolutionStack.shift();
|
||||
|
||||
// console.log('\tresolution path:' + this.resolutionStack.join(' < '));
|
||||
|
||||
return reg.resolved;
|
||||
}
|
||||
|
||||
|
||||
function Registration(definition) {
|
||||
this.def = definition;
|
||||
this.resolved = null;
|
||||
}
|
||||
|
||||
Registration.prototype.createInstance = function() {
|
||||
var def = this.def;
|
||||
if(typeof def == "function") {
|
||||
this.resolved = def();
|
||||
}
|
||||
else {
|
||||
// this.resolveProperties(inst);
|
||||
this.resolved = def;
|
||||
}
|
||||
|
||||
if(is.aFunction(this.onFirstTimeResolve)){
|
||||
this.onFirstTimeResolve(this.resolved);
|
||||
}
|
||||
};
|
||||
|
||||
Container.Registration = Registration;
|
||||
|
||||
function contains(arr, item) {
|
||||
var i = arr.length;
|
||||
while(i-- > 0) {
|
||||
if(arr[i] === item) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
core.Container = Container;
|
||||
})(window.core);
|
||||
@@ -1,62 +0,0 @@
|
||||
(function(core){
|
||||
"use strict";
|
||||
|
||||
var HtmlBuilder = {};
|
||||
var should = core.should;
|
||||
|
||||
HtmlBuilder.element = function(template, model) {
|
||||
var el = document.createElement('div');
|
||||
el.innerHTML = HtmlBuilder.template(template, model);
|
||||
return el.children[0];
|
||||
};
|
||||
|
||||
HtmlBuilder.template = function(template, model) {
|
||||
should.beString(template, "template");
|
||||
var regex = /(?:{([^}]+)})/g, html;
|
||||
|
||||
if(model == null){
|
||||
html = template;
|
||||
} else {
|
||||
html = template.replace(regex, function(m, g1) {
|
||||
return HtmlBuilder.escapeHtml(model[g1]);
|
||||
});
|
||||
}
|
||||
|
||||
return html;
|
||||
};
|
||||
|
||||
function getAttributesStr(attr) {
|
||||
if(attr == null) {
|
||||
return '';
|
||||
}
|
||||
var str = [];
|
||||
|
||||
for(var key in attr) {
|
||||
if(key == 'html')
|
||||
continue;
|
||||
str.push(key + '="' + HtmlBuilder.escapeHtml(attr[key]) + '"');
|
||||
}
|
||||
|
||||
return str.join(' ');
|
||||
}
|
||||
|
||||
HtmlBuilder.escapeHtml = function(obj) {
|
||||
if(obj == null) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
if(typeof obj != 'string') {
|
||||
obj = obj.toString();
|
||||
}
|
||||
|
||||
return obj
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/"/g, """)
|
||||
.replace(/'/g, "'");
|
||||
};
|
||||
|
||||
core.HtmlBuilder = HtmlBuilder;
|
||||
|
||||
})(window.core);
|
||||
33
core/is.js
33
core/is.js
@@ -1,33 +0,0 @@
|
||||
(function(){
|
||||
"use strict";
|
||||
|
||||
window.core.is = {
|
||||
plainObject: function(obj) {
|
||||
return typeof obj == "object" && obj instanceof Object;
|
||||
},
|
||||
|
||||
aFunction: function (obj) {
|
||||
return typeof obj == "function";
|
||||
},
|
||||
|
||||
string: function (obj) {
|
||||
return typeof obj == "string";
|
||||
},
|
||||
|
||||
regex: function (obj) {
|
||||
return typeof obj == "object" && this.constructedFrom(RegExp);
|
||||
},
|
||||
|
||||
constructedFrom: function (obj, ctor) {
|
||||
return obj instanceof ctor;
|
||||
},
|
||||
|
||||
htmlElement: function(obj) {
|
||||
return obj instanceof HtmlElement;
|
||||
},
|
||||
|
||||
array: function(obj) {
|
||||
return obj instanceof Array;
|
||||
}
|
||||
};
|
||||
})();
|
||||
@@ -1,80 +0,0 @@
|
||||
(function(core){
|
||||
"use strict";
|
||||
var is = core.is;
|
||||
|
||||
function ObservableObject () {
|
||||
this.$store = {};
|
||||
this.$executionHandlers = [];
|
||||
}
|
||||
|
||||
ObservableObject.create = function(definition){
|
||||
var obj = new ObservableObject();
|
||||
|
||||
for(var property in definition){
|
||||
if(!definition.hasOwnProperty(property)){
|
||||
continue;
|
||||
}
|
||||
|
||||
Object.defineProperty(obj, property, {
|
||||
get:ObservableObject.createGetter(property),
|
||||
set:ObservableObject.createSetter(property)
|
||||
});
|
||||
|
||||
obj[property] = definition[property];
|
||||
}
|
||||
|
||||
return Object.seal(obj);
|
||||
};
|
||||
|
||||
ObservableObject.createGetter = function (propertyName, store){
|
||||
return function(){
|
||||
return this.$store[propertyName];
|
||||
}
|
||||
};
|
||||
|
||||
ObservableObject.createSetter = function(propertyName, store){
|
||||
return function(value){
|
||||
this.$store[propertyName] = value;
|
||||
this.notifyPropertyChanged(propertyName, value);
|
||||
}
|
||||
};
|
||||
|
||||
ObservableObject.prototype.observe = function (property, handler){
|
||||
var func;
|
||||
if(is.aFunction(property)) {
|
||||
func = property;
|
||||
}
|
||||
else if(is.string(property) && is.aFunction(handler)) {
|
||||
func = function (p, v) {
|
||||
if(p === property) {
|
||||
handler(p, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
console.warn('Unsupported set of arguments: ', arguments);
|
||||
return;
|
||||
}
|
||||
|
||||
var handlers = this.$executionHandlers;
|
||||
var index = handlers.push(func);
|
||||
return function () { handlers.splice(1, index); }
|
||||
};
|
||||
|
||||
ObservableObject.prototype.notifyPropertyChanged = function(propertyName, value){
|
||||
this.$executionHandlers.forEach(function(h){
|
||||
h(propertyName, value);
|
||||
});
|
||||
};
|
||||
|
||||
ObservableObject.prototype.store = function() {
|
||||
return this.$store;
|
||||
};
|
||||
|
||||
ObservableObject.prototype.keys = function() {
|
||||
return Object.keys(this.$store);
|
||||
};
|
||||
|
||||
core.ObservableObject = ObservableObject;
|
||||
|
||||
})(window.core);
|
||||
@@ -1,34 +0,0 @@
|
||||
(function(){
|
||||
"use strict";
|
||||
|
||||
window.core.should = {
|
||||
beNumber: function (num, name) {
|
||||
this.check(typeof num == "number" && !isNaN(num), num + " is not a number");
|
||||
this.check(isFinite(num), append(name, "is an infinite number"));
|
||||
},
|
||||
|
||||
bePositiveInteger: function(num, name) {
|
||||
this.beNumber(num);
|
||||
this.check(num >= 0, append(name, "should be positive integer"));
|
||||
},
|
||||
|
||||
notBeNull: function (obj, name) {
|
||||
this.check(obj != null, append(name, "is null or undefined"));
|
||||
},
|
||||
|
||||
beString: function(obj, name) {
|
||||
this.check(typeof obj == "string", "should be a string");
|
||||
},
|
||||
check: function(assertion, message) {
|
||||
if(assertion !== true) {
|
||||
throw new Error (message);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function append(name, msg) {
|
||||
return typeof name == "string" ? name + " " + msg : msg;
|
||||
}
|
||||
})();
|
||||
|
||||
|
||||
@@ -1,36 +1 @@
|
||||
body { font-family: Verdana; font-size: 0.8em; padding: 20px 100px 0px 100px; margin: 0 }
|
||||
code { font-size: 1.2em; font-weight: bold; }
|
||||
|
||||
.links { float: right; position: absolute; right: 10px; top: 10px; }
|
||||
.mono { font-family: monospace; font-size: 1.3em }
|
||||
.expressionInput { width: 500px; padding: 3px; border: solid 1px lightgray; }
|
||||
|
||||
.result { margin: 10px 10px 30px; }
|
||||
.result .input { margin-bottom: 10px; }
|
||||
.result .content { padding-left: 10px}
|
||||
.result .cur { color: lightgray; margin-right: 5px; }
|
||||
|
||||
.expression .label { font-weight: bold; padding-right: 5px; text-align: right; }
|
||||
.expression .bin { letter-spacing: 3px; }
|
||||
.expression .byte { margin: 0 3px; }
|
||||
.expression .zero { color: #848586 }
|
||||
.expression .result td { border-top: dotted 1px gray; }
|
||||
.expression { font-size: 1.5em; font-family: monospace }
|
||||
|
||||
.help { padding: 10px; }
|
||||
.help ul { list-style-type: none; margin: 0; padding: 0; }
|
||||
.help p { margin-top: 0 }
|
||||
|
||||
.configPnl .indicator { font-size: 0.7em; background: gray; color: white; padding: 2px 5px; }
|
||||
.configPnl .on { background: darkblue; }
|
||||
|
||||
.error { color: maroon; }
|
||||
|
||||
#view { padding: 10px}
|
||||
|
||||
/* Light */
|
||||
.light .one { color: black; }
|
||||
/* Dark */
|
||||
.dark { background: black; color: white;}
|
||||
.dark .expressionInput { background: black; color: white; }
|
||||
.dark a, .dark a:visited { color: white; }
|
||||
body{font-family:Verdana;font-size:.8em;padding:20px 100px 0 100px;margin:0}.expression,.mono{font-family:monospace}code{font-size:1.2em;font-weight:700}.links{float:right;position:absolute;right:10px;top:10px}.mono{font-size:1.3em}.expressionInput{width:500px;padding:3px;border:solid 1px #d3d3d3}.result{margin:10px 10px 30px}.result .input{margin-bottom:10px}.result .content{padding-left:10px}.result .cur{color:#d3d3d3;margin-right:5px}.expression .label{font-weight:700;padding-right:5px;text-align:right}.expression .bin{letter-spacing:3px}.expression .byte{margin:0 3px}.expression .result td{border-top:dotted 1px gray}.expression{font-size:1.5em}.help{padding:10px}.help ul{list-style-type:none;margin:0;padding:0}.help p{margin-top:0}.configPnl .indicator{font-size:.7em;background:gray;color:#fff;padding:2px 5px}.configPnl .on{background:#00008b}.error{color:maroon}#view{padding:10px}.light{background:#fafafa}.light .one{color:#000}.light .zero{color:#696a6b}.dark,.dark a,.dark a:visited{color:#fff}.dark{background:#121212}.dark .expressionInput{background:#000;color:#fff}.dark .zero{color:#848586}
|
||||
36
index.html
36
index.html
@@ -7,43 +7,11 @@
|
||||
<title>BitwiseCmd</title>
|
||||
<link rel="shortcut icon" href="http://bitwisecmd.com/favicon.ico">
|
||||
|
||||
<script type="text/javascript" src="core/core.js"></script>
|
||||
<script type="text/javascript" src="core/is.js"></script>
|
||||
<script type="text/javascript" src="core/should.js"></script>
|
||||
<script type="text/javascript" src="core/di.js"></script>
|
||||
<script type="text/javascript" src="core/appShell.js"></script>
|
||||
<script type="text/javascript" src="core/htmlBuilder.js"></script>
|
||||
<script type="text/javascript" src="core/observable.js"></script>
|
||||
<script src="js/bitwisecmd.js"></script>
|
||||
|
||||
<script type="text/javascript" src="app/app.js"></script>
|
||||
|
||||
<script type="text/javascript" src="components/controllersFeature.js"></script>
|
||||
<script type="text/javascript" src="components/viewsFeature.js"></script>
|
||||
<script type="text/javascript" src="components/templatesFeature.js"></script>
|
||||
|
||||
<script type="text/javascript" src="app/bitwise/calc.js"></script>
|
||||
<script type="text/javascript" src="app/bitwise/expression.js"></script>
|
||||
<script type="text/javascript" src="app/bitwise/formatter.js"></script>
|
||||
|
||||
<script type="text/javascript" src="app/models.js"></script>
|
||||
<script type="text/javascript" src="app/modelViews.js"></script>
|
||||
|
||||
<script type="text/javascript" src="app/cmd/cmd.js"></script>
|
||||
<script type="text/javascript" src="app/services.js"></script>
|
||||
<script type="text/javascript" src="app/controllers.js"></script>
|
||||
<script type="text/javascript" src="app/cmd/commands.js"></script>
|
||||
<script src="js/analytics.js"></script>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="css/styles.css" />
|
||||
|
||||
<script>
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
|
||||
ga('create', 'UA-61569164-1', 'auto');
|
||||
ga('send', 'pageview');
|
||||
</script>
|
||||
</head>
|
||||
<body id="rootView" class="dark">
|
||||
|
||||
|
||||
7
js/analytics.js
Normal file
7
js/analytics.js
Normal file
@@ -0,0 +1,7 @@
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
|
||||
ga('create', 'UA-61569164-1', 'auto');
|
||||
ga('send', 'pageview');
|
||||
2
js/bitwisecmd.js
Normal file
2
js/bitwisecmd.js
Normal file
File diff suppressed because one or more lines are too long
@@ -1,4 +0,0 @@
|
||||
git checkout gh-pages
|
||||
git pull origin master
|
||||
git push
|
||||
git checkout master
|
||||
Reference in New Issue
Block a user