<commit_before>/**
 * Copyright (c) 2016 Kinvey Inc.
 *
 * 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.
 */

const data = require('./service/data');
const isNil = require('lodash.isnil');
const flex = require('../package.json');
const functions = require('./service/functions');
const auth = require('./service/auth');
const moduleGenerator = require('./service/moduleGenerator');
const logger = require('./service/logger');
const receiver = require('kinvey-code-task-runner');

class Flex {
  constructor(options, callback) {
    if (!callback && typeof options === 'function') {
      callback = options;
    }

    options = options || {};

    options.type = process.env.SDK_RECEIVER === 'tcp' ? 'tcp' : 'http';

    if (options.type === 'tcp') {
      delete options.host;
      delete options.port;
    }

    this.data = this.dataLink = data;
    this.functions = this.businessLogic = functions;
    this.auth = auth;
    this.logger = logger;
    this.moduleGenerator = moduleGenerator;
    this.version = flex.version;

    // TODO Remove legacy taskType values
    const taskReceivedCallback = ((task, completionCallback) => {
      task.sdkVersion = this.version;
      if ((!this[task.taskType] && task.taskType !== 'serviceDiscovery') || task.taskType === 'logger' || task.taskType === 'moduleGenerator') {
        return new Error('Invalid task Type');
      }

      if (task.taskType === 'serviceDiscovery') {
        task.discoveryObjects = {
          dataLink: {
            serviceObjects: this.data.getServiceObjects()
          },
          businessLogic: {
            handlers: this.functions.getHandlers()
          },
          auth: {
            handlers: this.auth.getHandlers()
          }
        };
        return completionCallback(null, task);
      }

      return this[task.taskType].process(task, this.moduleGenerator.generate(task), completionCallback);
    });

    receiver.start(options, taskReceivedCallback, (err) => {
      if (!isNil(err)) {
        return callback(new Error(`Could not start task receiver: ${err}`));
      }
      return callback(null, this);
    });
  }
}

function generateFlexService(options, callback) {
  if (!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }

  return new Flex(options, (err, service) => {
    callback(err, service);
  });
}

exports.service = generateFlexService;
<commit_msg>Better handle task type error<commit_after>/**
 * Copyright (c) 2016 Kinvey Inc.
 *
 * 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.
 */

const data = require('./service/data');
const isNil = require('lodash.isnil');
const flex = require('../package.json');
const functions = require('./service/functions');
const auth = require('./service/auth');
const moduleGenerator = require('./service/moduleGenerator');
const logger = require('./service/logger');
const receiver = require('kinvey-code-task-runner');
const kinveyErrors = require('kinvey-datalink-errors');

class Flex {
  constructor(options, callback) {
    if (!callback && typeof options === 'function') {
      callback = options;
    }

    options = options || {};

    options.type = process.env.SDK_RECEIVER === 'tcp' ? 'tcp' : 'http';

    if (options.type === 'tcp') {
      delete options.host;
      delete options.port;
    }

    this.data = this.dataLink = data;
    this.functions = this.businessLogic = functions;
    this.auth = auth;
    this.logger = logger;
    this.moduleGenerator = moduleGenerator;
    this.version = flex.version;

    // TODO Remove legacy taskType values
    const taskReceivedCallback = ((task, completionCallback) => {
      task.sdkVersion = this.version;
      if ((!this[task.taskType] && task.taskType !== 'serviceDiscovery') || task.taskType === 'logger' || task.taskType === 'moduleGenerator') {
        task.response = task.response || {};
        const result = task.response;
        result.body = kinveyErrors.generateKinveyError('BadRequest', 'Invalid task Type');
        result.statusCode = result.body.statusCode;
        delete result.body.statusCode;
        return completionCallback(task);
      }

      if (task.taskType === 'serviceDiscovery') {
        task.discoveryObjects = {
          dataLink: {
            serviceObjects: this.data.getServiceObjects()
          },
          businessLogic: {
            handlers: this.functions.getHandlers()
          },
          auth: {
            handlers: this.auth.getHandlers()
          }
        };
        return completionCallback(null, task);
      }

      return this[task.taskType].process(task, this.moduleGenerator.generate(task), completionCallback);
    });

    receiver.start(options, taskReceivedCallback, (err) => {
      if (!isNil(err)) {
        return callback(new Error(`Could not start task receiver: ${err}`));
      }
      return callback(null, this);
    });
  }
}

function generateFlexService(options, callback) {
  if (!callback && typeof options === 'function') {
    callback = options;
    options = null;
  }

  return new Flex(options, (err, service) => {
    callback(err, service);
  });
}

exports.service = generateFlexService;
<|endoftext|>


<commit_before>function upvoltPlug(cb) {
  /*global csrfToken*/
  var req = new XMLHttpRequest();

  var target = location.origin
    + location.pathname.replace(/\/?$/, '/')
    + 'upvolt';

  req.open('POST', target, true);
  req.onreadystatechange = function (aEvt) {
    if (req.readyState == 4) {
      if(req.status == 200)
        cb(null,JSON.parse(req.responseText));
      else
        cb(JSON.parse(req.responseText));
    }
  };
  req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
  req.send('_csrf='+csrfToken);
}

document.getElementById('upvolt-button').addEventListener('click',
  function(evt) {

  upvoltPlug(function(err,result) {
    if (err) return console.log(err);

    evt.target.textContent = result.upvolts + ' Upvolts';

    if (result.upvolted) {
      evt.target.className = 'upvolted';
    } else {
      evt.target.className = '';
    }
  });
});<commit_msg>Update only the count span when setting upvolt counts<commit_after>function upvoltPlug(cb) {
  /*global csrfToken*/
  var req = new XMLHttpRequest();

  var target = location.origin
    + location.pathname.replace(/\/?$/, '/')
    + 'upvolt';

  req.open('POST', target, true);
  req.onreadystatechange = function (aEvt) {
    if (req.readyState == 4) {
      if(req.status == 200)
        cb(null,JSON.parse(req.responseText));
      else
        cb(JSON.parse(req.responseText));
    }
  };
  req.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
  req.send('_csrf='+csrfToken);
}
(function(button, count){
  button.addEventListener('click',
    function(evt) {

    upvoltPlug(function(err,result) {
      if (err) return console.log(err);

      count.textContent = result.upvolts;

      if (result.upvolted) {
        button.className = 'upvolted';
      } else {
        button.className = '';
      }
    });
  });
})(document.getElementById('upvolt-button'),
  document.getElementById('upvolt-count'));
<|endoftext|>


<commit_before>/* jslint node: true, esnext: true */

"use strict";

const log4js = require('log4js');
const logger = log4js.getLogger('kronos-service-manager:flow');
logger.setLevel(log4js.levels.ERROR);

const channel = require("./channel");

const kronosStep = require('kronos-step');

/**
 * The template object
 */
const RootStep = {
  toString() {
      return this.name;
    },
    toJSON() {
      const json = {
        name: this.name,
        description: this.description,
        endpoints: this.endpoints,
        config: this.config,
        steps: this.steps
      };

      return json;
    },
    initialize(manager, parentStep) {
      for (let sid in this.steps) {
        const step = this.steps[sid];

        try {
          step.meta.initialize(manager, step);
        } catch (e) {
          // TODO
          logger.error(`error: ${e} ${step.meta.name}`);
          logger.error(`initialize ${this}/${step.name}: ${e}`);
        }
      }
    }
};

/*
 * Creates a series of steps from a json definition
 * @param manager the manager we belong to
 * @param definition the step definition
 * @param pr progress reporter to use
 * @return {object} object with channels and steps
 */
function createSteps(manager, definition, pr) {
  const steps = {};
  const channels = {};

  try {
    for (let stepName in definition) {
      logger.debug(`Iterate step definition to create steps : ${stepName}`);

      pr.pushScope('step', {
        step: stepName
      });

      const stepDef = definition[stepName];
      const stepImpl = manager.stepImplementations[stepDef.type || 'kronos-group'];

      if (!stepImpl) {
        pr.error('Step ${type} implementation not found', {
          type: stepDef.type
        });
        continue;
      }

      const endpoints = {};
      const config = stepDef.config;
      const stepProperties = {
        name: {
          value: stepName
        },
        endpoints: {
          value: endpoints
        },
        config: {
          value: config
        },
        meta: {
          value: stepImpl
        }
      };

      if (stepDef.steps) {
        const o = createSteps(manager, stepDef.steps, pr);
        const subSteps = o.steps;
        const subChannels = o.channels;

        stepProperties.steps = {
          value: subSteps
        };
        stepProperties.channels = {
          value: subChannels
        };
      }

      if (stepDef.endpoints) {
        for (let endpointName in stepImpl.endpoints) {
          logger.debug(`Step : '${stepName}' implemented endpoints '${endpointName}'`);
          endpoints[endpointName] = kronosStep.createEndpoint(endpointName,
            stepDef.endpoints[endpointName],
            stepImpl.endpoints[endpointName]
          );
        }

        // declared but not listed in implementation
        for (let endpointName in stepDef.endpoints) {
          if (endpoints[endpointName]) continue;
          logger.debug(`Step : '${stepName}' declared endpoints '${endpointName}' not implemented`);
          endpoints[endpointName] = kronosStep.createEndpoint(endpointName,
            stepDef.endpoints[endpointName]);
        }
      }

      steps[stepName] = Object.create(stepImpl, stepProperties);
      logger.debug(`Step '${stepName}' created`);

      pr.popScope();
    }

    for (let stepName in steps) {
      const step = steps[stepName];

      logger.debug(`Iterate created steps : ${stepName}`);

      pr.pushScope('step', {
        step: stepName
      });

      for (let endpointName in step.endpoints) {
        logger.debug(`Iterate endpoint '${endpointName}' of step '${stepName}'`);

        const endpoint = step.endpoints[endpointName];

        // code already assigned -> nothing more to do
        if (!endpoint.implementation) {
          let m = endpoint.target.match(/^([a-z][a-z0-9_]*):?(.*)/);

          if (m) {
            const scheme = m[1];
            const suffix = m[2];
            const ei = manager.endpointSchemeImplementations[scheme];
            if (ei) {
              step.addEndpoint(kronosStep.createEndpoint(endpointName, ei.implementation, endpoint));
            } else {
              if (scheme === 'step') {
                if ((m = suffix.match(/^([^\/]+)\/([^\/]+)(\/(.+))?/))) {
                  let targetEndpointName;
                  let targetStep;

                  if (m[1] === 'steps') { // alias
                    // The endpoint links to sub steps
                    let targetStepName = m[2];
                    targetEndpointName = m[4];
                    targetStep = step.steps[targetStepName];

                    if (targetStep) {
                      step.addEndpoint(kronosStep.createEndpoint(endpointName, targetStep.endpoints[
                        targetEndpointName]));
                    } else {
                      pr.error('Unknown target step: steps/${step}', {
                        step: targetStepName
                      });
                    }
                  } else {
                    let targetStepName = m[1];
                    targetEndpointName = m[2];
                    targetStep = steps[targetStepName];

                    if (targetStep) {
                      let targetEndpoint = targetStep.endpoints[targetEndpointName];

                      if (!targetEndpoint) {
                        targetStep.addEndpoint(kronosStep.createEndpoint(targetEndpointName,
                          endpoint));
                      }

                      if (targetEndpoint) {
                        try {
                          const chl = channel.create(step, endpoint, targetStep, targetEndpoint);
                          channels[chl.name] = channel;
                          step.endpoints[endpointName] = chl.endpointA;
                          targetStep.endpoints[targetEndpointName] = chl.endpointB;
                        } catch (e) {
                          pr.error(
                            'Unable to create channel: ${error} ${step}/${endpointA}<>${targetStep}/${endpointB}', {
                              targetStep: targetStepName,
                              endpointA: endpoint.name,
                              endpointB: targetEndpoint.name,
                              error: e
                            });
                        }
                      }
                    } else {
                      pr.error('Unknown target step: ${step}', {
                        step: targetStepName
                      });
                    }
                  }
                }
              }
              /*pr.error('No implementation for endpoint ${endpoint}', {
						  endpoint: endpoint.target
						});*/
            }
          }
        }
      }

      // finally report mandatory but missing endpoints
      for (let endpointName in step.meta.endpoints) {
        const metaEndpoint = step.meta.endpoints[endpointName];

        if (metaEndpoint.mandatory && !step.endpoints[endpointName]) {
          pr.error('Mandatory ${endpoint} not defined', {
            endpoint: endpointName
          });
        }
      }

      pr.popScope();
    }
  } catch (e) {
    pr.error('Mandatory ${error} not defined', {
      error: error
    });
  }

  return {
    steps,
    channels
  };
}

/**
 * function - Creates flows from the JSON object
 *
 * @param  {object} manager         The service manager
 * @param  {object} flowDefinitions The Json object describing the flows
 * @param  {object} progressReporter The progress reporter
 * @return {array}                  The created flows
 */
exports.create = function (manager, flowDefinitions, progressReporter) {

  if (!progressReporter) {
    throw ("No Prgress reporter given.");
  }

  const newFlows = [];

  for (let flowName in flowDefinitions) {
    logger.debug(`Create new flow '${flowName}'`);

    const definition = flowDefinitions[flowName];

    progressReporter.pushScope('flow', {
      flow: flowName
    });

    const o = createSteps(manager, definition.steps, progressReporter);
    const steps = o.steps;
    const channels = o.channels;

    newFlows[flowName] = Object.create(RootStep, {
      name: {
        value: flowName
      },
      steps: {
        value: steps
      },
      channels: {
        value: channels,
      },
      description: {
        value: definition.description
      }
    });
    // TODO belongs here: progressReporter.popScope();
  }
  return newFlows;
};
<commit_msg>fix: removed duplocate log<commit_after>/* jslint node: true, esnext: true */

"use strict";

const log4js = require('log4js');
const logger = log4js.getLogger('kronos-service-manager:flow');
logger.setLevel(log4js.levels.ERROR);

const channel = require("./channel");

const kronosStep = require('kronos-step');

/**
 * The template object
 */
const RootStep = {
  toString() {
      return this.name;
    },
    toJSON() {
      const json = {
        name: this.name,
        description: this.description,
        endpoints: this.endpoints,
        config: this.config,
        steps: this.steps
      };

      return json;
    },
    initialize(manager, parentStep) {
      for (let sid in this.steps) {
        const step = this.steps[sid];

        try {
          step.meta.initialize(manager, step);
        } catch (e) {
          // TODO
          logger.error(`error: ${e} ${step.meta.name}`);
        }
      }
    }
};

/*
 * Creates a series of steps from a json definition
 * @param manager the manager we belong to
 * @param definition the step definition
 * @param pr progress reporter to use
 * @return {object} object with channels and steps
 */
function createSteps(manager, definition, pr) {
  const steps = {};
  const channels = {};

  try {
    for (let stepName in definition) {
      logger.debug(`Iterate step definition to create steps : ${stepName}`);

      pr.pushScope('step', {
        step: stepName
      });

      const stepDef = definition[stepName];
      const stepImpl = manager.stepImplementations[stepDef.type || 'kronos-group'];

      if (!stepImpl) {
        pr.error('Step ${type} implementation not found', {
          type: stepDef.type
        });
        continue;
      }

      const endpoints = {};
      const config = stepDef.config;
      const stepProperties = {
        name: {
          value: stepName
        },
        endpoints: {
          value: endpoints
        },
        config: {
          value: config
        },
        meta: {
          value: stepImpl
        }
      };

      if (stepDef.steps) {
        const o = createSteps(manager, stepDef.steps, pr);
        const subSteps = o.steps;
        const subChannels = o.channels;

        stepProperties.steps = {
          value: subSteps
        };
        stepProperties.channels = {
          value: subChannels
        };
      }

      if (stepDef.endpoints) {
        for (let endpointName in stepImpl.endpoints) {
          logger.debug(`Step : '${stepName}' implemented endpoints '${endpointName}'`);
          endpoints[endpointName] = kronosStep.createEndpoint(endpointName,
            stepDef.endpoints[endpointName],
            stepImpl.endpoints[endpointName]
          );
        }

        // declared but not listed in implementation
        for (let endpointName in stepDef.endpoints) {
          if (endpoints[endpointName]) continue;
          logger.debug(`Step : '${stepName}' declared endpoints '${endpointName}' not implemented`);
          endpoints[endpointName] = kronosStep.createEndpoint(endpointName,
            stepDef.endpoints[endpointName]);
        }
      }

      steps[stepName] = Object.create(stepImpl, stepProperties);
      logger.debug(`Step '${stepName}' created`);

      pr.popScope();
    }

    for (let stepName in steps) {
      const step = steps[stepName];

      logger.debug(`Iterate created steps : ${stepName}`);

      pr.pushScope('step', {
        step: stepName
      });

      for (let endpointName in step.endpoints) {
        logger.debug(`Iterate endpoint '${endpointName}' of step '${stepName}'`);

        const endpoint = step.endpoints[endpointName];

        // code already assigned -> nothing more to do
        if (!endpoint.implementation) {
          let m = endpoint.target.match(/^([a-z][a-z0-9_]*):?(.*)/);

          if (m) {
            const scheme = m[1];
            const suffix = m[2];
            const ei = manager.endpointSchemeImplementations[scheme];
            if (ei) {
              step.addEndpoint(kronosStep.createEndpoint(endpointName, ei.implementation, endpoint));
            } else {
              if (scheme === 'step') {
                if ((m = suffix.match(/^([^\/]+)\/([^\/]+)(\/(.+))?/))) {
                  let targetEndpointName;
                  let targetStep;

                  if (m[1] === 'steps') { // alias
                    // The endpoint links to sub steps
                    let targetStepName = m[2];
                    targetEndpointName = m[4];
                    targetStep = step.steps[targetStepName];

                    if (targetStep) {
                      step.addEndpoint(kronosStep.createEndpoint(endpointName, targetStep.endpoints[
                        targetEndpointName]));
                    } else {
                      pr.error('Unknown target step: steps/${step}', {
                        step: targetStepName
                      });
                    }
                  } else {
                    let targetStepName = m[1];
                    targetEndpointName = m[2];
                    targetStep = steps[targetStepName];

                    if (targetStep) {
                      let targetEndpoint = targetStep.endpoints[targetEndpointName];

                      if (!targetEndpoint) {
                        targetStep.addEndpoint(kronosStep.createEndpoint(targetEndpointName,
                          endpoint));
                      }

                      if (targetEndpoint) {
                        try {
                          const chl = channel.create(step, endpoint, targetStep, targetEndpoint);
                          channels[chl.name] = channel;
                          step.endpoints[endpointName] = chl.endpointA;
                          targetStep.endpoints[targetEndpointName] = chl.endpointB;
                        } catch (e) {
                          pr.error(
                            'Unable to create channel: ${error} ${step}/${endpointA}<>${targetStep}/${endpointB}', {
                              targetStep: targetStepName,
                              endpointA: endpoint.name,
                              endpointB: targetEndpoint.name,
                              error: e
                            });
                        }
                      }
                    } else {
                      pr.error('Unknown target step: ${step}', {
                        step: targetStepName
                      });
                    }
                  }
                }
              }
              /*pr.error('No implementation for endpoint ${endpoint}', {
						  endpoint: endpoint.target
						});*/
            }
          }
        }
      }

      // finally report mandatory but missing endpoints
      for (let endpointName in step.meta.endpoints) {
        const metaEndpoint = step.meta.endpoints[endpointName];

        if (metaEndpoint.mandatory && !step.endpoints[endpointName]) {
          pr.error('Mandatory ${endpoint} not defined', {
            endpoint: endpointName
          });
        }
      }

      pr.popScope();
    }
  } catch (e) {
    pr.error('Mandatory ${error} not defined', {
      error: error
    });
  }

  return {
    steps,
    channels
  };
}

/**
 * function - Creates flows from the JSON object
 *
 * @param  {object} manager         The service manager
 * @param  {object} flowDefinitions The Json object describing the flows
 * @param  {object} progressReporter The progress reporter
 * @return {array}                  The created flows
 */
exports.create = function (manager, flowDefinitions, progressReporter) {

  if (!progressReporter) {
    throw ("No Prgress reporter given.");
  }

  const newFlows = [];

  for (let flowName in flowDefinitions) {
    logger.debug(`Create new flow '${flowName}'`);

    const definition = flowDefinitions[flowName];

    progressReporter.pushScope('flow', {
      flow: flowName
    });

    const o = createSteps(manager, definition.steps, progressReporter);
    const steps = o.steps;
    const channels = o.channels;

    newFlows[flowName] = Object.create(RootStep, {
      name: {
        value: flowName
      },
      steps: {
        value: steps
      },
      channels: {
        value: channels,
      },
      description: {
        value: definition.description
      }
    });
    // TODO belongs here: progressReporter.popScope();
  }
  return newFlows;
};
<|endoftext|>


<commit_before>var getIndex = require('./utils/getIndex');

module.exports = function() {
  this.Given(/^I submit the form$/, function(callback) {
    return driver.findElement(by.css('button[type="submit"]')).click().then(function() {
      callback();
    });
  });

  /**
   * Fill in a text input or textarea with some text
   * @param string Matches either the inputs name attribute or its label text
   * @param string The text to input
   */
  this.Given(/^I fill in "([^"]*)" with "([^"]*)"$/, function(arg1, arg2, callback) {
    var action = function(input) {
      input.clear();
      input.sendKeys(arg2).then(function() {
        callback();
      });
    };

    if (arg2.indexOf('%') !== -1) {
      arg2 = parameters[arg2.replace(/%/g, '')];
    }

    if (arg1.indexOf('#') !== -1) {
      arg1 = arg1.replace('#', '');
      driver.findElement(by.id(arg1)).then(function(input) {
        action(input);
      }).addErrback(function(e) {
        callback.fail(e.message);
      });
    } else {
      driver.findElement(by.xpath('//input[name="' + arg1 + '"]')).then(function(input) {
        action(input);
      }).addErrback(function(e) {
        driver.findElement(by.xpath('//label[text()="' + arg1 + '"]')).then(function(label) {
          label.getAttribute('for').then(function(id) {
            browser.findElement(by.id(id)).then(function(input) {
              action(input);
            });
          });
        }).addErrback(function(e) {
          callback.fail(e.message);
        });
      });
    }
  });

  this.Given(/^I select "([^"]*)" from "([^"]*)"$/, function(arg1, arg2, callback) {
    var option,
        opts;

    if (arg2.match(/\..*/)) { // find by class
      opts = browser.findElements(by.css(arg2 + ' option'));
    } else { //find by select name
      opts = browser.findElements(by.css('select[name="' + arg2 + '"] option'));
    }

    opts.then(function(elems) {
      elems.forEach(function(v, i) {
        v.getText().then(function(text) {
          if (text === arg1) {
            option = v;
            v.click().then(function() {
              callback();
            });
          }
        });
      });
    });
  });

  this.Given(/^I select "([^"]*)" and "([^"]*)" from "([^"]*)"$/, function(arg1, arg2, arg3, callback) {
    var selectCount = 0,
        opts;

    if (arg3.match(/\..*/)) { // find by class
      opts = browser.findElements(by.css(arg3 + ' option'));
    } else { //find by select name
      opts = browser.findElements(by.css('select[name="' + arg3 + '"] option'));
    }

    opts.then(function(elems) {
      elems.forEach(function(v, i) {
        v.getText().then(function(text) {
          if (text === arg1 || text === arg2) {
            v.click().then(function() {
              selectCount++;
              if (selectCount === 2) {
                callback();
              }
            });
          }
        });
      });
    });
  });

  this.Then(/^I fill in the "([^"]*)" "([^"]*)" input with "([^"]*)"$/, function(arg1, arg2, arg3, callback) {
    browser.findElements(by.css(arg2)).then(function(elems) {
      var el = elems[getIndex(arg1)];
      el.clear();
      el.sendKeys(arg3).then(function() {
        callback();
      });
    });
  });

  /**
   * Simulate a file upload
   * @param string   arg1 Matches either the inputs name attribute or its label text
   * @param string   arg1 The text to input
   * @param function callback
   */
  this.Given(/^I upload "([^"]*)" with "([^"]*)"$/, function(arg1, arg2, callback) {
    var action = function(input) {
      input.sendKeys(arg2).then(function() {
        callback();
      });
    };

    if (arg2.indexOf('%') !== -1) {
      arg2 = parameters[arg2.replace(/%/g, '')];
    }

    if (arg1.indexOf('#') !== -1) {
      arg1 = arg1.replace('#', '');
      driver.findElement(by.id(arg1)).then(function(input) {
        action(input);
      }).addErrback(function(e) {
        callback.fail(e.message);
      });
    } else {
      driver.findElement(by.xpath('//input[name="' + arg1 + '"]')).then(function(input) {
        action(input);
      }).addErrback(function(e) {
        driver.findElement(by.xpath('//label[text()="' + arg1 + '"]')).then(function(label) {
          label.getAttribute('for').then(function(id) {
            browser.findElement(by.id(id)).then(function(input) {
              action(input);
            });
          });
        }).addErrback(function(e) {
          callback.fail(e.message);
        });
      });
    }
  });

  this.Given(/^I choose "([^"]*)" from "([^"]*)"$/, function(arg1, arg2, callback) {
    browser.findElement(by.css('select[name="' + arg2 + '"]')).then(function(elem) {
      elem.getAttribute('id').then(function(id) {
        browser.findElement(by.id(id + '_chosen')).then(function(chosenContainer) {
          chosenContainer.click().then(function() {
            browser.findElement(by.xpath('//li[text()="' + arg1 + '"]')).then(function(option) {
              option.click().then(function() {
                callback();
              });
            });
          });
        });
      });
    });
  });

  this.Given(/^I choose "([^"]*)" and "([^"]*)" from "([^"]*)"$/, function(arg1, arg2, arg3, callback) {
    browser.findElement(by.css('select[name="' + arg3 + '"]')).then(function(elem) {
      elem.getAttribute('id').then(function(id) {
        browser.findElement(by.id(id + '_chosen')).then(function(chosenContainer) {
          chosenContainer.click().then(function() {
            browser.findElement(by.xpath('//li[text()="' + arg1 + '"]')).then(function(option) {
              option.click().then(function() {
                chosenContainer.click().then(function() {
                  browser.findElement(by.xpath('//li[text()="' + arg2 + '"]')).then(function(option) {
                    option.click().then(function() {
                      callback();
                    });
                  });
                });
              });
            });
          });
        });
      });
    });
  });
};
<commit_msg>speed up input filling<commit_after>var getIndex = require('./utils/getIndex');

module.exports = function() {
  this.Given(/^I submit the form$/, function(callback) {
    return driver.findElement(by.css('button[type="submit"]')).click().then(function() {
      callback();
    });
  });

  /**
   * Fill in a text input or textarea with some text
   * @param string Matches either the inputs name attribute or its label text
   * @param string The text to input
   */
  this.Given(/^I fill in "([^"]*)" with "([^"]*)"$/, function(arg1, arg2, callback) {
    var action = function(input) {
      input.clear();
      input.sendKeys(arg2).then(function() {
        callback();
      });
    };

    // replace parameter value
    if (arg2.indexOf('%') !== -1) {
      arg2 = parameters[arg2.replace(/%/g, '')];
    }

    // find by id if hash is found
    if (arg1.indexOf('#') !== -1) {
      arg1 = arg1.replace('#', '');
      driver.findElement(by.id(arg1)).then(function(input) {
        action(input);
      }).addErrback(function(e) {
        callback.fail(e.message);
      });
    } else {
      // find by label if first letter of arg1 is capitalized
      if (/[A-Z]/.test(arg1[0])) {
        driver.findElement(by.xpath('//label[text()="' + arg1 + '"]')).then(function(label) {
          label.getAttribute('for').then(function(id) {
            browser.findElement(by.id(id)).then(function(input) {
              action(input);
            });
          });
        }).addErrback(function(e) {
          callback.fail(e.message);
        });
      } else {
        // find by name attribute
        driver.findElement(by.xpath('//[name="' + arg1 + '"]')).then(function(input) {
          action(input);
        }).addErrback(function(e) {
          callback.fail(e.message);
        });
      }
    }
  });

  this.Given(/^I select "([^"]*)" from "([^"]*)"$/, function(arg1, arg2, callback) {
    var option,
        opts;

    if (arg2.match(/\..*/)) { // find by class
      opts = browser.findElements(by.css(arg2 + ' option'));
    } else { //find by select name
      opts = browser.findElements(by.css('select[name="' + arg2 + '"] option'));
    }

    opts.then(function(elems) {
      elems.forEach(function(v, i) {
        v.getText().then(function(text) {
          if (text === arg1) {
            option = v;
            v.click().then(function() {
              callback();
            });
          }
        });
      });
    });
  });

  this.Given(/^I select "([^"]*)" and "([^"]*)" from "([^"]*)"$/, function(arg1, arg2, arg3, callback) {
    var selectCount = 0,
        opts;

    if (arg3.match(/\..*/)) { // find by class
      opts = browser.findElements(by.css(arg3 + ' option'));
    } else { //find by select name
      opts = browser.findElements(by.css('select[name="' + arg3 + '"] option'));
    }

    opts.then(function(elems) {
      elems.forEach(function(v, i) {
        v.getText().then(function(text) {
          if (text === arg1 || text === arg2) {
            v.click().then(function() {
              selectCount++;
              if (selectCount === 2) {
                callback();
              }
            });
          }
        });
      });
    });
  });

  this.Then(/^I fill in the "([^"]*)" "([^"]*)" input with "([^"]*)"$/, function(arg1, arg2, arg3, callback) {
    browser.findElements(by.css(arg2)).then(function(elems) {
      var el = elems[getIndex(arg1)];
      el.clear();
      el.sendKeys(arg3).then(function() {
        callback();
      });
    });
  });

  /**
   * Simulate a file upload
   * @param string   arg1 Matches either the inputs name attribute or its label text
   * @param string   arg1 The text to input
   * @param function callback
   */
  this.Given(/^I upload "([^"]*)" with "([^"]*)"$/, function(arg1, arg2, callback) {
    var action = function(input) {
      input.sendKeys(arg2).then(function() {
        callback();
      });
    };

    if (arg2.indexOf('%') !== -1) {
      arg2 = parameters[arg2.replace(/%/g, '')];
    }

    if (arg1.indexOf('#') !== -1) {
      arg1 = arg1.replace('#', '');
      driver.findElement(by.id(arg1)).then(function(input) {
        action(input);
      }).addErrback(function(e) {
        callback.fail(e.message);
      });
    } else {
      driver.findElement(by.xpath('//input[name="' + arg1 + '"]')).then(function(input) {
        action(input);
      }).addErrback(function(e) {
        driver.findElement(by.xpath('//label[text()="' + arg1 + '"]')).then(function(label) {
          label.getAttribute('for').then(function(id) {
            browser.findElement(by.id(id)).then(function(input) {
              action(input);
            });
          });
        }).addErrback(function(e) {
          callback.fail(e.message);
        });
      });
    }
  });

  this.Given(/^I choose "([^"]*)" from "([^"]*)"$/, function(arg1, arg2, callback) {
    browser.findElement(by.css('select[name="' + arg2 + '"]')).then(function(elem) {
      elem.getAttribute('id').then(function(id) {
        browser.findElement(by.id(id + '_chosen')).then(function(chosenContainer) {
          chosenContainer.click().then(function() {
            browser.findElement(by.xpath('//li[text()="' + arg1 + '"]')).then(function(option) {
              option.click().then(function() {
                callback();
              });
            });
          });
        });
      });
    });
  });

  this.Given(/^I choose "([^"]*)" and "([^"]*)" from "([^"]*)"$/, function(arg1, arg2, arg3, callback) {
    browser.findElement(by.css('select[name="' + arg3 + '"]')).then(function(elem) {
      elem.getAttribute('id').then(function(id) {
        browser.findElement(by.id(id + '_chosen')).then(function(chosenContainer) {
          chosenContainer.click().then(function() {
            browser.findElement(by.xpath('//li[text()="' + arg1 + '"]')).then(function(option) {
              option.click().then(function() {
                chosenContainer.click().then(function() {
                  browser.findElement(by.xpath('//li[text()="' + arg2 + '"]')).then(function(option) {
                    option.click().then(function() {
                      callback();
                    });
                  });
                });
              });
            });
          });
        });
      });
    });
  });
};
<|endoftext|>


<commit_before>/*
 * fuel
 * https://github.com/ExactTarget/node-fuel
 *
 * Copyright (c) 2013 ExactTarget
 * Licensed under the MIT license.
 */

var extend = require('extend');
var request = require('request');

function fuel(options, callback) {

	fuel.token(options, function (error, response, body) {
		if (error) {
			callback(error);
		} else {
			options.json = true;
			options.headers = options.headers || {};
			options.headers.authorization = 'Bearer ' + body.accessToken;

			fuel._performRequest(options, callback);
		}
	});
}

fuel.token = function (options, callback) {

	if (!fuel._validateOptions(options, callback)) return;

	var authOptions = {
		url: options.authUrl,
		method: 'POST',
		json: true,
		body: {
			clientId: options.clientId,
			clientSecret: options.clientSecret
		}
	};

	if (options.accessType) authOptions.body.accessType = options.accessType;
	if (options.refreshToken) authOptions.body.refreshToken = options.refreshToken;
	if (options.scope) authOptions.body.scope = options.scope;

	var authOptionsHash = fuel._authOptionsHash(authOptions);

	if (fuel._refreshTokenCache[authOptionsHash]) {
		authOptions.body.refreshToken = fuel._refreshTokenCache[authOptionsHash];
	}

	fuel._performTokenRequest(authOptions, function (error, response, body) {
		if (error) {
			callback(error);
		} else {
			if (body.refreshToken) {
				fuel._refreshTokenCache[authOptionsHash] = body.refreshToken;
			}
			callback(error, response, body);
		}
	});
};

fuel.configure = createConfigurationWrapper(fuel);
fuel.token.configure = createConfigurationWrapper(fuel.token);

fuel._validateOptions = function (options, callback) {
	var message = null;

	// When validating, handle the negations first
	if (!options) {
		message = 'options object is required';
	} else if (!options.authUrl) {
		message = 'authUrl is required';
	} else if (!options.clientId || !fuel._verifyAPIKey('clientId', options.clientId)) {
		message = 'clientId is missing or invalid';
	} else if (!options.clientSecret || !fuel._verifyAPIKey('clientSecret', options.clientSecret)) {
		message = 'clientSecret is missing or invalid';
	}

	// Something is wrong, notifiy the user
	if (null !== message) {
		callback(new Error(message));
		return false;
	} else {
		// Should only be here if all is well
		return true;
	}
};

fuel._verifyAPIKey = function (APIKeyType, key) {
	var check = false;
	var idPattern = /^[a-z0-9]{24}$/;
	var secretPattern = /^[a-zA-Z0-9]{24}$/;

	if ('clientId' === APIKeyType) {
		check = idPattern.test(key);
	} else if ('clientSecret' === APIKeyType) {
		check = secretPattern.test(key);
	}

	return check;
};

fuel._removeAuthOptions = function (options) {
	options = extend(true, {}, options);
	delete options.clientId;
	delete options.clientSecret;
	delete options.refreshToken;
	delete options.accessType;
	delete options.authUrl;
	delete options.scope;
	return options;
};

fuel._performRequest = function (options, callback) {
	return request(fuel._removeAuthOptions(options), callback);
};

fuel._performTokenRequest = memoize(fuel._performRequest, function (options) {
	// Cache response per unique set of options
	return fuel._authOptionsHash(options);
}, function (error, response, body) {
	// Cache errors for 10 seconds, tokens until 30 seconds before expiration
	return (error) ? 10000 : (body.expiresIn - 30) * 1000;
});

fuel._authOptionsHash = function (options) {
	return options.url + options.body.clientId + options.body.scope;
};

fuel._refreshTokenCache = {};

module.exports = fuel;

// Utility

function createConfigurationWrapper(func) {
	return function (storedOptions) {
		return function (options, callback) {
			if (!callback) {
				callback = options;
				options = {};
			}
			return func(extend(true, {}, storedOptions, options), callback);
		};
	};
}

function memoize(fn, hasher, invalidator) {
	var exp = {};
	var memo = {};
	var queues = {};
	hasher = hasher || function (x) {
		return x;
	};
	invalidator = invalidator || function () {};
	var memoized = function () {
		var args = Array.prototype.slice.call(arguments);
		var callback = args.pop();
		var key = hasher.apply(null, args);
		reap();
		if (key in memo) {
			callback.apply(null, memo[key]);
		}
		else if (key in queues) {
			queues[key].push(callback);
		}
		else {
			queues[key] = [callback];
			fn.apply(null, args.concat([function () {
				var timeout = invalidator.apply(null, arguments);
				if (timeout) {
					exp[key] = Date.now() + timeout;
				}
				memo[key] = arguments;
				var q = queues[key];
				delete queues[key];
				for (var i = 0, l = q.length; i < l; i += 1) {
					q[i].apply(null, arguments);
				}
			}]));
		}
	};
	var reap = function () {
		var i;
		var key;
		var keys = Object.keys(memo);
		var length;
		var now = Date.now();

		for (i = 0, length = keys.length; i < length; i += 1) {
			if (key in exp && exp[key] <= now) {
				delete exp[key];
				delete memo[key];
			}
		}
	};
	memoized.unmemoized = fn;
	return memoized;
}
<commit_msg>Use monotonic clock to expire memorized functions<commit_after>/*
 * fuel
 * https://github.com/ExactTarget/node-fuel
 *
 * Copyright (c) 2013 ExactTarget
 * Licensed under the MIT license.
 */

var extend = require('extend');
var request = require('request');

function fuel(options, callback) {

	fuel.token(options, function (error, response, body) {
		if (error) {
			callback(error);
		} else {
			options.json = true;
			options.headers = options.headers || {};
			options.headers.authorization = 'Bearer ' + body.accessToken;

			fuel._performRequest(options, callback);
		}
	});
}

fuel.token = function (options, callback) {

	if (!fuel._validateOptions(options, callback)) return;

	var authOptions = {
		url: options.authUrl,
		method: 'POST',
		json: true,
		body: {
			clientId: options.clientId,
			clientSecret: options.clientSecret
		}
	};

	if (options.accessType) authOptions.body.accessType = options.accessType;
	if (options.refreshToken) authOptions.body.refreshToken = options.refreshToken;
	if (options.scope) authOptions.body.scope = options.scope;

	var authOptionsHash = fuel._authOptionsHash(authOptions);

	if (fuel._refreshTokenCache[authOptionsHash]) {
		authOptions.body.refreshToken = fuel._refreshTokenCache[authOptionsHash];
	}

	fuel._performTokenRequest(authOptions, function (error, response, body) {
		if (error) {
			callback(error);
		} else {
			if (body.refreshToken) {
				fuel._refreshTokenCache[authOptionsHash] = body.refreshToken;
			}
			callback(error, response, body);
		}
	});
};

fuel.configure = createConfigurationWrapper(fuel);
fuel.token.configure = createConfigurationWrapper(fuel.token);

fuel._validateOptions = function (options, callback) {
	var message = null;

	// When validating, handle the negations first
	if (!options) {
		message = 'options object is required';
	} else if (!options.authUrl) {
		message = 'authUrl is required';
	} else if (!options.clientId || !fuel._verifyAPIKey('clientId', options.clientId)) {
		message = 'clientId is missing or invalid';
	} else if (!options.clientSecret || !fuel._verifyAPIKey('clientSecret', options.clientSecret)) {
		message = 'clientSecret is missing or invalid';
	}

	// Something is wrong, notifiy the user
	if (null !== message) {
		callback(new Error(message));
		return false;
	} else {
		// Should only be here if all is well
		return true;
	}
};

fuel._verifyAPIKey = function (APIKeyType, key) {
	var check = false;
	var idPattern = /^[a-z0-9]{24}$/;
	var secretPattern = /^[a-zA-Z0-9]{24}$/;

	if ('clientId' === APIKeyType) {
		check = idPattern.test(key);
	} else if ('clientSecret' === APIKeyType) {
		check = secretPattern.test(key);
	}

	return check;
};

fuel._removeAuthOptions = function (options) {
	options = extend(true, {}, options);
	delete options.clientId;
	delete options.clientSecret;
	delete options.refreshToken;
	delete options.accessType;
	delete options.authUrl;
	delete options.scope;
	return options;
};

fuel._performRequest = function (options, callback) {
	return request(fuel._removeAuthOptions(options), callback);
};

fuel._performTokenRequest = memoize(fuel._performRequest, function (options) {
	// Cache response per unique set of options
	return fuel._authOptionsHash(options);
}, function (error, response, body) {
	// Cache errors for 10 seconds, tokens until 30 seconds before expiration
	return error ? 10 : (body.expiresIn - 30);
});

fuel._authOptionsHash = function (options) {
	return options.url + options.body.clientId + options.body.scope;
};

fuel._refreshTokenCache = {};

module.exports = fuel;

// Utility

function createConfigurationWrapper(func) {
	return function (storedOptions) {
		return function (options, callback) {
			if (!callback) {
				callback = options;
				options = {};
			}
			return func(extend(true, {}, storedOptions, options), callback);
		};
	};
}

function memoize(fn, hasher, invalidator) {
	var exp = {};
	var memo = {};
	var queues = {};
	hasher = hasher || function (x) {
		return x;
	};
	invalidator = invalidator || function () {};
	var memoized = function () {
		var args = Array.prototype.slice.call(arguments);
		var callback = args.pop();
		var key = hasher.apply(null, args);
		reap();
		if (key in memo) {
			callback.apply(null, memo[key]);
		}
		else if (key in queues) {
			queues[key].push(callback);
		}
		else {
			queues[key] = [callback];
			fn.apply(null, args.concat([function () {
				var timeout = invalidator.apply(null, arguments);
				if (timeout) {
					exp[key] = process.hrtime()[0] + timeout;
				}
				memo[key] = arguments;
				var q = queues[key];
				delete queues[key];
				for (var i = 0, l = q.length; i < l; i += 1) {
					q[i].apply(null, arguments);
				}
			}]));
		}
	};
	var reap = function () {
		var i;
		var key;
		var keys = Object.keys(memo);
		var length;
		var now = process.hrtime()[0];

		for (i = 0, length = keys.length; i < length; i += 1) {
			if (key in exp && exp[key] <= now) {
				delete exp[key];
				delete memo[key];
			}
		}
	};
	memoized.unmemoized = fn;
	return memoized;
}
<|endoftext|>


<commit_before>(function(undefined) {

    var parse = require('esprima').parse,
        generate = require('escodegen').generate;

    var CJS_TEMPLATE = {
            START: "module.exports = (",
            // <-- factory function -->
            MIDDLE: ")(",
            // <-- requires -->
            END: ");"
        },
        AMD_TEMPLATE = {
            START: "define([",
            // <-- dependencies -->
            MIDDLE: "],",
            // <-- factory function -->
            END: ");"
        };

    // defaults
    var NAME_TAG_PREFIX = "@name:",
        AMD_TAG_PREFIX = "@amd:",
        CJS_TAG_PREFIX = "@cjs:";

    // get pre-factory comment regex:
    var cmtLinesRe = new RegExp("^([\\s\\S]*?)\\s*function", "m");

    function Fume(sources, config) {

        config = config || {};
        config.nameTagPrefix = config.nameTagPrefix || NAME_TAG_PREFIX;
        config.amdTagPrefix = config.amdTagPrefix || AMD_TAG_PREFIX;
        config.cjsTagPrefix = config.cjsTagPrefix || CJS_TAG_PREFIX;

        var nameTagRe = new RegExp(
                "^.*?" +
                config.nameTagPrefix +
                "\\s*(\\w+)\\W*$"
            ),
            amdTagRe = new RegExp(
                "^.*?" +
                config.amdTagPrefix +
                "\\s*(\\S+)\\s+(\\S+)\\W*$"
            ),
            cjsTagRe = new RegExp(
                "^.*?" +
                config.cjsTagPrefix +
                "\\s*(\\S+)\\s+(\\S+)\\W*$"
            );

        // parse the sources and get needed information
        sources = sources.map(function(source) {

            source.tree = parse(source.code);
            source.factory = source.tree.body[0];
            source.amdMaps = {};
            source.cjsMaps = {};

            if (source.factory.type !== 'FunctionDeclaration')
                throw Error("Expected a factory function at " + source.path);

            source.args = source.factory.params;

            // get comment lines before the factory function:
            var m = source.code.match(cmtLinesRe);
            // this RegExp should always match
            if (!m) throw Error("Unable to parse pre-factory directives");
            var cLines = m[1].split(/[\n\r]/);

            // extract directives from the comment lines:
            cLines.forEach(function(line) {

                // attempt to detect the factory name:

                // first try:
                // the parse tree doesn't include comments, so we need to look
                // at the source. a simple regex to detect the @name tag
                // anywhere before the factory function:
                var m = line.match(nameTagRe);
                if (m) source.name = m[1];

                // second try:
                // if name tag isn't specified, take the function's name:
                source.name = source.name || source.factory.id.name;

                // check if this name is already taken by another factory:
                if (sources.some(function(other) {
                        return source !== other && other.name === source.name;
                    }))
                    throw Error(
                        "Factory name '" +
                        source.name +
                        "' cannot be specified more than once"
                    );

                // detect AMD mapping:
                m = line.match(amdTagRe);
                if (m) source.amdMaps[m[1]] = m[2];

                // detect CJS mapping:
                m = line.match(cjsTagRe);
                if (m) source.cjsMaps[m[1]] = m[2];

            });

            return source;

        });

        // create AMD & CJS modules from each of the sourcrs
        sources = sources.map(function(source) {

            // each of the factory's arguments needs to have a corresponding
            // 'require' (cjs) / dependency name (amd)

            var requires = source.factory.params.map(function(param) {

                var name = source.cjsMaps[param.name] || param.name;

                if (param.name === source.name)
                    throw Error(
                        "A factory cannot define itself as a dependency (" +
                        source.name +
                        ")"
                    );

                // this dependency is a sibling if one of the sources has a
                // matching name
                var sibling = sources.some(function(other) {
                    return other.name === param.name;
                });

                return "require('" + (sibling ? "./" : "") + param.name + "')";

            });

            var deps = source.factory.params.map(function(param) {

                var name = source.amdMaps[param.name] || param.name;

                if (param.name === source.name)
                    throw Error(
                        "A factory cannot define itself as a dependency (" +
                        source.name +
                        ")"
                    );

                // this dependency is a sibling if one of the sources has a
                // matching name
                var sibling = sources.some(function(other) {
                    return other.name === param.name;
                });

                return "'" + (sibling ? "./" : "") + param.name + "'";

            });

            var cjs = CJS_TEMPLATE.START +
                source.code +
                CJS_TEMPLATE.MIDDLE +
                requires.join(',') +
                CJS_TEMPLATE.END;

            var amd = AMD_TEMPLATE.START +
                deps.join(',') +
                AMD_TEMPLATE.MIDDLE +
                source.code +
                AMD_TEMPLATE.END;

            return {
                code: {
                    cjs: generate(parse(cjs)),
                    amd: generate(parse(amd))
                },
                path: source.path
            };

        });

        return sources;

    }

    module.exports = Fume;

})(void 0);
<commit_msg>Factory objects<commit_after>(function(undefined) {

    var parse = require('esprima').parse,
        generate = require('escodegen').generate;

    var CJS_TEMPLATE = {
            START: "module.exports = (",
            // <-- factory function -->
            MIDDLE: ")(",
            // <-- requires -->
            END: ");"
        },
        AMD_TEMPLATE = {
            START: "define([",
            // <-- dependencies -->
            MIDDLE: "],",
            // <-- factory function -->
            END: ");"
        };

    // defaults
    var NAME_TAG_PREFIX = "@name:",
        AMD_TAG_PREFIX = "@amd:",
        CJS_TAG_PREFIX = "@cjs:";

    // get pre-factory comment regex:
    var cmtLinesRe = new RegExp("^([\\s\\S]*?)\\s*function", "m");

    /**
     * Parse the list of sources
     */
    function Fume(sources, config) {

        config = config || {};
        config.nameTagPrefix = config.nameTagPrefix || NAME_TAG_PREFIX;
        config.amdTagPrefix = config.amdTagPrefix || AMD_TAG_PREFIX;
        config.cjsTagPrefix = config.cjsTagPrefix || CJS_TAG_PREFIX;
        this.config = config;

        var nameTagRe = new RegExp(
                "^.*?" +
                this.config.nameTagPrefix +
                "\\s*(\\w+)\\W*$"
            ),
            amdTagRe = new RegExp(
                "^.*?" +
                this.config.amdTagPrefix +
                "\\s*(\\S+)\\s+(\\S+)\\W*$"
            ),
            cjsTagRe = new RegExp(
                "^.*?" +
                this.config.cjsTagPrefix +
                "\\s*(\\S+)\\s+(\\S+)\\W*$"
            );

        // parse the sources and get needed information
        sources.forEach(function(source) {

            source.tree = parse(source.code);
            source.factory = source.tree.body[0];
            source.amdMaps = {};
            source.cjsMaps = {};

            if (source.factory.type !== 'FunctionDeclaration')
                throw Error("Expected a factory function at " + source.path);

            source.args = source.factory.params;

            // get comment lines before the factory function:
            var m = source.code.match(cmtLinesRe);
            // this RegExp should always match
            if (!m) throw Error("Unable to parse pre-factory directives");
            var cLines = m[1].split(/[\n\r]/);

            // extract directives from the comment lines:
            cLines.forEach(function(line) {

                // attempt to detect the factory name:

                // first try:
                // the parse tree doesn't include comments, so we need to look
                // at the source. a simple regex to detect the @name tag
                // anywhere before the factory function:
                var m = line.match(nameTagRe);
                if (m) source.name = m[1];

                // second try:
                // if name tag isn't specified, take the function's name:
                source.name = source.name || source.factory.id.name;

                // check if this name is already taken by another factory:
                if (sources.some(function(other) {
                        return other !== source && other.name === source.name;
                    }))
                    throw Error(
                        "Factory name '" +
                        source.name +
                        "' cannot be specified more than once"
                    );

                // detect AMD mapping:
                m = line.match(amdTagRe);
                if (m) source.amdMaps[m[1]] = m[2];

                // detect CJS mapping:
                m = line.match(cjsTagRe);
                if (m) source.cjsMaps[m[1]] = m[2];

            });

        });

        // detect sibling dependencies
        sources.forEach(function(source) {

            source.factory.params.forEach(function(param) {

                // this dependency is a sibling if one of the other sources has
                // a matching name
                param.sibling = sources.some(function(other) {
                    return other !== source && other.name === param.name;
                });

            });

        });

        return sources.reduce(function(p, e, i, o) {
            p[e.path] = new Factory(e);
            return p;
        }, {});

    }

    function Factory(source) {
        this.name = source.name;
        this.code = source.code;
        this.deps = source.factory.params;
        this.cjsMaps = source.cjsMaps;
        this.amdMaps = source.amdMaps;
    }

    /**
     * Return code of this factory wrapped as an amd module, with dependencies
     * mapped and resolved according to annotations.
     */
    Factory.prototype.amdify = function() {

        var self = this,
            deps = self.deps.map(function(dep) {

                var name = self.amdMaps[dep.name] || dep.name;

                if (name === self.name)
                    throw Error(
                        "A factory cannot define itself as a dependency (" +
                        self.name +
                        ")"
                    );

                return "'" + (dep.sibling ? "./" : "") + dep.name + "'";

            });
        return generate(
            parse(
                amdWrap(
                    self.code,
                    deps
                )
            )
        );

    }

    /**
     * Return code of this factory wrapped as a cjs module, with dependencies
     * mapped and resolved according to annotations.
     */
    Factory.prototype.cjsify = function() {

        var self = this,
            deps = self.deps.map(function(dep) {

                var name = self.cjsMaps[dep.name] || dep.name;

                if (name === self.name)
                    throw Error(
                        "A factory cannot define itself as a dependency (" +
                        self.name +
                        ")"
                    );

                return (self.sibling ? "./" : "") + dep.name;

            });

        return generate(
            parse(
                cjsWrap(
                    self.code,
                    deps
                )
            )
        );

    }

    /**
     * Wrap a factory with an AMD loader.
     */
    function amdWrap(factoryCode, deps) {
        return AMD_TEMPLATE.START +
            deps.join(',') +
            AMD_TEMPLATE.MIDDLE +
            factoryCode +
            AMD_TEMPLATE.END;
    }

    /**
     * Wrap a factory with a CJS loader.
     */
    function cjsWrap(factoryCode, deps) {
        var requires = deps.map(function(dep) {
            return "require('" + dep + "')";
        });
        return CJS_TEMPLATE.START +
            factoryCode +
            CJS_TEMPLATE.MIDDLE +
            requires.join(',') +
            CJS_TEMPLATE.END;
    }

    module.exports = Fume;

})(void 0);
<|endoftext|>


<commit_before>var express = require('express');
var bodyParser = require('body-parser');
var cors = require('cors');
var request = require('request');
var events = require('events');
var fh = require('fh-mbaas-api');
var _ = require('underscore');

var fuseRoute = function() {
  var fuse = new express.Router();
  fuse.use(cors());
  fuse.use(bodyParser());

  fuse.post('/', function(req, res) {
    console.log(new Date(), 'In fuse route POST / req.body=', req.body);
    return submitToFuse(req.body, function(error, response, body){
      return res.send(body);
    });
  });

  return fuse;
};

var submitToFuse = function(submission, cb){
  var data = transform(submission);
  var url = process.env.FUSE_URL || 'http://85.190.180.161:8182/cxf/redhat/forum/register';
  var options = { "url" : url, "body": submission, "json": true};
  request.post(options, function (error, response, body) {
    if (!error && response.statusCode == 200) {
      console.log("Well done!") // Show the HTML
    }
    cb(error, response, body);
  });
};

var mapping = {
  "FFIRSTNAME" : "name",
  "FLASTNAME" : "lastName",
  "FEMAIL" : "email",
  "FPICTURE" : "picture",
  "FCOMPANY" : "companyName"
  "FTITLE" : "jobTitle"
};

var transform = function(submission) {
  var map = {};
  _.each(submission.submission.formFields, function(item){
    //console.log(JSON.stringify(item));
    map[mapping[item.fieldId.fieldCode]] = item.fieldValues[0];
  });
  console.log(JSON.stringify(data));
  return data;
}

var submissionEventListener = new events.EventEmitter();

submissionEventListener.on('submissionComplete', function(submission){
  console.log('New submission received: ');
  //console.log(submission);
  return submitToFuse(submission, function(error, response, body){
      console.log('Received response from Fuse in event handler: ' + response.statusCode);
      console.log(body);
  });
});

fh.forms.registerListener(submissionEventListener, function(err){});

module.exports = fuseRoute;<commit_msg>update file /lib/fuse.js<commit_after>var express = require('express');
var bodyParser = require('body-parser');
var cors = require('cors');
var request = require('request');
var events = require('events');
var fh = require('fh-mbaas-api');
var _ = require('underscore');

var fuseRoute = function() {
  var fuse = new express.Router();
  fuse.use(cors());
  fuse.use(bodyParser());

  fuse.post('/', function(req, res) {
    console.log(new Date(), 'In fuse route POST / req.body=', req.body);
    return submitToFuse(req.body, function(error, response, body){
      return res.send(body);
    });
  });

  return fuse;
};

var submitToFuse = function(submission, cb){
  var data = transform(submission);
  var url = process.env.FUSE_URL || 'http://85.190.180.161:8182/cxf/redhat/forum/register';
  var options = { "url" : url, "body": submission, "json": true};
  request.post(options, function (error, response, body) {
    if (!error && response.statusCode == 200) {
      console.log("Well done!") // Show the HTML
    }
    cb(error, response, body);
  });
};

var mapping = {
  "FFIRSTNAME" : "name",
  "FLASTNAME" : "lastName",
  "FEMAIL" : "email",
  "FPICTURE" : "picture",
  "FCOMPANY" : "companyName",
  "FTITLE" : "jobTitle"
};

var transform = function(submission) {
  var map = {};
  _.each(submission.submission.formFields, function(item){
    //console.log(JSON.stringify(item));
    map[mapping[item.fieldId.fieldCode]] = item.fieldValues[0];
  });
  console.log(JSON.stringify(data));
  return data;
}

var submissionEventListener = new events.EventEmitter();

submissionEventListener.on('submissionComplete', function(submission){
  console.log('New submission received: ');
  //console.log(submission);
  return submitToFuse(submission, function(error, response, body){
      console.log('Received response from Fuse in event handler: ' + response.statusCode);
      console.log(body);
  });
});

fh.forms.registerListener(submissionEventListener, function(err){});

module.exports = fuseRoute;<|endoftext|>


<commit_before>/*
* Game Constructor
*
* @class Roguelike.game
* @classdesc The heart of this roguelike game! In here we provide access to
* all the other objects and function, and we handle the startup of the game
*
* @param {object} userSettings - The settings that the user provides
*/
Roguelike.Game = function(userSettings){

    /*
    * @property {bool} isInitialized - Boolean to see if the game is allready initialized
    */
    this.isInitialized = false;

    /*
    * @property {Roguelike.Controls} controls - The object that handles user input
    */
    this.controls = null;

    /*
    * @property {Roguelike.Map} map - Reference to the current map
    */
    this.map = null;

    /*
    * @property {Roguelike.Camera} camera - Reference to the camera
    */
    this.camera = null;

    /*
    * @property {Roguelike.Player} player - Reference to the player object
    */
    this.player = null;

    /*
    * @property {Roguelike.Renderer} map - Reference to the current renderer
    */
    this.renderer = null;

    /*
    * @property {object} settings - The default settings
    */
    this.settings = {
        canvas: null,
        tilesX: 60,
        tilesY: 40,
        tileSize: 20,
        maxRooms: 10,
        minRoomWidth: 6,
        maxRoomWidth: 12,
        minRoomHeight: 6,
        maxRoomHeight: 12,
        debug: false
    };

    //Extend the default settings with those of the user
    this.settings = Roguelike.Utils.extend(this.settings, userSettings);

    //Initialize itself
    this.initialize();

};

Roguelike.Game.prototype = {

    /*
    * Initialize the game, create all objects
    * @protected
    *
    * @param {int} tileX - The number of tiles on the X axis
    * @param {int} tileY - The number of tiles on the Y axis
    * @param {int} maxRooms - The maximum number of rooms in a map
    */
    initialize: function(){

        //Check if the game is allready initialized
        if(this.isInitialized){
            return;
        }

        //Check if the debugged has to be initialized
        if(this.settings.debug === true){
            canvas.addEventListener('mousemove', Roguelike.Utils.debugTiles, false);
        }

        //Set this to the currentgame variable, so all the stupid Event Listeners
        //and Intervals know what is going on
        var currentGame = this;

        //Initialize the tracking of the players input
        this.controls = new Roguelike.Controls();

        function keyDownFunction(e){
            currentGame.controls.keyDown(e);
        }
        function keyUpFunction(e){
            currentGame.controls.keyUp(e);
        }
        window.addEventListener('keydown', keyDownFunction, false);
        window.addEventListener('keyup', keyUpFunction, false);

        //Initialize the map
        this.map = new Roguelike.Map(this);
        this.map.initialize();

        //Generate rooms for this map
        this.map.roomFactory.generateRooms(this);
        this.map.addRooms();

        //Create the camera object
        this.camera = new Roguelike.Camera(this, {x: 0, y: 0});

        //Add the player in the mix
        this.player = new Roguelike.Player(this, this.map.entrance);

        //Let the camera follow the player object
        this.camera.follow(this.player, this.settings.canvas.width / 2, this.settings.canvas.height / 2);

        //Draw the map on canvas
        this.renderer = new Roguelike.Renderer(this);
        this.renderer.drawMap();
        this.renderer.drawPlayer();

        //Call the gameloop
        updateInterval = setInterval(function(){
            currentGame.update();
        //TODO: Make this configurable, STEP/(INTERVAL/FPS)
        }, 1000/(1000/30));

        //The game is fully initialized!
        this.isInitialized = true;

    },

    /*
    * All the functions that need to be executed everytime the game updates
    * Basically the game loop
    * @protected
    *
    */
    update: function(){

        //Update the player
        this.player.update();

        //Update the camera
        this.camera.update();

        //Render the changes
        this.renderer.update();

    },

};<commit_msg>No need to pass the game object to the generate function, it allready has a game reference.<commit_after>/*
* Game Constructor
*
* @class Roguelike.game
* @classdesc The heart of this roguelike game! In here we provide access to
* all the other objects and function, and we handle the startup of the game
*
* @param {object} userSettings - The settings that the user provides
*/
Roguelike.Game = function(userSettings){

    /*
    * @property {bool} isInitialized - Boolean to see if the game is allready initialized
    */
    this.isInitialized = false;

    /*
    * @property {Roguelike.Controls} controls - The object that handles user input
    */
    this.controls = null;

    /*
    * @property {Roguelike.Map} map - Reference to the current map
    */
    this.map = null;

    /*
    * @property {Roguelike.Camera} camera - Reference to the camera
    */
    this.camera = null;

    /*
    * @property {Roguelike.Player} player - Reference to the player object
    */
    this.player = null;

    /*
    * @property {Roguelike.Renderer} map - Reference to the current renderer
    */
    this.renderer = null;

    /*
    * @property {object} settings - The default settings
    */
    this.settings = {
        canvas: null,
        tilesX: 60,
        tilesY: 40,
        tileSize: 20,
        maxRooms: 10,
        minRoomWidth: 6,
        maxRoomWidth: 12,
        minRoomHeight: 6,
        maxRoomHeight: 12,
        debug: false
    };

    //Extend the default settings with those of the user
    this.settings = Roguelike.Utils.extend(this.settings, userSettings);

    //Initialize itself
    this.initialize();

};

Roguelike.Game.prototype = {

    /*
    * Initialize the game, create all objects
    * @protected
    *
    * @param {int} tileX - The number of tiles on the X axis
    * @param {int} tileY - The number of tiles on the Y axis
    * @param {int} maxRooms - The maximum number of rooms in a map
    */
    initialize: function(){

        //Check if the game is allready initialized
        if(this.isInitialized){
            return;
        }

        //Check if the debugged has to be initialized
        if(this.settings.debug === true){
            canvas.addEventListener('mousemove', Roguelike.Utils.debugTiles, false);
        }

        //Set this to the currentgame variable, so all the stupid Event Listeners
        //and Intervals know what is going on
        var currentGame = this;

        //Initialize the tracking of the players input
        this.controls = new Roguelike.Controls();

        function keyDownFunction(e){
            currentGame.controls.keyDown(e);
        }
        function keyUpFunction(e){
            currentGame.controls.keyUp(e);
        }
        window.addEventListener('keydown', keyDownFunction, false);
        window.addEventListener('keyup', keyUpFunction, false);

        //Initialize the map
        this.map = new Roguelike.Map(this);
        this.map.initialize();

        //Generate rooms for this map
        this.map.mapFactory.generateRooms();
        this.map.addRooms();

        //Create the camera object
        this.camera = new Roguelike.Camera(this, {x: 0, y: 0});

        //Add the player in the mix
        this.player = new Roguelike.Player(this, this.map.entrance);

        //Let the camera follow the player object
        this.camera.follow(this.player, this.settings.canvas.width / 2, this.settings.canvas.height / 2);

        //Draw the map on canvas
        this.renderer = new Roguelike.Renderer(this);
        this.renderer.drawMap();
        this.renderer.drawPlayer();

        //Call the gameloop
        updateInterval = setInterval(function(){
            currentGame.update();
        //TODO: Make this configurable, STEP/(INTERVAL/FPS)
        }, 1000/(1000/30));

        //The game is fully initialized!
        this.isInitialized = true;

    },

    /*
    * All the functions that need to be executed everytime the game updates
    * Basically the game loop
    * @protected
    *
    */
    update: function(){

        //Update the player
        this.player.update();

        //Update the camera
        this.camera.update();

        //Render the changes
        this.renderer.update();

    },

};<|endoftext|>


<commit_before>/**
 * Validate string using regular expression.
 *
 * @param {String} string a string
 * @param {String} part email address part (local or domain)
 * @return {Boolean} will return true if the regex test is successful
 */
function regex (string, part) {

  if (!string)
    throw new Error('string value should not an empty string');

  var regex = null;

  if (part === 0)
    regex = /\w/g;
  else if (part === 1)
    regex = /\w/g;

  return regex.test(string);
}

/**
 * Validate email address using techniques from RFC 3696,
 * Restrictions on email addresses http://tools.ietf.org/html/rfc3696#page-5
 *
 * @param {String} emailAddress e-mail address
 * @return {Boolean} will return true if the e-mail address is valid
 */
exports.isValid = function (emailAddress) {

  if (!emailAddress)
    throw new Error('email value shoult not an empty string');

  if (typeof emailAddress !== 'string')
    throw new Error('email value should be a string');

  var isValid = false;
  var splittedEmailAddress = emailAddress.split('@');
  var localPart = splittedEmailAddress[0];
  var domainPart = splittedEmailAddress[1];

  isValid = ((emailAddress.length <= 320) ? true : false) &&
    ((localPart === '') ? false : true) &&
    ((domainPart === '') ? false : true) &&
    ((localPart.length <= 64) ? true : false) &&
    ((domainPart.length <= 255) ? true : false) &&
    regex(localPart, 0) && regex(domainPart, 1);

  return isValid;
};<commit_msg>Extract functions to validate email address parts<commit_after>// constants
var
  LOCAL_PART = 0,
  DOMAIN_PART = 1,
  MAX_LENGTH_OF_LOCAL_PART = 64,
  MAX_LENGTH_OF_DOMAIN_PART = 255;
/**
 * Validate local part of email address
 *
 * @param {String} localPart local part characters of email address
 * @return {Boolean} will return true if the local part is valid
 */
function validateLocalPart (localPart) {

  return ((localPart === '') ? false : true) &&
    ((localPart.length <= MAX_LENGTH_OF_LOCAL_PART) ? true : false) &&
    regex(localPart, LOCAL_PART);
}

/**
 * Validate domain part of email address
 *
 * @param {String} domainPart domain part characters of email address
 * @return {Boolean} will return true if the domain part is valid
 */
function validateDomainPart (domainPart) {

  return ((domainPart === '') ? false : true) &&
    ((domainPart.length <= MAX_LENGTH_OF_DOMAIN_PART) ? true : false) &&
    regex(domainPart, DOMAIN_PART);
}

/**
 * Validate email address parts
 *
 * @param {String} emailAddress email address
 */
function validateEmailAddressParts (emailAddress) {

  var splittedEmailAddress = emailAddress.split('@');

  return (validateLocalPart(splittedEmailAddress[LOCAL_PART]) &&
    validateDomainPart(splittedEmailAddress[DOMAIN_PART]));
}

/**
 * Validate string using regular expression.
 *
 * @param {String} string a string
 * @param {String} part email address part (local or domain)
 * @return {Boolean} will return true if the regex test is successful
 */
function regex (string, part) {

  if (!string)
    throw new Error('string value should not an empty string');

  var regex = null;

  if (part === 0)
    regex = /\w/g;
  else if (part === 1)
    regex = /\w/g;

  return regex.test(string);
}

/**
 * Validate email address using techniques from RFC 3696,
 * Restrictions on email addresses http://tools.ietf.org/html/rfc3696#page-5
 *
 * @param {String} emailAddress e-mail address
 * @return {Boolean} will return true if the e-mail address is valid
 */
exports.isValid = function (emailAddress) {

  if (!emailAddress)
    throw new Error('email value shoult not an empty string');

  if (typeof emailAddress !== 'string')
    throw new Error('email value should be a string');

  return validateEmailAddressParts(emailAddress);
};<|endoftext|>


<commit_before>/*
 * express-lingua
 * A i18n middleware for the Express.js framework.
 *
 * Licensed under the MIT:
 * http://www.opensource.org/licenses/mit-license.php
 *
 * Copyright (c) 2012, André König (andre.koenig -[at]- gmail [*dot*] com)
 *
 */

var fs = require('fs'),
    traverse = require('traverse');

module.exports = (function() {

    "use strict";

    var _name = 'lingua:Guru',
        Guru;

    //
    // summary:
    //     Guru learns the languages.
    //
    // description:
    //     Loads all i18n resource files, parses and persists
    //     them in the resource cache (see above).
    //
    // exception:
    //     If there is no i18n resource file for the configured
    //     default language the guru has to throw an error.
    //
    Guru = function (config) {
        var that = this,
            path = config.resources.path,
            files = fs.readdirSync(path),
            available = false;

        if (!config) {
            throw new Error(_name + ': Please pass the configuration to the constructor.');
        } else {
            this.config = config;
        }

        //
        //
        // summary:
        //     The i18n resource cache.
        //
        // description:
        //     The loaded resources. After booting the express.js
        //     application lingua will parse the complete resource
        //     directory and inserts every single i18n resource into
        //     this cache. That makes resolving the entries very fast.
        //     The flipside of the coin is that it is not possible to
        //     change the i18n resources while the application is running.
        //
        //
        this.resources = [];

        files.forEach(function (file) {
            var absolutePath = path + file,
                content,
                resource = {};

            if (fs.statSync(absolutePath).isFile()) {
                content = fs.readFileSync(absolutePath);

                // The ISO locale code from the filename. We remove
                // the file extension.
                resource.locale = file.replace(that.config.resources.extension, '');

                try {
                    resource.content = JSON.parse(content);
                } catch (e) {
                    throw new Error('Lingua: Error while parsing the resource: ' + resource.locale);
                }

                // DOCME
                resource.content = traverse(resource.content).map(function (value) {
                    var hasPlaceholder,
                        compile;

                    hasPlaceholder = function () {
                        return value.match(config.resources.placeholder);
                    };

                    if (!this.isRoot && this.isLeaf) {
                        if (hasPlaceholder()) {
                            compile = function (data) {
                                var compiled = value;

                                if (typeof data === 'object') {
                                    for (var param in data) {
                                        if (data.hasOwnProperty(param)) {
                                            // TODO: Use the pattern from the configuration object.
                                            compiled = compiled.replace(new RegExp('{'+param+'}','g'), data[param]);
                                        }
                                    }
                                } else {
                                    compiled = compiled.replace(/\{(\w*)\}/g, data);
                                }

                                return compiled;
                            };

                            this.update(compile);
                        }
                    }
                });

                that.resources.push(resource);
            }
        });

        // Check if the resource for the default
        // locale is available. If not, well, ERROR!
        this.resources.forEach(function(resource) {
            if (resource.locale === that.config.resources.defaultLocale) {
                available = true;
            }
        });

        if (!available) {
            throw new Error(_name + ': Please create a resource file for your default locale: '+this.config.resources.defaultLocale);
        }
    };

    //
    // summary:
    //     Shares his language knowledge.
    //
    // description:
    //     Returns the complete i18n object which was defined in
    //     the language file by the given language code.
    //     So if the "locale" is "de-de" then the guru will return
    //     the content which was defined in the "de-de.json" file.
    //
    Guru.prototype.ask = function(locales) {
        var that = this,
            resource,
            i = 0,
            _filter;

        _filter = function(filter) {
            return that.resources.filter(function(resource) {
                return (resource.locale === filter);
            })[0];
        };

        for (i = 0; i < locales.length; i++) {
            resource = _filter(locales[i]);

            if (resource) {
                break;
            }
        }

        if (!resource) {
            resource = _filter(that.config.resources.defaultLocale);
        }

        return resource;
    };

    return Guru;
}());<commit_msg>Fixed issue #4.<commit_after>/*
 * express-lingua
 * A i18n middleware for the Express.js framework.
 *
 * Licensed under the MIT:
 * http://www.opensource.org/licenses/mit-license.php
 *
 * Copyright (c) 2012, André König (andre.koenig -[at]- gmail [*dot*] com)
 *
 */

var fs = require('fs'),
    path = require('path'),
    traverse = require('traverse');

module.exports = (function() {

    "use strict";

    var _name = 'lingua:Guru',
        Guru;

    //
    // summary:
    //     Guru learns the languages.
    //
    // description:
    //     Loads all i18n resource files, parses and persists
    //     them in the resource cache (see above).
    //
    // exception:
    //     If there is no i18n resource file for the configured
    //     default language the guru has to throw an error.
    //
    Guru = function (config) {
        var that = this,
            directory = config.resources.path,
            files = fs.readdirSync(directory),
            available = false;

        if (!config) {
            throw new Error(_name + ': Please pass the configuration to the constructor.');
        } else {
            this.config = config;
        }

        //
        //
        // summary:
        //     The i18n resource cache.
        //
        // description:
        //     The loaded resources. After booting the express.js
        //     application lingua will parse the complete resource
        //     directory and inserts every single i18n resource into
        //     this cache. That makes resolving the entries very fast.
        //     The flipside of the coin is that it is not possible to
        //     change the i18n resources while the application is running.
        //
        //
        this.resources = [];

        files.forEach(function (file) {
            var absolutePath = directory + file,
                resource = {},
                content;

            if (fs.statSync(absolutePath).isFile()) {

                // Regarding Issue #11
                // Check if the current file has the proper file extension.
                // If not (e.g. .DS_Store) then this file will not be treated.
                if (path.extname(file) === that.config.resources.extension) {
                    content = fs.readFileSync(absolutePath);

                    // The ISO locale code from the filename. We remove
                    // the file extension.
                    resource.locale = file.replace(that.config.resources.extension, '');

                    try {
                        resource.content = JSON.parse(content);
                    } catch (e) {
                        throw new Error('Lingua: Error while parsing the resource: ' + resource.locale);
                    }

                    // DOCME
                    resource.content = traverse(resource.content).map(function (value) {
                        var hasPlaceholder,
                            compile;

                        hasPlaceholder = function () {
                            return value.match(config.resources.placeholder);
                        };

                        if (!this.isRoot && this.isLeaf) {
                            if (hasPlaceholder()) {
                                compile = function (data) {
                                    var compiled = value;

                                    if (typeof data === 'object') {
                                        for (var param in data) {
                                            if (data.hasOwnProperty(param)) {
                                                // TODO: Use the pattern from the configuration object.
                                                compiled = compiled.replace(new RegExp('{'+param+'}','g'), data[param]);
                                            }
                                        }
                                    } else {
                                        compiled = compiled.replace(/\{(\w*)\}/g, data);
                                    }

                                    return compiled;
                                };

                                this.update(compile);
                            }
                        }
                    });

                    that.resources.push(resource);
                }
            }
        });

        // Check if the resource for the default
        // locale is available. If not, well, ERROR!
        this.resources.forEach(function(resource) {
            if (resource.locale === that.config.resources.defaultLocale) {
                available = true;
            }
        });

        if (!available) {
            throw new Error(_name + ': Please create a resource file for your default locale: '+this.config.resources.defaultLocale);
        }
    };

    //
    // summary:
    //     Shares his language knowledge.
    //
    // description:
    //     Returns the complete i18n object which was defined in
    //     the language file by the given language code.
    //     So if the "locale" is "de-de" then the guru will return
    //     the content which was defined in the "de-de.json" file.
    //
    Guru.prototype.ask = function(locales) {
        var that = this,
            resource,
            i = 0,
            _filter;

        _filter = function(filter) {
            return that.resources.filter(function(resource) {
                return (resource.locale === filter);
            })[0];
        };

        for (i = 0; i < locales.length; i++) {
            resource = _filter(locales[i]);

            if (resource) {
                break;
            }
        }

        if (!resource) {
            resource = _filter(that.config.resources.defaultLocale);
        }

        return resource;
    };

    return Guru;
}());<|endoftext|>


<commit_before>#!/usr/bin/env node

// process.title is read-only on OSX / darwin.
// but generally, I'll be the only user on an OSX system, so whatever.
process.title = 'guts';
var myname = process.platform === 'darwin' ? 'node' : 'guts';

var http = require('http');
var util = require('util');
var fs = require('fs');
var path = require('path');
var async = require('async');

var common = require('tillberg_common');
var _ = require('underscore')._;
_.mixin(require('underscore.string'));

var remoteUser = process.argv[2];
var remoteHost = process.argv[3];
var remoteFolder = process.argv[4];

var HTTP_PORT = 3294;

if (remoteHost === 'auto') {
  remoteHost = process.env['SSH_CLIENT'].split(' ')[0];
  console.log('auto-detected original remote host of ' + remoteHost);
} else {
  var localUser = process.env['USER'];
  var cmd = 'cd ~/guts && git pull origin master; killall -q ' + myname + '; killall -q gutsmon; sleep 1; ';
  var cmd = cmd + 'cd ' + remoteFolder + ' && node ~/guts/lib/guts.js ' + localUser + ' auto ' + path.resolve('./');
  console.log(cmd);
  var args = [
     '-o',
     'StrictHostKeyChecking=no',
     remoteUser + '@' + remoteHost,
     cmd
  ];
  var proc = exec('ssh', args, { cwd: './' }, function(err) {
    console.log('ssh connection terminated.');
  });
  proc.stdout.on('line', function(d) {
    console.log('[remote] ' + d);
  });
}

function time() {
  return (new Date()).getTime();
}
function throttledAsync(cb, throttleDelay, invokeDelay) {
  var timeout
    , fire = false
    , lastfire = false
    , inflight = false;
  return function() {
    if (!timeout) {
      var nextDelay = throttleDelay - (time() - lastfire);
      function callIt() {
        lastfire = time();
        inflight = true;
        setTimeout(function() {
          cb(function() {
            inflight = false;
            if (fire) {
              fire = false;
              callIt();
            }
          });
        }, invokeDelay);
      }
      function tryToCall() {
        if (inflight) {
          fire = true;
        } else {
          callIt();
        }
      }
      if (nextDelay <= 0) {
        tryToCall();
      } else {
        timeout = setTimeout(function() {
          tryToCall();
          timeout = undefined;
        }, nextDelay);
      }
    }
  };
}

function needToPull() {
  console.log('need to pull');
  pull = true;
  onChange();
}

http.createServer(function (req, res) {
  needToPull();
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('OK\n');
}).listen(HTTP_PORT);

var initted = false;
var changed = [];
var removed = [];
var pull = false;

function madeACommit() {
  console.log('We made a new commit');
  exec('curl', ['-s', remoteHost + ':' + HTTP_PORT + '/'], { cwd: './' }, function(err) {});
}

function gutUp(done) {
  if (!initted) {
    initted = true;
    exec('gut', ['init'], { cwd: './', pipe: true }, function(err) {
      exec('gut', ['add', '.'], { cwd: './', pipe: true }, function(err) {
        exec('gut', ['commit', '-a', '-m', 'post-walk commit'], { cwd: './', pipe: true }, function(err) {
          done();
          madeACommit();
          needToPull();
        });
      });
    });
  } else if (pull) {
    pull = false;
    console.log('pulling...');
    exec('gut', ['remote', 'rm', 'autohost'], { cwd: './' }, function(err) {
      exec('gut', ['remote', 'add', 'autohost', remoteUser + '@' + remoteHost + ':' + remoteFolder], { cwd: './' }, function(err) {
          exec('gut', ['pull', 'autohost', 'master'], { cwd: './', env: { GUT_SSH: path.join(__dirname, 'gut-ssh.sh') } }, function(err) {
          donePulling();
        });
      });
    })
    function donePulling() {
      if (changed.length || removed.length) {
        onChange();
      }
      done();
    }
  } else {
    var _changed = _.uniq(changed);
    var _removed = _.uniq(removed);
    changed = [];
    removed = [];
    function add() {
      function _add(f, cb) {
        info('gut-adding ' + f);
        exec('gut', ['add', f], { cwd: './', pipe: true }, function(err) { cb(); });
      }
      if (_changed.length) {
        async.forEachSeries(_changed, _add, commit);
      } else {
        commit();
      }
    }
    function remove() {
      function _remove(f, cb) {
        exec('gut', ['rm', '--cached'].concat(_removed), { cwd: './', pipe: true }, cb);
      }
      if (_removed.length) {
        async.forEachSeries(_removed, _remove, add);
      } else {
        add();
      }
    }
    function commit() {
      exec('gut', ['rev-parse', 'HEAD'], { cwd: './' }, function(err, data) {
        exec('gut', ['commit', '--untracked-files=no', '-a', '-m', 'autocommit'], { cwd: './', pipe: true }, function(err) {
          exec('gut', ['rev-parse', 'HEAD'], { cwd: './' }, function(err, data2) {
            if (data !== data2) {
              madeACommit();
            } else {
              console.log('We did not actually make a commit');
            }
            done();
          });
        });
      })
    }
    remove();
  }
}

var onChange = throttledAsync(gutUp, 1000, 100);
onChange();

console.log('starting monitor');
var monitor = exec(path.join(__dirname, 'monitor.py'), [path.resolve('./')], { cwd: './' }, function(err, data) {
  error('monitor exited');
});
monitor.stdout.on('line', function(line) {
  var match = (/(\w+) (.*)/).exec(line);
  var event = match[1];
  var filename = match[2];
  if (event === 'deleted') {
    removed.push(filename);
  } else {
    changed.push(path.dirname(filename));
  }
  onChange();
  info(line);
});
<commit_msg>Use origin instead of autohost for remote name<commit_after>#!/usr/bin/env node

// process.title is read-only on OSX / darwin.
// but generally, I'll be the only user on an OSX system, so whatever.
process.title = 'guts';
var myname = process.platform === 'darwin' ? 'node' : 'guts';

var http = require('http');
var util = require('util');
var fs = require('fs');
var path = require('path');
var async = require('async');

var common = require('tillberg_common');
var _ = require('underscore')._;
_.mixin(require('underscore.string'));

var remoteUser = process.argv[2];
var remoteHost = process.argv[3];
var remoteFolder = process.argv[4];

var HTTP_PORT = 3294;

if (remoteHost === 'auto') {
  remoteHost = process.env['SSH_CLIENT'].split(' ')[0];
  console.log('auto-detected original remote host of ' + remoteHost);
} else {
  var localUser = process.env['USER'];
  var cmd = 'cd ~/guts && git pull origin master; killall -q ' + myname + '; killall -q gutsmon; sleep 1; ';
  var cmd = cmd + 'cd ' + remoteFolder + ' && node ~/guts/lib/guts.js ' + localUser + ' auto ' + path.resolve('./');
  console.log(cmd);
  var args = [
     '-o',
     'StrictHostKeyChecking=no',
     remoteUser + '@' + remoteHost,
     cmd
  ];
  var proc = exec('ssh', args, { cwd: './' }, function(err) {
    console.log('ssh connection terminated.');
  });
  proc.stdout.on('line', function(d) {
    console.log('[remote] ' + d);
  });
}

function time() {
  return (new Date()).getTime();
}
function throttledAsync(cb, throttleDelay, invokeDelay) {
  var timeout
    , fire = false
    , lastfire = false
    , inflight = false;
  return function() {
    if (!timeout) {
      var nextDelay = throttleDelay - (time() - lastfire);
      function callIt() {
        lastfire = time();
        inflight = true;
        setTimeout(function() {
          cb(function() {
            inflight = false;
            if (fire) {
              fire = false;
              callIt();
            }
          });
        }, invokeDelay);
      }
      function tryToCall() {
        if (inflight) {
          fire = true;
        } else {
          callIt();
        }
      }
      if (nextDelay <= 0) {
        tryToCall();
      } else {
        timeout = setTimeout(function() {
          tryToCall();
          timeout = undefined;
        }, nextDelay);
      }
    }
  };
}

function needToPull() {
  console.log('need to pull');
  pull = true;
  onChange();
}

http.createServer(function (req, res) {
  needToPull();
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('OK\n');
}).listen(HTTP_PORT);

var initted = false;
var changed = [];
var removed = [];
var pull = false;

function madeACommit() {
  console.log('We made a new commit');
  exec('curl', ['-s', remoteHost + ':' + HTTP_PORT + '/'], { cwd: './' }, function(err) {});
}

function gutUp(done) {
  if (!initted) {
    initted = true;
    exec('gut', ['init'], { cwd: './', pipe: true }, function(err) {
      exec('gut', ['add', '.'], { cwd: './', pipe: true }, function(err) {
        exec('gut', ['commit', '-a', '-m', 'post-walk commit'], { cwd: './', pipe: true }, function(err) {
          done();
          madeACommit();
          needToPull();
        });
      });
    });
  } else if (pull) {
    pull = false;
    console.log('pulling...');
    exec('gut', ['remote', 'rm', 'origin'], { cwd: './' }, function(err) {
      exec('gut', ['remote', 'add', 'origin', remoteUser + '@' + remoteHost + ':' + remoteFolder], { cwd: './' }, function(err) {
          exec('gut', ['pull', 'origin', 'master'], { cwd: './', env: { GUT_SSH: path.join(__dirname, 'gut-ssh.sh') } }, function(err) {
          donePulling();
        });
      });
    })
    function donePulling() {
      if (changed.length || removed.length) {
        onChange();
      }
      done();
    }
  } else {
    var _changed = _.uniq(changed);
    var _removed = _.uniq(removed);
    changed = [];
    removed = [];
    function add() {
      function _add(f, cb) {
        info('gut-adding ' + f);
        exec('gut', ['add', f], { cwd: './', pipe: true }, function(err) { cb(); });
      }
      if (_changed.length) {
        async.forEachSeries(_changed, _add, commit);
      } else {
        commit();
      }
    }
    function remove() {
      function _remove(f, cb) {
        exec('gut', ['rm', '--cached'].concat(_removed), { cwd: './', pipe: true }, cb);
      }
      if (_removed.length) {
        async.forEachSeries(_removed, _remove, add);
      } else {
        add();
      }
    }
    function commit() {
      exec('gut', ['rev-parse', 'HEAD'], { cwd: './' }, function(err, data) {
        exec('gut', ['commit', '--untracked-files=no', '-a', '-m', 'autocommit'], { cwd: './', pipe: true }, function(err) {
          exec('gut', ['rev-parse', 'HEAD'], { cwd: './' }, function(err, data2) {
            if (data !== data2) {
              madeACommit();
            } else {
              console.log('We did not actually make a commit');
            }
            done();
          });
        });
      })
    }
    remove();
  }
}

var onChange = throttledAsync(gutUp, 1000, 100);
onChange();

console.log('starting monitor');
var monitor = exec(path.join(__dirname, 'monitor.py'), [path.resolve('./')], { cwd: './' }, function(err, data) {
  error('monitor exited');
});
monitor.stdout.on('line', function(line) {
  var match = (/(\w+) (.*)/).exec(line);
  var event = match[1];
  var filename = match[2];
  if (event === 'deleted') {
    removed.push(filename);
  } else {
    changed.push(path.dirname(filename));
  }
  onChange();
  info(line);
});
<|endoftext|>