<commit_before>const test = require('ava');
const _ = require('lodash');

const {
  mapFromActionObject,
  mapFromStateObject,
  mapToActionObject,
  mapToStateObject,
  buildStateObjectFromResponse,
  mapFromHueResponseObject
} = require('./maps');
const convert = require('./convert');

const baseTestAction = {
  on: true,
  bri: 254,
  hue: 34849,
  sat: 193,
  effect: 'none',
  xy: [0.323, 0.3278],
  ct: 167,
  alert: 'none'
};

const baseTestState = _.assign({}, baseTestAction, { reachable: true });

test('mapFromActionObject works in colorloop mode', t => {
  const colorLoopTestAction = _.assign({}, baseTestAction, {
    effect: 'colorloop'
  });
  const result = mapFromActionObject(colorLoopTestAction);

  t.is(result.colorloop, true);
  t.is(result.on, colorLoopTestAction.on);
});

test('mapFromActionObject works in ct mode', t => {
  const ctTestAction = _.assign({}, baseTestAction, { colormode: 'ct' });
  const result = mapFromActionObject(ctTestAction);

  t.is(result.colorTemp, convert.miredToTemp(ctTestAction.ct));
  t.is(result.on, ctTestAction.on);
});

test('mapFromActionObject works in hs mode', t => {
  const hsTestAction = _.assign({}, baseTestAction, { colormode: 'hs' });
  const result = mapFromActionObject(hsTestAction);

  t.is(
    result.color,
    convert.hueToRgbString([
      hsTestAction.hue,
      hsTestAction.sat,
      hsTestAction.bri
    ])
  );
  t.is(result.on, hsTestAction.on);
});

test('mapFromActionObject works in xy mode', t => {
  const xyTestAction = _.assign({}, baseTestAction, { colormode: 'xy' });
  const result = mapFromActionObject(xyTestAction);

  t.is(
    result.color,
    convert.hueToRgbString([
      xyTestAction.hue,
      xyTestAction.sat,
      xyTestAction.bri
    ])
  );
  t.is(result.on, xyTestAction.on);
});

test('mapFromActionObject acts as a passthrough when no interesting properties are found', t => {
  const passTestAction = {
    on: true,
    foo: 'bar'
  };
  const result = mapFromActionObject(passTestAction);

  t.is(result.foo, passTestAction.foo);
  t.is(result.on, passTestAction.on);
});

test('mapFromStateObject works in colorloop mode', t => {
  const colorLoopTestState = _.assign({}, baseTestState, {
    effect: 'colorloop'
  });
  const result = mapFromStateObject(colorLoopTestState);

  t.is(result.colorloop, true);
  t.is(result.on, colorLoopTestState.on);
  t.is(result.reachable, colorLoopTestState.reachable);
});

test('mapFromStateObject works in ct mode', t => {
  const ctTestState = _.assign({}, baseTestState, { colormode: 'ct' });
  const result = mapFromStateObject(ctTestState);

  t.is(result.colorTemp, convert.miredToTemp(ctTestState.ct));
  t.is(result.on, ctTestState.on);
  t.is(result.reachable, ctTestState.reachable);
});

test('mapFromStateObject works in hs mode', t => {
  const hsTestState = _.assign({}, baseTestState, { colormode: 'hs' });
  const result = mapFromStateObject(hsTestState);

  t.is(
    result.color,
    convert.hueToRgbString([hsTestState.hue, hsTestState.sat, hsTestState.bri])
  );
  t.is(result.on, hsTestState.on);
  t.is(result.reachable, hsTestState.reachable);
});

test('mapFromStateObject works in xy mode', t => {
  const xyTestState = _.assign({}, baseTestState, { colormode: 'xy' });
  const result = mapFromStateObject(xyTestState);

  t.is(
    result.color,
    convert.hueToRgbString([xyTestState.hue, xyTestState.sat, xyTestState.bri])
  );
  t.is(result.on, xyTestState.on);
  t.is(result.reachable, xyTestState.reachable);
});

test('mapFromStateObject acts as a passthrough when no interesting properties are found', t => {
  const passTestState = {
    on: true,
    foo: 'bar'
  };
  const result = mapFromStateObject(passTestState);

  t.is(result.foo, passTestState.foo);
  t.is(result.on, passTestState.on);
});

test('mapToActionObject maps off requests correctly', t => {
  t.false(mapToActionObject({ on: false }).on);
  t.pass(mapToActionObject({}).on === undefined);
});

test('mapToActionObject maps on requests correctly', t => {
  t.true(mapToActionObject({ on: true }).on);
});

test('mapToActionObject maps color requests correctly', t => {
  const testState = {
    on: true,
    color: '#00ff00'
  };
  const result = mapToActionObject(testState);

  t.true(result.on);
  t.is(result.hue, 21845);
  t.is(result.sat, 254);
  t.is(result.bri, 254);
  t.is(result.effect, 'none');
});

test('mapToActionObject maps colorTemp requests correctly', t => {
  const testState = {
    on: true,
    colorTemp: 5800
  };
  const result = mapToActionObject(testState);

  t.true(result.on);
  t.is(result.ct, 172);
  t.is(result.effect, 'none');
});

test('mapToActionObject maps colorloop requests correctly', t => {
  const testState = {
    on: true,
    colorloop: true
  };
  const result = mapToActionObject(testState);

  t.true(result.on);
  t.is(result.effect, 'colorloop');
});

test('mapToActionObject maps color without on requests correctly', t => {
  const testState = { color: '#00ffff' };
  const result = mapToActionObject(testState);

  t.true(result.on === undefined);
  t.is(result.hue, 32768);
  t.is(result.sat, 254);
  t.is(result.bri, 254);
  t.is(result.effect, 'none');
});

test('mapToActionObject maps colorTemp without on requests correctly', t => {
  const testState = { colorTemp: 5800 };
  const result = mapToActionObject(testState);

  t.true(result.on === undefined);
  t.is(result.ct, 172);
  t.is(result.effect, 'none');
});

test('mapToActionObject maps colorloop without on requests correctly', t => {
  const testState = { colorloop: true };
  const result = mapToActionObject(testState);

  t.true(result.on === undefined);
  t.is(result.effect, 'colorloop');
});

test('mapToStateObject does the same stuff as mapToActionObject', t => {
  const testState = {
    on: true,
    color: '#ffff00'
  };

  t.deepEqual(mapToActionObject(testState), mapToStateObject(testState));
});

test('buildStateObjectFromResponse builds state from one property', t => {
  const input = { 'lights/1/state/on': true };

  const output = buildStateObjectFromResponse(input);

  t.is(output.lights['1'].state.on, true);
});

test('buildStateObjectFromResponse builds state from multiple properties', t => {
  const input = {
    'lights/1/state/on': true,
    'lights/2/state/on': true,
    'lights/2/state/effect': 'none'
  };

  const output = buildStateObjectFromResponse(input);

  t.is(output.lights['1'].state.on, true);
  t.is(output.lights['2'].state.on, true);
  t.is(output.lights['2'].state.effect, 'none');
});

test('buildStateObjectFromResponse accounts for different datatypes', t => {
  const input = {
    'lights/2/state/on': true,
    'lights/2/state/ct': 213,
    'lights/2/state/effect': 'none'
  };

  const output = buildStateObjectFromResponse(input);

  t.is(output.lights['2'].state.on, true);
  t.is(output.lights['2'].state.ct, 213);
  t.is(output.lights['2'].state.effect, 'none');
});

test('buildStateObjectFromResponse handles an empty response', t => {
  const input = {};

  const output = buildStateObjectFromResponse(input);

  t.is(Object.keys(output).length, 0);
});

test('mapFromHueResponseObject handles a single POST response', t => {
  const input = [{ success: { id: 'groups/2' } }];

  const output = mapFromHueResponseObject(input);

  t.deepEqual(output.created, ['groups/2']);
});

test('mapFromHueResponseObject handles multiple POST responses', t => {
  const ids = ['groups/2', 'lights/7', 'schedules/1'];
  const input = ids.map(id => ({ success: { id } }));

  const output = mapFromHueResponseObject(input);

  t.deepEqual(output.created, ids);
});
<commit_msg>added some tests for delete response handling<commit_after>const test = require('ava');
const _ = require('lodash');

const {
  mapFromActionObject,
  mapFromStateObject,
  mapToActionObject,
  mapToStateObject,
  buildStateObjectFromResponse,
  mapFromHueResponseObject
} = require('./maps');
const convert = require('./convert');

const baseTestAction = {
  on: true,
  bri: 254,
  hue: 34849,
  sat: 193,
  effect: 'none',
  xy: [0.323, 0.3278],
  ct: 167,
  alert: 'none'
};

const baseTestState = _.assign({}, baseTestAction, { reachable: true });

test('mapFromActionObject works in colorloop mode', t => {
  const colorLoopTestAction = _.assign({}, baseTestAction, {
    effect: 'colorloop'
  });
  const result = mapFromActionObject(colorLoopTestAction);

  t.is(result.colorloop, true);
  t.is(result.on, colorLoopTestAction.on);
});

test('mapFromActionObject works in ct mode', t => {
  const ctTestAction = _.assign({}, baseTestAction, { colormode: 'ct' });
  const result = mapFromActionObject(ctTestAction);

  t.is(result.colorTemp, convert.miredToTemp(ctTestAction.ct));
  t.is(result.on, ctTestAction.on);
});

test('mapFromActionObject works in hs mode', t => {
  const hsTestAction = _.assign({}, baseTestAction, { colormode: 'hs' });
  const result = mapFromActionObject(hsTestAction);

  t.is(
    result.color,
    convert.hueToRgbString([
      hsTestAction.hue,
      hsTestAction.sat,
      hsTestAction.bri
    ])
  );
  t.is(result.on, hsTestAction.on);
});

test('mapFromActionObject works in xy mode', t => {
  const xyTestAction = _.assign({}, baseTestAction, { colormode: 'xy' });
  const result = mapFromActionObject(xyTestAction);

  t.is(
    result.color,
    convert.hueToRgbString([
      xyTestAction.hue,
      xyTestAction.sat,
      xyTestAction.bri
    ])
  );
  t.is(result.on, xyTestAction.on);
});

test('mapFromActionObject acts as a passthrough when no interesting properties are found', t => {
  const passTestAction = {
    on: true,
    foo: 'bar'
  };
  const result = mapFromActionObject(passTestAction);

  t.is(result.foo, passTestAction.foo);
  t.is(result.on, passTestAction.on);
});

test('mapFromStateObject works in colorloop mode', t => {
  const colorLoopTestState = _.assign({}, baseTestState, {
    effect: 'colorloop'
  });
  const result = mapFromStateObject(colorLoopTestState);

  t.is(result.colorloop, true);
  t.is(result.on, colorLoopTestState.on);
  t.is(result.reachable, colorLoopTestState.reachable);
});

test('mapFromStateObject works in ct mode', t => {
  const ctTestState = _.assign({}, baseTestState, { colormode: 'ct' });
  const result = mapFromStateObject(ctTestState);

  t.is(result.colorTemp, convert.miredToTemp(ctTestState.ct));
  t.is(result.on, ctTestState.on);
  t.is(result.reachable, ctTestState.reachable);
});

test('mapFromStateObject works in hs mode', t => {
  const hsTestState = _.assign({}, baseTestState, { colormode: 'hs' });
  const result = mapFromStateObject(hsTestState);

  t.is(
    result.color,
    convert.hueToRgbString([hsTestState.hue, hsTestState.sat, hsTestState.bri])
  );
  t.is(result.on, hsTestState.on);
  t.is(result.reachable, hsTestState.reachable);
});

test('mapFromStateObject works in xy mode', t => {
  const xyTestState = _.assign({}, baseTestState, { colormode: 'xy' });
  const result = mapFromStateObject(xyTestState);

  t.is(
    result.color,
    convert.hueToRgbString([xyTestState.hue, xyTestState.sat, xyTestState.bri])
  );
  t.is(result.on, xyTestState.on);
  t.is(result.reachable, xyTestState.reachable);
});

test('mapFromStateObject acts as a passthrough when no interesting properties are found', t => {
  const passTestState = {
    on: true,
    foo: 'bar'
  };
  const result = mapFromStateObject(passTestState);

  t.is(result.foo, passTestState.foo);
  t.is(result.on, passTestState.on);
});

test('mapToActionObject maps off requests correctly', t => {
  t.false(mapToActionObject({ on: false }).on);
  t.pass(mapToActionObject({}).on === undefined);
});

test('mapToActionObject maps on requests correctly', t => {
  t.true(mapToActionObject({ on: true }).on);
});

test('mapToActionObject maps color requests correctly', t => {
  const testState = {
    on: true,
    color: '#00ff00'
  };
  const result = mapToActionObject(testState);

  t.true(result.on);
  t.is(result.hue, 21845);
  t.is(result.sat, 254);
  t.is(result.bri, 254);
  t.is(result.effect, 'none');
});

test('mapToActionObject maps colorTemp requests correctly', t => {
  const testState = {
    on: true,
    colorTemp: 5800
  };
  const result = mapToActionObject(testState);

  t.true(result.on);
  t.is(result.ct, 172);
  t.is(result.effect, 'none');
});

test('mapToActionObject maps colorloop requests correctly', t => {
  const testState = {
    on: true,
    colorloop: true
  };
  const result = mapToActionObject(testState);

  t.true(result.on);
  t.is(result.effect, 'colorloop');
});

test('mapToActionObject maps color without on requests correctly', t => {
  const testState = { color: '#00ffff' };
  const result = mapToActionObject(testState);

  t.true(result.on === undefined);
  t.is(result.hue, 32768);
  t.is(result.sat, 254);
  t.is(result.bri, 254);
  t.is(result.effect, 'none');
});

test('mapToActionObject maps colorTemp without on requests correctly', t => {
  const testState = { colorTemp: 5800 };
  const result = mapToActionObject(testState);

  t.true(result.on === undefined);
  t.is(result.ct, 172);
  t.is(result.effect, 'none');
});

test('mapToActionObject maps colorloop without on requests correctly', t => {
  const testState = { colorloop: true };
  const result = mapToActionObject(testState);

  t.true(result.on === undefined);
  t.is(result.effect, 'colorloop');
});

test('mapToStateObject does the same stuff as mapToActionObject', t => {
  const testState = {
    on: true,
    color: '#ffff00'
  };

  t.deepEqual(mapToActionObject(testState), mapToStateObject(testState));
});

test('buildStateObjectFromResponse builds state from one property', t => {
  const input = { 'lights/1/state/on': true };

  const output = buildStateObjectFromResponse(input);

  t.is(output.lights['1'].state.on, true);
});

test('buildStateObjectFromResponse builds state from multiple properties', t => {
  const input = {
    'lights/1/state/on': true,
    'lights/2/state/on': true,
    'lights/2/state/effect': 'none'
  };

  const output = buildStateObjectFromResponse(input);

  t.is(output.lights['1'].state.on, true);
  t.is(output.lights['2'].state.on, true);
  t.is(output.lights['2'].state.effect, 'none');
});

test('buildStateObjectFromResponse accounts for different datatypes', t => {
  const input = {
    'lights/2/state/on': true,
    'lights/2/state/ct': 213,
    'lights/2/state/effect': 'none'
  };

  const output = buildStateObjectFromResponse(input);

  t.is(output.lights['2'].state.on, true);
  t.is(output.lights['2'].state.ct, 213);
  t.is(output.lights['2'].state.effect, 'none');
});

test('buildStateObjectFromResponse handles an empty response', t => {
  const input = {};

  const output = buildStateObjectFromResponse(input);

  t.is(Object.keys(output).length, 0);
});

test('mapFromHueResponseObject handles a single POST response', t => {
  const input = [{ success: { id: 'groups/2' } }];

  const output = mapFromHueResponseObject(input);

  t.deepEqual(output.created, ['groups/2']);
});

test('mapFromHueResponseObject handles multiple POST responses', t => {
  const ids = ['groups/2', 'lights/7', 'schedules/1'];
  const input = ids.map(id => ({ success: { id } }));

  const output = mapFromHueResponseObject(input);

  t.deepEqual(output.created, ids);
});

test('mapFromHueResponseObject handles a single DELETE response', t => {
  const input = [{ success: 'schedules/1 deleted' }];

  const output = mapFromHueResponseObject(input);

  t.deepEqual(output.messages, ['schedules/1 deleted']);
});

test('mapFromHueResponseObject handles multiple DELETE responses', t => {
  const messages = [
    'schedules/1 deleted',
    'groups/4 deleted',
    'lights/6 deleted'
  ];
  const input = messages.map(m => ({ success: m }));

  const output = mapFromHueResponseObject(input);

  t.deepEqual(output.messages, messages);
});
<|endoftext|>


<commit_before>var loader, define, requireModule, require, requirejs;

(function(global) {
  'use strict';

  var stats;

  // Save off the original values of these globals, so we can restore them if someone asks us to
  var oldGlobals = {
    loader: loader,
    define: define,
    requireModule: requireModule,
    require: require,
    requirejs: requirejs
  };

  requirejs = require = requireModule = function(name) {
    stats.require++;
    var pending = [];
    var mod = findModule(name, '(require)', pending);

    for (var i = pending.length - 1; i >= 0; i--) {
      pending[i].exports();
    }

    return mod.module.exports;
  };

  function resetStats() {
    stats = {
      define: 0,
      require: 0,
      reify: 0,
      findDeps: 0,
      modules: 0,
      exports: 0,
      resolve: 0,
      resolveRelative: 0,
      findModule: 0,
      pendingQueueLength: 0
    };
    requirejs._stats = stats;
  }

  resetStats();

  loader = {
    noConflict: function(aliases) {
      var oldName, newName;

      for (oldName in aliases) {
        if (aliases.hasOwnProperty(oldName)) {
          if (oldGlobals.hasOwnProperty(oldName)) {
            newName = aliases[oldName];

            global[newName] = global[oldName];
            global[oldName] = oldGlobals[oldName];
          }
        }
      }
    }
  };

  var _isArray;
  if (!Array.isArray) {
    _isArray = function (x) {
      return Object.prototype.toString.call(x) === '[object Array]';
    };
  } else {
    _isArray = Array.isArray;
  }

  var registry = {};
  var seen = {};

  var uuid = 0;

  function unsupportedModule(length) {
    throw new Error('an unsupported module was defined, expected `define(name, deps, module)` instead got: `' +
                    length + '` arguments to define`');
  }

  var defaultDeps = ['require', 'exports', 'module'];

  function Module(name, deps, callback, alias) {
    stats.modules++;
    this.id        = uuid++;
    this.name      = name;
    this.deps      = !deps.length && callback.length ? defaultDeps : deps;
    this.module    = { exports: {} };
    this.callback  = callback;
    this.hasExportsAsDep = false;
    this.isAlias = alias;
    this.reified = new Array(deps.length);

    /*
       Each module normally passes through these states, in order:
         new       : initial state
         pending   : this module is scheduled to be executed
         reifying  : this module's dependencies are being executed
         reified   : this module's dependencies finished executing successfully
         errored   : this module's dependencies failed to execute
         finalized : this module executed successfully
     */
    this.state = 'new';

  }

  Module.prototype.makeDefaultExport = function() {
    var exports = this.module.exports;
    if (exports !== null &&
        (typeof exports === 'object' || typeof exports === 'function') &&
          exports['default'] === undefined && !Object.isFrozen(exports)) {
      exports['default'] = exports;
    }
  };

  Module.prototype.exports = function() {
    // if finalized, there is no work to do. If reifying, there is a
    // circular dependency so we must return our (partial) exports.
    if (this.state === 'finalized' || this.state === 'reifying') { return this.module.exports; }
    stats.exports++;

    if (loader.wrapModules) {
      this.callback = loader.wrapModules(this.name, this.callback);
    }

    this.reify();

    var result = this.callback.apply(this, this.reified);
    this.state = 'finalized';

    if (!(this.hasExportsAsDep && result === undefined)) {
      this.module.exports = result;
    }
    this.makeDefaultExport();
    return this.module.exports;
  };

  Module.prototype.unsee = function() {
    this.state = 'new';
    this.module = { exports: {} };
  };

  Module.prototype.reify = function() {
    if (this.state === 'reified') { return; }
    this.state = 'reifying';
    try {
      this.reified = this._reify();
      this.state = 'reified';
    } finally {
      if (this.state === 'reifying') {
        this.state = 'errored';
      }
    }
  };

  Module.prototype._reify = function() {
    stats.reify++;
    var reified = this.reified.slice();
    for (var i = 0; i < reified.length; i++) {
      var mod = reified[i];
      reified[i] = mod.exports ? mod.exports : mod.module.exports();
    }
    return reified;
  };

  Module.prototype.findDeps = function(pending) {
    if (this.state !== 'new') {
      return;
    }

    stats.findDeps++;
    this.state = 'pending';

    var deps = this.deps;

    for (var i = 0; i < deps.length; i++) {
      var dep = deps[i];
      var entry = this.reified[i] = { exports: undefined, module: undefined };
      if (dep === 'exports') {
        this.hasExportsAsDep = true;
        entry.exports = this.module.exports;
      } else if (dep === 'require') {
        entry.exports = this.makeRequire();
      } else if (dep === 'module') {
        entry.exports = this.module;
      } else {
        entry.module = findModule(resolve(dep, this.name), this.name, pending);
      }
    }
  };

  Module.prototype.makeRequire = function() {
    var name = this.name;
    var r = function(dep) {
      return require(resolve(dep, name));
    };
    r['default'] = r;
    r.has = function(dep) {
      return has(resolve(dep, name));
    };
    return r;
  };

  define = function(name, deps, callback) {
    stats.define++;
    if (arguments.length < 2) {
      unsupportedModule(arguments.length);
    }

    if (!_isArray(deps)) {
      callback = deps;
      deps     =  [];
    }

    if (callback instanceof Alias) {
      registry[name] = new Module(callback.name, deps, callback, true);
    } else {
      registry[name] = new Module(name, deps, callback, false);
    }
  };

  // we don't support all of AMD
  // define.amd = {};
  // we will support petals...
  define.petal = { };

  function Alias(path) {
    this.name = path;
  }

  define.alias = function(path) {
    return new Alias(path);
  };

  function missingModule(name, referrer) {
    throw new Error('Could not find module `' + name + '` imported from `' + referrer + '`');
  }

  function findModule(name, referrer, pending) {
    stats.findModule++;
    var mod = registry[name] || registry[name + '/index'];

    while (mod && mod.isAlias) {
      mod = registry[mod.name];
    }

    if (!mod) { missingModule(name, referrer); }

    if (pending && mod.state !== 'pending' && mod.state !== 'finalized') {
      mod.findDeps(pending);
      pending.push(mod);
      stats.pendingQueueLength++;
    }
    return mod;
  }

  function resolve(child, name) {
    stats.resolve++;
    if (child.charAt(0) !== '.') { return child; }
    stats.resolveRelative++;

    var parts = child.split('/');
    var nameParts = name.split('/');
    var parentBase = nameParts.slice(0, -1);

    for (var i = 0, l = parts.length; i < l; i++) {
      var part = parts[i];

      if (part === '..') {
        if (parentBase.length === 0) {
          throw new Error('Cannot access parent module of root');
        }
        parentBase.pop();
      } else if (part === '.') {
        continue;
      } else { parentBase.push(part); }
    }

    return parentBase.join('/');
  }

  function has(name) {
    return !!(registry[name] || registry[name + '/index']);
  }

  requirejs.entries = requirejs._eak_seen = registry;
  requirejs.has = has;
  requirejs.unsee = function(moduleName) {
    findModule(moduleName, '(unsee)', false).unsee();
  };

  requirejs.clear = function() {
    resetStats();
    requirejs.entries = requirejs._eak_seen = registry = {};
    seen = {};
  };

  // prime
  define('foo',      function() {});
  define('foo/bar',  [], function() {});
  define('foo/asdf', ['module', 'exports', 'require'], function(module, exports, require) {
    if (require.has('foo/bar')) {
      require('foo/bar');
    }
  });
  define('foo/baz',  [], define.alias('foo'));
  define('foo/quz',  define.alias('foo'));
  define('foo/bar',  ['foo', './quz', './baz', './asdf', './bar', '../foo'], function() {});
  define('foo/main', ['foo/bar'], function() {});

  require('foo/main');
  require.unsee('foo/bar');

  requirejs.clear();

  if (typeof exports === 'object' && typeof module === 'object' && module.exports) {
    module.exports = { require: require, define: define };
  }
})(this);
<commit_msg>Use dict for registery and seen to avoid filling IC cache<commit_after>var loader, define, requireModule, require, requirejs;

(function(global) {
  'use strict';

  function dict() {
    var obj = Object.create(null);
    obj['__'] = undefined;
    delete obj['__'];
    return obj;
  }

  var stats;

  // Save off the original values of these globals, so we can restore them if someone asks us to
  var oldGlobals = {
    loader: loader,
    define: define,
    requireModule: requireModule,
    require: require,
    requirejs: requirejs
  };

  requirejs = require = requireModule = function(name) {
    stats.require++;
    var pending = [];
    var mod = findModule(name, '(require)', pending);

    for (var i = pending.length - 1; i >= 0; i--) {
      pending[i].exports();
    }

    return mod.module.exports;
  };

  function resetStats() {
    stats = {
      define: 0,
      require: 0,
      reify: 0,
      findDeps: 0,
      modules: 0,
      exports: 0,
      resolve: 0,
      resolveRelative: 0,
      findModule: 0,
      pendingQueueLength: 0
    };
    requirejs._stats = stats;
  }

  resetStats();

  loader = {
    noConflict: function(aliases) {
      var oldName, newName;

      for (oldName in aliases) {
        if (aliases.hasOwnProperty(oldName)) {
          if (oldGlobals.hasOwnProperty(oldName)) {
            newName = aliases[oldName];

            global[newName] = global[oldName];
            global[oldName] = oldGlobals[oldName];
          }
        }
      }
    }
  };

  var _isArray;
  if (!Array.isArray) {
    _isArray = function (x) {
      return Object.prototype.toString.call(x) === '[object Array]';
    };
  } else {
    _isArray = Array.isArray;
  }

  var registry = dict();
  var seen = dict();

  var uuid = 0;

  function unsupportedModule(length) {
    throw new Error('an unsupported module was defined, expected `define(name, deps, module)` instead got: `' +
                    length + '` arguments to define`');
  }

  var defaultDeps = ['require', 'exports', 'module'];

  function Module(name, deps, callback, alias) {
    stats.modules++;
    this.id        = uuid++;
    this.name      = name;
    this.deps      = !deps.length && callback.length ? defaultDeps : deps;
    this.module    = { exports: {} };
    this.callback  = callback;
    this.hasExportsAsDep = false;
    this.isAlias = alias;
    this.reified = new Array(deps.length);

    /*
       Each module normally passes through these states, in order:
         new       : initial state
         pending   : this module is scheduled to be executed
         reifying  : this module's dependencies are being executed
         reified   : this module's dependencies finished executing successfully
         errored   : this module's dependencies failed to execute
         finalized : this module executed successfully
     */
    this.state = 'new';

  }

  Module.prototype.makeDefaultExport = function() {
    var exports = this.module.exports;
    if (exports !== null &&
        (typeof exports === 'object' || typeof exports === 'function') &&
          exports['default'] === undefined && !Object.isFrozen(exports)) {
      exports['default'] = exports;
    }
  };

  Module.prototype.exports = function() {
    // if finalized, there is no work to do. If reifying, there is a
    // circular dependency so we must return our (partial) exports.
    if (this.state === 'finalized' || this.state === 'reifying') { return this.module.exports; }
    stats.exports++;

    if (loader.wrapModules) {
      this.callback = loader.wrapModules(this.name, this.callback);
    }

    this.reify();

    var result = this.callback.apply(this, this.reified);
    this.state = 'finalized';

    if (!(this.hasExportsAsDep && result === undefined)) {
      this.module.exports = result;
    }
    this.makeDefaultExport();
    return this.module.exports;
  };

  Module.prototype.unsee = function() {
    this.state = 'new';
    this.module = { exports: {} };
  };

  Module.prototype.reify = function() {
    if (this.state === 'reified') { return; }
    this.state = 'reifying';
    try {
      this.reified = this._reify();
      this.state = 'reified';
    } finally {
      if (this.state === 'reifying') {
        this.state = 'errored';
      }
    }
  };

  Module.prototype._reify = function() {
    stats.reify++;
    var reified = this.reified.slice();
    for (var i = 0; i < reified.length; i++) {
      var mod = reified[i];
      reified[i] = mod.exports ? mod.exports : mod.module.exports();
    }
    return reified;
  };

  Module.prototype.findDeps = function(pending) {
    if (this.state !== 'new') {
      return;
    }

    stats.findDeps++;
    this.state = 'pending';

    var deps = this.deps;

    for (var i = 0; i < deps.length; i++) {
      var dep = deps[i];
      var entry = this.reified[i] = { exports: undefined, module: undefined };
      if (dep === 'exports') {
        this.hasExportsAsDep = true;
        entry.exports = this.module.exports;
      } else if (dep === 'require') {
        entry.exports = this.makeRequire();
      } else if (dep === 'module') {
        entry.exports = this.module;
      } else {
        entry.module = findModule(resolve(dep, this.name), this.name, pending);
      }
    }
  };

  Module.prototype.makeRequire = function() {
    var name = this.name;
    var r = function(dep) {
      return require(resolve(dep, name));
    };
    r['default'] = r;
    r.has = function(dep) {
      return has(resolve(dep, name));
    };
    return r;
  };

  define = function(name, deps, callback) {
    stats.define++;
    if (arguments.length < 2) {
      unsupportedModule(arguments.length);
    }

    if (!_isArray(deps)) {
      callback = deps;
      deps     =  [];
    }

    if (callback instanceof Alias) {
      registry[name] = new Module(callback.name, deps, callback, true);
    } else {
      registry[name] = new Module(name, deps, callback, false);
    }
  };

  // we don't support all of AMD
  // define.amd = {};
  // we will support petals...
  define.petal = { };

  function Alias(path) {
    this.name = path;
  }

  define.alias = function(path) {
    return new Alias(path);
  };

  function missingModule(name, referrer) {
    throw new Error('Could not find module `' + name + '` imported from `' + referrer + '`');
  }

  function findModule(name, referrer, pending) {
    stats.findModule++;
    var mod = registry[name] || registry[name + '/index'];

    while (mod && mod.isAlias) {
      mod = registry[mod.name];
    }

    if (!mod) { missingModule(name, referrer); }

    if (pending && mod.state !== 'pending' && mod.state !== 'finalized') {
      mod.findDeps(pending);
      pending.push(mod);
      stats.pendingQueueLength++;
    }
    return mod;
  }

  function resolve(child, name) {
    stats.resolve++;
    if (child.charAt(0) !== '.') { return child; }
    stats.resolveRelative++;

    var parts = child.split('/');
    var nameParts = name.split('/');
    var parentBase = nameParts.slice(0, -1);

    for (var i = 0, l = parts.length; i < l; i++) {
      var part = parts[i];

      if (part === '..') {
        if (parentBase.length === 0) {
          throw new Error('Cannot access parent module of root');
        }
        parentBase.pop();
      } else if (part === '.') {
        continue;
      } else { parentBase.push(part); }
    }

    return parentBase.join('/');
  }

  function has(name) {
    return !!(registry[name] || registry[name + '/index']);
  }

  requirejs.entries = requirejs._eak_seen = registry;
  requirejs.has = has;
  requirejs.unsee = function(moduleName) {
    findModule(moduleName, '(unsee)', false).unsee();
  };

  requirejs.clear = function() {
    resetStats();
    requirejs.entries = requirejs._eak_seen = registry = dict();
    seen = dict();
  };

  // prime
  define('foo',      function() {});
  define('foo/bar',  [], function() {});
  define('foo/asdf', ['module', 'exports', 'require'], function(module, exports, require) {
    if (require.has('foo/bar')) {
      require('foo/bar');
    }
  });
  define('foo/baz',  [], define.alias('foo'));
  define('foo/quz',  define.alias('foo'));
  define('foo/bar',  ['foo', './quz', './baz', './asdf', './bar', '../foo'], function() {});
  define('foo/main', ['foo/bar'], function() {});

  require('foo/main');
  require.unsee('foo/bar');

  requirejs.clear();

  if (typeof exports === 'object' && typeof module === 'object' && module.exports) {
    module.exports = { require: require, define: define };
  }
})(this);
<|endoftext|>


<commit_before>const request = require('request')
const { exec } = require('child_process');
var fs = require('fs');
var path = require('path');

//const ffmpegPath = 'C:\\Users\\ijakk_000\\Downloads\\ffmpeg-4.3.1-2021-01-01-essentials_build\\ffmpeg-4.3.1-2021-01-01-essentials_build\\bin\\ffmpeg.exe';
const ffmpegPath = 'ffmpeg';

const homedir = require('os').homedir();
var timelapseDir = homedir + '/timelapse';

let imageCountNumber = 0;

if (!fs.existsSync(timelapseDir)){
    fs.mkdirSync(timelapseDir);
}

fs.readdir(timelapseDir, function (err, files) {
    if (err) {
        return console.log('Unable to scan directory: ' + err);
    }
    const fileNames = []
    files.forEach(function (file) {
        const splitName = file.split('.');
        if (splitName[1] === 'jpg') {
            console.log(file);
            fileNames.push(splitName[0]);
        }
    });

    fileNames.sort(function(a, b){return a-b});
    console.log(fileNames);
    if (fileNames.length > 0) {
        imageCountNumber = parseInt(fileNames[fileNames.length - 1]) + 1;
    }

    console.log('First timelapse number will be ' + imageCountNumber)

    takeScreenshot();
});

setInterval(function () {
    takeScreenshot();
 }, 20 * 60 * 1000);

module.exports = {
    createTimelapse: function(length, callback) {
        renderTimelapse(length, callback);
    },
    getTimelapsePath: function() {
        return path.join(timelapseDir, 'done.mp4');
    }
};

function renderTimelapse(length, callback) {
    const frameRate = imageCountNumber / length;
    const cmd = `${ffmpegPath} -y  -framerate ${frameRate} -i ${path.join(timelapseDir, '%04d.jpg')} -s:v 1440x1080 -c:v libx264 -crf 17 -pix_fmt yuv420p  ${path.join(timelapseDir, 'done.mp4')}`;
    console.log(cmd)
    exec(cmd, (err, stdout, stderr) => {
        if (err) {
            console.error(err)
            callback('')
        } else {
            console.log(`stdout: ${stdout}`);
            console.log(`stderr: ${stderr}`);
            imageCountNumber ++;
            callback(path.join(timelapseDir, 'done.mp4'));
        }
    });
}

function takeScreenshot() {
    const cmd = `${ffmpegPath} -y -i rtsp://rtsp:12345678@192.168.1.169:554/av_stream/ch0 -vframes 1 -strftime 1  ${path.join(timelapseDir, String(parseInt(imageCountNumber)).padStart(4, '0') + '.jpg')}`;
    console.log(cmd)
    exec(cmd, (err, stdout, stderr) => {
        if (err) {
            console.error(err)
        } else {
            console.log(`stdout: ${stdout}`);
            console.log(`stderr: ${stderr}`);
            imageCountNumber ++;
        }
    });
}

<commit_msg>Only increase image number when actually taking a screenshot.<commit_after>const request = require('request')
const { exec } = require('child_process');
var fs = require('fs');
var path = require('path');

//const ffmpegPath = 'C:\\Users\\ijakk_000\\Downloads\\ffmpeg-4.3.1-2021-01-01-essentials_build\\ffmpeg-4.3.1-2021-01-01-essentials_build\\bin\\ffmpeg.exe';
const ffmpegPath = 'ffmpeg';

const homedir = require('os').homedir();
var timelapseDir = homedir + '/timelapse';

let imageCountNumber = 0;

if (!fs.existsSync(timelapseDir)){
    fs.mkdirSync(timelapseDir);
}

fs.readdir(timelapseDir, function (err, files) {
    if (err) {
        return console.log('Unable to scan directory: ' + err);
    }
    const fileNames = []
    files.forEach(function (file) {
        const splitName = file.split('.');
        if (splitName[1] === 'jpg') {
            console.log(file);
            fileNames.push(splitName[0]);
        }
    });

    fileNames.sort(function(a, b){return a-b});
    console.log(fileNames);
    if (fileNames.length > 0) {
        imageCountNumber = parseInt(fileNames[fileNames.length - 1]) + 1;
    }

    console.log('First timelapse number will be ' + imageCountNumber)

    takeScreenshot();
});

setInterval(function () {
    takeScreenshot();
 }, 20 * 60 * 1000);

module.exports = {
    createTimelapse: function(length, callback) {
        renderTimelapse(length, callback);
    },
    getTimelapsePath: function() {
        return path.join(timelapseDir, 'done.mp4');
    }
};

function renderTimelapse(length, callback) {
    const frameRate = imageCountNumber / length;
    const cmd = `${ffmpegPath} -y  -framerate ${frameRate} -i ${path.join(timelapseDir, '%04d.jpg')} -s:v 1440x1080 -c:v libx264 -crf 17 -pix_fmt yuv420p  ${path.join(timelapseDir, 'done.mp4')}`;
    console.log(cmd)
    exec(cmd, (err, stdout, stderr) => {
        if (err) {
            console.error(err)
            callback('')
        } else {
            console.log(`stdout: ${stdout}`);
            console.log(`stderr: ${stderr}`);
            callback(path.join(timelapseDir, 'done.mp4'));
        }
    });
}

function takeScreenshot() {
    const cmd = `${ffmpegPath} -y -i rtsp://rtsp:12345678@192.168.1.169:554/av_stream/ch0 -vframes 1 -strftime 1  ${path.join(timelapseDir, String(parseInt(imageCountNumber)).padStart(4, '0') + '.jpg')}`;
    console.log(cmd)
    exec(cmd, (err, stdout, stderr) => {
        if (err) {
            console.error(err)
        } else {
            console.log(`stdout: ${stdout}`);
            console.log(`stderr: ${stderr}`);
            imageCountNumber ++;
        }
    });
}

<|endoftext|>


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

/*
 * Copyright 2011 eBay Software Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
var stringify = require('raptor-json/stringify');
var raptorModulesResolver = require('raptor-modules/resolver');
var raptorModulesUtil = require('raptor-modules/util');
var raptorRenderer = require('raptor-renderer');

var WidgetsContext = require('./WidgetsContext');
var TAG_START = '';
var STRINGIFY_OPTIONS = {
    special: /([^ -~]|(["'\\<&%]))/g,
    replace: {
        '"': '\\u0022',
        '\n': '\\n'
    },
    useSingleQuote: true
};

function WrappedString(val) {
    this.html = val;
}

WrappedString.prototype = {
    toString: function() {
        return this.html;
    }
};

var bubbleEventsLookup = {};

require('./bubble').forEach(function(eventType) {
    bubbleEventsLookup[eventType] = true;
});

exports.isBubbleEvent = function(eventType) {
    return bubbleEventsLookup.hasOwnProperty(eventType);
};

exports.WidgetsContext = WidgetsContext;
exports.getWidgetsContext = WidgetsContext.getWidgetsContext;
exports.uniqueId = require('./uniqueId');
exports.attrs = function(widgetDef) {
    if (!widgetDef.type) {
        return null;
    }

    var attrs = {
        'data-widget': widgetDef.type
    };

    var widgetConfig = widgetDef.config;
    if (widgetConfig) {
        attrs['data-w-config'] = new WrappedString(stringify(widgetConfig, STRINGIFY_OPTIONS));
    }

    var widgetState = widgetDef.state;
    if (widgetState) {
        attrs['data-w-state'] = new WrappedString(stringify(widgetState, STRINGIFY_OPTIONS));
    }

    var hasDomEvents = widgetDef.hasDomEvents;
    if (hasDomEvents) {
        attrs['data-w-on'] = '1';
    }

    var customEvents = widgetDef.customEvents;
    if (customEvents) {
        attrs['data-w-events'] = widgetDef.scope + ',' + customEvents.join(',');
    }

    var extend = widgetDef.extend;

    if (extend && extend.length) {
        attrs['data-w-extend'] = new WrappedString(extend.join(','));
    }

    var bodyElId = widgetDef.bodyElId;
    if (bodyElId != null) {
        attrs['data-w-body'] = bodyElId;
    }

    return attrs;
};
exports.writeDomEventsEl = function(widgetDef, out) {
    var domEvents = widgetDef.domEvents;
    if (domEvents) {
        out.write('');
    }
};

exports.writeInitWidgetsCode = function(widgetsContext, out, options) {
    var clearWidgets = true;
    var scanDOM = false;
    var immediate = false;

    if (options) {
        clearWidgets = options.clearWidgets !== false;
        scanDOM = options.scanDOM === true;
        immediate = options.immediate === true;
    }

    if (scanDOM) {
        out.write(TAG_START + '*' + TAG_END);
    } else {
        var widgets = widgetsContext.getWidgets();

        if (!widgets || !widgets.length) {
            return;
        }

        var ids = '';

        var commaRequired = false;

        var writeWidget = function(widget) {

            if (widget.children.length) {
                // Depth-first search (children should be initialized before parent)
                writeWidgets(widget.children);
            }

            if (commaRequired) {
                ids += ',';
            } else {
                commaRequired = true;
            }

            ids += widget.id;
        };

        var writeWidgets = function(widgets) {
            for (var i = 0, len = widgets.length; i < len; i++) {
                writeWidget(widgets[i]);
            }
        };

        writeWidgets(widgets);

        if (immediate) {
            out.write('');
        } else {
            out.write(TAG_START + ids + TAG_END);
        }
    }

    if (clearWidgets !== false) {
        widgetsContext.clearWidgets();
    }
};

function getWidgetIdsString(widgetsContext) {
    if (!widgetsContext) {
        throw new Error('"widgetsContext" is required');
    }

    if (!(widgetsContext instanceof WidgetsContext)) {
        // Assume that the provided "widgetsContext" argument is
        // actually an AsyncWriter
        var asyncWriter = widgetsContext;
        if (!asyncWriter.global) {
            throw new Error('Invalid argument: ' + widgetsContext);
        }

        widgetsContext = WidgetsContext.getWidgetsContext(asyncWriter);
    }

    var widgets = widgetsContext.getWidgets();
    if (!widgets || !widgets.length) {
        return;
    }

    var ids = '';

    var commaRequired = false;

    function writeWidget(widget) {

        if (widget.children.length) {
            // Depth-first search (children should be initialized before parent)
            writeWidgets(widget.children);
        }

        if (commaRequired) {
            ids += ',';
        } else {
            commaRequired = true;
        }

        ids += widget.id;
    }

    function writeWidgets(widgets) {
        for (var i = 0, len = widgets.length; i < len; i++) {
            writeWidget(widgets[i]);
        }
    }

    writeWidgets(widgets);

    return ids;
}

exports.getInitWidgetsCode = function(widgetsContext) {
    var idsString = getWidgetIdsString(widgetsContext);
    return '$rwidgets("' + idsString + '");';
};

exports.getRenderedWidgetIds = function(widgetsContext) {
    var idsString = getWidgetIdsString(widgetsContext);
    return idsString;
};

exports.getClientWidgetPath = function(targetModuleFile, from) {
    var resolved = raptorModulesResolver.resolveRequire(targetModuleFile, from);
    return resolved.logicalPath;
};

var dynamicClientWidgetPathCache = {};

exports.getDynamicClientWidgetPath = function(targetModuleFile) {
    if (!targetModuleFile) {
        return null;
    }

    var clientPath = dynamicClientWidgetPathCache[targetModuleFile];
    if (!clientPath) {
        var resolved = raptorModulesUtil.getPathInfo(targetModuleFile);
        clientPath = dynamicClientWidgetPathCache[targetModuleFile] = resolved.logicalPath;
    }
    return clientPath;
};

exports.makeRenderable = exports.renderable = raptorRenderer.renderable;
exports.render = raptorRenderer.render;

exports.defineComponent = require('./defineComponent');
exports.defineWidget = require('./defineWidget');
exports.defineRenderer = require('./defineRenderer');
<commit_msg>Correctly store when the root element is the body element<commit_after>/*
 * Copyright 2011 eBay Software Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
* Module to manage the lifecycle of widgets
*
*/

/*
 * Copyright 2011 eBay Software Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
var stringify = require('raptor-json/stringify');
var raptorModulesResolver = require('raptor-modules/resolver');
var raptorModulesUtil = require('raptor-modules/util');
var raptorRenderer = require('raptor-renderer');

var WidgetsContext = require('./WidgetsContext');
var TAG_START = '';
var STRINGIFY_OPTIONS = {
    special: /([^ -~]|(["'\\<&%]))/g,
    replace: {
        '"': '\\u0022',
        '\n': '\\n'
    },
    useSingleQuote: true
};

function WrappedString(val) {
    this.html = val;
}

WrappedString.prototype = {
    toString: function() {
        return this.html;
    }
};

var bubbleEventsLookup = {};

require('./bubble').forEach(function(eventType) {
    bubbleEventsLookup[eventType] = true;
});

exports.isBubbleEvent = function(eventType) {
    return bubbleEventsLookup.hasOwnProperty(eventType);
};

exports.WidgetsContext = WidgetsContext;
exports.getWidgetsContext = WidgetsContext.getWidgetsContext;
exports.uniqueId = require('./uniqueId');
exports.attrs = function(widgetDef) {
    if (!widgetDef.type) {
        return null;
    }

    var attrs = {
        'data-widget': widgetDef.type
    };

    var widgetConfig = widgetDef.config;
    if (widgetConfig) {
        attrs['data-w-config'] = new WrappedString(stringify(widgetConfig, STRINGIFY_OPTIONS));
    }

    var widgetState = widgetDef.state;
    if (widgetState) {
        attrs['data-w-state'] = new WrappedString(stringify(widgetState, STRINGIFY_OPTIONS));
    }

    var hasDomEvents = widgetDef.hasDomEvents;
    if (hasDomEvents) {
        attrs['data-w-on'] = '1';
    }

    var customEvents = widgetDef.customEvents;
    if (customEvents) {
        attrs['data-w-events'] = widgetDef.scope + ',' + customEvents.join(',');
    }

    var extend = widgetDef.extend;

    if (extend && extend.length) {
        attrs['data-w-extend'] = new WrappedString(extend.join(','));
    }

    var bodyElId = widgetDef.bodyElId;
    if (bodyElId != null) {
        attrs['data-w-body'] = bodyElId === '' ? true : bodyElId;
    }

    return attrs;
};
exports.writeDomEventsEl = function(widgetDef, out) {
    var domEvents = widgetDef.domEvents;
    if (domEvents) {
        out.write('');
    }
};

exports.writeInitWidgetsCode = function(widgetsContext, out, options) {
    var clearWidgets = true;
    var scanDOM = false;
    var immediate = false;

    if (options) {
        clearWidgets = options.clearWidgets !== false;
        scanDOM = options.scanDOM === true;
        immediate = options.immediate === true;
    }

    if (scanDOM) {
        out.write(TAG_START + '*' + TAG_END);
    } else {
        var widgets = widgetsContext.getWidgets();

        if (!widgets || !widgets.length) {
            return;
        }

        var ids = '';

        var commaRequired = false;

        var writeWidget = function(widget) {

            if (widget.children.length) {
                // Depth-first search (children should be initialized before parent)
                writeWidgets(widget.children);
            }

            if (commaRequired) {
                ids += ',';
            } else {
                commaRequired = true;
            }

            ids += widget.id;
        };

        var writeWidgets = function(widgets) {
            for (var i = 0, len = widgets.length; i < len; i++) {
                writeWidget(widgets[i]);
            }
        };

        writeWidgets(widgets);

        if (immediate) {
            out.write('');
        } else {
            out.write(TAG_START + ids + TAG_END);
        }
    }

    if (clearWidgets !== false) {
        widgetsContext.clearWidgets();
    }
};

function getWidgetIdsString(widgetsContext) {
    if (!widgetsContext) {
        throw new Error('"widgetsContext" is required');
    }

    if (!(widgetsContext instanceof WidgetsContext)) {
        // Assume that the provided "widgetsContext" argument is
        // actually an AsyncWriter
        var asyncWriter = widgetsContext;
        if (!asyncWriter.global) {
            throw new Error('Invalid argument: ' + widgetsContext);
        }

        widgetsContext = WidgetsContext.getWidgetsContext(asyncWriter);
    }

    var widgets = widgetsContext.getWidgets();
    if (!widgets || !widgets.length) {
        return;
    }

    var ids = '';

    var commaRequired = false;

    function writeWidget(widget) {

        if (widget.children.length) {
            // Depth-first search (children should be initialized before parent)
            writeWidgets(widget.children);
        }

        if (commaRequired) {
            ids += ',';
        } else {
            commaRequired = true;
        }

        ids += widget.id;
    }

    function writeWidgets(widgets) {
        for (var i = 0, len = widgets.length; i < len; i++) {
            writeWidget(widgets[i]);
        }
    }

    writeWidgets(widgets);

    return ids;
}

exports.getInitWidgetsCode = function(widgetsContext) {
    var idsString = getWidgetIdsString(widgetsContext);
    return '$rwidgets("' + idsString + '");';
};

exports.getRenderedWidgetIds = function(widgetsContext) {
    var idsString = getWidgetIdsString(widgetsContext);
    return idsString;
};

exports.getClientWidgetPath = function(targetModuleFile, from) {
    var resolved = raptorModulesResolver.resolveRequire(targetModuleFile, from);
    return resolved.logicalPath;
};

var dynamicClientWidgetPathCache = {};

exports.getDynamicClientWidgetPath = function(targetModuleFile) {
    if (!targetModuleFile) {
        return null;
    }

    var clientPath = dynamicClientWidgetPathCache[targetModuleFile];
    if (!clientPath) {
        var resolved = raptorModulesUtil.getPathInfo(targetModuleFile);
        clientPath = dynamicClientWidgetPathCache[targetModuleFile] = resolved.logicalPath;
    }
    return clientPath;
};

exports.makeRenderable = exports.renderable = raptorRenderer.renderable;
exports.render = raptorRenderer.render;

exports.defineComponent = require('./defineComponent');
exports.defineWidget = require('./defineWidget');
exports.defineRenderer = require('./defineRenderer');
<|endoftext|>


<commit_before>/**
 * mashape-tools
 * https://github.com/magdev/node-mashape-tools
 *
 * Copyright (c) 2014 Marco Grätsch
 * Licensed under the MIT license.
 */

'use strict';

var extend = require('xtend'),

    /** Mashape-specific proxy-secret header */
    PROXY_SECRET_HEADER = 'x-mashape-proxy-secret',

    /** Mashape-specific header to identify the current user */
    USER_HEADER = 'x-mashape-user',

    /** Default Configuration */
    defaultConfig = {
        /** Path to a JSON-File or an Array with allowed IP-Addresses */
        iplist: null,

        /** Mashape Proxy-Secret */
        proxySecret: null,

        /** HTTP-Status-Code to send on invalid requests */
        errorCode: 403,

        /** HTTP-Status-Message to send on invalid requests */
        errorMessage: 'Forbidden',

        /** Throw errors on invalid requests */
        strict: true,

        /** Enable logging */
        log: true,

        /** List of additional header-checks */
        additionalHeaderChecks: [],

        /** List of allowed IPs, i.e. load balancers */
        ipWhitelist: ['127.0.0.1']
    },

    /**
     * Find the Client-IP
     *
     * @param {Request} req
     * @returns String
     */
    clientIP = function(req) {
        if (req.ips.length) {
            return req.ips.length === 1 ? req.ips[0] : req.ips.slice(1).shift();
        }
        return req.ip;
    };

module.exports = exports = {

    /**
     * Middleware to filter clients by IP-Address
     *
     * @param {Object} config
     * @returns {Function}
     */
    ipFilter: function(config) {
        config = extend(defaultConfig, (config || {}));

        return function(req, res, next) {
            try {
                var ip = clientIP(req),
                    user = req.get(USER_HEADER) || 'UNKNOWN',
                    iplist = typeof config.iplist === String ? require(config.iplist) : config.iplist;

                if ((!iplist || !iplist.length) || (!config.ipWhitelist || !config.ipWhitelist.length)) {
                    var e = new Error('No IP-list or whitelist defined, skipping ipFilter()');
                    if (config.strict) {
                        return next(e);
                    }
                    console.log(e.message);
                    return next();
                }

                // Check if IP is whitelisted
                if (config.ipWhitelist && config.ipWhitelist.indexOf(ip) !== -1) {
                    if (config.log) {
                        console.log('Access granted for user %s, IP address: %s (whitelisted)', user, ip);
                    }
                    return next();
                }

                // Check if ip is on the iplist
                if (iplist.indexOf(ip) !== -1) {
                    if (config.log) {
                        console.log('Access granted for user %s, IP address: %s', user, ip);
                    }
                    return next();
                }

                if (config.log) {
                    console.log('Access denied to user %s, IP address: %s', user, ip);
                }
                res.statusCode = config.errorCode;
                return res.end(config.errorMessage);
            } catch (e) {
                if (config.strict) {
                    return next(e);
                }
                console.log(e);
                return next();
            }
        };
    },

    /**
     * Middleware to filter clients by Proxy-Secret
     *
     * @param {Object} config
     * @returns {Function}
     */
    headerFilter: function(config) {
        config = extend(defaultConfig, (config || {}));

        return function(req, res, next) {
            try {
                var user = req.get(USER_HEADER) || 'UNKNOWN';

                if (!config.proxySecret && (!config.additionalHeaderChecks || !config.additionalHeaderChecks.length)) {
                    var e = new Error('No Proxy-Secret or additional header checks defined, skipping headerFilter()');
                    if (config.strict) {
                        return next(e);
                    }
                    console.log(e.message);
                    return next();
                }

                // Check Proxy-Secret
                if (config.proxySecret) {
                    var secret = req.get(PROXY_SECRET_HEADER);
                    if (!secret || (secret && secret !== config.proxySecret)) {
                        if (config.log) {
                            console.log('Access denied for user %s, cause: Invalid Proxy-Secret [%s]', user, secret);
                        }
                        res.statusCode = config.errorCode;
                        return res.end(config.errorMessage);
                    }
                }

                // Perform additional header checks
                if (config.additionalHeaderChecks && config.additionalHeaderChecks.length) {
                    for (var i = 0; i < config.additionalHeaderChecks.length; i++) {
                        var check = config.additionalHeaderChecks[i],
                            header = req.get(check.name);

                        if (!header || !check.value || (header && header !== check.value)) {
                            if (config.log) {
                                console.log('Access denied for user %s, cause: Invalid HTTP-Header [%s = %s]', user, check.name, header);
                            }
                            res.statusCode = config.errorCode;
                            return res.end(config.errorMessage);
                        }
                    }
                }

                if (config.log) {
                    console.log('Access granted to user %s', user);
                }
                return next();
            } catch (e) {
                if (config.strict) {
                    return next(e);
                }
                console.log(e);
                return next();
            }
        };
    }
};<commit_msg>renamed var to whitelist<commit_after>/**
 * mashape-tools
 * https://github.com/magdev/node-mashape-tools
 *
 * Copyright (c) 2014 Marco Grätsch
 * Licensed under the MIT license.
 */

'use strict';

var extend = require('xtend'),

    /** Mashape-specific proxy-secret header */
    PROXY_SECRET_HEADER = 'x-mashape-proxy-secret',

    /** Mashape-specific header to identify the current user */
    USER_HEADER = 'x-mashape-user',

    /** Default Configuration */
    defaultConfig = {
        /** Path to a JSON-File or an Array with allowed IP-Addresses */
        iplist: null,

        /** Mashape Proxy-Secret */
        proxySecret: null,

        /** HTTP-Status-Code to send on invalid requests */
        errorCode: 403,

        /** HTTP-Status-Message to send on invalid requests */
        errorMessage: 'Forbidden',

        /** Throw errors on invalid requests */
        strict: true,

        /** Enable logging */
        log: true,

        /** List of additional header-checks */
        additionalHeaderChecks: [],

        /** List of allowed IPs, i.e. load balancers */
        whitelist: ['127.0.0.1']
    },

    /**
     * Find the Client-IP
     *
     * @param {Request} req
     * @returns String
     */
    clientIP = function(req) {
        if (req.ips.length) {
            return req.ips.length === 1 ? req.ips[0] : req.ips.slice(1).shift();
        }
        return req.ip;
    };

module.exports = exports = {

    /**
     * Middleware to filter clients by IP-Address
     *
     * @param {Object} config
     * @returns {Function}
     */
    ipFilter: function(config) {
        config = extend(defaultConfig, (config || {}));

        return function(req, res, next) {
            try {
                var ip = clientIP(req),
                    user = req.get(USER_HEADER) || 'UNKNOWN',
                    iplist = typeof config.iplist === String ? require(config.iplist) : config.iplist;

                if ((!iplist || !iplist.length) || (!config.whitelist || !config.whitelist.length)) {
                    var e = new Error('No IP-list or whitelist defined, skipping ipFilter()');
                    if (config.strict) {
                        return next(e);
                    }
                    console.log(e.message);
                    return next();
                }

                // Check if IP is whitelisted
                if (config.whitelist && config.whitelist.indexOf(ip) !== -1) {
                    if (config.log) {
                        console.log('Access granted for user %s, IP address: %s (whitelisted)', user, ip);
                    }
                    return next();
                }

                // Check if ip is on the iplist
                if (iplist.indexOf(ip) !== -1) {
                    if (config.log) {
                        console.log('Access granted for user %s, IP address: %s', user, ip);
                    }
                    return next();
                }

                if (config.log) {
                    console.log('Access denied to user %s, IP address: %s', user, ip);
                }
                res.statusCode = config.errorCode;
                return res.end(config.errorMessage);
            } catch (e) {
                if (config.strict) {
                    return next(e);
                }
                console.log(e);
                return next();
            }
        };
    },

    /**
     * Middleware to filter clients by Proxy-Secret
     *
     * @param {Object} config
     * @returns {Function}
     */
    headerFilter: function(config) {
        config = extend(defaultConfig, (config || {}));

        return function(req, res, next) {
            try {
                var user = req.get(USER_HEADER) || 'UNKNOWN';

                if (!config.proxySecret && (!config.additionalHeaderChecks || !config.additionalHeaderChecks.length)) {
                    var e = new Error('No Proxy-Secret or additional header checks defined, skipping headerFilter()');
                    if (config.strict) {
                        return next(e);
                    }
                    console.log(e.message);
                    return next();
                }

                // Check Proxy-Secret
                if (config.proxySecret) {
                    var secret = req.get(PROXY_SECRET_HEADER);
                    if (!secret || (secret && secret !== config.proxySecret)) {
                        if (config.log) {
                            console.log('Access denied for user %s, cause: Invalid Proxy-Secret [%s]', user, secret);
                        }
                        res.statusCode = config.errorCode;
                        return res.end(config.errorMessage);
                    }
                }

                // Perform additional header checks
                if (config.additionalHeaderChecks && config.additionalHeaderChecks.length) {
                    for (var i = 0; i < config.additionalHeaderChecks.length; i++) {
                        var check = config.additionalHeaderChecks[i],
                            header = req.get(check.name);

                        if (!header || !check.value || (header && header !== check.value)) {
                            if (config.log) {
                                console.log('Access denied for user %s, cause: Invalid HTTP-Header [%s = %s]', user, check.name, header);
                            }
                            res.statusCode = config.errorCode;
                            return res.end(config.errorMessage);
                        }
                    }
                }

                if (config.log) {
                    console.log('Access granted to user %s', user);
                }
                return next();
            } catch (e) {
                if (config.strict) {
                    return next(e);
                }
                console.log(e);
                return next();
            }
        };
    }
};<|endoftext|>


<commit_before>/*
 *
 */
'use strict';

Entry.Executor = function(block, entity) {
    this.scope = new Entry.Scope(block, this);
    this.entity = entity;
    this._callStack = [];
    this.register = {};
    this.parentExecutor = null;
    this.id = Entry.Utils.generateId();
};

Entry.Executor.MAXIMUM_CALLSTACK = 100;

(function(p) {
    p.execute = function(isFromOrigin) {
        if (this.isEnd()) return;

        var executedBlocks = [];
        var block;
        if (isFromOrigin) Entry.callStackLength = 0;

        var entity = this.entity;

        while (true) {
            var returnVal = null;
            executedBlocks.push(this.scope.block);

            try {
                var schema = this.scope.block.getSchema();
                if (schema && Entry.skeleton[schema.skeleton].executable) {
                    Entry.dispatchEvent(
                        'blockExecute',
                        this.scope.block && this.scope.block.view
                    );
                    returnVal = schema.func.call(
                        this.scope,
                        entity,
                        this.scope
                    );
                }
            } catch (e) {
                if (e.name === 'AsyncError') {
                    returnVal = Entry.STATIC.BREAK;
                } else if (this.isFuncExecutor)
                    //function executor
                    throw new Error();
                else {
                    Entry.Utils.stopProjectWithToast(this.scope, undefined, e);
                }
            }

            //executor can be ended after block function call
            if (this.isEnd()) return executedBlocks;

            if (
                returnVal === undefined ||
                returnVal === null ||
                returnVal === Entry.STATIC.PASS
            ) {
                this.scope = new Entry.Scope(
                    this.scope.block.getNextBlock(),
                    this
                );
                if (this.scope.block === null) {
                    if (this._callStack.length) {
                        var oldScope = this.scope;
                        this.scope = this._callStack.pop();
                        if (this.scope.isLooped !== oldScope.isLooped) break;
                    } else break;
                }
            } else if (returnVal === Entry.STATIC.CONTINUE) {
            } else if (
                returnVal === Entry.STATIC.BREAK ||
                this.scope === returnVal
            ) {
                break;
            }
        }
        return executedBlocks;
    };

    p.stepInto = function(thread) {
        if (!(thread instanceof Entry.Thread))
            console.error('Must step in to thread');

        var block = thread.getFirstBlock();
        if (!block) {
            return Entry.STATIC.BREAK;
        }

        this._callStack.push(this.scope);

        this.scope = new Entry.Scope(block, this);
        return Entry.STATIC.CONTINUE;
    };

    p.break = function() {
        if (this._callStack.length) this.scope = this._callStack.pop();
        return Entry.STATIC.PASS;
    };

    p.breakLoop = function() {
        if (this._callStack.length) this.scope = this._callStack.pop();
        while (this._callStack.length) {
            var schema = Entry.block[this.scope.block.type];
            if (schema.class === 'repeat') break;
            this.scope = this._callStack.pop();
        }
        return Entry.STATIC.PASS;
    };

    p.end = function() {
        Entry.dispatchEvent(
            'blockExecuteEnd',
            this.scope.block && this.scope.block.view
        );
        this.scope.block = null;
    };

    p.isEnd = function() {
        return this.scope.block === null;
    };
})(Entry.Executor.prototype);

Entry.Scope = function(block, executor) {
    this.block = block;
    this.type = block ? block.type : null; //legacy
    this.executor = executor;
    this.entity = executor.entity;
};

(function(p) {
    p.callReturn = function() {
        return undefined;
    };

    p.getParam = function(index) {
        var fieldBlock = this.block.params[index];
        var newScope = new Entry.Scope(fieldBlock, this.executor);
        var result = Entry.block[fieldBlock.type].func.call(
            newScope,
            this.entity,
            newScope
        );
        return result;
    };

    p.getParams = function() {
        var that = this;
        return this.block.params.map(function(param) {
            if (param instanceof Entry.Block) {
                var fieldBlock = param;
                var newScope = new Entry.Scope(fieldBlock, that.executor);
                return Entry.block[fieldBlock.type].func.call(
                    newScope,
                    that.entity,
                    newScope
                );
            } else return param;
        });
    };

    p.getValue = function(key, block) {
        var fieldBlock = this.block.params[this._getParamIndex(key, block)];
        var newScope = new Entry.Scope(fieldBlock, this.executor);
        var result = Entry.block[fieldBlock.type].func.call(
            newScope,
            this.entity,
            newScope
        );
        return result;
    };

    p.getStringValue = function(key, block) {
        return String(this.getValue(key, block));
    };

    p.getNumberValue = function(key, block) {
        return Number(this.getValue(key));
    };

    p.getBooleanValue = function(key, block) {
        var value = Number(this.getValue(key));
        return typeof value === "string" && isNaN(value) ? true : value; // handle "0" or "0.00"
    };

    p.getField = function(key, block) {
        return this.block.params[this._getParamIndex(key)];
    };

    p.getStringField = function(key, block) {
        return String(this.getField(key));
    };

    p.getNumberField = function(key) {
        return Number(this.getField(key));
    };

    p.getStatement = function(key, block) {
        return this.executor.stepInto(
            this.block.statements[this._getStatementIndex(key, block)]
        );
    };

    p._getParamIndex = function(key) {
        if (!this._schema) this._schema = Entry.block[this.type];
        return this._schema.paramsKeyMap[key];
    };

    p._getStatementIndex = function(key) {
        if (!this._schema) this._schema = Entry.block[this.type];
        return this._schema.statementsKeyMap[key];
    };

    p.die = function() {
        this.block = null;
        return Entry.STATIC.BREAK;
    };
})(Entry.Scope.prototype);
<commit_msg>fix issue<commit_after>/*
 *
 */
'use strict';

Entry.Executor = function(block, entity) {
    this.scope = new Entry.Scope(block, this);
    this.entity = entity;
    this._callStack = [];
    this.register = {};
    this.parentExecutor = null;
    this.id = Entry.Utils.generateId();
};

Entry.Executor.MAXIMUM_CALLSTACK = 100;

(function(p) {
    p.execute = function(isFromOrigin) {
        if (this.isEnd()) return;

        var executedBlocks = [];
        var block;
        if (isFromOrigin) Entry.callStackLength = 0;

        var entity = this.entity;

        while (true) {
            var returnVal = null;
            executedBlocks.push(this.scope.block);

            try {
                var schema = this.scope.block.getSchema();
                if (schema && Entry.skeleton[schema.skeleton].executable) {
                    Entry.dispatchEvent(
                        'blockExecute',
                        this.scope.block && this.scope.block.view
                    );
                    returnVal = schema.func.call(
                        this.scope,
                        entity,
                        this.scope
                    );
                }
            } catch (e) {
                if (e.name === 'AsyncError') {
                    returnVal = Entry.STATIC.BREAK;
                } else if (this.isFuncExecutor)
                    //function executor
                    throw new Error();
                else {
                    Entry.Utils.stopProjectWithToast(this.scope, undefined, e);
                }
            }

            //executor can be ended after block function call
            if (this.isEnd()) return executedBlocks;

            if (
                returnVal === undefined ||
                returnVal === null ||
                returnVal === Entry.STATIC.PASS
            ) {
                this.scope = new Entry.Scope(
                    this.scope.block.getNextBlock(),
                    this
                );
                if (this.scope.block === null) {
                    if (this._callStack.length) {
                        var oldScope = this.scope;
                        this.scope = this._callStack.pop();
                        if (this.scope.isLooped !== oldScope.isLooped) break;
                    } else break;
                }
            } else if (returnVal === Entry.STATIC.CONTINUE) {
            } else if (
                returnVal === Entry.STATIC.BREAK ||
                this.scope === returnVal
            ) {
                break;
            }
        }
        return executedBlocks;
    };

    p.stepInto = function(thread) {
        if (!(thread instanceof Entry.Thread))
            console.error('Must step in to thread');

        var block = thread.getFirstBlock();
        if (!block) {
            return Entry.STATIC.BREAK;
        }

        this._callStack.push(this.scope);

        this.scope = new Entry.Scope(block, this);
        return Entry.STATIC.CONTINUE;
    };

    p.break = function() {
        if (this._callStack.length) this.scope = this._callStack.pop();
        return Entry.STATIC.PASS;
    };

    p.breakLoop = function() {
        if (this._callStack.length) this.scope = this._callStack.pop();
        while (this._callStack.length) {
            var schema = Entry.block[this.scope.block.type];
            if (schema.class === 'repeat') break;
            this.scope = this._callStack.pop();
        }
        return Entry.STATIC.PASS;
    };

    p.end = function() {
        Entry.dispatchEvent(
            'blockExecuteEnd',
            this.scope.block && this.scope.block.view
        );
        this.scope.block = null;
    };

    p.isEnd = function() {
        return this.scope.block === null;
    };
})(Entry.Executor.prototype);

Entry.Scope = function(block, executor) {
    this.block = block;
    this.type = block ? block.type : null; //legacy
    this.executor = executor;
    this.entity = executor.entity;
};

(function(p) {
    p.callReturn = function() {
        return undefined;
    };

    p.getParam = function(index) {
        var fieldBlock = this.block.params[index];
        var newScope = new Entry.Scope(fieldBlock, this.executor);
        var result = Entry.block[fieldBlock.type].func.call(
            newScope,
            this.entity,
            newScope
        );
        return result;
    };

    p.getParams = function() {
        var that = this;
        return this.block.params.map(function(param) {
            if (param instanceof Entry.Block) {
                var fieldBlock = param;
                var newScope = new Entry.Scope(fieldBlock, that.executor);
                return Entry.block[fieldBlock.type].func.call(
                    newScope,
                    that.entity,
                    newScope
                );
            } else return param;
        });
    };

    p.getValue = function(key, block) {
        var fieldBlock = this.block.params[this._getParamIndex(key, block)];
        var newScope = new Entry.Scope(fieldBlock, this.executor);
        var result = Entry.block[fieldBlock.type].func.call(
            newScope,
            this.entity,
            newScope
        );
        return result;
    };

    p.getStringValue = function(key, block) {
        return String(this.getValue(key, block));
    };

    p.getNumberValue = function(key, block) {
        return Number(this.getValue(key));
    };

    p.getBooleanValue = function(key, block) {
        var value = this.getValue(key);
        if (value === undefined)
            return false;
        value = Number(this.getValue(key));
        return isNaN(value) ? true : value; // handle "0" or "0.00"
    };

    p.getField = function(key, block) {
        return this.block.params[this._getParamIndex(key)];
    };

    p.getStringField = function(key, block) {
        return String(this.getField(key));
    };

    p.getNumberField = function(key) {
        return Number(this.getField(key));
    };

    p.getStatement = function(key, block) {
        return this.executor.stepInto(
            this.block.statements[this._getStatementIndex(key, block)]
        );
    };

    p._getParamIndex = function(key) {
        if (!this._schema) this._schema = Entry.block[this.type];
        return this._schema.paramsKeyMap[key];
    };

    p._getStatementIndex = function(key) {
        if (!this._schema) this._schema = Entry.block[this.type];
        return this._schema.statementsKeyMap[key];
    };

    p.die = function() {
        this.block = null;
        return Entry.STATIC.BREAK;
    };
})(Entry.Scope.prototype);
<|endoftext|>