<commit_before>var BASE_URL = '../../..',
    self = this,
    publicData = {};

setupConsole();
setupWebsocket();
setupRequireJs();

onmessage = function(event) {
    require([
        'underscore',
        'util/promise',
        'data/web-worker/util/store'
    ], function(_, Promise, store) {
        self.store = store;
        onMessageHandler(event);
    })
};

function setupConsole() {
    if (typeof console === 'undefined') {
        console = {
            log: log('log'),
            info: log('info'),
            debug: log('debug'),
            error: log('error'),
            warn: log('warn'),
        };
    }
    function log(type) {
        return function() {
            dispatchMain('brokenWorkerConsole', {
                logType: type,
                messages: Array.prototype.slice.call(arguments, 0).map(function(arg) {
                    return JSON.stringify(arg);
                })
            });
        }
    }
}

function setupWebsocket() {
    var supportedInWorker = !!(this.WebSocket || this.MozWebSocket);

    if (supportedInWorker) {
        self.window = self;
        importScripts(BASE_URL + '/libs/atmosphere/atmosphere.js')
        atmosphere.util.getAbsoluteURL = function() {
            return location.origin + '/messaging';
        }
        self.pushSocketMessage = function(message) {
            Promise.all([
                Promise.require('util/websocket'),
                new Promise(function(fulfill, reject) {
                    if (atmosphere.util.__socketOpened) {
                        fulfill(publicData.socket);
                    }
                    atmosphere.util.__socketPromiseFulfill = fulfill;
                    atmosphere.util.__socketPromiseReject = reject;
                })
            ]).done(function(results) {
                var websocketUtils = results[0],
                    socket = results[1];

                websocketUtils.pushDataToSocket(socket, publicData.socketSourceGuid, message);
            });
        }
    } else {
        dispatchMain('websocketNotSupportedInWorker');
        self.pushSocketMessage = function(message) {
            dispatchMain('websocketFromWorker', { message: message });
        }
    }
}

function setupRequireJs() {
    if (typeof FormData === 'undefined') {
        importScripts('./util/formDataPolyfill.js');
    }
    importScripts(BASE_URL + '/jsc/require.config.js');
    require.baseUrl = BASE_URL + '/jsc/';
    importScripts(BASE_URL + '/libs/requirejs/require.js');
}

function onMessageHandler(event) {
    var data = event.data;
    processMainMessage(data);
}

function processMainMessage(data) {
    if (data.type) {
        require(['data/web-worker/handlers/' + data.type], function(handler) {
            handler(data);
        });
    } else console.warn('Unhandled message to worker', event);
}

function dispatchMain(type, message) {
    if (!type) {
        throw new Error('dispatchMain requires type argument');
    }
    message = message || {};
    message.type = type;
    try {
        postMessage(message);
    } catch(e) {
        postMessage({
            type:'brokenWorkerConsole',
            logType: 'error',
            messages: ['error posting', e.message, JSON.stringify(message).substring(0, 100)]
        });
    }
}

function ajaxPrefilter(xmlHttpRequest, method, url, parameters) {
    if (publicData) {
        var filters = [
                setWorkspaceHeader,
                setCsrfHeader,
                // TODO: set timezone
            ], invoke = function(f) {
                f();
            };

        filters.forEach(invoke);
    }

    function setWorkspaceHeader() {
        var hasWorkspaceParam = typeof (parameters && parameters.workspaceId) !== 'undefined';
        if (publicData.currentWorkspaceId && !hasWorkspaceParam) {
            xmlHttpRequest.setRequestHeader('Lumify-Workspace-Id', publicData.currentWorkspaceId);
        }
    }
    function setCsrfHeader() {
        var eligibleForProtection = !(/get/i).test(method),
            user = publicData.currentUser,
            token = user && user.csrfToken;

        if (eligibleForProtection && token) {
            xmlHttpRequest.setRequestHeader('Lumify-CSRF-Token', token);
        }
    }
}

function ajaxPostfilter(xmlHttpRequest, jsonResponse, request) {
    if (!jsonResponse) {
        return;
    }

    var params = request.parameters,
        workspaceId = params && params.workspaceId;

    if (!workspaceId) {
        workspaceId = publicData.currentWorkspaceId;
    }

    store.checkAjaxForPossibleCaching(xmlHttpRequest, jsonResponse, workspaceId, request);
}
<commit_msg>Fix atmosphere url<commit_after>var BASE_URL = '../../..',
    self = this,
    publicData = {};

setupConsole();
setupWebsocket();
setupRequireJs();

onmessage = function(event) {
    require([
        'underscore',
        'util/promise',
        'data/web-worker/util/store'
    ], function(_, Promise, store) {
        self.store = store;
        onMessageHandler(event);
    })
};

function setupConsole() {
    if (typeof console === 'undefined') {
        console = {
            log: log('log'),
            info: log('info'),
            debug: log('debug'),
            error: log('error'),
            warn: log('warn'),
        };
    }
    function log(type) {
        return function() {
            dispatchMain('brokenWorkerConsole', {
                logType: type,
                messages: Array.prototype.slice.call(arguments, 0).map(function(arg) {
                    return JSON.stringify(arg);
                })
            });
        }
    }
}

function setupWebsocket() {
    var supportedInWorker = !!(this.WebSocket || this.MozWebSocket);

    if (supportedInWorker) {
        self.window = self;
        importScripts(BASE_URL + '/libs/atmosphere/atmosphere.js')
        atmosphere.util.getAbsoluteURL = function() {
            return location.origin +
                location.pathname.replace(/\/jsc.*$/, '') +
                '/messaging';
        }
        self.pushSocketMessage = function(message) {
            Promise.all([
                Promise.require('util/websocket'),
                new Promise(function(fulfill, reject) {
                    if (atmosphere.util.__socketOpened) {
                        fulfill(publicData.socket);
                    }
                    atmosphere.util.__socketPromiseFulfill = fulfill;
                    atmosphere.util.__socketPromiseReject = reject;
                })
            ]).done(function(results) {
                var websocketUtils = results[0],
                    socket = results[1];

                websocketUtils.pushDataToSocket(socket, publicData.socketSourceGuid, message);
            });
        }
    } else {
        dispatchMain('websocketNotSupportedInWorker');
        self.pushSocketMessage = function(message) {
            dispatchMain('websocketFromWorker', { message: message });
        }
    }
}

function setupRequireJs() {
    if (typeof FormData === 'undefined') {
        importScripts('./util/formDataPolyfill.js');
    }
    importScripts(BASE_URL + '/jsc/require.config.js');
    require.baseUrl = BASE_URL + '/jsc/';
    importScripts(BASE_URL + '/libs/requirejs/require.js');
}

function onMessageHandler(event) {
    var data = event.data;
    processMainMessage(data);
}

function processMainMessage(data) {
    if (data.type) {
        require(['data/web-worker/handlers/' + data.type], function(handler) {
            handler(data);
        });
    } else console.warn('Unhandled message to worker', event);
}

function dispatchMain(type, message) {
    if (!type) {
        throw new Error('dispatchMain requires type argument');
    }
    message = message || {};
    message.type = type;
    try {
        postMessage(message);
    } catch(e) {
        postMessage({
            type:'brokenWorkerConsole',
            logType: 'error',
            messages: ['error posting', e.message, JSON.stringify(message).substring(0, 100)]
        });
    }
}

function ajaxPrefilter(xmlHttpRequest, method, url, parameters) {
    if (publicData) {
        var filters = [
                setWorkspaceHeader,
                setCsrfHeader,
                // TODO: set timezone
            ], invoke = function(f) {
                f();
            };

        filters.forEach(invoke);
    }

    function setWorkspaceHeader() {
        var hasWorkspaceParam = typeof (parameters && parameters.workspaceId) !== 'undefined';
        if (publicData.currentWorkspaceId && !hasWorkspaceParam) {
            xmlHttpRequest.setRequestHeader('Lumify-Workspace-Id', publicData.currentWorkspaceId);
        }
    }
    function setCsrfHeader() {
        var eligibleForProtection = !(/get/i).test(method),
            user = publicData.currentUser,
            token = user && user.csrfToken;

        if (eligibleForProtection && token) {
            xmlHttpRequest.setRequestHeader('Lumify-CSRF-Token', token);
        }
    }
}

function ajaxPostfilter(xmlHttpRequest, jsonResponse, request) {
    if (!jsonResponse) {
        return;
    }

    var params = request.parameters,
        workspaceId = params && params.workspaceId;

    if (!workspaceId) {
        workspaceId = publicData.currentWorkspaceId;
    }

    store.checkAjaxForPossibleCaching(xmlHttpRequest, jsonResponse, workspaceId, request);
}
<|endoftext|>


<commit_before>// http://erlang.org/doc/man/lists.html
import ErlangTypes from 'erlang-types';

function reverse(list) {
  return [...list].reverse();
}

function foreach(fun, list) {
  list.forEach(x => fun(x));

  return Symbol.for('ok');
}

function duplicate(n, elem) {
  const list = [];

  while (list.length < n) {
    list.push(elem);
  }

  return list;
}

function flatten(deepList, tail = []) {
  const val = deepList.reduce((acc, value) => {
    if (Array.isArray(value)) {
      return acc.concat(flatten(value));
    }

    return acc.concat(value);
  }, []);

  return val.concat(tail);
}

function foldl(fun, acc0, list) {
  return list.reduce((acc, value) => {
    return fun(value, acc);
  }, acc0);
}

function foldr(fun, acc0, list) {
  return foldl(fun, acc0, reverse(list));
}

function keyfind(key, n, tupleList) {
  for (const tuple of tupleList) {
    if (tuple.get(n) === key) {
      return tuple;
    }
  }

  return false;
}

function keymember(key, n, tupleList) {
  if (keyfind(key, n, tupleList) === false) {
    return false;
  }

  return true;
}

function keyreplace(key, n, tupleList, newTuple) {
  const newTupleList = [...tupleList];

  for (let index = 0; index < newTupleList.length; index++) {
    if (newTupleList[index].get(n) === key) {
      newTupleList[index] = newTuple;
      return newTupleList;
    }
  }

  return newTupleList;
}

function keysort(n, tupleList) {
  const newTupleList = [...tupleList];

  return newTupleList.sort((a, b) => {
    if (a.get(n) < b.get(n)) {
      return -1;
    } else if (a.get(n) > b.get(n)) {
      return 1;
    }

    return 0;
  });
}

function keystore(key, n, tupleList, newTuple) {
  const newTupleList = [...tupleList];

  for (let index = 0; index < newTupleList.length; index++) {
    if (newTupleList[index].get(n) === key) {
      newTupleList[index] = newTuple;
      return newTupleList;
    }
  }

  return newTupleList.concat(newTuple);
}

function keydelete(key, n, tupleList) {
  const newTupleList = [];
  let deleted = false;

  for (let index = 0; index < tupleList.length; index++) {
    if (deleted === false && tupleList[index].get(n) === key) {
      deleted = true;
    } else {
      newTupleList.push(tupleList[index]);
    }
  }

  return newTupleList;
}

function keytake(key, n, tupleList) {
  const result = keyfind(key, n, tupleList);

  if (result !== false) {
    return new ErlangTypes.Tuple(
      result.get(n),
      result,
      keydelete(key, n, tupleList)
    );
  }

  return false;
}

function mapfoldl(fun, acc0, list1) {
  const listResult = [];
  let accResult = acc0;

  for (const item of list1) {
    const tuple = fun(item, accResult);
    listResult.push(tuple.get(0));
    accResult = tuple.get(1);
  }

  return new ErlangTypes.Tuple(listResult, accResult);
}

function map(fun, list) {
  return list.map(value => fun(value));
}

export default {
  reverse,
  foreach,
  duplicate,
  flatten,
  foldl,
  foldr,
  keydelete,
  keyfind,
  keymember,
  keyreplace,
  keysort,
  keystore,
  keytake,
  mapfoldl,
  map,
};
<commit_msg>Add more lists functions<commit_after>// http://erlang.org/doc/man/lists.html
import ErlangTypes from 'erlang-types';

function reverse(list) {
  return [...list].reverse();
}

function foreach(fun, list) {
  list.forEach(x => fun(x));

  return Symbol.for('ok');
}

function duplicate(n, elem) {
  const list = [];

  while (list.length < n) {
    list.push(elem);
  }

  return list;
}

function flatten(deepList, tail = []) {
  const val = deepList.reduce((acc, value) => {
    if (Array.isArray(value)) {
      return acc.concat(flatten(value));
    }

    return acc.concat(value);
  }, []);

  return val.concat(tail);
}

function foldl(fun, acc0, list) {
  return list.reduce((acc, value) => {
    return fun(value, acc);
  }, acc0);
}

function foldr(fun, acc0, list) {
  return foldl(fun, acc0, reverse(list));
}

function keyfind(key, n, tupleList) {
  for (const tuple of tupleList) {
    if (tuple.get(n) === key) {
      return tuple;
    }
  }

  return false;
}

function keymember(key, n, tupleList) {
  if (keyfind(key, n, tupleList) === false) {
    return false;
  }

  return true;
}

function keyreplace(key, n, tupleList, newTuple) {
  const newTupleList = [...tupleList];

  for (let index = 0; index < newTupleList.length; index++) {
    if (newTupleList[index].get(n) === key) {
      newTupleList[index] = newTuple;
      return newTupleList;
    }
  }

  return newTupleList;
}

function keysort(n, tupleList) {
  const newTupleList = [...tupleList];

  return newTupleList.sort((a, b) => {
    if (a.get(n) < b.get(n)) {
      return -1;
    } else if (a.get(n) > b.get(n)) {
      return 1;
    }

    return 0;
  });
}

function keystore(key, n, tupleList, newTuple) {
  const newTupleList = [...tupleList];

  for (let index = 0; index < newTupleList.length; index++) {
    if (newTupleList[index].get(n) === key) {
      newTupleList[index] = newTuple;
      return newTupleList;
    }
  }

  return newTupleList.concat(newTuple);
}

function keydelete(key, n, tupleList) {
  const newTupleList = [];
  let deleted = false;

  for (let index = 0; index < tupleList.length; index++) {
    if (deleted === false && tupleList[index].get(n) === key) {
      deleted = true;
    } else {
      newTupleList.push(tupleList[index]);
    }
  }

  return newTupleList;
}

function keytake(key, n, tupleList) {
  const result = keyfind(key, n, tupleList);

  if (result !== false) {
    return new ErlangTypes.Tuple(
      result.get(n),
      result,
      keydelete(key, n, tupleList)
    );
  }

  return false;
}

function mapfoldl(fun, acc0, list1) {
  const listResult = [];
  let accResult = acc0;

  for (const item of list1) {
    const tuple = fun(item, accResult);
    listResult.push(tuple.get(0));
    accResult = tuple.get(1);
  }

  return new ErlangTypes.Tuple(listResult, accResult);
}

function concat(things) {
  return things.map(v => v.toString()).join();
}

function map(fun, list) {
  return list.map(value => fun(value));
}

function filter(pred, list1) {
  return list1.filter(x => pred(x));
}

function filtermap(fun, list1) {
  const list2 = [];

  for (const item of list1) {
    const value = fun(item);

    if (value === true) {
      list2.push(item);
    } else if (value instanceof ErlangTypes.Tuple && value.get(0) === true) {
      list2.push(value.get(1));
    }
  }

  return list2;
}

function member(elem, list) {
  for (const item of list) {
    if (item === elem) {
      return true;
    }
  }

  return false;
}

function all(pred, list) {
  for (const item of list) {
    if (pred(item) === false) {
      return false;
    }
  }

  return true;
}

function any(pred, list) {
  for (const item of list) {
    if (pred(item) === true) {
      return true;
    }
  }

  return false;
}

function splitwith(pred, list) {
  let switchToList2 = false;
  const list1 = [];
  const list2 = [];

  for (const item of list) {
    if (switchToList2 === true) {
      list2.push(item);
    } else if (pred(item) === true) {
      list1.push(item);
    } else {
      switchToList2 = true;
      list2.push(item);
    }
  }

  return new ErlangTypes.Tuple(list1, list2);
}

export default {
  reverse,
  foreach,
  duplicate,
  flatten,
  foldl,
  foldr,
  keydelete,
  keyfind,
  keymember,
  keyreplace,
  keysort,
  keystore,
  keytake,
  mapfoldl,
  concat,
  map,
  filter,
  filtermap,
  member,
  all,
  any,
  splitwith,
};
<|endoftext|>


<commit_before>
//
// Adapter for JS TestNet
// https://github.com/kumar303/jstestnet
//
// Be sure this file is loaded *after* qunit/testrunner.js or whatever else
// you're using

(function() {

    var canPost = false;
    try {
        canPost = !!window.top.postMessage;
    } catch(e){}
    if (!canPost) {
        return;
    }

    function postMsg(data) {
        var msg = '';
        for (var k in data) {
            if (msg.length > 0) {
                msg += '&';
            }
            msg += k + '=' + encodeURI(data[k]);
        }
        window.top.postMessage(msg, '*');
    }

    // QUnit (jQuery)
    // http://docs.jquery.com/QUnit
    if ( typeof QUnit !== "undefined" ) {

        QUnit.begin = function() {
            postMsg({
                action: 'hello',
                user_agent: navigator.userAgent
            });
        };

        QUnit.done = function(failures, total) {
            // // Clean up the HTML (remove any un-needed test markup)
            // $("nothiddendiv").remove();
            // $("loadediframe").remove();
            // $("dl").remove();
            // $("main").remove();
            //
            // // Show any collapsed results
            // $('ol').show();

            postMsg({
                action: 'done',
                failures: failures,
                total: total
            });
        };

        QUnit.log = function(result, message) {
            // Strip out html:
            message = message.replace(/<(?:.|\s)*?>/g, '');
            postMsg({
                action: 'log',
                result: result,
                message: message
            });
        };

        QUnit.moduleStart = function(name) {
            postMsg({
                action: 'set_module',
                name: name
            });
        };

        QUnit.testStart = function(name) {
            postMsg({
                action: 'set_test',
                name: name
            });
        };

        // window.TestSwarm.serialize = function(){
        //  // Clean up the HTML (remove any un-needed test markup)
        //  remove("nothiddendiv");
        //  remove("loadediframe");
        //  remove("dl");
        //  remove("main");
        //
        //  // Show any collapsed results
        //  var ol = document.getElementsByTagName("ol");
        //  for ( var i = 0; i < ol.length; i++ ) {
        //      ol[i].style.display = "block";
        //  }
        //
        //  return trimSerialize();
        // };
    } else {
        throw new Error("Cannot adapt to jstestnet: Unknown test runner");
    }

})();
<commit_msg>Upgraded jstestnet.js for QUnit stacktraces<commit_after>
//
// Adapter for JS TestNet
// https://github.com/kumar303/jstestnet
//
// Be sure this file is loaded *after* qunit/testrunner.js or whatever else
// you're using

(function() {

    var canPost = false;
    try {
        canPost = !!window.top.postMessage;
    } catch(e){}
    if (!canPost) {
        return;
    }

    function postMsg(data) {
        var msg = '';
        for (var k in data) {
            if (msg.length > 0) {
                msg += '&';
            }
            msg += k + '=' + encodeURI(data[k]);
        }
        window.top.postMessage(msg, '*');
    }

    // QUnit (jQuery)
    // http://docs.jquery.com/QUnit
    if ( typeof QUnit !== "undefined" ) {

        QUnit.begin = function() {
            postMsg({
                action: 'hello',
                user_agent: navigator.userAgent
            });
        };

        QUnit.done = function(failures, total) {
            // // Clean up the HTML (remove any un-needed test markup)
            // $("nothiddendiv").remove();
            // $("loadediframe").remove();
            // $("dl").remove();
            // $("main").remove();
            //
            // // Show any collapsed results
            // $('ol').show();

            postMsg({
                action: 'done',
                failures: failures,
                total: total
            });
        };

        QUnit.log = function(result, message, details) {
            // Strip out html:
            message = message.replace(/<(?:.|\s)*?>/g, '');
            var msg = {
                action: 'log',
                result: result,
                message: message,
                stacktrace: null
            };
            if (details) {
                if (typeof(details.source) !== 'undefined') {
                    msg.stacktrace = details.source;
                }
            }
            postMsg(msg);
        };

        QUnit.moduleStart = function(name) {
            postMsg({
                action: 'set_module',
                name: name
            });
        };

        QUnit.testStart = function(name) {
            postMsg({
                action: 'set_test',
                name: name
            });
        };

        // window.TestSwarm.serialize = function(){
        //  // Clean up the HTML (remove any un-needed test markup)
        //  remove("nothiddendiv");
        //  remove("loadediframe");
        //  remove("dl");
        //  remove("main");
        //
        //  // Show any collapsed results
        //  var ol = document.getElementsByTagName("ol");
        //  for ( var i = 0; i < ol.length; i++ ) {
        //      ol[i].style.display = "block";
        //  }
        //
        //  return trimSerialize();
        // };
    } else {
        throw new Error("Cannot adapt to jstestnet: Unknown test runner");
    }

})();
<|endoftext|>


<commit_before>/*
    AUTOHUE
    A daylight harvester for Hue. Why use a button or app in the first place? Light should just be there, and be right.

    Taco Ekkel, Chris Waalberg

    See README for instructions
*/

var b = require('bonescript');
var q = require('q');
var request = require('request');
var moment = require('moment');

// 'desired' needs very careful calibration based on location and all light sources.
// moving the sensor, changing a lamp, etc all imply recalibrating.
var DESIRED = 0.50;

// max is absolute, i.e. when the schedule says 100%
var MAX = 0.95;

// this prevents the lights from continously shifting a little bit,
// caused by fluctuation in the sensor reading
var THRESHOLD = 0.02;

var USERNAME = "newdeveloper";
var LIGHTS = [ 1, 2, 3 ];        // 'ardcode me lites, matey
var LIGHTFACTORS = [ 1, 1, 0.5 ]; // use values < 1 to scale down global max per light

var BRIDGEIP = null;
var CURRENTBRI = null;
var PININ = "P9_40"; // AIN1
var INTERVAL = 2 * 1000; // every 10 seconds

// setup: get bridge IP and start main loop with setInterval
console.log("Starting - connecting to bridge");
getBridgeIP()
.then(function() {
    setInterval(mainLoop, INTERVAL);
}).fail(function(error) {
    console.log(" -- ERROR: " + error);
}).done();

function mainLoop() {
    getHueBrightness()
    .then(function() {
        b.analogRead(PININ, calculateAction)
    }).fail(function(error) {
        console.log(" -- ERROR: " + error)
    }).done();
}

// given input x.value = light level between 0 and 1, what's the action the lights should take
// to get to the desired light level?
function calculateAction(analogReading) {
    if (CURRENTBRI == null) return;

    var now = moment();
    var factor = GetTimeBasedFactor(now);

    var actual = analogReading.value;
    var delta = DESIRED - actual;

    var huecurrent = CURRENTBRI;
    var huetarget = huecurrent + delta;
    if (huetarget < 0) huetarget = 0;
    if (huetarget > MAX * factor) huetarget = MAX * factor; // clamp down here to prevent interference with sensor reading
    var colortemptarget = CalcDesiredColorTemperature(now);

    function fn(f) { return Math.round(f*1000)/1000; }
    console.log('Sensor: ' + fn(actual) + ', hue: ' + fn(huecurrent) + '. Desired/factor: ' + fn(DESIRED) + '/' + fn(factor) +
                ', new hue: ' + fn(huetarget) + ' ' + Math.round(colortemptarget) + 'K');

    // TODO make threshold check work with color temp changes
    // if (Math.abs(delta) > THRESHOLD)
    setHueBrightnessAndCT(huetarget, colortemptarget);
}

// in: current time
// out: factor for multiplying target brightness compensated for time of day
function GetTimeBasedFactor(currentTime) {
    var mins = currentTime.hours() * 60 + currentTime.minutes();
    var factor = 1.0;
    switch(true) {
        case (mins < 60):
            factor = 0.4 - 0.4*(mins/60); // slow fade from midnight to 1am
            break;
        case (mins < 6 * 60):
            factor = 0; // night time, 1am to 6am
            break;
        case (mins < 19 * 60):
            factor = 1; // normal daytime
            break;
        case (mins < 24 * 60): // fade down to 40% between dinner and midnight
            factor = 1.0 - (((mins/60)-19)/5) * 0.6;
            break;
        default:
            console.log(" -- WARNING: unexpected minute count " + mins);
    }
    return factor;
}

function CalcDesiredColorTemperature(currentTime) {
    var mins = currentTime.hours() * 60 + currentTime.minutes();
    var dayTemp = 2800 // more or less incandescent
    var nightTemp = 2000; // warmest white available
    var colorTemp = dayTemp;
    switch(true) {
        case (mins < 6 * 60):
            colorTemp = nightTemp;
            break;
        case (mins < 19 * 60):
            colorTemp = dayTemp;
            break;
        case (mins < 24 * 60): //warm up between dinner (7pm) and midnight
            colorTemp = dayTemp - (((mins/60)-19)/5) * (dayTemp-nightTemp);
            break;
        default:
            console.log(" -- WARNING: unexpected minute count " + mins);
    }
    //console.log("Color temperature: " + colorTemp);
    return colorTemp;
}

function getHueBrightness() {
    var deferred = q.defer();
    var light = 2;
    var url = 'http://' + BRIDGEIP + '/api/' + USERNAME + '/lights/' + light;
    request(url, function(error, response, body) {
        if (!error && response.statusCode == 200) {
            var json = JSON.parse(body);
            if (!json || !json.state || !json.state.hasOwnProperty("bri")) {
                deferred.reject(' -- ERROR: No brightness value found.');
            } else {
                CURRENTBRI = json.state.bri / 255;
                deferred.resolve();
            }
        }
    });
    return deferred.promise;
}

function setHueBrightnessAndCT(brightness, colortemp) {
    var bri = brightness * 255;    // from [0..1] to [0..255]
    var ct = 1000000 / colortemp;  // convert color temperature to Mired
    for (var i = 0; i < LIGHTS.length; i++) {
        setHueLightBrightnessAndCT(LIGHTS[i], bri * LIGHTFACTORS[i], ct);
    }
}

function setHueLightBrightnessAndCT(light, bri, ct) {
    var url = 'http://' + BRIDGEIP + '/api/' + USERNAME + '/lights/' + light + '/state';
    var lampstate = (bri > 3.0);
    var state = { "bri": Math.round(bri), "ct": Math.round(ct), "on": lampstate };
    // console.log(' -- setLightState: ' + url, JSON.stringify(state));
    request.put({
        url: url,
        json: state
    }, function(error, response, body) {
        if (response.statusCode != 200) {
            console.log(' -- ERROR: Light state not set: ' + response.statusCode, body);
        }
    });
}

function getBridgeIP() {
    var deferred = q.defer();
    request('http://www.meethue.com/api/nupnp', function(error, response, body) {
        if (!error && response.statusCode == 200) {
            var json = JSON.parse(body);
            if (!json || !json[0] || !json[0].internalipaddress) {
                deferred.reject(' -- ERROR: No bridge found.');
            }
            else {
                BRIDGEIP = json[0].internalipaddress;
                console.log(' -- BridgeIP found: ' + BRIDGEIP);
                deferred.resolve();
            }
        }
        else {
            deferred.reject(' -- ERROR: cannot reach hue NUPNP');
        }
    });
    return deferred.promise;
}
<commit_msg>Added retry for bridge connect, so it can be run as a service. Logging with timestamp. Configurable light number for sampling current brightness. Changed default interval to 10 seconds.<commit_after>/*
    AUTOHUE
    A daylight harvester for Hue. Why use a button or app in the first place? Light should just be there, and be right.

    Taco Ekkel, Chris Waalberg

    See README for instructions
*/

var b = require('bonescript');
var q = require('q');
var request = require('request');
var moment = require('moment');

// 'desired' needs very careful calibration based on location and all light sources.
// moving the sensor, changing a lamp, etc all imply recalibrating.
var DESIRED = 0.50;

// max is absolute, i.e. when the schedule says 100%
var MAX = 0.95;

// this prevents the lights from continously shifting a little bit,
// caused by fluctuation in the sensor reading
var THRESHOLD = 0.02;

var USERNAME = "newdeveloper";
var LIGHTS = [ 1, 2, 3 ];        // 'ardcode me lites, matey
var LIGHTFACTORS = [ 1, 1, 0.5 ]; // use values < 1 to scale down global max per light
var MEASURELIGHT = 2;               // what light to use as the reference (make sure its LIGHTFACTOR is 1)

var BRIDGEIP = null;
var CURRENTBRI = null;
var PININ = "P9_40"; // AIN1
var INTERVAL = 10 * 1000; //

// setup: get bridge IP and start main loop with setInterval
log("AUTOHUE: Desired light level: " + DESIRED);
log("AUTOHUE: Measuring interval: " + INTERVAL/1000 + "s");
log("Connecting to bridge...");
getBridgeIP()
.then(function() {
    setInterval(mainLoop, INTERVAL);
}).fail(function(error) {
    log(" -- ERROR: " + error);
}).done();

function mainLoop() {
    getHueBrightness()
    .then(function() {
        b.analogRead(PININ, calculateAction)
    }).fail(function(error) {
        log(" -- ERROR: " + error)
    }).done();
}

// given input x.value = light level between 0 and 1, what's the action the lights should take
// to get to the desired light level?
function calculateAction(analogReading) {
    if (CURRENTBRI == null) return;

    var now = moment();
    var factor = GetTimeBasedFactor(now);

    var actual = analogReading.value;
    var delta = DESIRED - actual;

    var huecurrent = CURRENTBRI;
    var huetarget = huecurrent + delta;
    if (huetarget < 0) huetarget = 0;
    if (huetarget > MAX * factor) huetarget = MAX * factor; // clamp down here to prevent interference with sensor reading
    var colortemptarget = CalcDesiredColorTemperature(now);

    function fn(f) { return Math.round(f*1000)/1000; }
    log('Sensor: ' + fn(actual) + ', hue: ' + fn(huecurrent) + '. Brightfactor: ' + fn(factor) +
                ', new hue: ' + fn(huetarget) + ' ' + Math.round(colortemptarget) + 'K');

    // TODO make threshold check work with color temp changes
    // if (Math.abs(delta) > THRESHOLD)
    setHueBrightnessAndCT(huetarget, colortemptarget);
}

// in: current time
// out: factor for multiplying target brightness compensated for time of day
function GetTimeBasedFactor(currentTime) {
    var mins = currentTime.hours() * 60 + currentTime.minutes();
    var factor = 1.0;
    switch(true) {
        case (mins < 60):
            factor = 0.4 - 0.4*(mins/60); // slow fade from midnight to 1am
            break;
        case (mins < 6 * 60):
            factor = 0; // night time, 1am to 6am
            break;
        case (mins < 19 * 60):
            factor = 1; // normal daytime
            break;
        case (mins < 24 * 60): // fade down to 40% between dinner and midnight
            factor = 1.0 - (((mins/60)-19)/5) * 0.6;
            break;
        default:
            log(" -- WARNING: unexpected minute count " + mins);
    }
    return factor;
}

function CalcDesiredColorTemperature(currentTime) {
    var mins = currentTime.hours() * 60 + currentTime.minutes();
    var dayTemp = 2800 // more or less incandescent
    var nightTemp = 2000; // warmest white available
    var colorTemp = dayTemp;
    switch(true) {
        case (mins < 6 * 60):
            colorTemp = nightTemp;
            break;
        case (mins < 19 * 60):
            colorTemp = dayTemp;
            break;
        case (mins < 24 * 60): //warm up between dinner (7pm) and midnight
            colorTemp = dayTemp - (((mins/60)-19)/5) * (dayTemp-nightTemp);
            break;
        default:
            log(" -- WARNING: unexpected minute count " + mins);
    }
    //log("Color temperature: " + colorTemp);
    return colorTemp;
}

function getHueBrightness() {
    var deferred = q.defer();
    var url = 'http://' + BRIDGEIP + '/api/' + USERNAME + '/lights/' + MEASURELIGHT;
    request(url, function(error, response, body) {
        if (!error && response.statusCode == 200) {
            var json = JSON.parse(body);
            if (!json || !json.state || !json.state.hasOwnProperty("bri")) {
                deferred.reject(' -- ERROR: No brightness value found.');
            } else {
                CURRENTBRI = json.state.bri / 255;
                deferred.resolve();
            }
        }
    });
    return deferred.promise;
}

function setHueBrightnessAndCT(brightness, colortemp) {
    var bri = brightness * 255;    // from [0..1] to [0..255]
    var ct = 1000000 / colortemp;  // convert color temperature to Mired
    for (var i = 0; i < LIGHTS.length; i++) {
        setHueLightBrightnessAndCT(LIGHTS[i], bri * LIGHTFACTORS[i], ct);
    }
}

function setHueLightBrightnessAndCT(light, bri, ct) {
    var url = 'http://' + BRIDGEIP + '/api/' + USERNAME + '/lights/' + light + '/state';
    var lampstate = (bri > 3.0);
    var state = { "bri": Math.round(bri), "ct": Math.round(ct), "on": lampstate };
    // log(' -- setLightState: ' + url, JSON.stringify(state));
    request.put({
        url: url,
        json: state
    }, function(error, response, body) {
        if (response.statusCode != 200) {
            log(' -- ERROR: Light state not set: ' + response.statusCode, body);
        }
    });
}

// get bridge, with retry (for use at system boot, when wifi may not yet be up)
function getBridgeIP(deferred) {
    var deferred = deferred || q.defer();
    request('http://www.meethue.com/api/nupnp', function(error, response, body) {
        if (!error && response.statusCode == 200) {
            var json = JSON.parse(body);
            if (!json || !json[0] || !json[0].internalipaddress) {
                deferred.reject(' -- ERROR: No bridge registered in this network.');
            }
            else {
                BRIDGEIP = json[0].internalipaddress;
                log(' -- BridgeIP found: ' + BRIDGEIP);
                deferred.resolve();
            }
        }
        else {
            log(' -- Cannot connect to the network (http://www.meethue.com/api/nupnp). Retrying in 10.');
    		setTimeout(function() {
    			getBridgeIP(deferred);
    		}, 10 * 1000);
        }
    });
    return deferred.promise;
}

function log(s) {
    console.log(moment().format() + " " + s);
}<|endoftext|>


<commit_before>import enhancer from '../src/enhancer'
import createMockStorage from './utils/testStorage'

describe('enhancer', () => {
  it('returns enhanced store with initial storage state', () => {
    const enhancedCreateStore = enhancer({ storage: createMockStorage() })

    expect(enhancedCreateStore).toBeInstanceOf(Function)
  })

  it('sets up store with initial storage state', () => {
    const mock = jest.fn()
    const dummyData = {
      authenticated: {
        authenticator: 'dummy',
        token: 'abcde'
      }
    }
    const storage = createMockStorage(dummyData)
    const createStore = jest.fn()

    const enhancedCreateStore = enhancer({ storage })(createStore)(
      mock,
      null,
      mock
    )

    expect(createStore).toHaveBeenCalledWith(
      mock,
      {
        session: {
          authenticator: 'dummy',
          data: { token: 'abcde' },
          isAuthenticated: false
        }
      },
      mock
    )
  })

  it('throws when no storage given', () => {
    expect(() => enhancer({ storage: null })).toThrow(
      'Expected `storage` to be a valid storage. You either forgot to ' +
        'include it or you passed an invalid storage object'
    )
  })
})
<commit_msg>Fix lint error<commit_after>import enhancer from '../src/enhancer'
import createMockStorage from './utils/testStorage'

describe('enhancer', () => {
  it('returns enhanced store with initial storage state', () => {
    const enhancedCreateStore = enhancer({ storage: createMockStorage() })

    expect(enhancedCreateStore).toBeInstanceOf(Function)
  })

  it('sets up store with initial storage state', () => {
    const mock = jest.fn()
    const dummyData = {
      authenticated: {
        authenticator: 'dummy',
        token: 'abcde'
      }
    }
    const storage = createMockStorage(dummyData)
    const createStore = jest.fn()

    enhancer({ storage })(createStore)(mock, null, mock)

    expect(createStore).toHaveBeenCalledWith(
      mock,
      {
        session: {
          authenticator: 'dummy',
          data: { token: 'abcde' },
          isAuthenticated: false
        }
      },
      mock
    )
  })

  it('throws when no storage given', () => {
    expect(() => enhancer({ storage: null })).toThrow(
      'Expected `storage` to be a valid storage. You either forgot to ' +
        'include it or you passed an invalid storage object'
    )
  })
})
<|endoftext|>


<commit_before>var $ = require('jquery');
var ko = require('knockout');
var m = require('mithril');
var bootbox = require('bootbox');

var FilesWidget = require('js/filesWidget');
var Fangorn = require('js/fangorn');
var $osf = require('js/osfHelpers');
var waterbutler = require('js/waterbutler');
var ContribAdder = require('js/contribAdder');

var node = window.contextVars.node;

var NO_FILE = 'No file selected';

var limitContents = function(item) {
    if (item.data.provider !== undefined && item.data.provider !== 'osfstorage' || item.data.isPointer) {
        item.open = false;
        item.load = false;
        item.css = 'text-muted';
        item.data.permissions = item.data.permissions || {};
        item.data.permissions.edit = false;
        item.data.permissions.view = false;
        if (item.data.isPointer) {
            if (item.data.name.indexOf(' (Linked content is not allowed.)') === -1) {
                item.data.name = item.data.name + ' (Linked content is not allowed.)';
            }
        }
        else if (item.data.name.indexOf(' (Only OSF Storage supported to ensure accurate versioning.)') === -1) {
            item.data.name = item.data.name + ' (Only OSF Storage supported to ensure accurate versioning.)';
        }
    }
};

var filePicker;
var osfUploader = function(element, valueAccessor, allBindings, viewModel, bindingContext) {
    viewModel.showUploader(true);
    viewModel.toggleUploader = function() {
        this.showUploader(!this.showUploader());
    };

    var $root = bindingContext.$root;
    $root.currentPage.subscribe(function(question) {
        if (filePicker) {
            // A hack to flush the old mithril controller.
            // It's unclear to me exactly why this is happening (after 3hrs), but seems
            // to be a KO-mithril interaction. We're programattically changing the div
            // containing mithril mountings, and for some reason old controllers (and
            // their bound settings) are persisting and being reused. This call
            // explicity removes the old controller.
            // see: http://lhorie.github.io/mithril/mithril.component.html#unloading-components
            m.mount(document.getElementById(filePicker.fangornOpts.divID), null);

            filePicker.destroy();
            filePicker = null;
        }
    }, null, 'beforeChange');

    var onSelectRow = function(item) {
        if (item.kind === 'file') {
            viewModel.addFile(item);
            item.css = 'fangorn-selected';
        }
    };
    var fw = new FilesWidget(
        element.id,
        node.urls.api + 'files/grid/', {
            dropzone: {
                url: function(files) {
                    return files[0].url;
                },
                clickable: '#' + element.id,
                addRemoveLinks: false,
                previewTemplate: '

',
                parallelUploads: 1,
                acceptDirectories: false
            },
            dropzoneEvents: $.extend(
                {},
                Fangorn.DefaultOptions.dropzoneEvents,
                {
                    complete: function(tb, file, response) {
                        var fileMeta = JSON.parse(file.xhr.response);
                        fileMeta.nodeId = file.treebeardParent.data.nodeId;
                        onSelectRow({
                            kind: 'file',
                            data: fileMeta
                        });

                    }
                }
            ),
            onselectrow: onSelectRow,
            resolveRows: function(item) {
                var tb = this;

                item.css = '';

                limitContents(item);

                if (viewModel.value()) {
                    if (item.data.path === viewModel.value()) {
                        item.css = 'fangorn-selected';
                    }
                }

                var defaultColumns = [{
                    data: 'name',
                    folderIcons: true,
                    filter: true,
                    custom: Fangorn.DefaultColumns._fangornTitleColumn
                }];
                if (item.parentID) {
                    item.data.permissions = item.data.permissions || item.parent().data.permissions;
                    if (item.data.kind === 'folder') {
                        item.data.accept = item.data.accept || item.parent().data.accept;
                    }
                }

                var configOption = Fangorn.Utils.resolveconfigOption.call(this, item, 'resolveRows', [item]);
                return configOption || defaultColumns;
            },
            lazyLoadOnLoad: function(tree, event) {
                if (tree.data.provider === 'osfstorage' && tree.data.nodeId === window.contextVars.node.id) {
                    this.multiselected([tree]);
                }

                tree.children.forEach(function(item) {
                    limitContents(item);

                    if (viewModel.value() !== null) {
                        if (item.data.path === viewModel.value()) {
                            item.css = 'fangorn-selected';
                            item.data.nodeId = tree.data.nodeId;
                            viewModel.addFile(item);
                        }
                    }
                    Fangorn.Utils.inheritFromParent(item, tree);
                });
                Fangorn.Utils.resolveconfigOption.call(this, tree, 'lazyLoadOnLoad', [tree, event]);
                Fangorn.Utils.reapplyTooltips();

                if (tree.depth > 1) {
                    Fangorn.Utils.orderFolder.call(this, tree);
                }
            },
            links: false
        });
    filePicker = fw;
    fw.init().then(function() {
        viewModel.showUploader(false);
    });
};

ko.bindingHandlers.osfUploader = {
    init: osfUploader
};

var uploaderCount = 0;
var Uploader = function(question) {

    var self = this;

    question.showUploader = ko.observable(false);
    question.uid = 'uploader_' + uploaderCount;
    uploaderCount++;
    self.selectedFiles = ko.observableArray(question.extra() || []);
    self.selectedFiles.subscribe(function(fileList) {
        $.each(fileList, function(idx, file) {
            if (file && !self.fileAlreadySelected(file)) {
                question.extra().push(file);
            }
        });
        question.value(question.formattedFileList());
    });
    self.fileWarn = ko.observable(true);

    self.UPLOAD_LANGUAGE = 'You may attach up to 5 files to this question. You may attach files that you already have ' +
        'in this OSF project, or upload a new file from your computer. Uploaded files will automatically be added to this project ' +
        'so that they can be registered.';

    self.addFile = function(file) {
        if(self.selectedFiles().length >= 5 && self.fileWarn()) {
            self.fileWarn(false);
            bootbox.alert({
                title: 'Too many files',
                message: 'You cannot attach more than 5 files to a question.',
                buttons: {
                    ok: {
                        label: 'Close',
                        className: 'btn-default'
                    }
                }
            }).css({ 'top': '35%' });
            return false;
        } else if(self.selectedFiles().length >= 5 && !self.fileWarn()) {
            return false;
        }
        if(self.fileAlreadySelected(file))
            return false;

        self.selectedFiles.push({
            data: file.data,
            selectedFileName: file.data.name,
            nodeId: file.data.nodeId,
            viewUrl: '/project/' + file.data.nodeId + '/files/osfstorage' + file.data.path,
            sha256: file.data.extra.hashes.sha256
        });
        return true;
    };

    self.fileAlreadySelected = function(file) {
        var selected = false;
        $.each(question.extra(), function(idx, alreadyFile) {
            if(alreadyFile.selectedFileName === file.data.name && alreadyFile.sha256 === file.data.extra.hashes.sha256){
                selected = true;
                return;
            }
        });
        return selected;
    };

    self.hasSelectedFile = ko.computed(function() {
        return question.extra().length !== 0;
    });
    self.unselectFile = function(fileToRemove) {

        var files = question.extra();

        for (var i = 0; i < files.length; i++) {
            var file = files[i];
            if(file.sha256 === fileToRemove.sha256) {
                self.selectedFiles.splice(i, 1);
                question.value(question.formattedFileList());
                break;
            }
        }
    };

    self.filePicker = null;

    self.preview = function() {
        var value = question.value();
        if (!value || value === NO_FILE || question.extra().length === 0) {
            return 'no file selected';
        }
        else {
            var files = question.extra();
            var elem = '';
            $.each(files, function(_, file) {
                elem += '' + $osf.htmlEscape(file.selectedFileName) + ' ' + '
';
            });
            return $(elem);
        }
    };

    $.extend(self, question);
};

var AuthorImport = function(data, $root, preview) {
    var self = this;
    self.question = data;

    /**
     * Makes ajax request for a project's contributors
     */
    self.makeContributorsRequest = function() {
        var contributorsUrl = window.contextVars.node.urls.api + 'get_contributors/';
        return $.getJSON(contributorsUrl);
    };
    /**
     * Returns the `user_fullname` of each contributor attached to a node.
     **/
    self.getContributors = function() {
        return self.makeContributorsRequest()
            .fail(function(xhr, status, error) {
                Raven.captureMessage('Could not GET contributors', {
                    extra: {
                        url: window.contextVars.node.urls.api + 'get_contributors/',
                        textStatus: status,
                        error: error
                    }
                });
                $osf.growl('Could not retrieve contributors.', osfLanguage.REFRESH_OR_SUPPORT);
            });
    };

    self.serializeContributors = function(contributors) {
        return $.map(contributors, function(c) {
            return c.fullname;
        }).join(', ');
    };
    self.makeContributorsRequest = function() {
        var self = this;
        var contributorsUrl = window.contextVars.node.urls.api + 'get_contributors/';
        return $.getJSON(contributorsUrl);
    };

    self.contributors = ko.observable([]);
    if (!preview) {
        self.getContributors().done(function(data) {
            self.question.value(self.serializeContributors(data.contributors));
        });
    }

    self.preview = function() {
        return self.value();
    };
    var callback = function(data) {
        self.question.value(self.serializeContributors(data.contributors));
    };

    if ($('#addContributors').length > 0) {
        ko.cleanNode($('#addContributors')[0]);
        var adder = new ContribAdder(
            '#addContributors',
            node.title,
            node.id,
            null,
            null,
            {async: true, callback: callback}
        );
    }

    $.extend(self, data);
};

module.exports = {
    AuthorImport: AuthorImport,
    Uploader: Uploader,
    osfUploader: osfUploader,
    limitContents: limitContents
};
<commit_msg>Prereg challenge form on staging and production errors on 4th page  [#OSF-5977]<commit_after>var $ = require('jquery');
var ko = require('knockout');
var m = require('mithril');
var bootbox = require('bootbox');

var FilesWidget = require('js/filesWidget');
var Fangorn = require('js/fangorn');
var $osf = require('js/osfHelpers');
var waterbutler = require('js/waterbutler');
var ContribAdder = require('js/contribAdder');

var node = window.contextVars.node;

var NO_FILE = 'No file selected';

var limitContents = function(item) {
    if (item.data.provider !== undefined && item.data.provider !== 'osfstorage' || item.data.isPointer) {
        item.open = false;
        item.load = false;
        item.css = 'text-muted';
        item.data.permissions = item.data.permissions || {};
        item.data.permissions.edit = false;
        item.data.permissions.view = false;
        if (item.data.isPointer) {
            if (item.data.name.indexOf(' (Linked content is not allowed.)') === -1) {
                item.data.name = item.data.name + ' (Linked content is not allowed.)';
            }
        }
        else if (item.data.name.indexOf(' (Only OSF Storage supported to ensure accurate versioning.)') === -1) {
            item.data.name = item.data.name + ' (Only OSF Storage supported to ensure accurate versioning.)';
        }
    }
};

var filePicker;
var filesWidgetCleanUp = [];
var osfUploader = function(element, valueAccessor, allBindings, viewModel, bindingContext) {
    viewModel.showUploader(true);
    viewModel.toggleUploader = function() {
        this.showUploader(!this.showUploader());
    };

    var $root = bindingContext.$root;
    $root.currentPage.subscribe(function(question) {
        if (filePicker) {
            // A hack to flush the old mithril controller.
            // It's unclear to me exactly why this is happening (after 3hrs), but seems
            // to be a KO-mithril interaction. We're programattically changing the div
            // containing mithril mountings, and for some reason old controllers (and
            // their bound settings) are persisting and being reused. This call
            // explicity removes the old controller.
            // see: http://lhorie.github.io/mithril/mithril.component.html#unloading-components
            $.each(filesWidgetCleanUp, function( index, value ) {
                m.mount(document.getElementById(value), null);
            });
            filesWidgetCleanUp = [];

            filePicker.destroy();
            filePicker = null;
        }
    }, null, 'beforeChange');

    var onSelectRow = function(item) {
        if (item.kind === 'file') {
            viewModel.addFile(item);
            item.css = 'fangorn-selected';
        }
    };
    var fw = new FilesWidget(
        element.id,
        node.urls.api + 'files/grid/', {
            dropzone: {
                url: function(files) {
                    return files[0].url;
                },
                clickable: '#' + element.id,
                addRemoveLinks: false,
                previewTemplate: '

',
                parallelUploads: 1,
                acceptDirectories: false
            },
            dropzoneEvents: $.extend(
                {},
                Fangorn.DefaultOptions.dropzoneEvents,
                {
                    complete: function(tb, file, response) {
                        var fileMeta = JSON.parse(file.xhr.response);
                        fileMeta.nodeId = file.treebeardParent.data.nodeId;
                        onSelectRow({
                            kind: 'file',
                            data: fileMeta
                        });

                    }
                }
            ),
            onselectrow: onSelectRow,
            resolveRows: function(item) {
                var tb = this;

                item.css = '';

                limitContents(item);

                if (viewModel.value()) {
                    if (item.data.path === viewModel.value()) {
                        item.css = 'fangorn-selected';
                    }
                }

                var defaultColumns = [{
                    data: 'name',
                    folderIcons: true,
                    filter: true,
                    custom: Fangorn.DefaultColumns._fangornTitleColumn
                }];
                if (item.parentID) {
                    item.data.permissions = item.data.permissions || item.parent().data.permissions;
                    if (item.data.kind === 'folder') {
                        item.data.accept = item.data.accept || item.parent().data.accept;
                    }
                }

                var configOption = Fangorn.Utils.resolveconfigOption.call(this, item, 'resolveRows', [item]);
                return configOption || defaultColumns;
            },
            lazyLoadOnLoad: function(tree, event) {
                if (tree.data.provider === 'osfstorage' && tree.data.nodeId === window.contextVars.node.id) {
                    this.multiselected([tree]);
                }

                tree.children.forEach(function(item) {
                    limitContents(item);

                    if (viewModel.value() !== null) {
                        if (item.data.path === viewModel.value()) {
                            item.css = 'fangorn-selected';
                            item.data.nodeId = tree.data.nodeId;
                            viewModel.addFile(item);
                        }
                    }
                    Fangorn.Utils.inheritFromParent(item, tree);
                });
                Fangorn.Utils.resolveconfigOption.call(this, tree, 'lazyLoadOnLoad', [tree, event]);
                Fangorn.Utils.reapplyTooltips();

                if (tree.depth > 1) {
                    Fangorn.Utils.orderFolder.call(this, tree);
                }
            },
            links: false
        });
    filePicker = fw;
    fw.init().then(function() {
        viewModel.showUploader(false);
    });
    filesWidgetCleanUp.push(filePicker.fangornOpts.divID);
};

ko.bindingHandlers.osfUploader = {
    init: osfUploader
};

var uploaderCount = 0;
var Uploader = function(question) {

    var self = this;

    question.showUploader = ko.observable(false);
    question.uid = 'uploader_' + uploaderCount;
    uploaderCount++;
    self.selectedFiles = ko.observableArray(question.extra() || []);
    self.selectedFiles.subscribe(function(fileList) {
        $.each(fileList, function(idx, file) {
            if (file && !self.fileAlreadySelected(file)) {
                question.extra().push(file);
            }
        });
        question.value(question.formattedFileList());
    });
    self.fileWarn = ko.observable(true);

    self.UPLOAD_LANGUAGE = 'You may attach up to 5 files to this question. You may attach files that you already have ' +
        'in this OSF project, or upload a new file from your computer. Uploaded files will automatically be added to this project ' +
        'so that they can be registered.';

    self.addFile = function(file) {
        if(self.selectedFiles().length >= 5 && self.fileWarn()) {
            self.fileWarn(false);
            bootbox.alert({
                title: 'Too many files',
                message: 'You cannot attach more than 5 files to a question.',
                buttons: {
                    ok: {
                        label: 'Close',
                        className: 'btn-default'
                    }
                }
            }).css({ 'top': '35%' });
            return false;
        } else if(self.selectedFiles().length >= 5 && !self.fileWarn()) {
            return false;
        }
        if(self.fileAlreadySelected(file))
            return false;

        self.selectedFiles.push({
            data: file.data,
            selectedFileName: file.data.name,
            nodeId: file.data.nodeId,
            viewUrl: '/project/' + file.data.nodeId + '/files/osfstorage' + file.data.path,
            sha256: file.data.extra.hashes.sha256
        });
        return true;
    };

    self.fileAlreadySelected = function(file) {
        var selected = false;
        $.each(question.extra(), function(idx, alreadyFile) {
            if(alreadyFile.selectedFileName === file.data.name && alreadyFile.sha256 === file.data.extra.hashes.sha256){
                selected = true;
                return;
            }
        });
        return selected;
    };

    self.hasSelectedFile = ko.computed(function() {
        return question.extra().length !== 0;
    });
    self.unselectFile = function(fileToRemove) {

        var files = question.extra();

        for (var i = 0; i < files.length; i++) {
            var file = files[i];
            if(file.sha256 === fileToRemove.sha256) {
                self.selectedFiles.splice(i, 1);
                question.value(question.formattedFileList());
                break;
            }
        }
    };

    self.filePicker = null;

    self.preview = function() {
        var value = question.value();
        if (!value || value === NO_FILE || question.extra().length === 0) {
            return 'no file selected';
        }
        else {
            var files = question.extra();
            var elem = '';
            $.each(files, function(_, file) {
                elem += '' + $osf.htmlEscape(file.selectedFileName) + ' ' + '
';
            });
            return $(elem);
        }
    };

    $.extend(self, question);
};

var AuthorImport = function(data, $root, preview) {
    var self = this;
    self.question = data;

    /**
     * Makes ajax request for a project's contributors
     */
    self.makeContributorsRequest = function() {
        var contributorsUrl = window.contextVars.node.urls.api + 'get_contributors/';
        return $.getJSON(contributorsUrl);
    };
    /**
     * Returns the `user_fullname` of each contributor attached to a node.
     **/
    self.getContributors = function() {
        return self.makeContributorsRequest()
            .fail(function(xhr, status, error) {
                Raven.captureMessage('Could not GET contributors', {
                    extra: {
                        url: window.contextVars.node.urls.api + 'get_contributors/',
                        textStatus: status,
                        error: error
                    }
                });
                $osf.growl('Could not retrieve contributors.', osfLanguage.REFRESH_OR_SUPPORT);
            });
    };

    self.serializeContributors = function(contributors) {
        return $.map(contributors, function(c) {
            return c.fullname;
        }).join(', ');
    };
    self.makeContributorsRequest = function() {
        var self = this;
        var contributorsUrl = window.contextVars.node.urls.api + 'get_contributors/';
        return $.getJSON(contributorsUrl);
    };

    self.contributors = ko.observable([]);
    if (!preview) {
        self.getContributors().done(function(data) {
            self.question.value(self.serializeContributors(data.contributors));
        });
    }

    self.preview = function() {
        return self.value();
    };
    var callback = function(data) {
        self.question.value(self.serializeContributors(data.contributors));
    };

    if ($('#addContributors').length > 0) {
        ko.cleanNode($('#addContributors')[0]);
        var adder = new ContribAdder(
            '#addContributors',
            node.title,
            node.id,
            null,
            null,
            {async: true, callback: callback}
        );
    }

    $.extend(self, data);
};

module.exports = {
    AuthorImport: AuthorImport,
    Uploader: Uploader,
    osfUploader: osfUploader,
    limitContents: limitContents
};
<|endoftext|>


<commit_before>import React, { useState, useContext } from 'react';
import {
    Typography, ListItemText, Switch, Collapse, Button,
} from "@mui/material";
import {
    IconButton, Divider, MenuItem, ListItemIcon
} from "@mui/material";
import {
    Air, ExpandLess, ExpandMore, Thermostat, NavigateNext, NavigateBefore,
} from '@mui/icons-material';
import AppContext from "../../context/AppContext"

async function displayWeather(setWeatherPoint) {
    let lat = 0;
    let lon = 0;
    if (window.location.hash) {
        let spl = window.location.hash.split('/');
        if (spl.length > 1) {
            lon = parseFloat(spl[spl.length - 1]);
            lat = parseFloat(spl[spl.length - 2]);
        }
    }
    let data = { lat : lat, lon: lon }
    const response = await fetch(`${process.env.REACT_APP_WEATHER_API_SITE}/weather-api/point-info?lat=${data.lat}&lon=${data.lon}&week=false`, {
        method: 'GET',
        headers: { 'Content-Type': 'application/json' }
    });
    if (response.ok) {
        data.day = await response.json();
    }
    const responseWeek = await fetch(`/weather-api/point-info?lat=${data.lat}&lon=${data.lon}&week=true`, {
        method: 'GET',
        headers: { 'Content-Type': 'application/json' }
    });
    if (responseWeek.ok) {
        data.week = await responseWeek.json();
    }
    setWeatherPoint(data);
}

function formatWeatherDate(weatherDateObj) {
    let hours = (-(new Date().getTime() - weatherDateObj.getTime()) / 3600000).toFixed(0);
    let hourstr = "now"
    if (hours !== 0) {
        let day = 0;
        while (hours >=  24) {
            day++;
            hours -= 24;
        }
        if (day > 0) {
            if (day === 1) {
                hourstr = "+ " + day + " day ";
            } else {
                hourstr = "+ " + day + " days ";
            }
            hours = hours - hours % 3;
        } else if (hours > 0) {
            hourstr = "+";
        }
        if (hours > 0) {
            hourstr +=  hours + " hours";
        } else if (hours < 0) {
            hourstr = hours + " hours";
        }
    }
    let text = weatherDateObj.toDateString() + "  " + weatherDateObj.getHours() + ":00 [" + hourstr + "]";
    return text;
}

function updateTextLayer(ctx, dt) {
    ctx.setAppText(formatWeatherDate(dt));
}

const addWeatherHours = (ctx, hours) => () => {
    let dt = new Date(ctx.weatherDate.getTime() + (hours * 60 * 60 * 1000));
    ctx.setWeatherDate(dt);
    updateTextLayer(ctx, dt);
}

const switchLayer = (ctx, index) => (e) => {
    let newlayers = [...ctx.weatherLayers];
    newlayers[index].checked = e.target.checked;
    ctx.updateWeatherLayers(newlayers);
    updateTextLayer(ctx, ctx.weatherDate);
}

export default function Weather() {
    const ctx = useContext(AppContext);
    let hours = (-(new Date().getTime() - ctx.weatherDate.getTime()) / 3600000).toFixed(0);
    let utcHours = new Date().getUTCHours();
    let gmt30Hours = 24 - (utcHours % 3); // here we need to align to GMT hours
    const [weatherOpen, setWeatherOpen] = useState(false);
    return <>
        <MenuItem sx={{ mb: 1 }} onClick={() => {
                setWeatherOpen(!weatherOpen);
                if (!weatherOpen) {
                    updateTextLayer(ctx, ctx.weatherDate);
                }
            }}>
            <ListItemIcon>
                <Air fontSize="small" />
            </ListItemIcon>
            <ListItemText>Weather</ListItemText>
            {weatherOpen ? <ExpandLess /> : <ExpandMore />}
        </MenuItem>

        <Collapse in={weatherOpen} timeout="auto" unmountOnExit>
            {ctx.weatherLayers.map((item, index) => (
                <MenuItem key={item.key} >
                    <ListItemIcon sx={{ ml: 2 }}>
                        {item.iconComponent ?
                            item.iconComponent :
                            <Thermostat fontSize="small" />
                        }
                    </ListItemIcon>
                    <ListItemText>{item.name}</ListItemText>
                    <Switch
                        checked={item.checked}
                        onChange={switchLayer(ctx, index)} />
                </MenuItem>
            ))}
            <MenuItem disableRipple={true}>
                <IconButton sx={{ ml: 1 }} onClick={addWeatherHours(ctx, hours > gmt30Hours ? -3 : -1)}>
                    <NavigateBefore />
                </IconButton>
                <Typography>{ctx.weatherDate.toLocaleDateString() + " " + ctx.weatherDate.getHours() + ":00"}</Typography>
                <IconButton onClick={addWeatherHours(ctx, hours >= gmt30Hours ? 3 : 1)} >
                    <NavigateNext />
                </IconButton>
            </MenuItem>
            <MenuItem>
                <Button variant="contained" component="span" sx={{ ml: 3 }}
                    onClick={() => displayWeather(ctx.setWeatherPoint)}>
                    Weather Forecast
                </Button>
            </MenuItem>
            <Divider />
        </Collapse>
    </>
};<commit_msg>Add cors configuration (localhost)<commit_after>import React, { useState, useContext } from 'react';
import {
    Typography, ListItemText, Switch, Collapse, Button,
} from "@mui/material";
import {
    IconButton, Divider, MenuItem, ListItemIcon
} from "@mui/material";
import {
    Air, ExpandLess, ExpandMore, Thermostat, NavigateNext, NavigateBefore,
} from '@mui/icons-material';
import AppContext from "../../context/AppContext"

async function displayWeather(setWeatherPoint) {
    let lat = 0;
    let lon = 0;
    if (window.location.hash) {
        let spl = window.location.hash.split('/');
        if (spl.length > 1) {
            lon = parseFloat(spl[spl.length - 1]);
            lat = parseFloat(spl[spl.length - 2]);
        }
    }
    let data = { lat : lat, lon: lon }
    const response = await fetch(`${process.env.REACT_APP_WEATHER_API_SITE}/weather-api/point-info?lat=${data.lat}&lon=${data.lon}&week=false`, {
        method: 'GET',
        headers: { 'Content-Type': 'application/json' }
    });
    if (response.ok) {
        data.day = await response.json();
    }
    const responseWeek = await fetch(`${process.env.REACT_APP_WEATHER_API_SITE}/weather-api/point-info?lat=${data.lat}&lon=${data.lon}&week=true`, {
        method: 'GET',
        headers: { 'Content-Type': 'application/json' }
    });
    if (responseWeek.ok) {
        data.week = await responseWeek.json();
    }
    setWeatherPoint(data);
}

function formatWeatherDate(weatherDateObj) {
    let hours = (-(new Date().getTime() - weatherDateObj.getTime()) / 3600000).toFixed(0);
    let hourstr = "now"
    if (hours !== 0) {
        let day = 0;
        while (hours >=  24) {
            day++;
            hours -= 24;
        }
        if (day > 0) {
            if (day === 1) {
                hourstr = "+ " + day + " day ";
            } else {
                hourstr = "+ " + day + " days ";
            }
            hours = hours - hours % 3;
        } else if (hours > 0) {
            hourstr = "+";
        }
        if (hours > 0) {
            hourstr +=  hours + " hours";
        } else if (hours < 0) {
            hourstr = hours + " hours";
        }
    }
    let text = weatherDateObj.toDateString() + "  " + weatherDateObj.getHours() + ":00 [" + hourstr + "]";
    return text;
}

function updateTextLayer(ctx, dt) {
    ctx.setAppText(formatWeatherDate(dt));
}

const addWeatherHours = (ctx, hours) => () => {
    let dt = new Date(ctx.weatherDate.getTime() + (hours * 60 * 60 * 1000));
    ctx.setWeatherDate(dt);
    updateTextLayer(ctx, dt);
}

const switchLayer = (ctx, index) => (e) => {
    let newlayers = [...ctx.weatherLayers];
    newlayers[index].checked = e.target.checked;
    ctx.updateWeatherLayers(newlayers);
    updateTextLayer(ctx, ctx.weatherDate);
}

export default function Weather() {
    const ctx = useContext(AppContext);
    let hours = (-(new Date().getTime() - ctx.weatherDate.getTime()) / 3600000).toFixed(0);
    let utcHours = new Date().getUTCHours();
    let gmt30Hours = 24 - (utcHours % 3); // here we need to align to GMT hours
    const [weatherOpen, setWeatherOpen] = useState(false);
    return <>
        <MenuItem sx={{ mb: 1 }} onClick={() => {
                setWeatherOpen(!weatherOpen);
                if (!weatherOpen) {
                    updateTextLayer(ctx, ctx.weatherDate);
                }
            }}>
            <ListItemIcon>
                <Air fontSize="small" />
            </ListItemIcon>
            <ListItemText>Weather</ListItemText>
            {weatherOpen ? <ExpandLess /> : <ExpandMore />}
        </MenuItem>

        <Collapse in={weatherOpen} timeout="auto" unmountOnExit>
            {ctx.weatherLayers.map((item, index) => (
                <MenuItem key={item.key} >
                    <ListItemIcon sx={{ ml: 2 }}>
                        {item.iconComponent ?
                            item.iconComponent :
                            <Thermostat fontSize="small" />
                        }
                    </ListItemIcon>
                    <ListItemText>{item.name}</ListItemText>
                    <Switch
                        checked={item.checked}
                        onChange={switchLayer(ctx, index)} />
                </MenuItem>
            ))}
            <MenuItem disableRipple={true}>
                <IconButton sx={{ ml: 1 }} onClick={addWeatherHours(ctx, hours > gmt30Hours ? -3 : -1)}>
                    <NavigateBefore />
                </IconButton>
                <Typography>{ctx.weatherDate.toLocaleDateString() + " " + ctx.weatherDate.getHours() + ":00"}</Typography>
                <IconButton onClick={addWeatherHours(ctx, hours >= gmt30Hours ? 3 : 1)} >
                    <NavigateNext />
                </IconButton>
            </MenuItem>
            <MenuItem>
                <Button variant="contained" component="span" sx={{ ml: 3 }}
                    onClick={() => displayWeather(ctx.setWeatherPoint)}>
                    Weather Forecast
                </Button>
            </MenuItem>
            <Divider />
        </Collapse>
    </>
};<|endoftext|>


<commit_before>$(document).ready(function() {
    $('#content-title')
        .append(`<strong title="Presióname" id="average">Promedio: Presiona Aquí</strong>`)
    $('#average')
        .css('float', 'right')
        .click(getAverage)
})

function getAverage(e) {
    e.preventDefault()
    let sum = 0,
        average = 0,
        cells = $('tr.trKardexGris td:nth-child(4)')
    try {
        cells.each(function() {
            sum += Number.parseFloat($(this).text())
        })
    } catch (ex) {
        alert('Error: No se pudo calcular el promedio')
        console.log(ex);
        return;
    }

    average = sum / cells.length
    $('#average').text(`Promedio: ${average.toFixed(2)}`)
}
<commit_msg>Catch error if sum/cells.length equals 0<commit_after>$(document).ready(function() {
  $('#content-title')
    .append(`<strong title="Presióname" id="average">Promedio: Presiona Aquí</strong>`)
  $('#average')
    .css('float', 'right')
    .click(getAverage)
})

function getAverage(e) {
  e.preventDefault()
  let sum = 0,
      average = 0,
      cells = $('tr.trKardexGris td:nth-child(4)')

  try {
    cells.each(function() {
        sum += Number.parseFloat($(this).text())
    })
    average = sum / cells.length
  } catch (ex) {
    alert('Error: No se pudo calcular el promedio')
    console.log(ex);
    return;
  }
  $('#average').text(`Promedio: ${average.toFixed(2)}`)
}
<|endoftext|>


<commit_before>var gulp = require('gulp'),
    wiredep = require('wiredep').stream,
    eventStream = require('event-stream'),
    gulpLoadPlugins = require('gulp-load-plugins'),
    map = require('vinyl-map'),
    fs = require('fs'),
    path = require('path'),
    size = require('gulp-size'),
    uri = require('urijs'),
    s = require('underscore.string'),
    argv = require('yargs').argv,
    logger = require('js-logger'),
    hawtio = require('hawtio-node-backend'),
    tslint = require('gulp-tslint'),
    tslintRules = require('./tslint.json');

var plugins = gulpLoadPlugins({});
var pkg = require('./package.json');

var config = {
  proxyPort: argv.port || 8181,
  targetPath: argv.path || '/hawtio/jolokia',
  logLevel: argv.debug ? logger.DEBUG : logger.INFO,
  main: '.',
  ts: ['plugins/**/*.ts'],
  testTs: ['test-plugins/**/*.ts'],
  less: './less/**/*.less',
  templates: ['plugins/**/*.html'],
  testTemplates: ['test-plugins/**/*.html'],
  templateModule: pkg.name + '-templates',
  testTemplateModule: pkg.name + '-test-templates',
  dist: './dist/',
  js: pkg.name + '.js',
  testJs: pkg.name + '-test.js',
  css: pkg.name + '.css',
  tsProject: plugins.typescript.createProject({
    target: 'ES5',
    module: 'commonjs',
    declarationFiles: true,
    noResolve: false,
    removeComments: true
  }),
  testTsProject: plugins.typescript.createProject({
    target: 'ES5',
    module: 'commonjs',
    declarationFiles: false,
    noResolve: false
  }),
  tsLintOptions: {
    rulesDirectory: './tslint-rules/'
  },
  sourceMap: argv.sourcemap
};

var normalSizeOptions = {
    showFiles: true
}, gZippedSizeOptions  = {
    showFiles: true,
    gzip: true
};

gulp.task('bower', function() {
  return gulp.src('index.html')
    .pipe(wiredep({}))
    .pipe(gulp.dest('.'));
});

/** Adjust the reference path of any typescript-built plugin this project depends on */
gulp.task('path-adjust', function() {
  return gulp.src('libs/**/includes.d.ts')
    .pipe(map(function(buf, filename) {
      var textContent = buf.toString();
      var newTextContent = textContent.replace(/"\.\.\/libs/gm, '"../../../libs');
      if (argv.debug) {
        console.log("Filename: ", filename, " old: ", textContent, " new: ", newTextContent);
      }
      return newTextContent;
    }))
    .pipe(gulp.dest('libs'));
});

gulp.task('clean-defs', function() {
  return gulp.src('defs.d.ts', { read: false })
    .pipe(plugins.clean());
});

gulp.task('example-tsc', ['tsc'], function() {
  var tsResult = gulp.src(config.testTs)
    .pipe(config.testTsProject())
    .on('error', plugins.notify.onError({
      message: '<%= error.message %>',
      title: 'Typescript compilation error - test'
    }));

    return tsResult.js
        .pipe(plugins.concat('test-compiled.js'))
        .pipe(gulp.dest('.'));
});

gulp.task('example-template', ['example-tsc'], function() {
  return gulp.src(config.testTemplates)
    .pipe(plugins.angularTemplatecache({
      filename: 'test-templates.js',
      root: 'test-plugins/',
      standalone: true,
      module: config.testTemplateModule,
      templateFooter: '}]); hawtioPluginLoader.addModule("' + config.testTemplateModule + '");'
    }))
    .pipe(gulp.dest('.'));
});

gulp.task('example-concat', ['example-template'], function() {
  return gulp.src(['test-compiled.js', 'test-templates.js'])
    .pipe(plugins.concat(config.testJs))
    .pipe(gulp.dest(config.dist));
});

gulp.task('example-clean', ['example-concat'], function() {
  return gulp.src(['test-templates.js', 'test-compiled.js'], { read: false })
    .pipe(plugins.clean());
});

gulp.task('tsc', ['clean-defs'], function() {
  var cwd = process.cwd();
  var tsResult = gulp.src(config.ts)
    .pipe(plugins.if(config.sourceMap, plugins.sourcemaps.init()))
    .pipe(config.tsProject())
    .on('error', plugins.notify.onError({
      message: '<%= error.message %>',
      title: 'Typescript compilation error'
    }));

  return eventStream.merge(
    tsResult.js
      .pipe(plugins.concat('compiled.js'))
      .pipe(plugins.if(config.sourceMap, plugins.sourcemaps.write()))
      .pipe(gulp.dest('.')),
    tsResult.dts
      .pipe(gulp.dest('d.ts')))
    .pipe(map(function(buf, filename) {
      if (!s.endsWith(filename, 'd.ts')) {
        return buf;
      }
      var relative = path.relative(cwd, filename);
      fs.appendFileSync('defs.d.ts', '/// <reference path="' + relative + '"/>\n');
      return buf;
    }));
});

/*
gulp.task('tslint', function(){
  gulp.src(config.ts)
    .pipe(tslint(config.tsLintOptions))
    .pipe(tslint.report('verbose'));
});

gulp.task('tslint-watch', function(){
  gulp.src(config.ts)
    .pipe(tslint(config.tsLintOptions))
    .pipe(tslint.report('prose', {
      emitError: false
    }));
});
*/

gulp.task('less', function() {
  return gulp.src(config.less)
    .pipe(plugins.less({
      paths: [ path.join(__dirname, 'less', 'includes') ]
    }))
    .pipe(plugins.concat(config.css))
    .pipe(gulp.dest('./dist'));
});

gulp.task('template', ['tsc'], function() {
  return gulp.src(config.templates)
    .pipe(plugins.angularTemplatecache({
      filename: 'templates.js',
      root: 'plugins/',
      standalone: true,
      module: config.templateModule,
      templateFooter: '}]); hawtioPluginLoader.addModule("' + config.templateModule + '");'
    }))
    .pipe(gulp.dest('.'));
});

gulp.task('concat', ['template'], function() {
  var gZipSize = size(gZippedSizeOptions);
  var license = tslintRules.rules['license-header'][1];
  return gulp.src(['compiled.js', 'templates.js'])
    .pipe(plugins.concat(config.js))
    .pipe(plugins.header(license))
    .pipe(size(normalSizeOptions))
    .pipe(gZipSize)
    .pipe(gulp.dest(config.dist));
});

gulp.task('clean', ['concat'], function() {
  return gulp.src(['templates.js', 'compiled.js'], { read: false })
    .pipe(plugins.clean());
});

gulp.task('watch', ['build', 'build-example'], function() {
  plugins.watch(['libs/**/*.js', 'libs/**/*.css', 'index.html', config.dist + '/' + config.js], function() {
    gulp.start('reload');
  });
  plugins.watch(['libs/**/*.d.ts', config.ts, config.templates], function() {
    gulp.start(['tsc', 'template', 'concat', 'clean']);
  });
  plugins.watch([config.testTs, config.testTemplates], function() {
    gulp.start(['example-tsc', 'example-template', 'example-concat', 'example-clean']);
  });
  plugins.watch(config.less, function() {
    gulp.start('less', 'reload');
  })
});

gulp.task('connect', ['watch'], function() {
  /*
   * Example of fetching a URL from the environment, in this case for kubernetes
  var kube = uri(process.env.KUBERNETES_MASTER || 'http://localhost:8080');
  console.log("Connecting to Kubernetes on: " + kube);
  */

  hawtio.setConfig({
    logLevel: config.logLevel,
    port: 2772,
    staticProxies: [
    {
      proto: 'http',
      port: config.proxyPort,
      hostname: 'localhost',
      path: '/hawtio/jolokia',
      targetPath: config.targetPath
    }
    /*
    // proxy to a service, in this case kubernetes
    {
      proto: kube.protocol(),
      port: kube.port(),
      hostname: kube.hostname(),
      path: '/services/kubernetes',
      targetPath: kube.path()
    },
    // proxy to a jolokia instance
    {
      proto: kube.protocol(),
      hostname: kube.hostname(),
      port: kube.port(),
      path: '/jolokia',
      targetPath: '/hawtio/jolokia'
    }
    */
    ],
    staticAssets: [{
      path: '/hawtio',
      dir: '.'

    }],
    fallback: 'index.html',
    liveReload: {
      enabled: true
    }
  });
  /*
   * Example middleware that returns a 404 for templates
   * as they're already embedded in the js
  hawtio.use('/', function(req, res, next) {
          var path = req.originalUrl;
          // avoid returning these files, they should get pulled from js
          if (s.startsWith(path, '/plugins/') && s.endsWith(path, 'html')) {
            console.log("returning 404 for: ", path);
            res.statusCode = 404;
            res.end();
          } else {
            console.log("allowing: ", path);
            next();
          }
        });
        */
  hawtio.listen(function(server) {
    var host = server.address().address;
    var port = server.address().port;
    console.log("started from gulp file at ", host, ":", port);
  });
});

gulp.task('reload', function() {
  gulp.src('.')
    .pipe(hawtio.reload());
});

gulp.task('site-fonts', function() {
  return gulp.src(['libs/**/*.woff', 'libs/**/*.woff2', 'libs/**/*.ttf'], { base: '.' })
    .pipe(plugins.flatten())
    .pipe(plugins.debug({title: 'site font files'}))
    .pipe(gulp.dest('target/site/fonts'));
});

gulp.task('tweak-open-sans', ['site-fonts'], function() {
  return gulp.src('target/site/fonts/OpenSans*')
    .pipe(plugins.flatten())
    .pipe(gulp.dest('target/site/fonts'));
});

gulp.task('tweak-droid-sans-mono', ['site-fonts'], function() {
  return gulp.src('target/site/fonts/DroidSansMono*')
    .pipe(plugins.flatten())
    .pipe(gulp.dest('target/site/fonts'));
});

gulp.task('site-files', ['tweak-open-sans', 'tweak-droid-sans-mono'], function() {
  return gulp.src(['images/**', 'img/**', 'libs/**/*.swf'], {base: '.'})
    .pipe(plugins.debug({title: 'site files'}))
    .pipe(gulp.dest('target/site'));
});

gulp.task('usemin', ['site-files'], function() {
  return gulp.src('index.html')
    .pipe(plugins.usemin({
      css: [plugins.cleanCss(), 'concat'],
      js: [plugins.sourcemaps.init({
            loadMaps: true
          }),
          'concat',
          plugins.uglify(),
          plugins.rev(),
          plugins.sourcemaps.write('./')]
    }))
    .pipe(plugins.debug({title: 'usemin'}))
    .pipe(gulp.dest('target/site'));
});

gulp.task('site', ['usemin'], function() {
  gulp.src('target/site/index.html')
    .pipe(plugins.rename('404.html'))
    .pipe(gulp.dest('target/site'));
  gulp.src(['img/**'], { base: '.' })
    .pipe(gulp.dest('target/site'));
  var dirs = fs.readdirSync('./libs');
  var patterns = [];
  dirs.forEach(function(dir) {
    var path = './libs/' + dir + "/img";
    try {
      if (fs.statSync(path).isDirectory()) {
        console.log("found image dir: " + path);
        var pattern = 'libs/' + dir + "/img/**";
        patterns.push(pattern);
      }
    } catch (e) {
      // ignore, file does not exist
    }
  });
  return gulp.src(patterns).pipe(plugins.debug({ title: 'img-copy' })).pipe(gulp.dest('target/site/img'));
});

gulp.task('mvn', ['build', 'site']);

gulp.task('build', ['bower', 'path-adjust', 'tsc', 'less', 'template', 'concat', 'clean']);

gulp.task('build-example', ['example-tsc', 'example-template', 'example-concat', 'example-clean']);

gulp.task('default', ['connect']);

<commit_msg>Make 'gulp connect' in hawtio-console-assembly redirect from '/' to '/hawtio/'<commit_after>var gulp = require('gulp'),
    wiredep = require('wiredep').stream,
    eventStream = require('event-stream'),
    gulpLoadPlugins = require('gulp-load-plugins'),
    map = require('vinyl-map'),
    fs = require('fs'),
    path = require('path'),
    size = require('gulp-size'),
    uri = require('urijs'),
    s = require('underscore.string'),
    argv = require('yargs').argv,
    logger = require('js-logger'),
    hawtio = require('hawtio-node-backend'),
    tslint = require('gulp-tslint'),
    tslintRules = require('./tslint.json');

var plugins = gulpLoadPlugins({});
var pkg = require('./package.json');

var config = {
  proxyPort: argv.port || 8181,
  targetPath: argv.path || '/hawtio/jolokia',
  logLevel: argv.debug ? logger.DEBUG : logger.INFO,
  main: '.',
  ts: ['plugins/**/*.ts'],
  testTs: ['test-plugins/**/*.ts'],
  less: './less/**/*.less',
  templates: ['plugins/**/*.html'],
  testTemplates: ['test-plugins/**/*.html'],
  templateModule: pkg.name + '-templates',
  testTemplateModule: pkg.name + '-test-templates',
  dist: './dist/',
  js: pkg.name + '.js',
  testJs: pkg.name + '-test.js',
  css: pkg.name + '.css',
  tsProject: plugins.typescript.createProject({
    target: 'ES5',
    module: 'commonjs',
    declarationFiles: true,
    noResolve: false,
    removeComments: true
  }),
  testTsProject: plugins.typescript.createProject({
    target: 'ES5',
    module: 'commonjs',
    declarationFiles: false,
    noResolve: false
  }),
  tsLintOptions: {
    rulesDirectory: './tslint-rules/'
  },
  sourceMap: argv.sourcemap
};

var normalSizeOptions = {
    showFiles: true
}, gZippedSizeOptions  = {
    showFiles: true,
    gzip: true
};

gulp.task('bower', function() {
  return gulp.src('index.html')
    .pipe(wiredep({}))
    .pipe(gulp.dest('.'));
});

/** Adjust the reference path of any typescript-built plugin this project depends on */
gulp.task('path-adjust', function() {
  return gulp.src('libs/**/includes.d.ts')
    .pipe(map(function(buf, filename) {
      var textContent = buf.toString();
      var newTextContent = textContent.replace(/"\.\.\/libs/gm, '"../../../libs');
      if (argv.debug) {
        console.log("Filename: ", filename, " old: ", textContent, " new: ", newTextContent);
      }
      return newTextContent;
    }))
    .pipe(gulp.dest('libs'));
});

gulp.task('clean-defs', function() {
  return gulp.src('defs.d.ts', { read: false })
    .pipe(plugins.clean());
});

gulp.task('example-tsc', ['tsc'], function() {
  var tsResult = gulp.src(config.testTs)
    .pipe(config.testTsProject())
    .on('error', plugins.notify.onError({
      message: '<%= error.message %>',
      title: 'Typescript compilation error - test'
    }));

    return tsResult.js
        .pipe(plugins.concat('test-compiled.js'))
        .pipe(gulp.dest('.'));
});

gulp.task('example-template', ['example-tsc'], function() {
  return gulp.src(config.testTemplates)
    .pipe(plugins.angularTemplatecache({
      filename: 'test-templates.js',
      root: 'test-plugins/',
      standalone: true,
      module: config.testTemplateModule,
      templateFooter: '}]); hawtioPluginLoader.addModule("' + config.testTemplateModule + '");'
    }))
    .pipe(gulp.dest('.'));
});

gulp.task('example-concat', ['example-template'], function() {
  return gulp.src(['test-compiled.js', 'test-templates.js'])
    .pipe(plugins.concat(config.testJs))
    .pipe(gulp.dest(config.dist));
});

gulp.task('example-clean', ['example-concat'], function() {
  return gulp.src(['test-templates.js', 'test-compiled.js'], { read: false })
    .pipe(plugins.clean());
});

gulp.task('tsc', ['clean-defs'], function() {
  var cwd = process.cwd();
  var tsResult = gulp.src(config.ts)
    .pipe(plugins.if(config.sourceMap, plugins.sourcemaps.init()))
    .pipe(config.tsProject())
    .on('error', plugins.notify.onError({
      message: '<%= error.message %>',
      title: 'Typescript compilation error'
    }));

  return eventStream.merge(
    tsResult.js
      .pipe(plugins.concat('compiled.js'))
      .pipe(plugins.if(config.sourceMap, plugins.sourcemaps.write()))
      .pipe(gulp.dest('.')),
    tsResult.dts
      .pipe(gulp.dest('d.ts')))
    .pipe(map(function(buf, filename) {
      if (!s.endsWith(filename, 'd.ts')) {
        return buf;
      }
      var relative = path.relative(cwd, filename);
      fs.appendFileSync('defs.d.ts', '/// <reference path="' + relative + '"/>\n');
      return buf;
    }));
});

/*
gulp.task('tslint', function(){
  gulp.src(config.ts)
    .pipe(tslint(config.tsLintOptions))
    .pipe(tslint.report('verbose'));
});

gulp.task('tslint-watch', function(){
  gulp.src(config.ts)
    .pipe(tslint(config.tsLintOptions))
    .pipe(tslint.report('prose', {
      emitError: false
    }));
});
*/

gulp.task('less', function() {
  return gulp.src(config.less)
    .pipe(plugins.less({
      paths: [ path.join(__dirname, 'less', 'includes') ]
    }))
    .pipe(plugins.concat(config.css))
    .pipe(gulp.dest('./dist'));
});

gulp.task('template', ['tsc'], function() {
  return gulp.src(config.templates)
    .pipe(plugins.angularTemplatecache({
      filename: 'templates.js',
      root: 'plugins/',
      standalone: true,
      module: config.templateModule,
      templateFooter: '}]); hawtioPluginLoader.addModule("' + config.templateModule + '");'
    }))
    .pipe(gulp.dest('.'));
});

gulp.task('concat', ['template'], function() {
  var gZipSize = size(gZippedSizeOptions);
  var license = tslintRules.rules['license-header'][1];
  return gulp.src(['compiled.js', 'templates.js'])
    .pipe(plugins.concat(config.js))
    .pipe(plugins.header(license))
    .pipe(size(normalSizeOptions))
    .pipe(gZipSize)
    .pipe(gulp.dest(config.dist));
});

gulp.task('clean', ['concat'], function() {
  return gulp.src(['templates.js', 'compiled.js'], { read: false })
    .pipe(plugins.clean());
});

gulp.task('watch', ['build', 'build-example'], function() {
  plugins.watch(['libs/**/*.js', 'libs/**/*.css', 'index.html', config.dist + '/' + config.js], function() {
    gulp.start('reload');
  });
  plugins.watch(['libs/**/*.d.ts', config.ts, config.templates], function() {
    gulp.start(['tsc', 'template', 'concat', 'clean']);
  });
  plugins.watch([config.testTs, config.testTemplates], function() {
    gulp.start(['example-tsc', 'example-template', 'example-concat', 'example-clean']);
  });
  plugins.watch(config.less, function() {
    gulp.start('less', 'reload');
  })
});

gulp.task('connect', ['watch'], function() {
  /*
   * Example of fetching a URL from the environment, in this case for kubernetes
  var kube = uri(process.env.KUBERNETES_MASTER || 'http://localhost:8080');
  console.log("Connecting to Kubernetes on: " + kube);
  */

  hawtio.setConfig({
    logLevel: config.logLevel,
    port: 2772,
    staticProxies: [
    {
      proto: 'http',
      port: config.proxyPort,
      hostname: 'localhost',
      path: '/hawtio/jolokia',
      targetPath: config.targetPath
    }
    /*
    // proxy to a service, in this case kubernetes
    {
      proto: kube.protocol(),
      port: kube.port(),
      hostname: kube.hostname(),
      path: '/services/kubernetes',
      targetPath: kube.path()
    },
    // proxy to a jolokia instance
    {
      proto: kube.protocol(),
      hostname: kube.hostname(),
      port: kube.port(),
      path: '/jolokia',
      targetPath: '/hawtio/jolokia'
    }
    */
    ],
    staticAssets: [{
      path: '/hawtio',
      dir: '.'

    }],
    fallback: 'index.html',
    liveReload: {
      enabled: true
    }
  });
  hawtio.use('/', function(req, res, next) {
    var path = req.originalUrl;
    if (!s.startsWith(path, '/hawtio/')) {
      res.redirect('/hawtio/');
    } else {
      next();
    }
  });
  /*
   * Example middleware that returns a 404 for templates
   * as they're already embedded in the js
  hawtio.use('/', function(req, res, next) {
          var path = req.originalUrl;
          // avoid returning these files, they should get pulled from js
          if (s.startsWith(path, '/plugins/') && s.endsWith(path, 'html')) {
            console.log("returning 404 for: ", path);
            res.statusCode = 404;
            res.end();
          } else {
            console.log("allowing: ", path);
            next();
          }
        });
        */
  hawtio.listen(function(server) {
    var host = server.address().address;
    var port = server.address().port;
    console.log("started from gulp file at ", host, ":", port);
  });
});

gulp.task('reload', function() {
  gulp.src('.')
    .pipe(hawtio.reload());
});

gulp.task('site-fonts', function() {
  return gulp.src(['libs/**/*.woff', 'libs/**/*.woff2', 'libs/**/*.ttf'], { base: '.' })
    .pipe(plugins.flatten())
    .pipe(plugins.debug({title: 'site font files'}))
    .pipe(gulp.dest('target/site/fonts'));
});

gulp.task('tweak-open-sans', ['site-fonts'], function() {
  return gulp.src('target/site/fonts/OpenSans*')
    .pipe(plugins.flatten())
    .pipe(gulp.dest('target/site/fonts'));
});

gulp.task('tweak-droid-sans-mono', ['site-fonts'], function() {
  return gulp.src('target/site/fonts/DroidSansMono*')
    .pipe(plugins.flatten())
    .pipe(gulp.dest('target/site/fonts'));
});

gulp.task('site-files', ['tweak-open-sans', 'tweak-droid-sans-mono'], function() {
  return gulp.src(['images/**', 'img/**', 'libs/**/*.swf'], {base: '.'})
    .pipe(plugins.debug({title: 'site files'}))
    .pipe(gulp.dest('target/site'));
});

gulp.task('usemin', ['site-files'], function() {
  return gulp.src('index.html')
    .pipe(plugins.usemin({
      css: [plugins.cleanCss(), 'concat'],
      js: [plugins.sourcemaps.init({
            loadMaps: true
          }),
          'concat',
          plugins.uglify(),
          plugins.rev(),
          plugins.sourcemaps.write('./')]
    }))
    .pipe(plugins.debug({title: 'usemin'}))
    .pipe(gulp.dest('target/site'));
});

gulp.task('site', ['usemin'], function() {
  gulp.src('target/site/index.html')
    .pipe(plugins.rename('404.html'))
    .pipe(gulp.dest('target/site'));
  gulp.src(['img/**'], { base: '.' })
    .pipe(gulp.dest('target/site'));
  var dirs = fs.readdirSync('./libs');
  var patterns = [];
  dirs.forEach(function(dir) {
    var path = './libs/' + dir + "/img";
    try {
      if (fs.statSync(path).isDirectory()) {
        console.log("found image dir: " + path);
        var pattern = 'libs/' + dir + "/img/**";
        patterns.push(pattern);
      }
    } catch (e) {
      // ignore, file does not exist
    }
  });
  return gulp.src(patterns).pipe(plugins.debug({ title: 'img-copy' })).pipe(gulp.dest('target/site/img'));
});

gulp.task('mvn', ['build', 'site']);

gulp.task('build', ['bower', 'path-adjust', 'tsc', 'less', 'template', 'concat', 'clean']);

gulp.task('build-example', ['example-tsc', 'example-template', 'example-concat', 'example-clean']);

gulp.task('default', ['connect']);

<|endoftext|>