Merge pull request #64 from AdvancedAlgos/develop

Develop got rid of CanvasApp
This commit is contained in:
Luis Fernando Molina authored and GitHub committed 2018-11-16 12:27:03 +01:00
commit 2a3ec18859
128 files changed
+17116 -12489

No files matched your search

+2 -2
View File
@@ -1,7 +1,7 @@
.vs/*
.obj/*
obj/*
bin/*
node_modules/*
this.server.config.json
+61
View File
@@ -0,0 +1,61 @@
exports.newBotCode = function newBotCode() {
let thisObject = {
saveBotCode: saveBotCode,
initialize: initialize
}
let storage;
return thisObject;
function initialize(pServerConfig) {
const STORAGE = require('../Server/Storage');
storage = STORAGE.newStorage();
storage.initialize(undefined, pServerConfig);
}
function saveBotCode(pDevTeam, pSource, pRepo, pPath, pSourceCode, callBackFunction) {
let blobText = nodify(pSourceCode.toString());
storage.writeData(pDevTeam + "/" + pSource, pRepo, pPath, blobText, onDataWritten);
function onDataWritten(err) {
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
console.log("[ERROR] API -> saveBotCode -> Source code file could not be saved. ");
console.log("[ERROR] API -> saveBotCode -> err.message = " + err.message);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
return;
}
callBackFunction(global.DEFAULT_OK_RESPONSE);
}
}
function nodify(pData) {
let start = pData.indexOf('function') + 9;
let end = pData.indexOf('(') + 0;
let functionName = pData.substring(start, end);
let result = "exports." + functionName + " = " + pData;
result = replaceAll(result, "webRequire", "require");
result = replaceAll(result, "window", "global");
return result;
function replaceAll(text, search, replacement) {
return text.replace(new RegExp(search, 'g'), replacement);
}
}
}
File diff suppressed because it is too large. Load diff
+102
View File
@@ -0,0 +1,102 @@
exports.newUserAuthentication = function newUserAuthentication() {
MAX_STORAGE_PERMISSION_DAYS = 3;
let thisObject = {
authenticateUser: authenticateUser,
initialize: initialize
};
let sessionManager;
let storageAccessManager;
return thisObject;
function initialize(pSessionManager, pStorageAccessManager) {
sessionManager = pSessionManager;
storageAccessManager = pStorageAccessManager;
}
function authenticateUser(pSessionToken, callBackFunction) {
let userProfile = {
userName: "",
devTeams: [],
storagePermissions: []
};
/* The first possibility is that the sessionToken is not there. */
if (pSessionToken === "") {
callBackFunction(global.DEFAULT_OK_RESPONSE, userProfile);
return;
}
/* The second posiibility is that the session is not found. */
let session = sessionManager.getSession(pSessionToken);
if (session === undefined) {
let customResponse = {
result: global.CUSTOM_FAIL_RESPONSE.result,
message: "Invalid session token received. Please login again."
};
callBackFunction(customResponse, userProfile);
return;
}
/* The last one is that the session is found, meaning valid. */
userProfile.userName = session.userName;
userProfile.devTeams = session.devTeams;
for (let i = 0; i < session.devTeams.length; i++) {
let devTeam = session.devTeams[i];
let container = devTeam.codeName.toLowerCase();
let readPermission = storageAccessManager.getPermission(container, "READ", MAX_STORAGE_PERMISSION_DAYS);
let writePermission = storageAccessManager.getPermission(container, "WRITE", MAX_STORAGE_PERMISSION_DAYS);
let deletePermission = storageAccessManager.getPermission(container, "DELETE", MAX_STORAGE_PERMISSION_DAYS);
userProfile.storagePermissions.push([devTeam.codeName + "." + "READ", readPermission]);
userProfile.storagePermissions.push([devTeam.codeName + "." + "WRITE", writePermission]);
userProfile.storagePermissions.push([devTeam.codeName + "." + "DELETE", deletePermission]);
console.log(devTeam.codeName + "." + "READ" + ":" + readPermission);
console.log(devTeam.codeName + "." + "WRITE" + ":" + writePermission);
console.log(devTeam.codeName + "." + "DELETE" + ":" + writePermission);
/* Each devTeam potentially depends on data from other devTeams. The user will need the storage permissions to read that data. */
for (j = 0; j < devTeam.devTeamDependencies.length; j++) {
let dependecy = devTeam.devTeamDependencies[j];
let container = dependecy.toLowerCase();
let readPermission = storageAccessManager.getPermission(container, "READ", MAX_STORAGE_PERMISSION_DAYS);
userProfile.storagePermissions.push([dependecy + "." + "READ", readPermission]);
console.log(dependecy + "." + "READ" + ":" + readPermission);
}
}
/* In order to be able to download a bot source code, the user will need READ permissions over the Platform container. */
let container = "aaplatform";
let readPermission = storageAccessManager.getPermission(container, "READ", MAX_STORAGE_PERMISSION_DAYS);
userProfile.storagePermissions.push(["AAPlatform" + "." + "READ", readPermission]);
callBackFunction(global.DEFAULT_OK_RESPONSE, userProfile);
}
};
-12
View File
@@ -1,12 +0,0 @@
function newAccumulatedVolumeBar() {
var accumulatedVolumeBar = {
begin: undefined,
end: undefined,
accumulatedBuys: 0,
accumulatedSells: 0
};
return accumulatedVolumeBar;
}
-154
View File
@@ -1,154 +0,0 @@
function newAnimation() {
const MODULE_NAME = "Animation";
const INFO_LOG = false;
const ERROR_LOG = true;
const logger = newDebugLog();
logger.fileName = MODULE_NAME;
/*
Essentially, what the animation object does, is to call several functions in order to draw the content of each frame.
To do that, it has an array of functions that need to be called, and it just goes one by one through them. His parent object
is responsible for providing more functions to call, or removing functions from its list when they are not longer needed.
*/
let animationLoopHandle; // This is the handle to the animation loop. With this handle we can cancel the loop, for instance.
let callBackFunctions = new Map();
let thisObject = {
start: start,
stop: stop,
addCallBackFunction: addCallBackFunction,
removeCallBackFunction: removeCallBackFunction,
initialize: initialize
};
return thisObject;
function initialize(callBackFunction) {
try {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> Entering function."); }
/* Nothing to do here yet. */
callBackFunction(GLOBAL.CUSTOM_OK_RESPONSE);
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
function start(callBackFunction) {
try {
if (INFO_LOG === true) { logger.write("[INFO] start -> Entering function."); }
animationLoop(); // Inside this function the animation process is started, and at the same time it creates a loop.
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] start -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
function stop(callBackFunction) {
try {
if (INFO_LOG === true) { logger.write("[INFO] stop -> Entering function."); }
window.cancelAnimationFrame(animationLoopHandle);
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] stop -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
function addCallBackFunction(key, callBack, callBackFunction) {
try {
if (INFO_LOG === true) { logger.write("[INFO] addCallBackFunction -> Entering function."); }
callBackFunctions.set(key, callBack);
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] addCallBackFunction -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
function removeCallBackFunction(key, callBackFunction) {
try {
if (INFO_LOG === true) { logger.write("[INFO] removeCallBackFunction -> Entering function."); }
callBackFunctions.delete(key);
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] removeCallBackFunction -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
function animationLoop(callBackFunction) {
//try {
if (INFO_LOG === true) { logger.write("[INFO] animationLoop -> Entering function."); }
/* First thing is to clear the actual canvas */
clearBrowserCanvas();
/* We loop through the callback functions collections and execute them all. */
callBackFunctions.forEach(function (callBackFunction) {
callBackFunction();
});
/* We request the next frame to be drawn, and stablishing a loop */
animationLoopHandle = window.requestAnimationFrame(animationLoop);
// } catch (err) {
// if (ERROR_LOG === true) { logger.write("[ERROR] animationLoop -> err = " + err); }
// if (callBackFunction !== undefined) { // When the loop is called by the browser there will be no callBackFunction.
// callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
// }
// }
}
function clearBrowserCanvas() {
if (INFO_LOG === true) { logger.write("[INFO] clearBrowserCanvas -> Entering function."); }
browserCanvasContext.clearRect(0, 0, browserCanvas.width, browserCanvas.height);
}
}
-677
View File
@@ -1,677 +0,0 @@
function newButton() {
var button = {
container: undefined,
press: press,
draw: draw,
offFillStyle: 'rgba(150, 150, 250, 1)',
onFillStyle: 'rgba(250, 150, 150, 1)',
status: 'off',
type: undefined,
getContainer: getContainer, // returns the inner most container that holds the point received by parameter.
initialize: initialize
};
var container = newContainer();
container.initialize();
container.isDraggeable = false;
container.isClickeable = true;
button.container = container;
const REDUCTION_FACTOR = 3;
return button;
function initialize() {
/* Lets set the basic dimensions of this button. */
var position = {
x: 0,
y: 0
};
this.container.frame.position = position;
this.container.frame.width = 50 / REDUCTION_FACTOR;
this.container.frame.height = 50 / REDUCTION_FACTOR;
/* Now we start listening to the onClick event from the mouse, so that we can allow users operate this button. */
this.container.eventHandler.listenToEvent('onMouseClick', press, undefined);
}
function getContainer(point) {
var container;
/* First we check if this point is inside this space. */
if (this.container.frame.isThisPointHere(point, true) === true) {
return this.container;
} else {
/* This point does not belong to this space. */
return undefined;
}
}
function press(event, extraData) {
button.status = 'on';
}
function draw() {
switch (this.type) {
case "Fast Backwards":
drawFastBackwards();
break;
case "Play Backwards":
drawPlayBackwards();
break;
case "Step Backwards":
drawStepBackwards();
break;
case "Pause":
drawPause();
break;
case "Step Forward":
drawStepForward();
break;
case "Play Forward":
drawPlayForward();
break;
case "Fast Forward":
drawFastForward();
break;
default:
}
}
function drawFastBackwards() {
point1 = {
x: 40 / REDUCTION_FACTOR,
y: 10 / REDUCTION_FACTOR
};
point2 = {
x: 25 / REDUCTION_FACTOR,
y: 25 / REDUCTION_FACTOR
};
point3 = {
x: 40 / REDUCTION_FACTOR,
y: 40 / REDUCTION_FACTOR
};
point5 = {
x: 25 / REDUCTION_FACTOR,
y: 10 / REDUCTION_FACTOR
};
point6 = {
x: 10 / REDUCTION_FACTOR,
y: 25 / REDUCTION_FACTOR
};
point7 = {
x: 25 / REDUCTION_FACTOR,
y: 40 / REDUCTION_FACTOR
};
/* Now the transformations. */
point1 = button.container.frame.frameThisPoint(point1);
point2 = button.container.frame.frameThisPoint(point2);
point3 = button.container.frame.frameThisPoint(point3);
point5 = button.container.frame.frameThisPoint(point5);
point6 = button.container.frame.frameThisPoint(point6);
point7 = button.container.frame.frameThisPoint(point7);
point1 = button.container.displacement.displaceThisPoint(point1);
point2 = button.container.displacement.displaceThisPoint(point2);
point3 = button.container.displacement.displaceThisPoint(point3);
point5 = button.container.displacement.displaceThisPoint(point5);
point6 = button.container.displacement.displaceThisPoint(point6);
point7 = button.container.displacement.displaceThisPoint(point7);
/* Lets start the drawing. */
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(point1.x, point1.y);
browserCanvasContext.lineTo(point2.x, point2.y);
browserCanvasContext.lineTo(point3.x, point3.y);
browserCanvasContext.lineTo(point1.x, point1.y);
browserCanvasContext.moveTo(point5.x, point5.y);
browserCanvasContext.lineTo(point6.x, point6.y);
browserCanvasContext.lineTo(point7.x, point7.y);
browserCanvasContext.lineTo(point5.x, point5.y);
browserCanvasContext.closePath();
if (button.status === "on") {
browserCanvasContext.fillStyle = button.onFillStyle;
} else {
browserCanvasContext.fillStyle = button.offFillStyle;
}
browserCanvasContext.fill();
browserCanvasContext.strokeStyle = 'rgba(150, 150, 150, 0.5)';
browserCanvasContext.lineWidth = 1;
browserCanvasContext.stroke();
browserCanvasContext.closePath();
}
function drawPlayBackwards() {
point1 = {
x: 40 / REDUCTION_FACTOR,
y: 10 / REDUCTION_FACTOR
};
point2 = {
x: 10 / REDUCTION_FACTOR,
y: 25 / REDUCTION_FACTOR
};
point3 = {
x: 40 / REDUCTION_FACTOR,
y: 40 / REDUCTION_FACTOR
};
/* Now the transformations. */
point1 = button.container.frame.frameThisPoint(point1);
point2 = button.container.frame.frameThisPoint(point2);
point3 = button.container.frame.frameThisPoint(point3);
point1 = button.container.displacement.displaceThisPoint(point1);
point2 = button.container.displacement.displaceThisPoint(point2);
point3 = button.container.displacement.displaceThisPoint(point3);
/* Lets start the drawing. */
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(point1.x, point1.y);
browserCanvasContext.lineTo(point2.x, point2.y);
browserCanvasContext.lineTo(point3.x, point3.y);
browserCanvasContext.lineTo(point1.x, point1.y);
browserCanvasContext.closePath();
if (button.status === "on") {
browserCanvasContext.fillStyle = button.onFillStyle;
} else {
browserCanvasContext.fillStyle = button.offFillStyle;
}
browserCanvasContext.fill();
browserCanvasContext.strokeStyle = 'rgba(150, 150, 150, 0.5)';
browserCanvasContext.lineWidth = 1;
browserCanvasContext.stroke();
browserCanvasContext.closePath();
}
function drawStepBackwards() {
point1 = {
x: 40 / REDUCTION_FACTOR,
y: 10 / REDUCTION_FACTOR
};
point2 = {
x: 20 / REDUCTION_FACTOR,
y: 25 / REDUCTION_FACTOR
};
point3 = {
x: 40 / REDUCTION_FACTOR,
y: 40 / REDUCTION_FACTOR
};
point5 = {
x: 10 / REDUCTION_FACTOR,
y: 10 / REDUCTION_FACTOR
};
point6 = {
x: 20 / REDUCTION_FACTOR,
y: 10 / REDUCTION_FACTOR
};
point7 = {
x: 20 / REDUCTION_FACTOR,
y: 40 / REDUCTION_FACTOR
};
point8 = {
x: 10 / REDUCTION_FACTOR,
y: 40 / REDUCTION_FACTOR
};
/* Now the transformations. */
point1 = button.container.frame.frameThisPoint(point1);
point2 = button.container.frame.frameThisPoint(point2);
point3 = button.container.frame.frameThisPoint(point3);
point5 = button.container.frame.frameThisPoint(point5);
point6 = button.container.frame.frameThisPoint(point6);
point7 = button.container.frame.frameThisPoint(point7);
point8 = button.container.frame.frameThisPoint(point8);
point1 = button.container.displacement.displaceThisPoint(point1);
point2 = button.container.displacement.displaceThisPoint(point2);
point3 = button.container.displacement.displaceThisPoint(point3);
point5 = button.container.displacement.displaceThisPoint(point5);
point6 = button.container.displacement.displaceThisPoint(point6);
point7 = button.container.displacement.displaceThisPoint(point7);
point8 = button.container.displacement.displaceThisPoint(point8);
/* Lets start the drawing. */
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(point1.x, point1.y);
browserCanvasContext.lineTo(point2.x, point2.y);
browserCanvasContext.lineTo(point3.x, point3.y);
browserCanvasContext.lineTo(point1.x, point1.y);
browserCanvasContext.moveTo(point5.x, point5.y);
browserCanvasContext.lineTo(point6.x, point6.y);
browserCanvasContext.lineTo(point7.x, point7.y);
browserCanvasContext.lineTo(point8.x, point8.y);
browserCanvasContext.lineTo(point5.x, point5.y);
browserCanvasContext.closePath();
if (button.status === "on") {
browserCanvasContext.fillStyle = button.onFillStyle;
} else {
browserCanvasContext.fillStyle = button.offFillStyle;
}
browserCanvasContext.fill();
browserCanvasContext.strokeStyle = 'rgba(150, 150, 150, 0.5)';
browserCanvasContext.lineWidth = 1;
browserCanvasContext.stroke();
browserCanvasContext.closePath();
}
function drawPause() {
point1 = {
x: 10 / REDUCTION_FACTOR,
y: 10 / REDUCTION_FACTOR
};
point2 = {
x: 20 / REDUCTION_FACTOR,
y: 10 / REDUCTION_FACTOR
};
point3 = {
x: 20 / REDUCTION_FACTOR,
y: 40 / REDUCTION_FACTOR
};
point4 = {
x: 10 / REDUCTION_FACTOR,
y: 40 / REDUCTION_FACTOR
};
point5 = {
x: 30 / REDUCTION_FACTOR,
y: 10 / REDUCTION_FACTOR
};
point6 = {
x: 40 / REDUCTION_FACTOR,
y: 10 / REDUCTION_FACTOR
};
point7 = {
x: 40 / REDUCTION_FACTOR,
y: 40 / REDUCTION_FACTOR
};
point8 = {
x: 30 / REDUCTION_FACTOR,
y: 40 / REDUCTION_FACTOR
};
/* Now the transformations. */
point1 = button.container.frame.frameThisPoint(point1);
point2 = button.container.frame.frameThisPoint(point2);
point3 = button.container.frame.frameThisPoint(point3);
point4 = button.container.frame.frameThisPoint(point4);
point5 = button.container.frame.frameThisPoint(point5);
point6 = button.container.frame.frameThisPoint(point6);
point7 = button.container.frame.frameThisPoint(point7);
point8 = button.container.frame.frameThisPoint(point8);
point1 = button.container.displacement.displaceThisPoint(point1);
point2 = button.container.displacement.displaceThisPoint(point2);
point3 = button.container.displacement.displaceThisPoint(point3);
point4 = button.container.displacement.displaceThisPoint(point4);
point5 = button.container.displacement.displaceThisPoint(point5);
point6 = button.container.displacement.displaceThisPoint(point6);
point7 = button.container.displacement.displaceThisPoint(point7);
point8 = button.container.displacement.displaceThisPoint(point8);
/* Lets start the drawing. */
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(point1.x, point1.y);
browserCanvasContext.lineTo(point2.x, point2.y);
browserCanvasContext.lineTo(point3.x, point3.y);
browserCanvasContext.lineTo(point4.x, point4.y);
browserCanvasContext.lineTo(point1.x, point1.y);
browserCanvasContext.moveTo(point5.x, point5.y);
browserCanvasContext.lineTo(point6.x, point6.y);
browserCanvasContext.lineTo(point7.x, point7.y);
browserCanvasContext.lineTo(point8.x, point8.y);
browserCanvasContext.lineTo(point5.x, point5.y);
browserCanvasContext.closePath();
if (button.status === "on") {
browserCanvasContext.fillStyle = button.onFillStyle;
} else {
browserCanvasContext.fillStyle = button.offFillStyle;
}
browserCanvasContext.fill();
browserCanvasContext.strokeStyle = 'rgba(150, 150, 150, 0.5)';
browserCanvasContext.lineWidth = 1;
browserCanvasContext.stroke();
browserCanvasContext.closePath();
}
function drawStepForward() {
point1 = {
x: 10 / REDUCTION_FACTOR,
y: 10 / REDUCTION_FACTOR
};
point2 = {
x: 30 / REDUCTION_FACTOR,
y: 25 / REDUCTION_FACTOR
};
point3 = {
x: 10 / REDUCTION_FACTOR,
y: 40 / REDUCTION_FACTOR
};
point5 = {
x: 30 / REDUCTION_FACTOR,
y: 10 / REDUCTION_FACTOR
};
point6 = {
x: 40 / REDUCTION_FACTOR,
y: 10 / REDUCTION_FACTOR
};
point7 = {
x: 40 / REDUCTION_FACTOR,
y: 40 / REDUCTION_FACTOR
};
point8 = {
x: 30 / REDUCTION_FACTOR,
y: 40 / REDUCTION_FACTOR
};
/* Now the transformations. */
point1 = button.container.frame.frameThisPoint(point1);
point2 = button.container.frame.frameThisPoint(point2);
point3 = button.container.frame.frameThisPoint(point3);
point5 = button.container.frame.frameThisPoint(point5);
point6 = button.container.frame.frameThisPoint(point6);
point7 = button.container.frame.frameThisPoint(point7);
point8 = button.container.frame.frameThisPoint(point8);
point1 = button.container.displacement.displaceThisPoint(point1);
point2 = button.container.displacement.displaceThisPoint(point2);
point3 = button.container.displacement.displaceThisPoint(point3);
point5 = button.container.displacement.displaceThisPoint(point5);
point6 = button.container.displacement.displaceThisPoint(point6);
point7 = button.container.displacement.displaceThisPoint(point7);
point8 = button.container.displacement.displaceThisPoint(point8);
/* Lets start the drawing. */
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(point1.x, point1.y);
browserCanvasContext.lineTo(point2.x, point2.y);
browserCanvasContext.lineTo(point3.x, point3.y);
browserCanvasContext.lineTo(point1.x, point1.y);
browserCanvasContext.moveTo(point5.x, point5.y);
browserCanvasContext.lineTo(point6.x, point6.y);
browserCanvasContext.lineTo(point7.x, point7.y);
browserCanvasContext.lineTo(point8.x, point8.y);
browserCanvasContext.lineTo(point5.x, point5.y);
browserCanvasContext.closePath();
if (button.status === "on") {
browserCanvasContext.fillStyle = button.onFillStyle;
} else {
browserCanvasContext.fillStyle = button.offFillStyle;
}
browserCanvasContext.fill();
browserCanvasContext.strokeStyle = 'rgba(150, 150, 150, 0.5)';
browserCanvasContext.lineWidth = 1;
browserCanvasContext.stroke();
browserCanvasContext.closePath();
}
function drawPlayForward() {
point1 = {
x: 10 / REDUCTION_FACTOR,
y: 10 / REDUCTION_FACTOR
};
point2 = {
x: 40 / REDUCTION_FACTOR,
y: 25 / REDUCTION_FACTOR
};
point3 = {
x: 10 / REDUCTION_FACTOR,
y: 40 / REDUCTION_FACTOR
};
/* Now the transformations. */
point1 = button.container.frame.frameThisPoint(point1);
point2 = button.container.frame.frameThisPoint(point2);
point3 = button.container.frame.frameThisPoint(point3);
point1 = button.container.displacement.displaceThisPoint(point1);
point2 = button.container.displacement.displaceThisPoint(point2);
point3 = button.container.displacement.displaceThisPoint(point3);
/* Lets start the drawing. */
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(point1.x, point1.y);
browserCanvasContext.lineTo(point2.x, point2.y);
browserCanvasContext.lineTo(point3.x, point3.y);
browserCanvasContext.lineTo(point1.x, point1.y);
browserCanvasContext.closePath();
if (button.status === "on") {
browserCanvasContext.fillStyle = button.onFillStyle;
} else {
browserCanvasContext.fillStyle = button.offFillStyle;
}
browserCanvasContext.fill();
browserCanvasContext.strokeStyle = 'rgba(150, 150, 150, 0.5)';
browserCanvasContext.lineWidth = 1;
browserCanvasContext.stroke();
browserCanvasContext.closePath();
}
function drawFastForward() {
point1 = {
x: 10 / REDUCTION_FACTOR,
y: 10 / REDUCTION_FACTOR
};
point2 = {
x: 25 / REDUCTION_FACTOR,
y: 25 / REDUCTION_FACTOR
};
point3 = {
x: 10 / REDUCTION_FACTOR,
y: 40 / REDUCTION_FACTOR
};
point5 = {
x: 25 / REDUCTION_FACTOR,
y: 10 / REDUCTION_FACTOR
};
point6 = {
x: 40 / REDUCTION_FACTOR,
y: 25 / REDUCTION_FACTOR
};
point7 = {
x: 25 / REDUCTION_FACTOR,
y: 40 / REDUCTION_FACTOR
};
/* Now the transformations. */
point1 = button.container.frame.frameThisPoint(point1);
point2 = button.container.frame.frameThisPoint(point2);
point3 = button.container.frame.frameThisPoint(point3);
point5 = button.container.frame.frameThisPoint(point5);
point6 = button.container.frame.frameThisPoint(point6);
point7 = button.container.frame.frameThisPoint(point7);
point1 = button.container.displacement.displaceThisPoint(point1);
point2 = button.container.displacement.displaceThisPoint(point2);
point3 = button.container.displacement.displaceThisPoint(point3);
point5 = button.container.displacement.displaceThisPoint(point5);
point6 = button.container.displacement.displaceThisPoint(point6);
point7 = button.container.displacement.displaceThisPoint(point7);
/* Lets start the drawing. */
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(point1.x, point1.y);
browserCanvasContext.lineTo(point2.x, point2.y);
browserCanvasContext.lineTo(point3.x, point3.y);
browserCanvasContext.lineTo(point1.x, point1.y);
browserCanvasContext.moveTo(point5.x, point5.y);
browserCanvasContext.lineTo(point6.x, point6.y);
browserCanvasContext.lineTo(point7.x, point7.y);
browserCanvasContext.lineTo(point5.x, point5.y);
browserCanvasContext.closePath();
if (button.status === "on") {
browserCanvasContext.fillStyle = button.onFillStyle;
} else {
browserCanvasContext.fillStyle = button.offFillStyle;
}
browserCanvasContext.fill();
browserCanvasContext.strokeStyle = 'rgba(150, 150, 150, 0.5)';
browserCanvasContext.lineWidth = 1;
browserCanvasContext.stroke();
browserCanvasContext.closePath();
}
}
-17
View File
@@ -1,17 +0,0 @@
function newCandle() {
var candle = {
open: undefined,
close: undefined,
min: 10000000000000,
max: 0,
begin: undefined,
end: undefined,
direction: undefined,
beginId: undefined,
endId: undefined
};
return candle;
}
-476
View File
@@ -1,476 +0,0 @@
/*
Whithin this sub-system, the canvas object represents a layer on top of the browser canvas object.
Graphically, this sub-system has 3 spaces:
1) The "Chart Space": It is where the charts are plotted.
2) The "Floating Space": It is where floating elements live. There is a physics engine for this layer that allows these elements to flow.
3) The "Panels Space": It is where panels live. --> This space has yet to be develop, currently pannels are somehow at the Chart Space.
All these spaces are child objects of the Canvas object.
Canvas
|
|
---> chartSpace
|
|
---> flaotingSpace
|
|
---> panelsSpace
*/
let browserCanvas; // This is the canvas object of the browser.
let browserCanvasContext; // The context of the canvas object.
let stepsInitializationCounter = 0; // This counter the initialization steps required to be able to turn off the splash screen.
let marketInitializationCounter = 0; // This counter the initialization of markets required to be able to turn off the splash screen.
let splashScreenNeeded = true;
function newCanvas() {
const MODULE_NAME = "Canvas";
const INFO_LOG = false;
const ERROR_LOG = true;
const logger = newDebugLog();
logger.fileName = MODULE_NAME;
/* Mouse event related variables. */
let containerDragStarted = false;
let floatingObjectDragStarted = false;
let floatingObjectBeingDragged;
let containerBeingDragged;
let viewPortBeingDragged = false;
let dragVector = {
downX: 0,
downY: 0,
upX: 0,
upY: 0
};
/* canvas object */
let thisObject = {
eventHandler: undefined,
chartSpace: undefined,
floatingSpace: undefined,
panelsSpace: undefined,
animation: undefined,
initialize: initialize
};
thisObject.eventHandler = newEventHandler();
let splashScreen;
return thisObject;
function initialize(callBackFunction) {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> Entering function."); }
initializeBrowserCanvas();
addCanvasEvents();
/* Instantiate all the children of Canvas object */
let panelsSpace = newPanelsSpace();
panelsSpace.initialize();
this.panelsSpace = panelsSpace;
let floatingSpace = newFloatingSpace();
floatingSpace.initialize();
this.floatingSpace = floatingSpace;
let chartSpace = newChartSpace();
chartSpace.initialize();
this.chartSpace = chartSpace;
/* Splash Screen */
splashScreen = newSplashScreen();
splashScreen.initialize();
let animation = newAnimation();
animation.initialize(onAnimationInitialized);
function onAnimationInitialized(err) {
this.animation = animation;
/* Here we add all the functions that will be called during the animation cycle. */
animation.addCallBackFunction("Chart Space", thisObject.chartSpace.draw, onFunctionAdded);
animation.addCallBackFunction("Floating Space", thisObject.floatingSpace.floatingLayer.physicsLoop, onFunctionAdded);
animation.addCallBackFunction("Panels Space", thisObject.panelsSpace.draw, onFunctionAdded);
animation.addCallBackFunction("Splash Screen", splashScreen.draw, onFunctionAdded);
animation.addCallBackFunction("ViewPort Animate", viewPort.animate, onFunctionAdded);
animation.addCallBackFunction("ViewPort Draw", viewPort.draw, onFunctionAdded);
animation.start(onStart);
function onFunctionAdded(err) {
if (err.result === GLOBAL.DEFAULT_FAIL_RESPONSE.result) {
animation.stop();
if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> onAnimationInitialized -> onFunctionAdded -> Animation Stopped since a vital funtion could not be added."); }
/* Display some Error Page here. */
}
}
function onStart(err) {
switch (err.result) {
case GLOBAL.DEFAULT_OK_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onAnimationInitialized -> onStart -> Received OK Response."); }
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE);
return;
}
case GLOBAL.DEFAULT_FAIL_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onAnimationInitialized -> onStart -> Received FAIL Response."); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
return;
}
default: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onAnimationInitialized -> onStart -> Received Unexpected Response."); }
callBackFunction(err);
return;
}
}
}
}
}
function initializeBrowserCanvas() {
if (INFO_LOG === true) { logger.write("[INFO] initializeBrowserCanvas -> Entering function."); }
browserCanvas = document.getElementById('canvas');
browserCanvasContext = browserCanvas.getContext('2d');
let body = document.getElementById('body');
browserCanvas.width = window.innerWidth;
browserCanvas.height = window.innerHeight;
browserCanvas.style.border = "none";
viewPort.initialize();
}
function addCanvasEvents() {
if (INFO_LOG === true) { logger.write("[INFO] addCanvasEvents -> Entering function."); }
/* Mouse down and up events to control the drag of the canvas. */
browserCanvas.addEventListener('mousedown', onMouseDown, false);
browserCanvas.addEventListener('mouseup', onMouseUp, false);
browserCanvas.addEventListener('mousemove', onMouseMove, false);
browserCanvas.addEventListener('click', onMouseClick, false);
/* Mouse wheel events. */
if (browserCanvas.addEventListener) {
// IE9, Chrome, Safari, Opera
browserCanvas.addEventListener("mousewheel", onMouseWheel, false);
// Firefox
browserCanvas.addEventListener("DOMMouseScroll", onMouseWheel, false);
}
// IE 6/7/8
else browserCanvas.attachEvent("onmousewheel", onMouseWheel);
}
function onMouseDown(event) {
if (INFO_LOG === true) { logger.write("[INFO] onMouseDown -> Entering function."); }
/*
There are four types of elements that can be dragged.
1. Panels.
2. Floating Elements (Currently only FloatingObjects).
3. Charts.
4. The Viewport.
We eveluate each space in order to see if they are holding the element being dragged, and we fallout at the Viewport.
*/
dragVector.downX = event.pageX;
dragVector.downY = event.pageY;
let point = {
x: event.pageX,
y: event.pageY
};
let container;
/* We check first if the mouse is over a panel/ */
container = thisObject.panelsSpace.getContainer(point);
if (container !== undefined && container.isDraggeable === true) {
containerBeingDragged = container;
containerDragStarted = true;
return;
}
/* We check first if the mouse is over a floatingObject/ */
floatingObjectBeingDragged = thisObject.floatingSpace.floatingLayer.isInside(event.pageX, event.pageY);
if (floatingObjectBeingDragged >= 0) {
floatingObjectDragStarted = true;
return;
}
/* If it is not, then we check if it is over any of the existing containers at the Chart Space. */
container = thisObject.chartSpace.getContainer(point);
if (container !== undefined && container.isDraggeable === true) {
containerBeingDragged = container;
containerDragStarted = true;
return;
}
viewPortBeingDragged = true;
}
function onMouseClick(event) {
if (INFO_LOG === true) { logger.write("[INFO] onMouseClick -> Entering function."); }
let point = {
x: event.pageX,
y: event.pageY
};
let container;
/* We check first if the mouse is over a panel/ */
container = thisObject.panelsSpace.getContainer(point);
if (container !== undefined && container.isClickeable === true) {
container.eventHandler.raiseEvent('onMouseClick', event);
return;
}
/* We check first if the mouse is over a floatingObject/ */
let floatingObjectBeingClicked = thisObject.floatingSpace.floatingLayer.isInside(event.pageX, event.pageY);
if (floatingObjectBeingClicked >= 0) {
/* Right now we do nothing with this. */
return;
}
/* If it is not, then we check if it is over any of the existing containers at the Chart Space. */
container = thisObject.chartSpace.getContainer(point);
if (container !== undefined && container.isClickeable === true) {
container.eventHandler.raiseEvent('onMouseClick', event);
return;
}
}
function onMouseUp(event) {
if (INFO_LOG === true) { logger.write("[INFO] onMouseUp -> Entering function."); }
if (containerDragStarted || viewPortBeingDragged || floatingObjectDragStarted) {
thisObject.eventHandler.raiseEvent("Drag Finished", undefined);
}
/* Turn off all the possible things that can be dragged. */
containerDragStarted = false;
floatingObjectDragStarted = false;
viewPortBeingDragged = false;
containerBeingDragged = undefined;
browserCanvas.style.cursor = "auto";
}
function onMouseMove(event) {
if (INFO_LOG === true) { logger.write("[INFO] onMouseMove -> Entering function."); }
viewPort.mousePosition.x = event.pageX;
viewPort.mousePosition.y = event.pageY;
if (containerDragStarted === true || floatingObjectDragStarted === true || viewPortBeingDragged === true) {
if (floatingObjectDragStarted === true) {
if (thisObject.floatingSpace.floatingLayer.isInsideFloatingObject(floatingObjectBeingDragged, event.pageX, event.pageY) === false) {
/* This means that the user stop moving the mouse and the floatingObject floatingObject out of the pointer.
In this case we cancell the drag operation . */
floatingObjectDragStarted = false;
browserCanvas.style.cursor = "auto";
return;
}
}
dragVector.upX = event.pageX;
dragVector.upY = event.pageY;
checkDrag();
}
}
function onMouseWheel(event) {
if (INFO_LOG === true) { logger.write("[INFO] onMouseWheel -> Entering function."); }
// cross-browser wheel delta
var event = window.event || event; // old IE support
let delta = Math.max(-1, Math.min(1, event.wheelDelta || -event.detail));
/* We try first with panels. */
let panelContainer = canvas.panelsSpace.getContainer({ x: event.pageX, y: event.pageY });
if (panelContainer !== undefined && panelContainer.isWheelable === true) {
panelContainer.eventHandler.raiseEvent("Mouse Wheel", event.wheelDelta);
return false; // This instructs the browser not to take the event and scroll the page.
}
/* We try second with floating objects. */
let floatingObjectIndex = canvas.floatingSpace.floatingLayer.isInside(event.pageX, event.pageY);
if (floatingObjectIndex > 0) {
canvas.floatingSpace.floatingLayer.changeTargetRepulsion(event.wheelDelta);
} else {
viewPort.applyZoom(delta);
}
return false; // This instructs the browser not to take the event and scroll the page.
}
function checkDrag() {
if (INFO_LOG === true) { logger.write("[INFO] checkDrag -> Entering function."); }
if (containerDragStarted === true || floatingObjectDragStarted === true || viewPortBeingDragged === true) {
browserCanvas.style.cursor = "grabbing";
thisObject.eventHandler.raiseEvent("Dragging", undefined);
let targetFloatingObject = thisObject.floatingSpace.floatingLayer.isInside(event.pageX, event.pageY);
if (floatingObjectDragStarted) {
let floatingObject = thisObject.floatingSpace.floatingLayer.getFloatingObject(undefined, floatingObjectBeingDragged);
floatingObject.currentPosition.x = dragVector.upX;
floatingObject.currentPosition.y = dragVector.upY;
}
if (containerDragStarted || viewPortBeingDragged) {
/* The parameters received have been captured with zoom applied. We must remove the zoom in order to correctly modify the displacement. */
let downCopy = {
x: dragVector.downX,
y: dragVector.downY
};
let downCopyNoTransf;
downCopyNoTransf = viewPort.unzoomThisPoint(downCopy);
//downCopyNoTransf = containerBeingDragged.zoom.unzoomThisPoint(downCopyNoTransf);
let upCopy = {
x: dragVector.upX,
y: dragVector.upY
};
let upCopyNoTranf;
upCopyNoTranf = viewPort.unzoomThisPoint(upCopy);
//upCopyNoTranf = containerBeingDragged.zoom.unzoomThisPoint(upCopyNoTranf);
/*
let displaceVector = {
x: upCopyNoTranf.x - downCopyNoTransf.x,
y: upCopyNoTranf.y - downCopyNoTransf.y
};
*/
let displaceVector = {
x: dragVector.upX - dragVector.downX,
y: dragVector.upY - dragVector.downY
};
if (viewPortBeingDragged) {
viewPort.displace(displaceVector);
}
if (containerBeingDragged !== undefined) {
containerBeingDragged.frame.position.x = containerBeingDragged.frame.position.x + displaceVector.x;
containerBeingDragged.frame.position.y = containerBeingDragged.frame.position.y + displaceVector.y;
}
}
/* Finally we set the starting point of the new dragVector at this current point. */
dragVector.downX = dragVector.upX;
dragVector.downY = dragVector.upY;
}
}
}
-678
View File
@@ -1,678 +0,0 @@
function newChartGrid() {
var chartGrid = {
draw: draw
};
return chartGrid;
function draw(container, timeLineCoordinateSystem) {
let periods = [];
let boxes = [];
let labels = [];
const basePeriod = {
x: 8 * 60 * 60 * 1000,
y: timeLineCoordinateSystem.max.y / 1000 / CHART_ASPECT_RATIO
};
let period = {
x: basePeriod.x,
y: basePeriod.y
};
calculateTimeLabels();
printLabels(1000, 10000);
function calculateTimeLabels() {
periods.push(period); // 0
period = {
x: basePeriod.x / 8,
y: basePeriod.y / 10
};
periods.push(period); // 1
period = {
x: basePeriod.x / 8 / 6,
y: basePeriod.y / 100
};
periods.push(period); // 2
period = {
x: basePeriod.x * 3,
y: basePeriod.y * 10
};
periods.push(period); // 3
period = {
x: basePeriod.x * 3 * 7,
y: basePeriod.y * 100
};
periods.push(period); // 4
/* Period #2 Plotting */
boxes = [];
plotGrid(periods[2]);
labels = [];
/* Label Calculation */
for (let i = 0; i < boxes.length; i++) {
const UPPER_PERIOD = 1;
let box = boxes[i];
let currentValue = box.topLeft;
currentValue = unTransformThisPoint(currentValue, container);
currentValue = timeLineCoordinateSystem.unInverseTransform(currentValue, container.frame.height);
/* We must compare the current value on the current period, against the next period, to know which cell we are in. */
let distanceToNextPeriod = Math.trunc((currentValue.x / periods[UPPER_PERIOD].x - Math.trunc(currentValue.x / periods[UPPER_PERIOD].x)) * 1000);
switch (distanceToNextPeriod) {
case 0: {
labels.push("0");
break;
}
case Math.trunc(1 / 6 * 1000): {
}
labels.push("10");
break;
case Math.trunc(2 / 6 * 1000): {
}
labels.push("20");
break;
case Math.trunc(3 / 6 * 1000): {
}
labels.push("30");
break;
case Math.trunc(4 / 6 * 1000): {
}
labels.push("40");
break;
case Math.trunc(5 / 6 * 1000): {
}
labels.push("50");
break;
}
}
printLabels(1, 150);
/* Period #1 Plotting */
boxes = [];
plotGrid(periods[1]);
labels = [];
/* Label Calculation */
for (let i = 0; i < boxes.length; i++) {
const UPPER_PERIOD = 3;
let box = boxes[i];
let currentValue = box.topLeft;
currentValue = unTransformThisPoint(currentValue, container);
currentValue = timeLineCoordinateSystem.unInverseTransform(currentValue, container.frame.height);
/* We must compare the current value on the current period, against the next period, to know which cell we are in. */
let distanceToNextPeriod = Math.trunc((currentValue.x / periods[UPPER_PERIOD].x - Math.trunc(currentValue.x / periods[UPPER_PERIOD].x)) * 1000);
switch (distanceToNextPeriod) {
case 0: {
labels.push("0 Hs");
break;
}
case Math.trunc(1 / 24 * 1000): {
}
labels.push("1 Hs");
break;
case Math.trunc(2 / 24 * 1000): {
}
labels.push("2 Hs");
break;
case Math.trunc(3 / 24 * 1000): {
}
labels.push("3 Hs");
break;
case Math.trunc(4 / 24 * 1000): {
}
labels.push("4 Hs");
break;
case Math.trunc(5 / 24 * 1000): {
}
labels.push("5 Hs");
break;
case Math.trunc(6 / 24 * 1000): {
}
labels.push("6 Hs");
break;
case Math.trunc(7 / 24 * 1000): {
}
labels.push("7 Hs");
break;
case Math.trunc(8 / 24 * 1000): {
}
labels.push("8 Hs");
break;
case Math.trunc(9 / 24 * 1000): {
}
labels.push("9 Hs");
break;
case Math.trunc(10 / 24 * 1000): {
}
labels.push("10 Hs");
break;
case Math.trunc(11 / 24 * 1000): {
}
labels.push("11 Hs");
break;
case Math.trunc(12 / 24 * 1000): {
}
labels.push("12 Hs");
break;
case Math.trunc(13 / 24 * 1000): {
}
labels.push("13 Hs");
break;
case Math.trunc(14 / 24 * 1000): {
}
labels.push("14 Hs");
break;
case Math.trunc(15 / 24 * 1000): {
}
labels.push("15 Hs");
break;
case Math.trunc(16 / 24 * 1000): {
}
labels.push("16 Hs");
break;
case Math.trunc(17 / 24 * 1000): {
}
labels.push("17 Hs");
break;
case Math.trunc(18 / 24 * 1000): {
}
labels.push("18 Hs");
break;
case Math.trunc(19 / 24 * 1000): {
}
labels.push("19 Hs");
break;
case Math.trunc(20 / 24 * 1000): {
}
labels.push("20 Hs");
break;
case Math.trunc(21 / 24 * 1000): {
}
labels.push("21 Hs");
break;
case Math.trunc(22 / 24 * 1000): {
}
labels.push("22 Hs");
break;
case Math.trunc(23 / 24 * 1000): {
}
labels.push("23 Hs");
break;
}
}
printLabels(5, 250);
/* Period #0 Plotting */
boxes = [];
plotGrid(periods[0]);
labels = [];
/* Label Calculation */
for (let i = 0; i < boxes.length; i++) {
const UPPER_PERIOD = 3;
let box = boxes[i];
let currentValue = box.topLeft;
currentValue = unTransformThisPoint(currentValue, container);
currentValue = timeLineCoordinateSystem.unInverseTransform(currentValue, container.frame.height);
/* We must compare the current value on the current period, against the next period, to know which cell we are in. */
let distanceToNextPeriod = Math.trunc((currentValue.x / periods[UPPER_PERIOD].x - Math.trunc(currentValue.x / periods[UPPER_PERIOD].x)) * 1000);
switch (distanceToNextPeriod) {
case 0: {
labels.push("Morning");
break;
}
case Math.trunc(1 / 3 * 1000): {
}
labels.push("Afternoon");
break;
case Math.trunc(2 / 3 * 1000): {
}
labels.push("Evening");
break;
}
}
printLabels(15, 50);
/* Period #3 Plotting */
boxes = [];
plotGrid(periods[3]);
labels = [];
/* Label Calculation */
for (let i = 0; i < boxes.length; i++) {
const UPPER_PERIOD = 1;
let box = boxes[i];
let currentValue = box.topLeft;
currentValue = unTransformThisPoint(currentValue, container);
currentValue = timeLineCoordinateSystem.unInverseTransform(currentValue, container.frame.height);
let date = new Date(currentValue.x);
labels.push(date.toDateString());
}
printLabels(100, 2250);
/* Period #4 Plotting */
boxes = [];
plotGrid(periods[4]);
labels = [];
/* Label Calculation */
for (let i = 0; i < boxes.length; i++) {
const UPPER_PERIOD = 1;
let box = boxes[i];
let currentValue = box.topLeft;
currentValue = unTransformThisPoint(currentValue, container);
currentValue = timeLineCoordinateSystem.unInverseTransform(currentValue, container.frame.height);
let date = new Date(currentValue.x);
var monthNames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
labels.push(monthNames[date.getMonth()] + ' ' + date.getFullYear());
}
}
function plotGrid(period) {
let periodWidth = period.x;
let periodHeight = period.y;
let visiblePoint1 = {
x: viewPort.visibleArea.topLeft.x,
y: viewPort.visibleArea.bottomLeft.y
};
visiblePoint1 = unTransformThisPoint(visiblePoint1, container);
visiblePoint1 = timeLineCoordinateSystem.unInverseTransform(visiblePoint1, container.frame.height);
let visiblePoint2 = {
x: viewPort.visibleArea.bottomRight.x,
y: viewPort.visibleArea.topRight.y
};
visiblePoint2 = unTransformThisPoint(visiblePoint2, container);
visiblePoint2 = timeLineCoordinateSystem.unInverseTransform(visiblePoint2, container.frame.height);
startingPoint = {
x: Math.trunc(visiblePoint1.x / periodWidth) * periodWidth,
y: Math.round(Math.trunc(visiblePoint1.y / periodHeight) * periodHeight * 100000) / 100000
};
endingPoint = {
x: Math.trunc(visiblePoint2.x / periodWidth) * periodWidth,
y: Math.trunc(visiblePoint2.y / periodHeight) * periodHeight
};
let lineWidth;
if (viewPort.zoomLevel > 0) {
lineWidth = period.x / basePeriod.x + period.x / basePeriod.x * viewPort.zoomLevel / 20;
} else {
lineWidth = period.x / basePeriod.x + period.x / basePeriod.x * viewPort.zoomLevel / 80;
}
if (lineWidth < 0.7) {
return;
}
if (lineWidth > 1.4) {
lineWidth = 1.4;
}
browserCanvasContext.beginPath();
let y1;
let y2;
let lastRightLabelPosition = {
x: 0,
y: 0
};
let lastLeftLabelPosition = {
x: 0,
y: 0
};
for (var j = startingPoint.y; j <= endingPoint.y + periodHeight; j = j + periodHeight) {
if (j >= 0 && j <= timeLineCoordinateSystem.max.y) {
let point1 = {
x: visiblePoint1.x,
y: j
};
let point2 = {
x: visiblePoint2.x,
y: j
};
point1 = timeLineCoordinateSystem.transformThisPoint(point1);
point2 = timeLineCoordinateSystem.transformThisPoint(point2);
point1 = transformThisPoint(point1, container);
point2 = transformThisPoint(point2, container);
if (point1.y >= viewPort.visibleArea.topLeft.y) {
/* Here we keep the last two positive valued of y */
y2 = y1;
y1 = point1.y;
}
point1 = viewPort.fitIntoVisibleArea(point1);
point2 = viewPort.fitIntoVisibleArea(point2);
browserCanvasContext.moveTo(point1.x, point1.y);
browserCanvasContext.lineTo(point2.x, point2.y);
/* Now we put the scale on the right side of the chart */
rightScale();
leftScale();
function rightScale() {
let fontSize = 10;
let label = ' ' + Math.round(j * 1000000) / 1000000 / 4; // TODO This 4 is to be removed.
let labelPoint = {
x: viewPort.visibleArea.bottomRight.x + 1,
y: point1.y + fontSize / 2 * FONT_ASPECT_RATIO
};
if (Math.abs(lastRightLabelPosition.y - labelPoint.y > fontSize || lastRightLabelPosition.y === 0)) {
if (labelPoint.y > viewPort.visibleArea.topLeft.y + fontSize && labelPoint.y < viewPort.visibleArea.bottomRight.y - fontSize) {
browserCanvasContext.font = fontSize + 'px Courier New';
browserCanvasContext.fillStyle = 'rgba(60, 60, 60, 0.50)';
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y);
}
}
lastRightLabelPosition.x = labelPoint.x;
lastRightLabelPosition.y = labelPoint.y;
}
function leftScale() {
let fontSize = 10;
/*
j is a value between 0 and the max y on the scale of the products.
If we want to convert j to the scale of profits we need to apply the following formula:
*/
let labelValue = (j - timeLineCoordinateSystem.max.y / 2) * 200 / timeLineCoordinateSystem.max.y;
labelValue = Math.round(labelValue * 1000000) / 1000000;
if (labelValue > 0) { labelValue = '+' + labelValue; }
if (parseInt(labelValue) > -10 && parseInt(labelValue) < 10) { labelValue = ' ' + labelValue; }
if (parseInt(labelValue) === 0) { labelValue = ' ' + labelValue; }
let label = ' ' + pad(labelValue, 3) + '%';
let labelPoint = {
x: -2,
y: point1.y + fontSize / 2 * FONT_ASPECT_RATIO
};
if (Math.abs(lastLeftLabelPosition.y - labelPoint.y > fontSize || lastLeftLabelPosition.y === 0)) {
if (labelPoint.y > viewPort.visibleArea.topLeft.y + fontSize && labelPoint.y < viewPort.visibleArea.bottomRight.y - fontSize) {
browserCanvasContext.font = fontSize + 'px Courier New';
browserCanvasContext.fillStyle = 'rgba(60, 60, 60, 0.50)';
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y);
}
}
lastLeftLabelPosition.x = labelPoint.x;
lastLeftLabelPosition.y = labelPoint.y;
}
}
}
let x1;
let x2;
for (var i = startingPoint.x; i <= endingPoint.x + periodWidth; i = i + periodWidth) {
let point3 = {
x: i,
y: 0
};
let point4 = {
x: i,
y: timeLineCoordinateSystem.max.y
};
point3 = timeLineCoordinateSystem.transformThisPoint(point3);
point4 = timeLineCoordinateSystem.transformThisPoint(point4);
point3 = transformThisPoint(point3, container);
point4 = transformThisPoint(point4, container);
/* Here we keep the last two positive valued of y */
x2 = x1;
x1 = point3.x;
if (x2 !== undefined) {
let topLeft = {
x: x2,
y: y1
};
let bottomRight = {
x: x1,
y: y2
};
let box = {
topLeft: topLeft,
bottomRight: bottomRight
};
boxes.push(box);
}
/* Painting the lines */
point3 = viewPort.fitIntoVisibleArea(point3);
point4 = viewPort.fitIntoVisibleArea(point4);
browserCanvasContext.moveTo(point3.x, point3.y);
browserCanvasContext.lineTo(point4.x, point4.y);
}
browserCanvasContext.closePath();
browserCanvasContext.strokeStyle = 'rgba(0, 37, 224, 0.' + Math.trunc(lineWidth + 1) + ')';
browserCanvasContext.lineWidth = lineWidth;
browserCanvasContext.stroke();
}
function printLabels(baseZoomFilter, maxZoom) {
let zoomFilter = viewPort.zoomFontSize(baseZoomFilter);
if (zoomFilter < 7 || zoomFilter > maxZoom) {
return;
}
for (let i = 0; i < boxes.length; i++) {
let label = labels[i];
if (label === undefined) {
label = "undefined";
}
let fontSize = 10;
let labelPoint = {
x: boxes[i].topLeft.x - label.length / 2 * fontSize * FONT_ASPECT_RATIO,
y: viewPort.visibleArea.topLeft.y - fontSize / 2 + 1
};
let xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO;
browserCanvasContext.beginPath();
browserCanvasContext.rect(labelPoint.x, labelPoint.y - fontSize, xOffset * 2, fontSize );
browserCanvasContext.fillStyle = 'rgba(255, 255, 255, 1)';
browserCanvasContext.fill();
browserCanvasContext.closePath();
browserCanvasContext.font = fontSize + 'px Courier New';
browserCanvasContext.fillStyle = 'rgba(60, 60, 60, 0.50)';
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y);
}
browserCanvasContext.fillStyle = 'rgba(255, 255, 255, 1)';
browserCanvasContext.beginPath();
browserCanvasContext.rect(0, 0, viewPort.visibleArea.topLeft.x, viewPort.visibleArea.topLeft.y);
browserCanvasContext.rect(viewPort.visibleArea.topRight.x, 0, 500, viewPort.visibleArea.topLeft.y);
browserCanvasContext.closePath();
browserCanvasContext.fill();
}
}
}
-150
View File
@@ -1,150 +0,0 @@
function getSideDays(timePeriod) {
let daysOnSides;
if (timePeriod < _1_HOUR_IN_MILISECONDS) {
daysOnSides = 1;
}
if (timePeriod === _1_HOUR_IN_MILISECONDS) {
daysOnSides = 9;
}
if (timePeriod === _2_HOURS_IN_MILISECONDS) {
daysOnSides = 10;
}
if (timePeriod === _3_HOURS_IN_MILISECONDS) {
daysOnSides = 12;
}
if (timePeriod === _4_HOURS_IN_MILISECONDS) {
daysOnSides = 20;
}
if (timePeriod === _6_HOURS_IN_MILISECONDS) {
daysOnSides = 35;
}
if (timePeriod === _8_HOURS_IN_MILISECONDS) {
daysOnSides = 44;
}
if (timePeriod === _12_HOURS_IN_MILISECONDS) {
daysOnSides = 56;
}
if (timePeriod === ONE_DAY_IN_MILISECONDS) {
daysOnSides = 154;
}
return daysOnSides;
}
function getCondenseFactor(timePeriod) {
switch (timePeriod) {
case _1_MINUTE_IN_MILISECONDS: return 1;
case _5_MINUTES_IN_MILISECONDS: return 5;
case _10_MINUTES_IN_MILISECONDS: return 10;
case _30_MINUTES_IN_MILISECONDS: return 50;
case _1_HOUR_IN_MILISECONDS: return 100;
}
}
function getTransparenceFactor(timePeriod) {
switch (timePeriod) {
case _1_MINUTE_IN_MILISECONDS: return "0.12";
case _5_MINUTES_IN_MILISECONDS: return "0.10";
case _10_MINUTES_IN_MILISECONDS: return "0.08";
case _30_MINUTES_IN_MILISECONDS: return "0.06";
case _1_HOUR_IN_MILISECONDS: return "0.04";
}
}
function recalculatePeriod(zoomLevel) {
//console.log(" recalculatePeriod > " + zoomLevel);
if (zoomLevel > 200) {
return _1_MINUTE_IN_MILISECONDS;
}
if (zoomLevel > 120) {
return _2_MINUTES_IN_MILISECONDS;
}
if (zoomLevel > 80) {
return _3_MINUTES_IN_MILISECONDS;
}
if (zoomLevel > 60) {
return _4_MINUTES_IN_MILISECONDS;
}
if (zoomLevel > 15) {
return _5_MINUTES_IN_MILISECONDS;
}
if (zoomLevel > - 7) {
return _10_MINUTES_IN_MILISECONDS;
}
if (zoomLevel > - 10) {
return _15_MINUTES_IN_MILISECONDS;
}
if (zoomLevel > - 13) {
return _20_MINUTES_IN_MILISECONDS;
}
if (zoomLevel > - 15) {
return _30_MINUTES_IN_MILISECONDS;
}
if (zoomLevel > - 16) {
return _40_MINUTES_IN_MILISECONDS;
}
if (zoomLevel > - 17) {
return _45_MINUTES_IN_MILISECONDS;
}
if (zoomLevel > - 18) {
return _1_HOUR_IN_MILISECONDS;
}
if (zoomLevel > - 24) {
return _2_HOURS_IN_MILISECONDS;
}
if (zoomLevel > - 25) {
return _3_HOURS_IN_MILISECONDS;
}
if (zoomLevel > - 27) {
return _4_HOURS_IN_MILISECONDS;
}
if (zoomLevel > - 27.5) {
return _6_HOURS_IN_MILISECONDS;
}
if (zoomLevel > - 27.75) {
return _8_HOURS_IN_MILISECONDS;
}
if (zoomLevel > - 28) {
return _12_HOURS_IN_MILISECONDS;
}
if (zoomLevel <= - 28) {
return ONE_DAY_IN_MILISECONDS;
}
}
-156
View File
@@ -1,156 +0,0 @@
function newCompetitionStorage(pName) {
const MODULE_NAME = "Competition Storage";
const INFO_LOG = false;
const ERROR_LOG = true;
const logger = newDebugLog();
logger.fileName = MODULE_NAME;
let thisObject = {
competitorsSequences: [],
eventHandler: undefined,
initialize: initialize
}
thisObject.eventHandler = newEventHandler();
/* We name the event Handler to easy debugging. */
thisObject.eventHandler.name = "Storage-" + pName;
let fileSequences = [];
return thisObject;
function initialize(pHost, pCompetition, pExchange, pMarket, callBackFunction) {
try {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> Entering function."); }
if (INFO_LOG === true) { logger.write("[INFO] initialize -> key = " + pHost.codeName + "-" + pCompetition.codeName); }
let dataSetsToLoad = 0;
let dataSetsLoaded = 0;
fileSequences = [];
for (let j = 0; j < pCompetition.participants.length; j++) {
let devTeam = ecosystem.getTeam(pCompetition.participants[j].devTeam);
let bot = ecosystem.getBot(devTeam, pCompetition.participants[j].bot)
let product = ecosystem.getProduct(bot, "Competition Trading History");
if (INFO_LOG === true) { logger.write("[INFO] initialize -> key = " + devTeam.codeName + "-" + bot.codeName + "-" + product.codeName); }
for (let i = 0; i < product.dataSets.length; i++) {
let thisSet = product.dataSets[i];
switch (thisSet.type) {
case 'File Sequence': {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> File Sequence -> key = " + pHost.codeName + "-" + pCompetition.codeName + "-" + devTeam.codeName + "-" + bot.codeName + "-" + product.codeName); }
let fileSequence = newFileSequence();
fileSequence.initialize(devTeam, bot, product, thisSet, pExchange, pMarket, onFileSequenceReady);
fileSequences.push(fileSequence);
dataSetsToLoad++;
}
break;
}
function onFileSequenceReady(err, pCaller) {
try {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileSequenceReady -> Entering function."); }
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileSequenceReady -> key = " + pHost.codeName + "-" + pCompetition.codeName + "-" + devTeam.codeName + "-" + bot.codeName + "-" + product.codeName); }
switch (err.result) {
case GLOBAL.DEFAULT_OK_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileSequenceReady -> Received OK Response."); }
break;
}
case GLOBAL.DEFAULT_FAIL_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileSequenceReady -> Received FAIL Response."); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
return;
}
case GLOBAL.CUSTOM_FAIL_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileSequenceReady -> Received CUSTOM FAIL Response."); }
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileSequenceReady -> err.message = " + err.message); }
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileSequenceReady -> This bot has not starting competing yet."); }
break;
}
default: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileSequenceReady -> Received Unexpected Response."); }
callBackFunction(err);
return;
}
}
let event = {
totalValue: pCaller.getExpectedFiles(),
currentValue: pCaller.getFilesLoaded()
}
thisObject.eventHandler.raiseEvent('File Sequence Loaded', event);
if (event.currentValue === event.totalValue) {
dataSetsLoaded++;
checkInitializeComplete();
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> onFileSequenceReady -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
function checkInitializeComplete() {
try {
if (INFO_LOG === true) { logger.write("[INFO] checkInitializeComplete -> Entering function."); }
if (INFO_LOG === true) { logger.write("[INFO] checkInitializeComplete -> key = " + pHost.codeName + "-" + pCompetition.codeName + "-" + devTeam.codeName + "-" + bot.codeName + "-" + product.codeName); }
if (dataSetsLoaded === dataSetsToLoad) {
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE);
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> checkInitializeComplete -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
}
}
thisObject.competitorsSequences.push(fileSequences);
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
}
-36
View File
@@ -1,36 +0,0 @@
function newContainer() {
var container = {
frame: undefined,
displacement: undefined,
eventHandler: undefined,
parentContainer: undefined,
isDraggeable: true,
isClickeable: false,
isWheelable: false,
name: undefined,
initialize: initialize
};
return container;
function initialize() {
var frame = newFrame();
frame.initialize();
this.frame = frame;
frame.container = container;
var eventHandler = newEventHandler();
eventHandler.initialize();
eventHandler.name = container.name;
this.eventHandler = eventHandler;
var displacement = newDisplacement();
this.displacement = displacement;
displacement.container = container;
}
}
-195
View File
@@ -1,195 +0,0 @@
/* Callbacks default responses. */
let GLOBAL = {};
GLOBAL.DEFAULT_OK_RESPONSE = {
result: "Ok",
message: "Operation Succeeded"
};
GLOBAL.DEFAULT_FAIL_RESPONSE = {
result: "Fail",
message: "Operation Failed"
};
GLOBAL.DEFAULT_RETRY_RESPONSE = {
result: "Retry",
message: "Retry Later"
};
GLOBAL.CUSTOM_OK_RESPONSE = {
result: "Ok, but check Message",
message: "Custom Message"
};
GLOBAL.CUSTOM_FAIL_RESPONSE = {
result: "Fail Because",
message: "Custom Message"
};
/* The Dashboard is the root object that contains all the other stuff in it. Some of that stuff is visible, some other is invisible. */
let canvas;
let markets;
let ecosystem = newEcosystem();
let marketFilesPeriods =
'[' +
'[' + 24 * 60 * 60 * 1000 + ',' + '"24-hs"' + ']' + ',' +
'[' + 12 * 60 * 60 * 1000 + ',' + '"12-hs"' + ']' + ',' +
'[' + 8 * 60 * 60 * 1000 + ',' + '"08-hs"' + ']' + ',' +
'[' + 6 * 60 * 60 * 1000 + ',' + '"06-hs"' + ']' + ',' +
'[' + 4 * 60 * 60 * 1000 + ',' + '"04-hs"' + ']' + ',' +
'[' + 3 * 60 * 60 * 1000 + ',' + '"03-hs"' + ']' + ',' +
'[' + 2 * 60 * 60 * 1000 + ',' + '"02-hs"' + ']' + ',' +
'[' + 1 * 60 * 60 * 1000 + ',' + '"01-hs"' + ']' + ']';
marketFilesPeriods = JSON.parse(marketFilesPeriods);
let dailyFilePeriods =
'[' +
'[' + 45 * 60 * 1000 + ',' + '"45-min"' + ']' + ',' +
'[' + 40 * 60 * 1000 + ',' + '"40-min"' + ']' + ',' +
'[' + 30 * 60 * 1000 + ',' + '"30-min"' + ']' + ',' +
'[' + 20 * 60 * 1000 + ',' + '"20-min"' + ']' + ',' +
'[' + 15 * 60 * 1000 + ',' + '"15-min"' + ']' + ',' +
'[' + 10 * 60 * 1000 + ',' + '"10-min"' + ']' + ',' +
'[' + 05 * 60 * 1000 + ',' + '"05-min"' + ']' + ',' +
'[' + 04 * 60 * 1000 + ',' + '"04-min"' + ']' + ',' +
'[' + 03 * 60 * 1000 + ',' + '"03-min"' + ']' + ',' +
'[' + 02 * 60 * 1000 + ',' + '"02-min"' + ']' + ',' +
'[' + 01 * 60 * 1000 + ',' + '"01-min"' + ']' + ']';
dailyFilePeriods = JSON.parse(dailyFilePeriods);
function convertTimePeriodToName(pTimePeriod) {
for (let i = 0; i < dailyFilePeriods.length; i++) {
let period = dailyFilePeriods[i];
if (period[0] === pTimePeriod) {
return period[1];
}
}
for (let i = 0; i < marketFilesPeriods.length; i++) {
let period = marketFilesPeriods[i];
if (period[0] === pTimePeriod) {
return period[1];
}
}
}
const DEBUG_START_UP_DELAY = 0 //3000; // This is a waiting time in case there is a need to debug the very first steps of initialization, to be able to hit F12 on time.
const INITIAL_DEFAULT_MARKET = 2; // This is the market that will be shown when loading the site for the first time.
const DEFAULT_EXCHANGE = "Poloniex";
const DEFAULT_MARKET = {
assetA: "USDT",
assetB: "BTC",
};
const USDT_BTC_HTH = 19900; // This is needed to know the scale of the market time line.
const WIDHTER_VOLUME_BAR_BASE_FACTOR = 2.5;
const LESS_WIDHTER_VOLUME_BAR_TOP_FACTOR = 1 / 4;
const ONE_DAY_IN_MILISECONDS = 24 * 60 * 60 * 1000;
const _12_HOURS_IN_MILISECONDS = 12 * 60 * 60 * 1000;
const _8_HOURS_IN_MILISECONDS = 8 * 60 * 60 * 1000;
const _6_HOURS_IN_MILISECONDS = 6 * 60 * 60 * 1000;
const _4_HOURS_IN_MILISECONDS = 4 * 60 * 60 * 1000;
const _3_HOURS_IN_MILISECONDS = 3 * 60 * 60 * 1000;
const _2_HOURS_IN_MILISECONDS = 2 * 60 * 60 * 1000;
const _1_HOUR_IN_MILISECONDS = 1 * 60 * 60 * 1000;
const _45_MINUTES_IN_MILISECONDS = 45 * 60 * 1000;
const _40_MINUTES_IN_MILISECONDS = 40 * 60 * 1000;
const _30_MINUTES_IN_MILISECONDS = 30 * 60 * 1000;
const _20_MINUTES_IN_MILISECONDS = 20 * 60 * 1000;
const _15_MINUTES_IN_MILISECONDS = 15 * 60 * 1000;
const _10_MINUTES_IN_MILISECONDS = 10 * 60 * 1000;
const _5_MINUTES_IN_MILISECONDS = 5 * 60 * 1000;
const _4_MINUTES_IN_MILISECONDS = 4 * 60 * 1000;
const _3_MINUTES_IN_MILISECONDS = 3 * 60 * 1000;
const _2_MINUTES_IN_MILISECONDS = 2 * 60 * 1000;
const _1_MINUTE_IN_MILISECONDS = 1 * 60 * 1000;
const EARLIEST_DATE = new Date(2014, 0, 18, 4, 26, 8);
const FONT_ASPECT_RATIO = 0.60;
const CHART_ASPECT_RATIO = 1 / 10;
const INITIAL_ZOOM_LEVEL = -22; // This is the zoom level at the view port in which the APP starts.
const INITIAL_TIME_PERIOD = recalculatePeriod(INITIAL_ZOOM_LEVEL);
var viewPort = newViewPort();
const PRODUCT_CARD_STATUS = {
ON: 'on',
LOADING: 'loading',
OFF: 'off'
};
/* Here we list the valid Time Periods: */
const PERIOD_24_HS = "24-hs";
const PERIOD_12_HS = "12-hs";
const PERIOD_06_HS = "06-hs";
const PERIOD_03_HS = "03-hs";
const PERIOD_01_HS = "01-hs";
const PERIOD_30_MIN = "30-min";
const PERIOD_10_MIN = "10-min";
const PERIOD_05_MIN = "05-min";
const PERIOD_01_MIN = "01-min";
var newDate = new Date();
newDate.setMilliseconds(0);
newDate.setDate(newDate.getDate() - 90);
const INITIAL_DATE = new Date();
var maxDate = new Date();
maxDate.setMilliseconds(0);
maxDate.setDate(maxDate.getDate() + 10);
const MAX_PLOTABLE_DATE = maxDate;
function dashboardStart() {
setTimeout(start, DEBUG_START_UP_DELAY);
}
function start() {
const ID_EXCHANGE_POLONIEX = 1;
/* For now, we are supporting only one market. */
let market = {
id: 2,
assetA: "USDT",
assetB: "BTC"
};
markets = new Map();
markets.set(market.id, market);
canvas = newCanvas();
canvas.initialize();
}
-16
View File
@@ -1,16 +0,0 @@
function newDebugLog() {
let thisObject = {
write: write,
fileName: undefined
}
return thisObject;
function write(pText) {
console.log(thisObject.fileName + " : " + pText);
}
}
-81
View File
@@ -1,81 +0,0 @@
/*
We call displacement to the offset we can produce to the object which the displcement object is is a child from.
The displacement is a vector that displaces everything static drawn on on the context of the parent object.
*/
function newDisplacement() {
var displacement = {
containerName: "", // This is for debugging purposes only.
parentDisplacement: undefined, // Here we store the displacement object of the parent cointainer, if exists.
container: undefined,
x: 0, // This is the actual x displacement.
y: 0, // This is the actual y displacement.
displace: displace,
undisplaceThisPoint: undisplaceThisPoint,
displaceThisPoint: displaceThisPoint
};
return displacement;
function displace(amountX, amountY) {
/* First we check if by allowing this displacement we would produce the current frame to be beyond its limit. */
tempDisplacement = newDisplacement();
tempDisplacement.x = amountX;
tempDisplacement.y = amountY;
if (this.container.frame.canYouMoveHere(tempDisplacement)) {
/* Now we displace */
displacement.x = displacement.x + amountX;
displacement.y = displacement.y + amountY;
return true;
}
return false;
}
function displaceThisPoint(point) {
if (this.parentDisplacement !== undefined) {
point = this.parentDisplacement.displaceThisPoint(point);
}
point.x = point.x + displacement.x;
point.y = point.y + displacement.y;
return point;
}
function undisplaceThisPoint(point) {
if (this.parentDisplacement !== undefined) {
point = this.parentDisplacement.undisplaceThisPoint(point);
}
point.x = point.x - displacement.x;
point.y = point.y - displacement.y;
return point;
}
}
+9 -3
View File
@@ -1,7 +1,7 @@
function newEcosystem() {
let ecosystem = {
let thisObject = {
getHost: getHost,
getCompetition: getCompetition,
getTeam: getTeam,
@@ -12,17 +12,23 @@ function newEcosystem() {
getExchange: getExchange,
getPlotter: getPlotter,
getPlotterModule: getPlotterModule,
getStoragePermissions: getStoragePermissions,
initialize: initialize
}
const ECOSYSTEM = "@ecosystem.json@";
return ecosystem;
return thisObject;
function initialize() {
}
function getStoragePermissions() {
return ECOSYSTEM.STORAGE_PERMISSIONS;
}
function getHost(pHostCodeName) {
-63
View File
@@ -1,63 +0,0 @@
function newEventHandler() {
const CONSOLE_LOG = false;
let thisObject = {
name: undefined, // This is for debugging purposes only.
parentEventHandler: undefined, // Here we store the parent cointainer zoom object.
listenToEvent: listenToEvent,
raiseEvent: raiseEvent,
initialize: initialize
};
var eventHandlers = []; // Here we store all the functions we will call when an event is comming.
return thisObject;
function initialize() {
}
function listenToEvent(eventType, handler, extraData) {
eventHandlers.push([eventType, handler, extraData]);
if (thisObject.name !== undefined && CONSOLE_LOG === true) {
console.log("Event Handler named " + thisObject.name + " received a request to listenToEvent " + eventType + " and call " + (handler.toString()).substring(0, 50));
}
}
function raiseEvent(eventType, event) {
if (thisObject.name !== undefined && CONSOLE_LOG === true) {
console.log("Event Handler named " + thisObject.name + " received a request to raiseEvent " + eventType + " with this data " + (event.toString()).substring(0, 50));
}
for (var i = 0; i < eventHandlers.length; i++) {
/* We will execute all the functions listening to this event type. */
if (eventHandlers[i][0] === eventType) {
var handler = eventHandlers[i][1];
var extraData = eventHandlers[i][2];
if (thisObject.name !== undefined && CONSOLE_LOG === true) {
console.log("Event Handler named " + thisObject.name + " received a request to raiseEvent " + eventType + " and will call this handler: " + (handler.toString()).substring(0,50));
}
handler(event, extraData);
}
}
}
}
-282
View File
@@ -1,282 +0,0 @@
function newDailyFiles() {
const MODULE_NAME = "Daily Files";
const INFO_LOG = false;
const ERROR_LOG = true;
const logger = newDebugLog();
logger.fileName = MODULE_NAME;
let thisObject = {
getFileCursor: getFileCursor,
setDatetime: setDatetime,
setTimePeriod: setTimePeriod,
getExpectedFiles: getExpectedFiles,
getFilesLoaded: getFilesLoaded,
initialize: initialize
}
let filesLoaded = 0;
let expectedFiles = 0;
let fileCloud;
let marketFiles = new Map;
let fileCursors = new Map;
let callBackWhenFileReceived;
return thisObject;
function initialize(pDevTeam, pBot, pProduct, pSet, pExchange, pMarket, pDatetime, pTimePeriod, callBackFunction) {
try {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> Entering function."); }
if (INFO_LOG === true) { logger.write("[INFO] initialize -> key = " + pDevTeam.codeName + "-" + pBot.codeName + "-" + pProduct.codeName); }
callBackWhenFileReceived = callBackFunction;
let exchange = ecosystem.getExchange(pProduct, pExchange);
if (exchange === undefined) {
throw "Exchange not supoorted by this product of the ecosystem! - pDevTeam.codeName = " + pDevTeam.codeName + ", pBot.codeName = " + pBot.codeName + ", pProduct.codeName = " + pProduct.codeName + ", pExchange = " + pExchange;
}
fileCloud = newFileCloud();
fileCloud.initialize(pBot);
/* First we will get the Data Range */
fileCloud.getFile(pDevTeam, pBot, pSet, exchange, pMarket, undefined, undefined, undefined, true, onDataRangeReceived);
function onDataRangeReceived(err, pFile) {
try {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileReceived -> Entering function."); }
let beginDateRange;
let endDateRange;
switch (err.result) {
case GLOBAL.DEFAULT_OK_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileReceived -> Received OK Response."); }
beginDateRange = new Date(pFile.begin);
endDateRange = new Date(pFile.end);
break;
}
case GLOBAL.DEFAULT_FAIL_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileReceived -> Received FAIL Response."); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
return;
}
case GLOBAL.CUSTOM_FAIL_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileReceived -> Received CUSTOM FAIL Response."); }
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileReceived -> err.message = " + err.message); }
if (err.message === "File does not exist.") {
if (INFO_LOG === true) { logger.write("[WARN] initialize -> onFileReceived -> No Date Range file found. maxDate will be set to current datetime. "); }
endDateRange = new Date();
break;
}
if (err.message === "Missing Configuration.") {
if (ERROR_LOG === true) { logger.write("[WARN] initialize -> onFileReceived -> The needed configuration for the dateRange at the dataSet of the product was not found."); }
if (ERROR_LOG === true) { logger.write("[WARN] initialize -> onFileReceived -> maxDate will be set to current datetime."); }
endDateRange = new Date();
break;
}
/* If none of the previous conditions are met, the we return the err to the caller. */
callBackFunction(err);
return;
}
default: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileReceived -> Received Unexpected Response."); }
callBackFunction(err);
return;
}
}
/* Now we will get the daily files */
for (i = 0; i < dailyFilePeriods.length; i++) {
let periodTime = dailyFilePeriods[i][0];
let periodName = dailyFilePeriods[i][1];
if (pSet.validPeriods.includes(periodName) === true) {
let fileCursor = newFileCursor();
fileCursor.initialize(fileCloud, pDevTeam, pBot, pSet, exchange, pMarket, periodName, periodTime, pDatetime, pTimePeriod, beginDateRange, endDateRange, onFileReceived);
fileCursors.set(periodTime, fileCursor);
expectedFiles = expectedFiles + fileCursor.getExpectedFiles();
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> onFileReceived -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
function onFileReceived(err) {
try {
if (INFO_LOG === true) { logger.write("[INFO] onFileReceived -> Entering function."); }
switch (err.result) {
case GLOBAL.DEFAULT_OK_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] onFileReceived -> Received OK Response."); }
break;
}
case GLOBAL.DEFAULT_FAIL_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] onFileReceived -> Received FAIL Response."); }
callBackWhenFileReceived(GLOBAL.DEFAULT_FAIL_RESPONSE);
return;
}
case GLOBAL.CUSTOM_FAIL_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] onFileReceived -> Received CUSTOM FAIL Response."); }
if (INFO_LOG === true) { logger.write("[INFO] onFileReceived -> err.message = " + err.message); }
callBackWhenFileReceived(err);
return;
}
default: {
if (INFO_LOG === true) { logger.write("[INFO] onFileReceived -> Received Unexpected Response."); }
callBackWhenFileReceived(err);
return;
}
}
filesLoaded++;
callBackWhenFileReceived(GLOBAL.DEFAULT_OK_RESPONSE, thisObject); // Note that the call back is called for every file loaded at each cursor.
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] onFileReceived -> err = " + err); }
callBackWhenFileReceived(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
function getFileCursor(pPeriod) {
try {
if (INFO_LOG === true) { logger.write("[INFO] getFileCursor -> Entering function."); }
return fileCursors.get(pPeriod);
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] getFileCursor -> err = " + err); }
}
}
function setDatetime(pDatetime) {
try {
if (INFO_LOG === true) { logger.write("[INFO] setDatetime -> Entering function."); }
filesLoaded = 0;
expectedFiles = 0;
fileCursors.forEach(setDatetimeToEach)
function setDatetimeToEach(fileCursor, key, map) {
fileCursor.setDatetime(pDatetime, onFileReceived);
expectedFiles = expectedFiles + fileCursor.getExpectedFiles();
}
if (INFO_LOG === true) { logger.write("[INFO] setDatetime -> expectedFiles = " + expectedFiles); }
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] setDatetime -> err = " + err); }
}
}
function setTimePeriod(pTimePeriod, pDatetime) {
try {
if (INFO_LOG === true) { logger.write("[INFO] setTimePeriod -> Entering function."); }
filesLoaded = 0;
expectedFiles = 0;
fileCursors.forEach(setTimePeriodToEach)
function setTimePeriodToEach(fileCursor, key, map) {
fileCursor.setTimePeriod(pTimePeriod, pDatetime, onFileReceived);
expectedFiles = expectedFiles + fileCursor.getExpectedFiles();
}
if (INFO_LOG === true) { logger.write("[INFO] setTimePeriod -> expectedFiles = " + expectedFiles); }
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] setTimePeriod -> err = " + err); }
}
}
function getExpectedFiles() {
if (INFO_LOG === true) { logger.write("[INFO] getExpectedFiles -> Entering function."); }
return expectedFiles;
}
function getFilesLoaded() {
if (INFO_LOG === true) { logger.write("[INFO] getFilesLoaded -> Entering function."); }
return filesLoaded;
}
}
-208
View File
@@ -1,208 +0,0 @@
function newFileCloud() {
const MODULE_NAME = "File Cloud";
const INFO_LOG = false;
const ERROR_LOG = true;
const logger = newDebugLog();
logger.fileName = MODULE_NAME;
/*
This is the module in the system that actually connects to the cloud storage and grabs from there the needed files.
*/
var thisObject = {
getFile: getFile,
initialize: initialize
};
let blobService;
return thisObject;
function initialize(pBot) {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> Entering function."); }
if (INFO_LOG === true) { logger.write("[INFO] initialize -> pBot = " + pBot.codeName); }
blobService = AzureStorage.Blob.createBlobServiceWithSas(pBot.storage.fileUri, pBot.storage.sas);
}
function getFile(pDevTeam, pBot, pSet, pExchange, pMarket, pPeriodName, pDatetime, pSequence, pDataRange, callBackFunction) {
try {
if (INFO_LOG === true) { logger.write("[INFO] getFile -> Entering function."); }
if (INFO_LOG === true) { logger.write("[INFO] getFile -> key = " + pDevTeam.codeName + "-" + pBot.codeName + "-" + pSet.filePath + "-" + pSet.fileName); }
let fileName;
let filePath;
if (pDataRange === undefined) {
fileName = pSet.fileName;
filePath = pSet.filePath;
} else {
if (pSet.dataRange !== undefined) {
fileName = pSet.dataRange.fileName;
filePath = pSet.dataRange.filePath;
} else {
let customErr = {
result: GLOBAL.CUSTOM_FAIL_RESPONSE.result,
message: "Missing Configuration."
};
if (ERROR_LOG === true) { logger.write("[WARN] getFile -> onFileReceived -> customErr.message = " + customErr.message); }
if (ERROR_LOG === true) { logger.write("[WARN] getFile -> onFileReceived -> Data Range configuration could not be found. "); }
callBackFunction(customErr);
return;
}
}
if (fileName === undefined) {
logger.write("[ERROR] getFile -> Inconsistant data. Check the following: ");
logger.write("[ERROR] getFile -> pDevTeam = " + JSON.stringify(pDevTeam));
logger.write("[ERROR] getFile -> pBot = " + JSON.stringify(pBot));
logger.write("[ERROR] getFile -> pSet = " + JSON.stringify(pSet));
logger.write("[ERROR] getFile -> pExchange = " + JSON.stringify(pExchange));
logger.write("[ERROR] getFile -> pMarket = " + JSON.stringify(pMarket));
logger.write("[ERROR] getFile -> pPeriodName = " + JSON.stringify(pPeriodName));
throw ("Inconsistant data received.");
}
if (pMarket !== undefined) {
fileName = fileName.replace("@AssetA", pMarket.assetA);
fileName = fileName.replace("@AssetB", pMarket.assetB);
}
if (pDevTeam !== undefined) {
filePath = filePath.replace("@DevTeam", pDevTeam.codeName);
}
if (pBot !== undefined) {
filePath = filePath.replace("@Bot", pBot.codeName);
}
if (pExchange !== undefined) {
filePath = filePath.replace("@Exchange", pExchange.name);
}
filePath = filePath.replace("@Period", pPeriodName);
if (pDatetime !== undefined) {
filePath = filePath.replace("@Year", pDatetime.getUTCFullYear());
filePath = filePath.replace("@Month", pad(pDatetime.getUTCMonth() + 1, 2));
filePath = filePath.replace("@Day", pad(pDatetime.getUTCDate(), 2));
filePath = filePath.replace("@Hour", pad(pDatetime.getUTCHours(), 2));
filePath = filePath.replace("@Minute", pad(pDatetime.getUTCMinutes(), 2));
}
if (pSequence !== undefined) {
fileName = fileName.replace("@Sequence", pSequence);
}
if (INFO_LOG === true) { logger.write("[INFO] getFile -> filePath = " + filePath); }
if (INFO_LOG === true) { logger.write("[INFO] getFile -> fileName = " + fileName); }
let containerName;
if (pBot.codeName !== "AATom") {
containerName = pDevTeam.codeName.toLowerCase();
} else {
containerName = 'data';
}
blobService.getBlobToText(containerName, filePath + "/" + fileName, onFileReceived);
function onFileReceived(err, text, response) {
try {
if (INFO_LOG === true) { logger.write("[INFO] getFile -> onFileReceived -> Entering function."); }
if (INFO_LOG === true) { logger.write("[INFO] getFile -> onFileReceived -> filePath = " + filePath); }
if (INFO_LOG === true) { logger.write("[INFO] getFile -> onFileReceived -> fileName = " + fileName); }
let data;
if (err) {
if (err.code === "BlobNotFound" | err.code === "FileNotFound" | err.code === "ParentNotFound") {
let customErr = {
result: GLOBAL.CUSTOM_FAIL_RESPONSE.result,
message: "File does not exist."
};
if (INFO_LOG === true) { logger.write("[WARN] getFile -> onFileReceived -> customErr.message = " + customErr.message); }
callBackFunction(customErr);
return;
}
if (ERROR_LOG === true) { logger.write("[ERROR] getFile -> onFileReceived -> containerName = " + containerName); }
if (ERROR_LOG === true) { logger.write("[ERROR] getFile -> onFileReceived -> filePath = " + filePath); }
if (ERROR_LOG === true) { logger.write("[ERROR] getFile -> onFileReceived -> fileName = " + fileName); }
if (ERROR_LOG === true) { logger.write("[ERROR] getFile -> onFileReceived -> Unexpected Error Ocurred."); }
if (ERROR_LOG === true) { logger.write("[ERROR] getFile -> onFileReceived -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
return;
} else {
try {
data = JSON.parse(text);
if (INFO_LOG === true) { logger.write("[INFO] getFile -> onFileReceived -> Data received is valid JSON."); }
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE, data);
return;
} catch (err) {
if (INFO_LOG === true) { logger.write("[WARN] getFile -> onFileReceived -> err = " + err); }
let customErr = {
result: GLOBAL.CUSTOM_OK_RESPONSE.result,
message: "Data not in JSON Format."
};
if (INFO_LOG === true) { logger.write("[WARN] getFile -> onFileReceived -> customErr.message = " + customErr.message); }
callBackFunction(customErr, text);
return;
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] getFile -> onFileReceived -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] getFile -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
}
-541
View File
@@ -1,541 +0,0 @@
function newFileCursor() {
const MODULE_NAME = "File Cursor";
const INFO_LOG = false;
const ERROR_LOG = true;
const logger = newDebugLog();
logger.fileName = MODULE_NAME;
let files = new Map;
let cursorDate;
let thisObject = {
setDatetime: setDatetime,
setTimePeriod: setTimePeriod,
files: undefined,
getExpectedFiles: getExpectedFiles,
initialize: initialize
}
thisObject.files = files;
let minCursorSize = 10;
let maxCursorSize = 30;
let market;
let exchange;
let fileCloud;
let devTeam;
let bot;
let thisSet;
let periodName;
let timePeriod;
let beginDateRange;
let endDateRange;
return thisObject;
function initialize(pFileCloud, pDevTeam, pBot, pSet, pExchange, pMarket, pPeriodName, pTimePeriod, pCursorDate, pCurrentTimePeriod, pBeginDateRange, pEndDateRange, callBackFunction) {
try {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> Entering function."); }
if (INFO_LOG === true) { logger.write("[INFO] initialize -> key = " + pDevTeam.codeName + "-" + pBot.codeName + "-" + pSet.codeName + "-" + pPeriodName); }
market = pMarket;
exchange = pExchange;
fileCloud = pFileCloud;
devTeam = pDevTeam;
bot = pBot;
thisSet = pSet;
periodName = pPeriodName;
cursorDate = pCursorDate;
timePeriod = pTimePeriod;
beginDateRange = pBeginDateRange;
endDateRange = pEndDateRange;
setTimePeriod(pCurrentTimePeriod, pCursorDate, callBackFunction);
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
function setTimePeriod(pTimePeriod, pDatetime, callBackFunction) {
try {
if (INFO_LOG === true) { logger.write("[INFO] setTimePeriod -> Entering function."); }
/*
We are implementing here an algorithm designed to save bandwidth, memory and processing power at the browser.
We say there is a saving mode where the cursor is running at a minimum size. When the end user aproaches the time period the cursor
is set, then it should exit the saving mode and go to its actual size.
To do this we are going to measure the distance from the Time Period received to the one the cursors was initialized with.
If these periods are consecutive, it means that the cursor should exit saving mode and load its full size.
*/
cursorDate = pDatetime; // Adjust the cursor date to the one received.
let positionA;
for (let i = 0; i < dailyFilePeriods.length; i++) {
let period = dailyFilePeriods[i];
if (period[0] === pTimePeriod) {
positionA = i;
}
if (period[0] === timePeriod) {
positionB = i;
}
}
if (Math.abs(positionB - positionA) <= 1) {
exitSavingMode();
//console.log("File Cursor with period " + periodName + " EXITED saving mode after being notified the user is at period " + convertTimePeriodToName(pTimePeriod));
} else {
enterSavingMode();
//console.log("File Cursor with period " + periodName + " ENTERED saving mode after being notified the user is at period " + convertTimePeriodToName(pTimePeriod));
}
getFiles(callBackFunction);
collectGarbage(callBackFunction);
function enterSavingMode() {
try {
if (INFO_LOG === true) { logger.write("[INFO] setTimePeriod -> enterSavingMode -> Entering function."); }
switch (timePeriod) {
case _45_MINUTES_IN_MILISECONDS:
{
minCursorSize = 3;
maxCursorSize = 30;
}
break;
case _40_MINUTES_IN_MILISECONDS:
{
minCursorSize = 3;
maxCursorSize = 20;
}
break;
case _30_MINUTES_IN_MILISECONDS:
{
minCursorSize = 3;
maxCursorSize = 15;
}
break;
case _20_MINUTES_IN_MILISECONDS:
{
minCursorSize = 3;
maxCursorSize = 15;
}
break;
case _15_MINUTES_IN_MILISECONDS:
{
minCursorSize = 3;
maxCursorSize = 15;
}
break;
case _10_MINUTES_IN_MILISECONDS:
{
minCursorSize = 3;
maxCursorSize = 15;
}
break;
case _5_MINUTES_IN_MILISECONDS:
{
minCursorSize = 3;
maxCursorSize = 15;
}
break;
case _4_MINUTES_IN_MILISECONDS:
{
minCursorSize = 3;
maxCursorSize = 15;
}
break;
case _3_MINUTES_IN_MILISECONDS:
{
minCursorSize = 3;
maxCursorSize = 15;
}
break;
case _2_MINUTES_IN_MILISECONDS:
{
minCursorSize = 3;
maxCursorSize = 15;
}
break;
case _1_MINUTE_IN_MILISECONDS:
{
minCursorSize = 3;
maxCursorSize = 15;
}
break;
default:
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] setTimePeriod -> enterSavingMode -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
function exitSavingMode() {
try {
if (INFO_LOG === true) { logger.write("[INFO] setTimePeriod -> exitSavingMode -> Entering function."); }
switch (timePeriod) {
case _45_MINUTES_IN_MILISECONDS:
{
minCursorSize = 15;
maxCursorSize = 30;
}
break;
case _40_MINUTES_IN_MILISECONDS:
{
minCursorSize = 13;
maxCursorSize = 20;
}
break;
case _30_MINUTES_IN_MILISECONDS:
{
minCursorSize = 11;
maxCursorSize = 15;
}
break;
case _20_MINUTES_IN_MILISECONDS:
{
minCursorSize = 9;
maxCursorSize = 15;
}
break;
case _15_MINUTES_IN_MILISECONDS:
{
minCursorSize = 7;
maxCursorSize = 15;
}
break;
case _10_MINUTES_IN_MILISECONDS:
{
minCursorSize = 7;
maxCursorSize = 15;
}
break;
case _5_MINUTES_IN_MILISECONDS:
{
minCursorSize = 5;
maxCursorSize = 15;
}
break;
case _4_MINUTES_IN_MILISECONDS:
{
minCursorSize = 5;
maxCursorSize = 15;
}
break;
case _3_MINUTES_IN_MILISECONDS:
{
minCursorSize = 5;
maxCursorSize = 15;
}
break;
case _2_MINUTES_IN_MILISECONDS:
{
minCursorSize = 5;
maxCursorSize = 15;
}
break;
case _1_MINUTE_IN_MILISECONDS:
{
minCursorSize = 5;
maxCursorSize = 15;
}
break;
default:
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] setTimePeriod -> exitSavingMode -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] setTimePeriod -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
function setDatetime(pDatetime, callBackFunction) {
try {
if (INFO_LOG === true) { logger.write("[INFO] setDatetime -> Entering function."); }
if (pDatetime === undefined) { return; }
cursorDate = pDatetime;
getFiles(callBackFunction);
collectGarbage(callBackFunction);
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] setDatetime -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
function getFiles(callBackFunction) {
try {
if (INFO_LOG === true) { logger.write("[INFO] getFiles -> Entering function."); }
let i = 0;
let j = 0;
let dateString;
getNextFile();
function getNextFile() {
try {
if (INFO_LOG === true) { logger.write("[INFO] getFiles -> getNextFile -> Entering function."); }
let targetDate = new Date(cursorDate);
targetDate.setUTCDate(targetDate.getUTCDate() + j);
/* Small algorith to allow load first the current date, then alternate between the most forwad and the most backwards ones. */
if (j === 0) { j++; }
else {
if (j < 0) {
j = -j;
j++;
}
else {
j = -j;
}
}
let compareTargetDate = new Date(targetDate.toDateString());
if (beginDateRange !== undefined) {
let compareBeginDate = new Date(beginDateRange.toDateString());
if (compareTargetDate.valueOf() < compareBeginDate.valueOf()) {
if (INFO_LOG === true) { logger.write("[INFO] getFiles -> getNextFile -> compareTargetDate < compareBeginDate -> Not loading the file for this date."); }
if (INFO_LOG === true) { logger.write("[INFO] getFiles -> getNextFile -> compareTargetDate < compareBeginDate -> compareTargetDate = " + compareTargetDate); }
if (INFO_LOG === true) { logger.write("[INFO] getFiles -> getNextFile -> compareTargetDate < compareBeginDate -> compareBeginDate = " + compareBeginDate); }
controlLoop();
return;
}
}
if (endDateRange !== undefined) {
let compareEndDate = new Date(endDateRange.toDateString());
if (compareTargetDate.valueOf() > compareEndDate.valueOf()) {
if (INFO_LOG === true) { logger.write("[INFO] getFiles -> getNextFile -> compareTargetDate > compareEndDate -> Not loading the file for this date."); }
if (INFO_LOG === true) { logger.write("[INFO] getFiles -> getNextFile -> compareTargetDate > compareEndDate -> compareTargetDate = " + compareTargetDate); }
if (INFO_LOG === true) { logger.write("[INFO] getFiles -> getNextFile -> compareTargetDate > compareEndDate -> compareEndDate = " + compareEndDate); }
controlLoop();
return;
}
}
dateString = targetDate.getUTCFullYear() + '-' + pad(targetDate.getUTCMonth() + 1, 2) + '-' + pad(targetDate.getUTCDate(), 2);
let currentDay = Math.trunc((new Date()).valueOf() / (24 * 60 * 60 * 1000));
let targetDay = Math.trunc(targetDate.valueOf() / (24 * 60 * 60 * 1000));
if (targetDay > currentDay) {
controlLoop();
} else {
if (thisObject.files.get(dateString) === undefined) { // We dont reload files we already have.
fileCloud.getFile(devTeam, bot, thisSet, exchange, market, periodName, targetDate, undefined, undefined, onFileReceived);
} else {
controlLoop();
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] getFiles -> getNextFile -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
function onFileReceived(err, file) {
try {
if (INFO_LOG === true) { logger.write("[INFO] getFiles -> onFileReceived -> Entering function."); }
switch (err.result) {
case GLOBAL.DEFAULT_OK_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] getFiles -> onFileReceived -> Received OK Response."); }
break;
}
case GLOBAL.DEFAULT_FAIL_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] getFiles -> onFileReceived -> Received FAIL Response."); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
return;
}
case GLOBAL.CUSTOM_FAIL_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] getFiles -> onFileReceived -> Received CUSTOM FAIL Response."); }
if (INFO_LOG === true) { logger.write("[INFO] getFiles -> onFileReceived -> err.message = " + err.message); }
if (err.message === "File does not exist.") {
controlLoop();
return;
} else {
callBackFunction(err);
return;
}
}
default: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileReceived -> Received Unexpected Response."); }
callBackFunction(err);
return;
}
}
thisObject.files.set(dateString, file);
controlLoop();
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] getFiles -> onFileReceived -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
function controlLoop() {
try {
if (INFO_LOG === true) { logger.write("[INFO] getFiles -> controlLoop -> Entering function."); }
if (callBackFunction !== undefined) {
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE);
}
i++;
if (i < minCursorSize) {
getNextFile();
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] getFiles -> controlLoop -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] getFiles -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
function collectGarbage(callBackFunction) {
try {
if (INFO_LOG === true) { logger.write("[INFO] collectGarbage -> Entering function."); }
date = removeTime(cursorDate);
let minDate = date.valueOf() - maxCursorSize * ONE_DAY_IN_MILISECONDS / 2;
let maxDate = date.valueOf() + maxCursorSize * ONE_DAY_IN_MILISECONDS / 2;
for (let key of thisObject.files.keys()) {
let keyDate = new Date(key);
if (keyDate.valueOf() < minDate || keyDate.valueOf() > maxDate) {
thisObject.files.delete(key);
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] collectGarbage -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
function getExpectedFiles() {
if (INFO_LOG === true) { logger.write("[INFO] getExpectedFiles -> Entering function."); }
return minCursorSize;
}
}
-192
View File
@@ -1,192 +0,0 @@
function newFileSequence() {
const MODULE_NAME = "File Sequence";
const INFO_LOG = false;
const ERROR_LOG = true;
const logger = newDebugLog();
logger.fileName = MODULE_NAME;
let thisObject = {
getFile: getFile,
getExpectedFiles: getExpectedFiles,
getFilesLoaded: getFilesLoaded,
initialize: initialize
}
let filesLoaded = 0;
let fileCloud;
let files = new Map;
let maxSequence = -1; // This is replaced by the content of the sequence file, which contains an index that starts on zero. In the case that the sequence file is not found the default value is -1 sin when you add 1 it gives you the amount of files in the sequence, zero.
return thisObject;
function initialize(pDevTeam, pBot, pProduct, pSet, pExchange, pMarket, callBackFunction) {
try {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> Entering function."); }
if (INFO_LOG === true) { logger.write("[INFO] initialize -> key = " + pDevTeam.codeName + "-" + pBot.codeName + "-" + pProduct.codeName); }
let exchange = ecosystem.getExchange(pProduct, pExchange);
if (exchange === undefined) {
throw "Exchange not supoorted by this pProduct of the ecosystem! - pDevTeam.codeName = " + pDevTeam.codeName + ", pBot.codeName = " + pBot.codeName + ", pProduct.codeName = " + pProduct.codeName + ", pExchange = " + pExchange;
}
fileCloud = newFileCloud();
fileCloud.initialize(pBot);
/* First we will get the sequence max number */
fileCloud.getFile(pDevTeam, pBot, pSet, exchange, pMarket, undefined, undefined, "Sequence", undefined, onSequenceFileReceived);
function onSequenceFileReceived(err, file) {
try {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onSequenceFileReceived -> Entering function."); }
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onSequenceFileReceived -> key = " + pDevTeam.codeName + "-" + pBot.codeName + "-" + pProduct.codeName); }
switch (err.result) {
case GLOBAL.DEFAULT_OK_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onSequenceFileReceived -> Received OK Response."); }
break;
}
case GLOBAL.DEFAULT_FAIL_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onSequenceFileReceived -> Received FAIL Response."); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
return;
}
case GLOBAL.CUSTOM_OK_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onSequenceFileReceived -> Received CUSTOM OK Response."); }
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onSequenceFileReceived -> err.message = " + err.message); }
callBackFunction(err);
return;
}
case GLOBAL.CUSTOM_FAIL_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onSequenceFileReceived -> Received CUSTOM FAIL Response."); }
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onSequenceFileReceived -> err.message = " + err.message); }
callBackFunction(err, thisObject);
return;
}
default: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onSequenceFileReceived -> Received Unexpected Response."); }
callBackFunction(err);
return;
}
}
maxSequence = Number(file);
/* Now we will get the sequence of files */
for (let i = 0; i <= maxSequence; i++) {
fileCloud.getFile(pDevTeam, pBot, pSet, exchange, pMarket, undefined, undefined, i, undefined, onFileReceived);
function onFileReceived(err, file) {
try {
switch (err.result) {
case GLOBAL.DEFAULT_OK_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onSequenceFileReceived -> onFileReceived -> Received OK Response."); }
break;
}
case GLOBAL.DEFAULT_FAIL_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onSequenceFileReceived -> onFileReceived -> Received FAIL Response."); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
return;
}
case GLOBAL.CUSTOM_FAIL_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onSequenceFileReceived -> onFileReceived -> Received CUSTOM FAIL Response."); }
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onSequenceFileReceived -> onFileReceived -> err.message = " + err.message); }
callBackFunction(err);
return;
}
default: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onSequenceFileReceived -> onFileReceived -> Received Unexpected Response."); }
callBackFunction(err);
return;
}
}
files.set(i, file);
filesLoaded++;
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE, thisObject); // Note that the callback is called for every file loaded.
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> onSequenceFileReceived -> onFileReceived -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> onSequenceFileReceived -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
function getFile(pSequence) {
if (INFO_LOG === true) { logger.write("[INFO] getFile -> Entering function."); }
if (INFO_LOG === true) { logger.write("[INFO] getFile -> pSequence = " + pSequence); }
return files.get(pSequence);
}
function getExpectedFiles() {
if (INFO_LOG === true) { logger.write("[INFO] getExpectedFiles -> Entering function."); }
return maxSequence + 1;
}
function getFilesLoaded() {
if (INFO_LOG === true) { logger.write("[INFO] getFilesLoaded -> Entering function."); }
return filesLoaded;
}
}
-138
View File
@@ -1,138 +0,0 @@
function newMarketFiles() {
const MODULE_NAME = "Market Files";
const INFO_LOG = false;
const ERROR_LOG = true;
const logger = newDebugLog();
logger.fileName = MODULE_NAME;
let thisObject = {
getFile: getFile,
getExpectedFiles: getExpectedFiles,
getFilesLoaded: getFilesLoaded,
initialize: initialize
}
let filesLoaded = 0;
let fileCloud;
let files = new Map;
return thisObject;
function initialize(pDevTeam, pBot, pProduct, pSet, pExchange, pMarket, callBackFunction) {
try {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> Entering function."); }
if (INFO_LOG === true) { logger.write("[INFO] initialize -> key = " + pDevTeam.codeName + "-" + pBot.codeName + "-" + pProduct.codeName); }
let exchange = ecosystem.getExchange(pProduct, pExchange);
if (exchange === undefined) {
throw "Exchange not supoorted by this pProduct of the ecosystem! - pDevTeam.codeName = " + pDevTeam.codeName + ", pBot.codeName = " + pBot.codeName + ", pProduct.codeName = " + pProduct.codeName + ", pExchange = " + pExchange;
}
fileCloud = newFileCloud();
fileCloud.initialize(pBot);
/* Now we will get the market files */
for (let i = 0; i < marketFilesPeriods.length; i++) {
let periodTime = marketFilesPeriods[i][0];
let periodName = marketFilesPeriods[i][1];
if (pSet.validPeriods.includes(periodName) === true) {
fileCloud.getFile(pDevTeam, pBot, pSet, exchange, pMarket, periodName, undefined, undefined, undefined, onFileReceived);
function onFileReceived(err, file) {
try {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileReceived -> Entering function."); }
switch (err.result) {
case GLOBAL.DEFAULT_OK_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileReceived -> Received OK Response."); }
break;
}
case GLOBAL.DEFAULT_FAIL_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileReceived -> Received FAIL Response."); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
return;
}
case GLOBAL.CUSTOM_FAIL_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileReceived -> Received CUSTOM FAIL Response."); }
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileReceived -> err.message = " + err.message); }
callBackFunction(err);
return;
}
default: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileReceived -> Received Unexpected Response."); }
callBackFunction(err);
return;
}
}
files.set(periodTime, file);
filesLoaded++;
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE, thisObject); // Note that the callback is called for every file loaded.
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> onFileReceived -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
function getFile(pPeriod) {
if (INFO_LOG === true) { logger.write("[INFO] getFile -> Entering function."); }
return files.get(pPeriod);
}
function getExpectedFiles() {
if (INFO_LOG === true) { logger.write("[INFO] getExpectedFiles -> Entering function."); }
return marketFilesPeriods.length;
}
function getFilesLoaded() {
if (INFO_LOG === true) { logger.write("[INFO] getFilesLoaded -> Entering function."); }
return filesLoaded;
}
}
-105
View File
@@ -1,105 +0,0 @@
function newSingleFile() {
const MODULE_NAME = "Single File";
const INFO_LOG = false;
const ERROR_LOG = true;
const logger = newDebugLog();
logger.fileName = MODULE_NAME;
let thisObject = {
getFile: getFile,
initialize: initialize
}
let fileCloud;
let file;
return thisObject;
function initialize(pDevTeam, pBot, pProduct, pSet, pExchange, pMarket, callBackFunction) {
try {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> Entering function."); }
if (INFO_LOG === true) { logger.write("[INFO] initialize -> key = " + pDevTeam.codeName + "-" + pBot.codeName + "-" + pProduct.codeName); }
let exchange = ecosystem.getExchange(pProduct, pExchange);
if (pExchange !== undefined && exchange === undefined) { // We support no exchange as a parameter, but if provided, then it must be at the list of exchanges of that product.
throw "Exchange not supoorted by this pProduct of the ecosystem! - pDevTeam.codeName = " + pDevTeam.codeName + ", pBot.codeName = " + pBot.codeName + ", pProduct.codeName = " + pProduct.codeName + ", pExchange = " + pExchange;
}
fileCloud = newFileCloud();
fileCloud.initialize(pBot);
/* Now we will get the file */
fileCloud.getFile(pDevTeam, pBot, pSet, exchange, pMarket, undefined, undefined, undefined, undefined, onFileReceived);
function onFileReceived(err, pFile) {
try {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileReceived -> Entering function."); }
switch (err.result) {
case GLOBAL.DEFAULT_OK_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileReceived -> Received OK Response."); }
break;
}
case GLOBAL.DEFAULT_FAIL_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileReceived -> Received FAIL Response."); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
return;
}
case GLOBAL.CUSTOM_FAIL_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileReceived -> Received CUSTOM FAIL Response."); }
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileReceived -> err.message = " + err.message); }
callBackFunction(err);
return;
}
default: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileReceived -> Received Unexpected Response."); }
callBackFunction(err);
return;
}
}
file = pFile;
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE);
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> onFileReceived -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
function getFile() {
if (INFO_LOG === true) { logger.write("[INFO] getFile -> Entering function."); }
return file;
}
}
-810
View File
@@ -1,810 +0,0 @@
function newFloatingLayer() {
const MODULE_NAME = "Floating Layer";
const INFO_LOG = false;
const ERROR_LOG = true;
const logger = newDebugLog();
logger.fileName = MODULE_NAME;
let thisObject = {
addFloatingObject: addFloatingObject,
killFloatingObject: killFloatingObject,
getFloatingObject: getFloatingObject,
physicsLoop: physicsLoop,
isInside: isInside,
isInsideFloatingObject: isInsideFloatingObject,
changeTargetRepulsion: changeTargetRepulsion,
initialize: initialize
};
let visibleFloatingObjects = [];
let invisibleFloatingObjects = [];
let dyingFloatingObjects = [];
let maxTargetRepulsionForce = 0.0005;
return thisObject;
function initialize(callBackFunction) {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> Entering function."); }
callBackFunction();
}
function addFloatingObject(pFloatingObject) {
if (INFO_LOG === true) { logger.write("[INFO] addFloatingObject -> Entering function."); }
invisibleFloatingObjects.push(pFloatingObject);
if (INFO_LOG === true) { logger.write("[INFO] addFloatingObject -> invisibleFloatingObjects.length = " + invisibleFloatingObjects.length); }
pFloatingObject.handle = Math.floor((Math.random() * 10000000) + 1);
if (INFO_LOG === true) { logger.write("[INFO] addFloatingObject -> pFloatingObject.handle = " + pFloatingObject.handle); }
if (INFO_LOG === true) { logger.write("[INFO] addFloatingObject -> pFloatingObject.type = " + pFloatingObject.type); }
}
function killFloatingObject(pFloatingObjectHandle) {
if (INFO_LOG === true) { logger.write("[INFO] killFloatingObject -> Entering function."); }
for (let i = 0; i < invisibleFloatingObjects.length; i++) {
let floatingObject = invisibleFloatingObjects[i];
if (floatingObject.handle === pFloatingObjectHandle) {
invisibleFloatingObjects.splice(i, 1); // Delete item from array.
if (INFO_LOG === true) { logger.write("[INFO] killFloatingObject -> floatingObject.handle = " + floatingObject.handle); }
if (INFO_LOG === true) { logger.write("[INFO] killFloatingObject -> Removing floatingObject from invisibleFloatingObjects."); }
if (INFO_LOG === true) { logger.write("[INFO] killFloatingObject -> invisibleFloatingObjects.length = " + invisibleFloatingObjects.length); }
sendToDie(floatingObject);
return;
}
}
for (let i = 0; i < visibleFloatingObjects.length; i++) {
let floatingObject = visibleFloatingObjects[i];
if (floatingObject.handle === pFloatingObjectHandle) {
visibleFloatingObjects.splice(i, 1); // Delete item from array.
if (INFO_LOG === true) { logger.write("[INFO] killFloatingObject -> floatingObject.handle = " + floatingObject.handle); }
if (INFO_LOG === true) { logger.write("[INFO] killFloatingObject -> Removing floatingObject from visibleFloatingObjects."); }
if (INFO_LOG === true) { logger.write("[INFO] killFloatingObject -> visibleFloatingObjects.length = " + visibleFloatingObjects.length); }
sendToDie(floatingObject);
return;
}
}
function sendToDie(pFloatingObject) {
/* Lets mofigy the targerRadius */
pFloatingObject.targetRadius = 0;
/* Lets transfer the payload to a new payload structure. */
let payload = {};
switch (pFloatingObject.type) {
case "Profile Ball": {
if (pFloatingObject.payload.profile.visible === false) { return;}
payload.profile = {
position: {
x: pFloatingObject.payload.profile.position.x,
y: pFloatingObject.payload.profile.position.y
},
visible: pFloatingObject.payload.profile.visible
}
pFloatingObject.payload = payload;
break;
}
case "Note": {
if (pFloatingObject.payload.notes[pFloatingObject.payloadNoteIndex].visible === false) { return; }
payload.notes = [];
let note = {
title: pFloatingObject.payload.notes[pFloatingObject.payloadNoteIndex].title,
body: pFloatingObject.payload.notes[pFloatingObject.payloadNoteIndex].body,
date: pFloatingObject.payload.notes[pFloatingObject.payloadNoteIndex].date,
rate: pFloatingObject.payload.notes[pFloatingObject.payloadNoteIndex].rate,
position: {
x: pFloatingObject.payload.notes[pFloatingObject.payloadNoteIndex].position.x,
y: pFloatingObject.payload.notes[pFloatingObject.payloadNoteIndex].position.y
},
visible: pFloatingObject.payload.notes[pFloatingObject.payloadNoteIndex].visible
};
payload.notes.push(note);
pFloatingObject.payloadNoteIndex = 0;
pFloatingObject.payload = payload;
break;
}
default: {
break;
}
}
dyingFloatingObjects.push(pFloatingObject);
if (INFO_LOG === true) { logger.write("[INFO] killFloatingObject -> Adding floatingObject to dyingFloatingObjects."); }
if (INFO_LOG === true) { logger.write("[INFO] killFloatingObject -> dyingFloatingObjects.length = " + dyingFloatingObjects.length); }
}
}
function getFloatingObject(pFloatingObjectHandle, pFloatingObjectIndex) {
if (INFO_LOG === true) { logger.write("[INFO] getFloatingObject -> Entering function."); }
if (pFloatingObjectHandle !== undefined) {
for (let i = 0; i < invisibleFloatingObjects.length; i++) {
let floatingObject = invisibleFloatingObjects[i];
if (floatingObject.handle === pFloatingObjectHandle) {
return floatingObject;
}
}
for (let i = 0; i < visibleFloatingObjects.length; i++) {
let floatingObject = visibleFloatingObjects[i];
if (floatingObject.handle === pFloatingObjectHandle) {
return floatingObject;
}
}
}
if (pFloatingObjectIndex !== undefined) {
for (let i = 0; i < visibleFloatingObjects.length; i++) {
let floatingObject = visibleFloatingObjects[i];
if (i === pFloatingObjectIndex) {
return floatingObject;
}
}
}
}
/******************************************/
/* */
/* Physics Engine Follows */
/* */
/******************************************/
function physicsLoop() {
/* This function makes all the calculations to apply phisycs on all floatingObjects in this space. */
for (let i = 0; i < visibleFloatingObjects.length; i++) {
let floatingObject = visibleFloatingObjects[i];
/* Change position based on speed */
floatingObject.currentPosition.x = floatingObject.currentPosition.x + floatingObject.currentSpeed.x;
floatingObject.currentPosition.y = floatingObject.currentPosition.y + floatingObject.currentSpeed.y;
/* Apply some friction to desacelerate */
floatingObject.currentSpeed.x = floatingObject.currentSpeed.x * floatingObject.friction; // Desaceleration factor.
floatingObject.currentSpeed.y = floatingObject.currentSpeed.y * floatingObject.friction; // Desaceleration factor.
// Gives a minimun speed towards their taget.
let payload = {
position: undefined,
visible: false
};
switch (floatingObject.type) {
case "Profile Ball": {
payload.position = floatingObject.payload.profile.position;
payload.visible = floatingObject.payload.profile.visible;
break;
}
case "Note": {
payload.position = floatingObject.payload.notes[floatingObject.payloadNoteIndex].position;
payload.visible = floatingObject.payload.notes[floatingObject.payloadNoteIndex].visible;
break;
}
default: {
break;
}
}
if (floatingObject.currentPosition.x < payload.position.x) {
floatingObject.currentSpeed.x = floatingObject.currentSpeed.x + .005;
} else {
floatingObject.currentSpeed.x = floatingObject.currentSpeed.x - .005;
}
if (floatingObject.currentPosition.y < payload.position.y) {
floatingObject.currentSpeed.y = floatingObject.currentSpeed.y + .005;
} else {
floatingObject.currentSpeed.y = floatingObject.currentSpeed.y - .005;
}
// Lets put a maximun speed also.
const MAX_SPEED = 50;
if (floatingObject.currentSpeed.x > MAX_SPEED) {
floatingObject.currentSpeed.x = MAX_SPEED;
}
if (floatingObject.currentSpeed.y > MAX_SPEED) {
floatingObject.currentSpeed.y = MAX_SPEED;
}
if (floatingObject.currentSpeed.x < -MAX_SPEED) {
floatingObject.currentSpeed.x = -MAX_SPEED;
}
if (floatingObject.currentSpeed.y < -MAX_SPEED) {
floatingObject.currentSpeed.y = -MAX_SPEED;
}
// The radius also have a target.
if (Math.abs(floatingObject.currentRadius - floatingObject.targetRadius) >= 1) {
if (floatingObject.currentRadius < floatingObject.targetRadius) {
floatingObject.currentRadius = floatingObject.currentRadius + .5;
} else {
floatingObject.currentRadius = floatingObject.currentRadius - .5;
}
}
// The imageSize also have a target.
if (Math.abs(floatingObject.currentImageSize - floatingObject.targetImageSize) >= 1) {
if (floatingObject.currentImageSize < floatingObject.targetImageSize) {
floatingObject.currentImageSize = floatingObject.currentImageSize + 1;
} else {
floatingObject.currentImageSize = floatingObject.currentImageSize - 1;
}
}
/* Collision Control */
for (let k = i + 1; k < visibleFloatingObjects.length; k++) {
if (colliding(visibleFloatingObjects[i], visibleFloatingObjects[k])) {
resolveCollision(visibleFloatingObjects[k], visibleFloatingObjects[i]);
}
}
/* Calculate repulsion force produced by all other floatingObjects */
currentRepulsionForce(i);
targetRepulsionForce(i);
gravityForce(floatingObject, payload);
}
/* We draw all the visibleFloatingObjects. */
for (let i = 0; i < visibleFloatingObjects.length; i++) {
let floatingObject = visibleFloatingObjects[i];
floatingObject.drawBackground();
}
for (let i = 0; i < visibleFloatingObjects.length; i++) {
let floatingObject = visibleFloatingObjects[visibleFloatingObjects.length - i - 1];
floatingObject.drawForeground();
}
/* Now we check if any of the created FloatingObjects where enabled to run under the Physics Engine. */
for (let i = 0; i < invisibleFloatingObjects.length; i++) {
let floatingObject = invisibleFloatingObjects[i];
let payload = {
position: undefined,
visible: false
};
switch (floatingObject.type) {
case "Profile Ball": {
payload.position = floatingObject.payload.profile.position;
payload.visible = floatingObject.payload.profile.visible;
break;
}
case "Note": {
payload.position = floatingObject.payload.notes[floatingObject.payloadNoteIndex].position;
payload.visible = floatingObject.payload.notes[floatingObject.payloadNoteIndex].visible;
break;
}
default: {
break;
}
}
if (payload.visible === true) {
if (INFO_LOG === true) { logger.write("[INFO] physicsLoop -> payload.visible = " + payload.visible); }
/* The first time that the floatingObject becomes visible, we need to do this. */
floatingObject.radomizeCurrentPosition(payload.position);
floatingObject.radomizeCurrentSpeed();
visibleFloatingObjects.push(floatingObject);
if (INFO_LOG === true) { logger.write("[INFO] physicsLoop -> floatingObject.handle = " + floatingObject.handle); }
if (INFO_LOG === true) { logger.write("[INFO] physicsLoop -> floatingObject added to visibleFloatingObjects"); }
if (INFO_LOG === true) { logger.write("[INFO] physicsLoop -> visibleFloatingObjects.length = " + visibleFloatingObjects.length); }
invisibleFloatingObjects.splice(i, 1); // Delete item from array.
if (INFO_LOG === true) { logger.write("[INFO] physicsLoop -> floatingObject.handle = " + floatingObject.handle); }
if (INFO_LOG === true) { logger.write("[INFO] physicsLoop -> floatingObject removed from invisibleFloatingObjects"); }
if (INFO_LOG === true) { logger.write("[INFO] physicsLoop -> invisibleFloatingObjects.length = " + invisibleFloatingObjects.length); }
return; // Only one at the time.
}
}
/* Finally we check if any of the currently visible floatingObjects has become invisible and must be removed from the Physics Engine. */
for (let i = 0; i < visibleFloatingObjects.length; i++) {
let floatingObject = visibleFloatingObjects[i];
let payload = {
position: undefined,
visible: true
};
switch (floatingObject.type) {
case "Profile Ball": {
payload.visible = floatingObject.payload.profile.visible;
break;
}
case "Note": {
payload.visible = floatingObject.payload.notes[floatingObject.payloadNoteIndex].visible;
break;
}
default: {
break;
}
}
if (payload.visible === false) {
if (INFO_LOG === true) { logger.write("[INFO] physicsLoop -> payload.visible = " + payload.visible); }
invisibleFloatingObjects.push(floatingObject);
if (INFO_LOG === true) { logger.write("[INFO] physicsLoop -> floatingObject.handle = " + floatingObject.handle); }
if (INFO_LOG === true) { logger.write("[INFO] physicsLoop -> floatingObject added to invisibleFloatingObjects"); }
if (INFO_LOG === true) { logger.write("[INFO] physicsLoop -> invisibleFloatingObjects.length = " + invisibleFloatingObjects.length); }
visibleFloatingObjects.splice(i, 1); // Delete item from array.
if (INFO_LOG === true) { logger.write("[INFO] physicsLoop -> floatingObject.handle = " + floatingObject.handle); }
if (INFO_LOG === true) { logger.write("[INFO] physicsLoop -> floatingObject removed from visibleFloatingObjects"); }
if (INFO_LOG === true) { logger.write("[INFO] physicsLoop -> visibleFloatingObjects.length = " + visibleFloatingObjects.length); }
return; // Only one at the time.
}
}
/* We animate some parts of the dying objects */
for (let i = 0; i < dyingFloatingObjects.length; i++) {
let floatingObject = dyingFloatingObjects[i];
if (Math.abs(floatingObject.currentRadius - floatingObject.targetRadius) >= 5) {
let speed = Math.random();
floatingObject.currentRadius = floatingObject.currentRadius - speed * 3;
} else {
/* Here is when the floatingObjects are definetelly killed. */
dyingFloatingObjects.splice(i, 1); // Delete item from array.
break; // only one at the time.
}
}
/* We also draw all the dyingFloatingObjects */
for (let i = 0; i < dyingFloatingObjects.length; i++) {
let floatingObject = dyingFloatingObjects[i];
floatingObject.drawBackground();
}
for (let i = 0; i < dyingFloatingObjects.length; i++) {
let floatingObject = dyingFloatingObjects[dyingFloatingObjects.length - i - 1];
floatingObject.drawForeground();
}
}
function gravityForce(floatingObject, payload) {
/* We simulate a kind of gravity towards the target point of each floatingObject. This force will make the floatingObject to keep pushing to reach that point. */
const coulomb = .00001;
const minForce = 0.01;
var d = Math.sqrt(Math.pow(payload.position.x - floatingObject.currentPosition.x, 2) + Math.pow(payload.position.y - floatingObject.currentPosition.y, 2)); // ... we calculate the distance ...
var force = coulomb * d * d / floatingObject.currentMass; // In this case the mass of the floatingObject affects the gravity force that it receives, that gives priority to target position to bigger floatingObjects.
if (force < minForce) { // We need this attraction force to overcome the friction we imposed to the system.
force = minForce;
}
var pos1 = {
x: floatingObject.currentPosition.x,
y: floatingObject.currentPosition.y
};
var pos2 = {
x: payload.position.x,
y: payload.position.y
};
var posDiff = { // Next we need the vector resulting from the 2 positions.
x: pos2.x - pos1.x,
y: pos2.y - pos1.y
};
var unitVector = { // To find the unit vector, we divide each component by the magnitude of the vector.
x: posDiff.x / d,
y: posDiff.y / d
};
var forceVector = {
x: unitVector.x * force,
y: unitVector.y * force
};
/* We add the force vector to the speed vector */
floatingObject.currentSpeed.x = floatingObject.currentSpeed.x + forceVector.x;
floatingObject.currentSpeed.y = floatingObject.currentSpeed.y + forceVector.y;
}
function currentRepulsionForce(currentFloatingObject) {
/* We generate a repulsion force between floatingObjects, that prevents them to be collisioning so often. */
const coulomb = 2;
var floatingObject1 = visibleFloatingObjects[currentFloatingObject];
for (var i = 0; i < visibleFloatingObjects.length; i++) { // The force to be applied is considering all other floatingObjects...
if (i !== currentFloatingObject) { // ... except for the current one.
var floatingObject2 = visibleFloatingObjects[i]; // So, for each floatingObject...
var d = Math.sqrt(Math.pow(floatingObject2.currentPosition.x - floatingObject1.currentPosition.x, 2) + Math.pow(floatingObject2.currentPosition.y - floatingObject1.currentPosition.y, 2)); // ... we calculate the distance ...
var force = coulomb * floatingObject2.currentMass / (d * d); // ... and with it the repulsion force.
/* We need to put a hard limit to this force, in order to to eject very little floatingObjects to the infinite and beyond. */
if (force > 1) {
force = 1;
}
var pos1 = {
x: floatingObject1.currentPosition.x,
y: floatingObject1.currentPosition.y
};
var pos2 = {
x: floatingObject2.currentPosition.x,
y: floatingObject2.currentPosition.y
};
var posDiff = { // Next we need the vector resulting from the 2 positions.
x: pos2.x - pos1.x,
y: pos2.y - pos1.y
};
var unitVector = { // To find the unit vector, we divide each component by the magnitude of the vector.
x: posDiff.x / d,
y: posDiff.y / d
};
var forceVector = {
x: unitVector.x * force,
y: unitVector.y * force
};
/* We substract the force vector to the speed vector of the current floatingObject */
floatingObject1.currentSpeed.x = floatingObject1.currentSpeed.x - forceVector.x;
floatingObject1.currentSpeed.y = floatingObject1.currentSpeed.y - forceVector.y;
}
}
}
function targetRepulsionForce(currentFloatingObject) {
/* We generate a repulsion force between floatingObjects, that prevents them to be collisioning so often. */
const coulomb = 2;
var floatingObject1 = visibleFloatingObjects[currentFloatingObject];
for (var i = 0; i < visibleFloatingObjects.length; i++) { // The force to be applied is considering all other floatingObjects...
var floatingObject2 = visibleFloatingObjects[i]; // So, for each floatingObject...
let payload = {
position: undefined
};
switch (floatingObject2.type) {
case "Profile Ball": {
payload.position = floatingObject2.payload.profile.position;
break;
}
case "Note": {
payload.position = floatingObject2.payload.notes[floatingObject2.payloadNoteIndex].position;
break;
}
default: {
break;
}
}
var d = Math.sqrt(Math.pow(payload.position.x - floatingObject1.currentPosition.x, 2) + Math.pow(payload.position.y - floatingObject1.currentPosition.y, 2)); // ... we calculate the distance ...
var force = coulomb * floatingObject2.currentMass / (d * d); // ... and with it the repulsion force.
/* We need to put a hard limit to this force, in order to to eject very little floatingObjects to the infinite and beyond. */
if (force > maxTargetRepulsionForce) {
force = maxTargetRepulsionForce;
}
var pos1 = {
x: floatingObject1.currentPosition.x,
y: floatingObject1.currentPosition.y
};
var pos2 = {
x: payload.position.x,
y: payload.position.y
};
var posDiff = { // Next we need the vector resulting from the 2 positions.
x: pos2.x - pos1.x,
y: pos2.y - pos1.y
};
var unitVector = { // To find the unit vector, we divide each component by the magnitude of the vector.
x: posDiff.x / d,
y: posDiff.y / d
};
var forceVector = {
x: unitVector.x * force,
y: unitVector.y * force
};
/* We substract the force vector to the speed vector of the current floatingObject */
floatingObject1.currentSpeed.x = floatingObject1.currentSpeed.x - forceVector.x;
floatingObject1.currentSpeed.y = floatingObject1.currentSpeed.y - forceVector.y;
}
}
function changeTargetRepulsion(pDelta) {
if (pDelta > 0) {
pDelta = 1;
} else {
pDelta = -1;
}
maxTargetRepulsionForce = maxTargetRepulsionForce + pDelta / 10000;
if (maxTargetRepulsionForce < 0.0001) {
maxTargetRepulsionForce = 0.0001
}
}
function colliding(floatingObject1, floatingObject2) {
/* This function detects weather 2 floatingObjects collide with each other. */
var r1 = floatingObject1.currentRadius;
var r2 = floatingObject2.currentRadius;
var distance = Math.sqrt(Math.pow(floatingObject2.currentPosition.x - floatingObject1.currentPosition.x, 2) + Math.pow(floatingObject2.currentPosition.y - floatingObject1.currentPosition.y, 2));
if (distance > (r1 + r2)) {
// No solutions, the circles are too far apart.
return false;
}
else if (distance <= r1 + r2) {
// One circle contains the other.
return true;
}
else if ((distance === 0) && (r1 === r2)) {
// the circles coincide.
return true;
}
else return true;
}
function isInside(x, y) {
/* This function detects weather the point x,y is inside any of the floatingObjects. */
for (var i = 0; i < visibleFloatingObjects.length; i++) {
var floatingObject = visibleFloatingObjects[i];
var distance = Math.sqrt(Math.pow(floatingObject.currentPosition.x - x, 2) + Math.pow(floatingObject.currentPosition.y - y, 2));
if (distance < floatingObject.currentRadius) {
return i;
}
}
return -1;
}
function isInsideFloatingObject(floatingObjectIndex, x, y) {
/* This function detects weather the point x,y is inside one particular floatingObjects. */
var floatingObject = visibleFloatingObjects[floatingObjectIndex];
var distance = Math.sqrt(Math.pow(floatingObject.currentPosition.x - x, 2) + Math.pow(floatingObject.currentPosition.y - y, 2));
if (distance < floatingObject.currentRadius) {
return true;
}
return false;
}
function distance(x1, y1, x2, y2) {
return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
}
function resolveCollision(floatingObject1, floatingObject2) {
/* This function changes speed and position of floatingObjects that are in collision */
var collisionision_angle = Math.atan2((floatingObject2.currentPosition.y - floatingObject1.currentPosition.y), (floatingObject2.currentPosition.x - floatingObject1.currentPosition.x));
var speed1 = Math.sqrt(floatingObject1.currentSpeed.x * floatingObject1.currentSpeed.x + floatingObject1.currentSpeed.y * floatingObject1.currentSpeed.y); // Magnitude of Speed Vector for floatingObject 1
var speed2 = Math.sqrt(floatingObject2.currentSpeed.x * floatingObject2.currentSpeed.x + floatingObject2.currentSpeed.y * floatingObject2.currentSpeed.y); // Magnitude of Speed Vector for floatingObject 2
var direction_1 = Math.atan2(floatingObject1.currentSpeed.y, floatingObject1.currentSpeed.x);
var direction_2 = Math.atan2(floatingObject2.currentSpeed.y, floatingObject2.currentSpeed.x);
var new_xspeed_1 = speed1 * Math.cos(direction_1 - collisionision_angle);
var new_yspeed_1 = speed1 * Math.sin(direction_1 - collisionision_angle);
var new_xspeed_2 = speed2 * Math.cos(direction_2 - collisionision_angle);
var new_yspeed_2 = speed2 * Math.sin(direction_2 - collisionision_angle);
var final_xspeed_1 = ((floatingObject1.currentMass - floatingObject2.currentMass) * new_xspeed_1 + (floatingObject2.currentMass + floatingObject2.currentMass) * new_xspeed_2) / (floatingObject1.currentMass + floatingObject2.currentMass);
var final_xspeed_2 = ((floatingObject1.currentMass + floatingObject1.currentMass) * new_xspeed_1 + (floatingObject2.currentMass - floatingObject1.currentMass) * new_xspeed_2) / (floatingObject1.currentMass + floatingObject2.currentMass);
var final_yspeed_1 = new_yspeed_1;
var final_yspeed_2 = new_yspeed_2;
var cosAngle = Math.cos(collisionision_angle);
var sinAngle = Math.sin(collisionision_angle);
floatingObject1.currentSpeed.x = cosAngle * final_xspeed_1 - sinAngle * final_yspeed_1;
floatingObject1.currentSpeed.y = sinAngle * final_xspeed_1 + cosAngle * final_yspeed_1;
floatingObject2.currentSpeed.x = cosAngle * final_xspeed_2 - sinAngle * final_yspeed_2;
floatingObject2.currentSpeed.y = sinAngle * final_xspeed_2 + cosAngle * final_yspeed_2;
var pos1 = {
x: floatingObject1.currentPosition.x,
y: floatingObject1.currentPosition.y
};
var pos2 = {
x: floatingObject2.currentPosition.x,
y: floatingObject2.currentPosition.y
};
// get the mtd
var posDiff = {
x: pos1.x - pos2.x,
y: pos1.y - pos2.y
};
var d = Math.sqrt(Math.pow(floatingObject2.currentPosition.x - floatingObject1.currentPosition.x, 2) + Math.pow(floatingObject2.currentPosition.y - floatingObject1.currentPosition.y, 2));
// minimum translation distance to push floatingObjects apart after intersecting
var scalar = (((floatingObject1.currentRadius + floatingObject2.currentRadius) - d) / d);
var minTD = {
x: posDiff.x * scalar,
y: posDiff.y * scalar
};
// resolve intersection --
// computing inverse mass quantities
var im1 = 1 / floatingObject1.currentMass;
var im2 = 1 / floatingObject2.currentMass;
// push-pull them apart based off their mass
pos1.x = pos1.x + minTD.x * (im1 / (im1 + im2));
pos1.y = pos1.y + minTD.y * (im1 / (im1 + im2));
pos2.x = pos2.x - minTD.x * (im2 / (im1 + im2));
pos2.y = pos2.y - minTD.y * (im2 / (im1 + im2));
floatingObject1.currentPosition = pos1;
floatingObject2.currentPosition = pos2;
}
}
-192
View File
@@ -1,192 +0,0 @@
function newFloatingObject() {
var thisObject = {
payload: undefined, // This is a reference to an object controlled by a Plotter. The plotter can change its internal value and we will see them from here.
type: undefined, // Currently there are two types of Floating Objects: Profile Balls, and Notes.
physicsEnabled: false,
initializeMass: initializeMass,
initializeRadius: initializeRadius,
initializeImageSize: initializeImageSize,
imageId: undefined,
currentPosition: 0, // Current x,y position of the floating object at the floating object's layer, where there is no displacement or zoom. This position is always changing towards the target position.
currentSpeed: 0, // This is the current speed of the floating object.
currentRadius: 0, // This is the current radius of the floating object, including its zoom applied.
currentMass: 0, // This is the current mass of the floating object, including its zoom applied.
friction: 0, // This is a factor that will ultimatelly desacelerate the floating object.
rawMass: 0, // This is the mass value without zoom.
rawRadius: 0, // This is the radius of this floating object without zoom.
targetRadius: 0, // This is the target radius of the floating object with zoom applied. It should be animated until reaching this value.
fillStyle: '',
labelStrokeStyle: '',
radomizeCurrentPosition: radomizeCurrentPosition,
radomizeCurrentSpeed: radomizeCurrentSpeed,
drawBackground: drawBackground,
drawForeground: drawForeground,
updateMass: updateMass, // Function to update the mass when the zoom level changed.
updateRadius: updateRadius, // Function to update the radius when the zoom level changed.
linkedObject: undefined, // This is a reference to the object that this floating object is representing.
linkedObjectType: "", // Since there might be floating objects for different types of objects, here we store the type of object we are linking to.
container: undefined, // This is a pointer to the object where the floating object belongs to.
initialize: initialize
};
let underlayingObject;
return thisObject;
function initialize(pType, callBackFunction) {
switch (pType) {
case "Profile Ball": {
underlayingObject = newProfileBall();
underlayingObject.initialize(onInitialized);
function onInitialized(err) {
}
break;
}
case "Note": {
underlayingObject = newNote();
underlayingObject.initialize(onInitialized);
function onInitialized(err) {
}
break;
}
default: {
break;
}
}
thisObject.type = pType;
callBackFunction();
}
function drawBackground() {
underlayingObject.drawBackground(thisObject);
}
function drawForeground() {
underlayingObject.drawForeground(thisObject);
}
function initializeMass(suggestedValue) {
var mass = suggestedValue;
if (mass < 0.1) {
mass = 0.1;
}
thisObject.rawMass = mass;
thisObject.currentMass = mass;
}
function initializeRadius(suggestedValue) {
var radius = suggestedValue;
if (radius < 2) {
radius = 2;
}
thisObject.rawRadius = radius;
thisObject.targetRadius = radius;
thisObject.currentRadius = radius / 3;
}
function initializeImageSize(suggestedValue) {
var size = suggestedValue;
if (size < 2) {
size = 2;
}
thisObject.rawImageSize = size;
thisObject.targetImageSize = size;
thisObject.currentImageSize = size / 3;
}
function radomizeCurrentPosition(arroundPoint) {
var position = {
x: Math.floor((Math.random() * (200) - 100)) + arroundPoint.x,
y: Math.floor((Math.random() * (200) - 100)) + arroundPoint.y
};
thisObject.currentPosition = position;
}
function radomizeCurrentSpeed() {
var initialXDirection;
var randomX = Math.floor((Math.random() * 10) + 1);
if (randomX > 5) {
initialXDirection = 1;
} else {
initialXDirection = - 1;
}
var initialYDirection;
var randomY = Math.floor((Math.random() * 10) + 1);
if (randomY > 5) {
initialYDirection = 1;
} else {
initialYDirection = - 1;
}
var velocity = {
x: initialXDirection * Math.floor((Math.random() * 300) + 1) / 100,
y: initialYDirection * Math.floor((Math.random() * 300) + 1) / 100
};
thisObject.currentSpeed = velocity;
}
function updateMass() {
//thisObject.currentMass = thisObject.rawMass + thisObject.rawMass * thisObject.container.zoom.incrementM * thisObject.container.zoom.levelM;
}
function updateRadius() {
//thisObject.targetRadius = thisObject.rawRadius + thisObject.rawRadius * thisObject.container.zoom.incrementR * thisObject.container.zoom.levelR;
}
}
-309
View File
@@ -1,309 +0,0 @@
function newNote() {
var thisObject = {
drawBackground: drawBackground,
drawForeground: drawForeground,
initialize: initialize
};
return thisObject;
function initialize(callBackFunction) {
callBackFunction();
}
function drawBackground(pFloatingObject) {
if (pFloatingObject.currentRadius > 1) {
/* Target Line */
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(pFloatingObject.currentPosition.x, pFloatingObject.currentPosition.y);
browserCanvasContext.lineTo(pFloatingObject.payload.notes[pFloatingObject.payloadNoteIndex].position.x, pFloatingObject.payload.notes[pFloatingObject.payloadNoteIndex].position.y);
browserCanvasContext.strokeStyle = 'rgba(204, 204, 204, 0.5)';
browserCanvasContext.setLineDash([4, 2]);
browserCanvasContext.lineWidth = 1;
browserCanvasContext.stroke();
browserCanvasContext.setLineDash([0, 0]);
}
if (pFloatingObject.currentRadius > 0.5) {
/* Target Spot */
var radius = 1;
browserCanvasContext.beginPath();
browserCanvasContext.arc(pFloatingObject.payload.notes[pFloatingObject.payloadNoteIndex].position.x, pFloatingObject.payload.notes[pFloatingObject.payloadNoteIndex].position.y, radius, 0, Math.PI * 2, true);
browserCanvasContext.closePath();
browserCanvasContext.fillStyle = 'rgba(30, 30, 30, 1)';
browserCanvasContext.fill();
}
}
function drawForeground(pFloatingObject) {
const BUBBLE_CORNERS_RADIOUS = 5;
const TITLE_BAR_HEIGHT = 14;
const BUBBLE_WIDTH = BUBBLE_CORNERS_RADIOUS + pFloatingObject.currentRadius * 4;
const BUBBLE_HEIGHT = BUBBLE_CORNERS_RADIOUS + pFloatingObject.currentRadius * 2;
let borderPoint1;
let borderPoint2;
let borderPoint3;
let borderPoint4;
let intialDisplace = {
x: pFloatingObject.currentPosition.x - BUBBLE_WIDTH / 2,
y: pFloatingObject.currentPosition.y - BUBBLE_HEIGHT / 2
}
if (pFloatingObject.currentRadius > 5) {
/* Rounded Background */
borderPoint1 = {
x: intialDisplace.x + BUBBLE_CORNERS_RADIOUS,
y: intialDisplace.y + BUBBLE_CORNERS_RADIOUS
};
borderPoint2 = {
x: intialDisplace.x + BUBBLE_WIDTH - BUBBLE_CORNERS_RADIOUS,
y: intialDisplace.y + BUBBLE_CORNERS_RADIOUS
};
borderPoint3 = {
x: intialDisplace.x + BUBBLE_WIDTH - BUBBLE_CORNERS_RADIOUS,
y: intialDisplace.y + BUBBLE_HEIGHT - BUBBLE_CORNERS_RADIOUS
};
borderPoint4 = {
x: intialDisplace.x + BUBBLE_CORNERS_RADIOUS,
y: intialDisplace.y + + BUBBLE_HEIGHT - BUBBLE_CORNERS_RADIOUS
};
titleBarPoint1 = {
x: intialDisplace.x + 0,
y: intialDisplace.y + TITLE_BAR_HEIGHT
};
titleBarPoint2 = {
x: intialDisplace.x + BUBBLE_WIDTH,
y: intialDisplace.y + TITLE_BAR_HEIGHT
};
/* We paint the panel background first */
browserCanvasContext.fillStyle = 'rgba(255, 249, 196, 0.75)';
browserCanvasContext.beginPath();
browserCanvasContext.arc(borderPoint1.x, borderPoint1.y, BUBBLE_CORNERS_RADIOUS, 1.0 * Math.PI, 1.5 * Math.PI);
browserCanvasContext.lineTo(borderPoint2.x, borderPoint2.y - BUBBLE_CORNERS_RADIOUS);
browserCanvasContext.arc(borderPoint2.x, borderPoint2.y, BUBBLE_CORNERS_RADIOUS, 1.5 * Math.PI, 2.0 * Math.PI);
browserCanvasContext.lineTo(borderPoint3.x + BUBBLE_CORNERS_RADIOUS, borderPoint3.y);
browserCanvasContext.arc(borderPoint3.x, borderPoint3.y, BUBBLE_CORNERS_RADIOUS, 0 * Math.PI, 0.5 * Math.PI);
browserCanvasContext.lineTo(borderPoint4.x, borderPoint4.y + BUBBLE_CORNERS_RADIOUS);
browserCanvasContext.arc(borderPoint4.x, borderPoint4.y, BUBBLE_CORNERS_RADIOUS, 0.5 * Math.PI, 1.0 * Math.PI);
browserCanvasContext.lineTo(borderPoint1.x - BUBBLE_CORNERS_RADIOUS, borderPoint1.y);
browserCanvasContext.closePath();
browserCanvasContext.fill();
browserCanvasContext.lineWidth = 0.1;
browserCanvasContext.strokeStyle = 'rgba(54, 54, 54, 0.75)';
browserCanvasContext.stroke();
/* We paint the title bar now */
browserCanvasContext.fillStyle = 'rgba(244, 224, 44, 0.75)';
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(titleBarPoint1.x, titleBarPoint1.y);
browserCanvasContext.lineTo(borderPoint1.x - BUBBLE_CORNERS_RADIOUS, borderPoint1.y);
browserCanvasContext.arc(borderPoint1.x, borderPoint1.y, BUBBLE_CORNERS_RADIOUS, 1.0 * Math.PI, 1.5 * Math.PI);
browserCanvasContext.lineTo(borderPoint2.x, borderPoint2.y - BUBBLE_CORNERS_RADIOUS);
browserCanvasContext.arc(borderPoint2.x, borderPoint2.y, BUBBLE_CORNERS_RADIOUS, 1.5 * Math.PI, 2.0 * Math.PI);
browserCanvasContext.lineTo(titleBarPoint2.x, titleBarPoint2.y);
browserCanvasContext.closePath();
browserCanvasContext.fill();
browserCanvasContext.lineWidth = 0.1;
browserCanvasContext.strokeStyle = 'rgba(12, 64, 148, 0.75)';
browserCanvasContext.stroke();
}
if (pFloatingObject.currentRadius > 0.5) {
/* Image */
let imagePosition = {
x: pFloatingObject.currentPosition.x,
y: pFloatingObject.currentPosition.y + BUBBLE_HEIGHT / 2
};
if (pFloatingObject.payloadImageId !== undefined) {
let image = document.getElementById(pFloatingObject.payloadImageId);
if (image !== null) {
browserCanvasContext.drawImage(image, imagePosition.x - pFloatingObject.currentImageSize / 2, imagePosition.y - pFloatingObject.currentImageSize / 2, pFloatingObject.currentImageSize, pFloatingObject.currentImageSize);
}
}
/* Image Contourn */
browserCanvasContext.beginPath();
browserCanvasContext.arc(imagePosition.x, imagePosition.y, pFloatingObject.currentImageSize / 2, 0, Math.PI * 2, true);
browserCanvasContext.closePath();
browserCanvasContext.strokeStyle = 'rgba(30, 30, 30, 0.25)';
browserCanvasContext.lineWidth = 1;
browserCanvasContext.stroke();
/* Labels */
if (pFloatingObject.currentRadius > 6) {
browserCanvasContext.strokeStyle = pFloatingObject.labelStrokeStyle;
const SIZE_PERCENTAGE = Math.trunc(pFloatingObject.currentRadius / pFloatingObject.targetRadius * 100) / 100;
let ALPHA;
if (pFloatingObject.targetRadius > 0) {
ALPHA = 0.5 - (1 - SIZE_PERCENTAGE) * 5;
} else { // Object is dying...
ALPHA = Math.trunc((0.5 - (100 - pFloatingObject.currentRadius / 100) ) * 100) / 100;
if (ALPHA < 0) { ALPHA = 0}
}
let labelPoint;
let fontSize = 10;
let label;
/* print the title */
label = pFloatingObject.payload.notes[pFloatingObject.payloadNoteIndex].title;
if (label !== undefined) {
if (SIZE_PERCENTAGE > 0.9) {
browserCanvasContext.font = fontSize + 'px Courier New';
let xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO;
let yOffset = (TITLE_BAR_HEIGHT - fontSize) / 2 + 2;
labelPoint = {
x: intialDisplace.x + BUBBLE_WIDTH / 2 - xOffset,
y: intialDisplace.y + TITLE_BAR_HEIGHT - yOffset
};
browserCanvasContext.fillStyle = 'rgba(30, 30, 30, ' + ALPHA + ')'
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y);
}
}
/* Message Body */
label = pFloatingObject.payload.notes[pFloatingObject.payloadNoteIndex].body;
if (label !== undefined) {
const WORDS_PER_ROW = 5;
const TOTAL_ROWS = 5;
if (SIZE_PERCENTAGE > 0.9) {
let rawLabelArray = label.split(" ");
let labelArray = [];
/* Lets check when words are to long we add an empty space to the same line so as to roll all other words forward. */
for (let i = 0; i < rawLabelArray.length; i++) {
let word = rawLabelArray[i];
labelArray.push(word);
if (word.length > 8) {
labelArray.push("");
}
if (word.length > 10) {
labelArray.push("");
}
}
/* Calculate each ROW */
let labelRows = [];
for (let i = 0; i < TOTAL_ROWS; i++) {
let labelRow = "";
for (let j = 0; j < WORDS_PER_ROW; j++) {
let newWord = labelArray[j + i * WORDS_PER_ROW];
if (newWord !== undefined && newWord !== "") {
labelRow = labelRow + " " + newWord;
}
}
if (labelRow !== "") {
labelRows.push(labelRow);
}
}
/* Now we plot each row. */
for (let i = 0; i < labelRows.length; i++) {
let labelRow = labelRows[i];
let startingPosition = {
x: pFloatingObject.currentPosition.x,
y: pFloatingObject.currentPosition.y - labelRows.length / 2 * (fontSize * 0.60 + 10)
};
labelPoint = {
x: startingPosition.x - labelRow.length / 2 * fontSize * 0.60,
y: startingPosition.y + (i + 1) * (fontSize * 0.60 + 10)
};
browserCanvasContext.font = fontSize + 'px Courier New';
browserCanvasContext.fillStyle = 'rgba(60, 60, 60, ' + ALPHA + ')'
browserCanvasContext.fillText(labelRow, labelPoint.x, labelPoint.y);
}
}
}
}
}
}
}
-268
View File
@@ -1,268 +0,0 @@
function newNoteSets() {
const MODULE_NAME = "Note Sets";
const INFO_LOG = false;
const ERROR_LOG = true;
const logger = newDebugLog();
logger.fileName = MODULE_NAME;
let thisObject = {
createNoteSet: createNoteSet,
destroyNoteSet: destroyNoteSet,
initialize: initialize
};
let noteSets = [];
let floatingLayer;
return thisObject;
function initialize(pFloatingLayer, callBackFunction) {
try {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> Entering function."); }
floatingLayer = pFloatingLayer;
callBackFunction(GLOBAL.CUSTOM_OK_RESPONSE);
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
function createNoteSet(pPayload, pEventHandler, callBackFunction) {
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> Entering function."); }
let noteSet = {
imageId: pPayload.profile.imageId,
floatingNotes: [],
payload: pPayload,
handle: Math.floor((Math.random() * 10000000) + 1)
};
noteSets.push(noteSet);
pEventHandler.listenToEvent("Notes Changed", onNotesChanged, noteSets.length - 1)
callBackFunction(GLOBAL.CUSTOM_OK_RESPONSE, noteSet.handle);
function onNotesChanged(pNewNotes, pNoteSetIndex) {
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Entering function."); }
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> pNewNotes.length = " + pNewNotes.length); }
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> pNoteSetIndex = " + pNoteSetIndex); }
let noteSet = noteSets[pNoteSetIndex];
let found = false;
let newFloatingNotes;
/* First we remove the old notes. */
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes."); }
newFloatingNotes = []; // We will create a new array of Floating Notes as a result of this operation.
for (let j = 0; j < noteSet.floatingNotes.length; j++) {
found = false;
let floatingNote = noteSet.floatingNotes[j];
let floatingNoteKey = floatingNote.date.toString() + floatingNote.rate.toString();
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> j = " + j); }
let i;
for (i = 0; i < pNewNotes.length; i++) {
let plotterNote = pNewNotes[i];
let plotterNoteKey = plotterNote.date.toString() + plotterNote.rate.toString();
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> i = " + i); }
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> floatingNoteKey = " + floatingNoteKey); }
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> plotterNoteKey = " + plotterNoteKey); }
if (plotterNoteKey === floatingNoteKey) {
found = true;
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> found = " + found); }
break;
}
}
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> End of For i."); }
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> found = " + found); }
if (found === false) {
floatingLayer.killFloatingObject(floatingNote.floatingHandle);
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> floatingNote.floatingHandle = " + floatingNote.floatingHandle); }
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> Removed from Layer."); }
} else {
newFloatingNotes.push(floatingNote);
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> floatingNote.floatingHandle = " + floatingNote.floatingHandle); }
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> Added to newFloatingNotes."); }
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> newFloatingNotes.length = " + newFloatingNotes.length); }
let floatingObject = floatingLayer.getFloatingObject(floatingNote.floatingHandle);
floatingObject.payloadNoteIndex = i;
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> floatingObject index updated."); }
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> floatingObject.payloadNoteIndex = " + i); }
}
}
noteSet.floatingNotes = newFloatingNotes;
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Remove old Notes -> noteSet.floatingNotes.length = " + noteSet.floatingNotes.length); }
/* Second we add the new notes. */
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes."); }
newFloatingNotes = []; // We will create a new array of Floating Notes as a result of this operation.
for (let i = 0; i < pNewNotes.length; i++) {
found = false;
let plotterNote = pNewNotes[i];
let plotterNoteKey = plotterNote.date.toString() + plotterNote.rate.toString();
let floatingNote;
let floatingNoteKey;
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> i = " + i); }
for (let j = 0; j < noteSet.floatingNotes.length; j++) {
floatingNote = noteSet.floatingNotes[j];
floatingNoteKey = floatingNote.date.toString() + floatingNote.rate.toString();
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> j = " + j); }
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> floatingNoteKey = " + floatingNoteKey); }
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> plotterNoteKey = " + plotterNoteKey); }
if (plotterNoteKey === floatingNoteKey) {
found = true;
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> found = " + found); }
break;
}
}
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> End of For j."); }
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> found = " + found); }
if (found === false) {
let floatingObject = newFloatingObject();
floatingObject.initialize("Note", onInitialized);
function onInitialized(err) {
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> Entering function."); }
floatingObject.payload = noteSet.payload;
floatingObject.payloadNoteIndex = i;
floatingObject.payloadImageId = noteSet.imageId;
floatingObject.friction = .995;
floatingObject.initializeMass(200);
//let bodyText = pNewNotes[i].body;
let radius;
/*
if (bodyText.length < 100) {
radius = 100;
} else {
radius = bodyText.length;
}
*/
radius = 50;
floatingObject.initializeRadius(radius);
floatingObject.initializeImageSize(15);
floatingObject.fillStyle = 'rgba(255, 255, 255, 0.5)';
floatingObject.labelStrokeStyle = 'rgba(60, 60, 60, 0.50)';
floatingLayer.addFloatingObject(floatingObject);
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> New Note added to Layer."); }
plotterNote.floatingHandle = floatingObject.handle;
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> plotterNote.floatingHandle = " + plotterNote.floatingHandle); }
newFloatingNotes.push(plotterNote);
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> Added to newFloatingNotes."); }
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> newFloatingNotes.length = " + newFloatingNotes.length); }
}
} else {
newFloatingNotes.push(floatingNote);
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> Old Note Kept."); }
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> floatingNote.floatingHandle = " + floatingNote.floatingHandle); }
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> Added to newFloatingNotes."); }
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> newFloatingNotes.length = " + newFloatingNotes.length); }
let floatingObject = floatingLayer.getFloatingObject(floatingNote.floatingHandle);
floatingObject.payloadNoteIndex = i;
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> floatingObject index updated."); }
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> onInitialized -> floatingObject.payloadNoteIndex = " + i); }
}
}
noteSet.floatingNotes = newFloatingNotes;
if (INFO_LOG === true) { logger.write("[INFO] createNoteSet -> onNotesChanged -> Add new Notes -> noteSet.floatingNotes.length = " + noteSet.floatingNotes.length); }
}
}
function destroyNoteSet(pHandle) {
if (INFO_LOG === true) { logger.write("[INFO] destroyNoteSet -> Entering function."); }
for (let i = 0; i < noteSets.length; i++) {
let noteSet = noteSets[i];
if (noteSet.handle === pHandle) {
for (let j = 0; j < noteSet.floatingNotes.length; j++) {
let floatingNote = noteSet.floatingNotes[j];
floatingLayer.killFloatingObject(floatingNote.floatingHandle);
}
noteSets.splice(i, 1); // Delete item from array.
return;
}
}
}
}
-151
View File
@@ -1,151 +0,0 @@
function newProfileBall() {
var thisObject = {
drawBackground: drawBackground,
drawForeground: drawForeground,
initialize: initialize
};
return thisObject;
function initialize(callBackFunction) {
callBackFunction();
}
function drawBackground(pFloatingObject) {
if (pFloatingObject.currentRadius > 1) {
/* Target Line */
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(pFloatingObject.currentPosition.x, pFloatingObject.currentPosition.y);
browserCanvasContext.lineTo(pFloatingObject.payload.profile.position.x, pFloatingObject.payload.profile.position.y);
browserCanvasContext.strokeStyle = 'rgba(204, 204, 204, 0.5)';
browserCanvasContext.setLineDash([4, 2]);
browserCanvasContext.lineWidth = 1;
browserCanvasContext.stroke();
browserCanvasContext.setLineDash([0, 0]);
}
if (pFloatingObject.currentRadius > 0.5) {
/* Target Spot */
var radius = 1;
browserCanvasContext.beginPath();
browserCanvasContext.arc(pFloatingObject.payload.profile.position.x, pFloatingObject.payload.profile.position.y, radius, 0, Math.PI * 2, true);
browserCanvasContext.closePath();
browserCanvasContext.fillStyle = 'rgba(30, 30, 30, 1)';
browserCanvasContext.fill();
}
}
function drawForeground(pFloatingObject) {
if (pFloatingObject.currentRadius > 5) {
/* Contourn */
browserCanvasContext.beginPath();
browserCanvasContext.arc(pFloatingObject.currentPosition.x, pFloatingObject.currentPosition.y, pFloatingObject.currentRadius, 0, Math.PI * 2, true);
browserCanvasContext.closePath();
browserCanvasContext.strokeStyle = 'rgba(30, 30, 30, 0.75)';
browserCanvasContext.lineWidth = 1;
browserCanvasContext.stroke();
}
if (pFloatingObject.currentRadius > 0.5) {
/* Main FloatingObject */
var alphaA;
if (pFloatingObject.currentRadius < 3) {
alphaA = 1;
} else {
alphaA = 0.75;
}
alphaA = 0.75;
browserCanvasContext.beginPath();
browserCanvasContext.arc(pFloatingObject.currentPosition.x, pFloatingObject.currentPosition.y, pFloatingObject.currentRadius, 0, Math.PI * 2, true);
browserCanvasContext.closePath();
browserCanvasContext.fillStyle = pFloatingObject.fillStyle;
browserCanvasContext.fill();
}
/* Image */
if (pFloatingObject.payload.profile.imageId !== undefined) {
let image = document.getElementById(pFloatingObject.payload.profile.imageId);
if (image !== null) {
browserCanvasContext.drawImage(image, pFloatingObject.currentPosition.x - pFloatingObject.currentImageSize / 2, pFloatingObject.currentPosition.y - pFloatingObject.currentImageSize / 2, pFloatingObject.currentImageSize, pFloatingObject.currentImageSize);
}
}
/* Label Text */
if (pFloatingObject.currentRadius > 6) {
browserCanvasContext.strokeStyle = pFloatingObject.labelStrokeStyle;
let labelPoint;
let fontSize = 10;
browserCanvasContext.font = fontSize + 'px Courier New';
let label;
label = pFloatingObject.payload.profile.upLabel;
if (label !== undefined) {
labelPoint = {
x: pFloatingObject.currentPosition.x - label.length / 2 * fontSize * 0.60,
y: pFloatingObject.currentPosition.y - pFloatingObject.currentImageSize / 2 - fontSize * 0.60 - 5
};
browserCanvasContext.font = fontSize + 'px Courier New';
browserCanvasContext.fillStyle = pFloatingObject.labelStrokeStyle;
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y);
}
label = pFloatingObject.payload.profile.downLabel;
if (label !== undefined) {
labelPoint = {
x: pFloatingObject.currentPosition.x - label.length / 2 * fontSize * 0.60,
y: pFloatingObject.currentPosition.y + pFloatingObject.currentImageSize / 2 + fontSize * 0.60 + 10
};
browserCanvasContext.font = fontSize + 'px Courier New';
browserCanvasContext.fillStyle = pFloatingObject.labelStrokeStyle;
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y);
}
}
}
}
-76
View File
@@ -1,76 +0,0 @@
function newProfileBalls() {
const MODULE_NAME = "Profile Balls";
const INFO_LOG = false;
const ERROR_LOG = true;
const logger = newDebugLog();
logger.fileName = MODULE_NAME;
/*
This object deals with Profile Balls, a type of Floating Object that shows profile info in a floating ball.
*/
let thisObject = {
createNewProfileBall: createNewProfileBall,
destroyProfileBall: destroyProfileBall,
initialize: initialize
}
let floatingLayer;
return thisObject;
function initialize(pFloatingLayer, callBackFunction) {
try {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> Entering function."); }
floatingLayer = pFloatingLayer;
callBackFunction(GLOBAL.CUSTOM_OK_RESPONSE);
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
function createNewProfileBall(pPayload, callBackFunction) {
let floatingObject = newFloatingObject();
floatingObject.initialize("Profile Ball", onInitialized);
function onInitialized(err) {
floatingObject.payload = pPayload;
floatingObject.friction = .995;
floatingObject.initializeMass(100);
floatingObject.initializeRadius(30);
floatingObject.initializeImageSize(50);
floatingObject.fillStyle = 'rgba(255, 255, 255, 0.5)';
floatingObject.labelStrokeStyle = 'rgba(60, 60, 60, 0.50)';
floatingLayer.addFloatingObject(floatingObject);
callBackFunction(GLOBAL.CUSTOM_OK_RESPONSE, floatingObject.handle);
}
}
function destroyProfileBall(pFloatingObjectHandle) {
floatingLayer.killFloatingObject(pFloatingObjectHandle);
}
}
-590
View File
@@ -1,590 +0,0 @@
function newFrame() {
const PANEL_CORNERS_RADIOUS = 5;
const TITLE_BAR_HEIGHT = 14; // this must be grater than radius
var frame = {
containerName: "", // This is for debugging purposes only.
parentFrame: undefined, // Here we store the parent cointainer zoom object.
width: browserCanvas.width,
height: browserCanvas.height,
position: undefined,
getBodyHeight: getBodyHeight,
draw: draw,
container: undefined,
frameThisPoint: frameThisPoint, // This function changes the actual frame coordinate system to the screen coordinate system.
unframeThisPoint: unframeThisPoint,
fitIntoFrame: fitIntoFrame,
isThisPointHere: isThisPointHere, // This function return true is the point received as parameter lives within this frame.
isInViewPort: isInViewPort,
canYouMoveHere: canYouMoveHere,
canYouZoomHere: canYouZoomHere,
initialize: initialize
};
return frame;
function initialize() {
var position = {
x: 0,
y: 0
};
this.position = position;
}
function getBodyHeight() {
return frame.height - TITLE_BAR_HEIGHT;
}
function isInViewPort() {
point1 = {
x: 0,
y: 0
};
point3 = {
x: frame.width,
y: frame.height
};
/* Now the transformations. */
point1 = transformThisPoint(point1, frame.container);
point3 = transformThisPoint(point3, frame.container);
if (point1.x < viewPort.visibleArea.topRight.x && point1.y < viewPort.visibleArea.bottomRight.y && point3.x > viewPort.visibleArea.bottomLeft.x && point3.y > viewPort.visibleArea.topLeft.y ) {
return true;
} else {
return false;
}
}
function fitIntoFrame(point) {
/* Here we check the boundaries of the resulting points, so they dont go out of the visible area. */
if (point.x > frame.width) {
point.x = frame.width;
}
if (point.x < 0) {
point.x = 0;
}
if (point.y > frame.height) {
point.y = frame.height;
}
if (point.y < 0) {
point.y = 0;
}
return point;
}
function frameThisPoint(point) {
if (this.parentFrame !== undefined) {
point = this.parentFrame.frameThisPoint(point);
}
point.x = point.x + frame.position.x;
point.y = point.y + frame.position.y;
return point;
}
function unframeThisPoint(point) {
if (this.parentFrame !== undefined) {
point = this.parentFrame.unframeThisPoint(point);
}
point.x = point.x - this.position.x;
point.y = point.y - this.position.y;
return point;
}
function canYouMoveHere(tempDisplacement) {
/*
The current frame has a position and a displacement. We need to check that none of the boundaries points of the frame fall outside of its container frame.
First we apply the theoreticall displacement.
*/
point1 = {
x: this.position.x,
y: this.position.y
};
point2 = {
x: this.position.x + this.width,
y: this.position.y
};
point3 = {
x: this.position.x + this.width,
y: this.position.y + this.height
};
point4 = {
x: this.position.x,
y: this.position.y + this.height
};
/* Now the transformations. */
if (this.parentFrame !== undefined) { // If there is not a parent then there is no point to check bounderies.
point1 = this.parentFrame.frameThisPoint(point1);
point2 = this.parentFrame.frameThisPoint(point2);
point3 = this.parentFrame.frameThisPoint(point3);
point4 = this.parentFrame.frameThisPoint(point4);
/* We apply the temporary displacement. */
point1 = tempDisplacement.displaceThisPoint(point1);
point2 = tempDisplacement.displaceThisPoint(point2);
point3 = tempDisplacement.displaceThisPoint(point3);
point4 = tempDisplacement.displaceThisPoint(point4);
/* We add the actual displacement. */
point1 = this.container.displacement.displaceThisPoint(point1);
point2 = this.container.displacement.displaceThisPoint(point2);
point3 = this.container.displacement.displaceThisPoint(point3);
point4 = this.container.displacement.displaceThisPoint(point4);
if (this.parentFrame.isThisPointHere(point1) === false) {
return false;
}
if (this.parentFrame.isThisPointHere(point2) === false) {
return false;
}
if (this.parentFrame.isThisPointHere(point3) === false) {
return false;
}
if (this.parentFrame.isThisPointHere(point4) === false) {
return false;
}
}
return true;
}
function canYouZoomHere(tempZoom) {
point1 = {
x: this.position.x,
y: this.position.y
};
point2 = {
x: this.position.x + this.width,
y: this.position.y
};
point3 = {
x: this.position.x + this.width,
y: this.position.y + this.height
};
point4 = {
x: this.position.x,
y: this.position.y + this.height
};
/* Now the transformations. */
if (this.parentFrame !== undefined) { // If there is not a parent then there is no point to check bounderies.
point1 = this.parentFrame.frameThisPoint(point1);
point2 = this.parentFrame.frameThisPoint(point2);
point3 = this.parentFrame.frameThisPoint(point3);
point4 = this.parentFrame.frameThisPoint(point4);
/* We add the actual displacement. */
point1 = this.container.displacement.displaceThisPoint(point1);
point2 = this.container.displacement.displaceThisPoint(point2);
point3 = this.container.displacement.displaceThisPoint(point3);
point4 = this.container.displacement.displaceThisPoint(point4);
/* We temp zoom. */
point1 = tempZoom.zoomThisPoint(point1);
point2 = tempZoom.zoomThisPoint(point2);
point3 = tempZoom.zoomThisPoint(point3);
point4 = tempZoom.zoomThisPoint(point4);
if (this.parentFrame.isThisPointHere(point1) === false) {
return false;
}
if (this.parentFrame.isThisPointHere(point2) === false) {
return false;
}
if (this.parentFrame.isThisPointHere(point3) === false) {
return false;
}
if (this.parentFrame.isThisPointHere(point4) === false) {
return false;
}
}
return true;
}
function isThisPointHere(point, outsideViewPort) { // The second parameter is usefull when you want to check a point that you already know is outside the viewport.
/* We need not to modify the point received, so me make a copy of it. */
var checkPoint = {
x: point.x,
y: point.y
};
/* The point received is on the screen coordinates system, which already has zoom and displacement applied. We need to remove the zoom and displacement
in order to have the point on the containers coordinate system and be able to compare it with its dimmensions. */
if (outsideViewPort === true) {
checkPoint = this.container.displacement.undisplaceThisPoint(checkPoint);
checkPoint = this.container.frame.unframeThisPoint(checkPoint);
} else {
checkPoint = unTransformThisPoint(checkPoint, frame.container);
}
/* Now we check if the resulting point is whin the current Frame. */
if (checkPoint.x < 0 || checkPoint.y < 0 || checkPoint.x > frame.width || checkPoint.y > frame.height) {
/* The point received is not in this frame */
return false;
} else {
/* The point is within this frame. */
return true;
}
}
function draw(drawGrid, drawBorders, drawBackground) {
if (drawBorders === true) {
borders();
}
if (drawGrid === true) {
grid();
}
if (drawBackground === true) {
background();
}
}
function background() {
borderPoint1 = {
x: PANEL_CORNERS_RADIOUS,
y: PANEL_CORNERS_RADIOUS
};
borderPoint2 = {
x: frame.width - PANEL_CORNERS_RADIOUS,
y: PANEL_CORNERS_RADIOUS
};
borderPoint3 = {
x: frame.width - PANEL_CORNERS_RADIOUS,
y: frame.height - PANEL_CORNERS_RADIOUS
};
borderPoint4 = {
x: PANEL_CORNERS_RADIOUS,
y: frame.height - PANEL_CORNERS_RADIOUS
};
titleBarPoint1 = {
x: 0,
y: TITLE_BAR_HEIGHT
};
titleBarPoint2 = {
x: frame.width,
y: TITLE_BAR_HEIGHT
};
/* Now the transformations. */
borderPoint1 = frameThisPoint(borderPoint1);
borderPoint2 = frameThisPoint(borderPoint2);
borderPoint3 = frameThisPoint(borderPoint3);
borderPoint4 = frameThisPoint(borderPoint4);
titleBarPoint1 = frameThisPoint(titleBarPoint1);
titleBarPoint2 = frameThisPoint(titleBarPoint2);
/* We paint the panel background first */
browserCanvasContext.fillStyle = 'rgba(255, 255, 255, 0.75)';
browserCanvasContext.beginPath();
browserCanvasContext.arc(borderPoint1.x, borderPoint1.y, PANEL_CORNERS_RADIOUS, 1.0 * Math.PI, 1.5 * Math.PI);
browserCanvasContext.lineTo(borderPoint2.x, borderPoint2.y - PANEL_CORNERS_RADIOUS);
browserCanvasContext.arc(borderPoint2.x, borderPoint2.y, PANEL_CORNERS_RADIOUS, 1.5 * Math.PI, 2.0 * Math.PI);
browserCanvasContext.lineTo(borderPoint3.x + PANEL_CORNERS_RADIOUS, borderPoint3.y);
browserCanvasContext.arc(borderPoint3.x, borderPoint3.y, PANEL_CORNERS_RADIOUS, 0 * Math.PI, 0.5 * Math.PI);
browserCanvasContext.lineTo(borderPoint4.x, borderPoint4.y + PANEL_CORNERS_RADIOUS);
browserCanvasContext.arc(borderPoint4.x, borderPoint4.y, PANEL_CORNERS_RADIOUS, 0.5 * Math.PI, 1.0 * Math.PI);
browserCanvasContext.lineTo(borderPoint1.x - PANEL_CORNERS_RADIOUS, borderPoint1.y);
browserCanvasContext.closePath();
browserCanvasContext.fill();
browserCanvasContext.lineWidth = 0.1;
browserCanvasContext.strokeStyle = 'rgba(54, 54, 54, 0.75)';
browserCanvasContext.stroke();
/* We paint the title bar now */
browserCanvasContext.fillStyle = 'rgba(37, 107, 219, 0.75)';
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(titleBarPoint1.x, titleBarPoint1.y);
browserCanvasContext.lineTo(borderPoint1.x - PANEL_CORNERS_RADIOUS, borderPoint1.y);
browserCanvasContext.arc(borderPoint1.x, borderPoint1.y, PANEL_CORNERS_RADIOUS, 1.0 * Math.PI, 1.5 * Math.PI);
browserCanvasContext.lineTo(borderPoint2.x, borderPoint2.y - PANEL_CORNERS_RADIOUS);
browserCanvasContext.arc(borderPoint2.x, borderPoint2.y, PANEL_CORNERS_RADIOUS, 1.5 * Math.PI, 2.0 * Math.PI);
browserCanvasContext.lineTo(titleBarPoint2.x, titleBarPoint2.y);
browserCanvasContext.closePath();
browserCanvasContext.fill();
browserCanvasContext.lineWidth = 0.1;
browserCanvasContext.strokeStyle = 'rgba(12, 64, 148, 0.75)';
browserCanvasContext.stroke();
/* print the title */
let labelPoint;
let fontSize = 10;
browserCanvasContext.font = fontSize + 'px Courier New';
let label = frame.containerName;
let xOffset = label.length / 2 * fontSize * FONT_ASPECT_RATIO;
let yOffset = (TITLE_BAR_HEIGHT - fontSize) / 2 + 2;
labelPoint = {
x: frame.width / 2 - xOffset,
y: TITLE_BAR_HEIGHT - yOffset
};
labelPoint = frame.frameThisPoint(labelPoint);
browserCanvasContext.fillStyle = 'rgba(240, 240, 240, 1)';
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y);
}
function borders() {
/* Lest get the important points of the drawing so as to apply the needed transformations. */
point1 = {
x: 0,
y: 0
};
point2 = {
x: frame.width,
y: 0
};
point3 = {
x: frame.width,
y: frame.height
};
point4 = {
x: 0,
y: frame.height
};
/* Now the transformations. */
point1 = transformThisPoint(point1, frame.container);
point2 = transformThisPoint(point2, frame.container);
point3 = transformThisPoint(point3, frame.container);
point4 = transformThisPoint(point4, frame.container);
/* Lets start the drawing. */
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(point1.x, point1.y);
browserCanvasContext.lineTo(point2.x, point2.y);
browserCanvasContext.lineTo(point3.x, point3.y);
browserCanvasContext.lineTo(point4.x, point4.y);
browserCanvasContext.lineTo(point1.x, point1.y);
browserCanvasContext.closePath();
browserCanvasContext.strokeStyle = 'rgba(150, 150, 150, 1)';
browserCanvasContext.lineWidth = 1;
browserCanvasContext.stroke();
browserCanvasContext.closePath();
}
function grid(smallLines) {
if (smallLines === true) {
/* Small Lines */
var step = frame.width / 100;
browserCanvasContext.beginPath();
for (var i = 0; i < frame.width; i = i + step) {
for (var j = 0; j < frame.height; j = j + step) {
let point1 = {
x: 0,
y: j
};
let point2 = {
x: frame.width,
y: j
};
point1 = transformThisPoint(point1, frame.container);
point2 = transformThisPoint(point2, frame.container);
browserCanvasContext.moveTo(point1.x, point1.y);
browserCanvasContext.lineTo(point2.x, point2.y);
}
let point3 = {
x: frame.width,
y: frame.height
};
let point4 = {
x: 0,
y: frame.height
};
point3 = transformThisPoint(point3, frame.container);
point4 = transformThisPoint(point4, frame.container);
browserCanvasContext.moveTo(point3.x, point3.y);
browserCanvasContext.lineTo(point4.x, point4.y);
}
browserCanvasContext.closePath();
browserCanvasContext.strokeStyle = 'rgba(150, 150, 150, 0.1)';
browserCanvasContext.lineWidth = 1;
browserCanvasContext.stroke();
}
/* Main Lines */
var step = frame.width / 20;
browserCanvasContext.beginPath();
for (var i = 0; i < frame.width; i = i + step) {
for (var j = 0; j < frame.height; j = j + step) {
let point1 = {
x: 0,
y: j
};
let point2 = {
x: frame.width,
y: j
};
point1 = transformThisPoint(point1, frame.container);
point2 = transformThisPoint(point2, frame.container);
browserCanvasContext.moveTo(point1.x, point1.y);
browserCanvasContext.lineTo(point2.x, point2.y);
}
let point3 = {
x: i,
y: 0
};
let point4 = {
x: i,
y: frame.height
};
point3 = transformThisPoint(point3, frame.container);
point4 = transformThisPoint(point4, frame.container);
browserCanvasContext.moveTo(point3.x, point3.y);
browserCanvasContext.lineTo(point4.x, point4.y);
}
browserCanvasContext.closePath();
browserCanvasContext.strokeStyle = 'rgba(100, 100, 100, 0.2)';
browserCanvasContext.lineWidth = 1;
browserCanvasContext.stroke();
}
}
-127
View File
@@ -1,127 +0,0 @@
function newImageButton() {
var thisObject = {
container: undefined,
draw: draw,
status: 'neutral',
type: undefined,
getContainer: getContainer,
initialize: initialize
};
var container = newContainer();
container.initialize();
container.isDraggeable = false;
container.isClickeable = true;
thisObject.container = container;
let idNeutralImage;
let idOnImage;
let idOffImage;
let idDisabledImage;
return thisObject;
function initialize(pX, pY, pWidth, pHeight, pIdNeutralImage, pIdOnImage, pIdOffImage, pIdDisabledImage) {
idNeutralImage = pIdNeutralImage;
idOnImage = pIdOnImage;
idOffImage = pIdOffImage;
idDisabledImage = pIdDisabledImage;
/* Lets set the basic dimensions of this thisObject. */
var position = {
x: pX,
y: pY
};
thisObject.container.frame.position = position;
thisObject.container.frame.width = pWidth;
thisObject.container.frame.height = pHeight;
/* Now we start listening to the onClick event from the mouse, so that we can allow users operate this thisObject. */
thisObject.container.eventHandler.listenToEvent('onMouseClick', buttonPressed, undefined);
}
function getContainer(point) {
var container;
/* First we check if this point is inside this space. */
if (this.container.frame.isThisPointHere(point, true) === true) {
return this.container;
} else {
/* This point does not belong to this space. */
return undefined;
}
}
function buttonPressed(event, extraData) {
switch (thisObject.status) {
case 'neutral':
browserCanvasContext.fillStyle = onFillStyle;
return;
case 'on':
thisObject.status = 'off';
break;
case 'off':
thisObject.status = 'on';
break;
case 'disabled':
return;
}
}
function draw() {
drawImage();
}
function drawImage() {
let image;
let imagePoint = {
x: 0,
y: 0
};
imagePoint = thisObject.container.frame.frameThisPoint(imagePoint);
switch (thisObject.status) {
case 'neutral':
image = document.getElementById(idNeutralImage);
break;
case 'on':
image = document.getElementById(idOnImage);
break;
case 'off':
image = document.getElementById(idOffImage);
break;
case 'disabled':
image = document.getElementById(idDisabledImage);
break;
}
browserCanvasContext.drawImage(image, imagePoint.x, imagePoint.y, thisObject.container.frame.width, thisObject.container.frame.height);
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 923 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 343 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 669 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 723 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 475 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 801 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

-164
View File
@@ -1,164 +0,0 @@
/* This business logic module is responsible for Markets and Assets. */
const MODULE_NAME = "Markets";
var DATA_LAYER_MODULE = require('./Data Layer');
exports.newMarkets = function newMarkets() {
markets = {
getMarketsByExchange: getMarketsByExchange,
getExistingOrNewMarketId: getExistingOrNewMarketId,
createNewAsset: createNewAsset,
createNewMarket: createNewMarket,
initialize: initialize
};
var dataLayer;
return markets;
function initialize() {
dataLayer = DATA_LAYER_MODULE.newDataLayer();
}
function getMarketsByExchange(exchangeId, callBackFunction) {
dataLayer.getMarketsByExchange(exchangeId, onResultSetReady);
function onResultSetReady(resultSet) {
callBackFunction(resultSet);
}
}
function getExistingOrNewMarketId(marketName, market, exchangeId, callBackFunction) {
var assets = marketName.split("_");
var assetCodeA = assets[0];
var assetCodeB = assets[1];
var idAssetA;
var idAssetB;
var marketId;
getIdAssetA();
function getIdAssetA() {
dataLayer.getAssetIdByCodeName(assetCodeA, onIdReady);
function onIdReady(resultSet) {
idAssetA = resultSet.getValue(1, "Id");
if (idAssetA === undefined) {
createNewAsset(assetCodeA, onAssetCreated);
function onAssetCreated(resultSet) {
idAssetA = resultSet.getValue(1, "Id");
getIdAssetB();
}
} else {
getIdAssetB();
}
}
}
function getIdAssetB() {
dataLayer.getAssetIdByCodeName(assetCodeB, onIdReady);
function onIdReady(resultSet) {
idAssetB = resultSet.getValue(1, "Id");
if (idAssetB === undefined) {
createNewAsset(assetCodeB, onAssetCreated);
function onAssetCreated(resultSet) {
idAssetB = resultSet.getValue(1, "Id");
getMarketId();
}
} else {
getMarketId();
}
}
}
function getMarketId() {
dataLayer.getMarketId(idAssetA, idAssetB, exchangeId, onIdReady);
function onIdReady(resultSet) {
marketId = resultSet.getValue(1, "Id");
if (marketId === undefined) {
createNewMarket(exchangeId, idAssetA, idAssetB, onMarketCreated);
function onMarketCreated(resultSet) {
marketId = resultSet.getValue(1, "Id");
respond();
}
} else {
respond();
}
}
}
function respond() {
callBackFunction(marketName, market, marketId);
}
}
function createNewAsset(assetCode, callBackFunction) {
dataLayer.newAsset(assetCode, onIdReady);
function onIdReady(resultSet) {
callBackFunction(resultSet);
}
}
function createNewMarket(exchangeId, idAssetA, idAssetB, callBackFunction) {
dataLayer.newMarket(exchangeId, idAssetA, idAssetB, onIdReady);
function onIdReady(resultSet) {
callBackFunction(resultSet);
}
}
};
-236
View File
@@ -1,236 +0,0 @@
function newProductsPanel() {
var thisObject = {
container: undefined,
getLoadingProductCards: getLoadingProductCards,
draw: draw,
getContainer: getContainer, // returns the inner most container that holds the point received by parameter.
initialize: initialize
};
/* Cointainer stuff */
var container = newContainer();
container.name = "Algobots Product Panel";
container.initialize();
container.isDraggeable = true;
container.isWheelable = true;
thisObject.container = container;
thisObject.container.frame.containerName = "Algobots's Products";
let isInitialized = false;
let productCards = [];
let visibleProductCards = [];
let firstVisibleCard = 1;
return thisObject;
function initialize() {
thisObject.container.frame.width = 350;
thisObject.container.frame.height = viewPort.visibleArea.bottomRight.y - viewPort.visibleArea.topLeft.y + 15;
var position = {
x: viewPort.visibleArea.topLeft.x,
y: 0
};
thisObject.container.frame.position = position;
/* Needed Variables */
var lastY = 5;
/* First thing is to build the productCards array */
let devTeams = ecosystem.getTeams();
for (let i = 0; i < devTeams.length; i++) {
let devTeam = devTeams[i];
for (let j = 0; j < devTeam.bots.length; j++) {
let bot = devTeam.bots[j];
for (let k = 0; k < bot.products.length; k++) {
let product = bot.products[k];
/* Now we create Product objects */
let productCard = newProductCard();
productCard.devTeam = devTeam;
productCard.bot = bot;
productCard.product = product;
productCard.code = devTeam.codeName + '-' + bot.codeName + '-' + product.codeName;
/* Initialize it */
productCard.initialize();
/* Container Stuff */
productCard.container.displacement.parentDisplacement = thisObject.container.displacement;
productCard.container.frame.parentFrame = thisObject.container.frame;
productCard.container.parentContainer = thisObject.container;
productCard.container.isWheelable = true;
/* Positioning within thisObject Panel */
let position = {
x: 10,
y: thisObject.container.frame.height - thisObject.container.frame.getBodyHeight()
};
productCard.container.frame.position.x = position.x;
productCard.container.frame.position.y = position.y + lastY;
lastY = lastY + productCard.container.frame.height;
/* Add to Visible Product Array */
if (lastY < thisObject.container.frame.height) {
visibleProductCards.push(productCard);
}
/* Add to the Product Array */
productCards.push(productCard);
/* Listen to Status Changes Events */
productCard.container.eventHandler.listenToEvent('Status Changed', onProductCardStatusChanged);
productCard.container.eventHandler.listenToEvent('Mouse Wheel', onMouseWheel);
}
}
}
thisObject.container.eventHandler.listenToEvent("Mouse Wheel", onMouseWheel);
isInitialized = true;
}
function onMouseWheel(pDelta) {
if (pDelta > 0) {
pDelta = 1;
} else {
pDelta = -1;
}
firstVisibleCard = firstVisibleCard + pDelta;
let availableSlots = visibleProductCards.length;
if (firstVisibleCard < 1) { firstVisibleCard = 1; }
if (firstVisibleCard > (productCards.length - availableSlots + 1)) { firstVisibleCard = productCards.length - availableSlots + 1; }
visibleProductCards = [];
var lastY = 5;
for (let i = 0; i < productCards.length; i++) {
if (i + 1 >= firstVisibleCard && i + 1 < firstVisibleCard + availableSlots) {
let productCard = productCards[i];
/* Positioning within thisObject Panel */
let position = {
x: 10,
y: thisObject.container.frame.height - thisObject.container.frame.getBodyHeight()
};
productCard.container.frame.position.x = position.x;
productCard.container.frame.position.y = position.y + lastY;
lastY = lastY + productCard.container.frame.height;
/* Add to Visible Product Array */
visibleProductCards.push(productCard);
}
}
}
function onProductCardStatusChanged(pProductCard) {
thisObject.container.eventHandler.raiseEvent('Product Card Status Changed', pProductCard);
}
function getLoadingProductCards() {
/* Returns all productCards which status is LOADING */
let onProducts = [];
for (let i = 0; i < productCards.length; i++) {
if (productCards[i].status === PRODUCT_CARD_STATUS.LOADING) {
onProducts.push(productCards[i]);
}
}
return onProducts;
}
function getContainer(point) {
var container;
/* First we check if thisObject point is inside thisObject space. */
if (thisObject.container.frame.isThisPointHere(point, true) === true) {
/* Now we see which is the inner most container that has it */
for (var i = 0; i < visibleProductCards.length; i++) {
container = visibleProductCards[i].getContainer(point);
if (container !== undefined) {
/* We found an inner container which has the point. We return it. */
return container;
}
}
/* The point does not belong to any inner container, so we return the current container. */
return thisObject.container;
} else {
/* This point does not belong to thisObject space. */
return undefined;
}
}
function draw() {
if (isInitialized === false) {return;}
thisObject.container.frame.draw(false, false, true);
for (let i = 0; i < visibleProductCards.length; i++) {
visibleProductCards[i].draw();
}
}
}
-361
View File
@@ -1,361 +0,0 @@
function newTimeControlPanel() {
let PLAY_STEP = 0;
var thisObject = {
container: undefined,
buttons: undefined,
setDatetime: setDatetime,
datetimeDisplay: undefined,
stepDisplay: undefined,
draw: draw,
getContainer: getContainer, // returns the inner most container that holds the point received by parameter.
initialize: initialize
};
var container = newContainer();
container.initialize();
container.isDraggeable = true;
thisObject.container = container;
thisObject.container.frame.containerName = "Time Control Panel";
var playingLoop; // Controls the generation of events that allows to play continuosly the market.
return thisObject;
function initialize() {
this.container.frame.width = 200;
this.container.frame.height = 85;
var position = {
x: (viewPort.visibleArea.topRight.x - viewPort.visibleArea.topLeft.x) / 2 - this.container.frame.width / 2,
y: 0
};
this.container.frame.position = position;
var buttonPosition;
var buttonNames = ['Fast Backwards', 'Play Backwards', 'Step Backwards', 'Pause', 'Step Forward', 'Play Forward', 'Fast Forward'];
var lastX = 0;
var buttons = [];
for (var i = 0; i < buttonNames.length; i++) {
/* Buttons are going to be one at the right of the other. */
var button = newButton();
button.type = buttonNames[i];
button.container.displacement.parentDisplacement = this.container.displacement;
button.container.frame.parentFrame = this.container.frame;
button.container.parentContainer = this.container;
button.initialize();
buttonPosition = { // The first button
x: thisObject.container.frame.width / 2 - (buttonNames.length * button.container.frame.width) / 2,
y: thisObject.container.frame.height * 7 / 10
};
button.container.frame.position.x = buttonPosition.x + lastX;
button.container.frame.position.y = buttonPosition.y;
lastX = lastX + button.container.frame.width;
/* We start listening to the buttons click event, so as to know when one was pressed. */
button.container.eventHandler.listenToEvent('onMouseClick', buttonPressed, i);
if (buttonNames[i] === 'Pause') {
button.status = 'on'; // We turn on by default the PAUSE button.
}
buttons.push(button);
}
thisObject.buttons = buttons;
var datetime = INITIAL_DATE;
var datetimeDisplay = {
currentDatetime: datetime,
addTime: addTime,
draw: drawTimeDisplay
};
thisObject.buttons = buttons;
thisObject.datetimeDisplay = datetimeDisplay;
viewPort.eventHandler.listenToEvent("Zoom Changed", onZoomChanged);
PLAY_STEP = INITIAL_TIME_PERIOD;
}
function getContainer(point) {
var container;
/* First we check if this point is inside this space. */
if (this.container.frame.isThisPointHere(point, true) === true) {
/* Now we see which is the inner most container that has it */
for (var i = 0; i < this.buttons.length; i++) {
container = this.buttons[i].getContainer(point);
if (container !== undefined) {
/* We found an inner container which has the point. We return it. */
return container;
}
}
/* The point does not belong to any inner container, so we return the current container. */
return this.container;
} else {
/* This point does not belong to this space. */
return undefined;
}
}
function onZoomChanged(event) {
PLAY_STEP = recalculatePeriod(event.newLevel);
}
function setDatetime(newDatetime) {
thisObject.datetimeDisplay.currentDatetime = newDatetime;
}
function addTime(seconds) {
var newDate = thisObject.datetimeDisplay.currentDatetime;
newDate.setSeconds(newDate.getSeconds() + seconds);
thisObject.datetimeDisplay.currentDatetime = newDate;
}
function buttonPressed(event, buttonPressedIndex) {
clearInterval(playingLoop);
/* When any of the buttons are pressed, the control panel must turn off the resto of the buttons. */
for (var i = 0; i < thisObject.buttons.length; i++) {
if (i !== buttonPressedIndex) {
var button = thisObject.buttons[i];
button.status = 'off';
}
}
/* Now we actualy do something depending on which button was pressed. */
switch (thisObject.buttons[buttonPressedIndex].type) {
case "Fast Backwards":
pressFastBackwards();
break;
case "Play Backwards":
pressPlayBackwards();
break;
case "Step Backwards":
pressStepBackwards();
break;
case "Pause":
pressPause();
break;
case "Step Forward":
pressStepForward();
break;
case "Play Forward":
pressPlayForward();
break;
case "Fast Forward":
pressFastForward();
break;
default:
}
}
function pressFastBackwards() {
clearInterval(playingLoop);
playingLoop = setInterval(pressStepBackwards, 100);
}
function pressPlayBackwards() {
clearInterval(playingLoop);
playingLoop = setInterval(pressStepBackwards, 1000);
}
function pressStepBackwards() {
thisObject.datetimeDisplay.addTime(-1 * PLAY_STEP / 1000);
var newDatetime = thisObject.datetimeDisplay.currentDatetime;
thisObject.container.eventHandler.raiseEvent('Datetime Changed', newDatetime);
}
function pressPause() {
clearInterval(playingLoop);
}
function pressStepForward() {
thisObject.datetimeDisplay.addTime(PLAY_STEP / 1000);
var newDatetime = thisObject.datetimeDisplay.currentDatetime;
thisObject.container.eventHandler.raiseEvent('Datetime Changed', newDatetime);
}
function pressPlayForward() {
clearInterval(playingLoop);
playingLoop = setInterval(pressStepForward, 1000);
}
function pressFastForward() {
playingLoop = setInterval(pressStepForward, 100);
}
function draw() {
thisObject.container.frame.draw(false, false, true);
for (var i = 0; i < thisObject.buttons.length; i++) {
thisObject.buttons[i].draw();
}
this.datetimeDisplay.draw();
}
function drawTimeDisplay() {
let fontSize = 10;
let label = thisObject.datetimeDisplay.currentDatetime.toUTCString();
let labelArray = label.split(" ");
label = labelArray[0] + " " + labelArray[1] + " " + labelArray[2] + " " + labelArray[3];
/* Now we transform x on the actual coordinate on the canvas. */
let labelPoint = {
x: thisObject.container.frame.width / 2 - label.length / 2 * fontSize * FONT_ASPECT_RATIO,
y: thisObject.container.frame.height * 3.4 / 10
};
labelPoint = thisObject.container.frame.frameThisPoint(labelPoint);
browserCanvasContext.font = fontSize + 'px Courier New';
browserCanvasContext.fillStyle = 'rgba(60, 60, 60, 0.50)';
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y);
/* The time */
label = labelArray[4] + " " + labelArray[5];
/* Now we transform x on the actual coordinate on the canvas. */
labelPoint = {
x: thisObject.container.frame.width / 2 - label.length / 2 * fontSize * FONT_ASPECT_RATIO,
y: thisObject.container.frame.height * 5.0 / 10
};
labelPoint = thisObject.container.frame.frameThisPoint(labelPoint);
browserCanvasContext.font = fontSize + 'px Courier New';
browserCanvasContext.fillStyle = 'rgba(60, 60, 60, 0.50)';
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y);
label = PLAY_STEP / _1_MINUTE_IN_MILISECONDS + ' min';
/* Now we transform x on the actual coordinate on the canvas. */
labelPoint = {
x: thisObject.container.frame.width / 2 - label.length / 2 * fontSize * FONT_ASPECT_RATIO,
y: thisObject.container.frame.height * 6.5 / 10
};
labelPoint = thisObject.container.frame.frameThisPoint(labelPoint);
browserCanvasContext.font = fontSize + 'px Courier New';
browserCanvasContext.fillStyle = 'rgba(60, 60, 60, 0.50)';
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y);
}
}
-762
View File
@@ -1,762 +0,0 @@
function newProductCard() {
const CONSOLE_LOG = false;
var thisObject = {
container: undefined,
draw: draw,
status: 'off',
devTeam: undefined,
bot: undefined,
product: undefined,
code: undefined,
setDatetime: setDatetime,
setTimePeriod: setTimePeriod,
onMarketFileLoaded: onMarketFileLoaded,
onDailyFileLoaded: onDailyFileLoaded,
onSingleFileLoaded: onSingleFileLoaded,
onFileSequenceLoaded: onFileSequenceLoaded,
getContainer: getContainer, // returns the inner most container that holds the point received by parameter.
initialize: initialize
};
let LOADING_FILL_STYLE = 'rgba(234, 143, 23, @Opacity)';
let LOADED_FILL_STYLE = 'rgba(45, 232, 28, @Opacity)';
let UNLOADED_FILL_STYLE = 'rgba(226, 226, 226, @Opacity)';
let LOADING_STROKE_STYLE = 'rgba(234, 143, 23, @Opacity)';
let LOADED_STROKE_STYLE = 'rgba(150, 150, 150, @Opacity)';
let UNLOADED_STROKE_STYLE = 'rgba(226, 226, 226, @Opacity)';
let marketFileProgressBar = {
value: 0,
animatedValue: 0,
fillStyle: UNLOADED_FILL_STYLE,
strokeStyle: UNLOADED_STROKE_STYLE,
opacity: 0.00
};
let dailyFileProgressBar = {
value: 0,
animatedValue: 0,
fillStyle: UNLOADED_FILL_STYLE,
strokeStyle: UNLOADED_STROKE_STYLE,
opacity: 0.00
};
let singleFileProgressBar = {
value: 0,
animatedValue: 0,
fillStyle: UNLOADED_FILL_STYLE,
strokeStyle: UNLOADED_STROKE_STYLE,
opacity: 0.00
};
let fileSequenceProgressBar = {
value: 0,
animatedValue: 0,
fillStyle: UNLOADED_FILL_STYLE,
strokeStyle: UNLOADED_STROKE_STYLE,
opacity: 0.00
};
let timePeriod = INITIAL_TIME_PERIOD;
let datetime = INITIAL_DATE;
return thisObject;
function initialize() {
/* Create this objects continer */
var container = newContainer();
container.name = "Product Card " + thisObject.code;
container.initialize();
container.isDraggeable = false;
container.isClickeable = true;
thisObject.container = container;
/* Add information that will later be needed.*/
let team = ecosystem.getTeam(thisObject.product.plotter.devTeam);
let plotter = ecosystem.getPlotter(team, thisObject.product.plotter.codeName);
let plotterModule = ecosystem.getPlotterModule(plotter, thisObject.product.plotter.moduleName);
thisObject.product.plotter.profilePicture = plotterModule.profilePicture;
thisObject.product.plotter.module = plotterModule;
/* Lets set the basic dimensions of this thisObject. */
var position = {
x: 0,
y: 0
};
this.container.frame.position = position;
this.container.frame.width = 330;
this.container.frame.height = 100;
/* We retrieve the locally stored status of the Product */
let storedValue = window.localStorage.getItem(thisObject.code);
if (storedValue !== null) {
thisObject.status = storedValue;
if (thisObject.status === PRODUCT_CARD_STATUS.ON) {
changeStatusTo(PRODUCT_CARD_STATUS.LOADING);
}
} else {
changeStatusTo(PRODUCT_CARD_STATUS.LOADING); // This happens the first time the app is run on a new browser.
}
/* Lets listen to our own events to react when we have a Mouse Click */
thisObject.container.eventHandler.listenToEvent('onMouseClick', buttonPressed);
}
function getContainer(point) {
var container;
/* First we check if this point is inside this space. */
if (this.container.frame.isThisPointHere(point, true) === true) {
return this.container;
} else {
/* This point does not belong to this space. */
return undefined;
}
}
function setDatetime(pDatetime) {
/*
When the datetime changes from one day to another, this forces cursors to potentially load more files, thus we reset this counter and
get ready to receive events on files loaded.
*/
let currentDate = Math.trunc(datetime.valueOf() / ONE_DAY_IN_MILISECONDS);
let newDate = Math.trunc(pDatetime.valueOf() / ONE_DAY_IN_MILISECONDS);
datetime = pDatetime;
if (currentDate !== newDate) {
if (timePeriod <= _1_HOUR_IN_MILISECONDS) {
dailyFileProgressBar.animatedValue = 0;
if (CONSOLE_LOG === true) {
console.log("ProductCard -> onDayChanged -> dailyFileProgressBar.animatedValue = " + dailyFileProgressBar.animatedValue);
}
}
}
}
function setTimePeriod(pTimePeriod) {
/*
When the time period below or equal to 1 hour changes, this forces cursors to potentially load more files, thus we reset this counter and
get ready to receive events on files loaded.
*/
if (timePeriod !== pTimePeriod) {
timePeriod = pTimePeriod;
if (timePeriod <= _1_HOUR_IN_MILISECONDS) {
dailyFileProgressBar.animatedValue = 0;
if (CONSOLE_LOG === true) {
console.log("ProductCard -> onTimePeriodChanged -> dailyFileProgressBar.animatedValue = " + dailyFileProgressBar.animatedValue);
}
}
}
}
function onMarketFileLoaded(event) {
marketFileProgressBar.value = Math.trunc(event.currentValue * 100 / event.totalValue);
marketFileProgressBar.fillStyle = LOADING_FILL_STYLE;
marketFileProgressBar.strokeStyle = LOADING_STROKE_STYLE;
if (marketFileProgressBar.value > 100) { marketFileProgressBar.value = 100; }
if (CONSOLE_LOG === true) {
console.log("ProductCard onMarketFileLoaded Value = " + marketFileProgressBar.value + "% for " + thisObject.code + ". Event = " + JSON.stringify(event));
}
}
function onDailyFileLoaded(event) {
dailyFileProgressBar.value = Math.trunc(event.currentValue * 100 / event.totalValue);
dailyFileProgressBar.fillStyle = LOADING_FILL_STYLE;
dailyFileProgressBar.strokeStyle = LOADING_STROKE_STYLE;
if (dailyFileProgressBar.value > 100) { dailyFileProgressBar.value = 100;}
if (CONSOLE_LOG === true) {
console.log("ProductCard onDailyFileLoaded Value = " + dailyFileProgressBar.value + "% for " + thisObject.code + ". Event = " + JSON.stringify(event));
}
}
function onSingleFileLoaded(event) {
singleFileProgressBar.value = Math.trunc(event.currentValue * 100 / event.totalValue);
singleFileProgressBar.fillStyle = LOADING_FILL_STYLE;
singleFileProgressBar.strokeStyle = LOADING_STROKE_STYLE;
if (singleFileProgressBar.value > 100) { singleFileProgressBar.value = 100; }
if (CONSOLE_LOG === true) {
console.log("ProductCard onSingleFileLoaded Value = " + singleFileProgressBar.value + "% for " + thisObject.code + ". Event = " + JSON.stringify(event));
}
}
function onFileSequenceLoaded(event) {
fileSequenceProgressBar.value = Math.trunc(event.currentValue * 100 / event.totalValue);
fileSequenceProgressBar.fillStyle = LOADING_FILL_STYLE;
fileSequenceProgressBar.strokeStyle = LOADING_STROKE_STYLE;
if (fileSequenceProgressBar.value > 100) { fileSequenceProgressBar.value = 100; }
if (CONSOLE_LOG === true) {
console.log("ProductCard onFileSequenceLoaded Value = " + fileSequenceProgressBar.value + "% for " + thisObject.code + ". Event = " + JSON.stringify(event));
}
}
function buttonPressed(event) {
switch (thisObject.status) {
case PRODUCT_CARD_STATUS.ON:
changeStatusTo(PRODUCT_CARD_STATUS.OFF);
marketFileProgressBar.animatedValue = 0;
marketFileProgressBar.value = 0;
marketFileProgressBar.fillStyle = UNLOADED_FILL_STYLE;
marketFileProgressBar.strokeStyle = UNLOADED_STROKE_STYLE;
dailyFileProgressBar.animatedValue = 0;
dailyFileProgressBar.value = 0;
dailyFileProgressBar.fillStyle = UNLOADED_FILL_STYLE;
dailyFileProgressBar.strokeStyle = UNLOADED_STROKE_STYLE;
singleFileProgressBar.animatedValue = 0;
singleFileProgressBar.value = 0;
singleFileProgressBar.fillStyle = UNLOADED_FILL_STYLE;
singleFileProgressBar.strokeStyle = UNLOADED_STROKE_STYLE;
fileSequenceProgressBar.animatedValue = 0;
fileSequenceProgressBar.value = 0;
fileSequenceProgressBar.fillStyle = UNLOADED_FILL_STYLE;
fileSequenceProgressBar.strokeStyle = UNLOADED_STROKE_STYLE;
break;
case PRODUCT_CARD_STATUS.OFF:
changeStatusTo(PRODUCT_CARD_STATUS.LOADING);
break;
}
}
function changeStatusTo(pNewStatus) {
if (thisObject.status !== pNewStatus) {
thisObject.status = pNewStatus;
let eventData = thisObject;
thisObject.container.eventHandler.raiseEvent('Status Changed', eventData);
window.localStorage.setItem(thisObject.code, thisObject.status);
}
}
function draw() {
drawProductCard();
}
function drawProductCard() {
/*
Put images on the card.
*/
const devTeamImageSize = 50;
const botImageSize = 50;
const plotterImageSize = {
width: 180,
height: 50
};
/* First the Dev Team Profile Picture. */
let teamImagePoint = {
x: 10,
y: thisObject.container.frame.height / 2 - devTeamImageSize / 2
};
teamImagePoint = thisObject.container.frame.frameThisPoint(teamImagePoint);
let teamImage = document.getElementById(thisObject.bot.devTeam + ".png");
browserCanvasContext.drawImage(teamImage, teamImagePoint.x, teamImagePoint.y, devTeamImageSize, devTeamImageSize);
/* Second the Bot's Profile Picture. */
if (thisObject.bot.profilePicture !== undefined) {
let botImagePoint = {
x: thisObject.container.frame.width - 10 - botImageSize,
y: thisObject.container.frame.height / 2 - botImageSize / 2
};
botImagePoint = thisObject.container.frame.frameThisPoint(botImagePoint);
let imageId = thisObject.bot.devTeam + "." + thisObject.bot.profilePicture;
let botImage = document.getElementById(imageId);
browserCanvasContext.drawImage(botImage, botImagePoint.x, botImagePoint.y, botImageSize, botImageSize);
}
/* Third the Plotter's Profile Picture. */
if (thisObject.product.plotter.profilePicture !== undefined) {
let plotterImagePoint = {
x: thisObject.container.frame.width / 2 - plotterImageSize.width / 2,
y: thisObject.container.frame.height / 2 - plotterImageSize.height / 2
};
plotterImagePoint = thisObject.container.frame.frameThisPoint(plotterImagePoint);
let imageId = thisObject.product.plotter.devTeam + "." + thisObject.product.plotter.codeName + "." + thisObject.product.plotter.moduleName + "." + thisObject.product.plotter.profilePicture;
let plotterImage = document.getElementById(imageId);
browserCanvasContext.drawImage(plotterImage, plotterImagePoint.x, plotterImagePoint.y, plotterImageSize.width, plotterImageSize.height);
}
/* Now the small circle */
centerPoint = {
x: thisObject.container.frame.width / 2,
y: thisObject.container.frame.height / 2
};
/* Now the transformations. */
centerPoint = thisObject.container.frame.frameThisPoint(centerPoint);
/* Lets start the drawing. */
browserCanvasContext.beginPath();
browserCanvasContext.arc(centerPoint.x, centerPoint.y, 3, 0, 2 * Math.PI);
browserCanvasContext.closePath();
let offFillStyle = 'rgba(232, 28, 28, 0.75)';
let onFillStyle = 'rgba(45, 232, 28, 0.75)';
let loadingFillStyle = 'rgba(237, 227, 47, 0.75)';
switch (thisObject.status) {
case PRODUCT_CARD_STATUS.ON:
browserCanvasContext.fillStyle = onFillStyle;
break;
case PRODUCT_CARD_STATUS.OFF:
browserCanvasContext.fillStyle = offFillStyle;
break;
case PRODUCT_CARD_STATUS.LOADING:
browserCanvasContext.fillStyle = loadingFillStyle;
break;
}
browserCanvasContext.fill();
browserCanvasContext.strokeStyle = 'rgba(150, 150, 150, 1)';
browserCanvasContext.lineWidth = 1;
browserCanvasContext.stroke();
browserCanvasContext.closePath();
/* print the text */
let labelPoint;
let fontSize = 10;
browserCanvasContext.font = fontSize + 'px Courier New';
let label;
/* devTeam */
label = thisObject.devTeam.displayName;
labelPoint = {
x: 10 + devTeamImageSize / 2 - label.length / 2 * fontSize * 0.60,
y: thisObject.container.frame.height / 2 + devTeamImageSize / 2 + fontSize * 0.60 + 5
};
labelPoint = thisObject.container.frame.frameThisPoint(labelPoint);
browserCanvasContext.font = fontSize + 'px Courier New';
browserCanvasContext.fillStyle = 'rgba(60, 60, 60, 0.50)';
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y);
/* bot */
label = thisObject.bot.displayName;
labelPoint = {
x: thisObject.container.frame.width - 10 - botImageSize - 5 + botImageSize / 2 - label.length / 2 * fontSize * 0.60,
y: thisObject.container.frame.height / 2 + devTeamImageSize / 2 + fontSize * 0.60 + 5
};
labelPoint = thisObject.container.frame.frameThisPoint(labelPoint);
browserCanvasContext.font = fontSize + 'px Courier New';
browserCanvasContext.fillStyle = 'rgba(60, 60, 60, 0.50)';
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y);
/* product */
fontSize = 10;
label = thisObject.product.displayName;
labelPoint = {
x: 65,
y: thisObject.container.frame.height / 2 + 15
};
labelPoint = {
x: thisObject.container.frame.width / 2 - label.length / 2 * fontSize * 0.60,
y: thisObject.container.frame.height / 2 - devTeamImageSize / 2 - fontSize * 0.60 - 5
};
labelPoint = thisObject.container.frame.frameThisPoint(labelPoint);
browserCanvasContext.font = fontSize + 'px Courier New bold';
browserCanvasContext.fillStyle = 'rgba(60, 60, 60, 0.50)';
browserCanvasContext.fillText(label, labelPoint.x, labelPoint.y);
/* ------------------- Progress Bars -------------------------- */
const ANIMATED_INCREMENT = 5;
const OPACITY_INCREMENT = 0.05;
const OPACITY_MIN = 0.1;
let point1;
let point2;
let point3;
let point4;
/* We draw here the Market Progress Bar. */
/* Animate */
if (marketFileProgressBar.animatedValue < marketFileProgressBar.value) {
marketFileProgressBar.animatedValue = marketFileProgressBar.animatedValue + ANIMATED_INCREMENT;
marketFileProgressBar.opacity = marketFileProgressBar.opacity + OPACITY_INCREMENT;
}
if (marketFileProgressBar.animatedValue >= 100) {
marketFileProgressBar.animatedValue = 100;
marketFileProgressBar.opacity = marketFileProgressBar.opacity - OPACITY_INCREMENT;
if (marketFileProgressBar.opacity < OPACITY_MIN) { marketFileProgressBar.opacity = OPACITY_MIN;}
marketFileProgressBar.fillStyle = LOADED_FILL_STYLE.replace('@Opacity', marketFileProgressBar.opacity.toString());
marketFileProgressBar.strokeStyle = LOADED_STROKE_STYLE.replace('@Opacity', marketFileProgressBar.opacity.toString());
changeStatusTo(PRODUCT_CARD_STATUS.ON);
}
point1 = {
x: 0,
y: thisObject.container.frame.height - 1
};
point2 = {
x: thisObject.container.frame.width * marketFileProgressBar.animatedValue / 100,
y: thisObject.container.frame.height - 1
};
point3 = {
x: thisObject.container.frame.width * marketFileProgressBar.animatedValue / 100,
y: thisObject.container.frame.height - 3
};
point4 = {
x: 0,
y: thisObject.container.frame.height - 3
};
/* Now the transformations. */
point1 = thisObject.container.frame.frameThisPoint(point1);
point2 = thisObject.container.frame.frameThisPoint(point2);
point3 = thisObject.container.frame.frameThisPoint(point3);
point4 = thisObject.container.frame.frameThisPoint(point4);
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(point1.x, point1.y);
browserCanvasContext.lineTo(point2.x, point2.y);
browserCanvasContext.lineTo(point3.x, point3.y);
browserCanvasContext.lineTo(point4.x, point4.y);
browserCanvasContext.closePath();
browserCanvasContext.fillStyle = marketFileProgressBar.fillStyle.replace('@Opacity', marketFileProgressBar.opacity.toString());
browserCanvasContext.strokeStyle = marketFileProgressBar.strokeStyle.replace('@Opacity', marketFileProgressBar.opacity.toString());
browserCanvasContext.fill();
browserCanvasContext.lineWidth = 0.1;
browserCanvasContext.stroke();
/* We draw here the Daily Progress Bar. */
/* Animate */
if (dailyFileProgressBar.animatedValue < dailyFileProgressBar.value) {
dailyFileProgressBar.animatedValue = dailyFileProgressBar.animatedValue + ANIMATED_INCREMENT;
dailyFileProgressBar.opacity = dailyFileProgressBar.opacity + OPACITY_INCREMENT;
}
if (dailyFileProgressBar.animatedValue >= 100) {
dailyFileProgressBar.animatedValue = 100;
dailyFileProgressBar.opacity = dailyFileProgressBar.opacity - OPACITY_INCREMENT;
if (dailyFileProgressBar.opacity < OPACITY_MIN) { dailyFileProgressBar.opacity = OPACITY_MIN; }
dailyFileProgressBar.fillStyle = LOADED_FILL_STYLE.replace('@Opacity', dailyFileProgressBar.opacity.toString());
dailyFileProgressBar.strokeStyle = LOADED_STROKE_STYLE.replace('@Opacity', dailyFileProgressBar.opacity.toString());
changeStatusTo(PRODUCT_CARD_STATUS.ON);
}
point1 = {
x: 0,
y: thisObject.container.frame.height - 4
};
point2 = {
x: thisObject.container.frame.width * dailyFileProgressBar.animatedValue / 100,
y: thisObject.container.frame.height - 4
};
point3 = {
x: thisObject.container.frame.width * dailyFileProgressBar.animatedValue / 100,
y: thisObject.container.frame.height - 6
};
point4 = {
x: 0,
y: thisObject.container.frame.height - 6
};
/* Now the transformations. */
point1 = thisObject.container.frame.frameThisPoint(point1);
point2 = thisObject.container.frame.frameThisPoint(point2);
point3 = thisObject.container.frame.frameThisPoint(point3);
point4 = thisObject.container.frame.frameThisPoint(point4);
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(point1.x, point1.y);
browserCanvasContext.lineTo(point2.x, point2.y);
browserCanvasContext.lineTo(point3.x, point3.y);
browserCanvasContext.lineTo(point4.x, point4.y);
browserCanvasContext.closePath();
browserCanvasContext.fillStyle = dailyFileProgressBar.fillStyle.replace('@Opacity', dailyFileProgressBar.opacity.toString());
browserCanvasContext.strokeStyle = dailyFileProgressBar.strokeStyle.replace('@Opacity', dailyFileProgressBar.opacity.toString());
browserCanvasContext.fill();
browserCanvasContext.lineWidth = 0.1;
browserCanvasContext.stroke();
/* We draw here the Single File Progress Bar. */
/* Animate */
if (singleFileProgressBar.animatedValue < singleFileProgressBar.value) {
singleFileProgressBar.animatedValue = singleFileProgressBar.animatedValue + ANIMATED_INCREMENT;
singleFileProgressBar.opacity = singleFileProgressBar.opacity + OPACITY_INCREMENT;
}
if (singleFileProgressBar.animatedValue >= 100) {
singleFileProgressBar.animatedValue = 100;
singleFileProgressBar.opacity = singleFileProgressBar.opacity - OPACITY_INCREMENT;
if (singleFileProgressBar.opacity < OPACITY_MIN) { singleFileProgressBar.opacity = OPACITY_MIN; }
singleFileProgressBar.fillStyle = LOADED_FILL_STYLE.replace('@Opacity', singleFileProgressBar.opacity.toString());
singleFileProgressBar.strokeStyle = LOADED_STROKE_STYLE.replace('@Opacity', singleFileProgressBar.opacity.toString());
changeStatusTo(PRODUCT_CARD_STATUS.ON);
}
point1 = {
x: 0,
y: thisObject.container.frame.height - 7
};
point2 = {
x: thisObject.container.frame.width * singleFileProgressBar.animatedValue / 100,
y: thisObject.container.frame.height - 7
};
point3 = {
x: thisObject.container.frame.width * singleFileProgressBar.animatedValue / 100,
y: thisObject.container.frame.height - 9
};
point4 = {
x: 0,
y: thisObject.container.frame.height - 9
};
/* Now the transformations. */
point1 = thisObject.container.frame.frameThisPoint(point1);
point2 = thisObject.container.frame.frameThisPoint(point2);
point3 = thisObject.container.frame.frameThisPoint(point3);
point4 = thisObject.container.frame.frameThisPoint(point4);
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(point1.x, point1.y);
browserCanvasContext.lineTo(point2.x, point2.y);
browserCanvasContext.lineTo(point3.x, point3.y);
browserCanvasContext.lineTo(point4.x, point4.y);
browserCanvasContext.closePath();
browserCanvasContext.fillStyle = singleFileProgressBar.fillStyle.replace('@Opacity', singleFileProgressBar.opacity.toString());
browserCanvasContext.strokeStyle = singleFileProgressBar.strokeStyle.replace('@Opacity', singleFileProgressBar.opacity.toString());
browserCanvasContext.fill();
browserCanvasContext.lineWidth = 0.1;
browserCanvasContext.stroke();
/* We draw here the File Sequence Progress Bar. */
/* Animate */
if (fileSequenceProgressBar.animatedValue < fileSequenceProgressBar.value) {
fileSequenceProgressBar.animatedValue = fileSequenceProgressBar.animatedValue + ANIMATED_INCREMENT;
fileSequenceProgressBar.opacity = fileSequenceProgressBar.opacity + OPACITY_INCREMENT;
}
if (fileSequenceProgressBar.animatedValue >= 100) {
fileSequenceProgressBar.animatedValue = 100;
fileSequenceProgressBar.opacity = fileSequenceProgressBar.opacity - OPACITY_INCREMENT;
if (fileSequenceProgressBar.opacity < OPACITY_MIN) { fileSequenceProgressBar.opacity = OPACITY_MIN; }
fileSequenceProgressBar.fillStyle = LOADED_FILL_STYLE.replace('@Opacity', fileSequenceProgressBar.opacity.toString());
fileSequenceProgressBar.strokeStyle = LOADED_STROKE_STYLE.replace('@Opacity', fileSequenceProgressBar.opacity.toString());
changeStatusTo(PRODUCT_CARD_STATUS.ON);
}
point1 = {
x: 0,
y: thisObject.container.frame.height - 10
};
point2 = {
x: thisObject.container.frame.width * fileSequenceProgressBar.animatedValue / 100,
y: thisObject.container.frame.height - 10
};
point3 = {
x: thisObject.container.frame.width * fileSequenceProgressBar.animatedValue / 100,
y: thisObject.container.frame.height - 11
};
point4 = {
x: 0,
y: thisObject.container.frame.height - 11
};
/* Now the transformations. */
point1 = thisObject.container.frame.frameThisPoint(point1);
point2 = thisObject.container.frame.frameThisPoint(point2);
point3 = thisObject.container.frame.frameThisPoint(point3);
point4 = thisObject.container.frame.frameThisPoint(point4);
browserCanvasContext.beginPath();
browserCanvasContext.moveTo(point1.x, point1.y);
browserCanvasContext.lineTo(point2.x, point2.y);
browserCanvasContext.lineTo(point3.x, point3.y);
browserCanvasContext.lineTo(point4.x, point4.y);
browserCanvasContext.closePath();
browserCanvasContext.fillStyle = fileSequenceProgressBar.fillStyle.replace('@Opacity', fileSequenceProgressBar.opacity.toString());
browserCanvasContext.strokeStyle = fileSequenceProgressBar.strokeStyle.replace('@Opacity', fileSequenceProgressBar.opacity.toString());
browserCanvasContext.fill();
browserCanvasContext.lineWidth = 0.1;
browserCanvasContext.stroke();
}
}
-426
View File
@@ -1,426 +0,0 @@
function newProductStorage(pName) {
const MODULE_NAME = "Product Storage";
const INFO_LOG = false;
const ERROR_LOG = true;
const logger = newDebugLog();
logger.fileName = MODULE_NAME;
/*
This object will initialize children objects that will end up loading the data of each set defined at each product of the bot received at initialization.
Once all the underlaying objects are fully initialized it will callback.
At the same time it will raise an event for each underlaying file being loaded, so that the UI can reflect the progress to the end user.
Product Storage
|
|-----> SingleFile
|
|-----> FileSequence
|
|-----> DailyFiles -----> FileCursor
|
|-----> MarketFiles
*/
let thisObject = {
marketFiles: [],
dailyFiles: [],
singleFile: [],
fileSequence: [],
setDatetime: setDatetime,
setTimePeriod: setTimePeriod,
eventHandler: undefined,
initialize: initialize
}
thisObject.eventHandler = newEventHandler();
/* We name the event Handler to easy debugging. */
thisObject.eventHandler.name = "Storage-" + pName;
let datetime;
let timePeriod;
return thisObject;
function initialize(pDevTeam, pBot, pProduct, pExchange, pMarket, pDatetime, pTimePeriod, callBackFunction) {
try {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> Entering function."); }
if (INFO_LOG === true) { logger.write("[INFO] initialize -> key = " + pDevTeam.codeName + "-" + pBot.codeName + "-" + pProduct.codeName); }
datetime = pDatetime;
timePeriod = pTimePeriod;
let dataSetsToLoad = 0;
let dataSetsLoaded = 0;
for (let i = 0; i < pProduct.dataSets.length; i++) {
let thisSet = pProduct.dataSets[i];
switch (thisSet.type) {
case 'Market Files': {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> Market Files -> key = " + pDevTeam.codeName + "-" + pBot.codeName + "-" + pProduct.codeName); }
let marketFiles = newMarketFiles();
marketFiles.initialize(pDevTeam, pBot, pProduct, thisSet, pExchange, pMarket, onMarketFileReady);
thisObject.marketFiles.push(marketFiles);
dataSetsToLoad++;
}
break;
case 'Daily Files': {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> Daily Files -> key = " + pDevTeam.codeName + "-" + pBot.codeName + "-" + pProduct.codeName); }
let dailyFiles = newDailyFiles();
dailyFiles.initialize(pDevTeam, pBot, pProduct, thisSet, pExchange, pMarket, pDatetime, pTimePeriod, onDailyFileReady);
thisObject.dailyFiles.push(dailyFiles);
dataSetsToLoad++;
}
break;
case 'Single File': {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> Single File -> key = " + pDevTeam.codeName + "-" + pBot.codeName + "-" + pProduct.codeName); }
let singleFile = newSingleFile();
singleFile.initialize(pDevTeam, pBot, pProduct, thisSet, pExchange, pMarket, onSingleFileReady);
thisObject.singleFile.push(singleFile);
dataSetsToLoad++;
}
break;
case 'File Sequence': {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> File Sequence -> key = " + pDevTeam.codeName + "-" + pBot.codeName + "-" + pProduct.codeName); }
let fileSequence = newFileSequence();
fileSequence.initialize(pDevTeam, pBot, pProduct, thisSet, pExchange, pMarket, onFileSequenceReady);
thisObject.fileSequence.push(fileSequence);
dataSetsToLoad++;
}
break;
}
function onMarketFileReady(err, pCaller) {
try {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onMarketFileReady -> Entering function."); }
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onMarketFileReady -> key = " + pDevTeam.codeName + "-" + pBot.codeName + "-" + pProduct.codeName); }
switch (err.result) {
case GLOBAL.DEFAULT_OK_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onMarketFileReady -> Received OK Response."); }
break;
}
case GLOBAL.DEFAULT_FAIL_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onMarketFileReady -> Received FAIL Response."); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
return;
}
case GLOBAL.CUSTOM_FAIL_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onMarketFileReady -> Received CUSTOM FAIL Response."); }
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onMarketFileReady -> err.message = " + err.message); }
callBackFunction(err);
return;
}
default: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onMarketFileReady -> Received Unexpected Response."); }
callBackFunction(err);
return;
}
}
let event = {
totalValue: pCaller.getExpectedFiles(),
currentValue: pCaller.getFilesLoaded()
}
thisObject.eventHandler.raiseEvent('Market File Loaded', event);
if (event.currentValue === event.totalValue) {
dataSetsLoaded++;
checkInitializeComplete();
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> onMarketFileReady -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
function onDailyFileReady(err, pCaller) {
try {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onDailyFileReady -> Entering function."); }
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onDailyFileReady -> key = " + pDevTeam.codeName + "-" + pBot.codeName + "-" + pProduct.codeName); }
switch (err.result) {
case GLOBAL.DEFAULT_OK_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onDailyFileReady -> Received OK Response."); }
break;
}
case GLOBAL.DEFAULT_FAIL_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onDailyFileReady -> Received FAIL Response."); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
return;
}
case GLOBAL.CUSTOM_FAIL_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onDailyFileReady -> Received CUSTOM FAIL Response."); }
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onDailyFileReady -> err.message = " + err.message); }
callBackFunction(err);
return;
}
default: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onDailyFileReady -> Received Unexpected Response."); }
callBackFunction(err);
return;
}
}
let event = {
totalValue: pCaller.getExpectedFiles(),
currentValue: pCaller.getFilesLoaded()
}
thisObject.eventHandler.raiseEvent('Daily File Loaded', event);
if (event.currentValue === event.totalValue) {
dataSetsLoaded++;
checkInitializeComplete();
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> onDailyFileReady -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
function onSingleFileReady(err, pCaller) {
try {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onSingleFileReady -> Entering function."); }
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onSingleFileReady -> key = " + pDevTeam.codeName + "-" + pBot.codeName + "-" + pProduct.codeName); }
switch (err.result) {
case GLOBAL.DEFAULT_OK_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onSingleFileReady -> Received OK Response."); }
break;
}
case GLOBAL.DEFAULT_FAIL_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onSingleFileReady -> Received FAIL Response."); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
return;
}
case GLOBAL.CUSTOM_FAIL_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onSingleFileReady -> Received CUSTOM FAIL Response."); }
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onSingleFileReady -> err.message = " + err.message); }
callBackFunction(err);
return;
}
default: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onSingleFileReady -> Received Unexpected Response."); }
callBackFunction(err);
return;
}
}
let event = {
totalValue: 1,
currentValue: 1
}
thisObject.eventHandler.raiseEvent('Single File Loaded', event);
if (event.currentValue === event.totalValue) {
dataSetsLoaded++;
checkInitializeComplete();
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> onSingleFileReady -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
function onFileSequenceReady(err, pCaller) {
try {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileSequenceReady -> Entering function."); }
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileSequenceReady -> key = " + pDevTeam.codeName + "-" + pBot.codeName + "-" + pProduct.codeName); }
switch (err.result) {
case GLOBAL.DEFAULT_OK_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileSequenceReady -> Received OK Response."); }
break;
}
case GLOBAL.DEFAULT_FAIL_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileSequenceReady -> Received FAIL Response."); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
return;
}
case GLOBAL.CUSTOM_FAIL_RESPONSE.result: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileSequenceReady -> Received CUSTOM FAIL Response."); }
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileSequenceReady -> err.message = " + err.message); }
callBackFunction(err);
return;
}
default: {
if (INFO_LOG === true) { logger.write("[INFO] initialize -> onFileSequenceReady -> Received Unexpected Response."); }
callBackFunction(err);
return;
}
}
let event = {
totalValue: pCaller.getExpectedFiles(),
currentValue: pCaller.getFilesLoaded()
}
thisObject.eventHandler.raiseEvent('File Sequence Loaded', event);
if (event.currentValue === event.totalValue) {
dataSetsLoaded++;
checkInitializeComplete();
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> onFileSequenceReady -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
function checkInitializeComplete() {
try {
if (INFO_LOG === true) { logger.write("[INFO] checkInitializeComplete -> Entering function."); }
if (INFO_LOG === true) { logger.write("[INFO] checkInitializeComplete -> key = " + pDevTeam.codeName + "-" + pBot.codeName + "-" + pProduct.codeName); }
if (dataSetsLoaded === dataSetsToLoad) {
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE);
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> checkInitializeComplete -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] initialize -> err = " + err); }
callBackFunction(GLOBAL.DEFAULT_FAIL_RESPONSE);
}
}
function setDatetime(pDatetime) {
if (INFO_LOG === true) { logger.write("[INFO] setDatetime -> Entering function."); }
/* If there is a change in the day, then we take some actions, otherwise, we dont. */
let currentDate = Math.trunc(datetime.valueOf() / ONE_DAY_IN_MILISECONDS);
let newDate = Math.trunc(pDatetime.valueOf() / ONE_DAY_IN_MILISECONDS);
datetime = pDatetime;
if (currentDate !== newDate) {
if (timePeriod <= _1_HOUR_IN_MILISECONDS) {
for (let i = 0; i < thisObject.dailyFiles.length; i++) {
thisObject.dailyFiles[i].setDatetime(pDatetime);
}
}
}
}
function setTimePeriod(pTimePeriod) {
if (INFO_LOG === true) { logger.write("[INFO] setTimePeriod -> Entering function."); }
/* We are going to filter out the cases in which the timePeriod received is the same that the one we already know. */
if (timePeriod !== pTimePeriod) {
timePeriod = pTimePeriod;
if (timePeriod <= _1_HOUR_IN_MILISECONDS) {
for (let i = 0; i < thisObject.dailyFiles.length; i++) {
thisObject.dailyFiles[i].setTimePeriod(pTimePeriod, datetime);
}
}
}
}
}
+37 -77
View File
@@ -4,6 +4,7 @@
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
<Name>Project</Name>
<RootNamespace>browser</RootNamespace>
<LastActiveSolutionConfig>Debug|Any CPU</LastActiveSolutionConfig>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
@@ -29,108 +30,67 @@
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<Compile Include="AccumulatedVolumeBar.js" />
<Compile Include="Animation.js" />
<Compile Include="AABrowserAPI\BotCode.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="AABrowserAPI\TeamSetup.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="AABrowserAPI\UserAuthentication.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="Azure\azure-storage.blob.js" />
<Compile Include="FloatingSpace\Note.js">
<Compile Include="Ecosystem.js" />
<Compile Include="Plotter.js" />
<Compile Include="PlotterPanel.js" />
<Compile Include="Server\Exchange\ExchangeAPI.js" />
<Compile Include="Server\Exchange\exchangeUtils.js" />
<Compile Include="Server\Exchange\Wrappers\beautifier.js" />
<Compile Include="Server\Exchange\Wrappers\binance.js" />
<Compile Include="Server\Exchange\Wrappers\binanceClient.js" />
<Compile Include="Server\Exchange\Wrappers\poloniex.js" />
<Compile Include="Server\Exchange\Wrappers\poloniexClient.js" />
<Compile Include="Scripts\AppLoader.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="FloatingSpace\NoteSets.js">
<Compile Include="Scripts\AppPreLoader.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="FloatingSpace\FloatingObject.js" />
<Compile Include="CompetitionStorage.js">
<Compile Include="Server\BotsScripts.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="Files\FileSequence.js">
<Compile Include="Server\SessionManager.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="FloatingSpace\FloatingLayer.js">
<Compile Include="Server\StorageAccessManager.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="ImageButton.js">
<Compile Include="Scripts\require.js" />
<Compile Include="Server\CloudScripts.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="DebugLog.js">
<Compile Include="Server\ConfigReader.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="FloatingSpace\ProfileBalls.js">
<Compile Include="Server\Github.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="FloatingSpace\ProfileBall.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="Spaces\PanelsSpace.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="PlotterPanel.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="ProductCard.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="Ecosystem.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="Files\SingleFile.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="Files\FileCloud.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="Files\FileCursor.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="Files\DailyFiles.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="Button.js" />
<Compile Include="Candle.js" />
<Compile Include="Canvas.js" />
<Compile Include="ChartGrid.js" />
<Compile Include="Spaces\ChartSpace.js" />
<Compile Include="ChartUtilities.js" />
<Compile Include="Container.js" />
<Compile Include="Dashboard.js" />
<Compile Include="Files\MarketFiles.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="Plotter.js">
<Compile Include="Server\Storage.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="server.js" />
<Compile Include="Displace.js" />
<Compile Include="EventHandler.js" />
<Compile Include="Spaces\FloatingSpace.js" />
<Compile Include="Frame.js" />
<Compile Include="Markets.js" />
<Compile Include="Panels\ProductsPanel.js" />
<Compile Include="Panels\TimeControlPanel.js" />
<Compile Include="TimeLineCoordinateSystem.js" />
<Compile Include="SplashScreen.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="ProductStorage.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="TempExosystem.js">
<SubType>Code</SubType>
</Compile>
<Compile Include="TextButton.js" />
<Compile Include="TimelineChart.js" />
<Compile Include="TimeMachine.js" />
<Compile Include="Utilities.js" />
<Compile Include="ViewPort.js" />
<Compile Include="VolumeBar.js" />
<Content Include="index.html" />
<Content Include="Server\Exchange\Wrappers\binanceProperties.json" />
<Content Include="Server\Exchange\Wrappers\poloniexProperties.json" />
<Content Include="this.server.config.json" />
</ItemGroup>
<ItemGroup>
<Folder Include="Azure\" />
<Folder Include="Files\" />
<Folder Include="FloatingSpace\" />
<Folder Include="Spaces\" />
<Folder Include="Panels\" />
<Folder Include="Server\Exchange\" />
<Folder Include="AABrowserAPI\" />
<Folder Include="Server\Exchange\Wrappers\" />
<Folder Include="Scripts\" />
<Folder Include="Server\" />
</ItemGroup>
<!-- Do not delete the following Import Project. While this appears to do nothing it is a marker for setting TypeScript properties before our import that depends on them. -->
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.targets" Condition="False" />
+158
View File
@@ -0,0 +1,158 @@
function newAppLoader() {
const MODULE_NAME = "App Loader";
const INFO_LOG = false;
const ERROR_LOG = true;
const INTENSIVE_LOG = false;
const logger = newWebDebugLog();
logger.fileName = MODULE_NAME;
let thisObject = {
loadModules: loadModules
};
return thisObject;
function loadModules() {
try {
if (INFO_LOG === true) { logger.write("[INFO] loadModules -> Entering function."); }
let modulesArray = [
/* CloudWebScripts */
/* Plotters */
/* PlotterPanels */
"Globals.js",
"BottomSpace/DeleteTradingHistory.js",
"BottomSpace/ChartAspectRatio.js",
"BottomSpace/PlayStopButton.js",
"TopSpace/CompanyLogo.js",
"TopSpace/CurrentStartMode.js",
"TopSpace/CurrentProcess.js",
"TopSpace/CurrentBot.js",
"TopSpace/DevTeam.js",
"TopSpace/EndUser.js",
"TopSpace/Login.js",
"Panels/TimeControlPanel.js",
"Panels/ProductsPanel.js",
"Spaces/BottomSpace.js",
"Spaces/TopSpace.js",
"Spaces/PanelsSpace.js",
"Spaces/ChartSpace.js",
"Spaces/FloatingSpace.js",
"Files/SingleFile.js",
"Files/FileCloud.js",
"Files/MarketFiles.js",
"Files/DailyFiles.js",
"Files/FileCursor.js",
"Files/FileSequence.js",
"FloatingSpace/NoteSets.js",
"FloatingSpace/Note.js",
"FloatingSpace/ProfileBalls.js",
"FloatingSpace/ProfileBall.js",
"FloatingSpace/FloatingObject.js",
"FloatingSpace/FloatingLayer.js",
"Exchange/ExchangeAPI.js",
"CloudVM/CloudSupport.js",
"CloudVM/CloudRequire.js",
"CloudVM/WebFS.js",
"CloudVM/CloudVM.js",
"Scales/ChartGrid.js",
"Scales/RightScale.js",
"BreakpointsBar.js",
"Plotter.js",
"PlotterPanel.js",
"PlottersManager.js",
"ProductStorage.js",
"CompetitionStorage.js",
"ProductCard.js",
"Ecosystem.js",
"SplashScreen.js",
"Canvas.js",
"TextButton.js",
"ImageButton.js",
"EventHandler.js",
"Frame.js",
"ViewPort.js",
"TimeMachine.js",
"Candle.js",
"VolumeBar.js",
"ChartUtilities.js",
"TimelineChart.js",
"Animation.js",
"Container.js",
"Displace.js",
"Azure/azure-storage.blob.js",
"TimeLineCoordinateSystem.js",
"Utilities.js",
"Dashboard.js"
];
let downloadedCounter = 0;
for (let i = 0; i < modulesArray.length; i++) {
let path = window.canvasApp.urlPrefix + modulesArray[i];
REQUIREJS([path], onRequired);
if (INFO_LOG === true) { logger.write("[INFO] loadModules -> Module Requested."); }
if (INFO_LOG === true) { logger.write("[INFO] loadModules -> path = " + path); }
if (INFO_LOG === true) { logger.write("[INFO] loadModules -> total requested = " + (i + 1)); }
function onRequired(pModule) {
try {
if (INFO_LOG === true) { logger.write("[INFO] loadModules -> onRequired -> Entering function."); }
if (INFO_LOG === true) { logger.write("[INFO] loadModules -> onRequired -> Module Downloaded."); }
if (INFO_LOG === true) { logger.write("[INFO] loadModules -> onRequired -> path = " + path); }
downloadedCounter++;
if (INFO_LOG === true) { logger.write("[INFO] loadModules -> onRequired -> downloadedCounter = " + downloadedCounter); }
if (downloadedCounter === modulesArray.length) {
if (INFO_LOG === true) { logger.write("[INFO] loadModules -> onRequired -> Starting Advanced Algos Platform."); }
let dashboard = newDashboard();
dashboard.start();
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] loadModules -> onRequired -> err = " + err); }
}
}
}
} catch (err) {
if (ERROR_LOG === true) { logger.write("[ERROR] loadModules -> err = " + err); }
}
}
}
+138
View File
@@ -0,0 +1,138 @@
/* Callbacks default responses. */
let GLOBAL = {};
GLOBAL.DEFAULT_OK_RESPONSE = {
result: "Ok",
message: "Operation Succeeded"
};
GLOBAL.DEFAULT_FAIL_RESPONSE = {
result: "Fail",
message: "Operation Failed"
};
GLOBAL.DEFAULT_RETRY_RESPONSE = {
result: "Retry",
message: "Retry Later"
};
GLOBAL.CUSTOM_OK_RESPONSE = {
result: "Ok, but check Message",
message: "Custom Message"
};
GLOBAL.CUSTOM_FAIL_RESPONSE = {
result: "Fail Because",
message: "Custom Message"
};
let browserCanvas; // This is the canvas object of the browser.
function spacePad(str, max) {
str = str.toString();
return str.length < max ? spacePad(" " + str, max) : str;
}
function loadAdvancedAlgosPlatform() {
const MODULE_NAME = "App Pre-Loader";
const INFO_LOG = false;
const ERROR_LOG = true;
if (INFO_LOG === true) { console.log(spacePad(MODULE_NAME, 50) + " : " + "[INFO] loadAdvancedAlgosPlatform -> Entering function."); }
/* The first thing to do here is to add the canvas where all the action is going to happen. */
let canvas = document.createElement('canvas');
canvas.id = "canvas";
canvas.width = 1400;
canvas.height = 600;
canvas.style.border = "0";
canvas.style = "position:absolute; top:0px; left:0px; z-index:1";
let canvasApp = document.getElementById('canvasApp');
canvasApp.appendChild(canvas);
browserCanvas = document.getElementById('canvas');
browserCanvas.width = window.innerWidth;
browserCanvas.height = window.innerHeight - window.canvasApp.topMargin;
browserCanvas.style.border = "none";
browserCanvas.style.top = window.canvasApp.topMargin + 'px';
loadDebugModule();
function loadDebugModule() {
if (INFO_LOG === true) { console.log(spacePad(MODULE_NAME, 50) + " : " + "[INFO] loadDebugModule -> Entering function."); }
let path = window.canvasApp.urlPrefix + "WebDebugLog.js";
REQUIREJS([path], onRequired);
function onRequired(pModule) {
if (INFO_LOG === true) { console.log(spacePad(MODULE_NAME, 50) + " : " + "[INFO] " + path + " downloaded."); }
loadModules();
}
}
/* And Finally, we start loading all the scripts we will inmediatelly need. */
function loadModules() {
if (INFO_LOG === true) { console.log(spacePad(MODULE_NAME, 50) + " : " + "[INFO] loadModules -> Entering function."); }
let path = window.canvasApp.urlPrefix + "Scripts/AppLoader.js";
REQUIREJS([path], onRequired);
function onRequired(pModule) {
if (INFO_LOG === true) { console.log(spacePad(MODULE_NAME, 50) + " : " + "[INFO] " + path + " downloaded."); }
let APP_LOADER_MODULE = newAppLoader();
APP_LOADER_MODULE.loadModules();
}
}
}
function callServer(pContentToSend, pPath, callBackFunction) {
let xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState === 4 && this.status === 200) {
callBackFunction(xhttp.responseText);
}
};
if (pContentToSend === undefined) {
xhttp.open("GET", pPath, true);
xhttp.send();
} else {
try {
let blob = new Blob([pContentToSend], { type: 'text/plain' });
xhttp.open("POST", pPath, true);
xhttp.send(blob);
} catch (err) {
if (ERROR_LOG === true) { console.log(spacePad(MODULE_NAME, 50) + " : " + "[ERROR] callServer -> err.message = " & err.message); }
}
}
}
+2145
View File
File diff suppressed because it is too large. Load diff
+78
View File
@@ -0,0 +1,78 @@
exports.newBotScripts = function newBotScripts() {
let thisObject = {
getScript: getScript,
initialize: initialize
}
const STORAGE = require('../Server/Storage');
let storage = STORAGE.newStorage();
let serverConfig;
let storageData;
return thisObject;
function initialize(pServerConfig, callBackFunction) {
let storageData = new Map(); // For backwards compatibility only. Not used.
storage.initialize(storageData, pServerConfig);
callBackFunction();
}
function getScript(pDevTeam, pSource, pRepo, pPath, callBackFunction) {
storage.readData(pDevTeam + "/" + pSource, pRepo, pPath, false, onDataArrived);
function onDataArrived(err, pData) {
try {
if (CONSOLE_LOG === true) { console.log("[INFO] BotScripts -> retrieveScripts -> Cloud -> onDataArrived -> Entering function."); }
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
console.log("[ERROR] BotScripts -> retrieveScripts -> Cloud -> onDataArrived -> Could not read a file. ");
console.log("[ERROR] BotScripts -> retrieveScripts -> Cloud -> onDataArrived -> err.message = " + err.message);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
return;
}
let data;
if (pData !== undefined) {
data = pData.toString();
data = data.trim(); // remove first byte with some encoding.
data = browserify(data);
}
callBackFunction(global.DEFAULT_OK_RESPONSE, data);
}
catch (err) {
console.log("[ERROR] BotScripts -> retrieveScripts -> Cloud -> onDataArrived -> Error = " + err);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
}
function browserify(pData) {
let result = pData.substring(pData.indexOf('=') + 2);
result = replaceAll(result, "require", "webRequire");
result = replaceAll(result, "global", "window");
return result;
function replaceAll(text, search, replacement) {
return text.replace(new RegExp(search, 'g'), replacement);
}
}
}
+172
View File
@@ -0,0 +1,172 @@
exports.newCloudScripts = function newCloudScripts() {
let thisObject = {
loadCloudScripts: loadCloudScripts,
initialize: initialize
}
const GITHUB = require('../Server/Github');
let github = GITHUB.newGithub();
const STORAGE = require('../Server/Storage');
let storage = STORAGE.newStorage();
let serverConfig;
let storageData;
let ecosystem;
let ecosystemObject;
return thisObject;
function initialize(pEcosystem, pEcosystemObject, pServerConfig, pStorageData, callBackFunction) {
serverConfig = pServerConfig;
storageData = pStorageData;
ecosystem = pEcosystem;
ecosystemObject = pEcosystemObject;
storage.initialize(storageData, serverConfig);
callBackFunction(global.DEFAULT_OK_RESPONSE);
}
function loadCloudScripts(callBackFunction) {
try {
if (CONSOLE_LOG === true) { console.log("[INFO] CloudScripts -> loadCloudScripts -> Entering function."); }
/*
First we will get a list of the scripts to be loaded, and then we will load them into the cache.
*/
storage.readData('AdvancedAlgos', 'AACloud', 'web.config.json', true, onDataArrived);
function onDataArrived(err, pData) {
try {
if (CONSOLE_LOG === true) { console.log("[INFO] CloudScripts -> loadCloudScripts -> Cloud -> onDataArrived -> Entering function."); }
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
console.log("[ERROR] CloudScripts -> loadCloudScripts -> Cloud -> onDataArrived -> Could not read a file. ");
console.log("[ERROR] CloudScripts -> loadCloudScripts -> Cloud -> onDataArrived -> err.message = " + err.message);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
return;
}
let data = pData.toString();
data = data.trim(); // remove first byte with some encoding.
dataObject = JSON.parse(data);
retrieveScripts(dataObject, callBackFunction);
}
catch (err) {
console.log("[ERROR] CloudScripts -> loadCloudScripts -> Cloud -> onDataArrived -> Error = " + err);
}
}
}
catch (err) {
console.log("[ERROR] CloudScripts -> loadCloudScripts -> Error = " + err);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
function retrieveScripts(pCloudWebConfig, callBackFunction) {
try {
if (CONSOLE_LOG === true) { console.log("[INFO] CloudScripts -> retrieveScripts -> Entering function."); }
/*
Here we go through the webModules Array and bring them all.
*/
let modulesRetrieved = 0;
for (let i = 0; i < pCloudWebConfig.webModules.length; i++) {
let webModule = pCloudWebConfig.webModules[i].name;
storage.readData('AdvancedAlgos', 'AACloud', webModule, true, onDataArrived);
function onDataArrived(err, pData) {
try {
if (CONSOLE_LOG === true) { console.log("[INFO] CloudScripts -> retrieveScripts -> Cloud -> onDataArrived -> Entering function."); }
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
console.log("[ERROR] CloudScripts -> retrieveScripts -> Cloud -> onDataArrived -> Could not read a file. ");
console.log("[ERROR] CloudScripts -> retrieveScripts -> Cloud -> onDataArrived -> err.message = " + err.message);
console.log("[ERROR] CloudScripts -> retrieveScripts -> Cloud -> onDataArrived -> ewebModule = " + webModule);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
return;
}
let data = pData.toString();
data = data.trim(); // remove first byte with some encoding.
data = browserify(data);
storageData.set(webModule, data);
modulesRetrieved++;
if (modulesRetrieved === pCloudWebConfig.webModules.length) {
createJS(callBackFunction);
}
}
catch (err) {
console.log("[ERROR] CloudScripts -> retrieveScripts -> Cloud -> onDataArrived -> Error = " + err);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
}
function browserify(pData) {
let result = pData.substring(pData.indexOf('=') + 2);
result = replaceAll(result, "require", "webRequire");
result = replaceAll(result, "global", "window");
return result;
function replaceAll(text, search, replacement) {
return text.replace(new RegExp(search, 'g'), replacement);
}
}
function createJS(callBackFunction) {
let lines = "";
let jsLine = '' + '\n' + ' "AACloud/@module@",'
for (let i = 0; i < pCloudWebConfig.webModules.length; i++) {
let webModule = pCloudWebConfig.webModules[i].name;
let htmlLineCopy = jsLine;
let newLink = htmlLineCopy.replace('@module@', webModule);
lines = lines + newLink;
}
callBackFunction(global.DEFAULT_OK_RESPONSE, lines);
}
}
catch (err) {
console.log("[ERROR] CloudScripts -> retrieveScripts -> Error = " + err);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
}
+621
View File
@@ -0,0 +1,621 @@
exports.newConfigReader = function newConfigReader() {
let thisObject = {
loadConfigs: loadConfigs,
initialize: initialize
}
const GITHUB = require('../Server/Github');
let github = GITHUB.newGithub();
const STORAGE = require('../Server/Storage');
let storage = STORAGE.newStorage();
let serverConfig;
let storageData;
let ecosystem;
let ecosystemObject;
return thisObject;
function initialize(pEcosystem, pEcosystemObject, pStorageData, callBackFunction) {
storageData = pStorageData;
ecosystem = pEcosystem;
ecosystemObject = pEcosystemObject;
readAAWebConfig();
function readAAWebConfig() {
try {
if (CONSOLE_LOG === true) { console.log("[INFO] ConfigReader -> readAAWebConfig -> Entering function."); }
let fs = require('fs');
let fileName = './this.server.config.json';
fs.readFile(fileName, onFileRead);
function onFileRead(err, file) {
try {
if (CONSOLE_LOG === true) { console.log("[INFO] ConfigReader -> readAAWebConfig -> onFileRead -> Entering function."); }
let fileText;
fileText = file.toString();
fileText = fileText.trim(); // remove first byte with some encoding.
serverConfig = JSON.parse(fileText);
if (LOG_FILE_CONTENT === true) { console.log("[INFO] ConfigReader -> readAAWebConfig -> onFileRead -> fileText = " + fileText); }
CONSOLE_LOG = serverConfig.webServerLog.console;
LOG_FILE_CONTENT = serverConfig.webServerLog.fileContent;
/* Finalize initializations. */
storage.initialize(storageData, serverConfig);
callBackFunction(global.DEFAULT_OK_RESPONSE, serverConfig);
}
catch (err) {
console.log("[ERROR] ConfigReader -> readAAWebConfig -> onFileRead -> File = " + fileName + " Error = " + err);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
}
catch (err) {
console.log("[ERROR] ConfigReader -> readAAWebConfig -> Error = " + err);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
}
function loadConfigs(callBackFunction) {
readEcosystemConfig();
function readEcosystemConfig() {
try {
if (CONSOLE_LOG === true) { console.log("[INFO] ConfigReader -> readEcosystemConfig -> Entering function."); }
/*
This configuration file is the backbone of the system. The first file we are going to get is a template where other configurations are
injected and the files ends up inflated with all these configs in one single JSON object that in turn is later injected into a
javascript module with an object that is going to instantiate it at run-time.
*/
storage.readData('AdvancedAlgos', 'AAPlatform', 'ecosystem.json', true, onDataArrived);
function onDataArrived(err, pData) {
try {
if (CONSOLE_LOG === true) { console.log("[INFO] ConfigReader -> readEcosystemConfig -> Cloud -> onDataArrived -> Entering function."); }
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
console.log("[ERROR] ConfigReader -> readEcosystemConfig -> Cloud -> onDataArrived -> Could not read a file. ");
console.log("[ERROR] ConfigReader -> readEcosystemConfig -> Cloud -> onDataArrived -> err.message = " + err.message);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
return;
}
ecosystem = pData.toString();
ecosystem = ecosystem.trim(); // remove first byte with some encoding.
ecosystemObject = JSON.parse(ecosystem);
readHostsConfigs();
}
catch (err) {
console.log("[ERROR] ConfigReader -> loadConfigs -> readEcosystemConfig -> onDataArrived -> Error = " + err);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
}
catch (err) {
console.log("[ERROR] ConfigReader -> loadConfigs -> readEcosystemConfig -> Error = " + err);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
function readHostsConfigs() {
try {
if (CONSOLE_LOG === true) { console.log("[INFO] ConfigReader -> readHostsConfigs -> Entering function."); }
let requestsSent = 0;
let responsesReceived = 0;
for (let i = 0; i < ecosystemObject.hosts.length; i++) {
let host = ecosystemObject.hosts[i];
getCompetitions();
getPlotters();
function getCompetitions() {
try {
if (CONSOLE_LOG === true) { console.log("[INFO] ConfigReader -> readHostsConfigs -> getCompetitions -> Entering function."); }
/* In this first section we will load the competitions configurations. */
for (let j = 0; j < host.competitions.length; j++) {
let competition = host.competitions[j];
requestsSent++;
storage.readData(host.codeName + "/" + "competitions", competition.repo, competition.configFile, true, onDataArrived);
function onDataArrived(err, pData) {
try {
if (CONSOLE_LOG === true) { console.log("[INFO] ConfigReader -> readHostsConfigs -> getCompetitions -> Cloud -> onDataArrived -> Entering function."); }
if (CONSOLE_LOG === true) { console.log("[INFO] ConfigReader -> readHostsConfigs -> getCompetitions -> Cloud -> onDataArrived -> host.codeName = " + host.codeName); }
if (CONSOLE_LOG === true) { console.log("[INFO] ConfigReader -> readHostsConfigs -> getCompetitions -> Cloud -> onDataArrived -> competition.repo = " + competition.repo); }
if (LOG_FILE_CONTENT === true) { console.log("[INFO] ConfigReader -> readHostsConfigs -> getCompetitions -> Cloud -> onDataArrived -> pData = " + pData); }
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
console.log("[ERROR] ConfigReader -> readHostsConfigs -> getCompetitions -> Cloud -> onDataArrived -> Could not read a file. ");
console.log("[ERROR] ConfigReader -> readHostsConfigs -> getCompetitions -> Cloud -> onDataArrived -> err.message = " + err.message);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
return;
}
responsesReceived++;
pData = pData.toString();
pData = pData.trim(); // remove first byte with some encoding.
let configObj = JSON.parse(pData);
/* Since we are going to replace the full bot object and we dont want to lose these two properties, we do this: */
configObj.repo = competition.repo;
configObj.configFile = competition.configFile;
host.competitions[j] = configObj;
if (requestsSent === responsesReceived) {
readDevTeamsConfigs();
}
}
catch (err) {
console.log("[ERROR] ConfigReader -> readHostsConfigs -> getCompetitions -> Cloud -> onDataArrived -> Error = " + err);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
}
}
catch (err) {
console.log("[ERROR] ConfigReader -> readHostsConfigs -> getCompetitions -> getCompetitions -> Error = " + err);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
function getPlotters() {
try {
if (CONSOLE_LOG === true) { console.log("[INFO] ConfigReader -> readHostsConfigs -> getPlotters -> getPlotters -> Entering function."); }
/* In this second section we will load the competition plotters configurations. */
for (let j = 0; j < host.plotters.length; j++) {
let plotter = host.plotters[j];
requestsSent++;
storage.readData(host.codeName + "/" + "plotters", plotter.repo, plotter.configFile, true, onDataArrived);
function onDataArrived(err, pData) {
try {
if (CONSOLE_LOG === true) { console.log("[INFO] ConfigReader -> readHostsConfigs -> getPlotters -> Cloud -> onDataArrived -> Entering function."); }
if (CONSOLE_LOG === true) { console.log("[INFO] ConfigReader -> readHostsConfigs -> getPlotters -> Cloud -> onDataArrived -> host.codeName = " + host.codeName); }
if (CONSOLE_LOG === true) { console.log("[INFO] ConfigReader -> readHostsConfigs -> getPlotters -> Cloud -> onDataArrived -> plotter.repo = " + plotter.repo); }
if (LOG_FILE_CONTENT === true) { console.log("[INFO] ConfigReader -> readHostsConfigs -> getPlotters -> Cloud -> onDataArrived -> pData = " + pData); }
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
console.log("[ERROR] ConfigReader -> readHostsConfigs -> getPlotters -> Cloud -> onDataArrived -> Could not read a file. ");
console.log("[ERROR] ConfigReader -> readHostsConfigs -> getPlotters -> Cloud -> onDataArrived -> err.message = " + err.message);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
return;
}
responsesReceived++;
pData = pData.toString();
pData = pData.trim(); // remove first byte with some encoding.
let configObj = JSON.parse(pData);
/* Since we are going to replace the full bot object and we dont want to lose these two properties, we do this: */
configObj.repo = plotter.repo;
configObj.configFile = plotter.configFile;
host.plotters[j] = configObj;
if (requestsSent === responsesReceived) {
readDevTeamsConfigs();
}
}
catch (err) {
console.log("[ERROR] ConfigReader -> readHostsConfigs -> getPlotters -> Cloud -> onDataArrived -> Error = " + err);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
}
}
catch (err) {
console.log("[ERROR] ConfigReader -> readHostsConfigs -> getPlotters -> getCompetitions -> Error = " + err);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
}
}
catch (err) {
console.log("[ERROR] ConfigReader -> readHostsConfigs -> Error = " + err);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
function readDevTeamsConfigs() {
try {
if (CONSOLE_LOG === true) { console.log("[INFO] ConfigReader -> readDevTeamsConfigs -> Entering function."); }
/*
Each bot has its configuration at its own repo since each team must be able to change it at will.
So what we do here is to use the master config at the AAPlatform repo that we already have on
memory and inject into it the config of each bot.
Inmediatelly after that, we also load the Plotters configs using the same technique.
*/
let requestsSent = 0;
let responsesReceived = 0;
for (let i = 0; i < ecosystemObject.devTeams.length; i++) {
let devTeam = ecosystemObject.devTeams[i];
getBots();
getPlotters();
function getBots() {
try {
if (CONSOLE_LOG === true) { console.log("[INFO] ConfigReader -> readDevTeamsConfigs -> getBots -> Entering function."); }
/* In the next section we are loading the bots configurations. */
for (let j = 0; j < devTeam.bots.length; j++) {
let bot = devTeam.bots[j];
requestsSent++;
storage.readData(devTeam.codeName + "/" + "bots", bot.repo, bot.configFile, true, onDataArrived);
function onDataArrived(err, pData) {
try {
if (CONSOLE_LOG === true) { console.log("[INFO] ConfigReader -> readDevTeamsConfigs -> getBots -> Cloud -> onDataArrived -> Entering function."); }
if (CONSOLE_LOG === true) { console.log("[INFO] ConfigReader -> readDevTeamsConfigs -> getBots -> Cloud -> onDataArrived -> devTeam.codeName = " + devTeam.codeName); }
if (CONSOLE_LOG === true) { console.log("[INFO] ConfigReader -> readDevTeamsConfigs -> getBots -> Cloud -> onDataArrived -> bot.repo = " + bot.repo); }
if (LOG_FILE_CONTENT === true) { console.log("[INFO] ConfigReader -> readDevTeamsConfigs -> getBots -> Cloud -> onDataArrived -> pData = " + pData); }
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
console.log("[ERROR] ConfigReader -> readDevTeamsConfigs -> getBots -> Cloud -> onDataArrived -> Could not read a file. ");
console.log("[ERROR] ConfigReader -> readDevTeamsConfigs -> getBots -> Cloud -> onDataArrived -> err.message = " + err.message);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
return;
}
responsesReceived++;
if (pData !== "{}") { // If for any reason we could not tet this config, then we just exclude this bot to improve resiliency.
pData = pData.toString();
pData = pData.trim(); // remove first byte with some encoding.
let configObj = JSON.parse(pData);
/* Since we are going to replace the full bot object and we dont want to lose these two properties, we do this: */
configObj.repo = bot.repo;
configObj.configFile = bot.configFile;
addStoragePermissions(configObj);
/* Here we will add all the possible Clones of this bot */
if (configObj.genes !== undefined) {
/* Here, based on the genes we will create one instance for each combination of genes */
let valueMatrix = [];
for (let i = 0; i < configObj.genes.length; i++) {
let gene = configObj.genes[i];
let possibleValues = [];
for (let j = gene.lowerLimit; j <= gene.upperLimit; j++) {
possibleValues.push(j);
}
valueMatrix.push(possibleValues);
}
/*
Now we have all the possible genes values in a multi-dimensional matrix.
We will go thorugh each of the elements of each dimension and get each combination possible with the other dimmensions.
*/
let combinations = [];
let combination = [];
let dimensionIndex = 0;
calculateCombinations(dimensionIndex, combination);
function calculateCombinations(pDimensionIndex, pCombination) {
let dimension = valueMatrix[pDimensionIndex];
for (let j = 0; j < dimension.length; j++) {
let copy = JSON.parse(JSON.stringify(pCombination));
let value = dimension[j];
copy.push(value);
if (pDimensionIndex < valueMatrix.length - 1) {
calculateCombinations(pDimensionIndex + 1, copy);
} else {
combinations.push(copy);
}
}
}
/* We delete the bot definition since it is going to be replaced by one definition for each of its clones. */
devTeam.bots.splice(j);
/* At this point we have an array with all the possible combinations, we just need to create an instance for each one and set the genes according to that. */
for (let i = 0; i < combinations.length; i++) {
let botConfig = JSON.parse(JSON.stringify(configObj));
let combination = combinations[i];
let genes = {};
let clonKey = "";
for (let j = 0; j < botConfig.genes.length; j++) {
genes[botConfig.genes[j].name] = combination[j];
clonKey = clonKey + "." + combination[j];
}
let clonName = "Clon" + clonKey;
let clonConfig = JSON.parse(JSON.stringify(botConfig));
/* Lets adapt the bot config so as to tune it for the new clon. */
clonConfig.displayName = clonConfig.displayName + " " + clonName;
clonConfig.codeName = clonConfig.codeName + "-" + clonName;
/*
for (let j = 0; j < clonConfig.products.length; j++) {
let product = clonConfig.products[j];
for (let k = 0; k < product.dataSets.length; k++) {
let dataSet = product.dataSets[k];
dataSet.filePath = dataSet.filePath.replace("@Clon", "-" + clonName);
}
}
*/
devTeam.bots.push(clonConfig);
}
} else {
/* If the bot does not have any genes at all we do what we did before clones existed */
devTeam.bots[j] = configObj;
}
}
if (requestsSent === responsesReceived) {
callBackFunction(global.DEFAULT_OK_RESPONSE, ecosystem, ecosystemObject);
}
}
catch (err) {
console.log("[ERROR] ConfigReader -> readDevTeamsConfigs -> getBots -> Cloud -> onDataArrived -> Error = " + err);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
}
}
catch (err) {
console.log("[ERROR] ConfigReader -> readDevTeamsConfigs -> getBots -> Error = " + err);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
function getPlotters() {
try {
if (CONSOLE_LOG === true) { console.log("[INFO] ConfigReader -> readDevTeamsConfigs -> getPlotters -> Entering Function."); }
/* In the next section we are loading the plotters configurations. */
for (let j = 0; j < devTeam.plotters.length; j++) {
let plotter = devTeam.plotters[j];
requestsSent++;
storage.readData(devTeam.codeName + "/" + "plotters", plotter.repo, plotter.configFile, true, onDataArrived);
function onDataArrived(err, pData) {
try {
if (CONSOLE_LOG === true) { console.log("[INFO] ConfigReader -> readDevTeamsConfigs -> getPlotters -> Cloud -> onDataArrived -> Entering function."); }
if (CONSOLE_LOG === true) { console.log("[INFO] ConfigReader -> readDevTeamsConfigs -> getPlotters -> Cloud -> onDataArrived -> devTeam.codeName = " + devTeam.codeName); }
if (CONSOLE_LOG === true) { console.log("[INFO] ConfigReader -> readDevTeamsConfigs -> getPlotters -> Cloud -> onDataArrived -> plotter.repo = " + plotter.repo); }
if (LOG_FILE_CONTENT === true) { console.log("[INFO] ConfigReader -> readDevTeamsConfigs -> getPlotters -> Cloud -> onDataArrived -> pData = " + pData); }
if (err.result !== global.DEFAULT_OK_RESPONSE.result) {
console.log("[ERROR] ConfigReader -> readDevTeamsConfigs -> getPlotters -> Cloud -> onDataArrived -> Could not read a file. ");
console.log("[ERROR] ConfigReader -> readDevTeamsConfigs -> getPlotters -> Cloud -> onDataArrived -> err.message = " + err.message);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
return;
}
responsesReceived++;
if (pData !== "{}") { // If for any reason we could not tet this config, then we just exclude this bot to improve resiliency.
pData = pData.toString();
pData = pData.trim(); // remove first byte with some encoding.
let configObj = JSON.parse(pData);
/* Since we are going to replace the full plotter object and we dont want to lose these two properties, we do this: */
configObj.repo = plotter.repo;
configObj.configFile = plotter.configFile;
devTeam.plotters[j] = configObj;
}
if (requestsSent === responsesReceived) {
callBackFunction(global.DEFAULT_OK_RESPONSE, ecosystem, ecosystemObject);
}
}
catch (err) {
console.log("[ERROR] ConfigReader -> readDevTeamsConfigs -> getPlotters -> Cloud -> onDataArrived -> Error = " + err);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
}
}
catch (err) {
console.log("[ERROR] ConfigReader -> readDevTeamsConfigs -> getPlotters -> Error = " + err);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
}
function addStoragePermissions(pConfigObj) {
try {
if (CONSOLE_LOG === true) { console.log("[INFO] ConfigReader -> readDevTeamsConfigs -> addStoragePermissions -> Entering function."); }
if (pConfigObj.storage !== undefined) { return; } // If this information is at the config file, then we take it, otherwise, we define it here.
let fileUri;
let sas;
switch (serverConfig.environment) {
case "Develop": {
fileUri = serverConfig.productsStorage.Develop.fileUri;
sas = serverConfig.productsStorage.Develop.sas;
break;
}
case "Production": {
fileUri = serverConfig.productsStorage.Production.fileUri;
sas = serverConfig.productsStorage.Production.sas;
break;
}
}
pConfigObj.storage = {
sas: sas,
fileUri: fileUri
};
}
catch (err) {
console.log("[ERROR] ConfigReader -> readDevTeamsConfigs -> addStoragePermissions -> Error = " + err);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
}
catch (err) {
console.log("[ERROR] ConfigReader -> readDevTeamsConfigs -> Error = " + err);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
}
}
+304
View File
@@ -0,0 +1,304 @@
exports.newExchangeAPI = function newExchangeAPI(botDisplayName, authToken) {
/*
This module allows trading bots to connect to the exchange and do trading operations on it. So far it can only work with Poloniex.
*/
const _ = require('lodash');
const isValidOrder = require('./exchangeUtils').isValidOrder;
const graphqlClient = require('graphql-client')
const MASTER_APP_API = 'https://app-api.advancedalgos.net/graphql';
//const MASTER_APP_API = 'http://localhost:4100/graphql';
let MODULE_NAME = "Exchange API";
let thisObject = {
initialize: initialize,
getTicker: getTicker,
getOpenPositions: getOpenPositions,
getExecutedTrades: getExecutedTrades,
putPosition: putPosition,
movePosition: movePosition,
getPublicTradeHistory: getPublicTradeHistory,
getExchangeProperties: getExchangeProperties,
getMaxDecimalPositions: getMaxDecimalPositions
};
let apiClient;
return thisObject;
function initialize(callBackFunction) {
try {
if (CONSOLE_LOG === true) { console.log("[INFO] ExchangeAPI -> initialize -> Entering function."); }
//TODO From financial beings we get the exchange the bot is trading
let botExchange = 'Poloniex';
let exchange = botExchange.toLowerCase() + 'Client.js';
let api = require('./Wrappers/' + exchange);
if (!authToken) {
console.log("[ERROR] Exchange API -> initialize -> User Not Logged In.");
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
} else {
let keyVaultAPI = createKeyVaultAPIClient(authToken)
apiClient = api.newAPIClient(keyVaultAPI);
callBackFunction(global.DEFAULT_OK_RESPONSE);
}
} catch (err) {
console.log("[ERROR] ExchangeAPI -> initialize -> err = " + err.message);
callBackFunction(global.DEFAULT_FAIL_RESPONSE);
}
}
function createKeyVaultAPIClient(authToken) {
if (CONSOLE_LOG === true) { console.log("[INFO] createKeyVaultAPIClient -> Entering function."); }
const keyVaultAPI = graphqlClient({
url: MASTER_APP_API,
headers: {
Authorization: 'Bearer ' + authToken
}
});
keyVaultAPI.signTransaction = function (transaction, next) {
let variables = {
botId: botDisplayName,
transaction: transaction
}
keyVaultAPI.query(`
mutation($botId: String, $transaction: String!){
keyVault_SignTransaction(botId: $botId, transaction: $transaction){
key,
signature,
date
}
}`, variables, function (req, res) {
if (res.status === 401) {
next(undefined, 'Error from graphql: Not authorized');
}
}).then(res => {
if (res.errors) {
next(undefined, 'Error from graphql: ' + res.errors);
} else {
let signature = {
Key: res.data.keyVault_SignTransaction.key,
Sign: res.data.keyVault_SignTransaction.signature
}
next(signature)
}
}).catch(error => {
next(undefined, 'Error signing the message on the key vault: ' + error.message);
});
}
if (CONSOLE_LOG === true) { console.log("[INFO] createKeyVaultAPIClient -> Returning graphql client."); }
return keyVaultAPI;
}
/*
* Position Object = {
* id, String
* type, String
* rate, Number
* amountA, Number
* amountB, Number
* fee, Number
* datetime Date
* };
*/
function truncDecimals(pFloatValue) {
let decimals = getMaxDecimalPositions();
return parseFloat(parseFloat(pFloatValue).toFixed(decimals));
}
/*
* Return number of decimals for the current market
*/
function getMaxDecimalPositions() {
return getMarketConfig().maxDecimals;
}
/*
* Return number of decimals for the current market
*/
function getMarketConfig() {
return _.find(getExchangeProperties().markets, (p) => {
return _.first(p.pair) === global.MARKET.assetA.toUpperCase() &&
_.last(p.pair) === global.MARKET.assetB.toUpperCase();
});
}
/*
* Return number of decimals for the current market
*/
function getExchangeProperties() {
try {
if (CONSOLE_LOG === true) { console.log("[INFO] ExchangeAPI -> getExchangeProperties -> Entering function."); }
return apiClient.getExchangeProperties();
} catch (err) {
console.log("[ERROR] ExchangeAPI -> getExchangeProperties -> err = " + err.message);
callBack(global.DEFAULT_FAIL_RESPONSE);
}
}
/*
* Returns the price for a given pair of assets.
* The object returned is an array of trades:
* ticker = {
* bid, Number
* ask, Number
* last Number
* };
*/
function getTicker(pMarket, callBack) {
try {
if (CONSOLE_LOG === true) { console.log("[INFO] ExchangeAPI -> getTicker -> Entering function."); }
apiClient.getTicker(pMarket, callBack);
} catch (err) {
console.log("[ERROR] ExchangeAPI -> getTicker -> err = " + err.message);
callBack(global.DEFAULT_FAIL_RESPONSE);
}
}
/*
* Returns the open positions ath the exchange for a given market and user account.
* The object returned is an array of positions
*
*/
function getOpenPositions(pMarket, callBack) {
try {
if (CONSOLE_LOG === true) { console.log("[INFO] ExchangeAPI -> getOpenPositions -> Entering function."); }
if (CONSOLE_LOG === true) { console.log("[INFO] ExchangeAPI -> getOpenPositions -> pMarket = " + JSON.stringify(pMarket)); }
apiClient.getOpenPositions(pMarket, callBack);
} catch (err) {
console.log("[ERROR] ExchangeAPI -> getOpenPositions -> Error = " + err.message);
callBack(global.DEFAULT_FAIL_RESPONSE);
}
}
/*
* Returns the trades for a given order number.
* The object returned is an array of positions
*/
function getExecutedTrades(pPositionId, callBack) {
try {
if (CONSOLE_LOG === true) { console.log("[INFO] ExchangeAPI -> getExecutedTrades -> Entering function."); }
if (CONSOLE_LOG === true) { console.log("[INFO] ExchangeAPI -> getExecutedTrades -> pPositionId = " + pPositionId); }
apiClient.getExecutedTrades(pPositionId, callBack);
} catch (err) {
console.log("[ERROR] ExchangeAPI -> getExecutedTrades -> Error = " + err.message);
callBack(global.DEFAULT_FAIL_RESPONSE);
}
}
/*
* Creates a new buy or sell order.
* The orderNumber is returned. String
*/
function putPosition(pMarket, pType, pRate, pAmountA, pAmountB, callBack) {
try {
if (CONSOLE_LOG === true) { console.log("[INFO] ExchangeAPI -> putPosition -> Entering function."); }
if (CONSOLE_LOG === true) { console.log("[INFO] ExchangeAPI -> putPosition -> pMarket = " + JSON.stringify(pMarket)); }
if (CONSOLE_LOG === true) { console.log("[INFO] ExchangeAPI -> putPosition -> pType = " + pType); }
if (CONSOLE_LOG === true) { console.log("[INFO] ExchangeAPI -> putPosition -> pRate = " + truncDecimals(pRate)); }
if (CONSOLE_LOG === true) { console.log("[INFO] ExchangeAPI -> putPosition -> pAmountA = " + truncDecimals(pAmountA)); }
if (CONSOLE_LOG === true) { console.log("[INFO] ExchangeAPI -> putPosition -> pAmountB = " + truncDecimals(pAmountB)); }
let check = isValidOrder({
market: getMarketConfig(),
api: apiClient,
amount: truncDecimals(pAmountB),
price: truncDecimals(pRate)
});
if (check.valid) {
if (pType === "buy") {
apiClient.buy(pMarket.assetA, pMarket.assetB, truncDecimals(pRate), truncDecimals(pAmountB), callBack);
return;
}
if (pType === "sell") {
apiClient.sell(pMarket.assetA, pMarket.assetB, truncDecimals(pRate), truncDecimals(pAmountB), callBack);
return;
}
console.log("[ERROR] ExchangeAPI -> putPosition -> pType must be either 'buy' or 'sell'.");
callBack(global.DEFAULT_FAIL_RESPONSE);
} else {
console.log("[ERROR] ExchangeAPI -> putPosition -> The order is invalid: " + check.reason);
callBack(global.DEFAULT_FAIL_RESPONSE);
}
} catch (err) {
console.log("[ERROR] ExchangeAPI -> putPosition -> err = " + err.message);
callBack(global.DEFAULT_FAIL_RESPONSE);
}
}
/*
* Move an existing position to the new rate.
* The new orderNumber is returned.
*/
function movePosition(pPosition, pNewRate, pNewAmountB, callBack) {
try {
if (CONSOLE_LOG === true) { console.log("[INFO] ExchangeAPI -> movePosition -> Entering function."); }
if (CONSOLE_LOG === true) { console.log("[INFO] ExchangeAPI -> movePosition -> pPosition = " + JSON.stringify(pPosition)); }
if (CONSOLE_LOG === true) { console.log("[INFO] ExchangeAPI -> movePosition -> pNewRate = " + truncDecimals(pNewRate)); }
apiClient.movePosition(pPosition, truncDecimals(pNewRate), truncDecimals(pNewAmountB), callBack);
} catch (err) {
console.log("[ERROR] ExchangeAPI -> movePosition -> err = " + err.message);
callBack(global.DEFAULT_FAIL_RESPONSE);
}
}
/*
* Returns all the trade history from the Exchange since startTime to endTime orderd by tradeId.
* It's possible that the exchange doesn't support this method.
* The object returned is an array of trades:
* trade = {
* tradeID, String
* globalTradeID, String
* type, String
* rate, Number
* amountA, Number
* amountB, Number
* date Date
* };
*/
function getPublicTradeHistory(assetA, assetB, startTime, endTime, callBack) {
try {
if (CONSOLE_LOG === true) { console.log("[INFO] ExchangeAPI -> getTradeHistory -> Entering function."); }
apiClient.getPublicTradeHistory(assetA, assetB, startTime, endTime, callBack);
} catch (err) {
console.log("[ERROR] ExchangeAPI -> getTradeHistory -> err = " + err.message);
callBack(global.DEFAULT_FAIL_RESPONSE);
}
}
};
+183
View File
@@ -0,0 +1,183 @@
const _ = require('underscore');
class Beautifier {
constructor() {
this._beautifications = {
aggTrades: {
a: 'aggTradeId',
p: 'price',
q: 'quantity',
f: 'firstTradeId',
l: 'lastTradeId',
T: 'timestamp',
m: 'maker',
M: 'bestPriceMatch'
},
klines: {
0: 'openTime',
1: 'open',
2: 'high',
3: 'low',
4: 'close',
5: 'volume',
6: 'closeTime',
7: 'quoteAssetVolume',
8: 'trades',
9: 'takerBaseAssetVolume',
10: 'takerQuoteAssetVolume',
11: 'ignored'
},
bids: [
{
0: 'price',
1: 'quantity',
2: 'ignored'
}
],
asks: [
{
0: 'price',
1: 'quantity',
2: 'ignored'
}
],
depthUpdateEvent: {
e: 'eventType',
E: 'eventTime',
s: 'symbol',
u: 'updateId',
b: 'bidDepthDelta',
a: 'askDepthDelta'
},
bidDepthDelta: [
{
0: 'price',
1: 'quantity',
2: 'ignored'
}
],
askDepthDelta: [
{
0: 'price',
1: 'quantity',
2: 'ignored'
}
],
klineEvent: {
e: 'eventType',
E: 'eventTime',
s: 'symbol',
k: 'kline'
},
kline: {
t: 'startTime',
T: 'endTime',
s: 'symbol',
i: 'interval',
f: 'firstTradeId',
L: 'lastTradeId',
o: 'open',
c: 'close',
h: 'high',
l: 'low',
v: 'volume',
n: 'trades',
x: 'final',
q: 'quoteVolume',
V: 'volumeActive',
Q: 'quoteVolumeActive',
B: 'ignored'
},
aggTradeEvent: {
e: 'eventType',
E: 'eventTime',
s: 'symbol',
a: 'tradeId',
p: 'price',
q: 'quantity',
f: 'firstTradeId',
l: 'lastTradeId',
T: 'time',
m: 'maker',
M: 'ignored'
},
outboundAccountInfoEvent: {
e: 'eventType',
E: 'eventTime',
m: 'makerCommission',
t: 'takerCommission',
b: 'buyerCommission',
s: 'sellerCommission',
T: 'canTrade',
W: 'canWithdraw',
D: 'canDeposit',
B: 'balances'
},
balances: [
{
a: 'asset',
f: 'availableBalance',
l: 'onOrderBalance'
}
],
executionReportEvent: {
e: 'eventType',
E: 'eventTime',
s: 'symbol',
c: 'newClientOrderId',
S: 'side',
o: 'orderType',
f: 'cancelType', // GTC 'Good till Cancel', IOC: 'Immediate or Cancel'
q: 'quantity',
p: 'price',
x: 'executionType',
X: 'orderStatus',
r: 'rejectReason',
i: 'orderId',
l: 'lastTradeQuantity',
z: 'accumulatedQuantity',
L: 'lastTradePrice',
n: 'commission',
N: 'commissionAsset',
m: 'maker',
T: 'tradeTime',
t: 'tradeId'
}
}
}
beautify(object, type) {
const beautifications = _.isObject(type) ? type : this._beautifications[type];
if (!beautifications) {
return object;
}
let newItem = {};
_.each(object, (value, key) => {
if (_.isArray(value)) {
const newArray = [];
if (_.isArray(this._beautifications[beautifications[key]])) {
_.each(value, arrayValue => {
newArray.push(this.beautify(arrayValue, this._beautifications[beautifications[key]][0]));
});
} else {
_.each(value, (value, key) => {
newItem.push(this.beautify(value, beautifications[key]))
});
}
const newKey = beautifications[key] || key;
newItem[newKey] = newArray;
} else if (_.isObject(value)) {
const newKey = beautifications[key] || key;
newItem[newKey] = this.beautify(value, beautifications[key]);
} else {
const newKey = beautifications[key] || key;
newItem[newKey] = value;
}
});
return newItem;
}
}
module.exports = Beautifier;
+368
View File
@@ -0,0 +1,368 @@
// Source: https://github.com/zoeyg/binance/blob/master/lib/rest.js
const request = require('request');
const qs = require('querystring');
const _ = require('underscore');
const crypto = require('crypto');
const Beautifier = require('./beautifier.js');
const assert = require('assert');
class BinanceRest {
constructor({
key,
secret,
recvWindow = false,
timeout = 15000,
disableBeautification = false,
handleDrift = false
}) {
this.key = key;
this.secret = secret;
this.recvWindow = recvWindow;
this.timeout = timeout;
this.disableBeautification = disableBeautification;
this.handleDrift = handleDrift;
this._beautifier = new Beautifier();
this._baseUrl = 'https://api.binance.com/';
this._drift = 0;
this._syncInterval = 0;
}
_makeRequest(query, callback, route, security, method, attempt = 0) {
assert(_.isUndefined(callback) || _.isFunction(callback), 'callback must be a function or undefined');
assert(_.isObject(query), 'query must be an object');
let queryString;
const type = _.last(route.split('/')),
options = {
url: `${this._baseUrl}${route}`,
timeout: this.timeout
};
if (security === 'SIGNED') {
if (this.recvWindow) {
query.recvWindow = this.recvWindow;
}
queryString = qs.stringify(query);
options.url += '?' + queryString;
if (options.url.substr(options.url.length - 1) !== '?') {
options.url += '&';
}
options.url += `signature=${this._sign(queryString)}`;
} else {
queryString = qs.stringify(query);
if (queryString) {
options.url += '?' + queryString;
}
}
if (security === 'API-KEY' || security === 'SIGNED') {
options.headers = { 'X-MBX-APIKEY': this.key };
}
if (method) {
options.method = method;
}
const action = cb => {
request(options, (err, response, body) => {
let payload;
try {
payload = JSON.parse(body);
} catch (e) {
payload = body;
}
if (err) {
cb(err, payload);
} else if (response.statusCode < 200 || response.statusCode > 299) {
/*
* If we get a response that the timestamp is ahead of the server,
* calculate the drift and then attempt the request again
*/
if (response.statusCode === 400 && payload.code === -1021 &&
this.handleDrift && attempt === 0) {
this.calculateDrift()
.then(() => {
query.timestamp = this._getTime() + this._drift;
return this._makeRequest(query, cb, route, security, method,
++attempt);
});
} else {
cb(new Error(`Response code ${response.statusCode}`), payload);
}
} else {
if (_.isArray(payload)) {
payload = _.map(payload, (item) => {
return this._doBeautifications(item, type);
});
} else {
payload = this._doBeautifications(payload);
}
cb(err, payload);
}
});
};
if (callback) {
action(callback);
} else {
return new Promise((resolve, reject) => action((err, payload) => {
if (err) {
if (payload === undefined) {
reject(err);
} else {
reject(payload);
}
} else {
resolve(payload);
}
}));
}
}
_doBeautifications(response, route) {
if (this.disableBeautification) {
return response;
}
return this._beautifier.beautify(response, route);
}
_sign(queryString) {
return crypto.createHmac('sha256', this.secret)
.update(queryString)
.digest('hex');
}
_setTimestamp(query) {
if (!query.timestamp) {
query.timestamp = this._getTime() + this._drift;
}
}
_getTime() {
return new Date().getTime();
}
calculateDrift() {
const systemTime = this._getTime();
return this.time()
.then((response) => {
// Calculate the approximate trip time from here to binance
const transitTime = parseInt((this._getTime() - systemTime) / 2);
this._drift = response.serverTime - (systemTime + transitTime);
});
}
startTimeSync(interval = 300000, onRecalculateDriftCb) {
return new Promise((resolve, reject) => {
// If there's already an interval running, clear it and reset values
if (this._syncInterval !== 0) {
this.endTimeSync();
return resolve();
}
// Calculate initial drift value and setup interval to periodically update it
this.calculateDrift()
.then(resolve)
.catch(reject);
this._syncInterval = setInterval(() => {
const promise = this.calculateDrift();
if (_.isFunction(onRecalculateDriftCb)) {
onRecalculateDriftCb(promise);
}
}, interval);
});
}
endTimeSync() {
clearInterval(this._syncInterval);
this._drift = 0;
this._syncInterval = 0;
}
// Public APIs
ping(callback) {
return this._makeRequest({}, callback, 'api/v1/ping');
}
time(callback) {
return this._makeRequest({}, callback, 'api/v1/time');
}
depth(query = {}, callback) {
if (_.isString(query)) {
query = { symbol: query };
}
return this._makeRequest(query, callback, 'api/v1/depth');
}
trades(query = {}, callback) {
if (_.isString(query)) {
query = { symbol: query };
}
return this._makeRequest(query, callback, 'api/v1/trades');
}
historicalTrades(query = {}, callback) {
if (_.isString(query)) {
query = { symbol: query };
}
return this._makeRequest(query, callback, 'api/v1/historicalTrades', 'API-KEY');
}
aggTrades(query = {}, callback) {
if (_.isString(query)) {
query = { symbol: query };
}
return this._makeRequest(query, callback, 'api/v1/aggTrades');
}
exchangeInfo(callback) {
return this._makeRequest({}, callback, 'api/v1/exchangeInfo');
}
klines(query = {}, callback) {
return this._makeRequest(query, callback, 'api/v1/klines');
}
ticker24hr(query = {}, callback) {
if (_.isString(query)) {
query = { symbol: query };
}
return this._makeRequest(query, callback, 'api/v1/ticker/24hr');
}
tickerPrice(query = {}, callback) {
if (_.isString(query)) {
query = { symbol: query };
}
return this._makeRequest(query, callback, 'api/v3/ticker/price');
}
bookTicker(query = {}, callback) {
if (_.isString(query)) {
query = { symbol: query };
}
return this._makeRequest(query, callback, 'api/v3/ticker/bookTicker');
}
allBookTickers(callback) {
return this._makeRequest({}, callback, 'api/v1/ticker/allBookTickers');
}
allPrices(callback) {
return this._makeRequest({}, callback, 'api/v1/ticker/allPrices');
}
// Private APIs
newOrder(query = {}, callback) {
this._setTimestamp(query);
return this._makeRequest(query, callback, 'api/v3/order', 'SIGNED', 'POST');
}
testOrder(query = {}, callback) {
this._setTimestamp(query);
return this._makeRequest(query, callback, 'api/v3/order/test', 'SIGNED', 'POST');
}
queryOrder(query = {}, callback) {
this._setTimestamp(query);
return this._makeRequest(query, callback, 'api/v3/order', 'SIGNED');
}
cancelOrder(query = {}, callback) {
this._setTimestamp(query);
return this._makeRequest(query, callback, 'api/v3/order', 'SIGNED', 'DELETE');
}
openOrders(query = {}, callback) {
if (_.isString(query)) {
query = { symbol: query };
}
this._setTimestamp(query);
return this._makeRequest(query, callback, 'api/v3/openOrders', 'SIGNED');
}
allOrders(query = {}, callback) {
if (_.isString(query)) {
query = { symbol: query };
}
this._setTimestamp(query);
return this._makeRequest(query, callback, 'api/v3/allOrders', 'SIGNED');
}
account(query = {}, callback) {
if (_.isFunction(query)) {
callback = query;
query = {};
}
this._setTimestamp(query);
return this._makeRequest(query, callback, 'api/v3/account', 'SIGNED');
}
myTrades(query = {}, callback) {
if (_.isString(query)) {
query = { symbol: query };
}
this._setTimestamp(query);
return this._makeRequest(query, callback, 'api/v3/myTrades', 'SIGNED');
}
withdraw(query = {}, callback) {
this._setTimestamp(query);
return this._makeRequest(query, callback, 'wapi/v3/withdraw.html', 'SIGNED', 'POST');
}
depositHistory(query = {}, callback) {
if (_.isString(query)) {
query = { asset: query };
}
this._setTimestamp(query);
return this._makeRequest(query, callback, 'wapi/v3/depositHistory.html', 'SIGNED');
}
withdrawHistory(query = {}, callback) {
if (_.isString(query)) {
query = { asset: query };
}
this._setTimestamp(query);
return this._makeRequest(query, callback, 'wapi/v3/withdrawHistory.html', 'SIGNED');
}
depositAddress(query = {}, callback) {
if (_.isString(query)) {
query = { asset: query };
}
this._setTimestamp(query);
return this._makeRequest(query, callback, 'wapi/v3/depositAddress.html', 'SIGNED');
}
accountStatus(callback) {
const query = {};
this._setTimestamp(query);
return this._makeRequest(query, callback, 'wapi/v3/accountStatus.html', 'SIGNED');
}
startUserDataStream(callback) {
return this._makeRequest({}, callback, 'api/v1/userDataStream', 'API-KEY', 'POST');
}
keepAliveUserDataStream(query = {}, callback) {
return this._makeRequest(query, callback, 'api/v1/userDataStream', 'API-KEY', 'PUT');
}
closeUserDataStream(query = {}, callback) {
return this._makeRequest(query, callback, 'api/v1/userDataStream', 'API-KEY', 'DELETE');
}
}
module.exports = BinanceRest;
Loaded 100 of 128 files, more files were not shown because too many files have changed in this diff. Show more