<commit_before>require('rootpath')();
var ptp = require('camera/ptp/ptp.js');
var lists = require('camera/ptp/lists.js');
var bulb = require('node-bulb');

var camera = {};

camera.bulb = bulb;
camera.ptp = ptp;
camera.connected = ptp.connected;
camera.lists = lists;

camera.settings = {
    brampGap: 5,
    bulbMinUs: null,
}

var cbStore = {};
var cbIndex = 0;

console.log(">>>>>>> Starting camera module >>>>>>>>");

function getCallbackId(cb) {
    if (!cb) return 0;
    cbIndex++;
    if (cbIndex > 1000) cbIndex = 1;
    cbStore[cbIndex.toString()] = cb;
    return cbIndex;
}

function runCallback(cbData) {
    if (cbData && cbData.id && cbStore[cbData.id.toString()]) {
        var cb = cbStore[cbData.id.toString()];
        cb(cbData.err, cbData.data);
        delete cbStore[cbData.id.toString()]
    }
}

function sum(arr) {
    var sum = 0;
    for (var i = 0; i < arr.length; i++) {
        sum += arr[i];
    }
    return sum;
}

camera.testBulb = function() {
    var options = {
        preFocusMs: 500,
        expectSync: true,
        runTest: false
    }

    var testCount = 5;

    var testStart = [];
    var testEnd = [];
    var testMin = [];
    var testGap = [];

    var testError = null;

    var testStartTime;

    console.log("running test...");

    function testDone() {
        camera.settings.bulbMinUs = Math.max.apply(Math, testMin);
        camera.settings.bulbStartUs = sum(testStart) / testStart.length;
        camera.settings.bulbEndUs = sum(testEnd) / testEnd.length;
        camera.settings.brampGap = sum(testGap) / testGap.length;

        console.log('bulbMinUs:', camera.settings.bulbMinUs);
        console.log('bulbStartUs:', camera.settings.bulbStartUs);
        console.log('bulbEndUs:', camera.settings.bulbEndUs);
        console.log('brampGap:', camera.settings.brampGap);

    }

    function doTest() {
        if (testCount > 0) {
            testStartTime = new Date();
            testCount--;
            camera.ptp.captureTethered(function(err, res) {
                if (!err && !testError) {
                    var testEndTime = new Date();
                    testGap.push((testEndTime - testStartTime) / 1000);
                    setTimeout(doTest);
                } else {
                    testError = err;
                    console.log("error occurred during capture: (" + (err || testError) + ")!");
                }
            });
            bulb(options, function(err, start_us, end_us, actual_us) {
                if (!err && !testError) {
                    testStart.push(start_us);
                    testEnd.push(end_us);
                    testMin.push(actual_us);
                } else {
                    testError = err;
                    console.log("error occurred during test: (" + (err || testError) + ")!");
                }
            });
        } else {
            testDone();
        }

    }

    doTest();
}

camera.getEv = function(callback) {
    camera.ptp.getSettings(function() {
        var settings = camera.ptp.settings.details;
        var av = (settings.aperture && settings.aperture.ev != null) ? settings.aperture.ev : lists.fixedApertureEv;

        if (callback) {
            if(settings && settings.shutter && settings.iso) {
                callback(null, lists.getEv(settings.shutter.ev, av, settings.iso.ev), {
                    shutter: settings.shutter,
                    aperture: settings.aperture,
                    iso: settings.iso
                });
            } else {
                callback("error retreiving camera settings");
            }
        }
    });
}

var lastParam = null;
camera.setEv = function(ev, options, cb) {
    if (!options) options = {};
    var doSet = function(settings) {
        var shutter = settings.details.shutter;
        var aperture = settings.details.aperture;
        var iso = settings.details.iso;

        var apertureEnabled = false;
        //var shutterEnabled = true; //to be added
        if(options.parameters && options.parameters.indexOf('A') !== -1) apertureEnabled = true
        // if(options.parameters && options.parameters.indexOf('I') === -1) shutterEnabled = false // defaults to enabled

        if (!aperture) {
            apertureEnabled = false;
            aperture = {
                ev: lists.fixedApertureEv
            };
        }

        //console.log("current shutter", shutter);
        //console.log("current aperture", aperture);
        //console.log("current iso", iso);

        var shutterList = settings.lists.shutter;
        var apertureList = settings.lists.aperture;
        var isoList = settings.lists.iso;

        //console.log("options: ", options);

        if(shutterList) shutterList = lists.cleanEvCopy(shutterList);
        if(apertureList) apertureList = lists.cleanEvCopy(apertureList);
        if(isoList) isoList = lists.cleanEvCopy(isoList);

        //console.log("isoList2: ", isoList);

        if (shutterList && options && options.maxShutterLengthMs) {
            var maxSeconds = Math.floor(options.maxShutterLengthMs / 1000);
            if(maxSeconds < 1) maxSeconds = 1;
            //console.log("MAX seconds for shutter: ", maxSeconds);
            shutterList = shutterList.filter(function(item) {
                return lists.getSecondsFromEv(item.ev) <= maxSeconds;
            });
            //console.log("Filtered shutter list: ", shutterList);
        }
        if (shutterList && options && options.shutterMax != null) {
            shutterList = shutterList.filter(function(item) {
                return item.ev >= options.shutterMax;
            });
        }
        if (isoList && options && options.isoMax != null) {
            isoList = isoList.filter(function(item) {
                return item.ev >= options.isoMax;
            });
        }
        if (isoList && options && options.isoMin != null) {
            isoList = isoList.filter(function(item) {
                return item.ev <= options.isoMin;
            });
        }
        if (apertureList && options && options.apertureMax != null) {
            apertureList = apertureList.filter(function(item) {
                return item.ev <= options.apertureMax;
            });
        }
        if (apertureList && options && options.apertureMin != null) {
            apertureList = apertureList.filter(function(item) {
                return item.ev >= options.apertureMin;
            });
        }

        //console.log("apertureList: ", apertureList);

        var currentEv = null;
        if(shutter && aperture && iso && shutter.ev != null && aperture.ev != null && iso.ev != null) {
            currentEv = lists.getEv(shutter.ev, aperture.ev, iso.ev);
        }
        console.log("setEv: currentEv: ", currentEv, "targetEv:", ev);

        console.log("setEv: list lengths: s:", shutterList ? shutterList.length : -1, "i:", isoList ? isoList.length : -1, "a:", apertureList ? apertureList.length : -1);

        if (ev === null || currentEv === null) {
            console.log("setEv: unable to set ev, insufficient settings available");
            if (cb) cb("unable to set ev, insufficient settings available", {
                ev: currentEv,
                shutter: shutter,
                aperture: aperture,
                iso: iso
            });
            return;
        }

        if(!options.blendParams) lastParam = null;

        for (var trys = 0; trys < 3; trys++) {
            while (ev < currentEv - 1 / 4) {
                //console.log("ev < currentEv");
                var s = lists.decEv(shutter, shutterList);
                if (apertureEnabled) var a = lists.decEv(aperture, apertureList);
                var i = lists.decEv(iso, isoList);

                if (s && shutter.ev != s.ev && lastParam != 's') {
                    shutter = s;
                    if(options.blendParams) lastParam = 's';
                } else if (apertureEnabled && a && aperture.ev != a.ev && lastParam != 'a') {
                    aperture = a;
                    if(options.blendParams) lastParam = 'a';
                } else if (i && iso.ev != i.ev && lastParam != 'i') {
                    iso = i;
                    if(options.blendParams) lastParam = 'i';
                } else {
                    lastParam = null;
                    currentEv = lists.getEv(shutter.ev, aperture.ev, iso.ev);
                    break;
                }
                currentEv = lists.getEv(shutter.ev, aperture.ev, iso.ev);
                //console.log(" update: ", currentEv);
            }

            while (ev > currentEv + 1 / 4) {
                //console.log("ev > currentEv");
                var s = lists.incEv(shutter, shutterList);
                if (apertureEnabled) var a = lists.incEv(aperture, apertureList);
                var i = lists.incEv(iso, isoList);

                if (i && iso.ev != i.ev && lastParam != 'i') {
                    iso = i;
                    if(options.blendParams) lastParam = 'i';
                } else if (apertureEnabled && a && aperture.ev != a.ev && lastParam != 'a') {
                    aperture = a;
                    if(options.blendParams) lastParam = 'a';
                } else if (s && shutter.ev != s.ev && lastParam != 's') {
                    shutter = s;
                    if(options.blendParams) lastParam = 's';
                } else {
                    lastParam = null;
                    currentEv = lists.getEv(shutter.ev, aperture.ev, iso.ev);
                    break;
                }
                currentEv = lists.getEv(shutter.ev, aperture.ev, iso.ev);
                //console.log(" update: ", currentEv);
            }

            if (Math.abs(ev - currentEv) <= 1 / 4) break;

        }

        console.log("setEv: finalEv: ", currentEv);

        function runQueue(queue, callback) {
            set = queue.pop();
            if (set) {
                console.log("setEv: setting ", set.name);
                camera.ptp.set(set.name, set.val, function() {
                    setTimeout(function() {
                        runQueue(queue, callback)
                    });
                });
            } else {
                if (callback) callback();
                return;
            }
        }

        if(options.doNotSet) {
            if (cb) return cb(null, {
                ev: currentEv,
                shutter: shutter,
                aperture: aperture,
                iso: iso
            }); else return;
        }

        var setQueue = [];

        if (shutter.ev != settings.details.shutter.ev) setQueue.push({
            name: 'shutter',
            val: shutter.cameraName || shutter.name
        });
        if (apertureEnabled && aperture.ev != settings.details.aperture.ev) setQueue.push({
            name: 'aperture',
            val: aperture.cameraName || aperture.name
        });
        if (iso.ev != settings.details.iso.ev) setQueue.push({
            name: 'iso',
            val: iso.cameraName || iso.name
        });

        runQueue(setQueue, function() {
            if (cb) cb(null, {
                ev: currentEv,
                shutter: shutter,
                aperture: aperture,
                iso: iso
            });

        });
    }

    if (options && options.cameraSettings) {
        console.log("setEv: using provided settings");
        doSet(options.cameraSettings);
    } else {
        camera.ptp.getSettings(function() {
            console.log("setEv: retreived settings from camera");
            var settings = camera.ptp.settings;
            doSet(settings);
        });
    }

}

camera.setExposure = function(shutterEv, apertureEv, isoEv, cb) {
    function runQueue(queue, callback) {
        set = queue.pop();
        if (set) {
            console.log("setEv: setting ", set.name);
            camera.ptp.set(set.name, set.val, function() {
                setTimeout(function() {
                    runQueue(queue, callback)
                });
            });
        } else {
            if (callback) callback();
            return;
        }
    }
    function getItemFromEvList(list, ev) {
        if(!list) return null;
        list = lists.cleanEvCopy(list);
        var minDiff = Infinity;
        var correction = 0;
        var item = null;
        for(var i = 0; i < list.length; i++) {
            var diff = Math.abs(ev - list[i].ev);
            if(diff < minDiff) {
                correction = ev - list[i].ev;
                minDiff = diff;
                item = list[i];
            }
        }
        if(item) {
            return { item: item, correction: correction };
        } else {
            return null;
        }
    }

    var setQueue = [];

    var correction = 0;

    if (shutterEv != null && (!camera.ptp.settings.details || (camera.ptp.settings.details.shutter && shutterEv != camera.ptp.settings.details.shutter.ev))) {
        var res = getItemFromEvList(camera.ptp.settings.lists.shutter, shutterEv);
        if(res != null) {
            correction = res.correction;
            setQueue.push({
                name: 'shutter',
                val: res.item.cameraName || res.item.name
            });
        }
    }
    if (apertureEv != null && (!camera.ptp.settings.details || (camera.ptp.settings.details.aperture && apertureEv != camera.ptp.settings.details.aperture.ev))) {
        var res = getItemFromEvList(camera.ptp.settings.lists.aperture, apertureEv + correction);
        if(res != null) {
            correction = res.correction;
            setQueue.push({
                name: 'aperture',
                val: res.item.cameraName || res.item.name
            });
        }
    }
    if (isoEv != null && (!camera.ptp.settings.details || (camera.ptp.settings.details.iso && isoEv != camera.ptp.settings.details.iso.ev))) {
        var res = getItemFromEvList(camera.ptp.settings.lists.iso, isoEv + correction);
        if(res != null) {
            correction = res.correction;
            setQueue.push({
                name: 'iso',
                val: res.item.cameraName || res.item.name
            });
        }
    }

    runQueue(setQueue, function() {
        if (cb) camera.getEv(cb);
    });
}

camera.minEv = function(settings, options) {
    var stats = lists.evStats(settings, options);
    return stats.minEv;
}

camera.maxEv = function(settings, options) {
    var stats = lists.evStats(settings, options);
    return stats.maxEv;
}

camera.captureEv = function(ev, cb) {
    var res = camera.setEv(ev);
    var evDiff = res.ev - ev;
}

module.exports = camera;<commit_msg>hdr testing<commit_after>require('rootpath')();
var ptp = require('camera/ptp/ptp.js');
var lists = require('camera/ptp/lists.js');
var bulb = require('node-bulb');

var camera = {};

camera.bulb = bulb;
camera.ptp = ptp;
camera.connected = ptp.connected;
camera.lists = lists;

camera.settings = {
    brampGap: 5,
    bulbMinUs: null,
}

var cbStore = {};
var cbIndex = 0;

console.log(">>>>>>> Starting camera module >>>>>>>>");

function getCallbackId(cb) {
    if (!cb) return 0;
    cbIndex++;
    if (cbIndex > 1000) cbIndex = 1;
    cbStore[cbIndex.toString()] = cb;
    return cbIndex;
}

function runCallback(cbData) {
    if (cbData && cbData.id && cbStore[cbData.id.toString()]) {
        var cb = cbStore[cbData.id.toString()];
        cb(cbData.err, cbData.data);
        delete cbStore[cbData.id.toString()]
    }
}

function sum(arr) {
    var sum = 0;
    for (var i = 0; i < arr.length; i++) {
        sum += arr[i];
    }
    return sum;
}

camera.testBulb = function() {
    var options = {
        preFocusMs: 500,
        expectSync: true,
        runTest: false
    }

    var testCount = 5;

    var testStart = [];
    var testEnd = [];
    var testMin = [];
    var testGap = [];

    var testError = null;

    var testStartTime;

    console.log("running test...");

    function testDone() {
        camera.settings.bulbMinUs = Math.max.apply(Math, testMin);
        camera.settings.bulbStartUs = sum(testStart) / testStart.length;
        camera.settings.bulbEndUs = sum(testEnd) / testEnd.length;
        camera.settings.brampGap = sum(testGap) / testGap.length;

        console.log('bulbMinUs:', camera.settings.bulbMinUs);
        console.log('bulbStartUs:', camera.settings.bulbStartUs);
        console.log('bulbEndUs:', camera.settings.bulbEndUs);
        console.log('brampGap:', camera.settings.brampGap);

    }

    function doTest() {
        if (testCount > 0) {
            testStartTime = new Date();
            testCount--;
            camera.ptp.captureTethered(function(err, res) {
                if (!err && !testError) {
                    var testEndTime = new Date();
                    testGap.push((testEndTime - testStartTime) / 1000);
                    setTimeout(doTest);
                } else {
                    testError = err;
                    console.log("error occurred during capture: (" + (err || testError) + ")!");
                }
            });
            bulb(options, function(err, start_us, end_us, actual_us) {
                if (!err && !testError) {
                    testStart.push(start_us);
                    testEnd.push(end_us);
                    testMin.push(actual_us);
                } else {
                    testError = err;
                    console.log("error occurred during test: (" + (err || testError) + ")!");
                }
            });
        } else {
            testDone();
        }

    }

    doTest();
}

camera.getEv = function(callback) {
    camera.ptp.getSettings(function() {
        var settings = camera.ptp.settings.details;
        var av = (settings.aperture && settings.aperture.ev != null) ? settings.aperture.ev : lists.fixedApertureEv;

        if (callback) {
            if(settings && settings.shutter && settings.iso) {
                callback(null, lists.getEv(settings.shutter.ev, av, settings.iso.ev), {
                    shutter: settings.shutter,
                    aperture: settings.aperture,
                    iso: settings.iso
                });
            } else {
                callback("error retreiving camera settings");
            }
        }
    });
}

var lastParam = null;
camera.setEv = function(ev, options, cb) {
    if (!options) options = {};
    var doSet = function(settings) {
        var shutter = settings.details.shutter;
        var aperture = settings.details.aperture;
        var iso = settings.details.iso;

        var apertureEnabled = false;
        //var shutterEnabled = true; //to be added
        if(options.parameters && options.parameters.indexOf('A') !== -1) apertureEnabled = true
        // if(options.parameters && options.parameters.indexOf('I') === -1) shutterEnabled = false // defaults to enabled

        if (!aperture) {
            apertureEnabled = false;
            aperture = {
                ev: lists.fixedApertureEv
            };
        }

        //console.log("current shutter", shutter);
        //console.log("current aperture", aperture);
        //console.log("current iso", iso);

        var shutterList = settings.lists.shutter;
        var apertureList = settings.lists.aperture;
        var isoList = settings.lists.iso;

        //console.log("options: ", options);

        if(shutterList) shutterList = lists.cleanEvCopy(shutterList);
        if(apertureList) apertureList = lists.cleanEvCopy(apertureList);
        if(isoList) isoList = lists.cleanEvCopy(isoList);

        //console.log("isoList2: ", isoList);

        if (shutterList && options && options.maxShutterLengthMs) {
            var maxSeconds = Math.floor(options.maxShutterLengthMs / 1000);
            if(maxSeconds < 1) maxSeconds = 1;
            //console.log("MAX seconds for shutter: ", maxSeconds);
            shutterList = shutterList.filter(function(item) {
                return lists.getSecondsFromEv(item.ev) <= maxSeconds;
            });
            //console.log("Filtered shutter list: ", shutterList);
        }
        if (shutterList && options && options.shutterMax != null) {
            shutterList = shutterList.filter(function(item) {
                return item.ev >= options.shutterMax;
            });
        }
        if (isoList && options && options.isoMax != null) {
            isoList = isoList.filter(function(item) {
                return item.ev >= options.isoMax;
            });
        }
        if (isoList && options && options.isoMin != null) {
            isoList = isoList.filter(function(item) {
                return item.ev <= options.isoMin;
            });
        }
        if (apertureList && options && options.apertureMax != null) {
            apertureList = apertureList.filter(function(item) {
                return item.ev <= options.apertureMax;
            });
        }
        if (apertureList && options && options.apertureMin != null) {
            apertureList = apertureList.filter(function(item) {
                return item.ev >= options.apertureMin;
            });
        }

        //console.log("apertureList: ", apertureList);

        var currentEv = null;
        if(shutter && aperture && iso && shutter.ev != null && aperture.ev != null && iso.ev != null) {
            currentEv = lists.getEv(shutter.ev, aperture.ev, iso.ev);
        }
        console.log("setEv: currentEv: ", currentEv, "targetEv:", ev);

        console.log("setEv: list lengths: s:", shutterList ? shutterList.length : -1, "i:", isoList ? isoList.length : -1, "a:", apertureList ? apertureList.length : -1);

        if (ev === null || currentEv === null) {
            console.log("setEv: unable to set ev, insufficient settings available");
            if (cb) cb("unable to set ev, insufficient settings available", {
                ev: currentEv,
                shutter: shutter,
                aperture: aperture,
                iso: iso
            });
            return;
        }

        if(!options.blendParams) lastParam = null;

        for (var trys = 0; trys < 3; trys++) {
            while (ev < currentEv - 1 / 4) {
                //console.log("ev < currentEv");
                var s = lists.decEv(shutter, shutterList);
                if (apertureEnabled) var a = lists.decEv(aperture, apertureList);
                var i = lists.decEv(iso, isoList);

                if (s && shutter.ev != s.ev && lastParam != 's') {
                    shutter = s;
                    if(options.blendParams) lastParam = 's';
                } else if (apertureEnabled && a && aperture.ev != a.ev && lastParam != 'a') {
                    aperture = a;
                    if(options.blendParams) lastParam = 'a';
                } else if (i && iso.ev != i.ev && lastParam != 'i') {
                    iso = i;
                    if(options.blendParams) lastParam = 'i';
                } else {
                    lastParam = null;
                    currentEv = lists.getEv(shutter.ev, aperture.ev, iso.ev);
                    break;
                }
                currentEv = lists.getEv(shutter.ev, aperture.ev, iso.ev);
                //console.log(" update: ", currentEv);
            }

            while (ev > currentEv + 1 / 4) {
                //console.log("ev > currentEv");
                var s = lists.incEv(shutter, shutterList);
                if (apertureEnabled) var a = lists.incEv(aperture, apertureList);
                var i = lists.incEv(iso, isoList);

                if (i && iso.ev != i.ev && lastParam != 'i') {
                    iso = i;
                    if(options.blendParams) lastParam = 'i';
                } else if (apertureEnabled && a && aperture.ev != a.ev && lastParam != 'a') {
                    aperture = a;
                    if(options.blendParams) lastParam = 'a';
                } else if (s && shutter.ev != s.ev && lastParam != 's') {
                    shutter = s;
                    if(options.blendParams) lastParam = 's';
                } else {
                    lastParam = null;
                    currentEv = lists.getEv(shutter.ev, aperture.ev, iso.ev);
                    break;
                }
                currentEv = lists.getEv(shutter.ev, aperture.ev, iso.ev);
                //console.log(" update: ", currentEv);
            }

            if (Math.abs(ev - currentEv) <= 1 / 4) break;

        }

        console.log("setEv: finalEv: ", currentEv);

        function runQueue(queue, callback) {
            set = queue.pop();
            if (set) {
                console.log("setEv: setting ", set.name);
                camera.ptp.set(set.name, set.val, function() {
                    setTimeout(function() {
                        runQueue(queue, callback)
                    });
                });
            } else {
                if (callback) callback();
                return;
            }
        }

        if(options.doNotSet) {
            console.log("setEv: done, not applying changes.");
            if (cb) return cb(null, {
                ev: currentEv,
                shutter: shutter,
                aperture: aperture,
                iso: iso
            }); else return;
        }

        var setQueue = [];

        if (shutter.ev != settings.details.shutter.ev) setQueue.push({
            name: 'shutter',
            val: shutter.cameraName || shutter.name
        });
        if (apertureEnabled && aperture.ev != settings.details.aperture.ev) setQueue.push({
            name: 'aperture',
            val: aperture.cameraName || aperture.name
        });
        if (iso.ev != settings.details.iso.ev) setQueue.push({
            name: 'iso',
            val: iso.cameraName || iso.name
        });

        runQueue(setQueue, function() {
            console.log("setEv: done.");
            if (cb) cb(null, {
                ev: currentEv,
                shutter: shutter,
                aperture: aperture,
                iso: iso
            });

        });
    }

    if (options && options.cameraSettings) {
        console.log("setEv: using provided settings");
        doSet(options.cameraSettings);
    } else {
        camera.ptp.getSettings(function() {
            console.log("setEv: retreived settings from camera");
            var settings = camera.ptp.settings;
            doSet(settings);
        });
    }

}

camera.setExposure = function(shutterEv, apertureEv, isoEv, cb) {
    function runQueue(queue, callback) {
        set = queue.pop();
        if (set) {
            console.log("setEv: setting ", set.name);
            camera.ptp.set(set.name, set.val, function() {
                setTimeout(function() {
                    runQueue(queue, callback)
                });
            });
        } else {
            if (callback) callback();
            return;
        }
    }
    function getItemFromEvList(list, ev) {
        if(!list) return null;
        list = lists.cleanEvCopy(list);
        var minDiff = Infinity;
        var correction = 0;
        var item = null;
        for(var i = 0; i < list.length; i++) {
            var diff = Math.abs(ev - list[i].ev);
            if(diff < minDiff) {
                correction = ev - list[i].ev;
                minDiff = diff;
                item = list[i];
            }
        }
        if(item) {
            return { item: item, correction: correction };
        } else {
            return null;
        }
    }

    var setQueue = [];

    var correction = 0;

    if (shutterEv != null && (!camera.ptp.settings.details || (camera.ptp.settings.details.shutter && shutterEv != camera.ptp.settings.details.shutter.ev))) {
        var res = getItemFromEvList(camera.ptp.settings.lists.shutter, shutterEv);
        if(res != null) {
            correction = res.correction;
            setQueue.push({
                name: 'shutter',
                val: res.item.cameraName || res.item.name
            });
        }
    }
    if (apertureEv != null && (!camera.ptp.settings.details || (camera.ptp.settings.details.aperture && apertureEv != camera.ptp.settings.details.aperture.ev))) {
        var res = getItemFromEvList(camera.ptp.settings.lists.aperture, apertureEv + correction);
        if(res != null) {
            correction = res.correction;
            setQueue.push({
                name: 'aperture',
                val: res.item.cameraName || res.item.name
            });
        }
    }
    if (isoEv != null && (!camera.ptp.settings.details || (camera.ptp.settings.details.iso && isoEv != camera.ptp.settings.details.iso.ev))) {
        var res = getItemFromEvList(camera.ptp.settings.lists.iso, isoEv + correction);
        if(res != null) {
            correction = res.correction;
            setQueue.push({
                name: 'iso',
                val: res.item.cameraName || res.item.name
            });
        }
    }

    runQueue(setQueue, function() {
        if (cb) camera.getEv(cb);
    });
}

camera.minEv = function(settings, options) {
    var stats = lists.evStats(settings, options);
    return stats.minEv;
}

camera.maxEv = function(settings, options) {
    var stats = lists.evStats(settings, options);
    return stats.maxEv;
}

camera.captureEv = function(ev, cb) {
    var res = camera.setEv(ev);
    var evDiff = res.ev - ev;
}

module.exports = camera;<|endoftext|>


<commit_before>/**
 * @class GeometryBuffer
 */

EZ3.GeometryBuffer = function() {
  this._id = null;
  this._data = [];
};

EZ3.GeometryBuffer.prototype.setup = function(config) {
  var gl = config.context;

  gl.bindBuffer(config.target, this._id);

  if(config.layout !== undefined) {
    gl.enableVertexAttribArray(config.layout);
    gl.vertexAttribPointer(config.layout, config.length, config.type, config.normalized, config.stride, config.offset);
  }
};

EZ3.GeometryBuffer.prototype.update = function(config) {
  var gl = config.context;

  if (config.dynamic) {
    if (!this._id) {
      this._id = gl.createBuffer();
      gl.bindBuffer(config.target, this._id);
      gl.bufferData(config.target, (config.type === gl.FLOAT) ? new Float32Array(config.data) : new Uint16Array(config.data), gl.DYNAMIC_DRAW);
      gl.bindBuffer(config.target, null);
    } else {
      gl.bindBuffer(config.target, this._id);
      gl.bufferSubData(config.target, 0, (config.type === gl.FLOAT) ? new Float32Array(config.data) : new Uint16Array(config.data));
      gl.bindBuffer(config.target, null);
    }
  } else {
    if (!this._id) {
      this._id = gl.createBuffer();
      gl.bindBuffer(config.target, this._id);
      gl.bufferData(config.target, (config.type === gl.FLOAT) ? new Float32Array(config.data) : new Uint16Array(config.data), gl.STATIC_DRAW);
      gl.bindBuffer(config.target, null);
    }
  }
  this._data = config.data;
};

Object.defineProperty(EZ3.GeometryBuffer.prototype, "id", {
  get: function() {
    return this._id;
  }
});

Object.defineProperty(EZ3.GeometryBuffer.prototype, "data", {
  get: function() {
    return this._data;
  },
  set: function(data) {
    this._data = data;
  }
});

EZ3.GeometryBuffer.UV_LENGTH = 2;
EZ3.GeometryBuffer.COLOR_LENGTH = 3;
EZ3.GeometryBuffer.VERTEX_LENGTH = 3;
EZ3.GeometryBuffer.NORMAL_LENGTH = 3;
EZ3.GeometryBuffer.TANGENT_LENGTH = 4;
EZ3.GeometryBuffer.BITANGENT_LENGTH = 3;
<commit_msg>Updated GeometryBuffer.js<commit_after>/**
 * @class GeometryBuffer
 */

EZ3.GeometryBuffer = function() {
  this._id = null;
  this._data = [];
};

EZ3.GeometryBuffer.prototype.setup = function(config) {
  var gl = config.context;

  gl.bindBuffer(config.target, this._id);

  if(config.layout !== undefined) {
    gl.enableVertexAttribArray(config.layout);
    gl.vertexAttribPointer(config.layout, config.length, config.type, config.normalized, config.stride, config.offset);
  }
};

EZ3.GeometryBuffer.prototype.update = function(config) {
  var gl = config.context;
  var array;

  if(config.type === gl.UNSIGNED_SHORT)
    array = new Uint16Array(config.data);
  else
    array = new Float32Array(config.data);

  if (config.dynamic) {
    if (!this._id) {
      this._id = gl.createBuffer();
      gl.bindBuffer(config.target, this._id);
      gl.bufferData(config.target, array, gl.DYNAMIC_DRAW);
      gl.bindBuffer(config.target, null);
    } else {
      gl.bindBuffer(config.target, this._id);
      gl.bufferSubData(config.target, 0, array);
      gl.bindBuffer(config.target, null);
    }
  } else {
    if (!this._id) {
      this._id = gl.createBuffer();
      gl.bindBuffer(config.target, this._id);
      gl.bufferData(config.target, array, gl.STATIC_DRAW);
      gl.bindBuffer(config.target, null);
    }
  }
  this._data = config.data;
};

Object.defineProperty(EZ3.GeometryBuffer.prototype, "id", {
  get: function() {
    return this._id;
  }
});

Object.defineProperty(EZ3.GeometryBuffer.prototype, "data", {
  get: function() {
    return this._data;
  },
  set: function(data) {
    this._data = data;
  }
});

EZ3.GeometryBuffer.UV_LENGTH = 2;
EZ3.GeometryBuffer.COLOR_LENGTH = 3;
EZ3.GeometryBuffer.VERTEX_LENGTH = 3;
EZ3.GeometryBuffer.NORMAL_LENGTH = 3;
EZ3.GeometryBuffer.TANGENT_LENGTH = 4;
EZ3.GeometryBuffer.BITANGENT_LENGTH = 3;
<|endoftext|>


<commit_before>class Influxdb {
    constructor(host, sendPointsOnClose) {
        this.sendPointsOnClose = sendPointsOnClose;
        this.host = host;
        this.points = [];
        this.beaconSent = false;
        if (this.sendPointsOnClose) this.registerUnloadEvent();
        return this;
    }

    registerUnloadEvent() {
        var _self = this;
        //need both events to work in chrome http://stackoverflow.com/a/20322988/1368683
        window.addEventListener('unload', _self.sendBeacon, false);
        window.onbeforeunload = function (e) {
            _self.sendBeacon();
        };
    }

    sendBeacon() {
        //need this polyfill https://github.com/miguelmota/Navigator.sendBeacon
        if (this.points.length == 0) return;
        if (this.beaconSent) return;
        this.beaconSent = true;
        var data = this.implodePoints();
        navigator.sendBeacon(this.host, data);
    }

    point(key, fields, tags, time) {
        return this._addPoint(new Influxdb_Point(key, fields, tags, time));
    }

    _addPoint(point) {
        if (point.isValid()) {
            this.points.push(point);
        }
        return this;
    }

    implodePoints() {
        if (this.points.length == 0) return '';
        var index, data = '', _data = '';
        for (index = 0; index < this.points.length; ++index) {
            if (!this.points[index].isValid()){
                this.points.slice(index,1);
                continue;
            }
            _data = this.points[index].getLine();
            if (index > 0 && data) data = data + '\n';
            data = data + this.points[index].getLine();
        }
        return data;
    }

    send() {
        if (this.points.length == 0) return false;
        var data = this.implodePoints();
        if (data) {
            var request = new XMLHttpRequest();
            request.open('POST', this.host, true);
            request.setRequestHeader('Content-Type', 'text/plain; charset=UTF-8');
            request.send(data);
        }

        this.points = [];
    }

}

class Influxdb_Point {

    constructor(key, fields, tags, time) {
        this.key = key;
        if (typeof fields !== 'undefined' && !this.isEmpty(fields)) this.fields = fields;
        if (typeof tags !== 'undefined' && !this.isEmpty(fields)) this.tags = tags;
        if (typeof time !== 'undefined') this.time = time;

    }

    isValid(){
        if (!this.key || !this.fields) return false;
        return true;
    }

    getLine() {
        if (!this.key && !this.fields) return;
        this.line = this.key;
        if (this.tags) {
            this.line = this.line + ',' + this.objToString(this.tags)
        }
        if (this.fields) {
            this.line = this.line + ' ' + this.objToString(this.fields);
        }
        if (this.time) {
            this.line = this.line + ' ' + this.time;
        }
        return this.line;
    }

    sortObjectByKey(obj) {
        if (!Array.prototype.forEach) return obj;
        if (!Array.prototype.sort) return obj;
        if (!Object.keys) return obj;
        var ordered = {};
        Object.keys(obj).sort().forEach(function (key) {
            ordered[key] = obj[key];
        });
        return ordered;
    }

    objToString(obj) {
        var i = 0;
        var str = '';
        var key, value;
        //Tags should be sorted by key before being sent for best performance https://docs.influxdata.com/influxdb/v0.13/write_protocols/line/#key
        obj = this.sortObjectByKey(obj);
        for (var key in obj) {
            if (obj.hasOwnProperty(key)) {
                //todo: right now not supporting space in tags where it should be support with back slash
                key = key.replace(/\s+/g, '');
                value = obj[key].toString();
                value = value.replace(/\s+/g, '');
                i++;
                if (i > 1) str = str + ',';
                str += key + '=' + value;
            }
        }
        return str;
    }

    isEmpty(obj) {
        for (var prop in obj) {
            if (obj.hasOwnProperty(prop))
                return false;
        }
        if (!window.JSON) return true;
        return true && JSON.stringify(obj) === JSON.stringify({});
    }
}
<commit_msg>fixing the sendBeacon option<commit_after>class Influxdb {
    constructor(host, sendPointsOnClose) {
        this.sendPointsOnClose = sendPointsOnClose;
        this.host = host;
        this.points = [];
        this.beaconSent = false;
        if (this.sendPointsOnClose) this.registerUnloadEvent();
        return this;
    }

    registerUnloadEvent() {
        var _self = this;
        //need both events to work in chrome http://stackoverflow.com/a/20322988/1368683
        window.addEventListener('unload', function (e) {
            _self.sendBeacon(_self);
        }, false);
        window.onbeforeunload = function (e) {
            _self.sendBeacon(_self);
        };
    }

    sendBeacon(_self) {
        //need this polyfill https://github.com/miguelmota/Navigator.sendBeacon
        if (_self.beaconSent) return;
        if (_self.points && _self.points.length == 0) return;
        _self.beaconSent = true;
        if (!navigator && !navigator.sendBeacon) return;
        var data = _self.implodePoints();
        navigator.sendBeacon(_self.host, data);
    }

    point(key, fields, tags, time) {
        return this._addPoint(new Influxdb_Point(key, fields, tags, time));
    }

    _addPoint(point) {
        if (point.isValid()) {
            this.points.push(point);
        }
        return this;
    }

    implodePoints() {
        if (this.points.length == 0) return '';
        var index, data = '';
        for (index = 0; index < this.points.length; ++index) {
            if (!this.points[index].isValid()) {
                this.points.slice(index, 1);
                continue;
            }
            data = data + this.points[index].getLine();
        }
        return data;
    }

    send() {
        if (this.points.length == 0) return false;
        var data = this.implodePoints();
        if (data) {
            var request = new XMLHttpRequest();
            request.open('POST', this.host, true);
            request.setRequestHeader('Content-Type', 'text/plain; charset=UTF-8');
            request.send(data);
        }

        this.points = [];
    }

}

class Influxdb_Point {

    constructor(key, fields, tags, time) {
        this.key = key;
        if (typeof fields !== 'undefined' && !this.isEmpty(fields)) this.fields = fields;
        if (typeof tags !== 'undefined' && !this.isEmpty(fields)) this.tags = tags;
        if (typeof time !== 'undefined') this.time = time;

    }

    isValid() {
        if (!this.key || !this.fields) return false;
        return true;
    }

    getLine() {
        if (!this.key && !this.fields) return;
        this.line = this.key;
        if (this.tags) {
            this.line = this.line + ',' + this.objToString(this.tags)
        }
        if (this.fields) {
            this.line = this.line + ' ' + this.objToString(this.fields);
        }
        if (this.time) {
            this.line = this.line + ' ' + this.time;
        }
        this.line = this.line + '\n';
        return this.line;
    }

    sortObjectByKey(obj) {
        if (!Array.prototype.forEach) return obj;
        if (!Array.prototype.sort) return obj;
        if (!Object.keys) return obj;
        var ordered = {};
        Object.keys(obj).sort().forEach(function (key) {
            ordered[key] = obj[key];
        });
        return ordered;
    }

    objToString(obj) {
        var i = 0;
        var str = '';
        var key, value;
        //Tags should be sorted by key before being sent for best performance https://docs.influxdata.com/influxdb/v0.13/write_protocols/line/#key
        obj = this.sortObjectByKey(obj);
        for (var key in obj) {
            if (obj.hasOwnProperty(key)) {
                //todo: right now not supporting space in tags where it should be support with back slash
                key = key.replace(/\s+/g, '');
                value = obj[key].toString();
                value = value.replace(/\s+/g, '');
                i++;
                if (i > 1) str = str + ',';
                str += key + '=' + value;
            }
        }
        return str;
    }

    isEmpty(obj) {
        for (var prop in obj) {
            if (obj.hasOwnProperty(prop))
                return false;
        }
        if (!window.JSON) return true;
        return true && JSON.stringify(obj) === JSON.stringify({});
    }
}
<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/**
 * Before AngularJS routing takes effect, test whether the URL fragment
 * contains an OpenID Connect "id_token" parameter, and reformat the fragment
 * such that the client side of Guacamole's authentication system will
 * automatically forward the "id_token" value for server-side validation.
 *
 * Note that not all OpenID identity providers will include the "id_token"
 * parameter in the first position; it may occur after several other parameters
 * within the hash.
 */
(function guacOpenIDTransformToken() {

    // Transform "/#id_token=..." to "/#/?id_token=..."
    if (/(^#|&)id_token=/.test(location.hash))
        location.hash = '/?' + location.hash.substring(1);

})();
<commit_msg>GUACAMOLE-805: Only reformat a URL fragment that appears to be from OpenID Connect if the fragment is not already in a format consumable by AngularJS ("#?..." or "#/?...").<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

/**
 * Before AngularJS routing takes effect, reformat the URL fragment
 * from the format used by OpenID Connect ("#param1=value1&param2=value2&...")
 * to the format used by AngularJS ("#/?param1=value1&param2=value2&...") such
 * that the client side of Guacamole's authentication system will automatically
 * forward the "id_token" value for server-side validation.
 *
 * Note that not all OpenID identity providers will include the "id_token"
 * parameter in the first position; it may occur after several other parameters
 * within the fragment.
 */
(function guacOpenIDTransformToken() {
    if (/^#(?![?\/])(.*&)?id_token=/.test(location.hash))
        location.hash = '/?' + location.hash.substring(1);
})();
<|endoftext|>


<commit_before>import ModelService from '../services/ModelService';
import AdhocModelService from '../services/AdhocModelService';
import models from '../models';

const groupModel = models.Group;
/**
 * @class GroupController
 */
class GroupController {

  /**
   * Restrict access to group owner only
   * @method permitOnlyGroupOwner
   * @memberof GroupController
   * @static
   * @return {function} Express middleware function which
   * permits only a group owner to utilize an endpoint
   */
  static permitOnlyGroupOwner() {
    return (req, res, next) => {
      const groupId = req.params.groupId;
      return ModelService.getModelInstance(groupModel, {
        id: groupId
      })
      .then((group) => {
        if (group.CreatorUsername === req.username ||
        req.userStatus === 'admin') {
          req.group = group;
          return next();
        }
        const msg = 'Access denied! You need group Ownership';
        const err = new Error(msg);
        err.code = 403;
        throw err;
      })
      .catch((err) => {
        return next(err);
      });
    };
  }

  /**
   * Restrict access to group members only
   * @method permitOnlyGroupMembers
   * @memberof GroupController
   * @static
   * @return {function} Express middleware function which
   * permits only group members to utilize an endpoint
   */
  static permitOnlyGroupMembers() {
    return (req, res, next) => {
      const groupId = req.params.groupId;
      return ModelService.getModelInstance(groupModel, {
        id: groupId
      })
      .then((group) => {
        return group.hasUser(req.username)
        .then((hasUser) => {
          if (hasUser || req.userStatus === 'admin') {
            req.group = group;
            return next();
          }
          const msg = 'Access denied! You need group membership';
          const err = new Error(msg);
          err.code = 403;
          throw err;
        });
      })
      .catch((err) => {
        return next(err);
      });
    };
  }

  /**
   * Create a broadcast group
   * @method
   * @memberof GroupController
   * @static
   * @return {function} Express middleware function which creates
   * a group and sends response to client
   */
  static createGroup() {
    return (req, res, next) => {
      return AdhocModelService.validateInputs(req.body)
      .then(() => {
        return groupModel.findOne({
          where: {
            name: req.body.name,
            CreatorUsername: req.username
          }
        });
      })
      .then((group) => {
        if (group) {
          const err = new Error();
          err.message = `You have an existing group ${req.body.name}`;
          err.code = 400;
          throw err;
        }
      })
      .then(() => {
        req.body.CreatorUsername = req.username;
        return ModelService.createModelInstance(groupModel, req.body)
        .then((group) => {
          return group.addUser(req.username)
          .then(() => {
            const { id, name, description, CreatorUsername } = group;
            return res.status(201).json({
              group: { id, name, description, CreatorUsername },
              message: 'Group created'
            });
          });
        });
      })
      .catch((err) => {
        return next(err);
      });
    };
  }

  /**
   * Add a user to a group
   * @method
   * @memberof GroupController
   * @static
   * @return {function} Express middleware function which adds a
   * user to a group and sends response to client
   */
  static addUserToGroup() {
    return (req, res, next) => {
      const username = req.body.username;
      return AdhocModelService.addUserToGroup(username, req.group)
      .then(() => {
        return res.status(200).json({
          username,
          message: `User ${username} added to group`
        });
      })
      .catch((err) => {
        return next(err);
      });
    };
  }

  /**
   * Post message to a group
   * @method
   * @memberof GroupController
   * @static
   * @return {function} Express middleware function which adds a
   * message to a group and sends response to client
   */
  static addMessageToGroup() {
    return (req, res, next) => {
      const message = {
        ...req.body,
        AuthorUsername: req.username
      };
      return AdhocModelService
      .addMessageToGroup(message, req.group)
      .then((createdMessage) => {
        return res.status(200).json({
          createdMessage,
          message: 'Message posted to group'
        });
      })
      .catch((err) => {
        return next(err);
      });
    };
  }

  /**
   * Retrieve messages that have been posted to a group
   * @method
   * @memberof GroupController
   * @static
   * @return {function} Express middleware function which gets
   * group messages and sends response to client
   */
  static getGroupMessages() {
    return (req, res, next) => {
      return AdhocModelService.getGroupMessages(req.group)
      .then((messages) => {
        return res.status(200).json({ messages });
      })
      .catch((err) => {
        return next(err);
      });
    };
  }

  /**
   * Retrieve all users in a group
   * @method
   * @memberof GroupController
   * @static
   * @return {function} Express middleware function which gets
   * group users and sends response to client
   */
  static getGroupUsers() {
    return (req, res, next) => {
      return AdhocModelService.getAllGroupUsers(req.group)
      .then((users) => {
        return res.status(200).json({ users });
      })
      .catch((err) => {
        return next(err);
      });
    };
  }

  /**
   * Remove a user from a group
   * @method
   * @memberof GroupController
   * @static
   * @return {function} Express middleware function which removes a
   * user from a group and sends response to client
   */
  static removeUserFromGroup() {
    return (req, res, next) => {
      const username = req.body.username;
      return AdhocModelService
      .removeUserFromGroup(username, req.group)
      .then(() => {
        return res.status(200).json({
          username,
          message: 'User removed from group'
        });
      })
      .catch((err) => {
        return next(err);
      });
    };
  }

  /**
   * Read a message posted to a group
   * @method
   * @memberof GroupController
   * @static
   * @return {function} Express middleware function
   * which adds a user to a message
   */
  static readGroupMessage() {
    return (req, res, next) => {
      const { messageId } = req.body;
      AdhocModelService
      .addUserToMessage(messageId, req.username, req.group.id)
      .then(() => {
        return res.status(200).json({
          message: `Hi ${req.username}, you just read a message`
        });
      })
      .catch((err) => {
        return next(err);
      });
    };
  }

  /**
   * Get all users that have read a group message
   * @method
   * @memberof GroupController
   * @static
   * @return {function} Express middleware function
   * which gets all users that have read a group message
   * and send response to client
   */
  static getUsersThatReadMessage() {
    return (req, res, next) => {
      const { messageId } = req.params;
      AdhocModelService.getMessageUsers(messageId)
      .then((users) => {
        return res.status(200).json({ users });
      })
      .catch((err) => {
        return next(err);
      });
    };
  }
}

export default GroupController;
<commit_msg>[feat] return user photo url when user adds message to group<commit_after>import ModelService from '../services/ModelService';
import AdhocModelService from '../services/AdhocModelService';
import models from '../models';

const groupModel = models.Group;
/**
 * @class GroupController
 */
class GroupController {

  /**
   * Restrict access to group owner only
   * @method permitOnlyGroupOwner
   * @memberof GroupController
   * @static
   * @return {function} Express middleware function which
   * permits only a group owner to utilize an endpoint
   */
  static permitOnlyGroupOwner() {
    return (req, res, next) => {
      const groupId = req.params.groupId;
      return ModelService.getModelInstance(groupModel, {
        id: groupId
      })
      .then((group) => {
        if (group.CreatorUsername === req.username ||
        req.userStatus === 'admin') {
          req.group = group;
          return next();
        }
        const msg = 'Access denied! You need group Ownership';
        const err = new Error(msg);
        err.code = 403;
        throw err;
      })
      .catch((err) => {
        return next(err);
      });
    };
  }

  /**
   * Restrict access to group members only
   * @method permitOnlyGroupMembers
   * @memberof GroupController
   * @static
   * @return {function} Express middleware function which
   * permits only group members to utilize an endpoint
   */
  static permitOnlyGroupMembers() {
    return (req, res, next) => {
      const groupId = req.params.groupId;
      return ModelService.getModelInstance(groupModel, {
        id: groupId
      })
      .then((group) => {
        return group.hasUser(req.username)
        .then((hasUser) => {
          if (hasUser || req.userStatus === 'admin') {
            req.group = group;
            return next();
          }
          const msg = 'Access denied! You need group membership';
          const err = new Error(msg);
          err.code = 403;
          throw err;
        });
      })
      .catch((err) => {
        return next(err);
      });
    };
  }

  /**
   * Create a broadcast group
   * @method
   * @memberof GroupController
   * @static
   * @return {function} Express middleware function which creates
   * a group and sends response to client
   */
  static createGroup() {
    return (req, res, next) => {
      return AdhocModelService.validateInputs(req.body)
      .then(() => {
        return groupModel.findOne({
          where: {
            name: req.body.name,
            CreatorUsername: req.username
          }
        });
      })
      .then((group) => {
        if (group) {
          const err = new Error();
          err.message = `You have an existing group ${req.body.name}`;
          err.code = 400;
          throw err;
        }
      })
      .then(() => {
        req.body.CreatorUsername = req.username;
        return ModelService.createModelInstance(groupModel, req.body)
        .then((group) => {
          return group.addUser(req.username)
          .then(() => {
            const { id, name, description, CreatorUsername } = group;
            return res.status(201).json({
              group: { id, name, description, CreatorUsername },
              message: 'Group created'
            });
          });
        });
      })
      .catch((err) => {
        return next(err);
      });
    };
  }

  /**
   * Add a user to a group
   * @method
   * @memberof GroupController
   * @static
   * @return {function} Express middleware function which adds a
   * user to a group and sends response to client
   */
  static addUserToGroup() {
    return (req, res, next) => {
      const username = req.body.username;
      return AdhocModelService.addUserToGroup(username, req.group)
      .then(() => {
        return res.status(200).json({
          username,
          message: `User ${username} added to group`
        });
      })
      .catch((err) => {
        return next(err);
      });
    };
  }

  /**
   * Post message to a group
   * @method
   * @memberof GroupController
   * @static
   * @return {function} Express middleware function which adds a
   * message to a group and sends response to client
   */
  static addMessageToGroup() {
    return (req, res, next) => {
      const message = {
        ...req.body,
        AuthorUsername: req.username
      };
      return ModelService.getModelInstance(models.User, {
        username: message.AuthorUsername
      })
      .then((user) => {
        return AdhocModelService
        .addMessageToGroup(message, req.group)
        .then((createdMessage) => {
          createdMessage.dataValues = {
            ...createdMessage.dataValues,
            AuthorImageLink: user.photoURL
          };
          return res.status(200).json({
            createdMessage,
            message: 'Message posted to group'
          });
        });
      })
      .catch((err) => {
        return next(err);
      });
    };
  }

  /**
   * Retrieve messages that have been posted to a group
   * @method
   * @memberof GroupController
   * @static
   * @return {function} Express middleware function which gets
   * group messages and sends response to client
   */
  static getGroupMessages() {
    return (req, res, next) => {
      return AdhocModelService.getGroupMessages(req.group)
      .then((messages) => {
        return res.status(200).json({ messages });
      })
      .catch((err) => {
        return next(err);
      });
    };
  }

  /**
   * Retrieve all users in a group
   * @method
   * @memberof GroupController
   * @static
   * @return {function} Express middleware function which gets
   * group users and sends response to client
   */
  static getGroupUsers() {
    return (req, res, next) => {
      return AdhocModelService.getAllGroupUsers(req.group)
      .then((users) => {
        return res.status(200).json({ users });
      })
      .catch((err) => {
        return next(err);
      });
    };
  }

  /**
   * Remove a user from a group
   * @method
   * @memberof GroupController
   * @static
   * @return {function} Express middleware function which removes a
   * user from a group and sends response to client
   */
  static removeUserFromGroup() {
    return (req, res, next) => {
      const username = req.body.username;
      return AdhocModelService
      .removeUserFromGroup(username, req.group)
      .then(() => {
        return res.status(200).json({
          username,
          message: 'User removed from group'
        });
      })
      .catch((err) => {
        return next(err);
      });
    };
  }

  /**
   * Read a message posted to a group
   * @method
   * @memberof GroupController
   * @static
   * @return {function} Express middleware function
   * which adds a user to a message
   */
  static readGroupMessage() {
    return (req, res, next) => {
      const { messageId } = req.body;
      AdhocModelService
      .addUserToMessage(messageId, req.username, req.group.id)
      .then(() => {
        return res.status(200).json({
          message: `Hi ${req.username}, you just read a message`
        });
      })
      .catch((err) => {
        return next(err);
      });
    };
  }

  /**
   * Get all users that have read a group message
   * @method
   * @memberof GroupController
   * @static
   * @return {function} Express middleware function
   * which gets all users that have read a group message
   * and send response to client
   */
  static getUsersThatReadMessage() {
    return (req, res, next) => {
      const { messageId } = req.params;
      AdhocModelService.getMessageUsers(messageId)
      .then((users) => {
        return res.status(200).json({ users });
      })
      .catch((err) => {
        return next(err);
      });
    };
  }
}

export default GroupController;
<|endoftext|>


<commit_before><commit_msg>scale properly in drawImageURL<commit_after><|endoftext|>


<commit_before>/*
 * This program is part of the OpenLMIS logistics management information system platform software.
 * Copyright © 2017 VillageReach
 *
 * This program is free software: you can redistribute it and/or modify it under the terms
 * of the GNU Affero General Public License as published by the Free Software Foundation, either
 * version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero General Public License for more details. You should have received a copy of
 * the GNU Affero General Public License along with this program. If not, see
 * http://www.gnu.org/licenses.  For additional information contact info@OpenLMIS.org.
 */

(function() {

    'use strict';

    /**
     * @ngdoc service
     * @name openlmis-local-storage.localStorageFactory
     *
     * @description
     * It stores objects in browser cache to make them accessible offline.
     * Each stored or retrieved object is copied.
     */
    angular
        .module('openlmis-local-storage')
        .factory('localStorageFactory', factory);

    factory.$inject = ['localStorageService', '$filter'];

    function factory(localStorageService, $filter) {
        var resources = {};

        return LocalStorageFactory;

        /**
         * @ngdoc method
         * @methodOf openlmis-local-storage.localStorageFactory
         * @name LocalStorageFactory
         *
         * @description
         * Creates array in local storage that is named with resourceName.
         * It returns object with methods to operate on this resource.
         *
         * @param  {String} resourceName Name of resource to be stored
         * @return {Object}              Object with methods to save/get resource objects
         */
        function LocalStorageFactory(resourceName) {
            if (resources[resourceName]) {
                return resources[resourceName];
            }

            var items = getFromStorage(resourceName);
            if (!items) {
                items = [];
            }

            var resource = {
                put: put,
                getBy: getBy,
                getAll: getAll,
                search: search,
                remove: remove,
                removeBy: removeBy,
                clearAll: clearAll,
                contains: contains
            };
            resources[resourceName] = resource;
            return resource;

            /**
             * @ngdoc method
             * @methodOf openlmis-local-storage.localStorageFactory
             * @name put
             *
             * @description
             * Stores given object in local storage.
             *
             * @param {Object} object Object to store
             */
            function put(item) {
                if (item && !contains(item)) {
                    executeWithStorageUpdate(function() {
                        if (item.id) {
                            removeItemBy('id', item.id);
                        }
                        items.push(typeof item === 'object' ? angular.copy(item) : item);
                    });
                }
            }

            /**
             * @ngdoc method
             * @methodOf openlmis-local-storage.localStorageFactory
             * @name getBy
             *
             * @description
             * It searches for all objects that given property value is equal
             * and returns first from the list. If there is no results method returns undefined.
             *
             * @param  {String} property Name of object property to be compared
             * @param  {Object} value    Value of property (equals found object property value)
             * @return {Object}          First found object with equal property value
             */
            function getBy(property, value) {
                var filtered = searchItems(toParams(property, value));
                return filtered.length ? angular.copy(filtered[0]) : undefined;
            }

            /**
             * @ngdoc method
             * @methodOf openlmis-local-storage.localStorageFactory
             * @name getAll
             *
             * @description
             * Method returns all resource objects stored in local storage.
             *
             * @return {Array} All objects stored in this resource
             */
            function getAll() {
                return angular.copy(items);
            }

            /**
             * @ngdoc method
             * @methodOf openlmis-local-storage.localStorageFactory
             * @name search
             *
             * @description
             * It takes params and passes it to filter. If filter name is
             * not defined the default filter will be used.
             *
             * @param  {Object} params Criteria passed to filter
             * @param  {String} filter Name of the filter(optional)
             * @return {Array}         Filtered objects
             */
            function search(params, filter) {
                return angular.copy(searchItems(params, filter));
            }

            /**
             * @ngdoc method
             * @methodOf openlmis-local-storage.localStorageFactory
             * @name remove
             *
             * @description
             * Removes a specific object from local storage
             *
             * @param {Object} item Object to remove
             */
            function remove(item) {
                executeWithStorageUpdate(function() {
                    removeItem(item);
                });
            }

            /**
             * @ngdoc method
             * @methodOf openlmis-local-storage.localStorageFactory
             * @name removeBy
             *
             * @description
             * It searches for all objects that given property value is equal
             * and removes first from the list. If there is no results method returns undefined.
             *
             * @param {String} property Name of object property to be compared
             * @param {Object} value    Value of property (equals found object property value)
             */
            function removeBy(property, value) {
                executeWithStorageUpdate(function() {
                    removeItemBy(property, value);
                });
            }

            /**
             * @ngdoc method
             * @methodOf openlmis-local-storage.localStorageFactory
             * @name clearAll
             *
             * @description
             * Removes all items from resource.
             */
            function clearAll() {
                executeWithStorageUpdate(function() {
                    items.splice(0, items.length);
                });
            }

            /**
             * @ngdoc method
             * @methodOf openlmis-local-storage.localStorageFactory
             * @name contains
             *
             * @description
             * Check if exactly same object exist in storage and if so
             * returns true, otherwise false.
             *
             * @param   {Object}  object Object to compare
             * @return {Boolean}        if objects exist a in storage
             */
            function contains(object) {
                return items.indexOf(object) !== -1;
            }

            function removeItem(item) {
                items.splice(items.indexOf(item), 1);
            }

            function removeItemBy(property, value) {
                var filtered = searchItems(toParams(property, value));
                if (filtered.length) {
                    removeItem(filtered[0]);
                }
            }

            function searchItems(params, filter) {
                return $filter(filter ? filter : 'filter')(items, params);
            }

            function toParams(property, value) {
                var params = {};
                params[property] = value;
                return params;
            }

            function executeWithStorageUpdate(functionToExecute) {
                functionToExecute();
                updateStorage(resourceName, items);
            }
        }

        function getFromStorage(key) {
            var json = localStorageService.get(key);
            return json ? angular.fromJson(json) : undefined;
        }

        function updateStorage(key, data) {
            localStorageService.add(key, angular.toJson(data));
        }

    }
})();
<commit_msg>OLMIS-6684: Replaced angular.copy with JSON.parse to improve performance on the product grid<commit_after>/*
 * This program is part of the OpenLMIS logistics management information system platform software.
 * Copyright © 2017 VillageReach
 *
 * This program is free software: you can redistribute it and/or modify it under the terms
 * of the GNU Affero General Public License as published by the Free Software Foundation, either
 * version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
 * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero General Public License for more details. You should have received a copy of
 * the GNU Affero General Public License along with this program. If not, see
 * http://www.gnu.org/licenses.  For additional information contact info@OpenLMIS.org.
 */

(function() {

    'use strict';

    /**
     * @ngdoc service
     * @name openlmis-local-storage.localStorageFactory
     *
     * @description
     * It stores objects in browser cache to make them accessible offline.
     * Each stored or retrieved object is copied.
     */
    angular
        .module('openlmis-local-storage')
        .factory('localStorageFactory', factory);

    factory.$inject = ['localStorageService', '$filter'];

    function factory(localStorageService, $filter) {
        var resources = {};

        return LocalStorageFactory;

        /**
         * @ngdoc method
         * @methodOf openlmis-local-storage.localStorageFactory
         * @name LocalStorageFactory
         *
         * @description
         * Creates array in local storage that is named with resourceName.
         * It returns object with methods to operate on this resource.
         *
         * @param  {String} resourceName Name of resource to be stored
         * @return {Object}              Object with methods to save/get resource objects
         */
        function LocalStorageFactory(resourceName) {
            if (resources[resourceName]) {
                return resources[resourceName];
            }

            var items = getFromStorage(resourceName);
            if (!items) {
                items = [];
            }

            var resource = {
                put: put,
                getBy: getBy,
                getAll: getAll,
                search: search,
                remove: remove,
                removeBy: removeBy,
                clearAll: clearAll,
                contains: contains
            };
            resources[resourceName] = resource;
            return resource;

            /**
             * @ngdoc method
             * @methodOf openlmis-local-storage.localStorageFactory
             * @name put
             *
             * @description
             * Stores given object in local storage.
             *
             * @param {Object} object Object to store
             */
            function put(item) {
                if (item && !contains(item)) {
                    executeWithStorageUpdate(function() {
                        if (item.id) {
                            removeItemBy('id', item.id);
                        }
                        items.push(typeof item === 'object' ? JSON.parse(JSON.stringify(item)) : item);
                    });
                }
            }

            /**
             * @ngdoc method
             * @methodOf openlmis-local-storage.localStorageFactory
             * @name getBy
             *
             * @description
             * It searches for all objects that given property value is equal
             * and returns first from the list. If there is no results method returns undefined.
             *
             * @param  {String} property Name of object property to be compared
             * @param  {Object} value    Value of property (equals found object property value)
             * @return {Object}          First found object with equal property value
             */
            function getBy(property, value) {
                var filtered = searchItems(toParams(property, value));
                return filtered.length ? angular.copy(filtered[0]) : undefined;
            }

            /**
             * @ngdoc method
             * @methodOf openlmis-local-storage.localStorageFactory
             * @name getAll
             *
             * @description
             * Method returns all resource objects stored in local storage.
             *
             * @return {Array} All objects stored in this resource
             */
            function getAll() {
                return angular.copy(items);
            }

            /**
             * @ngdoc method
             * @methodOf openlmis-local-storage.localStorageFactory
             * @name search
             *
             * @description
             * It takes params and passes it to filter. If filter name is
             * not defined the default filter will be used.
             *
             * @param  {Object} params Criteria passed to filter
             * @param  {String} filter Name of the filter(optional)
             * @return {Array}         Filtered objects
             */
            function search(params, filter) {
                return angular.copy(searchItems(params, filter));
            }

            /**
             * @ngdoc method
             * @methodOf openlmis-local-storage.localStorageFactory
             * @name remove
             *
             * @description
             * Removes a specific object from local storage
             *
             * @param {Object} item Object to remove
             */
            function remove(item) {
                executeWithStorageUpdate(function() {
                    removeItem(item);
                });
            }

            /**
             * @ngdoc method
             * @methodOf openlmis-local-storage.localStorageFactory
             * @name removeBy
             *
             * @description
             * It searches for all objects that given property value is equal
             * and removes first from the list. If there is no results method returns undefined.
             *
             * @param {String} property Name of object property to be compared
             * @param {Object} value    Value of property (equals found object property value)
             */
            function removeBy(property, value) {
                executeWithStorageUpdate(function() {
                    removeItemBy(property, value);
                });
            }

            /**
             * @ngdoc method
             * @methodOf openlmis-local-storage.localStorageFactory
             * @name clearAll
             *
             * @description
             * Removes all items from resource.
             */
            function clearAll() {
                executeWithStorageUpdate(function() {
                    items.splice(0, items.length);
                });
            }

            /**
             * @ngdoc method
             * @methodOf openlmis-local-storage.localStorageFactory
             * @name contains
             *
             * @description
             * Check if exactly same object exist in storage and if so
             * returns true, otherwise false.
             *
             * @param   {Object}  object Object to compare
             * @return {Boolean}        if objects exist a in storage
             */
            function contains(object) {
                return items.indexOf(object) !== -1;
            }

            function removeItem(item) {
                items.splice(items.indexOf(item), 1);
            }

            function removeItemBy(property, value) {
                var filtered = searchItems(toParams(property, value));
                if (filtered.length) {
                    removeItem(filtered[0]);
                }
            }

            function searchItems(params, filter) {
                return $filter(filter ? filter : 'filter')(items, params);
            }

            function toParams(property, value) {
                var params = {};
                params[property] = value;
                return params;
            }

            function executeWithStorageUpdate(functionToExecute) {
                functionToExecute();
                updateStorage(resourceName, items);
            }
        }

        function getFromStorage(key) {
            var json = localStorageService.get(key);
            return json ? angular.fromJson(json) : undefined;
        }

        function updateStorage(key, data) {
            localStorageService.add(key, angular.toJson(data));
        }

    }
})();
<|endoftext|>


<commit_before>/*
  Ported to JavaScript by Lazar Laszlo 2011

  lazarsoft@gmail.com, www.lazarsoft.info

*/

/*
*
* Copyright 2007 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

function GF256Poly(field,  coefficients)
{
	if (coefficients == null || coefficients.length == 0)
	{
		throw "System.ArgumentException";
	}
	this.field = field;
	var coefficientsLength = coefficients.length;
	if (coefficientsLength > 1 && coefficients[0] == 0)
	{
		// Leading term must be non-zero for anything except the constant polynomial "0"
		var firstNonZero = 1;
		while (firstNonZero < coefficientsLength && coefficients[firstNonZero] == 0)
		{
			firstNonZero++;
		}
		if (firstNonZero == coefficientsLength)
		{
			this.coefficients = field.Zero.coefficients;
		}
		else
		{
			this.coefficients = new Array(coefficientsLength - firstNonZero);
			for(var i=0;i<this.coefficients.length;i++)this.coefficients[i]=0;
			//Array.Copy(coefficients, firstNonZero, this.coefficients, 0, this.coefficients.length);
			for(var ci=0;ci<this.coefficients.length;ci++)this.coefficients[ci]=coefficients[firstNonZero+ci];
		}
	}
	else
	{
		this.coefficients = coefficients;
	}

	this.__defineGetter__("Zero", function()
	{
		return this.coefficients[0] == 0;
	});
	this.__defineGetter__("Degree", function()
	{
		return this.coefficients.length - 1;
	});
	this.__defineGetter__("Coefficients", function()
	{
		return this.coefficients;
	});

	this.getCoefficient=function( degree)
	{
		return this.coefficients[this.coefficients.length - 1 - degree];
	}

	this.evaluateAt=function( a)
	{
		if (a == 0)
		{
			// Just return the x^0 coefficient
			return this.getCoefficient(0);
		}
		var size = this.coefficients.length;
		if (a == 1)
		{
			// Just the sum of the coefficients
			var result = 0;
			for (var i = 0; i < size; i++)
			{
				result = GF256.addOrSubtract(result, this.coefficients[i]);
			}
			return result;
		}
		var result2 = this.coefficients[0];
		for (var i = 1; i < size; i++)
		{
			result2 = GF256.addOrSubtract(this.field.multiply(a, result2), this.coefficients[i]);
		}
		return result2;
	}

	this.addOrSubtract=function( other)
		{
			if (this.field != other.field)
			{
				throw "GF256Polys do not have same GF256 field";
			}
			if (this.Zero)
			{
				return other;
			}
			if (other.Zero)
			{
				return this;
			}

			var smallerCoefficients = this.coefficients;
			var largerCoefficients = other.coefficients;
			if (smallerCoefficients.length > largerCoefficients.length)
			{
				var temp = smallerCoefficients;
				smallerCoefficients = largerCoefficients;
				largerCoefficients = temp;
			}
			var sumDiff = new Array(largerCoefficients.length);
			var lengthDiff = largerCoefficients.length - smallerCoefficients.length;
			// Copy high-order terms only found in higher-degree polynomial's coefficients
			//Array.Copy(largerCoefficients, 0, sumDiff, 0, lengthDiff);
			for(var ci=0;ci<lengthDiff;ci++)sumDiff[ci]=largerCoefficients[ci];

			for (var i = lengthDiff; i < largerCoefficients.length; i++)
			{
				sumDiff[i] = GF256.addOrSubtract(smallerCoefficients[i - lengthDiff], largerCoefficients[i]);
			}

			return new GF256Poly(field, sumDiff);
	}
	this.multiply1=function( other)
		{
			if (this.field!=other.field)
			{
				throw "GF256Polys do not have same GF256 field";
			}
			if (this.Zero || other.Zero)
			{
				return this.field.Zero;
			}
			var aCoefficients = this.coefficients;
			var aLength = aCoefficients.length;
			var bCoefficients = other.coefficients;
			var bLength = bCoefficients.length;
			var product = new Array(aLength + bLength - 1);
			for (var i = 0; i < aLength; i++)
			{
				var aCoeff = aCoefficients[i];
				for (var j = 0; j < bLength; j++)
				{
					product[i + j] = GF256.addOrSubtract(product[i + j], this.field.multiply(aCoeff, bCoefficients[j]));
				}
			}
			return new GF256Poly(this.field, product);
		}
	this.multiply2=function( scalar)
		{
			if (scalar == 0)
			{
				return this.field.Zero;
			}
			if (scalar == 1)
			{
				return this;
			}
			var size = this.coefficients.length;
			var product = new Array(size);
			for (var i = 0; i < size; i++)
			{
				product[i] = this.field.multiply(this.coefficients[i], scalar);
			}
			return new GF256Poly(this.field, product);
		}
	this.multiplyByMonomial=function( degree,  coefficient)
		{
			if (degree < 0)
			{
				throw "System.ArgumentException";
			}
			if (coefficient == 0)
			{
				return this.field.Zero;
			}
			var size = this.coefficients.length;
			var product = new Array(size + degree);
			for(var i=0;i<product.length;i++)product[i]=0;
			for (var i = 0; i < size; i++)
			{
				product[i] = this.field.multiply(this.coefficients[i], coefficient);
			}
			return new GF256Poly(this.field, product);
		}
	this.divide=function( other)
		{
			if (this.field!=other.field)
			{
				throw "GF256Polys do not have same GF256 field";
			}
			if (other.Zero)
			{
				throw "Divide by 0";
			}

			var quotient = this.field.Zero;
			var remainder = this;

			var denominatorLeadingTerm = other.getCoefficient(other.Degree);
			var inverseDenominatorLeadingTerm = this.field.inverse(denominatorLeadingTerm);

			while (remainder.Degree >= other.Degree && !remainder.Zero)
			{
				var degreeDifference = remainder.Degree - other.Degree;
				var scale = this.field.multiply(remainder.getCoefficient(remainder.Degree), inverseDenominatorLeadingTerm);
				var term = other.multiplyByMonomial(degreeDifference, scale);
				var iterationQuotient = this.field.buildMonomial(degreeDifference, scale);
				quotient = quotient.addOrSubtract(iterationQuotient);
				remainder = remainder.addOrSubtract(term);
			}

			return new Array(quotient, remainder);
		}
}<commit_msg>Delete gf256poly.js<commit_after><|endoftext|>


<commit_before>let fs = require("fs");
let path = require("path");
let glob = require("glob");
let handlebars = require("handlebars");
let opt = require("get-args")().options;

//Import colors list
let colors = require("../colors.json");

//Header object
let header = [];
header.push("//");
header.push("// WARNING: THIS FILE IS AUTO-GENERATED. DO NOT EDIT IT.");
header.push("// You can generate this file running the following command from the project root: ");
header.push("// $ make templates");
header.push("//");

//Get all templates from the specified source
glob("./templates/" + opt.source + "/*.hbs", function(error, files){
    if(error) {
        process.stderr.write("ERROR: " + error.message);
        return process.exit(1);
    }
    //Initialize the data object to be passed to all templates
    let data = {colors: colors, header: header.join("\n")};
    //Output directory
    let outputDir = path.join(process.cwd(), opt.source);
    //Compile each template
    for (let i = 0; i < files.length; i++) {
        let file = path.join(process.cwd(), files[i]);
        let fileObject = path.parse(file);
        process.stdout.write("Compiling " + file);
        try {
            let content = fs.readFileSync(file, "utf8");
            let template = handlebars.compile(content);
            let output = path.format({dir: outputDir, name: fileObject.name, ext: ""});
            fs.writeFileSync(output, template(data), "utf8");
        } catch (error) {
            process.stderr.write("ERROR: " + error.message);
            return process.exit(1);
        }
    }
    //Compile finished
    return process.exit(0);
});

<commit_msg>Minor changes<commit_after>let fs = require("fs");
let path = require("path");
let glob = require("glob");
let handlebars = require("handlebars");
let opt = require("get-args")().options;

//Import colors list
let colors = require("../colors.json");

//Header object
let header = [];
header.push("//");
header.push("// WARNING: THIS FILE IS AUTO-GENERATED. DO NOT EDIT IT.");
header.push("// You can generate this file running the following command from the project root: ");
header.push("// $ make templates");
header.push("//");

//Get all templates from the specified source
glob("./templates/" + opt.source + "/*.hbs", function(error, files){
    if(error) {
        process.stderr.write("ERROR: " + error.message);
        return process.exit(1);
    }
    //Initialize the data object to be passed to all templates
    let data = {
        "colors": colors.palette,
        "header": header.join("\n")
    };
    //Output directory
    let outputDir = path.join(process.cwd(), opt.source);
    //Compile each template
    for (let i = 0; i < files.length; i++) {
        let file = path.join(process.cwd(), files[i]);
        let fileObject = path.parse(file);
        process.stdout.write("Compiling " + file);
        try {
            let content = fs.readFileSync(file, "utf8");
            let template = handlebars.compile(content);
            let output = path.format({dir: outputDir, name: fileObject.name, ext: ""});
            fs.writeFileSync(output, template(data), "utf8");
        } catch (error) {
            process.stderr.write("ERROR: " + error.message);
            return process.exit(1);
        }
    }
    //Compile finished
    return process.exit(0);
});

<|endoftext|>


<commit_before>var consts = {};

consts.isBeta = true;<commit_msg>Yay release time<commit_after>var consts = {};

consts.isBeta = false;<|endoftext|>