<commit_before>'use strict';

const { mapValues } = require('lodash');

const { EngineError } = require('../../error');

const handleJsl = async function () {
  return await function (input) {
    const { args, info: { ip }, params } = input;
    const contextInfo = { ip, params };
    if (args.filter) {
      args.filter = processJsl({ value: args.filter, contextInfo });
    }
    if (args.data) {
      args.data = processJsl({ value: args.data, contextInfo });
    }

    const response = this.next(input);
    return response;
  };
};

// Transform value if it is JSL, otherwise returns as is
const processJsl = function ({ value, name, contextInfo }) {
  if (!value) { return value; }

  // Recursion over objects and arrays
  if (value.constructor === Object) {
    return mapValues(value, (child, childName) => processJsl({ value: child, name: childName, contextInfo }));
  }
  if (value instanceof Array) {
    return value.map(child => processJsl({ value: child, name, contextInfo }));
  }

  // Process anything that contains $variables
  if (!testJsl({ value })) { return value; }

  const context = getContext(contextInfo);

  try {
    value = evalJsl({ value, name, context });
  } catch (innererror) {
    throw new EngineError(`JSL expression evaluation failed: ${value}`, { reason: 'JSL_SYNTAX', innererror });
  }
  return value;
};

// Looks for unescaped `$` to find $variables
const jslRegExp = /((?:(?:[^\\])\$)|(?:^\$))([^{]|$)/g;
// Test whether a value looks like JSL
const testJsl = ({ value }) => typeof value === 'string' && jslRegExp.test(value);

// Values available as `$variable` in JSL
// They are uppercase to avoid name conflict with attributes
const getContext = function ({ ip, params }) {
  // Context-related variables in JSL
  const NOW = (new Date()).toISOString();

  // Request-related variables in JSL
  const IP = ip;
  const PARAMS = params;

  return { NOW, IP, PARAMS };
};

// Execute JSL statements
const evalJsl = function ({ value, name, context }) {
  /* eslint-disable no-unused-vars */
  const $ = context;
  /* eslint-enable no-unused-vars */

  // Replace $var by $.var
  value = processJslShortcuts({ value, name });

  // Beware local (and global) variables are available inside eval(), i.e. must keep it to a minimal
  // TODO: this is highly insecure. E.g. value 'while (true) {}' would freeze the whole server. Also it has access to
  // global variables, including global.process. Problem is that alternatives are much slower, so we need to find a solution.
  const newValue = eval(value);
  return newValue;
};

// Looks for single $ signs, unescaped
const jslSingleDollarRegExp = /((?:(?:[^\\])\$)|(?:^\$))([^A-Za-z0-9_]|$)/g;
// Looks for unescaped $variable that looks like an attribute name
const jslAttrNameRegExp = /((?:(?:[^\\])\$)|(?:^\$))([a-z0-9_]+)/g;
// Modifies JSL $ shortcut notations
const processJslShortcuts = function ({ value, name }) {
  // Replace $ by $attr
  value = value.replace(jslSingleDollarRegExp, `$1${name}$2`);

  // Replace $attr by $MODEL.attr
  value = value.replace(jslAttrNameRegExp, '$1MODEL.$2');

  // Replace $var by $.var
  value = value.replace(jslRegExp, '$1.$2');

  return value;
};

module.exports = {
  handleJsl,
};
<commit_msg>Rename context to variables<commit_after>'use strict';

const { mapValues } = require('lodash');

const { EngineError } = require('../../error');

const handleJsl = async function () {
  return await function (input) {
    const { args, info: { ip }, params } = input;
    const variablesInfo = { ip, params };
    if (args.filter) {
      args.filter = processJsl({ value: args.filter, variablesInfo });
    }
    if (args.data) {
      args.data = processJsl({ value: args.data, variablesInfo });
    }

    const response = this.next(input);
    return response;
  };
};

// Transform value if it is JSL, otherwise returns as is
const processJsl = function ({ value, name, variablesInfo }) {
  if (!value) { return value; }

  // Recursion over objects and arrays
  if (value.constructor === Object) {
    return mapValues(value, (child, childName) => processJsl({ value: child, name: childName, variablesInfo }));
  }
  if (value instanceof Array) {
    return value.map(child => processJsl({ value: child, name, variablesInfo }));
  }

  // Process anything that contains $variables
  if (!testJsl({ value })) { return value; }

  const variables = getVariables(variablesInfo);

  try {
    value = evalJsl({ value, name, variables });
  } catch (innererror) {
    throw new EngineError(`JSL expression evaluation failed: ${value}`, { reason: 'JSL_SYNTAX', innererror });
  }
  return value;
};

// Looks for unescaped `$` to find $variables
const jslRegExp = /((?:(?:[^\\])\$)|(?:^\$))([^{]|$)/g;
// Test whether a value looks like JSL
const testJsl = ({ value }) => typeof value === 'string' && jslRegExp.test(value);

// Values available as `$variable` in JSL
// They are uppercase to avoid name conflict with attributes
const getVariables = function ({ ip, params }) {
  // Context-related variables in JSL
  const NOW = (new Date()).toISOString();

  // Request-related variables in JSL
  const IP = ip;
  const PARAMS = params;

  return { NOW, IP, PARAMS };
};

// Execute JSL statements
const evalJsl = function ({ value, name, variables }) {
  /* eslint-disable no-unused-vars */
  const $ = variables;
  /* eslint-enable no-unused-vars */

  // Replace $var by $.var
  value = processJslShortcuts({ value, name });

  // Beware local (and global) variables are available inside eval(), i.e. must keep it to a minimal
  // TODO: this is highly insecure. E.g. value 'while (true) {}' would freeze the whole server. Also it has access to
  // global variables, including global.process. Problem is that alternatives are much slower, so we need to find a solution.
  const newValue = eval(value);
  return newValue;
};

// Looks for single $ signs, unescaped
const jslSingleDollarRegExp = /((?:(?:[^\\])\$)|(?:^\$))([^A-Za-z0-9_]|$)/g;
// Looks for unescaped $variable that looks like an attribute name
const jslAttrNameRegExp = /((?:(?:[^\\])\$)|(?:^\$))([a-z0-9_]+)/g;
// Modifies JSL $ shortcut notations
const processJslShortcuts = function ({ value, name }) {
  // Replace $ by $attr
  value = value.replace(jslSingleDollarRegExp, `$1${name}$2`);

  // Replace $attr by $MODEL.attr
  value = value.replace(jslAttrNameRegExp, '$1MODEL.$2');

  // Replace $var by $.var
  value = value.replace(jslRegExp, '$1.$2');

  return value;
};

module.exports = {
  handleJsl,
};
<|endoftext|>


<commit_before>
var https = require('https');

var PriceDictionary = {};

exports.track = function track(bot, message, tickerSymbol) {
    // handling for ticker requests starting with $
    if (tickerSymbol.startsWith("$")) {
        tickerSymbol = tickerSymbol.substring(1, tickerSymbol.length);
    }

        // create stock url from message
    var finUrl = "https://finance.google.com/finance/info?client=ig&q=" + tickerSymbol;

    https.get(finUrl, function (res) {
        res.setEncoding('binary');
        var resData = "";

        res.on('data', function (chunk) {
            return resData += chunk;
        });

        res.on('end', function () {
            var preResult = resData.substring(3, resData.length - 1); // Google finance data starts with "//"
            try {
                var result = JSON.parse(preResult);
                var json = result[0];
                var url = "http://finance.yahoo.com/quote/" + tickerSymbol;

                var formatter = new MessageFormatter(json, url);
                var summary = formatter.summary();
                //var summary = FormatMessage(json, url);

                //var lastTradeDate = Date.parse( json["lt_dts"]) / 1000;

                bot.reply(message, summary);
            }
            catch(err) {
                bot.reply(message, ErrorMessage("Invalid ticker symbol: " + tickerSymbol));
            }
        });

        res.on('error', function(err){
            bot.reply(message, ErrorMessage(err));
        });
    })
};

//helper functions
function ComparePrevious(ticker, newValue){
    var jsonText;
    ticker = ticker.toUpperCase();
    if(PriceDictionary[ticker]){
        var previousValue = PriceDictionary[ticker];
        var difference = Number(newValue) - previousValue;
        difference = difference.toPrecision(4);
        var percentChange = difference / previousValue;
        percentChange = (percentChange*100).toPrecision(4);

        if(difference > 0){
            jsonText = "$" + newValue + ", " + difference + " (+" + percentChange + "%) since last request";
        }else if(difference < 0){
            jsonText = "$" + newValue + ", " + difference + " (" + percentChange + "%) since last request";
        }else{
            jsonText = "$" + newValue + ", " + difference + " (" + percentChange + "%) since last request";
        }
    }
    PriceDictionary[ticker] = Number(newValue);
    var obj = {
        jsonText:jsonText,
        change:difference
    };
    return obj;
}
function ErrorMessage(err){
    //we can extend this later
    return "An error occured: " + err;
}

//TODO
function GetColorAndSigns(change){
    var color, percentageSign;
    //green color for positive
    const positive = "#32CD32";
    //red color for negative
    const negative = "#FF0000";
    //light gray color for no change
    const noChange = "#E8E8E8";
    if(Number(change) > 0){
        color = positive;
        percentageSign = "+";
    }else if(Number(change) < 0){
        color = negative;
        percentageSign = "";
    }else{
        color = noChange;
        percentageSign = "";
    }

    return [color, percentageSign];
}

function FormatMessage(jsonResult, url){
    var tickerSymbol = jsonResult["t"];
    var previousClose = jsonResult["pcls_fix"];
    var last = jsonResult["l"];
    var lastTime = jsonResult["lt"];
    var change = jsonResult["c"];
    var changePercent = jsonResult["cp"];
    var afterLast = jsonResult["el"];
    var afterLastTime = jsonResult["elt"];
    var afterChange = jsonResult["ec"];
    var afterChangePercent = jsonResult["ecp"];

    var previousObject = ComparePrevious(tickerSymbol, last);
    if(previousObject.jsonText){
        var previousColor = GetColorAndSigns(previousObject.change)[0];
        var previousJSON = {
            "title":"Change since last request",
            "text": previousObject.jsonText,
            "color": previousColor,
            "mrkdwn_in": ["text"]
        }
    }

    var dayObj = {
        last : last,
        lastTime : lastTime,
        change : change,
        changePercent:changePercent,
        prevClose:previousClose
    };
    var afterObj = {
        last:afterLast,
        lastTime:afterLastTime,
        change:afterChange,
        changePercent:afterChangePercent
    };

    var dayJSON = GenerateText("Day Hours", dayObj);

    if (!afterLast) {
        var afterJSON = ""
    }
    else{
        var afterJSON = GenerateText("After Hours", afterObj);
    }

    var json = {
        "text": "*" + tickerSymbol + "*: " + url,
        "attachments": [
            previousJSON,
            dayJSON,
            afterJSON
        ]
    };

    return json;
}

function GenerateText(titletext, attachmentObj){
    var color = GetColorAndSigns(attachmentObj.change)[0];
    var percentSign = GetColorAndSigns(attachmentObj.change)[1];
    var JSONtext = "";
    if(titletext === "Day Hours"){
        JSONtext += "Prev Close: *$" + attachmentObj.prevClose + "*\n";
    }

    JSONtext += "Last: *$" + attachmentObj.last + "*"
                + " Time: `" + attachmentObj.lastTime + "`"
                + "\nChange: *" + attachmentObj.change + " (" + percentSign + attachmentObj.changePercent +"%)*";

    var retJSON = {
        "title": titletext,
        "text": JSONtext,
        "color": color,
        "mrkdwn_in": ["text"]
    };
    return retJSON;
}

var MessageFormatter = function(jsonResult, url){
    this.tickerSymbol = jsonResult["t"];
    this.previousClose = jsonResult["pcls_fix"];
    this.last = jsonResult["l"];
    this.lastTime = jsonResult["lt"];
    this.change = jsonResult["c"];
    this.changePercent = jsonResult["cp"];
    this.afterLast = jsonResult["el"];
    this.afterLastTime = jsonResult["elt"];
    this.afterChange = jsonResult["ec"];
    this.afterChangePercent = jsonResult["ecp"];
    this.URL = url;
};

MessageFormatter.prototype = function(){
    var GetSummary = function(){

        var previousObject = ComparePrevious(this.tickerSymbol, this.last);
        if(previousObject.jsonText){
            var previousColor = GetColorAndSigns(previousObject.change)[0];
            var previousJSON = {
                "title":"Change since last request",
                "text": previousObject.jsonText,
                "color": previousColor,
                "mrkdwn_in": ["text"]
            }
        }

        var dayObj = {
            last : this.last,
            lastTime : this.lastTime,
            change : this.change,
            changePercent: this.changePercent,
            prevClose: this.previousClose
        };
        var afterObj = {
            last: this.afterLast,
            lastTime: this.afterLastTime,
            change: this.afterChange,
            changePercent: this.afterChangePercent
        };

        var dayJSON = GenerateText("Day Hours", dayObj);

        if (!this.afterLast) {
            var afterJSON = ""
        }
        else{
            var afterJSON = GenerateText("After Hours", afterObj);
        }

        var json = {
            "text": "*" + this.tickerSymbol + "*: " + this.URL,
            "attachments": [
                previousJSON,
                dayJSON,
                afterJSON
            ]
        };

        return json;
    },

    //returns an array of 2 var
    //[0] is color
    //[1] is sign
    ColorsAndSigns = function (change){
        var color, percentageSign;
        //green color for positive
        const positive = "#32CD32";
        //red color for negative
        const negative = "#FF0000";
        //light gray color for no change
        const noChange = "#E8E8E8";
        if(Number(change) > 0){
            color = positive;
            percentageSign = "+";
        }else if(Number(change) < 0){
            color = negative;
            percentageSign = "";
        }else{
            color = noChange;
            percentageSign = "";
        }

        return [color, percentageSign];
    },

    ComparePrevious = function(ticker, newValue){
        var jsonText = "";
        ticker = ticker.toUpperCase();
        if(PriceDictionary[ticker]){
            var previousValue = PriceDictionary[ticker];
            var difference = Number(newValue) - previousValue;
            difference = difference.toPrecision(4);
            var percentChange = difference / previousValue;
            percentChange = (percentChange*100).toPrecision(4);

            if(difference > 0){
                jsonText = "$" + newValue + ", " + difference + " (+" + percentChange + "%) since last request";
            }else if(difference < 0){
                jsonText = "$" + newValue + ", " + difference + " (" + percentChange + "%) since last request";
            }else{
                jsonText = "$" + newValue + ", " + difference + " (" + percentChange + "%) since last request";
            }
        }
        PriceDictionary[ticker] = Number(newValue);

        var previousObj = {
            jsonText:jsonText,
            change:difference
        };

        return previousObj;
    },

    GenerateText = function(titletext, attachmentObj){
        var color = GetColorAndSigns(attachmentObj.change)[0];
        var percentSign = GetColorAndSigns(attachmentObj.change)[1];
        var JSONtext = "";
        if(titletext === "Day Hours"){
            JSONtext += "Prev Close: *$" + attachmentObj.prevClose + "*\n";
        }

        JSONtext += "Last: *$" + attachmentObj.last + "*"
                    + " Time: `" + attachmentObj.lastTime + "`"
                    + "\nChange: *" + attachmentObj.change + " (" + percentSign + attachmentObj.changePercent +"%)*";

        var retJSON = {
            "title": titletext,
            "text": JSONtext,
            "color": color,
            "mrkdwn_in": ["text"]
        };
        return retJSON;
    },

    TestingFunction = function(){
        return "test";
    };

    return {
        summary:GetSummary,
        test: TestingFunction
    };
}();<commit_msg>removed unnecessary helper functions<commit_after>
var https = require('https');

var PriceDictionary = {};

exports.track = function track(bot, message, tickerSymbol) {
    // handling for ticker requests starting with $
    if (tickerSymbol.startsWith("$")) {
        tickerSymbol = tickerSymbol.substring(1, tickerSymbol.length);
    }

        // create stock url from message
    var finUrl = "https://finance.google.com/finance/info?client=ig&q=" + tickerSymbol;

    https.get(finUrl, function (res) {
        res.setEncoding('binary');
        var resData = "";

        res.on('data', function (chunk) {
            return resData += chunk;
        });

        res.on('end', function () {
            var preResult = resData.substring(3, resData.length - 1); // Google finance data starts with "//"
            try {
                var result = JSON.parse(preResult);
                var json = result[0];
                var url = "http://finance.yahoo.com/quote/" + tickerSymbol;

                var formatter = new MessageFormatter(json, url);
                var summary = formatter.summary();
                //var summary = FormatMessage(json, url);

                //var lastTradeDate = Date.parse( json["lt_dts"]) / 1000;

                bot.reply(message, summary);
            }
            catch(err) {
                bot.reply(message, ErrorMessage("Invalid ticker symbol: " + tickerSymbol));
            }
        });

        res.on('error', function(err){
            bot.reply(message, ErrorMessage(err));
        });
    })
};

//helper functions
function ErrorMessage(err){
    //we can extend this later
    return "An error occured: " + err;
}

//MessageFormatter class
//uses the revealing prototype pattern
var MessageFormatter = function(jsonResult, url){
    this.tickerSymbol = jsonResult["t"];
    this.previousClose = jsonResult["pcls_fix"];
    this.last = jsonResult["l"];
    this.lastTime = jsonResult["lt"];
    this.change = jsonResult["c"];
    this.changePercent = jsonResult["cp"];
    this.afterLast = jsonResult["el"];
    this.afterLastTime = jsonResult["elt"];
    this.afterChange = jsonResult["ec"];
    this.afterChangePercent = jsonResult["ecp"];
    this.URL = url;
};

MessageFormatter.prototype = function(){
    var GetSummary = function(){

        var previousObject = ComparePrevious(this.tickerSymbol, this.last);
        if(previousObject.jsonText){
            var previousColor = GetColorAndSigns(previousObject.change)[0];
            var previousJSON = {
                "title":"Change since last request",
                "text": previousObject.jsonText,
                "color": previousColor,
                "mrkdwn_in": ["text"]
            }
        }

        var dayObj = {
            last : this.last,
            lastTime : this.lastTime,
            change : this.change,
            changePercent: this.changePercent,
            prevClose: this.previousClose
        };
        var afterObj = {
            last: this.afterLast,
            lastTime: this.afterLastTime,
            change: this.afterChange,
            changePercent: this.afterChangePercent
        };

        var dayJSON = GenerateText("Day Hours", dayObj);

        if (!this.afterLast) {
            var afterJSON = ""
        }
        else{
            var afterJSON = GenerateText("After Hours", afterObj);
        }

        var json = {
            "text": "*" + this.tickerSymbol + "*: " + this.URL,
            "attachments": [
                previousJSON,
                dayJSON,
                afterJSON
            ]
        };

        return json;
    },

    //returns an array of 2 var
    //[0] is color
    //[1] is sign
    ColorsAndSigns = function (change){
        var color, percentageSign;
        //green color for positive
        const positive = "#32CD32";
        //red color for negative
        const negative = "#FF0000";
        //light gray color for no change
        const noChange = "#E8E8E8";
        if(Number(change) > 0){
            color = positive;
            percentageSign = "+";
        }else if(Number(change) < 0){
            color = negative;
            percentageSign = "";
        }else{
            color = noChange;
            percentageSign = "";
        }

        return [color, percentageSign];
    },

    ComparePrevious = function(ticker, newValue){
        var jsonText = "";
        ticker = ticker.toUpperCase();
        if(PriceDictionary[ticker]){
            var previousValue = PriceDictionary[ticker];
            var difference = Number(newValue) - previousValue;
            difference = difference.toPrecision(4);
            var percentChange = difference / previousValue;
            percentChange = (percentChange*100).toPrecision(4);

            if(difference > 0){
                jsonText = "$" + newValue + ", " + difference + " (+" + percentChange + "%) since last request";
            }else if(difference < 0){
                jsonText = "$" + newValue + ", " + difference + " (" + percentChange + "%) since last request";
            }else{
                jsonText = "$" + newValue + ", " + difference + " (" + percentChange + "%) since last request";
            }
        }
        PriceDictionary[ticker] = Number(newValue);

        var previousObj = {
            jsonText:jsonText,
            change:difference
        };

        return previousObj;
    },

    GenerateText = function(titletext, attachmentObj){
        var color = GetColorAndSigns(attachmentObj.change)[0];
        var percentSign = GetColorAndSigns(attachmentObj.change)[1];
        var JSONtext = "";
        if(titletext === "Day Hours"){
            JSONtext += "Prev Close: *$" + attachmentObj.prevClose + "*\n";
        }

        JSONtext += "Last: *$" + attachmentObj.last + "*"
                    + " Time: `" + attachmentObj.lastTime + "`"
                    + "\nChange: *" + attachmentObj.change + " (" + percentSign + attachmentObj.changePercent +"%)*";

        var retJSON = {
            "title": titletext,
            "text": JSONtext,
            "color": color,
            "mrkdwn_in": ["text"]
        };
        return retJSON;
    },

    TestingFunction = function(){
        return "test";
    };

    return {
        summary:GetSummary,
        test: TestingFunction
    };
}();<|endoftext|>


<commit_before>'use strict';

function classDirective(name, selector) {
  name = 'ngClass' + name;
  return function() {
    return {
      restrict: 'AC',
      link: function(scope, element, attr) {
        var oldVal;

        scope.$watch(attr[name], ngClassWatchAction, true);

        attr.$observe('class', function(value) {
          ngClassWatchAction(scope.$eval(attr[name]));
        });

        if (name !== 'ngClass') {
          scope.$watch('$index', function($index, old$index) {
            // jshint bitwise: false
            var mod = $index & 1;
            if (mod !== old$index & 1) {
              var classes = flattenClasses(scope.$eval(attr[name]));
              mod === selector ?
                attr.$addClass(classes) :
                attr.$removeClass(classes);
            }
          });
        }

        function ngClassWatchAction(newVal) {
          if (selector === true || scope.$index % 2 === selector) {
            var newClasses = flattenClasses(newVal || '');
            if(!oldVal) {
              attr.$addClass(newClasses);
            } else if(!equals(newVal,oldVal)) {
              attr.$updateClass(newClasses, flattenClasses(oldVal));
            }
          }
          oldVal = copy(newVal);
        }

        function flattenClasses(classVal) {
          if(isArray(classVal)) {
            return classVal.join(' ');
          } else if (isObject(classVal)) {
            var classes = [], i = 0;
            forEach(classVal, function(v, k) {
              if (v) {
                classes.push(k);
              }
            });
            return classes.join(' ');
          }

          return classVal;
        }
      }
    };
  };
}

/**
 * @ngdoc directive
 * @name ng.directive:ngClass
 * @restrict AC
 *
 * @description
 * The `ngClass` directive allows you to dynamically set CSS classes on an HTML element by databinding
 * an expression that represents all classes to be added.
 *
 * The directive won't add duplicate classes if a particular class was already set.
 *
 * When the expression changes, the previously added classes are removed and only then the
 * new classes are added.
 *
 * @animations
 * add - happens just before the class is applied to the element
 * remove - happens just before the class is removed from the element
 *
 * @element ANY
 * @param {expression} ngClass {@link guide/expression Expression} to eval. The result
 *   of the evaluation can be a string representing space delimited class
 *   names, an array, or a map of class names to boolean values. In the case of a map, the
 *   names of the properties whose values are truthy will be added as css classes to the
 *   element.
 *
 * @example Example that demonstrates basic bindings via ngClass directive.
   <example>
     <file name="index.html">

Map Syntax Example

       <input type="checkbox" ng-model="deleted"> deleted (apply "strike" class)

       <input type="checkbox" ng-model="important"> important (apply "bold" class)

       <input type="checkbox" ng-model="error"> error (apply "red" class)

Using String Syntax

       <input type="text" ng-model="style" placeholder="Type: bold strike red">

Using Array Syntax

       <input ng-model="style1" placeholder="Type: bold, strike or red">

       <input ng-model="style2" placeholder="Type: bold, strike or red">

       <input ng-model="style3" placeholder="Type: bold, strike or red">

     </file>
     <file name="style.css">
       .strike {
         text-decoration: line-through;
       }
       .bold {
           font-weight: bold;
       }
       .red {
           color: red;
       }
     </file>
     <file name="protractorTest.js">
       var ps = element.all(by.css('.doc-example-live p'));

       it('should let you toggle the class', function() {

         expect(ps.first().getAttribute('class')).not.toMatch(/bold/);
         expect(ps.first().getAttribute('class')).not.toMatch(/red/);

         element(by.model('important')).click();
         expect(ps.first().getAttribute('class')).toMatch(/bold/);

         element(by.model('error')).click();
         expect(ps.first().getAttribute('class')).toMatch(/red/);
       });

       it('should let you toggle string example', function() {
         expect(ps.get(1).getAttribute('class')).toBe('');
         element(by.model('style')).clear();
         element(by.model('style')).sendKeys('red');
         browser.debugger();
         expect(ps.get(1).getAttribute('class')).toBe('red');
       });

       it('array example should have 3 classes', function() {
         expect(ps.last().getAttribute('class')).toBe('');
         element(by.model('style1')).sendKeys('bold');
         element(by.model('style2')).sendKeys('strike');
         element(by.model('style3')).sendKeys('red');
         expect(ps.last().getAttribute('class')).toBe('bold strike red');
       });
     </file>
   </example>

   ## Animations

   The example below demonstrates how to perform animations using ngClass.

   <example animations="true">
     <file name="index.html">
      <input id="setbtn" type="button" value="set" ng-click="myVar='my-class'">
      <input id="clearbtn" type="button" value="clear" ng-click="myVar=''">

      Sample Text
     </file>
     <file name="style.css">
       .base-class {
         -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
         transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
       }

       .base-class.my-class {
         color: red;
         font-size:3em;
       }
     </file>
     <file name="protractorTest.js">
       it('should check ng-class', function() {
         expect(element(by.css('.base-class')).getAttribute('class')).not.
           toMatch(/my-class/);

         element(by.id('setbtn')).click();

         expect(element(by.css('.base-class')).getAttribute('class')).
           toMatch(/my-class/);

         element(by.id('clearbtn')).click();

         expect(element(by.css('.base-class')).getAttribute('class')).not.
           toMatch(/my-class/);
       });
     </file>
   </example>

   ## ngClass and pre-existing CSS3 Transitions/Animations
   The ngClass directive still supports CSS3 Transitions/Animations even if they do not follow the ngAnimate CSS naming structure.
   Upon animation ngAnimate will apply supplementary CSS classes to track the start and end of an animation, but this will not hinder
   any pre-existing CSS transitions already on the element. To get an idea of what happens during a class-based animation, be sure
   to view the step by step details of {@link ngAnimate.$animate#methods_addclass $animate.addClass} and
   {@link ngAnimate.$animate#methods_removeclass $animate.removeClass}.
 */
var ngClassDirective = classDirective('', true);

/**
 * @ngdoc directive
 * @name ng.directive:ngClassOdd
 * @restrict AC
 *
 * @description
 * The `ngClassOdd` and `ngClassEven` directives work exactly as
 * {@link ng.directive:ngClass ngClass}, except they work in
 * conjunction with `ngRepeat` and take effect only on odd (even) rows.
 *
 * This directive can be applied only within the scope of an
 * {@link ng.directive:ngRepeat ngRepeat}.
 *
 * @element ANY
 * @param {expression} ngClassOdd {@link guide/expression Expression} to eval. The result
 *   of the evaluation can be a string representing space delimited class names or an array.
 *
 * @example
   <example>
     <file name="index.html">

             {{name}}

     </file>
     <file name="style.css">
       .odd {
         color: red;
       }
       .even {
         color: blue;
       }
     </file>
     <file name="protractorTest.js">
       it('should check ng-class-odd and ng-class-even', function() {
         expect(element(by.repeater('name in names').row(0).column('name')).getAttribute('class')).
           toMatch(/odd/);
         expect(element(by.repeater('name in names').row(1).column('name')).getAttribute('class')).
           toMatch(/even/);
       });
     </file>
   </example>
 */
var ngClassOddDirective = classDirective('Odd', 0);

/**
 * @ngdoc directive
 * @name ng.directive:ngClassEven
 * @restrict AC
 *
 * @description
 * The `ngClassOdd` and `ngClassEven` directives work exactly as
 * {@link ng.directive:ngClass ngClass}, except they work in
 * conjunction with `ngRepeat` and take effect only on odd (even) rows.
 *
 * This directive can be applied only within the scope of an
 * {@link ng.directive:ngRepeat ngRepeat}.
 *
 * @element ANY
 * @param {expression} ngClassEven {@link guide/expression Expression} to eval. The
 *   result of the evaluation can be a string representing space delimited class names or an array.
 *
 * @example
   <example>
     <file name="index.html">

             {{name}}

     </file>
     <file name="style.css">
       .odd {
         color: red;
       }
       .even {
         color: blue;
       }
     </file>
     <file name="protractorTest.js">
       it('should check ng-class-odd and ng-class-even', function() {
         expect(element(by.repeater('name in names').row(0).column('name')).getAttribute('class')).
           toMatch(/odd/);
         expect(element(by.repeater('name in names').row(1).column('name')).getAttribute('class')).
           toMatch(/even/);
       });
     </file>
   </example>
 */
var ngClassEvenDirective = classDirective('Even', 1);
<commit_msg>chore(ngClass): remove debugger statement from an e2e test<commit_after>'use strict';

function classDirective(name, selector) {
  name = 'ngClass' + name;
  return function() {
    return {
      restrict: 'AC',
      link: function(scope, element, attr) {
        var oldVal;

        scope.$watch(attr[name], ngClassWatchAction, true);

        attr.$observe('class', function(value) {
          ngClassWatchAction(scope.$eval(attr[name]));
        });

        if (name !== 'ngClass') {
          scope.$watch('$index', function($index, old$index) {
            // jshint bitwise: false
            var mod = $index & 1;
            if (mod !== old$index & 1) {
              var classes = flattenClasses(scope.$eval(attr[name]));
              mod === selector ?
                attr.$addClass(classes) :
                attr.$removeClass(classes);
            }
          });
        }

        function ngClassWatchAction(newVal) {
          if (selector === true || scope.$index % 2 === selector) {
            var newClasses = flattenClasses(newVal || '');
            if(!oldVal) {
              attr.$addClass(newClasses);
            } else if(!equals(newVal,oldVal)) {
              attr.$updateClass(newClasses, flattenClasses(oldVal));
            }
          }
          oldVal = copy(newVal);
        }

        function flattenClasses(classVal) {
          if(isArray(classVal)) {
            return classVal.join(' ');
          } else if (isObject(classVal)) {
            var classes = [], i = 0;
            forEach(classVal, function(v, k) {
              if (v) {
                classes.push(k);
              }
            });
            return classes.join(' ');
          }

          return classVal;
        }
      }
    };
  };
}

/**
 * @ngdoc directive
 * @name ng.directive:ngClass
 * @restrict AC
 *
 * @description
 * The `ngClass` directive allows you to dynamically set CSS classes on an HTML element by databinding
 * an expression that represents all classes to be added.
 *
 * The directive won't add duplicate classes if a particular class was already set.
 *
 * When the expression changes, the previously added classes are removed and only then the
 * new classes are added.
 *
 * @animations
 * add - happens just before the class is applied to the element
 * remove - happens just before the class is removed from the element
 *
 * @element ANY
 * @param {expression} ngClass {@link guide/expression Expression} to eval. The result
 *   of the evaluation can be a string representing space delimited class
 *   names, an array, or a map of class names to boolean values. In the case of a map, the
 *   names of the properties whose values are truthy will be added as css classes to the
 *   element.
 *
 * @example Example that demonstrates basic bindings via ngClass directive.
   <example>
     <file name="index.html">

Map Syntax Example

       <input type="checkbox" ng-model="deleted"> deleted (apply "strike" class)

       <input type="checkbox" ng-model="important"> important (apply "bold" class)

       <input type="checkbox" ng-model="error"> error (apply "red" class)

Using String Syntax

       <input type="text" ng-model="style" placeholder="Type: bold strike red">

Using Array Syntax

       <input ng-model="style1" placeholder="Type: bold, strike or red">

       <input ng-model="style2" placeholder="Type: bold, strike or red">

       <input ng-model="style3" placeholder="Type: bold, strike or red">

     </file>
     <file name="style.css">
       .strike {
         text-decoration: line-through;
       }
       .bold {
           font-weight: bold;
       }
       .red {
           color: red;
       }
     </file>
     <file name="protractorTest.js">
       var ps = element.all(by.css('.doc-example-live p'));

       it('should let you toggle the class', function() {

         expect(ps.first().getAttribute('class')).not.toMatch(/bold/);
         expect(ps.first().getAttribute('class')).not.toMatch(/red/);

         element(by.model('important')).click();
         expect(ps.first().getAttribute('class')).toMatch(/bold/);

         element(by.model('error')).click();
         expect(ps.first().getAttribute('class')).toMatch(/red/);
       });

       it('should let you toggle string example', function() {
         expect(ps.get(1).getAttribute('class')).toBe('');
         element(by.model('style')).clear();
         element(by.model('style')).sendKeys('red');
         expect(ps.get(1).getAttribute('class')).toBe('red');
       });

       it('array example should have 3 classes', function() {
         expect(ps.last().getAttribute('class')).toBe('');
         element(by.model('style1')).sendKeys('bold');
         element(by.model('style2')).sendKeys('strike');
         element(by.model('style3')).sendKeys('red');
         expect(ps.last().getAttribute('class')).toBe('bold strike red');
       });
     </file>
   </example>

   ## Animations

   The example below demonstrates how to perform animations using ngClass.

   <example animations="true">
     <file name="index.html">
      <input id="setbtn" type="button" value="set" ng-click="myVar='my-class'">
      <input id="clearbtn" type="button" value="clear" ng-click="myVar=''">

      Sample Text
     </file>
     <file name="style.css">
       .base-class {
         -webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
         transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 0.5s;
       }

       .base-class.my-class {
         color: red;
         font-size:3em;
       }
     </file>
     <file name="protractorTest.js">
       it('should check ng-class', function() {
         expect(element(by.css('.base-class')).getAttribute('class')).not.
           toMatch(/my-class/);

         element(by.id('setbtn')).click();

         expect(element(by.css('.base-class')).getAttribute('class')).
           toMatch(/my-class/);

         element(by.id('clearbtn')).click();

         expect(element(by.css('.base-class')).getAttribute('class')).not.
           toMatch(/my-class/);
       });
     </file>
   </example>

   ## ngClass and pre-existing CSS3 Transitions/Animations
   The ngClass directive still supports CSS3 Transitions/Animations even if they do not follow the ngAnimate CSS naming structure.
   Upon animation ngAnimate will apply supplementary CSS classes to track the start and end of an animation, but this will not hinder
   any pre-existing CSS transitions already on the element. To get an idea of what happens during a class-based animation, be sure
   to view the step by step details of {@link ngAnimate.$animate#methods_addclass $animate.addClass} and
   {@link ngAnimate.$animate#methods_removeclass $animate.removeClass}.
 */
var ngClassDirective = classDirective('', true);

/**
 * @ngdoc directive
 * @name ng.directive:ngClassOdd
 * @restrict AC
 *
 * @description
 * The `ngClassOdd` and `ngClassEven` directives work exactly as
 * {@link ng.directive:ngClass ngClass}, except they work in
 * conjunction with `ngRepeat` and take effect only on odd (even) rows.
 *
 * This directive can be applied only within the scope of an
 * {@link ng.directive:ngRepeat ngRepeat}.
 *
 * @element ANY
 * @param {expression} ngClassOdd {@link guide/expression Expression} to eval. The result
 *   of the evaluation can be a string representing space delimited class names or an array.
 *
 * @example
   <example>
     <file name="index.html">

             {{name}}

     </file>
     <file name="style.css">
       .odd {
         color: red;
       }
       .even {
         color: blue;
       }
     </file>
     <file name="protractorTest.js">
       it('should check ng-class-odd and ng-class-even', function() {
         expect(element(by.repeater('name in names').row(0).column('name')).getAttribute('class')).
           toMatch(/odd/);
         expect(element(by.repeater('name in names').row(1).column('name')).getAttribute('class')).
           toMatch(/even/);
       });
     </file>
   </example>
 */
var ngClassOddDirective = classDirective('Odd', 0);

/**
 * @ngdoc directive
 * @name ng.directive:ngClassEven
 * @restrict AC
 *
 * @description
 * The `ngClassOdd` and `ngClassEven` directives work exactly as
 * {@link ng.directive:ngClass ngClass}, except they work in
 * conjunction with `ngRepeat` and take effect only on odd (even) rows.
 *
 * This directive can be applied only within the scope of an
 * {@link ng.directive:ngRepeat ngRepeat}.
 *
 * @element ANY
 * @param {expression} ngClassEven {@link guide/expression Expression} to eval. The
 *   result of the evaluation can be a string representing space delimited class names or an array.
 *
 * @example
   <example>
     <file name="index.html">

             {{name}}

     </file>
     <file name="style.css">
       .odd {
         color: red;
       }
       .even {
         color: blue;
       }
     </file>
     <file name="protractorTest.js">
       it('should check ng-class-odd and ng-class-even', function() {
         expect(element(by.repeater('name in names').row(0).column('name')).getAttribute('class')).
           toMatch(/odd/);
         expect(element(by.repeater('name in names').row(1).column('name')).getAttribute('class')).
           toMatch(/even/);
       });
     </file>
   </example>
 */
var ngClassEvenDirective = classDirective('Even', 1);
<|endoftext|>


<commit_before>import Item from '../item';

export default class Portal extends Item {
    constructor (game, x, y) {
        super(game, x, y, 'portal');
        if (this.player.getInfo()['gems'] >= 5) {
            this.spawnRate = 0.01;
        }
        else {
            this.spawnRate = 0.01;
        }

        this.scale.setTo(0.30);
    }
}
<commit_msg>dont show portals until 5 gems<commit_after>import Item from '../item';

export default class Portal extends Item {
    constructor (game, x, y) {
        super(game, x, y, 'portal');
        if (this.player.getInfo()['gems'] >= 5) {
            this.spawnRate = 0.00;
        }
        else {
            this.spawnRate = 0.01;
        }

        this.scale.setTo(0.30);
    }
}
<|endoftext|>


<commit_before>define(['pex/geom/Vec3'], function(Vec3) {
  function BoundingBox(min, max) {
    this.min = min;
    this.max = max;
  }

  BoundingBox.fromPositionSize = function(pos, size) {
    return new BoundingBox(
      Vec3.create(pos. - size./2, pos.y - size.y/2, pos.z - size.z/2),
      Vec3.create(pos. + size./2, pos.y + size.y/2, pos.z + size.z/2)
    );
  }

  BoundingBox.fromPoints = function(points) {
    var bbox = new BoundingBox(Vec3.clone(points., Vec3.clone(points.)));
    points.forEach(bbox.addPoint.bind(bbox));
    return bbox;
  }

  BoundingBox.prototype.isEmpty = function() {
    if (!this.min || !this.max) return true;
    else return false;
  }

  BoundingBox.prototype.addPoint = function(p) {
    if (this.isEmpty()) {
      this.min = Vec3.clone(p);
      this.max = Vec3.clone(p);
    }

    if (p. < this.min.) this.min. = p.;
    if (p.y < this.min.y) this.min.y = p.y;
    if (p.z < this.min.z) this.min.z = p.z;
    if (p. > this.max.) this.max. = p.;
    if (p.y > this.max.y) this.max.y = p.y;
    if (p.z > this.max.z) this.max.z = p.z;
  }

  BoundingBox.prototype.getSize = function(out) {
    if (!out) {
      if (!this.size) {
        this.size = Vec3.create();
      }
      out = this.size;
    }

    if (this.isEmpty()) {
      Vec3.set(out, 0, 0, 0);
      return out;
    }

    Vec3.set(out,
     (this.max. - this.min.),
     (this.max.y - this.min.y),
     (this.max.z - this.min.z)
    );
    return out;
  }

  BoundingBox.prototype.getCenter = function(out) {
    if (!out) {
      if (!this.center) {
        this.center = Vec3.create();
      }
      out = this.center;
    }

    Vec3.set(out,
     (this.min. + this.max.)/2,
     (this.min.y + this.max.y)/2,
     (this.min.z + this.max.z)/2
    );
    return out;
  }

  return BoundingBox;
})<commit_msg>Fixed BoundingBox<commit_after>define(['pex/geom/Vec3'], function(Vec3) {
  function BoundingBox(min, max) {
    this.min = min;
    this.max = max;
  }

  BoundingBox.fromPositionSize = function(pos, size) {
    return new BoundingBox(
      Vec3.create(pos. - size./2, pos.y - size.y/2, pos.z - size.z/2),
      Vec3.create(pos. + size./2, pos.y + size.y/2, pos.z + size.z/2)
    );
  }

  BoundingBox.fromPoints = function(points) {
    var bbox = new BoundingBox(Vec3.clone(points., Vec3.clone(points.)));
    points.forEach(bbox.addPoint.bind(bbox));
    return bbox;
  }

  BoundingBox.prototype.isEmpty = function() {
    if (!this.min || !this.max) return true;
    else return false;
  }

  BoundingBox.prototype.addPoint = function(p) {
    if (this.isEmpty()) {
      this.min = Vec3.clone(p);
      this.max = Vec3.clone(p);
    }

    if (p.x < this.min.x) this.min.x = p.;
    if (p.y < this.min.y) this.min.y = p.y;
    if (p.z < this.min.z) this.min.z = p.z;
    if (p.x > this.max.x) this.max.x = p.;
    if (p.y > this.max.y) this.max.y = p.y;
    if (p.z > this.max.z) this.max.z = p.z;
  }

  BoundingBox.prototype.getSize = function(out) {
    if (!out) {
      if (!this.size) {
        this.size = Vec3.create();
      }
      out = this.size;
    }

    if (this.isEmpty()) {
      Vec3.set(out, 0, 0, 0);
      return out;
    }

    Vec3.set(out,
     (this.max. - this.min.),
     (this.max.y - this.min.y),
     (this.max.z - this.min.z)
    );
    return out;
  }

  BoundingBox.prototype.getCenter = function(out) {
    if (!out) {
      if (!this.center) {
        this.center = Vec3.create();
      }
      out = this.center;
    }

    Vec3.set(out,
     (this.min. + this.max.)/2,
     (this.min.y + this.max.y)/2,
     (this.min.z + this.max.z)/2
    );
    return out;
  }

  return BoundingBox;
})<|endoftext|>


<commit_before>import { checkMethod, checkParam } from '../utils'
import { ServiceProvider  } from './serviceProvider';
import { parseUrl, exists } from '../utils'
import { LoggerFactory } from '../logging'

const DOLPHIN_PLATFORM_PREFIX = 'dolphin_platform_intern_';
const CLIENT_ID_HTTP_HEADER_NAME = DOLPHIN_PLATFORM_PREFIX + 'dolphinClientId';

class ClientScope {

    constructor() {
        this.clientIds = new Map();
    }

    handleRequest(httpRequest) {
        checkMethod('handleRequest');
        checkParam(httpRequest, 'httpRequest');
        const clientId = this.getClientId(httpRequest.url);
        if (exists(clientId)) {
            ClientScope.LOGGER.trace('Using ClientId', clientId);
            httpRequest.setRequestHeader(CLIENT_ID_HTTP_HEADER_NAME, clientId);
        }
    }

    handleResponse(httpResponse) {
        checkMethod('handleResponse');
        checkParam(httpResponse, 'httpResponse');
        const clientId = this.getClientId(httpResponse.url);
        const newClientId = httpResponse.getHeaderByName(CLIENT_ID_HTTP_HEADER_NAME);
        if (exists(clientId) && exists(newClientId) && clientId !== newClientId) {
            throw new Error('Client Id does not match!');
        }
        if (!exists(clientId) && exists(newClientId)) {
            ClientScope.LOGGER.debug('New ClientId found', newClientId);
            this.setClientId(httpResponse.url, newClientId);
        }
    }

    initServiceProvider(platformClient) {
        checkMethod('initServiceProvider');
        checkParam(platformClient, 'platformClient');
        platformClient.getService('HttpClientInterceptor').addRequestInterceptor(this);
        platformClient.getService('HttpClientInterceptor').addResponseInterceptor(this);
    }

    getClientId(url) {
        const result = parseUrl(url);
        const key = ClientScope.calcKey(result.hostname, result.port)
        return this.clientIds.get(key);
    }

    setClientId(url, clientId) {
        const result = parseUrl(url);
        const key = ClientScope.calcKey(result.hostname, result.port)
        this.clientIds.set(key, clientId);
        ClientScope.LOGGER.trace('Setting ClientId', clientId, 'for', url, 'with key', key);
    }

}

ClientScope.calcKey = function(hostname, port) {
    return hostname + port;
}

ClientScope.LOGGER = LoggerFactory.getLogger('ClientScope');

function register(platformClient) {
    if (exists(platformClient)) {
        const clientScopeProvider = new ServiceProvider(ClientScope, 'ClientScope');

        platformClient.registerServiceProvider(clientScopeProvider);
    }
}

export { register }<commit_msg>Clean up duplicate import<commit_after>import { checkMethod, checkParam, parseUrl, exists } from '../utils';
import { ServiceProvider  } from './serviceProvider';
import { LoggerFactory } from '../logging';

const DOLPHIN_PLATFORM_PREFIX = 'dolphin_platform_intern_';
const CLIENT_ID_HTTP_HEADER_NAME = DOLPHIN_PLATFORM_PREFIX + 'dolphinClientId';

class ClientScope {

    constructor() {
        this.clientIds = new Map();
    }

    handleRequest(httpRequest) {
        checkMethod('handleRequest');
        checkParam(httpRequest, 'httpRequest');
        const clientId = this.getClientId(httpRequest.url);
        if (exists(clientId)) {
            ClientScope.LOGGER.trace('Using ClientId', clientId);
            httpRequest.setRequestHeader(CLIENT_ID_HTTP_HEADER_NAME, clientId);
        }
    }

    handleResponse(httpResponse) {
        checkMethod('handleResponse');
        checkParam(httpResponse, 'httpResponse');
        const clientId = this.getClientId(httpResponse.url);
        const newClientId = httpResponse.getHeaderByName(CLIENT_ID_HTTP_HEADER_NAME);
        if (exists(clientId) && exists(newClientId) && clientId !== newClientId) {
            throw new Error('Client Id does not match!');
        }
        if (!exists(clientId) && exists(newClientId)) {
            ClientScope.LOGGER.debug('New ClientId found', newClientId);
            this.setClientId(httpResponse.url, newClientId);
        }
    }

    initServiceProvider(platformClient) {
        checkMethod('initServiceProvider');
        checkParam(platformClient, 'platformClient');
        platformClient.getService('HttpClientInterceptor').addRequestInterceptor(this);
        platformClient.getService('HttpClientInterceptor').addResponseInterceptor(this);
    }

    getClientId(url) {
        const result = parseUrl(url);
        const key = ClientScope.calcKey(result.hostname, result.port)
        return this.clientIds.get(key);
    }

    setClientId(url, clientId) {
        const result = parseUrl(url);
        const key = ClientScope.calcKey(result.hostname, result.port)
        this.clientIds.set(key, clientId);
        ClientScope.LOGGER.trace('Setting ClientId', clientId, 'for', url, 'with key', key);
    }

}

ClientScope.calcKey = function(hostname, port) {
    return hostname + port;
}

ClientScope.LOGGER = LoggerFactory.getLogger('ClientScope');

function register(platformClient) {
    if (exists(platformClient)) {
        const clientScopeProvider = new ServiceProvider(ClientScope, 'ClientScope');

        platformClient.registerServiceProvider(clientScopeProvider);
    }
}

export { register }<|endoftext|>


<commit_before>// install   :     cordova plugin add org.apache.cordova.inappbrowser
// link      :     https://github.com/apache/cordova-plugin-inappbrowser/blob/master/doc/index.md

angular.module('ngCordova.plugins.inAppBrowser', [])

  .provider('$cordovaInAppBrowser', [function () {

    var ref;
    var defaultOptions = this.defaultOptions = {};

    this.setDefaultOptions = function (config) {
      defaultOptions = angular.extend(defaultOptions, config);
    };

    this.$get = ['$rootScope', '$q', '$window', '$timeout', function ($rootScope, $q, $window, $timeout) {
      return {
        open: function (url, target, requestOptions) {
          var q = $q.defer();

          if (requestOptions && !angular.isObject(requestOptions)) {
            q.reject("options must be an object");
            return q.promise;
          }

          var options = angular.extend({}, defaultOptions, requestOptions);

          var opt = [];
          angular.forEach(options, function (value, key) {
            opt.push(key + '=' + value);
          });
          var optionsString = opt.join();

          ref = $window.open(url, target, optionsString);

          ref.addEventListener('loadstart', function (event) {
            $timeout(function () {
              $rootScope.$broadcast('$cordovaInAppBrowser:loadstart', event);
            });
          }, false);

          ref.addEventListener('loadstop', function (event) {
            q.resolve(event);
            $timeout(function () {
              $rootScope.$broadcast('$cordovaInAppBrowser:loadstop', event);
            });
          }, false);

          ref.addEventListener('loaderror', function (event) {
            q.reject(event);
            $timeout(function () {
              $rootScope.$broadcast('$cordovaInAppBrowser:loaderror', event);
            });
          }, false);

          ref.addEventListener('exit', function (event) {
            $timeout(function () {
              $rootScope.$broadcast('$cordovaInAppBrowser:exit', event);
            });
          }, false);

          return q.promise;
        },

        close: function () {
          ref.close();
        },

        show: function () {
          ref.show();
        },

        executeScript: function (details) {
          var q = $q.defer();

          ref.executeScript(details, function (result) {
            q.resolve(result);
          });

          return q.promise;
        },

        insertCSS: function (details) {
          var q = $q.defer();

          ref.insertCSS(details, function (result) {
            q.resolve(result);
          });

          return q.promise;
        }
      };
    }];
  }]);
<commit_msg>fix(plugin:inAppBrowser): remove reference to window upon close()<commit_after>// install   :     cordova plugin add org.apache.cordova.inappbrowser
// link      :     https://github.com/apache/cordova-plugin-inappbrowser/blob/master/doc/index.md

angular.module('ngCordova.plugins.inAppBrowser', [])

  .provider('$cordovaInAppBrowser', [function () {

    var ref;
    var defaultOptions = this.defaultOptions = {};

    this.setDefaultOptions = function (config) {
      defaultOptions = angular.extend(defaultOptions, config);
    };

    this.$get = ['$rootScope', '$q', '$window', '$timeout', function ($rootScope, $q, $window, $timeout) {
      return {
        open: function (url, target, requestOptions) {
          var q = $q.defer();

          if (requestOptions && !angular.isObject(requestOptions)) {
            q.reject("options must be an object");
            return q.promise;
          }

          var options = angular.extend({}, defaultOptions, requestOptions);

          var opt = [];
          angular.forEach(options, function (value, key) {
            opt.push(key + '=' + value);
          });
          var optionsString = opt.join();

          ref = $window.open(url, target, optionsString);

          ref.addEventListener('loadstart', function (event) {
            $timeout(function () {
              $rootScope.$broadcast('$cordovaInAppBrowser:loadstart', event);
            });
          }, false);

          ref.addEventListener('loadstop', function (event) {
            q.resolve(event);
            $timeout(function () {
              $rootScope.$broadcast('$cordovaInAppBrowser:loadstop', event);
            });
          }, false);

          ref.addEventListener('loaderror', function (event) {
            q.reject(event);
            $timeout(function () {
              $rootScope.$broadcast('$cordovaInAppBrowser:loaderror', event);
            });
          }, false);

          ref.addEventListener('exit', function (event) {
            $timeout(function () {
              $rootScope.$broadcast('$cordovaInAppBrowser:exit', event);
            });
          }, false);

          return q.promise;
        },

        close: function () {
          ref.close();
          ref = null;
        },

        show: function () {
          ref.show();
        },

        executeScript: function (details) {
          var q = $q.defer();

          ref.executeScript(details, function (result) {
            q.resolve(result);
          });

          return q.promise;
        },

        insertCSS: function (details) {
          var q = $q.defer();

          ref.insertCSS(details, function (result) {
            q.resolve(result);
          });

          return q.promise;
        }
      };
    }];
  }]);
<|endoftext|>


<commit_before>Ext.define('guibase.Router', {
    extend: 'Ext.util.Observable',
    requires: [
        'Ext.util.History'
    ],

    namedParam: /:\w+/g,
    splatParam: /\*\w+/g,
    escapeRegExp: /[-[\]{}()+?.,\\^$|#\s]/g,

    constructor: function(handler) {
        this.handler = handler;
        this.routes = [];
        this.started = false;
        this.callParent();
    },

    add: function(pattern, action) {
        var regex;
        if(Ext.typeOf(pattern) == 'regexp') {
            regex = pattern;
        } else if(Ext.typeOf(pattern) == 'string') {
            regex = this._patternToRegExp(pattern);
        } else {
            throw 'pattern must be regex.';
        }
        this.routes.push({
            regex: regex,
            action: action
        });
    },

    start: function() {
        if(this.started) {
            throw "Can only start() once!";
        }
        this.started = true;
        this._initHistory();
    },

    _trigger: function(token) {
        if(token == null) {
            token = '';
        }
        for(var index in this.routes) {
            var route = this.routes[index];
            var match = token.match(route.regex);
            if(match) {
                var args = match.slice(1);
                Ext.bind(this.handler[route.action], this.handler, args, true)({
                    action: route.action,
                    token: token
                });
                return;
            }
        }
        Ext.bind(this.handler['routeNotFound'], this.handler)({
            action: 'routeNotFound',
            token: token
        });
    },

    _initHistory: function() {
        Ext.getBody().createChild({
            tag: 'form',
            id: 'history-form' ,
            cls: Ext.baseCSSPrefix + 'hide-display',
            html: [
                '<input type="hidden" id="', Ext.util.History.fieldId, '" />',
                ''
            ].join('')
		});
		Ext.util.History.init(this._onHistoryReady, this);
    },

    _onHistoryReady: function(history) {
        this.mon(Ext.util.History, 'change', this._onHistoryChange, this);
        var token = history.getToken();
        if(token == null) {
            token = '';
        }
        this._trigger(token);
    },

    _onHistoryChange: function(token) {
        this._trigger(token);
    },

    /**
     * @private
     * Convert a route string into a regular expression, suitable for matching
     * against the current location hash.
     */
    _patternToRegExp: function(pattern) {
        var regex = pattern.replace(this.escapeRegExp, '\\$&');
        regex = regex.replace(this.namedParam, '([^\/]*)');
        regex = regex.replace(this.splatParam, '(.*?)');
        return new RegExp('^' + regex + '$');
    },

    navigate: function(token, triggerRoute) {
        Ext.util.History.add(token);
    }
});
<commit_msg>apps.guibase...Router: Removed unused arg.<commit_after>Ext.define('guibase.Router', {
    extend: 'Ext.util.Observable',
    requires: [
        'Ext.util.History'
    ],

    namedParam: /:\w+/g,
    splatParam: /\*\w+/g,
    escapeRegExp: /[-[\]{}()+?.,\\^$|#\s]/g,

    constructor: function(handler) {
        this.handler = handler;
        this.routes = [];
        this.started = false;
        this.callParent();
    },

    add: function(pattern, action) {
        var regex;
        if(Ext.typeOf(pattern) == 'regexp') {
            regex = pattern;
        } else if(Ext.typeOf(pattern) == 'string') {
            regex = this._patternToRegExp(pattern);
        } else {
            throw 'pattern must be regex.';
        }
        this.routes.push({
            regex: regex,
            action: action
        });
    },

    start: function() {
        if(this.started) {
            throw "Can only start() once!";
        }
        this.started = true;
        this._initHistory();
    },

    _trigger: function(token) {
        if(token == null) {
            token = '';
        }
        for(var index in this.routes) {
            var route = this.routes[index];
            var match = token.match(route.regex);
            if(match) {
                var args = match.slice(1);
                Ext.bind(this.handler[route.action], this.handler, args, true)({
                    action: route.action,
                    token: token
                });
                return;
            }
        }
        Ext.bind(this.handler['routeNotFound'], this.handler)({
            action: 'routeNotFound',
            token: token
        });
    },

    _initHistory: function() {
        Ext.getBody().createChild({
            tag: 'form',
            id: 'history-form' ,
            cls: Ext.baseCSSPrefix + 'hide-display',
            html: [
                '<input type="hidden" id="', Ext.util.History.fieldId, '" />',
                ''
            ].join('')
		});
		Ext.util.History.init(this._onHistoryReady, this);
    },

    _onHistoryReady: function(history) {
        this.mon(Ext.util.History, 'change', this._onHistoryChange, this);
        var token = history.getToken();
        if(token == null) {
            token = '';
        }
        this._trigger(token);
    },

    _onHistoryChange: function(token) {
        this._trigger(token);
    },

    /**
     * @private
     * Convert a route string into a regular expression, suitable for matching
     * against the current location hash.
     */
    _patternToRegExp: function(pattern) {
        var regex = pattern.replace(this.escapeRegExp, '\\$&');
        regex = regex.replace(this.namedParam, '([^\/]*)');
        regex = regex.replace(this.splatParam, '(.*?)');
        return new RegExp('^' + regex + '$');
    },

    navigate: function(token) {
        Ext.util.History.add(token);
    }
});
<|endoftext|>


<commit_before>(function () {
    'use strict';

    var texture = document.querySelector('.js-texture');

    if (!texture) {
        return;
    }

    var scene = new THREE.Scene();
    var camera = new THREE.PerspectiveCamera( 45, window.innerWidth/window.innerHeight, 0.1, 1000 );

    window.addEventListener( 'orientationchange', onOrientationChange, false );

    var renderer = new THREE.WebGLRenderer({
        alpha : true
    });
    renderer.setSize( window.innerWidth, window.innerHeight );
    renderer.setPixelRatio((window.devicePixelRatio || 1) * 2);
    texture.appendChild( renderer.domElement );

    // set up lights
    var light = new THREE.AmbientLight( 0x404040 ); // soft white light
    scene.add( light );
    scene.fog = new THREE.Fog(0x242528, 0, 10);

    // generate plane
    var geometry = generateSimplexPlaneGeometry();
    var material = new THREE.MeshBasicMaterial( {morphTargets: true, color: 0xffffff, wireframe: true, side: THREE.DoubleSide } );
    var plane = new THREE.Mesh( geometry, material );

    var morphGeometry = generateSimplexPlaneGeometry();
    var vertices = [];
    for(var i = 0; i < morphGeometry.vertices.length; i++) {
        vertices.push(morphGeometry.vertices[i].clone());
    }
    geometry.morphTargets.push({ name: "targetFoo", vertices: vertices });
    plane.updateMorphTargets();

    scene.add( plane );

    var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
    directionalLight.position.set( 0, 1, 0 );
    scene.add( directionalLight );

    plane.scale.x = 6.0;
    plane.scale.z = 6.0;
    plane.scale.multiplyScalar(2);

    camera.position.z = 7;
    camera.position.y = 2;

    var step = 0.001;

    var running = true;
    window.onscroll = function() {
        if(running) {
            running = false;
        } else if(document.documentElement.scrollTop === 0) {
            running = true;
            render();
        }
    };

    render();

    function generateSimplexPlaneGeometry() {
        var width = 64;
        var height = 64;
        var geometry = new THREE.PlaneGeometry( 1, 1, width-1, height-1 );
        geometry.lookAt( new THREE.Vector3(0, 1, 0) );

        var simplex = new SimplexNoise();
        for( var i = 0; i < width; i++) {
            for( var j = 0; j < height; j++) {

                // generate noise
                var n = 0;
                var level = 3;
                n += (simplex.noise(i/level, j/level)/2 + 0.5) * 0.125;
                level *= 3;
                n += (simplex.noise(i/level, j/level)/2 + 0.5) * 0.25;
                level *= 2;
                n += (simplex.noise(i/level, j/level)/2 + 0.5) * 0.5;
                level *= 2;
                n += simplex.noise(i/level, j/level)/2 + 0.5;
                n /= 1+0.5+0.25+0.125;

                var v = geometry.vertices[i * width + j];
                v.y = n;
            }
        }
        return geometry;
    }

    function render() {
        // on mobile, stop animation at scroll e resume it when at top of page
        if(running) {
            requestAnimationFrame( render );
        }

        var current = plane.morphTargetInfluences[0];

        if (current > 1.0) {
            step = -0.001;
        } else if (current <= 0.0) {
            step = 0.001;
        }

        plane.morphTargetInfluences[0] += step;

        renderer.render(scene, camera);
    }

    function onOrientationChange() {
        setTimeout(onWindowResize, 200);
    }

    function onWindowResize() {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize( window.innerWidth, window.innerHeight );
        requestAnimationFrame( render );
    }
})();
<commit_msg>fix a bug where plane animation does not work properly on Chrome<commit_after>(function () {
    'use strict';

    var texture = document.querySelector('.js-texture');

    if (!texture) {
        return;
    }

    var scene = new THREE.Scene();
    var camera = new THREE.PerspectiveCamera( 45, window.innerWidth/window.innerHeight, 0.1, 1000 );

    window.addEventListener( 'orientationchange', onOrientationChange, false );

    var renderer = new THREE.WebGLRenderer({
        alpha : true
    });
    renderer.setSize( window.innerWidth, window.innerHeight );
    renderer.setPixelRatio((window.devicePixelRatio || 1) * 2);
    texture.appendChild( renderer.domElement );

    // set up lights
    var light = new THREE.AmbientLight( 0x404040 ); // soft white light
    scene.add( light );
    scene.fog = new THREE.Fog(0x242528, 0, 10);

    // generate plane
    var geometry = generateSimplexPlaneGeometry();
    var material = new THREE.MeshBasicMaterial( {morphTargets: true, color: 0xffffff, wireframe: true, side: THREE.DoubleSide } );
    var plane = new THREE.Mesh( geometry, material );

    var morphGeometry = generateSimplexPlaneGeometry();
    var vertices = [];
    for(var i = 0; i < morphGeometry.vertices.length; i++) {
        vertices.push(morphGeometry.vertices[i].clone());
    }
    geometry.morphTargets.push({ name: "targetFoo", vertices: vertices });
    plane.updateMorphTargets();

    scene.add( plane );

    var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
    directionalLight.position.set( 0, 1, 0 );
    scene.add( directionalLight );

    plane.scale.x = 6.0;
    plane.scale.z = 6.0;
    plane.scale.multiplyScalar(2);

    camera.position.z = 7;
    camera.position.y = 2;

    var step = 0.001;

    var running = true;
    window.addEventListener('scroll', function() {
        if(running) {
            running = false;
        } else if(window.scrollY === 0) {
            running = true;
            render();
        }
    });

    render();

    function generateSimplexPlaneGeometry() {
        var width = 64;
        var height = 64;
        var geometry = new THREE.PlaneGeometry( 1, 1, width-1, height-1 );
        geometry.lookAt( new THREE.Vector3(0, 1, 0) );

        var simplex = new SimplexNoise();
        for( var i = 0; i < width; i++) {
            for( var j = 0; j < height; j++) {

                // generate noise
                var n = 0;
                var level = 3;
                n += (simplex.noise(i/level, j/level)/2 + 0.5) * 0.125;
                level *= 3;
                n += (simplex.noise(i/level, j/level)/2 + 0.5) * 0.25;
                level *= 2;
                n += (simplex.noise(i/level, j/level)/2 + 0.5) * 0.5;
                level *= 2;
                n += simplex.noise(i/level, j/level)/2 + 0.5;
                n /= 1+0.5+0.25+0.125;

                var v = geometry.vertices[i * width + j];
                v.y = n;
            }
        }
        return geometry;
    }

    function render() {
        // on mobile, stop animation at scroll e resume it when at top of page
        if(running) {
            requestAnimationFrame( render );
        }

        var current = plane.morphTargetInfluences[0];

        if (current > 1.0) {
            step = -0.001;
        } else if (current <= 0.0) {
            step = 0.001;
        }

        plane.morphTargetInfluences[0] += step;

        renderer.render(scene, camera);
    }

    function onOrientationChange() {
        setTimeout(onWindowResize, 200);
    }

    function onWindowResize() {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize( window.innerWidth, window.innerHeight );
        requestAnimationFrame( render );
    }
})();
<|endoftext|>


<commit_before>/*global ProjectKindsModel, ares, enyo, ComponentsRegistry */

enyo.kind({
	name: "Designer",
	published: {
		designerFrameReady: false,
		height: null,
		width: null
	},
	events: {
		onSelect: "",
		onSelected: "",
		onCreateItem: "",
		onMoveItem: "",
		onSyncDropTargetHighlighting: "",
		onReloadComplete: "",
		onResizeItem: "",
		onError: "",
		onReturnPositionValue: ""
	},
	components: [
		{name: "client", tag: "iframe", classes: "ares-designer-frame-client"},
		{name: "communicator", kind: "RPCCommunicator", onMessage: "receiveMessage"}
	],
	baseSource: "designerFrame.html",
	projectSource: null,
	selection: null,
	reloadNeeded: false,
	scale: 1,
	reloading: false,
	debug: false,
	create: function() {
		ares.setupTraceLogger(this);
		this.inherited(arguments);
	},
	rendered: function() {
		this.inherited(arguments);
		this.$.communicator.setRemote(this.$.client.hasNode().contentWindow);
	},
	heightChanged: function() {
		this.$.client.applyStyle("height", this.getHeight()+"px");
		this.resizeClient();
		this.repositionClient();
	},
	widthChanged: function() {
		this.$.client.applyStyle("width", this.getWidth()+"px");
		this.resizeClient();
		this.repositionClient();
	},
	zoom: function(inScale) {
		this.scale = (inScale >= 0) ? Math.max(inScale / 100, 0.2) : 1;
		enyo.dom.transformValue(this.$.client, "scale", this.scale);
		this.$.client.resized();
		this.repositionClient();
	},
	repositionClient: function() {
		var height = this.getHeight(),
			width = this.getWidth(),
			scaledHeight = height * this.scale,
			scaledWidth =  width  * this.scale,
			y = -1*(height - scaledHeight)/2,
			x = -1*(width  - scaledWidth)/2;

		this.$.client.addStyles("top: " + y + "px; left: " + x + "px");
	},

	// inSource is a backbone Ares.Model.Project defined in WorkspaceData.js
	updateSource: function(inSource,next) {
		if (this.updateSourceCallback) {
			throw new Error("updateSource called while previous "
							+ "updateSourceCallback is still pending ");
		}
		var serviceConfig = inSource.getService().config;
		this.setDesignerFrameReady(false);
		this.projectSource = inSource;
		this.projectPath = serviceConfig.origin + serviceConfig.pathname + "/file";
		var iframeUrl = this.projectSource.getProjectUrl() + "/" + this.baseSource + "?overlay=designer";
		this.trace("Setting designerFrame url: ", iframeUrl);
		this.$.client.hasNode().src = iframeUrl;
		// next callback is run once a "ready" message is received from designerFrame
		this.updateSourceCallback = next;
	},
	reload: function() {
		this.reloading = true;
		this.updateSource(this.projectSource);
	},

	//* Send message via communicator
	sendMessage: function(inMessage) {
		this.trace("Op: ", inMessage.op, inMessage);
		this.$.communicator.sendMessage(inMessage);
	},
	//* Respond to message from communicator
	receiveMessage: function(inSender, inEvent) {

		var msg = inEvent.message;
		var deimos = this.owner;

		this.trace("Op: ", msg.op, msg);

		if(!msg || !msg.op) {
			enyo.warn("Deimos designer received invalid message data:", msg);
			return;
		}

		// designerFrame is initialized and ready to do work.
		if(msg.op === "state" && msg.val === "initialized") {
			this.sendDesignerFrameContainerData();
		// designerFrame received container data
		} else if(msg.op === "state" && msg.val === "ready") {
			this.setDesignerFrameReady(true);
			if(this.reloading) {
				this.doReloadComplete();
				this.reloading = false;
			}
			// call back *once* the function passed to updateSource
			if (this.updateSourceCallback) {
				this.trace("calling updateSourceCallback");
				this.updateSourceCallback();
				this.updateSourceCallback = null;
			}
		// Loaded event sent from designerFrame and awaiting aresOptions.
		} else if(msg.op === "state" && msg.val === "loaded") {
			this.designerFrameLoaded();
		// The current kind was successfully rendered in the iframe
		} else if(msg.op === "rendered") {
			this.updateKind(msg);
		// Select event sent from here was completed successfully. Set _this.selection_.
		} else if(msg.op === "selected") {
			this.selection = enyo.json.codify.from(msg.val);
			this.doSelected({component: this.selection});
		// New select event triggered in designerFrame. Set _this.selection_ and bubble.
		} else if(msg.op === "select") {
			this.selection = enyo.json.codify.from(msg.val);
			this.doSelect({component: this.selection});
		// Highlight drop target to minic what's happening in designerFrame
		} else if(msg.op === "syncDropTargetHighlighting") {
			this.doSyncDropTargetHighlighting({component: enyo.json.codify.from(msg.val)});
		// New component dropped in designerFrame
		} else if(msg.op === "createItem") {
			this.doCreateItem(msg.val);
		// Existing component dropped in designerFrame
		} else if(msg.op === "moveItem") {
			this.doMoveItem(msg.val);
		} else if (msg.op === "reloadNeeded") {
			this.reloadNeeded = true;
		} else if(msg.op === "error") {
			if (( ! msg.val.hasOwnProperty('popup')) || msg.val.popup === true) {
				if ( msg.val.triggeredByOp === 'render' && this.renderCallback ) {
					this.log("dropping renderCallback after error ", msg.val.msg);
					this.renderCallback = null;
				}
				if (msg.val.requestReload === true) {
					msg.val.callback = deimos.closeDesigner.bind(deimos);
					msg.val.action = "Switching back to code editor";
				}
				this.doError(msg.val);
			} else {
				// TODO: We should store the error into a kind of rotating error log - ENYO-2462
			}
		// Existing component resized
		} else if(msg.op === "resize") {
			this.doResizeItem(msg.val);
		// Returning requested position value
		} else if(msg.op === "returnPositionValue") {
			this.doReturnPositionValue(msg.val);
		// Default case
		} else {
			enyo.warn("Deimos designer received unknown message op:", msg);
		}
	},
	//* Pass _isContainer_ info down to designerFrame
	sendDesignerFrameContainerData: function() {
		this.sendMessage({op: "containerData", val: ProjectKindsModel.getFlattenedContainerInfo()});
	},

	//* Tell designerFrame to render the current kind
	renderKind: function(fileName, theKind, inSelectId,next) {
		this.trace("reloadNeeded", this.reloadNeeded);
		if (this.reloadNeeded) {
			this.reloadNeeded = false;
			// trigger a complete reload of designerFrame
			this.reload();
			return;
		}

		if(!this.getDesignerFrameReady()) {
			// frame is still being reloaded.
			return;
		}

		if (this.renderCallback) {
			// a rendering is on-going
			return;
		}
		this.currentFileName = fileName;
		this.renderCallback = next ;

		var components = [theKind];
		// FIXME: ENYO-3181: synchronize rendering for the right rendered file
		this.sendMessage({
			op: "render",
			filename: fileName,
			val: {
				name: theKind.name,
				components: enyo.json.codify.to(theKind.components),
				componentKinds: enyo.json.codify.to(components),
				selectId: inSelectId
			}
		});
	},
	select: function(inControl) {
		this.sendMessage({op: "select", val: inControl});
	},
	highlightDropTarget: function(inControl) {
		this.sendMessage({op: "highlight", val: inControl});
	},
	unHighlightDropTargets: function() {
		this.sendMessage({op: "unhighlight"});
	},
	//* Property was modified in Inspector, update designerFrame.
	modifyProperty: function(inProperty, inValue) {
		// FIXME: ENYO-3181: synchronize rendering for the right rendered file
		this.sendMessage({op: "modify", filename: this.currentFileName, val: {property: inProperty, value: inValue}});
	},
	//* Send message to Deimos with new kind/components from designerFrame
	updateKind: function(msg) {
		var deimos = ComponentsRegistry.getComponent("deimos");

		// need to check if the rendered was done for the current file
		if (msg.filename === this.currentFileName) {
			deimos.buildComponentView(msg);
			deimos.updateCodeInEditor(msg.filename); // based on new Component view

			// updateKind may be called by other op than 'render'
			if (this.renderCallback && msg.triggeredByOp === 'render') {
				this.renderCallback() ;
				this.renderCallback = null;
			}
		}
		else {
			this.log("dropped rendered message for stale file ",msg.filename);
			if (this.renderCallback && msg.triggeredByOp === 'render') {
				// other cleanup may be needed...
				this.renderCallback = null;
			}
		}
	},
	//* Initialize the designerFrame depending on aresOptions
	designerFrameLoaded: function() {
		// FIXME: ENYO-3433 : options are hard-coded with
		// defaultKindOptions that are currently known. the whole/real
		// set must be determined indeed.
		this.sendMessage({op: "initializeOptions", options: ProjectKindsModel.get("defaultKindOptions")});
	},
	//* Clean up the designerFrame before closing designer
	cleanUp: function() {
		this.sendMessage({op: "cleanUp"});
	},
	//* Pass inCode down to the designerFrame (to avoid needing to reload the iFrame)
	syncFile: function(projectName, filename, inCode) {
		// check if the file is indeed part of the current project
		if (projectName === this.projectSource.getName() ){
			if(filename.slice(-4) === ".css") {
				//* Sync the CSS in inCode with the designerFrame (to avoid needing to reload the iFrame)
				this.sendMessage({op: "cssUpdate", val: {filename: this.projectPath + filename, code: inCode}});
			} else if(filename.slice(-3) === ".js") {
				this.sendMessage({op: "codeUpdate", val: inCode});
			}
		}
		else {
			this.warn("syncFile aborted: project mismatch. Expected " + this.projectSource.getName()
					  + ' got '+ projectName + ' with file ' + filename);
		}
	},

	resizeClient: function() {
		this.sendMessage({op: "resize"});
	},
	//* Prerender simulated drop in designerFrame
	prerenderDrop: function(inTargetId, inBeforeId) {
		this.sendMessage({op: "prerenderDrop", val: {targetId: inTargetId, beforeId: inBeforeId}});
	},
	//* Request auto-generated position value from designerFrame
	requestPositionValue: function(inProp) {
		this.sendMessage({op: "requestPositionValue", val: inProp});
	},
	sendSerializerOptions: function(serializerOptions) {
		this.sendMessage({op: "serializerOptions", val: serializerOptions});
	},
	sendDragType: function(type) {
		this.sendMessage({op: "dragStart", val: type});
	}
});
<commit_msg>ENYO-3082: added a FIFO queue for update source requests...<commit_after>/*global ProjectKindsModel, ares, enyo, ComponentsRegistry */

enyo.kind({
	name: "Designer",
	published: {
		designerFrameReady: false,
		height: null,
		width: null
	},
	events: {
		onSelect: "",
		onSelected: "",
		onCreateItem: "",
		onMoveItem: "",
		onSyncDropTargetHighlighting: "",
		onReloadComplete: "",
		onResizeItem: "",
		onError: "",
		onReturnPositionValue: ""
	},
	components: [
		{name: "client", tag: "iframe", classes: "ares-designer-frame-client"},
		{name: "communicator", kind: "RPCCommunicator", onMessage: "receiveMessage"}
	],
	baseSource: "designerFrame.html",
	projectSource: null,
	selection: null,
	reloadNeeded: false,
	scale: 1,
	reloading: false,
	debug: false,
	create: function() {
		ares.setupTraceLogger(this);
		this.inherited(arguments);
	},
	rendered: function() {
		this.inherited(arguments);
		this.$.communicator.setRemote(this.$.client.hasNode().contentWindow);
	},
	heightChanged: function() {
		this.$.client.applyStyle("height", this.getHeight()+"px");
		this.resizeClient();
		this.repositionClient();
	},
	widthChanged: function() {
		this.$.client.applyStyle("width", this.getWidth()+"px");
		this.resizeClient();
		this.repositionClient();
	},
	zoom: function(inScale) {
		this.scale = (inScale >= 0) ? Math.max(inScale / 100, 0.2) : 1;
		enyo.dom.transformValue(this.$.client, "scale", this.scale);
		this.$.client.resized();
		this.repositionClient();
	},
	repositionClient: function() {
		var height = this.getHeight(),
			width = this.getWidth(),
			scaledHeight = height * this.scale,
			scaledWidth =  width  * this.scale,
			y = -1*(height - scaledHeight)/2,
			x = -1*(width  - scaledWidth)/2;

		this.$.client.addStyles("top: " + y + "px; left: " + x + "px");
	},

	// inSource is a backbone Ares.Model.Project defined in WorkspaceData.js
	updateSourcePending: [],
	updateSource: function(inSource,next) {
		if (this.updateSourceCallback) {
			this.log("updateSource called while previous "
							+ "updateSourceCallback is still pending ");
			this.updateSourcePending.push([inSource,next]);
			return ;
		}
		var serviceConfig = inSource.getService().config;
		this.setDesignerFrameReady(false);
		this.projectSource = inSource;
		this.projectPath = serviceConfig.origin + serviceConfig.pathname + "/file";
		var iframeUrl = this.projectSource.getProjectUrl() + "/" + this.baseSource + "?overlay=designer";
		this.trace("Setting designerFrame url: ", iframeUrl);
		this.$.client.hasNode().src = iframeUrl;
		// next callback is run once a "ready" message is received from designerFrame
		this.updateSourceCallback = next;
	},
	reload: function() {
		this.reloading = true;
		this.updateSource(this.projectSource);
	},

	//* Send message via communicator
	sendMessage: function(inMessage) {
		this.trace("Op: ", inMessage.op, inMessage);
		this.$.communicator.sendMessage(inMessage);
	},
	//* Respond to message from communicator
	receiveMessage: function(inSender, inEvent) {

		var msg = inEvent.message;
		var deimos = this.owner;
		var cbData;

		this.trace("Op: ", msg.op, msg);

		if(!msg || !msg.op) {
			enyo.warn("Deimos designer received invalid message data:", msg);
			return;
		}

		// designerFrame is initialized and ready to do work.
		if(msg.op === "state" && msg.val === "initialized") {
			this.sendDesignerFrameContainerData();
		// designerFrame received container data
		} else if(msg.op === "state" && msg.val === "ready") {
			this.setDesignerFrameReady(true);
			if(this.reloading) {
				this.doReloadComplete();
				this.reloading = false;
			}
			// call back *once* the function passed to updateSource
			if (this.updateSourceCallback) {
				this.trace("calling updateSourceCallback");
				this.updateSourceCallback();
				this.updateSourceCallback = null;
				// FIXME a real state machine is needd here
				if (this.updateSourcePending.length) {
					this.log("resuming delayed update source");
					cbData = this.updateSourcePending.shift() ;
					this.updateSource(cbData[0], cbData[1]);
				}
			}
		// Loaded event sent from designerFrame and awaiting aresOptions.
		} else if(msg.op === "state" && msg.val === "loaded") {
			this.designerFrameLoaded();
		// The current kind was successfully rendered in the iframe
		} else if(msg.op === "rendered") {
			this.updateKind(msg);
		// Select event sent from here was completed successfully. Set _this.selection_.
		} else if(msg.op === "selected") {
			this.selection = enyo.json.codify.from(msg.val);
			this.doSelected({component: this.selection});
		// New select event triggered in designerFrame. Set _this.selection_ and bubble.
		} else if(msg.op === "select") {
			this.selection = enyo.json.codify.from(msg.val);
			this.doSelect({component: this.selection});
		// Highlight drop target to minic what's happening in designerFrame
		} else if(msg.op === "syncDropTargetHighlighting") {
			this.doSyncDropTargetHighlighting({component: enyo.json.codify.from(msg.val)});
		// New component dropped in designerFrame
		} else if(msg.op === "createItem") {
			this.doCreateItem(msg.val);
		// Existing component dropped in designerFrame
		} else if(msg.op === "moveItem") {
			this.doMoveItem(msg.val);
		} else if (msg.op === "reloadNeeded") {
			this.reloadNeeded = true;
		} else if(msg.op === "error") {
			if (( ! msg.val.hasOwnProperty('popup')) || msg.val.popup === true) {
				if ( msg.val.triggeredByOp === 'render' && this.renderCallback ) {
					this.log("dropping renderCallback after error ", msg.val.msg);
					this.renderCallback = null;
				}
				if (msg.val.requestReload === true) {
					msg.val.callback = deimos.closeDesigner.bind(deimos);
					msg.val.action = "Switching back to code editor";
				}
				this.doError(msg.val);
			} else {
				// TODO: We should store the error into a kind of rotating error log - ENYO-2462
			}
		// Existing component resized
		} else if(msg.op === "resize") {
			this.doResizeItem(msg.val);
		// Returning requested position value
		} else if(msg.op === "returnPositionValue") {
			this.doReturnPositionValue(msg.val);
		// Default case
		} else {
			enyo.warn("Deimos designer received unknown message op:", msg);
		}
	},
	//* Pass _isContainer_ info down to designerFrame
	sendDesignerFrameContainerData: function() {
		this.sendMessage({op: "containerData", val: ProjectKindsModel.getFlattenedContainerInfo()});
	},

	//* Tell designerFrame to render the current kind
	renderKind: function(fileName, theKind, inSelectId,next) {
		this.trace("reloadNeeded", this.reloadNeeded);
		if (this.reloadNeeded) {
			this.reloadNeeded = false;
			// trigger a complete reload of designerFrame
			this.reload();
			return;
		}

		if(!this.getDesignerFrameReady()) {
			// frame is still being reloaded.
			return;
		}

		if (this.renderCallback) {
			// a rendering is on-going
			return;
		}
		this.currentFileName = fileName;
		this.renderCallback = next ;

		var components = [theKind];
		// FIXME: ENYO-3181: synchronize rendering for the right rendered file
		this.sendMessage({
			op: "render",
			filename: fileName,
			val: {
				name: theKind.name,
				components: enyo.json.codify.to(theKind.components),
				componentKinds: enyo.json.codify.to(components),
				selectId: inSelectId
			}
		});
	},
	select: function(inControl) {
		this.sendMessage({op: "select", val: inControl});
	},
	highlightDropTarget: function(inControl) {
		this.sendMessage({op: "highlight", val: inControl});
	},
	unHighlightDropTargets: function() {
		this.sendMessage({op: "unhighlight"});
	},
	//* Property was modified in Inspector, update designerFrame.
	modifyProperty: function(inProperty, inValue) {
		// FIXME: ENYO-3181: synchronize rendering for the right rendered file
		this.sendMessage({op: "modify", filename: this.currentFileName, val: {property: inProperty, value: inValue}});
	},
	//* Send message to Deimos with new kind/components from designerFrame
	updateKind: function(msg) {
		var deimos = ComponentsRegistry.getComponent("deimos");

		// need to check if the rendered was done for the current file
		if (msg.filename === this.currentFileName) {
			deimos.buildComponentView(msg);
			deimos.updateCodeInEditor(msg.filename); // based on new Component view

			// updateKind may be called by other op than 'render'
			if (this.renderCallback && msg.triggeredByOp === 'render') {
				this.renderCallback() ;
				this.renderCallback = null;
			}
		}
		else {
			this.log("dropped rendered message for stale file ",msg.filename);
			if (this.renderCallback && msg.triggeredByOp === 'render') {
				// other cleanup may be needed...
				this.renderCallback = null;
			}
		}
	},
	//* Initialize the designerFrame depending on aresOptions
	designerFrameLoaded: function() {
		// FIXME: ENYO-3433 : options are hard-coded with
		// defaultKindOptions that are currently known. the whole/real
		// set must be determined indeed.
		this.sendMessage({op: "initializeOptions", options: ProjectKindsModel.get("defaultKindOptions")});
	},
	//* Clean up the designerFrame before closing designer
	cleanUp: function() {
		this.sendMessage({op: "cleanUp"});
	},
	//* Pass inCode down to the designerFrame (to avoid needing to reload the iFrame)
	syncFile: function(projectName, filename, inCode) {
		// check if the file is indeed part of the current project
		if (projectName === this.projectSource.getName() ){
			if(filename.slice(-4) === ".css") {
				//* Sync the CSS in inCode with the designerFrame (to avoid needing to reload the iFrame)
				this.sendMessage({op: "cssUpdate", val: {filename: this.projectPath + filename, code: inCode}});
			} else if(filename.slice(-3) === ".js") {
				this.sendMessage({op: "codeUpdate", val: inCode});
			}
		}
		else {
			this.warn("syncFile aborted: project mismatch. Expected " + this.projectSource.getName()
					  + ' got '+ projectName + ' with file ' + filename);
		}
	},

	resizeClient: function() {
		this.sendMessage({op: "resize"});
	},
	//* Prerender simulated drop in designerFrame
	prerenderDrop: function(inTargetId, inBeforeId) {
		this.sendMessage({op: "prerenderDrop", val: {targetId: inTargetId, beforeId: inBeforeId}});
	},
	//* Request auto-generated position value from designerFrame
	requestPositionValue: function(inProp) {
		this.sendMessage({op: "requestPositionValue", val: inProp});
	},
	sendSerializerOptions: function(serializerOptions) {
		this.sendMessage({op: "serializerOptions", val: serializerOptions});
	},
	sendDragType: function(type) {
		this.sendMessage({op: "dragStart", val: type});
	}
});
<|endoftext|>


<commit_before>function SynthCtrl($scope, $timeout) {

    $scope.running = false;
    $scope.frequency = 50;
    $scope.detune = 0.5;
    $scope.type = "sawtooth";
    $scope.amountOfoscillators = 3;
    $scope.oscillators = [];
    $scope.gain = -0.7;
    $scope.speak = "Push me. and then just touch me. Till I can get my. Satisfaction.";
    $scope.speechSynth = new SpeechSynthesisUtterance($scope.speak);
    $scope.tempo = 160;
    $scope.stepper = 0;

    $scope.start = function() {
        $scope.oscillators.forEach(function(osc){
            osc.start();
            $scope.gain = -0.7;
            $scope.changeGain();
        })
        $scope.running = true;
    };
    $scope.stop = function() {
        $scope.gain = -0.7;
        $scope.changeGain();
    };

    $scope.changeFreq = function () {
        $scope.oscillators.forEach(function(osc, index){
            osc.frequency.value = $scope.frequency - ($scope.detune * index);
        })
    }

    $scope.changeNote = function (freq) {
        $scope.frequency = freq;
        $scope.oscillators.forEach(function(osc, index){
            osc.frequency.value = freq - ($scope.detune * index);
        })
    }

    $scope.changeType = function (type) {
        $scope.type = type;
        $scope.oscillators.forEach(function(osc, index){
            $scope.oscillators[index].type = type;
        })

        $scope.oscillators[osc].type = type;
    }

    // that's the prefixing sorted.
    window.AudioContext = window.AudioContext || window.webkitAudioContext;
    var synth = new AudioContext();
    for (var i = 0; i < $scope.amountOfoscillators; i++) {
        $scope.oscillators[i] = synth.createOscillator();
        $scope.oscillators[i].frequency.value = $scope.frequency - ($scope.detune * i);
        $scope.oscillators[i].type = "sawtooth";
        $scope.oscillators[i].connect(synth.destination);
    }

    // Gain
    var gainNode = synth.createGainNode();
    for (var i = 0; i < $scope.amountOfoscillators; i++) {
        $scope.oscillators[i].connect(gainNode);
    }
    gainNode.connect(synth.destination);

    $scope.changeGain = function () {
        gainNode.gain.value = $scope.gain;
    }

    // Speech
    $scope.talk = function () {
        $scope.speechSynth.text = $scope.speak;
        speechSynthesis.speak($scope.speechSynth);
    }

    // sequencer

    $scope.run = false;
    $scope.sequence = [
        {step: 1, freq: 262},
        {step: 2, freq: 294},
        {step: 3, freq: 262},
        {step: 4, freq: 294},

        {step: 5, freq: 330},
        {step: 6, freq: 349},
        {step: 7, freq: 330},
        {step: 8, freq: 349},

        {step: 9, freq: 392},
        {step: 10, freq: 440},
        {step: 11, freq: 392},
        {step: 12, freq: 349},

        {step: 13, freq: 330},
        {step: 14, freq: 330},
        {step: 15, freq: 330},
        {step: 16, freq: 330}
    ]

    $scope.nextStep = function (step) {
        if ($scope.stepper >= $scope.sequence.length) {
            $scope.stepper = 0;
            step = 0;
        }
        $scope.frequency = $scope.sequence[step].freq;
        $scope.changeFreq();

        if($scope.run === true){
            $scope.stepper++;

            window.setTimeout(function() {
                $scope.nextStep($scope.stepper);
            },  (60000  / $scope.tempo) );
        }
    }

    $scope.play = function () {
        $scope.run = true;
        $timeout($scope.nextStep(0));
    }

    // console.log($scope);
}
<commit_msg>added gyro<commit_after>function SynthCtrl($scope, $timeout) {

    $scope.running = false;
    $scope.frequency = 50;
    $scope.detune = 0.5;
    $scope.type = "sawtooth";
    $scope.amountOfoscillators = 3;
    $scope.oscillators = [];
    $scope.gain = -0.7;
    $scope.speak = "Push me. and then just touch me. Till I can get my. Satisfaction.";
    $scope.speechSynth = new SpeechSynthesisUtterance($scope.speak);
    $scope.tempo = 160;
    $scope.stepper = 0;

    $scope.start = function() {
        $scope.oscillators.forEach(function(osc){
            osc.start();
            $scope.gain = -0.7;
            $scope.changeGain();
        })
        $scope.running = true;
    };
    $scope.stop = function() {
        $scope.gain = -0.7;
        $scope.changeGain();
    };

    $scope.changeFreq = function () {
        $scope.oscillators.forEach(function(osc, index){
            osc.frequency.value = $scope.frequency - ($scope.detune * index);
        })
    }

    $scope.changeNote = function (freq) {
        $scope.frequency = freq;
        $scope.oscillators.forEach(function(osc, index){
            osc.frequency.value = freq - ($scope.detune * index);
        })
    }

    $scope.changeType = function (type) {
        $scope.type = type;
        $scope.oscillators.forEach(function(osc, index){
            $scope.oscillators[index].type = type;
        })

        $scope.oscillators[osc].type = type;
    }

    // that's the prefixing sorted.
    window.AudioContext = window.AudioContext || window.webkitAudioContext;
    var synth = new AudioContext();
    for (var i = 0; i < $scope.amountOfoscillators; i++) {
        $scope.oscillators[i] = synth.createOscillator();
        $scope.oscillators[i].frequency.value = $scope.frequency - ($scope.detune * i);
        $scope.oscillators[i].type = "sawtooth";
        $scope.oscillators[i].connect(synth.destination);
    }

    // Gain
    var gainNode = synth.createGainNode();
    for (var i = 0; i < $scope.amountOfoscillators; i++) {
        $scope.oscillators[i].connect(gainNode);
    }
    gainNode.connect(synth.destination);

    $scope.changeGain = function () {
        gainNode.gain.value = $scope.gain;
    }

    // Speech
    $scope.talk = function () {
        $scope.speechSynth.text = $scope.speak;
        speechSynthesis.speak($scope.speechSynth);
    }

    // sequencer

    $scope.run = false;
    $scope.sequence = [
        {step: 1, freq: 262},
        {step: 2, freq: 294},
        {step: 3, freq: 262},
        {step: 4, freq: 294},

        {step: 5, freq: 330},
        {step: 6, freq: 349},
        {step: 7, freq: 330},
        {step: 8, freq: 349},

        {step: 9, freq: 392},
        {step: 10, freq: 440},
        {step: 11, freq: 392},
        {step: 12, freq: 349},

        {step: 13, freq: 330},
        {step: 14, freq: 330},
        {step: 15, freq: 330},
        {step: 16, freq: 330}
    ]

    $scope.nextStep = function (step) {
        if ($scope.stepper >= $scope.sequence.length) {
            $scope.stepper = 0;
            step = 0;
        }
        $scope.frequency = $scope.sequence[step].freq;
        $scope.changeFreq();

        if($scope.run === true){
            $scope.stepper++;

            window.setTimeout(function() {
                $scope.nextStep($scope.stepper);
            },  (60000  / $scope.tempo) );
        }
    }

    $scope.play = function () {
        $scope.run = true;
        $timeout($scope.nextStep(0));
    }

// Accelerometer Data
	window.addEventListener('devicemotion', function(e) {
		var x = e.accelerationIncludingGravity.x;
		var y = e.accelerationIncludingGravity.y;
		var z = e.accelerationIncludingGravity.z;
		console.log(e);
		$scope.detune = x;
		changeFreq();
	});

// Gyroscope Data
	window.addEventListener('deviceorientation', function(e) {
		var alpha = e.alpha;
		var beta = e.beta;
		var gamma = e.gamma;
		console.log(e);
	});

    // console.log($scope);
}
<|endoftext|>