<commit_before>var Compiler = exports.Compiler = (function() {

  // {{{ primary expressions

  function Identifier(node) {
    return function(locals, env, data) {
      return env[node.name];
    };
  }

  function This(node) {
    return function(locals, env, data) {
      return locals['__this__'];
    };
  }

  function Variable(node) {
    return function(locals, env, data) {
      var value = locals[node.name];
      if (value !== undefined)
        return value;
      return data[node.name];
    };
  }

  function Global(node) {
    return function(locals, env, data) {
      return env.GLOBALS[node.name];
    };
  }

  function NumberLiteral(node) {
    return function(locals, env, data) {
      return node.content;
    };
  }

  function StringLiteral(node) {
    return function(locals, env, data) {
      return node.content;
    };
  }

  function ArrayLiteral(node) {
    var content = [];
    var defaultKey = 0;
    node.content.forEach(function(elem, i) {
      content.push(new Expression(elem));
      if (elem.default)
        defaultKey = i;
    });
    return function(locals, env, data, key) {
      if (typeof key == 'function')
        key = key(locals, env, data);
      if (key && content[key])
        return content[key];
      return content[defaultKey];
    };
  }

  function HashLiteral(node) {
    var content = [];
    var defaultKey = null;
    node.content.forEach(function(elem, i) {
      content[elem.id] = new Expression(elem);
      if (i == 0 || elem.default)
        defaultKey = elem.id;
    });
    return function(locals, env, data, key) {
      if (typeof key == 'function')
        key = key(locals, env, data);
      if (key && content[key])
        return content[key];
      return content[defaultKey];
    };
  }

  function ComplexString(node) {
    var content = [];
    node.content.forEach(function(elem) {
      content.push(new Expression(elem));
    })
    return function(locals, env, data) {
      var parts = [];
      content.forEach(function(elem) {
        var part = elem(locals, env, data);
        while (typeof part !== 'string') {
          if (part instanceof Entity)
            part = part.yield(env, data);
          else
            part = part(locals, env, data);
        }
        parts.push(part);
      })
      return parts.join('');
    };
  }

  function KeyValuePair(node) {
    return new Expression(node.value)
  }

  // }}}
  // {{{ operators

  function UnaryOperator(token) {
    if (token == '-') return function(operand) {
      return -operand;
    };
    if (token == '+') return function(operand) {
      return +operand;
    };
    if (token == '!') return function(operand) {
      return !operand;
    };
  }

  function BinaryOperator(token) {
    if (token == '==') return function(left, right) {
      return left == right;
    };
    if (token == '!=') return function(left, right) {
      return left != right;
    };
    if (token == '<') return function(left, right) {
      return left < right;
    };
    if (token == '<=') return function(left, right) {
      return left <= right;
    };
    if (token == '>') return function(left, right) {
      return left > right;
    };
    if (token == '>=') return function(left, right) {
      return left >= right;
    };
    if (token == '+') return function(left, right) {
      return left + right;
    };
    if (token == '-') return function(left, right) {
      return left - right;
    };
    if (token == '*') return function(left, right) {
      return left * right;
    };
    if (token == '/') return function(left, right) {
      return left / right;
    };
    if (token == '%') return function(left, right) {
      return left % right;
    };
  }

  function LogicalOperator(token) {
    if (token == '&&') return function(left, right) {
      return left && right;
    };
    if (token == '||') return function(left, right) {
      return left || right;
    };
  }

  // }}}
  // {{{ logical expressions

  function UnaryExpression(node) {
    var operator = new UnaryOperator(node.operator);
    var operand = new Expression(node.operand);
    return function(locals, env, data) {
      return operator(operand(locals, env, data));
    };
  }

  function BinaryExpression(node) {
    var left = new Expression(node.left);
    var operator = new BinaryOperator(node.operator);
    var right = new Expression(node.right);
    return function(locals, env, data) {
      return operator(left(locals, env, data), right(locals, env, data));
    };
  }

  function LogicalExpression(node) {
    var left = new Expression(node.left);
    if (node.operator) {
      var operator = new LogicalOperator(node.operator);
      var right = new Expression(node.right);
      return function(locals, env, data) {
        operator(left(locals, env, data), right(locals, env, data));
      }
    } else return left;
  }

  function ConditionalExpression(node) {
    var test = new Expression(node.test);
    var consequent = new Expression(node.consequent);
    var alternate = new Expression(node.alternate);
    return function(locals, env, data) {
      if (test(locals, env, data))
        return consequent(locals, env, data);
      return alternate(locals, env, data);
    };
  }

  // }}}
  // {{{ member expressions

  function CallExpression(node) {
    var callee = new Expression(node.callee);
    var args = [];
    node.arguments.forEach(function(elem, i) {
      args.push(new Expression(elem));
    });
    return function(locals, env, data) {
      var resolved_args = [];
      args.forEach(function(arg, i) {
        resolved_args.push(arg(locals, env, data));
      });
      return callee(locals, env, data)(resolved_args, env, data);
    };
  }

  function PropertyExpression(node) {
    var expression = new Expression(node.expression);
    var computed = node.computed;
    if (computed)
      var property = new Expression(node.property);
    else
      var property = node.property.name;
    return function(locals, env, data) {
      var ret = expression(locals, env, data);
      if (ret instanceof Entity)
        return ret.yield(env, data, property);
      if (ret instanceof Attribute)
        return ret.yield(locals, env, data, property);
      // else, `expression` is a HashLiteral
      return ret(locals, env, data, property);
    }
  }

  function AttributeExpression(node) {
    var expression = new Expression(node.expression, false);
    var computed = node.computed;
    if (computed)
      var attribute = new Expression(node.attribute);
    else
      var attribute = node.attribute.name;
    return function(locals, env, data) {
      var entity = expression(locals, env, data);
      //if (!entity instanceof Entity)
      //  throw "Expression does not evaluate to a valid entity."
      return entity.getAttribute(attribute, env, data);
    }
  }

  // }}}
  // {{{ the base Expression class

  function Expression(node) {
    if (!node) return null;

    if (node.type == 'conditionalExpression')
      return new ConditionalExpression(node);
    if (node.type == 'logicalExpression')
      return new LogicalExpression(node);
    if (node.type == 'binaryExpression')
      return new BinaryExpression(node);
    if (node.type == 'unaryExpression')
      return new UnaryExpression(node);

    if (node.type == 'callExpression')
      return new CallExpression(node);
    if (node.type == 'propertyExpression')
      return new PropertyExpression(node);
    if (node.type == 'attributeExpression')
      return new AttributeExpression(node);
    if (node.type == 'parenthesisExpression')
      return new ParenthesisExpression(node);

    if (node.type == 'keyValuePair')
      return new KeyValuePair(node);

    if (node.type == 'identifier')
      return new Identifier(node);
    if (node.type == 'this')
      return new This(node);
    if (node.type == 'variable')
      return new Variable(node);
    if (node.type == 'number')
      return new NumberLiteral(node);
    if (node.type == 'string')
      return new StringLiteral(node);
    if (node.type == 'complexString')
      return new ComplexString(node);
    if (node.type == 'array')
      return new ArrayLiteral(node);
    if (node.type == 'hash')
      return new HashLiteral(node);
  }

  // }}}
  // {{{ entries

  function Attribute(node) {
    this.id = node.id;
    this.local = node.local || false;
    this.value = new Expression(node.value);
  }

  Attribute.prototype = {
    yield: function yield(locals, env, data, key) {
      return this.value(locals, env, data, key);
    },
    get: function get(locals, env, data, index) {
      if (index === undefined)
        var index = locals['__this__'].index;
      var ret = this.yield(locals, env, data, index.shift());
      while (typeof ret !== 'string') {
        ret = ret(locals, env, data, index.shift());
      }
      return ret;
    },
  }

  function Entity(node) {
    this.id = node.id;
    this.value = new Expression(node.value);
    this.index = [];
    node.index.forEach(function(ind) {
      this.index.push(new Expression(ind));
    }, this);
    this.attributes = {};
    node.attrs.forEach(function(attr) {
      this.attributes[attr.id] = new Attribute(attr);
    }, this);
    this.local = node.local || false;
  }

  Entity.prototype = {
    yield: function yield(env, data, key) {
      return this.value({ __this__: this }, env, data, key);
    },
    get: function get(env, data, index) {
      if (index === undefined)
        var index = this.index;
      var ret = this.yield(env, data, index.shift());
      while (typeof ret !== 'string') {
        ret = ret({ __this__: this }, env, data, index.shift());
      }
      return ret;
    },
    getAttribute: function getAttribute(name, env, data) {
      return this.attributes[name].get({ __this__: this }, env, data);
    },
    getAttributes: function getAttributes(env, data) {
      var attrs = {};
      for (var i in this.attributes) {
        var attr = this.attributes[i];
        attrs[attr.id] = attr.get({ __this__: this }, env, data);
      }
      return attrs;
    },
    getEntity: function getEntity(env, data) {
      return {
        value: this.get(env, data),
        attributes: this.getAttributes(env, data),
      };
    }
  }

  function Macro(node) {
    var expression = new Expression(node.expression);
    return function(args, env, data) {
      var locals = {};
      node.args.forEach(function(arg, i) {
        locals[arg.name] = args[i];
      });
      return expression(locals, env, data);
    };
  }

  // }}}
  // {{{ public API

  function compile(ast, obj) {
    for (var i = 0, elem; elem = ast[i]; i++) {
      if (elem.type == 'entity')
        obj[elem.id] = new Entity(elem);
      else if (elem.type == 'macro')
        obj[elem.id] = new Macro(elem);
    }
  }

  return {
    compile: compile,
  };

  // }}}

})();
<commit_msg>locals.__stack__<commit_after>var Compiler = exports.Compiler = (function() {

  // {{{ primary expressions

  function Identifier(node) {
    var name = node.name;
    return function(locals, env, data) {
      if (locals.__stack__.indexOf(name) > -1) {
        console.error('Circular reference')
        return '';
      }
      return env[name];
    };
  }

  function This(node) {
    return function(locals, env, data) {
      if (locals.__stack__.indexOf(locals.__this__.id) > -1) {
        console.error('Circular reference')
        return '';
      }
      return locals.__this__;
    };
  }

  function Variable(node) {
    return function(locals, env, data) {
      var value = locals[node.name];
      if (value !== undefined)
        return value;
      return data[node.name];
    };
  }

  function Global(node) {
    return function(locals, env, data) {
      return env.GLOBALS[node.name];
    };
  }

  function NumberLiteral(node) {
    return function(locals, env, data) {
      return node.content;
    };
  }

  function StringLiteral(node) {
    return function(locals, env, data) {
      return node.content;
    };
  }

  function ArrayLiteral(node) {
    var content = [];
    var defaultKey = 0;
    node.content.forEach(function(elem, i) {
      content.push(new Expression(elem));
      if (elem.default)
        defaultKey = i;
    });
    return function(locals, env, data, index) {
      var key = index.shift();
      if (typeof key == 'function')
        key = key(locals, env, data);
      if (key && content[key])
        var member = content[key];
      else
        var member = content[defaultKey];
      if (locals.__resolve__)
        return member(locals, env, data, index);
      else
        return member;
    };
  }

  function HashLiteral(node) {
    var content = [];
    var defaultKey = null;
    node.content.forEach(function(elem, i) {
      content[elem.id] = new Expression(elem);
      if (i == 0 || elem.default)
        defaultKey = elem.id;
    });
    return function(locals, env, data, index) {
      var key = index.shift();
      if (typeof key == 'function')
        key = key(locals, env, data);
      if (key && content[key])
        var member = content[key];
      else
        var member = content[defaultKey];
      if (locals.__resolve__)
        return member(locals, env, data, index);
      else
        return member;
    };
  }

  function ComplexString(node) {
    var content = [];
    node.content.forEach(function(elem) {
      content.push(new Expression(elem));
    })
    return function(locals, env, data) {
      var parts = [];
      content.forEach(function(elem) {
        var part = elem(locals, env, data);
        while (typeof part !== 'string') {
          if (part instanceof Entity)
            part = part._resolve(locals, env, data);
          else
            part = part(locals, env, data);
        }
        parts.push(part);
      })
      return parts.join('');
    };
  }

  function KeyValuePair(node) {
    return new Expression(node.value)
  }

  // }}}
  // {{{ operators

  function UnaryOperator(token) {
    if (token == '-') return function(operand) {
      return -operand;
    };
    if (token == '+') return function(operand) {
      return +operand;
    };
    if (token == '!') return function(operand) {
      return !operand;
    };
  }

  function BinaryOperator(token) {
    if (token == '==') return function(left, right) {
      return left == right;
    };
    if (token == '!=') return function(left, right) {
      return left != right;
    };
    if (token == '<') return function(left, right) {
      return left < right;
    };
    if (token == '<=') return function(left, right) {
      return left <= right;
    };
    if (token == '>') return function(left, right) {
      return left > right;
    };
    if (token == '>=') return function(left, right) {
      return left >= right;
    };
    if (token == '+') return function(left, right) {
      return left + right;
    };
    if (token == '-') return function(left, right) {
      return left - right;
    };
    if (token == '*') return function(left, right) {
      return left * right;
    };
    if (token == '/') return function(left, right) {
      return left / right;
    };
    if (token == '%') return function(left, right) {
      return left % right;
    };
  }

  function LogicalOperator(token) {
    if (token == '&&') return function(left, right) {
      return left && right;
    };
    if (token == '||') return function(left, right) {
      return left || right;
    };
  }

  // }}}
  // {{{ logical expressions

  function UnaryExpression(node) {
    var operator = new UnaryOperator(node.operator);
    var operand = new Expression(node.operand);
    return function(locals, env, data) {
      return operator(operand(locals, env, data));
    };
  }

  function BinaryExpression(node) {
    var left = new Expression(node.left);
    var operator = new BinaryOperator(node.operator);
    var right = new Expression(node.right);
    return function(locals, env, data) {
      return operator(left(locals, env, data), right(locals, env, data));
    };
  }

  function LogicalExpression(node) {
    var left = new Expression(node.left);
    if (node.operator) {
      var operator = new LogicalOperator(node.operator);
      var right = new Expression(node.right);
      return function(locals, env, data) {
        operator(left(locals, env, data), right(locals, env, data));
      }
    } else return left;
  }

  function ConditionalExpression(node) {
    var test = new Expression(node.test);
    var consequent = new Expression(node.consequent);
    var alternate = new Expression(node.alternate);
    return function(locals, env, data) {
      if (test(locals, env, data))
        return consequent(locals, env, data);
      return alternate(locals, env, data);
    };
  }

  // }}}
  // {{{ member expressions

  function CallExpression(node) {
    var callee = new Expression(node.callee);
    var args = [];
    node.arguments.forEach(function(elem, i) {
      args.push(new Expression(elem));
    });
    return function(locals, env, data) {
      var resolved_args = [];
      args.forEach(function(arg, i) {
        resolved_args.push(arg(locals, env, data));
      });
      return callee(locals, env, data)(resolved_args, env, data);
    };
  }

  function PropertyExpression(node) {
    var expression = new Expression(node.expression);
    var computed = node.computed;
    if (computed)
      var property = new Expression(node.property);
    else
      var property = node.property.name;
    return function(locals, env, data) {
      var ret = expression(locals, env, data);
      if (ret instanceof Entity)
        return ret._yield(locals, env, data, [property]);
      if (ret instanceof Attribute)
        return ret._yield(locals, env, data, [property]);
      // else, `expression` is a HashLiteral
      return ret(locals, env, data, property);
    }
  }

  function AttributeExpression(node) {
    var expression = new Expression(node.expression, false);
    var computed = node.computed;
    if (computed)
      var attribute = new Expression(node.attribute);
    else
      var attribute = node.attribute.name;
    return function(locals, env, data) {
      var entity = expression(locals, env, data);
      //if (!entity instanceof Entity)
      //  throw "Expression does not evaluate to a valid entity."
      return entity.getAttribute(attribute, env, data);
    }
  }

  // }}}
  // {{{ the base Expression class

  function Expression(node) {
    if (!node) return null;

    if (node.type == 'conditionalExpression')
      return new ConditionalExpression(node);
    if (node.type == 'logicalExpression')
      return new LogicalExpression(node);
    if (node.type == 'binaryExpression')
      return new BinaryExpression(node);
    if (node.type == 'unaryExpression')
      return new UnaryExpression(node);

    if (node.type == 'callExpression')
      return new CallExpression(node);
    if (node.type == 'propertyExpression')
      return new PropertyExpression(node);
    if (node.type == 'attributeExpression')
      return new AttributeExpression(node);
    if (node.type == 'parenthesisExpression')
      return new ParenthesisExpression(node);

    if (node.type == 'keyValuePair')
      return new KeyValuePair(node);

    if (node.type == 'identifier')
      return new Identifier(node);
    if (node.type == 'this')
      return new This(node);
    if (node.type == 'variable')
      return new Variable(node);
    if (node.type == 'number')
      return new NumberLiteral(node);
    if (node.type == 'string')
      return new StringLiteral(node);
    if (node.type == 'complexString')
      return new ComplexString(node);
    if (node.type == 'array')
      return new ArrayLiteral(node);
    if (node.type == 'hash')
      return new HashLiteral(node);
  }

  // }}}
  // {{{ entries

  function Attribute(node) {
    this.id = node.id;
    this.local = node.local || false;
    this.value = new Expression(node.value);
  }

  Attribute.prototype = {
    yield: function yield(locals, env, data, key) {
      return this.value(locals, env, data, key);
    },
    get: function get(locals, env, data, index) {
      if (index === undefined)
        index = locals['__this__'].index;
      var ret = this.yield(locals, env, data, index.shift());
      while (typeof ret !== 'string') {
        ret = ret(locals, env, data, index.shift());
      }
      return ret;
    },
  }

  function Entity(node) {
    this.id = node.id;
    this.value = new Expression(node.value);
    this.index = [];
    node.index.forEach(function(ind) {
      this.index.push(new Expression(ind));
    }, this);
    this.attributes = {};
    node.attrs.forEach(function(attr) {
      this.attributes[attr.id] = new Attribute(attr);
    }, this);
    this.local = node.local || false;
  }

  Entity.prototype = {
    _get: function _get(locals, env, data, index) {
      if (index === undefined)
        index = this.index;
      locals.__this__ = this;
      locals.__stack__ = locals.__stack__ || [];
      locals.__stack__.push(this.id);
      return this.value(locals, env, data, index);
    },
    _yield: function _yield(locals, env, data, index) {
      locals.__resolve__ = false;
      return this._get(locals, env, data, index);
    },
    _resolve: function _resolve(locals, env, data, index) {
      locals.__resolve__ = true;
      return this._get(locals, env, data, index);
    },
    get: function get(env, data, index) {
      return this._resolve({}, env, data, index);
    },
    getAttribute: function getAttribute(name, env, data) {
      return this.attributes[name].get({ __this__: this }, env, data);
    },
    getAttributes: function getAttributes(env, data) {
      var attrs = {};
      for (var i in this.attributes) {
        var attr = this.attributes[i];
        attrs[attr.id] = attr.get({ __this__: this }, env, data);
      }
      return attrs;
    },
    getEntity: function getEntity(env, data) {
      return {
        value: this.get(env, data),
        attributes: this.getAttributes(env, data),
      };
    }
  }

  function Macro(node) {
    var expression = new Expression(node.expression);
    return function(args, env, data) {
      var locals = {};
      node.args.forEach(function(arg, i) {
        locals[arg.name] = args[i];
      });
      return expression(locals, env, data);
    };
  }

  // }}}
  // {{{ public API

  function compile(ast, obj) {
    for (var i = 0, elem; elem = ast[i]; i++) {
      if (elem.type == 'entity')
        obj[elem.id] = new Entity(elem);
      else if (elem.type == 'macro')
        obj[elem.id] = new Macro(elem);
    }
  }

  return {
    compile: compile,
  };

  // }}}

})();
<|endoftext|>


<commit_before>'use strict'

/**
 * @module serverless-plugin-warmup
 *
 * @see {@link https://serverless.com/framework/docs/providers/aws/guide/plugins/}
 *
 * @requires 'bluebird'
 * @requires 'fs-extra'
 * @requires 'path'
 * */
const BbPromise = require('bluebird')
const fs = BbPromise.promisifyAll(require('fs-extra'))
const path = require('path')

/**
 * @classdesc Keep your lambdas warm during Winter
 * @class WarmUP
 * */
class WarmUP {
  /**
   * @description Serverless Warm Up
   * @constructor
   *
   * @param {!Object} serverless - Serverless object
   * @param {!Object} options - Serverless options
   * */
  constructor (serverless, options) {
    /** Serverless variables */
    this.serverless = serverless
    this.options = options
    this.custom = this.serverless.service.custom
    this.provider = this.serverless.getProvider('aws')

    this.hooks = {
      'after:package:initialize': this.afterPackageInitialize.bind(this),
      'after:package:createDeploymentArtifacts': this.afterCreateDeploymentArtifacts.bind(this),
      'after:deploy:deploy': this.afterDeployFunctions.bind(this)
    }
  }

  /**
   * @description After package initialize hook. Create warmer function and add it to the service.
   *
   * @fulfil {} — Warm up set
   * @reject {Error} Warm up error
   *
   * @return {(boolean|Promise)}
   * */
  afterPackageInitialize () {
    this.configPlugin()
    return this.createWarmer()
  }

  /**
   * @description After create deployment artifacts. Clean prefix folder.
   *
   * @fulfil {} — Optimization finished
   * @reject {Error} Optimization error
   *
   * @return {Promise}
   * */
  afterCreateDeploymentArtifacts () {
    return this.cleanFolder()
  }

  /**
   * @description After deploy functions hooks
   *
   * @fulfil {} — Functions warmed up sucessfuly
   * @reject {Error} Functions couldn't be warmed up
   *
   * @return {Promise}
   * */
  afterDeployFunctions () {
    this.configPlugin()
    if (this.warmup.prewarm) {
      return this.warmUpFunctions()
    }
  }

  /**
   * @description Configure the plugin based on the context of serverless.yml
   *
   * @return {}
   * */
  configPlugin () {
    /** Set warm up folder, file and handler paths */
    this.folderName = '_warmup'
    this.pathFolder = this.getPath(this.folderName)
    this.pathFile = this.pathFolder + '/index.js'
    this.pathHandler = this.folderName + '/index.warmUp'

    /** Default options */
    this.warmup = {
      cleanFolder: true,
      memorySize: 128,
      name: this.serverless.service.service + '-' + this.options.stage + '-warmup-plugin',
      schedule: 'rate(5 minutes)',
      timeout: 10,
      prewarm: false
    }

    /** Set global custom options */
    if (!this.custom || !this.custom.warmup) {
      return
    }

    /** Clean folder */
    if (typeof this.custom.warmup.cleanFolder === 'boolean') {
      this.warmup.cleanFolder = this.custom.warmup.cleanFolder
    }

    /** Memory size */
    if (typeof this.custom.warmup.memorySize === 'number') {
      this.warmup.memorySize = this.custom.warmup.memorySize
    }

    /** Function name */
    if (typeof this.custom.warmup.name === 'string') {
      this.warmup.name = this.custom.warmup.name
    }

    /** Schedule expression */
    if (typeof this.custom.warmup.schedule === 'string') {
      this.warmup.schedule = this.custom.warmup.schedule
    }

    /** Timeout */
    if (typeof this.custom.warmup.timeout === 'number') {
      this.warmup.timeout = this.custom.warmup.timeout
    }

    /** Pre-warm */
    if (typeof this.custom.warmup.prewarm === 'boolean') {
      this.warmup.prewarm = this.custom.warmup.prewarm
    }
  }

  /**
   * @description After create deployment artifacts
   *
   * @param {string} file — File path
   *
   * @return {String} Absolute file path
   * */
  getPath (file) {
    return path.join(this.serverless.config.servicePath, file)
  }

  /**
   * @description Clean prefix folder
   *
   * @fulfil {} — Folder cleaned
   * @reject {Error} File system error
   *
   * @return {Promise}
   * */
  cleanFolder () {
    if (!this.warmup.cleanFolder) {
      return Promise.resolve()
    }
    return fs.removeAsync(this.pathFolder)
  }

  /**
   * @description Warm up functions
   *
   * @fulfil {} — Warm up function created and added to service
   * @reject {Error} Warm up error
   *
   * @return {Promise}
   * */
  createWarmer () {
    /** Get functions */
    const allFunctions = this.serverless.service.getAllFunctions()

    /** Filter functions for warm up */
    return BbPromise.filter(allFunctions, (functionName) => {
      const functionObject = this.serverless.service.getFunction(functionName)

      /** Function needs to be warm */
      if (functionObject.warmup === true) {
        return functionObject
      }
    }).then((functionNames) => {
      /** Skip writing if no functions need to be warm */
      if (!functionNames.length) {
        /** Log no warmup */
        this.serverless.cli.log('WarmUP: no lambda to warm')
        return true
      }

      /** Write warm up function */
      return this.createWarmUpFunctionArtifact(functionNames)
    }).then((skip) => {
      /** Add warm up function to service */
      if (skip !== true) {
        return this.addWarmUpFunctionToService()
      }
    })
  }

  /**
   * @description Write warm up ES6 function
   *
   * @param {Array} functionNames - Function names
   *
   * @fulfil {} — Warm up function created
   * @reject {Error} Warm up error
   *
   * @return {Promise}
   * */
  createWarmUpFunctionArtifact (functionNames) {
    /** Log warmup start */
    this.serverless.cli.log('WarmUP: setting ' + functionNames.length + ' lambdas to be warm')

    /** Get function names */
    functionNames = functionNames.map((functionName) => {
      const functionObject = this.serverless.service.getFunction(functionName)
      this.serverless.cli.log('WarmUP: ' + functionObject.name)
      return functionObject.name
    })

    /** Write function invoke promises and push to array */
    const warmUpFunction = `"use strict";

/** Generated by Serverless WarmUP Plugin at ${new Date().toISOString()} */
const aws = require("aws-sdk");
aws.config.region = "${this.serverless.service.provider.region}";
const lambda = new aws.Lambda();
const functionNames = "${functionNames.join()}".split(",");
module.exports.warmUp = (event, context, callback) => {
  let invokes = [];
  let errors = 0;
  console.log("Warm Up Start");
  functionNames.forEach((functionName) => {
    const params = {
      FunctionName: functionName,
      InvocationType: "RequestResponse",
      LogType: "None",
      Qualifier: process.env.SERVERLESS_ALIAS || "$LATEST",
      Payload: JSON.stringify({ source: "serverless-plugin-warmup" })
    };
    invokes.push(lambda.invoke(params).promise().then((data) => {
      console.log("Warm Up Invoke Success: " + functionName, data);
    }, (error) => {
      errors++;
      console.log("Warm Up Invoke Error: " + functionName, error);
    }));
  });
  Promise.all(invokes).then(() => {
    console.log("Warm Up Finished with " + errors + " invoke errors");
    callback();
  });
}`

    /** Write warm up file */
    return fs.outputFileAsync(this.pathFile, warmUpFunction)
  }

  /**
   * @description Add warm up function to service
   *
   * @return {Object} Warm up service function object
   * */
  addWarmUpFunctionToService () {
    /** SLS warm up function */
    this.serverless.service.functions.warmUpPlugin = {
      description: 'Serverless WarmUP Plugin',
      events: [
        {
          schedule: this.warmup.schedule
        }
      ],
      handler: this.pathHandler,
      memorySize: this.warmup.memorySize,
      name: this.warmup.name,
      runtime: 'nodejs6.10',
      package: {
        individually: true,
        exclude: ['**'],
        include: [this.folderName + '/**']
      },
      timeout: this.warmup.timeout
    }

    /** Return service function object */
    return this.serverless.service.functions.warmUpPlugin
  }

  /**
   * @description Warm up the functions immediately after deployment
   *
   * @fulfil {} — Functions warmed up sucessfuly
   * @reject {Error} Functions couldn't be warmed up
   *
   * @return {Promise}
   * */
  warmUpFunctions () {
    this.serverless.cli.log('WarmUP: Pre-warming up your functions')

    const params = {
      FunctionName: this.warmup.name,
      InvocationType: 'RequestResponse',
      LogType: 'None',
      Qualifier: process.env.SERVERLESS_ALIAS || '$LATEST',
      Payload: JSON.stringify({ source: 'serverless-plugin-warmup' })
    }

    return this.provider.request('Lambda', 'invoke', params)
      .then(data => this.serverless.cli.log('WarmUp: Functions sucessfuly pre-warmed'))
      .catch(error => this.serverless.cli.log('WarmUp: Error while pre-warming functions', error))
  }
}

/** Export WarmUP class */
module.exports = WarmUP
<commit_msg>feat(scheduler): Handle multiple schedules<commit_after>'use strict'

/**
 * @module serverless-plugin-warmup
 *
 * @see {@link https://serverless.com/framework/docs/providers/aws/guide/plugins/}
 *
 * @requires 'bluebird'
 * @requires 'fs-extra'
 * @requires 'path'
 * */
const BbPromise = require('bluebird')
const fs = BbPromise.promisifyAll(require('fs-extra'))
const path = require('path')

/**
 * @classdesc Keep your lambdas warm during Winter
 * @class WarmUP
 * */
class WarmUP {
  /**
   * @description Serverless Warm Up
   * @constructor
   *
   * @param {!Object} serverless - Serverless object
   * @param {!Object} options - Serverless options
   * */
  constructor (serverless, options) {
    /** Serverless variables */
    this.serverless = serverless
    this.options = options
    this.custom = this.serverless.service.custom
    this.provider = this.serverless.getProvider('aws')

    this.hooks = {
      'after:package:initialize': this.afterPackageInitialize.bind(this),
      'after:package:createDeploymentArtifacts': this.afterCreateDeploymentArtifacts.bind(this),
      'after:deploy:deploy': this.afterDeployFunctions.bind(this)
    }
  }

  /**
   * @description After package initialize hook. Create warmer function and add it to the service.
   *
   * @fulfil {} — Warm up set
   * @reject {Error} Warm up error
   *
   * @return {(boolean|Promise)}
   * */
  afterPackageInitialize () {
    this.configPlugin()
    return this.createWarmer()
  }

  /**
   * @description After create deployment artifacts. Clean prefix folder.
   *
   * @fulfil {} — Optimization finished
   * @reject {Error} Optimization error
   *
   * @return {Promise}
   * */
  afterCreateDeploymentArtifacts () {
    return this.cleanFolder()
  }

  /**
   * @description After deploy functions hooks
   *
   * @fulfil {} — Functions warmed up sucessfuly
   * @reject {Error} Functions couldn't be warmed up
   *
   * @return {Promise}
   * */
  afterDeployFunctions () {
    this.configPlugin()
    if (this.warmup.prewarm) {
      return this.warmUpFunctions()
    }
  }

  /**
   * @description Configure the plugin based on the context of serverless.yml
   *
   * @return {}
   * */
  configPlugin () {
    /** Set warm up folder, file and handler paths */
    this.folderName = '_warmup'
    this.pathFolder = this.getPath(this.folderName)
    this.pathFile = this.pathFolder + '/index.js'
    this.pathHandler = this.folderName + '/index.warmUp'

    /** Default options */
    this.warmup = {
      cleanFolder: true,
      memorySize: 128,
      name: this.serverless.service.service + '-' + this.options.stage + '-warmup-plugin',
      schedule: 'rate(5 minutes)',
      timeout: 10,
      prewarm: false
    }

    /** Set global custom options */
    if (!this.custom || !this.custom.warmup) {
      return
    }

    /** Clean folder */
    if (typeof this.custom.warmup.cleanFolder === 'boolean') {
      this.warmup.cleanFolder = this.custom.warmup.cleanFolder
    }

    /** Memory size */
    if (typeof this.custom.warmup.memorySize === 'number') {
      this.warmup.memorySize = this.custom.warmup.memorySize
    }

    /** Function name */
    if (typeof this.custom.warmup.name === 'string') {
      this.warmup.name = this.custom.warmup.name
    }

    /** Schedule expression */
    if (typeof this.custom.warmup.schedule === 'string') {
      this.warmup.schedule = [this.custom.warmup.schedule]
    } else if (Array.isArray(this.custom.warmup.schedule)) {
      this.warmup.schedule = this.custom.warmup.schedule
    }

    /** Timeout */
    if (typeof this.custom.warmup.timeout === 'number') {
      this.warmup.timeout = this.custom.warmup.timeout
    }

    /** Pre-warm */
    if (typeof this.custom.warmup.prewarm === 'boolean') {
      this.warmup.prewarm = this.custom.warmup.prewarm
    }
  }

  /**
   * @description After create deployment artifacts
   *
   * @param {string} file — File path
   *
   * @return {String} Absolute file path
   * */
  getPath (file) {
    return path.join(this.serverless.config.servicePath, file)
  }

  /**
   * @description Clean prefix folder
   *
   * @fulfil {} — Folder cleaned
   * @reject {Error} File system error
   *
   * @return {Promise}
   * */
  cleanFolder () {
    if (!this.warmup.cleanFolder) {
      return Promise.resolve()
    }
    return fs.removeAsync(this.pathFolder)
  }

  /**
   * @description Warm up functions
   *
   * @fulfil {} — Warm up function created and added to service
   * @reject {Error} Warm up error
   *
   * @return {Promise}
   * */
  createWarmer () {
    /** Get functions */
    const allFunctions = this.serverless.service.getAllFunctions()

    /** Filter functions for warm up */
    return BbPromise.filter(allFunctions, (functionName) => {
      const functionObject = this.serverless.service.getFunction(functionName)

      /** Function needs to be warm */
      if (functionObject.warmup === true) {
        return functionObject
      }
    }).then((functionNames) => {
      /** Skip writing if no functions need to be warm */
      if (!functionNames.length) {
        /** Log no warmup */
        this.serverless.cli.log('WarmUP: no lambda to warm')
        return true
      }

      /** Write warm up function */
      return this.createWarmUpFunctionArtifact(functionNames)
    }).then((skip) => {
      /** Add warm up function to service */
      if (skip !== true) {
        return this.addWarmUpFunctionToService()
      }
    })
  }

  /**
   * @description Write warm up ES6 function
   *
   * @param {Array} functionNames - Function names
   *
   * @fulfil {} — Warm up function created
   * @reject {Error} Warm up error
   *
   * @return {Promise}
   * */
  createWarmUpFunctionArtifact (functionNames) {
    /** Log warmup start */
    this.serverless.cli.log('WarmUP: setting ' + functionNames.length + ' lambdas to be warm')

    /** Get function names */
    functionNames = functionNames.map((functionName) => {
      const functionObject = this.serverless.service.getFunction(functionName)
      this.serverless.cli.log('WarmUP: ' + functionObject.name)
      return functionObject.name
    })

    /** Write function invoke promises and push to array */
    const warmUpFunction = `"use strict";

/** Generated by Serverless WarmUP Plugin at ${new Date().toISOString()} */
const aws = require("aws-sdk");
aws.config.region = "${this.serverless.service.provider.region}";
const lambda = new aws.Lambda();
const functionNames = "${functionNames.join()}".split(",");
module.exports.warmUp = (event, context, callback) => {
  let invokes = [];
  let errors = 0;
  console.log("Warm Up Start");
  functionNames.forEach((functionName) => {
    const params = {
      FunctionName: functionName,
      InvocationType: "RequestResponse",
      LogType: "None",
      Qualifier: process.env.SERVERLESS_ALIAS || "$LATEST",
      Payload: JSON.stringify({ source: "serverless-plugin-warmup" })
    };
    invokes.push(lambda.invoke(params).promise().then((data) => {
      console.log("Warm Up Invoke Success: " + functionName, data);
    }, (error) => {
      errors++;
      console.log("Warm Up Invoke Error: " + functionName, error);
    }));
  });
  Promise.all(invokes).then(() => {
    console.log("Warm Up Finished with " + errors + " invoke errors");
    callback();
  });
}`

    /** Write warm up file */
    return fs.outputFileAsync(this.pathFile, warmUpFunction)
  }

  /**
   * @description Add warm up function to service
   *
   * @return {Object} Warm up service function object
   * */
  addWarmUpFunctionToService () {
    /** SLS warm up function */
    this.serverless.service.functions.warmUpPlugin = {
      description: 'Serverless WarmUP Plugin',
      events: this.warmup.schedule.map(schedule => { schedule }),
      handler: this.pathHandler,
      memorySize: this.warmup.memorySize,
      name: this.warmup.name,
      runtime: 'nodejs6.10',
      package: {
        individually: true,
        exclude: ['**'],
        include: [this.folderName + '/**']
      },
      timeout: this.warmup.timeout
    }

    /** Return service function object */
    return this.serverless.service.functions.warmUpPlugin
  }

  /**
   * @description Warm up the functions immediately after deployment
   *
   * @fulfil {} — Functions warmed up sucessfuly
   * @reject {Error} Functions couldn't be warmed up
   *
   * @return {Promise}
   * */
  warmUpFunctions () {
    this.serverless.cli.log('WarmUP: Pre-warming up your functions')

    const params = {
      FunctionName: this.warmup.name,
      InvocationType: 'RequestResponse',
      LogType: 'None',
      Qualifier: process.env.SERVERLESS_ALIAS || '$LATEST',
      Payload: JSON.stringify({ source: 'serverless-plugin-warmup' })
    }

    return this.provider.request('Lambda', 'invoke', params)
      .then(data => this.serverless.cli.log('WarmUp: Functions sucessfuly pre-warmed'))
      .catch(error => this.serverless.cli.log('WarmUp: Error while pre-warming functions', error))
  }
}

/** Export WarmUP class */
module.exports = WarmUP
<|endoftext|>


<commit_before>(function() {

  // main entry point for the application
  function main() {

    console.log('focalendar is up and running!');

    //
    // list days

    var container = byClass('container');

    var baseDay = byClass('day');
    baseDay.remove();

    var baseMonth = byClass('month');
    baseMonth.remove();

    var date = new Date();
    month = createMonth(baseMonth, baseDay, date);
    container.appendChild(month);

  }

  function createMonth(baseMonth, baseDay, date) {

    var month = baseMonth.cloneNode(true);
    var header = byClass('month-header', month);
    var days = byClass('days', month);

    var monthNumber = date.getMonth();

    header.innerText = nameOfMonth(date) + ' ' + date.getUTCFullYear();

    // start at first of month
    date.setDate(1);

    while (date.getMonth() === monthNumber) {
      var day = createDay(baseDay, date);
      days.appendChild(day);
      date.setDate( date.getDate() + 1 );
    }

    return month;
  }

  function createDay(base, date) {
    var day = base.cloneNode(true);
    var label = byClass('day-label', day);
    label.innerText = dayOfWeek(date) + ' ' + date.getDate();
    day.setAttribute('data-date', date.toDateString());
    if (isToday(date)) day.id = 'today';
    return day;
  }

  function isToday(date) {
    return date.toDateString() === new Date().toDateString();
  }

  // return something like 'MON' or 'SUN'
  function dayOfWeek(date) {
    return date.toString().match(/[^\s]+/)[0].toUpperCase();
  }

  // returns a function that takes a date
  // and returns something like 'JANURARY' or 'SEPTEMBER'
  var nameOfMonth = (function() {

    var monthNames = [
      'Janurary',
      'Februrary',
      'March',
      'April',
      'May',
      'June',
      'July',
      'August',
      'SEPTEMBER',
      'October',
      'November',
      'December'
    ];

    return function(date) {
      return monthNames[date.getMonth()].toUpperCase();
    };

  })();

  // get single element by classname
  // optionally give parent element as second parameter
  function byClass(name, el) {
    return (el || document).getElementsByClassName(name)[0];
  }

  // kick of the application
  main();

  // ROADMAP
  //
  // highlight today
  // when you reach top or bottom while scrolling load more days
  // make month headers sticky to the month they belong to
  // add a notifier pointing in the direction where today is
  // grey out past days

})();
<commit_msg>infinite scrolling<commit_after>(function() {

  var container = byClass('container');

  // main entry point for the application
  function main() {

    var date = new Date();
    var month = createMonth(date);
    container.appendChild(month);

    window.onscroll = infiniteScroll;

  }

  // createDay(date) - returns a day DOM element
  var createDay = (function() {

    var baseDay = byClass('day');
    baseDay.remove();

    return function(date) {
      var day = baseDay.cloneNode(true);
      var label = byClass('day-label', day);

      label.innerText = dayOfWeek(date) + ' ' + date.getDate();
      day.setAttribute('data-date', date.toDateString());

      // mark today
      if (isToday(date)) day.id = 'today';

      return day;
    };

  })();

  // createMonth(date)
  // returns a month DOM element for the month of the given date
  var createMonth = (function() {

    var baseMonth = byClass('month');
    baseMonth.remove();

    return function(date) {

      var month = baseMonth.cloneNode(true);
      var header = byClass('month-header', month);
      var days = byClass('days', month);
      var monthNumber = date.getMonth();

      // TODO: year for January is wrong when scrolling down
      header.innerText = nameOfMonth(date) + ' ' + date.getUTCFullYear();

      // start at first of month
      date.setDate(1);

      while (date.getMonth() === monthNumber) {
        var day = createDay(date);
        days.appendChild(day);
        date.setDate( date.getDate() + 1 );
      }

      return month;
    };

  })();

  // returns a boolean
  function isToday(date) {
    return date.toDateString() === new Date().toDateString();
  }

  // return something like 'MON' or 'SUN'
  function dayOfWeek(date) {
    return date.toString().match(/[^\s]+/)[0].toUpperCase();
  }

  // nameOfMonth(date) - returns the name of the month
  // example: 'JANURARY' or 'SEPTEMBER'
  var nameOfMonth = (function() {

    var monthNames = [
      'JANURARY',
      'FEBRURARY',
      'MARCH',
      'APRIL',
      'MAY',
      'JUNE',
      'JULY',
      'AUGUST',
      'SEPTEMBER',
      'OCTOBER',
      'NOVEMBER',
      'DECEMBER'
    ];

    return function(date) {
      return monthNames[date.getMonth()].toUpperCase();
    };

  })();

  function infiniteScroll() {
    var top = scrollTop();
    var maxTop = document.body.scrollHeight - document.documentElement.clientHeight;

    if (top <= 0) return fetchEarlierDates();
    if (top >= maxTop) fetchLaterDates();
  }

  function fetchEarlierDates() {
    var firstDay = byClass('day').getAttribute('data-date');
    var previousDay = new Date(firstDay);
    previousDay.setDate( previousDay.getDate() - 1 );
    var previousMonth = createMonth(previousDay);
    var currentMonth = byClass('month');
    container.insertBefore(previousMonth, currentMonth);
    scrollTop(currentMonth.offsetTop);
  }

  function fetchLaterDates() {
    var days = document.getElementsByClassName('day');
    var lastDay = days[days.length -1].getAttribute('data-date');
    var nextDay = new Date(lastDay);
    nextDay.setDate( nextDay.getDate() + 1 );
    var nextMonth = createMonth(nextDay);
    container.appendChild(nextMonth);
  }

  // get single element by classname
  // optionally give parent element as second parameter
  function byClass(name, el) {
    return (el || document).getElementsByClassName(name)[0];
  }

  // cross-browser get or set scrollTop
  function scrollTop(val) {
    var doc = document.documentElement;
    var body = document.body;

    if (val) return doc.scrollTop = body.scrollTop = val;

    return doc.scrollTop || body.scrollTop || 0;
  }

  // kick of the application
  main();

  // ROADMAP
  //
  // highlight today
  // when you reach top or bottom while scrolling load more days
  // make month headers sticky to the month they belong to
  // add a notifier pointing in the direction where today is
  // grey out past days

})();
<|endoftext|>


<commit_before>(function() {
	analyzingURL();
})();

function randomTime(time) {
	return time * (Math.ramdom() + 0.8);
}

function analyzingURL() {
	console.log('==Analyzing URL==');
	var hash = location.hash;
	console.log('Get Hash : ' + hash);
	if(/coopraid\/offer/i.test(hash))
		offer();
	else if(/coopraid\/room/i.test(hash))
		room();
	else if(/supporter/i.test(hash))
		supporter();
	else if(/raid_multi/i.test(hash))
		raid_multi();
	else if(/result_multi/i.test(hash) || /quest$/i.test(hash)) {
		setTimeout(function(){
			console.log('==Result Multi Stage==');
			location.href = "http://gbf.game.mbga.jp/#coopraid";
			setTimeout(analyzingURL, 1000);
		}, 1000);
	}
	else if(/coopraid/i.test(hash))
		coopraid();
}

function coopraid() {
	console.log('==Coopraid Stage==');
	if($('.btn-join').length)
		$('.btn-join').trigger('tap');
	else if($('.prt-result-head head-win').length) {
		setTimeout(function(){
			location.reload();
		}, 1000);
	}
	setTimeout(analyzingURL, 1000);
}

function offer() {
	console.log('==Offer Stage==');
	if($('.prt-wanted-list>div').length) {
		setTimeout(function(){
			if($('.prt-invite-type-1'))
				$('.prt-invite-type-1').trigger('tap');
			setTimeout(function(){
				if($('.btn-usual-join'))
					$('.btn-usual-join').trigger('tap');
				setTimeout(function(){
					if($('.btn-usual-ok'))
						$('.btn-usual-ok').trigger('tap');
					setTimeout(function(){
						if($('.btn-refresh-list'))
							$('.btn-refresh-list').trigger('tap');
						setTimeout(function(){
							if($('.btn-usual-cancel'))
								$('.btn-usual-cancel').trigger('tap');
							setTimeout(analyzingURL, 100);
							return;
						}, 100);
					}, 100);
				}, 100);
			}, 100);
		}, 600);
		return;
	}
	setTimeout(analyzingURL, 100);
}

function room() {
	console.log('==Room Stage==');
	if($('.btn-make-ready-large.not-ready').length) {
		$('.btn-make-ready-large.not-ready').trigger('tap');
	}
	else if($('.btn-execute-ready.se-ok').length) {
		$('.btn-execute-ready.se-ok').trigger('tap');
		//btn-retraction-ready
	}
	setTimeout(analyzingURL, 1000);
}

function supporter() {
	console.log('==Supporter Stage==');
	if($('.prt-supporter-detail').length) {
		$('.prt-supporter-detail').trigger('tap');
	}
	setTimeout(function(){
		if($('.btn-usual-ok').length) {
			$('.btn-usual-ok').trigger('tap');
		}
		setTimeout(analyzingURL, 1000);
	}, 1000);
}

function raid_multi() {
	console.log('==Raid Multi Stage==');
	if($('.btn-attack-start.display-on').length) {
		$('.btn-attack-start.display-on').trigger('tap');
	}
	else if($('.btn-result').length) {
		$('.btn-result').trigger('tap');
	}
	setTimeout(analyzingURL, 1000);
}
<commit_msg>Update coopraid<commit_after>(function() {
	analyzingURL();
})();

function randomTime(time) {
	return time * (Math.ramdom() + 0.8);
}

function analyzingURL() {
	console.log('==Analyzing URL==');
	var hash = location.hash;
	console.log('Get Hash : ' + hash);
	if(/coopraid\/offer/i.test(hash))
		offer();
	else if(/coopraid\/room/i.test(hash))
		room();
	else if(/supporter/i.test(hash))
		supporter();
	else if(/raid_multi/i.test(hash))
		raid_multi();
	else if(/result_multi/i.test(hash) || /quest$/i.test(hash)) {
		setTimeout(function(){
			console.log('==Result Multi Stage==');
			location.href = "http://gbf.game.mbga.jp/#coopraid";
			setTimeout(analyzingURL, 1000);
		}, 1000);
	}
	else if(/coopraid/i.test(hash))
		coopraid();
}

function coopraid() {
	console.log('==Coopraid Stage==');
	if($('.btn-join').length)
		$('.btn-join').trigger('tap');
	else if($('.prt-result-head head-win').length) {
		setTimeout(function(){
			location.reload();
		}, 1000);
	}
	setTimeout(analyzingURL, 1000);
}

function offer() {
	console.log('==Offer Stage==');
	if($('.prt-wanted-list>div').length) {
		setTimeout(offerJoin, 700);
		return;
	}
	setTimeout(analyzingURL, 100);
}

function offerFind() {
	if($('.prt-invite-type-1'))
		$('.prt-invite-type-1').trigger('tap');
	setTimeout(offerJoin, 100);
}

function offerJoin() {
	if($('.btn-usual-join'))
		$('.btn-usual-join').trigger('tap');
	setTimeout(offerOK, 100);
}

function offerOK() {
	if($('.btn-usual-ok'))
		$('.btn-usual-ok').trigger('tap');
	setTimeout(offerRefresh, 100);
}

function offerRefresh() {
	if($('.btn-refresh-list'))
		$('.btn-refresh-list').trigger('tap');
	setTimeout(offerCancel, 100);
}

function offerCancel() {
	if($('.btn-usual-cancel'))
		$('.btn-usual-cancel').trigger('tap');
	setTimeout(analyzingURL, 100);
}

function room() {
	console.log('==Room Stage==');
	if($('.btn-make-ready-large.not-ready').length) {
		$('.btn-make-ready-large.not-ready').trigger('tap');
	}
	else if($('.btn-execute-ready.se-ok').length) {
		$('.btn-execute-ready.se-ok').trigger('tap');
		//btn-retraction-ready
	}
	setTimeout(analyzingURL, 1000);
}

function supporter() {
	console.log('==Supporter Stage==');
	if($('.prt-supporter-detail').length) {
		$('.prt-supporter-detail').trigger('tap');
	}
	setTimeout(function(){
		if($('.btn-usual-ok').length) {
			$('.btn-usual-ok').trigger('tap');
		}
		setTimeout(analyzingURL, 1000);
	}, 1000);
}

function raid_multi() {
	console.log('==Raid Multi Stage==');
	if($('.btn-attack-start.display-on').length) {
		$('.btn-attack-start.display-on').trigger('tap');
	}
	else if($('.btn-result').length) {
		$('.btn-result').trigger('tap');
	}
	setTimeout(analyzingURL, 1000);
}
<|endoftext|>


<commit_before>import Mousetrap from 'mousetrap';
import React from 'react';

export function mouseTrap(Base){
    return class extends React.Component {
        constructor(props){
            super(props);
            this.__mousetrapBindings = [];
        }

        bindShortcut (key, callback) {
            Mousetrap.bind(key, callback);
            this.__mousetrapBindings.push(key);
        }

        unbindShortcut (key) {
            var index = this.__mousetrapBindings.indexOf(key);

            if (index > -1) {
                this.__mousetrapBindings.splice(index, 1);
            }

            Mousetrap.unbind(key);
        }

        unbindAllShortcuts () {
            if (this.__mousetrapBindings.length < 1) {
                return;
            }

            this.__mousetrapBindings.forEach(function (binding) {
                Mousetrap.unbind(binding);
            });
            this.__mousetrapBindings = [];
        }

        componentWillUnmount () {
            this.unbindAllShortcuts();
        }

        render () {
            return <Base
                {...this.props}
                bindShortcut={this.bindShortcut.bind(this)}
                unbindShortcut={this.unbindShortcut.bind(this)} />
        }
    };
}
<commit_msg>move `require(‘mousetrap’)` to constructor<commit_after>import React from 'react';

export function mouseTrap(Base){

    return class extends React.Component {
        constructor(props){
            super(props);
            this.__mousetrapBindings = [];
            this.Mousetrap = require('mousetrap');
        }

        bindShortcut (key, callback) {
            this.Mousetrap.bind(key, callback);
            this.__mousetrapBindings.push(key);
        }

        unbindShortcut (key) {
            var index = this.__mousetrapBindings.indexOf(key);

            if (index > -1) {
                this.__mousetrapBindings.splice(index, 1);
            }

            this.Mousetrap.unbind(key);
        }

        unbindAllShortcuts () {
            if (this.__mousetrapBindings.length < 1) {
                return;
            }

            this.__mousetrapBindings.forEach(function (binding) {
                this.Mousetrap.unbind(binding);
            });
            this.__mousetrapBindings = [];
        }

        componentWillUnmount () {
            this.unbindAllShortcuts();
        }

        render () {
            return <Base
                {...this.props}
                bindShortcut={this.bindShortcut.bind(this)}
                unbindShortcut={this.unbindShortcut.bind(this)} />
        }
    };
}
<|endoftext|>


<commit_before>import { find, identity, map } from 'ramda';
import React, { Component } from 'react';
import { View } from 'react-native';
import { NativeRouter, Redirect, Route } from 'react-router-native';

import { EntityFactory } from '../packages/entities';
import { CourseInteractorLoader } from '../packages/entities-interactor';
import courses from '../packages/assets/courses.json';
import { ExerciseComponents } from './components/exercises';
import Course from './components/screens/Course';
import Splash from './components/screens/Splash';
import { LoadSounds } from './components/helpers/Audio';
import { ExerciseGroup } from './components/helpers/exercise-group';
import { play, getSound } from './helpers/audio';
import Storage from './storage/CourseStorage';
import ProgressStorage from './storage/ProgressStorage';
import { PRIMARY } from './styles/colors';
import { AssetResolver } from './asset-resolver';

export class AppRoutes extends Component {
  constructor(props) {
    super(props);

    const storage = new Storage(courses);
    const progressStorage = new ProgressStorage();
    this.interactorLoader = new CourseInteractorLoader(
      storage,
      progressStorage
    );

    const resolver = new AssetResolver();
    this.entityFactory = new EntityFactory(resolver);

    this.state = {
      course: null
    };
  }

  getNextChild = id => {
    return this.interactor.getNextChild(id);
  };

  getNextSibling = id => {
    return this.interactor.getNextSibling(id);
  };

  getProgress = id => {
    return this.interactor.getProgress(id);
  };

  resetProgress = () => {
    return this.interactor.resetProgress();
  };

  findEntity = id => {
    return this.interactor.findEntity(id);
  };

  markAsCorrect = id => {
    return this.interactor.markAsCorrect(id);
  };

  markAsIncorrect = id => {
    return this.interactor.markAsIncorrect(id);
  };

  goUp = (id, level) => {
    if (level <= 2) {
      return <Redirect to="/course" />;
    }

    return (
      <Redirect
        to={{
          pathname: `/node/${id}`,
          state: { level: level - 1 }
        }}
      />
    );
  };

  goDown = (id, level) => {
    return (
      <Redirect
        to={{
          pathname: `/node/${id}`,
          state: { level: level + 1 }
        }}
      />
    );
  };

  componentDidMount() {
    this.interactorLoader
      .loadCourse('09438926-b170-4005-a6e8-5dd8fba83cde')
      .then(interactor => {
        this.interactor = interactor;
        const course = this.interactor.getStructure();
        this.setState({ course });
      });
  }

  render() {
    return (
      <LoadSounds
        sounds={[getSound('correct'), getSound('wrong')]}
        render={([correctSound, wrongSound]) => (
          <View
            style={{
              flex: 1,
              backgroundColor: PRIMARY
            }}
          >
            <Route
              exact
              path="/"
              render={({ history }) => (
                <Splash next={() => history.push('/course')} />
              )}
            />
            <Route
              path="/course"
              render={({ history }) => {
                if (!this.state.course) {
                  return null;
                }

                const nexts = map(
                  ({ id }) => this.getNextChild(id),
                  this.state.course.children
                );
                const next = find(identity, nexts);

                return (
                  <Course
                    next={next && next.id}
                    getProgress={this.getProgress}
                    resetProgress={this.resetProgress}
                    course={this.state.course}
                    goToSection={id =>
                      history.push(`/node/${id}`, { level: 2 })
                    }
                  />
                );
              }}
            />
            <Route
              path="/node/:id"
              render={({ location, match, history }) => {
                const { id } = match.params;
                const { level } = location.state;

                if (!this.state.course) {
                  return null;
                }

                const entity = this.findEntity(id);

                if (!entity) {
                  console.warn('Entity with id', id, 'does not exist');
                  return <Redirect to="/course" />;
                }

                const { type, props } = entity;

                if (!type) {
                  // Internal node
                  const next = this.getNextChild(id);

                  if (!next) {
                    this.markAsCorrect(id);
                    return this.goUp(entity.parent, level);
                  }

                  return this.goDown(next.id, level);
                }

                const newWords = this.interactor.getNewVocabulary(id);
                const words = this.interactor.getVocabulary(id);
                const letter = this.interactor.getNewLetter(id);
                const letters = this.interactor.getLetters(id);

                // Leaf
                const group = this.entityFactory.createExerciseGroup(
                  type,
                  newWords,
                  words,
                  letter,
                  letters,
                  props
                );

                if (!group) {
                  console.warn('no view found for type', type);
                  return null;
                }

                const done = () => {
                  this.markAsCorrect(id);

                  history.push(`/node/${entity.parent}`, {
                    level: level - 1
                  });
                };

                return (
                  <ExerciseGroup
                    createExerciseComponent={type => ExerciseComponents[type]}
                    group={group}
                    goToNav={() => history.push('/course')}
                    onCorrect={() => play(correctSound)}
                    onWrong={() => play(wrongSound)}
                    onDone={done}
                  />
                );
              }}
            />
          </View>
        )}
      />
    );
  }
}

export default () => (
  <NativeRouter>
    <AppRoutes />
  </NativeRouter>
);
<commit_msg>Register app usage by sending a PageHit to GoogleAnalytics when app is opened.<commit_after>import { find, identity, map } from 'ramda';
import React, { Component } from 'react';
import { View } from 'react-native';
import { NativeRouter, Redirect, Route } from 'react-router-native';
import { Analytics, PageHit } from 'expo-analytics';

import { EntityFactory } from '../packages/entities';
import { CourseInteractorLoader } from '../packages/entities-interactor';
import courses from '../packages/assets/courses.json';
import { ExerciseComponents } from './components/exercises';
import Course from './components/screens/Course';
import Splash from './components/screens/Splash';
import { LoadSounds } from './components/helpers/Audio';
import { ExerciseGroup } from './components/helpers/exercise-group';
import { play, getSound } from './helpers/audio';
import Storage from './storage/CourseStorage';
import ProgressStorage from './storage/ProgressStorage';
import { PRIMARY } from './styles/colors';
import { AssetResolver } from './asset-resolver';

export class AppRoutes extends Component {
  constructor(props) {
    super(props);

    const storage = new Storage(courses);
    const progressStorage = new ProgressStorage();
    this.interactorLoader = new CourseInteractorLoader(
      storage,
      progressStorage
    );

    const resolver = new AssetResolver();
    this.entityFactory = new EntityFactory(resolver);
    this.analytics = new Analytics('UA-126536605-1');

    this.state = {
      course: null
    };
  }

  getNextChild = id => {
    return this.interactor.getNextChild(id);
  };

  getNextSibling = id => {
    return this.interactor.getNextSibling(id);
  };

  getProgress = id => {
    return this.interactor.getProgress(id);
  };

  resetProgress = () => {
    return this.interactor.resetProgress();
  };

  findEntity = id => {
    return this.interactor.findEntity(id);
  };

  markAsCorrect = id => {
    return this.interactor.markAsCorrect(id);
  };

  markAsIncorrect = id => {
    return this.interactor.markAsIncorrect(id);
  };

  goUp = (id, level) => {
    if (level <= 2) {
      return <Redirect to="/course" />;
    }

    return (
      <Redirect
        to={{
          pathname: `/node/${id}`,
          state: { level: level - 1 }
        }}
      />
    );
  };

  goDown = (id, level) => {
    return (
      <Redirect
        to={{
          pathname: `/node/${id}`,
          state: { level: level + 1 }
        }}
      />
    );
  };

  componentDidMount() {
    this.interactorLoader
      .loadCourse('09438926-b170-4005-a6e8-5dd8fba83cde')
      .then(interactor => {
        this.interactor = interactor;
        const course = this.interactor.getStructure();
        this.setState({ course });
      });
    this.analytics
      .hit(new PageHit('Main'))
      .then(() => console.log('success'))
      .catch(e => console.error(e.message));
  }

  render() {
    return (
      <LoadSounds
        sounds={[getSound('correct'), getSound('wrong')]}
        render={([correctSound, wrongSound]) => (
          <View
            style={{
              flex: 1,
              backgroundColor: PRIMARY
            }}
          >
            <Route
              exact
              path="/"
              render={({ history }) => (
                <Splash next={() => history.push('/course')} />
              )}
            />
            <Route
              path="/course"
              render={({ history }) => {
                if (!this.state.course) {
                  return null;
                }

                const nexts = map(
                  ({ id }) => this.getNextChild(id),
                  this.state.course.children
                );
                const next = find(identity, nexts);

                return (
                  <Course
                    next={next && next.id}
                    getProgress={this.getProgress}
                    resetProgress={this.resetProgress}
                    course={this.state.course}
                    goToSection={id =>
                      history.push(`/node/${id}`, { level: 2 })
                    }
                  />
                );
              }}
            />
            <Route
              path="/node/:id"
              render={({ location, match, history }) => {
                const { id } = match.params;
                const { level } = location.state;

                if (!this.state.course) {
                  return null;
                }

                const entity = this.findEntity(id);

                if (!entity) {
                  console.warn('Entity with id', id, 'does not exist');
                  return <Redirect to="/course" />;
                }

                const { type, props } = entity;

                if (!type) {
                  // Internal node
                  const next = this.getNextChild(id);

                  if (!next) {
                    this.markAsCorrect(id);
                    return this.goUp(entity.parent, level);
                  }

                  return this.goDown(next.id, level);
                }

                const newWords = this.interactor.getNewVocabulary(id);
                const words = this.interactor.getVocabulary(id);
                const letter = this.interactor.getNewLetter(id);
                const letters = this.interactor.getLetters(id);

                // Leaf
                const group = this.entityFactory.createExerciseGroup(
                  type,
                  newWords,
                  words,
                  letter,
                  letters,
                  props
                );

                if (!group) {
                  console.warn('no view found for type', type);
                  return null;
                }

                const done = () => {
                  this.markAsCorrect(id);

                  history.push(`/node/${entity.parent}`, {
                    level: level - 1
                  });
                };

                return (
                  <ExerciseGroup
                    createExerciseComponent={type => ExerciseComponents[type]}
                    group={group}
                    goToNav={() => history.push('/course')}
                    onCorrect={() => play(correctSound)}
                    onWrong={() => play(wrongSound)}
                    onDone={done}
                  />
                );
              }}
            />
          </View>
        )}
      />
    );
  }
}

export default () => (
  <NativeRouter>
    <AppRoutes />
  </NativeRouter>
);
<|endoftext|>


<commit_before>/*global HTMLDocument, Window, console */
this.Costanza = (function() {
  "use strict";

  function defaultReporter(info, err) {
    console.error('Costanza error', info);
  }

  var reportCallback = defaultReporter,
      currentSection = 'global',
      _onError,
      _setTimeout,
      _setInterval,
      _addEventListener,
      _removeEventListener;

  function init(_reportCallback, options) {
    reportCallback = _reportCallback || defaultReporter;

    if (!window.onerror || !window.onerror.errorSite) {
      _onError = _onError || window.onerror;
      window.onerror = onErrorRoot;

      window.addEventListener('error', onError, true);
    }

    // Allow users to opt out of the native prototype augmentation.
    if (options && options.safeMode) {
      return;
    }

    if (!setTimeout.errorSite) {
      _setTimeout = setTimeout;
      window.setTimeout = function(callback, duration) {
        return _setTimeout(bind(callback), duration);
      };
      setTimeout.errorSite = true;
    }

    if (!setInterval.errorSite) {
      _setInterval = setInterval;
      window.setInterval = function(callback, interval) {
        return _setInterval(bind(callback), interval);
      };
      setInterval.errorSite = true;
    }

    if (window.Element && Element.prototype.addEventListener && !Element.prototype.addEventListener.errorSite) {
      _addEventListener = Element.prototype.addEventListener;
      var addEventListener = function(type, callback, useCapture) {
        callback._section = callback._section || bind(callback);
        _addEventListener.call(this, type, callback._section, useCapture);
      };
      addEventListener.errorSite = true;
      Element.prototype.addEventListener = addEventListener;

      _removeEventListener = Element.prototype.removeEventListener;
      var removeEventListener = function(type, callback, useCapture) {
        _removeEventListener.call(this, type, callback._section || callback, useCapture);
      };
      removeEventListener.errorSite = true;
      Element.prototype.removeEventListener = removeEventListener;

      if (window.HTMLDocument) {
        HTMLDocument.prototype.addEventListener = addEventListener;
        HTMLDocument.prototype.removeEventListener = removeEventListener;
      }

      if (window.Window) {
        Window.prototype.addEventListener = addEventListener;
        Window.prototype.removeEventListener = removeEventListener;
      }
    }
  }
  function cleanup() {
    reportCallback = defaultReporter;
    if (window.onerror && window.onerror.errorSite) {
      window.onerror = _onError;

      window.removeEventListener('error', onError, true);
    }
    if (setTimeout.errorSite) {
      window.setTimeout = _setTimeout;
    }
    if (setInterval.errorSite) {
      window.setInterval = _setInterval;
    }
    if (window.Element && Element.prototype.addEventListener && Element.prototype.addEventListener.errorSite) {
      Element.prototype.addEventListener = _addEventListener;
      Element.prototype.removeEventListener = _removeEventListener;

      if (window.HTMLDocument) {
        HTMLDocument.prototype.addEventListener = _addEventListener;
        HTMLDocument.prototype.removeEventListener = _removeEventListener;
      }

      if (window.Window) {
        Window.prototype.addEventListener = _addEventListener;
        Window.prototype.removeEventListener = _removeEventListener;
      }
    }
  }

  function bind(name, callback) {
    if (!callback) {
      callback = name;
      name = currentSection;
    }

    return function() {
      var priorSite = currentSection;

      try {
        currentSection = name;

        callback.apply(this, arguments);
      } catch (err) {
        reportCallback({
          type: 'javascript',
          section: currentSection,
          msg: err.message,
          stack: err.stack
        }, err);
      } finally {
        currentSection = priorSite;
      }
    };
  }

  function onError(errorMsg, url, lineNumber, error) {
    var type = 'javascript';

    // Handle ErrorEvent if we receieve it
    if (errorMsg && errorMsg.message) {
      url = errorMsg.filename;
      lineNumber = errorMsg.lineno;
      error = errorMsg.error;
      errorMsg = errorMsg.message;
    }

    if (errorMsg === 'Script error.' && !url) {
      // Ignore untrackable external errors locally
      return;
    }

    // This is a real event handler vs. the onerror special case.
    // Since some browsers decide to treat window.onerror as the error event handler,
    // we have to be prepared for either case
    if (errorMsg && errorMsg.srcElement) {
      // Don't submit duplciate events (and if we weren't already tracking
      // it, it probably wasn't that important)
      if (errorMsg.defaultPrevented || errorMsg.errorSiteHandled) {
        return;
      }

      errorMsg.errorSiteHandled = true;
      url = url || errorMsg.srcElement.src || errorMsg.srcElement.href;
      type = errorMsg.srcElement.tagName.toLowerCase();
      errorMsg = 'load-failed';
    }

    // Error argument added to the spec. Adding support so we can catch this as it rolls out
    // http://html5.org/tools/web-apps-tracker?from=8085&to=8086
    reportCallback({
      section: currentSection,
      url: url,
      line: lineNumber,
      type: type,

      // Cast error message to string as it sometimes can come through with objects, particularly DOM objects
      // containing circular references.
      msg: errorMsg+'',
      stack: error && error.stack
    }, error);
  }

  function onErrorRoot(errorMsg, url, lineNumber, error) {
    _onError && _onError(errorMsg, url, lineNumber, error);
    onError(errorMsg, url, lineNumber, error);
  }
  onErrorRoot.errorSite = true;

  return {
    init: init,
    cleanup: cleanup,
    current: function() {
      return currentSection;
    },
    emit: function(info, error) {
      reportCallback(info, error);
    },
    bind: bind,
    run: function(name, callback) {
      bind(name, callback)();
    },
    onError: onError
  };
})();
<commit_msg>Rename errorSite flag<commit_after>/*global HTMLDocument, Window, console */
this.Costanza = (function() {
  "use strict";

  function defaultReporter(info, err) {
    console.error('Costanza error', info);
  }

  var reportCallback = defaultReporter,
      currentSection = 'global',
      _onError,
      _setTimeout,
      _setInterval,
      _addEventListener,
      _removeEventListener;

  function init(_reportCallback, options) {
    reportCallback = _reportCallback || defaultReporter;

    if (!window.onerror || !window.onerror._costanza) {
      _onError = _onError || window.onerror;
      window.onerror = onErrorRoot;

      window.addEventListener('error', onError, true);
    }

    // Allow users to opt out of the native prototype augmentation.
    if (options && options.safeMode) {
      return;
    }

    if (!setTimeout._costanza) {
      _setTimeout = setTimeout;
      window.setTimeout = function(callback, duration) {
        return _setTimeout(bind(callback), duration);
      };
      setTimeout._costanza = true;
    }

    if (!setInterval._costanza) {
      _setInterval = setInterval;
      window.setInterval = function(callback, interval) {
        return _setInterval(bind(callback), interval);
      };
      setInterval._costanza = true;
    }

    if (window.Element && Element.prototype.addEventListener && !Element.prototype.addEventListener._costanza) {
      _addEventListener = Element.prototype.addEventListener;
      var addEventListener = function(type, callback, useCapture) {
        callback._section = callback._section || bind(callback);
        _addEventListener.call(this, type, callback._section, useCapture);
      };
      addEventListener._costanza = true;
      Element.prototype.addEventListener = addEventListener;

      _removeEventListener = Element.prototype.removeEventListener;
      var removeEventListener = function(type, callback, useCapture) {
        _removeEventListener.call(this, type, callback._section || callback, useCapture);
      };
      removeEventListener._costanza = true;
      Element.prototype.removeEventListener = removeEventListener;

      if (window.HTMLDocument) {
        HTMLDocument.prototype.addEventListener = addEventListener;
        HTMLDocument.prototype.removeEventListener = removeEventListener;
      }

      if (window.Window) {
        Window.prototype.addEventListener = addEventListener;
        Window.prototype.removeEventListener = removeEventListener;
      }
    }
  }
  function cleanup() {
    reportCallback = defaultReporter;
    if (window.onerror && window.onerror._costanza) {
      window.onerror = _onError;

      window.removeEventListener('error', onError, true);
    }
    if (setTimeout._costanza) {
      window.setTimeout = _setTimeout;
    }
    if (setInterval._costanza) {
      window.setInterval = _setInterval;
    }
    if (window.Element && Element.prototype.addEventListener && Element.prototype.addEventListener._costanza) {
      Element.prototype.addEventListener = _addEventListener;
      Element.prototype.removeEventListener = _removeEventListener;

      if (window.HTMLDocument) {
        HTMLDocument.prototype.addEventListener = _addEventListener;
        HTMLDocument.prototype.removeEventListener = _removeEventListener;
      }

      if (window.Window) {
        Window.prototype.addEventListener = _addEventListener;
        Window.prototype.removeEventListener = _removeEventListener;
      }
    }
  }

  function bind(name, callback) {
    if (!callback) {
      callback = name;
      name = currentSection;
    }

    return function() {
      var priorSite = currentSection;

      try {
        currentSection = name;

        callback.apply(this, arguments);
      } catch (err) {
        reportCallback({
          type: 'javascript',
          section: currentSection,
          msg: err.message,
          stack: err.stack
        }, err);
      } finally {
        currentSection = priorSite;
      }
    };
  }

  function onError(errorMsg, url, lineNumber, error) {
    var type = 'javascript';

    // Handle ErrorEvent if we receieve it
    if (errorMsg && errorMsg.message) {
      url = errorMsg.filename;
      lineNumber = errorMsg.lineno;
      error = errorMsg.error;
      errorMsg = errorMsg.message;
    }

    if (errorMsg === 'Script error.' && !url) {
      // Ignore untrackable external errors locally
      return;
    }

    // This is a real event handler vs. the onerror special case.
    // Since some browsers decide to treat window.onerror as the error event handler,
    // we have to be prepared for either case
    if (errorMsg && errorMsg.srcElement) {
      // Don't submit duplciate events (and if we weren't already tracking
      // it, it probably wasn't that important)
      if (errorMsg.defaultPrevented || errorMsg._costanzaHandled) {
        return;
      }

      errorMsg._costanzaHandled = true;
      url = url || errorMsg.srcElement.src || errorMsg.srcElement.href;
      type = errorMsg.srcElement.tagName.toLowerCase();
      errorMsg = 'load-failed';
    }

    // Error argument added to the spec. Adding support so we can catch this as it rolls out
    // http://html5.org/tools/web-apps-tracker?from=8085&to=8086
    reportCallback({
      section: currentSection,
      url: url,
      line: lineNumber,
      type: type,

      // Cast error message to string as it sometimes can come through with objects, particularly DOM objects
      // containing circular references.
      msg: errorMsg+'',
      stack: error && error.stack
    }, error);
  }

  function onErrorRoot(errorMsg, url, lineNumber, error) {
    _onError && _onError(errorMsg, url, lineNumber, error);
    onError(errorMsg, url, lineNumber, error);
  }
  onErrorRoot._costanza = true;

  return {
    init: init,
    cleanup: cleanup,
    current: function() {
      return currentSection;
    },
    emit: function(info, error) {
      reportCallback(info, error);
    },
    bind: bind,
    run: function(name, callback) {
      bind(name, callback)();
    },
    onError: onError
  };
})();
<|endoftext|>


<commit_before>// This skill reuses elements from the Adrian Smart Assistant project
// https://github.com/TheAdrianProject/AdrianSmartAssistant/blob/master/Modules/Google/Google.js

'use strict'

var AlexaSkill = require('./AlexaSkill')
var rp = require('request-promise')
var $ = require('cheerio')
var Entities = require('html-entities').XmlEntities;
var entities = new Entities();
var striptags = require('striptags');

var APP_ID = undefined; //replace with 'amzn1.echo-sdk-ams.app.[your-unique-value-here]';

var AlexaGoogleSearch = function() {
    AlexaSkill.call(this, APP_ID)
}

AlexaGoogleSearch.prototype = Object.create(AlexaSkill.prototype)
AlexaGoogleSearch.prototype.constructor = AlexaGoogleSearch

AlexaGoogleSearch.prototype.eventHandlers.onLaunch = function(launchRequest, session, response) {
    console.log("AlexaGoogleSearch onLaunch requestId" + launchRequest.requestId + ", sessionId: " + session.sessionId)
    var speechOutput = "Welcome to Google Search. What are you searching for?"
    var repromptText = ""
    response.ask(speechOutput, repromptText)
}

AlexaGoogleSearch.prototype.intentHandlers = {
    "SearchIntent": function(intent, session, response) {
		var query = intent.slots.search.value

		// Title for Alexa app card
        var cardTitle = ("Google Search Result for: " + query)

		// Remove spaces and replace with +
		query = query.replace(" ","+")

		// Remove _ and replace with +
		query = query.replace(/ /g ,"+")

        var speechOutput = "Error"

        // Parsing routine modified from
        // https://github.com/TheAdrianProject/AdrianSmartAssistant/blob/master/Modules/Google/Google.js

        //parse queries

        // Create search sring
        var queryString = "http://www.google.com/search?q="
			+'?hl=en-GB'      //  Search language - change to en-US for US based results
	        +'&oe=utf8'       //  Output encoding
	        +'&q=' + query    // add search string

        rp(queryString)
            .then(function(body) {
            	console.log("Running parsing")
                console.log("Search string is:" + queryString)
                console.log("HTML is:" + $("#ires",body).html())

            // result variable init
			var found = 0;

//			if (!found && $('._m3b',body).length>0){
//                console.log("Don't know")
//				found = $('._m3b',body).html()

//			}
            //how many 2
			if (!found ){

                //how many
				var items = $('._m3b',body).get().length // find how many lines there are in answer table

                if (items) {
                console.log( items + " how many 2 answer found")
                        found = $('._eGc',body).html() + ", "

                        for (var count = 0; count < items; count++) {

                        found = found + $('._m3b',body).eq(count).html() + ", "
                        }
            }
            }

			//facts 1
			if (!found && $('._tXc>span',body).length>0){

				found = $('._tXc>span',body).html()
				console.log("Found facts 1")

			}

			//facts 2
			if (!found && $('._sPg',body).length>0){

				found = " "+$('._sPg',body).html()
				console.log("Found facts 2")

			}

			//instant + description 1
			if (!found && $('._Oqb',body).length>0){

				found = $('._Oqb',body).html()
				console.log("Found instant and desc 1")

			//how many 1
				if ( $('._Mqb',body).length>0){

					found+= " "+$('._Mqb',body).html()
					console.log("Found Found instant and desc 1 - how many")
				}
			}
			//instant + description 2
			if (!found && $('._o0d',body).length>0){
				found = $('._o0d',body).text()
				console.log("Found instant and desc 2")
			//how many table
				if ( $('.g>div>table>tr>td>ol',body).length>0){
					found+= " "+$('.g>div>table>tr>td>ol',body).html()
				}

			//how many 1
				if ( $('._Mqb',body).length>0){
					found+= " "+$('._Mqb',body).html()
					console.log("Found Found instant and desc 2 - how many")
				}
			}

			//Time, Date
			if (!found && $('._rkc._Peb',body).length>0){

				found = $('._rkc._Peb',body).html()
				console.log("Found date and Time")

			}
			//Maths
			if (!found && $('.nobr>.r',body).length>0){
				found = $('.nobr>.r',body).html()
				console.log("Found maths")
			}

			//simple answer
			if (!found && $('.obcontainer',body).length>0){
				found = $('.obcontainer',body).html()
				console.log("Found Simple answer")

			}

			//Definition
			if (!found && $('.r>div>span',body).first().length>0){
				found = $('.r>div>span',body).first().html() +" definition. "
				console.log("Found definition")
				//how many
				var items = $('.g>div>table>tr>td>ol>li',body).get().length // find how many lines there are in answer table

                if (items) {
                console.log( items + " Type 4 answer sections result")

                        for (var count = 0; count < items; count++) {

                        found = found + $('.g>div>table>tr>td>ol>li',body).eq(count).html() + ", "
                        }
            }
			}
			//TV show
			if (!found && $('._B5d',body).length>0){
				found = $('._B5d',body).html()
				console.log("Found tv show")
				//how many
				if ( $('._Pxg',body).length>0){
					found+= ". "+$('._Pxg',body).html()
				}
				//how many
				if ( $('._tXc',body).length>0){

					found+= ". "+$('._tXc',body).html()
				}
			}

			//Weather
			if (!found && $('.g>.e>h3',body).length>0){

				found = $('.g>.e>h3',body).html()
				console.log("Found weather")

				//how many
				if ( $('.wob_t',body).first().length>0){

					found+= " "+ $('.wob_t',body).first().html()
					console.log("Found weather")
				}

				//how many
				if ( $('._Lbd',body).length>0){

					found+= " "+ $('._Lbd',body).html()
					console.log("Found how many")
				}
			}

			// strip out html tags to leave just text
			var speechOutputTemp = entities.decode(striptags(found))

			// make sure all full stops have space after them otherwise alexa says the word dot
			var speechOutputTemp = speechOutputTemp.split('.com').join(" dot com ") // deal with dot com
			var speechOutputTemp = speechOutputTemp.split('.co.uk').join(" dot co dot uk ") // deal with .co.uk
            //var speechOutputTemp = speechOutputTemp.split(/[0-9].[0-9]/).replace(" point ") // need deal with decimal places but this code is incorrect
			var speechOutput = speechOutputTemp.split('.').join(". ") // deal with any remaining dots and turn them into full stops

			if (speechOutput=="") speechOutput = "I'm sorry, I wasn't able to find an answer."
			response.tellWithCard(speechOutput, cardTitle, speechOutput)

            //    response.tell(speechOutput)
            }).catch(function(err) {
            console.log("ERROR" + err)
            speechOutput = "There was an error processing your search."
            response.tell(speechOutput)
        })
    },

    "AMAZON.StopIntent": function(intent, session, response) {
        var speechOutput = ""
        response.tell(speechOutput)
    }
}

exports.handler = function(event, context) {
    var AlexaGoogleSearchHelper = new AlexaGoogleSearch()
    AlexaGoogleSearchHelper.execute(event, context)
}<commit_msg>Fix for US hosted skills<commit_after>// This skill reuses elements from the Adrian Smart Assistant project
// https://github.com/TheAdrianProject/AdrianSmartAssistant/blob/master/Modules/Google/Google.js

'use strict'

var AlexaSkill = require('./AlexaSkill')
var rp = require('request-promise')
var $ = require('cheerio')
var Entities = require('html-entities').XmlEntities;
var entities = new Entities();
var striptags = require('striptags');

var APP_ID = undefined; //replace with 'amzn1.echo-sdk-ams.app.[your-unique-value-here]';

var AlexaGoogleSearch = function() {
    AlexaSkill.call(this, APP_ID)
}

AlexaGoogleSearch.prototype = Object.create(AlexaSkill.prototype)
AlexaGoogleSearch.prototype.constructor = AlexaGoogleSearch

AlexaGoogleSearch.prototype.eventHandlers.onLaunch = function(launchRequest, session, response) {
    console.log("AlexaGoogleSearch onLaunch requestId" + launchRequest.requestId + ", sessionId: " + session.sessionId)
    var speechOutput = "Welcome to Google Search. What are you searching for?"
    var repromptText = ""
    response.ask(speechOutput, repromptText)
}

AlexaGoogleSearch.prototype.intentHandlers = {
    "SearchIntent": function(intent, session, response) {
		var query = intent.slots.search.value

		// Title for Alexa app card
        var cardTitle = ("Google Search Result for: " + query)

		// Remove spaces and replace with +
		query = query.replace(" ","+")

		// Remove _ and replace with +
		query = query.replace(/ /g ,"+")

        var speechOutput = "Error"

        // Parsing routine modified from
        // https://github.com/TheAdrianProject/AdrianSmartAssistant/blob/master/Modules/Google/Google.js

        //parse queries

        // Create search sring
        var queryString = "http://www.google.com/search?q="

	        +'&oe=utf8'       //  Output encoding
	        +'&q=' + query    // add search string

        rp(queryString)
            .then(function(body) {
            	console.log("Running parsing")
                console.log("Search string is:" + queryString)
                console.log("HTML is:" + $("#ires",body).html())

            // result variable init
			var found = 0;

//			if (!found && $('._m3b',body).length>0){
//                console.log("Don't know")
//				found = $('._m3b',body).html()

//			}
            //how many 2
			if (!found ){

                //how many
				var items = $('._m3b',body).get().length // find how many lines there are in answer table

                if (items) {
                console.log( items + " how many 2 answer found")
                        found = $('._eGc',body).html() + ", "

                        for (var count = 0; count < items; count++) {

                        found = found + $('._m3b',body).eq(count).html() + ", "
                        }
            }
            }

			//facts 1
			if (!found && $('._tXc>span',body).length>0){

				found = $('._tXc>span',body).html()
				console.log("Found facts 1")

			}

			//facts 2
			if (!found && $('._sPg',body).length>0){

				found = " "+$('._sPg',body).html()
				console.log("Found facts 2")

			}

			//instant + description 1
			if (!found && $('._Oqb',body).length>0){

				found = $('._Oqb',body).html()
				console.log("Found instant and desc 1")

			//how many 1
				if ( $('._Mqb',body).length>0){

					found+= " "+$('._Mqb',body).html()
					console.log("Found Found instant and desc 1 - how many")
				}
			}
			//instant + description 2
			if (!found && $('._o0d',body).length>0){
				found = $('._o0d',body).text()
				console.log("Found instant and desc 2")
			//how many table
				if ( $('.g>div>table>tr>td>ol',body).length>0){
					found+= " "+$('.g>div>table>tr>td>ol',body).html()
				}

			//how many 1
				if ( $('._Mqb',body).length>0){
					found+= " "+$('._Mqb',body).html()
					console.log("Found Found instant and desc 2 - how many")
				}
			}

			//Time, Date
			if (!found && $('._rkc._Peb',body).length>0){

				found = $('._rkc._Peb',body).html()
				console.log("Found date and Time")

			}
			//Maths
			if (!found && $('.nobr>.r',body).length>0){
				found = $('.nobr>.r',body).html()
				console.log("Found maths")
			}

			//simple answer
			if (!found && $('.obcontainer',body).length>0){
				found = $('.obcontainer',body).html()
				console.log("Found Simple answer")

			}

			//Definition
			if (!found && $('.r>div>span',body).first().length>0){
				found = $('.r>div>span',body).first().html() +" definition. "
				console.log("Found definition")
				//how many
				var items = $('.g>div>table>tr>td>ol>li',body).get().length // find how many lines there are in answer table

                if (items) {
                console.log( items + " Type 4 answer sections result")

                        for (var count = 0; count < items; count++) {

                        found = found + $('.g>div>table>tr>td>ol>li',body).eq(count).html() + ", "
                        }
            }
			}
			//TV show
			if (!found && $('._B5d',body).length>0){
				found = $('._B5d',body).html()
				console.log("Found tv show")
				//how many
				if ( $('._Pxg',body).length>0){
					found+= ". "+$('._Pxg',body).html()
				}
				//how many
				if ( $('._tXc',body).length>0){

					found+= ". "+$('._tXc',body).html()
				}
			}

			//Weather
			if (!found && $('.g>.e>h3',body).length>0){

				found = $('.g>.e>h3',body).html()
				console.log("Found weather")

				//how many
				if ( $('.wob_t',body).first().length>0){

					found+= " "+ $('.wob_t',body).first().html()
					console.log("Found weather")
				}

				//how many
				if ( $('._Lbd',body).length>0){

					found+= " "+ $('._Lbd',body).html()
					console.log("Found how many")
				}
			}

			// strip out html tags to leave just text
			var speechOutputTemp = entities.decode(striptags(found))

			// make sure all full stops have space after them otherwise alexa says the word dot
			var speechOutputTemp = speechOutputTemp.split('.com').join(" dot com ") // deal with dot com
			var speechOutputTemp = speechOutputTemp.split('.co.uk').join(" dot co dot uk ") // deal with .co.uk
            //var speechOutputTemp = speechOutputTemp.split(/[0-9].[0-9]/).replace(" point ") // need deal with decimal places but this code is incorrect
			var speechOutput = speechOutputTemp.split('.').join(". ") // deal with any remaining dots and turn them into full stops

			if (speechOutput=="") speechOutput = "I'm sorry, I wasn't able to find an answer."
			response.tellWithCard(speechOutput, cardTitle, speechOutput)

            //    response.tell(speechOutput)
            }).catch(function(err) {
            console.log("ERROR" + err)
            speechOutput = "There was an error processing your search."
            response.tell(speechOutput)
        })
    },

    "AMAZON.StopIntent": function(intent, session, response) {
        var speechOutput = ""
        response.tell(speechOutput)
    }
}

exports.handler = function(event, context) {
    var AlexaGoogleSearchHelper = new AlexaGoogleSearch()
    AlexaGoogleSearchHelper.execute(event, context)
}<|endoftext|>