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

//  Takes two XHR Objects and creates a new object

//  The new object is based on global initially, but any setting in
//  local overrides the global value.

var MergeXHRSettings = function (global, local)
{
    var output = (global === undefined) ? XHRSettings() : Object.assign(global);

    if (local)
    {
        for (var setting in local)
        {
            if (local[setting] !== undefined)
            {
                output[setting] = local[setting];
            }
        }
    }

    return output;
};

module.exports = MergeXHRSettings;
<commit_msg>Fixed use of Object.assign (doesn't work on IE11)<commit_after>var Extend = require('../utils/object/Extend');
var XHRSettings = require('./XHRSettings');

//  Takes two XHR Objects and creates a new object

//  The new object is based on global initially, but any setting in
//  local overrides the global value.

var MergeXHRSettings = function (global, local)
{
    var output = (global === undefined) ? XHRSettings() : Extend(global);

    if (local)
    {
        for (var setting in local)
        {
            if (local[setting] !== undefined)
            {
                output[setting] = local[setting];
            }
        }
    }

    return output;
};

module.exports = MergeXHRSettings;
<|endoftext|>


<commit_before>console.log('Loading CAP event notifications');

var http = require('http');
var aws = require('aws-sdk');
// var s3 = new aws.S3({ apiVersion: '2006-03-01' });

console.log("OK GO");
/**
 * See https://nodejs.org/api/http.html#http_http_request_options_callback
 *
 * This handler accepts an event containing a GeoJson shape definition. Normally [tho not constrained so] this will
 * be a polygon or a circle. The handler will return a list of all subscriptions intersecting that alert profile.
 * Example events include
 *
 *  "polygonCoordinates": [
 *    [-109.5297,40.4554], [-109.5298,40.4556], [-109.5299,40.4556], [-109.5299,40.4554], [-109.5297,40.4554]
 *  ]
 *
 *
 *  "circleCenterRadius": [ -109.5288, 40.4555, 1000]
 *
 */
exports.handler = function(event, context) {

    // console.log("Event %o",event);
    console.log("Get xml2js 2");
    var xml2js = require('xml2js');

    var parseString = xml2js.parseString;
    var stripPrefix = null;

    try {
      var prefixMatch = new RegExp(/(?!xmlns)^.*:/);

      stripPrefix = function(str) {
        return str.replace(prefixMatch, '');
      };

    }
    catch ( err ) {
      console.log("Problem loading xml2js parse string %o",err);
    }

    var shape = null;
    var send_sns = 0;
    var alerts = [];
    var num_alerts = 1;
    var lambda_response = 'OK';
    var ctr = 0;

    if ( event.Records ) {
      console.log("Handle sns");
      num_alerts = event.Records.length;

      for (var i = 0; i < num_alerts; i++) {
        // console.log("Pushing %o",event.Records[i].Sns.Message);
        var json_payload = JSON.parse(event.Records[i].Sns.Message);
        console.log("Parsed json payload");

        // try {
          parseString(json_payload.alert.capXml, {tagNameProcessors:[stripPrefix]}, function(err, result) {

            if ( err ) {
              console.log("Parsed XML payload err:%o",err);
            }

            if ( result ) {
              console.log("Got alert : result",result);
              alerts.push({orig:json_payload.alert,json:result});
            }

          });
        // }
        // catch(err) {
        //   console.log("Problem parsing capXML %o",err);
        // }
      }
      send_sns = 1;
    }
    else {
      console.log("Handle direct");
      // Direct event from http interface or test
      parseString(event.alert.capXML, function(err, result) {
        alerts.push(result);
      });
    }

    var sns = send_sns ? new aws.SNS({region:'eu-west-1'}) : null;

    for (var i = 0; i < alerts.length; i++) {

      var source_alert = alerts[i].orig;
      var alert = alerts[i].json;
      console.log("Processing -> (XML AS JSON) alert:",alert);

      var info_elements = alert['alert']['info'];
      // console.log("Processing info %o",info_elements);

      for ( var j=0; j<info_elements.length; j++ ) {
        // console.log("Process info element %o",info_elements[j]);

        var cap_area_elements = info_elements[j]['area'];
        for ( var k=0; k<info_elements.length; k++ ) {
          // console.log("Process cap area %o %o",cap_area_elements[k]['areaDesc'],cap_area_elements[k]['polygon']);
          if ( cap_area_elements[k]['polygon'] ) {

            var polygon_str = cap_area_elements[k]['polygon'][0];
            var polygon_arr = []

            // String should be a sequence of space separated pairs, themselves split by a ,
            console.log("Process polygon_str",polygon_str);

            // Parse polygon into array of points consisting of lng lat comma separated
            var points_arr = polygon_str.split(' ');
            for ( var l = 0; l<points_arr.length; l++ ) {
              var lonlat = points_arr[l].split(',');
              // Flip the lon/lat due to geohash oddness
              polygon_arr.push([lonlat[1],lonlat[0]]);
            }

            shape = {
              "type": "polygon",
              "coordinates" : [ polygon_arr ]
            }
            // console.log("Setting up polygon shape : %o",shape);
          }
          else {
            console.log("No polygon found");
          }
        }

      }

      if ( shape ) {

        var postData = JSON.stringify({
                         "from":0,
                         "size":1000,
                         "query":{
                           "bool": {
                             "must": {
                               "match_all": {}
                             },
                             "filter": {
                                 "geo_shape": {
                                   "subshape": {
                                     "shape": shape,
                                     "relation":'intersects'
                                   }
                                 }
                               }
                             }
                           },
                           "sort":{
                             "recid":{order:'asc'}
                           }

        });

        console.log("curl -X GET 'http://se.semweb.co/es/alertssubscriptions/_search' -d '",postData,"'");

        var options = {
          hostname: 'ce.semweb.co',
          port: 80,
          json: true,
          body: postData,
          path: '/es/alertssubscriptions/_search',
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Content-Length': postData.length
          }
        };

        console.log("Create request");

        var req = http.request(options, function(res) {

            var body = '';
            console.log('Status:', res.statusCode);
            console.log('Headers:', JSON.stringify(res.headers));
            res.setEncoding('utf8');
            res.on('data', function(chunk) {
                body += chunk;
            });

            res.on('end', function() {
                console.log("Processing search response");

                // console.log('Successfully processed HTTP response');
                // If we know it's JSON, parse it
                if (res.headers['content-type'].lastIndexOf('application/json',0) === 0 ) {
                  body = JSON.parse(body);
                  var num_profiles = body.hits.hits.length;

                  // console.log("Processing %d profiles",num_profiles);
                  for (var i = 0; i < num_profiles; i++) {
                    var profile_entry = body.hits.hits[i]
                    console.log("Processing hit %d %s %s %s %s",i,profile_entry._source.name,profile_entry._source.recid,profile_entry._source.shortcode);
                    // Shape is in profile_entry._source.subshape

                    if ( send_sns ) {
                      ctr++;

                      var areaFilter = {};

                      if ( profile_entry._source.subshape.type === 'polygon' ) {
                        // Polygon
                        areaFilter.polygonCoordinates=profile_entry._source.subshape.coordinates;
                        areaFilter.circleCenterRadius="none";
                      }
                      else {
                        // circle centre radius
                        areaFilter.polygonCoordinates="none";
                        areaFilter.circleCenterRadius=profile_entry._source.subshape.coordinates;
                      }

                      var response_main = {
                        alert:source_alert,
                        subscription:{
                          subscriptionId:profile_entry._source.recid,
                          subscriptionName:profile_entry._source.name,
                          subscriptionUrl:profile_entry._source.subscriptionUrl,
                          languageOnly:profile_entry._source.languageOnly,
                          highPriorityOnly:profile_entry._source.highPriorityOnly,
                          officialOnly:profile_entry._source.officialOnly,
                          xPathFilterId:profile_entry._source.xPathFilterId,
                          xPathFilter:profile_entry._source.xPathFilter,
                          areaFilterId:profile_entry._source.areaFilterId,
                          shortcode:profile_entry._source.shortcode,
                          areaFilter:areaFilter
                        },
                      };

                      var response_json = {
                        default: JSON.stringify(response_main)
                      };

                      var response_payload = JSON.stringify(response_json);

                      try {
                        console.log("Publish profile alert message ", response_payload);

                        // Send sns for each matching sub
                        var pubResult = sns.publish({
                            Message: response_payload,
                            TopicArn: 'arn:aws:sns:eu-west-1:381798314226:alert-hub-area-match',
                            MessageStructure: 'json'
                        }, function(err, data) {

                            console.log("In sns.publish callback");

                            if (err) {
                              console.log("Problem ",err);
                              ctr--;
                              if ( ctr == 0 ) {
                                console.log("context.done");
                                context.done(null,"success");
                              }
                              else {
                                console.log("context not done ",ctr);
                              }
                            }
                            else {
                              console.log('Message sent ',data);
                              ctr--;
                              if ( ctr == 0 ) {
                                console.log("context.done");
                                context.done(null,"success");
                              }
                              else {
                                console.log("context not done ",ctr);
                              }
                            }
                        });

                        console.log("sns.publish completed cleanly");

                      }
                      catch(err) {
                        console.log("problem %o",err);
                      }
                      finally {
                        console.log("SNS Send complete ctr=",ctr);
                      }
                    }
                  }
                }
                else {
                  console.log("Unable to process response type %s",res.headers['content-type']);
                }
            });
        });

        // console.log("Sending http query %s",postData);

        req.on('error', function(e) {
          console.log("error %o",e);
          context.fail();
        });

        req.write(postData);
        // console.log("req.end");
        req.end();
        // console.log("Call completed");
      }
      else {
        // No shape to search against
        console.log("No shape to search against");
      }
    }

    console.log("Complete");

};
<commit_msg>updatesd<commit_after>console.log('Loading CAP event notifications');

var http = require('http');
var aws = require('aws-sdk');
// var s3 = new aws.S3({ apiVersion: '2006-03-01' });

console.log("OK GO");
/**
 * See https://nodejs.org/api/http.html#http_http_request_options_callback
 *
 * This handler accepts an event containing a GeoJson shape definition. Normally [tho not constrained so] this will
 * be a polygon or a circle. The handler will return a list of all subscriptions intersecting that alert profile.
 * Example events include
 *
 *  "polygonCoordinates": [
 *    [-109.5297,40.4554], [-109.5298,40.4556], [-109.5299,40.4556], [-109.5299,40.4554], [-109.5297,40.4554]
 *  ]
 *
 *
 *  "circleCenterRadius": [ -109.5288, 40.4555, 1000]
 *
 */
exports.handler = function(event, context) {

    // console.log("Event %o",event);
    console.log("Get xml2js 2");
    var xml2js = require('xml2js');

    var parseString = xml2js.parseString;
    var stripPrefix = null;

    try {
      var prefixMatch = new RegExp(/(?!xmlns)^.*:/);

      stripPrefix = function(str) {
        return str.replace(prefixMatch, '');
      };

    }
    catch ( err ) {
      console.log("Problem loading xml2js parse string %o",err);
    }

    var shape = null;
    var send_sns = 0;
    var alerts = [];
    var num_alerts = 1;
    var lambda_response = 'OK';
    var ctr = 0;

    if ( event.Records ) {
      console.log("Handle sns");
      num_alerts = event.Records.length;

      for (var i = 0; i < num_alerts; i++) {
        // console.log("Pushing %o",event.Records[i].Sns.Message);
        var json_payload = JSON.parse(event.Records[i].Sns.Message);
        console.log("Parsed json payload");

        // try {
          parseString(json_payload.alert.capXml, {tagNameProcessors:[stripPrefix]}, function(err, result) {

            if ( err ) {
              console.log("Parsed XML payload err:%o",err);
            }

            if ( result ) {
              console.log("Got alert : result",result);
              alerts.push({orig:json_payload.alert,json:result});
            }

          });
        // }
        // catch(err) {
        //   console.log("Problem parsing capXML %o",err);
        // }
      }
      send_sns = 1;
    }
    else {
      console.log("Handle direct");
      // Direct event from http interface or test
      parseString(event.alert.capXML, function(err, result) {
        alerts.push(result);
      });
    }

    var sns = send_sns ? new aws.SNS({region:'eu-west-1'}) : null;

    for (var i = 0; i < alerts.length; i++) {

      var source_alert = alerts[i].orig;
      var alert = alerts[i].json;
      console.log("Processing -> (XML AS JSON) alert:",alert);

      var info_elements = alert['alert']['info'];
      // console.log("Processing info %o",info_elements);

      for ( var j=0; j<info_elements.length; j++ ) {
        // console.log("Process info element %o",info_elements[j]);

        var cap_area_elements = info_elements[j]['area'];
        for ( var k=0; k<info_elements.length; k++ ) {
          // console.log("Process cap area %o %o",cap_area_elements[k]['areaDesc'],cap_area_elements[k]['polygon']);
          if ( cap_area_elements[k]['polygon'] ) {

            var polygon_str = cap_area_elements[k]['polygon'][0];
            var polygon_arr = []

            // String should be a sequence of space separated pairs, themselves split by a ,
            console.log("Process polygon_str",polygon_str);

            // Parse polygon into array of points consisting of lng lat comma separated
            var points_arr = polygon_str.split(' ');
            for ( var l = 0; l<points_arr.length; l++ ) {
              var lonlat = points_arr[l].split(',');
              // Flip the lon/lat due to geohash oddness
              polygon_arr.push([lonlat[1],lonlat[0]]);
            }

            shape = {
              "type": "polygon",
              "coordinates" : [ polygon_arr ]
            }
            // console.log("Setting up polygon shape : %o",shape);
          }
          else {
            console.log("No polygon found");
          }
        }

      }

      if ( shape ) {

        var postData = JSON.stringify({
                         "from":0,
                         "size":1000,
                         "query":{
                           "bool": {
                             "must": {
                               "match_all": {}
                             },
                             "filter": {
                                 "geo_shape": {
                                   "subshape": {
                                     "shape": shape,
                                     "relation":'intersects'
                                   }
                                 }
                               }
                             }
                           },
                           "sort":{
                             "recid":{order:'asc'}
                           }

        });

        console.log("curl -X GET 'http://ce.semweb.co/es/alertssubscriptions/_search' -d '",postData,"'");

        var options = {
          hostname: 'ce.semweb.co',
          port: 80,
          json: true,
          body: postData,
          path: '/es/alertssubscriptions/_search',
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
            'Content-Length': postData.length
          }
        };

        console.log("Create request");

        var req = http.request(options, function(res) {

            var body = '';
            console.log('Status:', res.statusCode);
            console.log('Headers:', JSON.stringify(res.headers));
            res.setEncoding('utf8');
            res.on('data', function(chunk) {
                body += chunk;
            });

            res.on('end', function() {
                console.log("Processing search response");

                // console.log('Successfully processed HTTP response');
                // If we know it's JSON, parse it
                if (res.headers['content-type'].lastIndexOf('application/json',0) === 0 ) {
                  body = JSON.parse(body);
                  var num_profiles = body.hits.hits.length;

                  // console.log("Processing %d profiles",num_profiles);
                  for (var i = 0; i < num_profiles; i++) {
                    var profile_entry = body.hits.hits[i]
                    console.log("Processing hit %d %s %s %s %s",i,profile_entry._source.name,profile_entry._source.recid,profile_entry._source.shortcode);
                    // Shape is in profile_entry._source.subshape

                    if ( send_sns ) {
                      ctr++;

                      var areaFilter = {};

                      if ( profile_entry._source.subshape.type === 'polygon' ) {
                        // Polygon
                        areaFilter.polygonCoordinates=profile_entry._source.subshape.coordinates;
                        areaFilter.circleCenterRadius="none";
                      }
                      else {
                        // circle centre radius
                        areaFilter.polygonCoordinates="none";
                        areaFilter.circleCenterRadius=profile_entry._source.subshape.coordinates;
                      }

                      var response_main = {
                        alert:source_alert,
                        subscription:{
                          subscriptionId:profile_entry._source.recid,
                          subscriptionName:profile_entry._source.name,
                          subscriptionUrl:profile_entry._source.subscriptionUrl,
                          languageOnly:profile_entry._source.languageOnly,
                          highPriorityOnly:profile_entry._source.highPriorityOnly,
                          officialOnly:profile_entry._source.officialOnly,
                          xPathFilterId:profile_entry._source.xPathFilterId,
                          xPathFilter:profile_entry._source.xPathFilter,
                          areaFilterId:profile_entry._source.areaFilterId,
                          shortcode:profile_entry._source.shortcode,
                          areaFilter:areaFilter
                        },
                      };

                      var response_json = {
                        default: JSON.stringify(response_main)
                      };

                      var response_payload = JSON.stringify(response_json);

                      try {
                        console.log("Publish profile alert message ", response_payload);

                        // Send sns for each matching sub
                        var pubResult = sns.publish({
                            Message: response_payload,
                            TopicArn: 'arn:aws:sns:eu-west-1:381798314226:alert-hub-area-match',
                            MessageStructure: 'json'
                        }, function(err, data) {

                            console.log("In sns.publish callback");

                            if (err) {
                              console.log("Problem ",err);
                              ctr--;
                              if ( ctr == 0 ) {
                                console.log("context.done");
                                context.done(null,"success");
                              }
                              else {
                                console.log("context not done ",ctr);
                              }
                            }
                            else {
                              console.log('Message sent ',data);
                              ctr--;
                              if ( ctr == 0 ) {
                                console.log("context.done");
                                context.done(null,"success");
                              }
                              else {
                                console.log("context not done ",ctr);
                              }
                            }
                        });

                        console.log("sns.publish completed cleanly");

                      }
                      catch(err) {
                        console.log("problem %o",err);
                      }
                      finally {
                        console.log("SNS Send complete ctr=",ctr);
                      }
                    }
                  }
                }
                else {
                  console.log("Unable to process response type %s",res.headers['content-type']);
                }
            });
        });

        // console.log("Sending http query %s",postData);

        req.on('error', function(e) {
          console.log("error %o",e);
          context.fail();
        });

        req.write(postData);
        // console.log("req.end");
        req.end();
        // console.log("Call completed");
      }
      else {
        // No shape to search against
        console.log("No shape to search against");
      }
    }

    console.log("Complete");

};
<|endoftext|>


<commit_before>/*
  nr is the prefix for this function space.

  There's probably a way to do it in YUI that's not so awful, but I only know jQuery...
*/
function ddg_spice_zanran(zanran_results) {
  /* IE6 cannot be supported due to lack of max-width / min-width without rewriting everything */
  if(YAHOO.env.ua.ie && YAHOO.env.ua.ie < 7) {
    return;
  }
  if(!zanran_results || !zanran_results.results || !zanran_results.results.length) {
    return;
  }

  var results = zanran_results.results;

  var out = "";

  for(var i=0; i<results.length; i++) {
    if(i==3) break; // 3 results max
    var div = d.createElement("div");
    YAHOO.util.Dom.addClass(div, 'highlight_zero_click1 highlight_zero_click_wrapper');
    YAHOO.util.Dom.setStyle(div, 'clear', 'both');
    YAHOO.util.Dom.setStyle(div, 'border-bottom', '1px dotted black');
    YAHOO.util.Dom.setStyle(div, 'width', '620px');

    var img_link = d.createElement("a");
    img_link.href = results[i].preview_url;
    img_link.title = results[i].title;
    var img = d.createElement('img');
    img.src = results[i].preview_image;
    img_link.appendChild(img);
    YAHOO.util.Dom.setStyle(img, 'max-width', '43px');
    YAHOO.util.Dom.setStyle(img, 'max-height', '60px'); // A4 ratio
    YAHOO.util.Dom.setStyle(img, 'border', '1px solid black');
    YAHOO.util.Dom.setStyle(img_link, 'float', 'right');
    YAHOO.util.Dom.setStyle(img_link, 'margin-left', '15px');

    div.appendChild(img_link);

    var title = results[i].title;
    if(title.length > 150){
      var words = title.split(/\s+/);
      title = "";
      while(words.length && title.length + 1 + words[0].length < 150) {
        title = title + " " + words.shift();
      }
    }

    var p1 = d.createElement('div');
    p1.appendChild(d.createTextNode(title));
    div.appendChild(p1);

    YAHOO.util.Dom.setStyle(p1, 'max-height', '38px');
    YAHOO.util.Dom.setStyle(p1, 'overflow', 'hidden');
    YAHOO.util.Dom.setStyle(p1, 'text-overflow', 'ellipsis');

    var p2 = d.createElement('div');

    var link1 = d.createElement("a");
    link1.href = results[i].final_url;
    link1.title = results[i].title;
    link1.appendChild(d.createTextNode("Link"));

    var link2 = d.createElement("a");
    link2.href = results[i].preview_url;
    link2.title = results[i].title;
    link2.appendChild(d.createTextNode("Preview"));

    p2.appendChild(link1);
    p2.appendChild(d.createTextNode(" | "));
    p2.appendChild(link2);
    p2.appendChild(d.createTextNode(" | "));

    var source = d.createElement('i');
    p2.appendChild(source);
    source.appendChild(d.createTextNode("Source: "));

    p2.appendChild(d.createTextNode(results[i].site_name));

    YAHOO.util.Dom.setStyle(p2, "overflow", "hidden");
    YAHOO.util.Dom.setStyle(p2, "white-space", "nowrap");
    YAHOO.util.Dom.setStyle(p2, "text-overflow", "ellipsis");

    div.appendChild(p2);

    var container_div = d.createElement("div");
    container_div.appendChild(div);
    out += container_div.innerHTML;
  }
  out += '

';

  items = [[]];
  items[0]['a'] = out;
  items[0]['h'] = "Data & Statistics from Zanran (" + DDG.get_query() + ")";
  items[0]['s'] = 'Zanran';
  items[0]['u'] = zanran_results.more;
  items[0]['f'] = 1;
  items[0]['force_big_header'] = 1;
  // items[0]['i'] = 'http://zanran.com/favicon.ico';

  nra(items,1,1);
};
<commit_msg>Styling tweaks<commit_after>/*
  nr is the prefix for this function space.

  There's probably a way to do it in YUI that's not so awful, but I only know jQuery...
*/
function ddg_spice_zanran(zanran_results) {
  /* IE6 cannot be supported due to lack of max-width / min-width without rewriting everything */
  if(YAHOO.env.ua.ie && YAHOO.env.ua.ie < 7) {
    return;
  }
  if(!zanran_results || !zanran_results.results || !zanran_results.results.length) {
    return;
  }

  var results = zanran_results.results;

  var out = "";

  for(var i=0; i<results.length; i++) {
    if(i==3) break; // 3 results max
    var div = d.createElement("div");
    YAHOO.util.Dom.addClass(div, 'highlight_zero_click1 highlight_zero_click_wrapper');
    YAHOO.util.Dom.setStyle(div, 'clear', 'both');
    YAHOO.util.Dom.setStyle(div, 'border-bottom', '1px dotted black');
    YAHOO.util.Dom.setStyle(div, 'width', '620px');

    var img_link = d.createElement("a");
    img_link.href = results[i].preview_url;
    img_link.title = results[i].title;
    var img = d.createElement('img');
    img.src = results[i].preview_image;
    img_link.appendChild(img);
    YAHOO.util.Dom.setStyle(img, 'max-width', '43px');
    YAHOO.util.Dom.setStyle(img, 'max-height', '60px'); // A4 ratio
    YAHOO.util.Dom.setStyle(img, 'border', '1px solid black');
    YAHOO.util.Dom.setStyle(img_link, 'float', 'right');
    YAHOO.util.Dom.setStyle(img_link, 'margin-left', '10px');

    div.appendChild(img_link);

    var title = results[i].title;
    if(title.length > 140) {
      var words = title.split(/\s+/);
      title = "";
      while(words.length && title.length + 1 + words[0].length < 140) {
        title = title + " " + words.shift();
      }
      title += "\u2026";
    }

    var p1 = d.createElement('div');
    p1.appendChild(d.createTextNode(title));
    div.appendChild(p1);

    YAHOO.util.Dom.setStyle(p1, 'max-width', '575px');

    var p2 = d.createElement('div');

    var link1 = d.createElement("a");
    link1.href = results[i].final_url;
    link1.title = results[i].title;
    link1.appendChild(d.createTextNode("Link"));

    var link2 = d.createElement("a");
    link2.href = results[i].preview_url;
    link2.title = results[i].title;
    link2.appendChild(d.createTextNode("Preview"));

    p2.appendChild(link1);
    p2.appendChild(d.createTextNode(" | "));
    p2.appendChild(link2);
    p2.appendChild(d.createTextNode(" | "));

    var source = d.createElement('i');
    p2.appendChild(source);
    source.appendChild(d.createTextNode("Source: "));

    p2.appendChild(d.createTextNode(results[i].site_name));

    YAHOO.util.Dom.setStyle(p2, "overflow", "hidden");
    YAHOO.util.Dom.setStyle(p2, "white-space", "nowrap");
    YAHOO.util.Dom.setStyle(p2, "text-overflow", "ellipsis");

    div.appendChild(p2);

    var container_div = d.createElement("div");
    container_div.appendChild(div);
    out += container_div.innerHTML;
  }
  out += '

';

  items = [[]];
  items[0]['a'] = out;
  items[0]['h'] = "Data & Statistics from Zanran (" + DDG.get_query() + ")";
  items[0]['s'] = 'Zanran';
  items[0]['u'] = zanran_results.more;
  items[0]['f'] = 1;
  items[0]['force_big_header'] = 1;
  // items[0]['i'] = 'http://zanran.com/favicon.ico';

  nra(items,1,1);
};
<|endoftext|>


<commit_before>import { updateApp } from "./update-app";

import {
    DEMO_INFORMATION
} from "./constants";

const submittedFilename = $upload => {
    let path = $upload.val();
    let fakePathCheck = path.search("\\\\") + 1;

    while (fakePathCheck) {
        path = path.substring(fakePathCheck);
        fakePathCheck = path.search("\\\\") + 1;
    }

    return path;
};

const createFileForm = $upload => {
    const formData = new FormData();
    formData.append("file", $upload[0].files[0]);
    return formData;
};

const uploadEpilogue = event => {
    if (window.ga) {
        window.ga("send", "pageview", {
            page: "/GRNsight/upload",
            sessionControl: "start"
        });
    }

    $("a.upload > input[type=file]").val("");
    event.preventDefault();
};

const uploadHandler = (uploadRoute, uploader) => {
    return function (event) { // Must be `function` due to use of `this`.
        const $upload = $(this);
        const filename = submittedFilename($upload);
        if ($upload[0].files[0].size < 100000) {
            const formData = createFileForm($upload);
            uploader(uploadRoute, filename, formData);
            uploadEpilogue(event);
        } else {
            let errorString = "The file size is too large. Please try again with a smaller file.";
            $("#error").html(errorString);
            $("#errorModal").modal("show");
        }
    };
};

const networkErrorDisplayer = xhr => {
    // Deleted status, error for argument because it was never used
    const err = JSON.parse(xhr.responseText);
    let errorString = "Your graph failed to load.

";

    if (!err.errors) { // will be falsy if an error was thrown before the network was generated
        errorString += err;
    } else {
        console.log(err.errors);
        errorString = err.errors.reduce(
            (currentErrorString, currentError) =>
                `${currentErrorString}${currentError.possibleCause} ${currentError.suggestedFix}<br><br>`,

            errorString
        );
    }

    $("#error").html(errorString);
    $("#errorModal").modal("show");
};

let reloader = () => { };

export const setupLoadAndImportHandlers = grnState => {
    const loadGrn = (url, name, formData) => {
        // The presence of formData is taken to indicate a POST.
        const fullUrl = [ $("#service-root").val(), url ].join("/");
        (formData ? $.ajax({
            url: fullUrl,
            data: formData,
            processData: false,
            contentType: false,
            type: "POST",
            crossDomain: true
        }) : $.getJSON(fullUrl)).done((network, textStatus, jqXhr) => {
            // Display the network in the console
            console.log(network);
            grnState.name = name || jqXhr.getResponseHeader("X-GRNsight-Filename");
            grnState.network = network;

            reloader = () => loadGrn(url, name, formData);

            updateApp(grnState);
            // displayStatistics(network);
        }).error(networkErrorDisplayer);
    };

    /*
     * Thanks to http://stackoverflow.com/questions/6974684/how-to-send-formdata-objects-with-ajax-requests-in-jquery
     * for helping to resolve this.
     */

    // TODO Some opportunity for unification with loadGrn?
    const importGrn = (uploadRoute, filename, formData) => {
        const fullUrl = [ $("#service-root").val(), uploadRoute ].join("/");
        $.ajax({
            url: fullUrl,
            data: formData,
            processData: false,
            contentType: false,
            type: "POST",
            crossDomain: true
        }).done(function (network) {
            grnState.name = filename;
            grnState.network = network;
            grnState.annotateLinks();

            reloader = () => importGrn(uploadRoute, filename, formData);

            updateApp(grnState);
        }).error(networkErrorDisplayer);
    };

    $("#upload").click(() =>
        $("#launchFileOpen").off("click").on("click", () => $("#upload").click())
    );
    $("#upload-sif").click(() =>
        $("#launchFileOpen").off("click").on("click", () => $("#upload-sif").click())
    );
    $("#upload-graphml").click(() =>
        $("#launchFileOpen").off("click").on("click", () => $("#upload-graphml").click())
    );

    $("#upload").on("change", uploadHandler("upload", loadGrn));
    $("#upload-sif").on("change", uploadHandler("upload-sif", importGrn));
    $("#upload-graphml").on("change", uploadHandler("upload-graphml", importGrn));

    const loadDemo = url => {
        loadGrn(url);
        reloader = () => loadGrn(url);

        $("a.upload > input[type=file]").val("");
    };

    const initializeDemoFile = (demoId, demoPath, demoName) => {
        // Deleted parameter `event`
        $(demoId).on("click", () => loadDemo(demoPath, demoName));
    };

    DEMO_INFORMATION.forEach(demoInfo => initializeDemoFile.apply(null, demoInfo));

    $("#reload").click(function () {
        // Deleted `event` parameter but need `function` because of `this`.
        if (!$(this).parent().hasClass("disabled")) {
            if ($.isFunction(reloader)) {
                reloader();
            }
        }
    });
};
<commit_msg>update message<commit_after>import { updateApp } from "./update-app";

import {
    DEMO_INFORMATION
} from "./constants";

const submittedFilename = $upload => {
    let path = $upload.val();
    let fakePathCheck = path.search("\\\\") + 1;

    while (fakePathCheck) {
        path = path.substring(fakePathCheck);
        fakePathCheck = path.search("\\\\") + 1;
    }

    return path;
};

const createFileForm = $upload => {
    const formData = new FormData();
    formData.append("file", $upload[0].files[0]);
    return formData;
};

const uploadEpilogue = event => {
    if (window.ga) {
        window.ga("send", "pageview", {
            page: "/GRNsight/upload",
            sessionControl: "start"
        });
    }

    $("a.upload > input[type=file]").val("");
    event.preventDefault();
};

const uploadHandler = (uploadRoute, uploader) => {
    return function (event) { // Must be `function` due to use of `this`.
        const $upload = $(this);
        const filename = submittedFilename($upload);
        if ($upload[0].files[0].size < 1000000) {
            const formData = createFileForm($upload);
            uploader(uploadRoute, filename, formData);
            uploadEpilogue(event);
        } else {
            let errorString = "The file uploaded is too large. Please try again with a file smaller than 1 MB.";
            $("#error").html(errorString);
            $("#errorModal").modal("show");
        }
    };
};

const networkErrorDisplayer = xhr => {
    // Deleted status, error for argument because it was never used
    const err = JSON.parse(xhr.responseText);
    let errorString = "Your graph failed to load.

";

    if (!err.errors) { // will be falsy if an error was thrown before the network was generated
        errorString += err;
    } else {
        console.log(err.errors);
        errorString = err.errors.reduce(
            (currentErrorString, currentError) =>
                `${currentErrorString}${currentError.possibleCause} ${currentError.suggestedFix}<br><br>`,

            errorString
        );
    }

    $("#error").html(errorString);
    $("#errorModal").modal("show");
};

let reloader = () => { };

export const setupLoadAndImportHandlers = grnState => {
    const loadGrn = (url, name, formData) => {
        // The presence of formData is taken to indicate a POST.
        const fullUrl = [ $("#service-root").val(), url ].join("/");
        (formData ? $.ajax({
            url: fullUrl,
            data: formData,
            processData: false,
            contentType: false,
            type: "POST",
            crossDomain: true
        }) : $.getJSON(fullUrl)).done((network, textStatus, jqXhr) => {
            // Display the network in the console
            console.log(network);
            grnState.name = name || jqXhr.getResponseHeader("X-GRNsight-Filename");
            grnState.network = network;

            reloader = () => loadGrn(url, name, formData);

            updateApp(grnState);
            // displayStatistics(network);
        }).error(networkErrorDisplayer);
    };

    /*
     * Thanks to http://stackoverflow.com/questions/6974684/how-to-send-formdata-objects-with-ajax-requests-in-jquery
     * for helping to resolve this.
     */

    // TODO Some opportunity for unification with loadGrn?
    const importGrn = (uploadRoute, filename, formData) => {
        const fullUrl = [ $("#service-root").val(), uploadRoute ].join("/");
        $.ajax({
            url: fullUrl,
            data: formData,
            processData: false,
            contentType: false,
            type: "POST",
            crossDomain: true
        }).done(function (network) {
            grnState.name = filename;
            grnState.network = network;
            grnState.annotateLinks();

            reloader = () => importGrn(uploadRoute, filename, formData);

            updateApp(grnState);
        }).error(networkErrorDisplayer);
    };

    $("#upload").click(() =>
        $("#launchFileOpen").off("click").on("click", () => $("#upload").click())
    );
    $("#upload-sif").click(() =>
        $("#launchFileOpen").off("click").on("click", () => $("#upload-sif").click())
    );
    $("#upload-graphml").click(() =>
        $("#launchFileOpen").off("click").on("click", () => $("#upload-graphml").click())
    );

    $("#upload").on("change", uploadHandler("upload", loadGrn));
    $("#upload-sif").on("change", uploadHandler("upload-sif", importGrn));
    $("#upload-graphml").on("change", uploadHandler("upload-graphml", importGrn));

    const loadDemo = url => {
        loadGrn(url);
        reloader = () => loadGrn(url);

        $("a.upload > input[type=file]").val("");
    };

    const initializeDemoFile = (demoId, demoPath, demoName) => {
        // Deleted parameter `event`
        $(demoId).on("click", () => loadDemo(demoPath, demoName));
    };

    DEMO_INFORMATION.forEach(demoInfo => initializeDemoFile.apply(null, demoInfo));

    $("#reload").click(function () {
        // Deleted `event` parameter but need `function` because of `this`.
        if (!$(this).parent().hasClass("disabled")) {
            if ($.isFunction(reloader)) {
                reloader();
            }
        }
    });
};
<|endoftext|>


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

var UInt256 = require('./uint256').UInt256;

function KeyPair() {
  this._curve  = sjcl.ecc.curves['c256'];
  this._secret = null;
  this._pubkey = null;
};

KeyPair.from_bn_secret = function (j) {
  return j instanceof this ? j.clone() : (new this()).parse_bn_secret(j);
};

KeyPair.prototype.parse_bn_secret = function (j) {
  this._secret = new sjcl.ecc.ecdsa.secretKey(sjcl.ecc.curves['c256'], j);
  return this;
};

/**
 * Returns public key as sjcl public key.
 *
 * @private
 */
KeyPair.prototype._pub = function () {
  var curve = this._curve;

  if (!this._pubkey && this._secret) {
    var exponent = this._secret._exponent;
    this._pubkey = new sjcl.ecc.ecdsa.publicKey(curve, curve.G.mult(exponent));
  }

  return this._pubkey;
};

/**
 * Returns public key as hex.
 *
 * Key will be returned as a compressed pubkey - 33 bytes converted to hex.
 */
KeyPair.prototype.to_hex_pub = function () {
  var pub = this._pub();

  if (!pub) {
    return null;
  }

  var point = pub._point, y_even = point.y.mod(2).equals(0);

  return sjcl.codec.hex.fromBits(sjcl.bitArray.concat(
    [sjcl.bitArray.partial(8, y_even ? 0x02 : 0x03)],
    point.x.toBits(this._curve.r.bitLength())
  )).toUpperCase();
};

KeyPair.prototype.sign = function (hash) {
  var hash = UInt256.from_json(hash);
  return this._secret.signDER(hash.to_bits(), 0);
};

exports.KeyPair = KeyPair;
<commit_msg>Add the ability to generate addresses from keypairs.<commit_after>var sjcl    = require('./utils').sjcl;

var UInt160 = require('./uint160').UInt160;
var UInt256 = require('./uint256').UInt256;

function KeyPair() {
  this._curve  = sjcl.ecc.curves['c256'];
  this._secret = null;
  this._pubkey = null;
};

KeyPair.from_bn_secret = function (j) {
  return j instanceof this ? j.clone() : (new this()).parse_bn_secret(j);
};

KeyPair.prototype.parse_bn_secret = function (j) {
  this._secret = new sjcl.ecc.ecdsa.secretKey(sjcl.ecc.curves['c256'], j);
  return this;
};

/**
 * Returns public key as sjcl public key.
 *
 * @private
 */
KeyPair.prototype._pub = function () {
  var curve = this._curve;

  if (!this._pubkey && this._secret) {
    var exponent = this._secret._exponent;
    this._pubkey = new sjcl.ecc.ecdsa.publicKey(curve, curve.G.mult(exponent));
  }

  return this._pubkey;
};

/**
 * Returns public key in compressed format as bit array.
 *
 * @private
 */
KeyPair.prototype._pub_bits = function () {
  var pub = this._pub();

  if (!pub) {
    return null;
  }

  var point = pub._point, y_even = point.y.mod(2).equals(0);

  return sjcl.bitArray.concat(
    [sjcl.bitArray.partial(8, y_even ? 0x02 : 0x03)],
    point.x.toBits(this._curve.r.bitLength())
  );
};

/**
 * Returns public key as hex.
 *
 * Key will be returned as a compressed pubkey - 33 bytes converted to hex.
 */
KeyPair.prototype.to_hex_pub = function () {
  var bits = this._pub_bits();

  if (!bits) {
    return null;
  }

  return sjcl.codec.hex.fromBits(bits).toUpperCase();
};

function SHA256_RIPEMD160(bits) {
  return sjcl.hash.ripemd160.hash(sjcl.hash.sha256.hash(bits));
}

KeyPair.prototype.get_address = function () {
  var bits = this._pub_bits();

  if (!bits) {
    return null;
  }

  var hash = SHA256_RIPEMD160(bits);

  return UInt160.from_bits(hash);
};

KeyPair.prototype.sign = function (hash) {
  var hash = UInt256.from_json(hash);
  return this._secret.signDER(hash.to_bits(), 0);
};

exports.KeyPair = KeyPair;
<|endoftext|>


<commit_before>/**
 * View class for Texts
 *
 * @copyright  2014-today Justso GmbH, Frankfurt, Germany
 * @author     j.schirrmacher@justso.de
 *
 * @package    Generator
 */

define([ "jquery", "backbone", "text!templates/TextEntry.html" ], function($, Backbone, template) {
    return Backbone.View.extend({
        tagName: 'li',
        className: "list-group-item",

        initialize: function() {
            this.model.on('change', this.render, this);
        },

        render: function(text) {
            this.$el.attr("id", text.cid);
            this.$el.html(_.template(template, text.attributes));
            return this.el;
        }
    });
});
<commit_msg>Precompile template<commit_after>/**
 * View class for Texts
 *
 * @copyright  2014-today Justso GmbH, Frankfurt, Germany
 * @author     j.schirrmacher@justso.de
 *
 * @package    Generator
 */

define([ "jquery", "backbone", "text!templates/TextEntry.html" ], function($, Backbone, template) {
    var compiled = _.template(template);

    return Backbone.View.extend({
        tagName: 'li',
        className: "list-group-item",

        initialize: function() {
            this.model.on('change', this.render, this);
        },

        render: function(text) {
            this.$el.attr("id", text.cid);
            this.$el.html(compiled(text.attributes));
            return this.el;
        }
    });
});
<|endoftext|>


<commit_before>'use strict';

/**
 * @ngdoc service
 * @name script2Bit.mockDataService
 * @description
 * # mockDataService
 * Service in the script2Bit.
 */
angular.module('script2Bit')
  .service('mockDataService', ['$rootScope', function ($rootScope) {

    var getHeadings = function(scenes) {
      if (!Array.isArray(scenes)) {
        console.log("Scenes shouldbe an array");
        return [];
      }
      var headings = [];
      for (var i=0; i < scenes.length; i++) {
        var scene = scenes[i];
        for (var j=0; j < scene.length; j++) {
          var element = scene[j];
          if (element.type == "heading") {
            headings.push("Scene " + (i) + ": " + element.heading);
          }
        }
      }

      return headings;
    }

    //Removes those (V.O) or (CONT'D) parts
    //from a character's name
    var removeBraces = function(character_name) {
      character_name = character_name.trim()
      var index = character_name.indexOf("(");
      if (index > 0) {
        //take it out
        character_name = character_name.substr(0, index);
      }

      return character_name;
    }

    // AngularJS will instantiate a singleton by calling "new" on this function
    return {
      getScenes: function () {
        if (typeof $rootScope.script == 'undefined') {
          console.log("No script loaded in $rootScope");
          return [];
        }
        var scenes = getHeadings($rootScope.script.script.scenes);
        return scenes;
      },

      getActorsForScene: function (sceneIndex) {
        var dialogues = getDialoguesForScene(sceneIndex);

        var actorsMap = {};
        for (var dialogueId = 0; dialogueId < dialogues.length; dialogueId++) {
          actorsMap[dialogues[dialogueId].actor] = 1;
        }

        var actors = [];
        for (var actor in actorsMap) {
          actors.push(actor);
        }

        //convert these to actors based on assignment
        return actor;
      },

      getDialoguesForScene: function (sceneIndex) {
        var scene = $rootScope.script.script.scenes[sceneIndex];
        var dialogues = [];
        for (var elementId = 0; elementId < scene.length; elementId++) {
          var element = scene[elementId];
          if ((element.type == "dialogue-single" || element.type == "dialogue-dual") &&
            typeof element.characters != 'undefined') {
            for (var characterId = 0; characterId < element.characters.length; characterId++) {
              var character = element.characters[characterId];
              if (character.type == "character") {
                var actorLine = {actor: removeBraces(character.name), content: ""};
                if (typeof character.lines != 'undefined') {
                  for (var lineId = 0; lineId < character.lines.length; lineId++) {
                    actorLine.content = actorLine.content + "\n" + character.lines[lineId].text;
                  }
                }
                dialogues.push(actorLine);
              }
            }
          }
        }

        return dialogues;

      }
    };
  }]);
<commit_msg>Deduplication successful<commit_after>'use strict';

/**
 * @ngdoc service
 * @name script2Bit.mockDataService
 * @description
 * # mockDataService
 * Service in the script2Bit.
 */
angular.module('script2Bit')
  .service('mockDataService', ['$rootScope', function ($rootScope) {

    var getHeadings = function(scenes) {
      if (!Array.isArray(scenes)) {
        console.log("Scenes shouldbe an array");
        return [];
      }
      var headings = [];
      for (var i=0; i < scenes.length; i++) {
        var scene = scenes[i];
        for (var j=0; j < scene.length; j++) {
          var element = scene[j];
          if (element.type == "heading") {
            headings.push("Scene " + (i) + ": " + element.heading);
          }
        }
      }

      return headings;
    }

    //Removes those (V.O) or (CONT'D) parts
    //from a character's name
    var removeBraces = function(character_name) {
      character_name = character_name.trim()
      var index = character_name.indexOf("(");
      if (index > 0) {
        //take it out
        character_name = character_name.substr(0, index).trim();
      }

      return character_name;
    }

    // AngularJS will instantiate a singleton by calling "new" on this function
    return {
      getScenes: function () {
        if (typeof $rootScope.script == 'undefined') {
          console.log("No script loaded in $rootScope");
          return [];
        }
        var scenes = getHeadings($rootScope.script.script.scenes);
        return scenes;
      },

      getActorsForScene: function (sceneIndex) {
        var dialogues = getDialoguesForScene(sceneIndex);

        var actorsMap = {};
        for (var dialogueId = 0; dialogueId < dialogues.length; dialogueId++) {
          actorsMap[dialogues[dialogueId].actor] = 1;
        }

        var actors = [];
        for (var actor in actorsMap) {
          actors.push(actor);
        }

        //convert these to actors based on assignment
        return actor;
      },

      getDialoguesForScene: function (sceneIndex) {
        var scene = $rootScope.script.script.scenes[sceneIndex];
        var dialogues = [];
        for (var elementId = 0; elementId < scene.length; elementId++) {
          var element = scene[elementId];
          if ((element.type == "dialogue-single" || element.type == "dialogue-dual") &&
            typeof element.characters != 'undefined') {
            for (var characterId = 0; characterId < element.characters.length; characterId++) {
              var character = element.characters[characterId];
              if (character.type == "character") {
                var actorLine = {actor: removeBraces(character.name), content: ""};
                if (typeof character.lines != 'undefined') {
                  for (var lineId = 0; lineId < character.lines.length; lineId++) {
                    actorLine.content = actorLine.content + "\n" + character.lines[lineId].text;
                  }
                }
                dialogues.push(actorLine);
              }
            }
          }
        }

        return dialogues;

      }
    };
  }]);
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Owner: felix@famo.us
 * @license MPL 2.0
 * @copyright Famous Industries, Inc. 2014
 */

define(function(require, exports, module) {
    var Entity = require('famous/core/Entity');
    var RenderNode = require('famous/core/RenderNode');
    var Transform = require('famous/core/Transform');
    var ViewSequence = require('famous/core/ViewSequence');
    var Modifier = require('famous/core/Modifier');
    var OptionsManager = require('famous/core/OptionsManager');
    var Transitionable = require('famous/transitions/Transitionable');
    var TransitionableTransform = require('famous/transitions/TransitionableTransform');

    /**
     * A layout which divides a context into several evenly-sized grid cells.
     *   If dimensions are provided, the grid is evenly subdivided with children
     *   cells representing their own context, otherwise the cellSize property is used to compute
     *   dimensions so that items of cellSize will fit.
     * @class GridLayout
     * @constructor
     * @param {Options} [options] An object of configurable options.
     * @param {Array.Number} [options.dimensions=[1, 1]] A two value array which specifies the amount of columns
     * and rows in your Gridlayout instance.
     * @param {Array.Number} [options.cellSize=[250, 250]]  A two-value array which specifies the width and height
     * of each cell in your Gridlayout instance.
     * @param {Transition} [options.transition=false] The transiton that controls the Gridlayout instance's reflow.
     */
    function GridLayout(options) {
        this.options = Object.create(GridLayout.DEFAULT_OPTIONS);
        this.optionsManager = new OptionsManager(this.options);
        if (options) this.setOptions(options);

        this.id = Entity.register(this);

        this._modifiers = [];
        this._states = [];
        this._contextSizeCache = [0, 0];
        this._dimensionsCache = [0, 0];
        this._activeCount = 0;
    }

    function _reflow(size, cols, rows) {
        if (!rows) rows = (size[1] / this.options.cellSize[1]) | 0;
        if (!cols) cols = (size[0] / this.options.cellSize[0]) | 0;
        var rowSize = size[1] / rows;
        var colSize = size[0] / cols;
        for (var i = 0; i < rows; i++) {
            var currY = Math.round(rowSize * i);
            for (var j = 0; j < cols; j++) {
                var currX = Math.round(colSize * j);
                var currIndex = i * cols + j;
                if (!(currIndex in this._modifiers)) _createModifier.call(this, currIndex);
                _animateModifier.call(this, currIndex, [Math.round(colSize * (j + 1)) - currX, Math.round(rowSize * (i+ 1)) - currY], [currX, currY, 0], 1);
            }
        }
        this._dimensionsCache = [this.options.dimensions[0], this.options.dimensions[1]];
        this._contextSizeCache = [size[0], size[1]];

        this._activeCount = rows * cols;

        for (i = this._activeCount ; i < this._modifiers.length; i++) {
            _animateModifier.call(this, i, [Math.round(colSize), Math.round(rowSize)], [0, 0], 0);
        }
    }

    function _createModifier(index) {
        var transitionItem = {
            transform: new TransitionableTransform(Transform.identity),
            opacity: new Transitionable(0),
            size: new Transitionable([0, 0])
        };

        var modifier = new Modifier({
            transform: transitionItem.transform,
            opacity: transitionItem.opacity,
            size: transitionItem.size
        });

        this._states[index] = transitionItem;
        this._modifiers[index] = modifier;

    }

    function _animateModifier(index, size, position, opacity) {
        var currState = this._states[index];

        var currSize = currState.size;
        var currOpacity = currState.opacity;
        var currTransform = currState.transform;

        var transition = this.options.transition;

        currTransform.halt();
        currOpacity.halt();
        currSize.halt();

        currTransform.setTranslate(position, transition);
        currSize.set(size, transition);
        currOpacity.set(opacity, transition);
    }

    GridLayout.DEFAULT_OPTIONS = {
        dimensions: [1, 1],
        cellSize: [250, 250],
        transition: false
    };

    /**
     * Generate a render spec from the contents of this component.
     *
     * @private
     * @method render
     * @return {Object} Render spec for this component
     */
    GridLayout.prototype.render = function render() {
        return this.id;
    };

    /**
     * Patches the GridLayout instance's options with the passed-in ones.
     *
     * @method setOptions
     * @param {Options} options An object of configurable options for the GridLayout instance.
     */
    GridLayout.prototype.setOptions = function setOptions(options) {
        return this.optionsManager.setOptions(options);
    };

    /**
     * Sets the collection of renderables under the Gridlayout instance's control.
     *
     * @method sequenceFrom
     * @param {Array|ViewSequence} sequence Either an array of renderables or a Famous viewSequence.
     */
    GridLayout.prototype.sequenceFrom = function sequenceFrom(sequence) {
        if (sequence instanceof Array) sequence = new ViewSequence(sequence);
        this.sequence = sequence;
    };

    /**
     * Apply changes from this component to the corresponding document element.
     * This includes changes to classes, styles, size, content, opacity, origin,
     * and matrix transforms.
     *
     * @private
     * @method commit
     * @param {Context} context commit context
     */
    GridLayout.prototype.commit = function commit(context) {
        var transform = context.transform;
        var opacity = context.opacity;
        var origin = context.origin;
        var size = context.size;

        var cols = this.options.dimensions[0];
        var rows = this.options.dimensions[1];

        if (size[0] !== this._contextSizeCache[0] || size[1] !== this._contextSizeCache[1] || cols !== this._dimensionsCache[0] || rows !== this._dimensionsCache[1]) {
            _reflow.call(this, size, cols, rows);
        }

        var sequence = this.sequence;
        var result = [];
        var currIndex = 0;
        while (sequence && (currIndex < this._modifiers.length)) {
            var item = sequence.get();
            var modifier = this._modifiers[currIndex];
            if (currIndex >= this._activeCount && this._states[currIndex].opacity.isActive()) {
                this._modifiers.splice(currIndex, 1);
                this._states.splice(currIndex, 1);
            }
            if (item) {
                result[currIndex] = modifier.modify({
                    origin: origin,
                    target: item.render()
                });
            }
            sequence = sequence.getNext();
            currIndex++;
        }

        if (size) transform = Transform.moveThen([-size[0]*origin[0], -size[1]*origin[1], 0], transform);
        var nextSpec = {
            transform: transform,
            opacity: opacity,
            size: size,
            target: result
        };
        return nextSpec;
    };

    module.exports = GridLayout;
});
<commit_msg>made gridlayout return unnamed obj<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * Owner: felix@famo.us
 * @license MPL 2.0
 * @copyright Famous Industries, Inc. 2014
 */

define(function(require, exports, module) {
    var Entity = require('famous/core/Entity');
    var RenderNode = require('famous/core/RenderNode');
    var Transform = require('famous/core/Transform');
    var ViewSequence = require('famous/core/ViewSequence');
    var Modifier = require('famous/core/Modifier');
    var OptionsManager = require('famous/core/OptionsManager');
    var Transitionable = require('famous/transitions/Transitionable');
    var TransitionableTransform = require('famous/transitions/TransitionableTransform');

    /**
     * A layout which divides a context into several evenly-sized grid cells.
     *   If dimensions are provided, the grid is evenly subdivided with children
     *   cells representing their own context, otherwise the cellSize property is used to compute
     *   dimensions so that items of cellSize will fit.
     * @class GridLayout
     * @constructor
     * @param {Options} [options] An object of configurable options.
     * @param {Array.Number} [options.dimensions=[1, 1]] A two value array which specifies the amount of columns
     * and rows in your Gridlayout instance.
     * @param {Array.Number} [options.cellSize=[250, 250]]  A two-value array which specifies the width and height
     * of each cell in your Gridlayout instance.
     * @param {Transition} [options.transition=false] The transiton that controls the Gridlayout instance's reflow.
     */
    function GridLayout(options) {
        this.options = Object.create(GridLayout.DEFAULT_OPTIONS);
        this.optionsManager = new OptionsManager(this.options);
        if (options) this.setOptions(options);

        this.id = Entity.register(this);

        this._modifiers = [];
        this._states = [];
        this._contextSizeCache = [0, 0];
        this._dimensionsCache = [0, 0];
        this._activeCount = 0;
    }

    function _reflow(size, cols, rows) {
        if (!rows) rows = (size[1] / this.options.cellSize[1]) | 0;
        if (!cols) cols = (size[0] / this.options.cellSize[0]) | 0;
        var rowSize = size[1] / rows;
        var colSize = size[0] / cols;
        for (var i = 0; i < rows; i++) {
            var currY = Math.round(rowSize * i);
            for (var j = 0; j < cols; j++) {
                var currX = Math.round(colSize * j);
                var currIndex = i * cols + j;
                if (!(currIndex in this._modifiers)) _createModifier.call(this, currIndex);
                _animateModifier.call(this, currIndex, [Math.round(colSize * (j + 1)) - currX, Math.round(rowSize * (i+ 1)) - currY], [currX, currY, 0], 1);
            }
        }
        this._dimensionsCache = [this.options.dimensions[0], this.options.dimensions[1]];
        this._contextSizeCache = [size[0], size[1]];

        this._activeCount = rows * cols;

        for (i = this._activeCount ; i < this._modifiers.length; i++) {
            _animateModifier.call(this, i, [Math.round(colSize), Math.round(rowSize)], [0, 0], 0);
        }
    }

    function _createModifier(index) {
        var transitionItem = {
            transform: new TransitionableTransform(Transform.identity),
            opacity: new Transitionable(0),
            size: new Transitionable([0, 0])
        };

        var modifier = new Modifier({
            transform: transitionItem.transform,
            opacity: transitionItem.opacity,
            size: transitionItem.size
        });

        this._states[index] = transitionItem;
        this._modifiers[index] = modifier;

    }

    function _animateModifier(index, size, position, opacity) {
        var currState = this._states[index];

        var currSize = currState.size;
        var currOpacity = currState.opacity;
        var currTransform = currState.transform;

        var transition = this.options.transition;

        currTransform.halt();
        currOpacity.halt();
        currSize.halt();

        currTransform.setTranslate(position, transition);
        currSize.set(size, transition);
        currOpacity.set(opacity, transition);
    }

    GridLayout.DEFAULT_OPTIONS = {
        dimensions: [1, 1],
        cellSize: [250, 250],
        transition: false
    };

    /**
     * Generate a render spec from the contents of this component.
     *
     * @private
     * @method render
     * @return {Object} Render spec for this component
     */
    GridLayout.prototype.render = function render() {
        return this.id;
    };

    /**
     * Patches the GridLayout instance's options with the passed-in ones.
     *
     * @method setOptions
     * @param {Options} options An object of configurable options for the GridLayout instance.
     */
    GridLayout.prototype.setOptions = function setOptions(options) {
        return this.optionsManager.setOptions(options);
    };

    /**
     * Sets the collection of renderables under the Gridlayout instance's control.
     *
     * @method sequenceFrom
     * @param {Array|ViewSequence} sequence Either an array of renderables or a Famous viewSequence.
     */
    GridLayout.prototype.sequenceFrom = function sequenceFrom(sequence) {
        if (sequence instanceof Array) sequence = new ViewSequence(sequence);
        this.sequence = sequence;
    };

    /**
     * Apply changes from this component to the corresponding document element.
     * This includes changes to classes, styles, size, content, opacity, origin,
     * and matrix transforms.
     *
     * @private
     * @method commit
     * @param {Context} context commit context
     */
    GridLayout.prototype.commit = function commit(context) {
        var transform = context.transform;
        var opacity = context.opacity;
        var origin = context.origin;
        var size = context.size;

        var cols = this.options.dimensions[0];
        var rows = this.options.dimensions[1];

        if (size[0] !== this._contextSizeCache[0] || size[1] !== this._contextSizeCache[1] || cols !== this._dimensionsCache[0] || rows !== this._dimensionsCache[1]) {
            _reflow.call(this, size, cols, rows);
        }

        var sequence = this.sequence;
        var result = [];
        var currIndex = 0;
        while (sequence && (currIndex < this._modifiers.length)) {
            var item = sequence.get();
            var modifier = this._modifiers[currIndex];
            if (currIndex >= this._activeCount && this._states[currIndex].opacity.isActive()) {
                this._modifiers.splice(currIndex, 1);
                this._states.splice(currIndex, 1);
            }
            if (item) {
                result[currIndex] = modifier.modify({
                    origin: origin,
                    target: item.render()
                });
            }
            sequence = sequence.getNext();
            currIndex++;
        }

        if (size) transform = Transform.moveThen([-size[0]*origin[0], -size[1]*origin[1], 0], transform);
        return {
            transform: transform,
            opacity: opacity,
            size: size,
            target: result
        };
    };

    module.exports = GridLayout;
});
<|endoftext|>


<commit_before>import styled, { css } from "styled-components";
import Card from "@crave/farmblocks-card";
import { colors } from "@crave/farmblocks-theme";
import Text from "@crave/farmblocks-text";

import alignments from "../constants/alignments";

const alignStyles = {
  [alignments.LEFT]: css`
    left: -33px;
    transform-origin: bottom left;
  `,
  [alignments.RIGHT]: css`
    transform-origin: bottom right;
    right: -33px;
  `,
};

const animation = css`
  transition: transform 0.3s, opacity 0.3s, color 0.3s;

  &.fade-enter,
  &.fade-exit-active {
    transform: scale(0.5) rotate(5deg);
    opacity: 0;
  }
  &.fade-enter-active,
  &.fade-enter-done {
    transform: scale(1);
    opacity: 1;
  }

  .wg-small-arrow-right {
    transition: color 0.3s;
  }
`;

const interactiveStyle = css`
  cursor: pointer;

  bottom: ${props => props.pinSize / 2 + 8}px;

  .wg-small-arrow-right {
    color: ${colors.GREY_16};
  }

  &:active {
    transform: translateY(2px);

    .wg-small-arrow-right {
      color: ${colors.GREY_32};
    }
  }
`;
const Balloon = styled(Card)`
  ${props => props.animated && animation};
  position: absolute;
  bottom: ${props => props.pinSize + 8}px;

  ${props => alignStyles[props.align]};

  height: ${props => props.balloonSize}px;
  width: ${props => props.balloonSize}px;
  padding: 0;
  border-radius: ${props => props.borderRadius};
  border: none;
  box-shadow: 0 2px 16px 0 ${colors.GREY_16};

  display: flex;
  flex-direction: column;

  user-select: none;

  .caption {
    margin: 16px 8px;
  }

  ${props => (props.interactive ? interactiveStyle : "")};
`;

export const Caption = styled(Text)`
  padding-left: 8px;
  display: flex;
  align-items: center;
  justify-content: space-between;
`;

export default Balloon;
<commit_msg>fix(map-balloon): balloon radius not clipping the image<commit_after>import styled, { css } from "styled-components";
import Card from "@crave/farmblocks-card";
import { colors } from "@crave/farmblocks-theme";
import Text from "@crave/farmblocks-text";

import alignments from "../constants/alignments";

const alignStyles = {
  [alignments.LEFT]: css`
    left: -33px;
    transform-origin: bottom left;
  `,
  [alignments.RIGHT]: css`
    transform-origin: bottom right;
    right: -33px;
  `,
};

const animation = css`
  transition: transform 0.3s, opacity 0.3s, color 0.3s;

  &.fade-enter,
  &.fade-exit-active {
    transform: scale(0.5) rotate(5deg);
    opacity: 0;
  }
  &.fade-enter-active,
  &.fade-enter-done {
    transform: scale(1);
    opacity: 1;
  }

  .wg-small-arrow-right {
    transition: color 0.3s;
  }
`;

const interactiveStyle = css`
  cursor: pointer;

  bottom: ${props => props.pinSize / 2 + 8}px;

  .wg-small-arrow-right {
    color: ${colors.GREY_16};
  }

  &:active {
    transform: translateY(2px);

    .wg-small-arrow-right {
      color: ${colors.GREY_32};
    }
  }
`;
const Balloon = styled(Card).attrs({ overflow: "hidden" })`
  ${props => props.animated && animation};
  position: absolute;
  bottom: ${props => props.pinSize + 8}px;

  ${props => alignStyles[props.align]};

  height: ${props => props.balloonSize}px;
  width: ${props => props.balloonSize}px;
  padding: 0;
  border-radius: ${props => props.borderRadius};
  border: none;
  box-shadow: 0 2px 16px 0 ${colors.GREY_16};

  display: flex;
  flex-direction: column;

  user-select: none;

  .caption {
    margin: 16px 8px;
  }

  ${props => (props.interactive ? interactiveStyle : "")};
`;

export const Caption = styled(Text)`
  padding-left: 8px;
  display: flex;
  align-items: center;
  justify-content: space-between;
`;

export default Balloon;
<|endoftext|>


<commit_before>(function(){

    "use strict";

    var Timestring = function(settings) {
        // default settings
        var defaults = {
            hoursPerDay: 24,
            daysPerWeek: 7,
            weeksPerMonth: 4,
            monthsPerYear: 12
        };

        // merge default settings with user settings
        var settings = settings || {};
        this.settings = {};
        for (var property in defaults) { this.settings[property] = defaults[property]; }
        for (var property in settings) { this.settings[property] = settings[property]; }

        // time units
        this.units = {
            s: ['s', 'sec', 'secs', 'second', 'seconds'],
            m: ['m', 'min', 'mins', 'minute', 'minutes'],
            h: ['h', 'hr', 'hrs', 'hour', 'hours'],
            d: ['d', 'day', 'days'],
            w: ['w', 'week', 'weeks'],
            mth: ['mth', 'mths','month', 'months'],
            y: ['y', 'yr', 'yrs', 'year', 'years']
        };

        // time unit seconds mappings
        this.unitValues = {
            s: 1,
            m: 60,
            h: 3600
        };

        // dynamic time unit seconds mappings
        // these are dynamic based on the settings
        this.unitValues.d = this.settings.hoursPerDay * this.unitValues.h;
        this.unitValues.w = this.settings.daysPerWeek * this.unitValues.d;
        this.unitValues.mth = this.settings.weeksPerMonth * this.unitValues.w;
        this.unitValues.y = this.settings.monthsPerYear * this.unitValues.w;
    };

    Timestring.prototype.parse = function(string, returnUnit) {
        // reference to this
        var self = this;

        // get unit key helper
        function getUnitKey(unit) {
            for (var key in self.units) {
                for (var u in self.units[key]) {
                    if (unit === self.units[key][u]) {
                        return key;
                    }
                }
            }

            // throw exception if invalid unit is passed
            throw 'The unit [' + unit + '] is not supported by timestring';
        }

        // convert a value to a specific unit
        function convert(value, unit) {
            var baseValue = self.unitValues[getUnitKey(unit)];
            return value / baseValue;
        }

        // get a value in seconds based on a specific unit
        function getSeconds(value, unit) {
            var baseValue = self.unitValues[getUnitKey(unit)];
            return value * baseValue;
        }

        // seconds counter
        var totalSeconds = 0;

        // split string into groups and get total seconds for each group
        var groups = string
                        .toLowerCase() // convert words to lower case
                        .replace(/[^\.\w+-]+/g, '') // remove white space
                        .match(/[-+]?[0-9]+[a-z]+/g); // match time groups (digit followed by time unit - i.e 5d 15m = 2 time groups)

        if (groups !== null) {
            for(var group in groups) {
                var g = groups[group],
                    value = g.match(/[0-9]+/g)[0],
                    unit = g.match(/[a-z]+/g)[0];

                totalSeconds += getSeconds(value, unit);
            }
        }

        // return total, convert if needed
        return (returnUnit) ? convert(totalSeconds, returnUnit) : totalSeconds;
    }

    // add convenience method to string proto
    String.prototype.parseTime = function (unit, settings) {
        return (new Timestring(settings)).parse(this, unit);
    }

    // export Timestring object for either the browser or node.js
    if (typeof module !== 'undefined' && module.exports) {
        module.exports = Timestring;
    }
    else {
        this.Timestring = Timestring;
    }

}).call(this);
<commit_msg>Exchanged for-each with vanilla for-loop<commit_after>(function(){

    "use strict";

    var Timestring = function(settings) {
        // default settings
        var defaults = {
            hoursPerDay: 24,
            daysPerWeek: 7,
            weeksPerMonth: 4,
            monthsPerYear: 12
        };

        // merge default settings with user settings
        var settings = settings || {};
        this.settings = {};
        for (var property in defaults) { this.settings[property] = defaults[property]; }
        for (var property in settings) { this.settings[property] = settings[property]; }

        // time units
        this.units = {
            s: ['s', 'sec', 'secs', 'second', 'seconds'],
            m: ['m', 'min', 'mins', 'minute', 'minutes'],
            h: ['h', 'hr', 'hrs', 'hour', 'hours'],
            d: ['d', 'day', 'days'],
            w: ['w', 'week', 'weeks'],
            mth: ['mth', 'mths','month', 'months'],
            y: ['y', 'yr', 'yrs', 'year', 'years']
        };

        // time unit seconds mappings
        this.unitValues = {
            s: 1,
            m: 60,
            h: 3600
        };

        // dynamic time unit seconds mappings
        // these are dynamic based on the settings
        this.unitValues.d = this.settings.hoursPerDay * this.unitValues.h;
        this.unitValues.w = this.settings.daysPerWeek * this.unitValues.d;
        this.unitValues.mth = this.settings.weeksPerMonth * this.unitValues.w;
        this.unitValues.y = this.settings.monthsPerYear * this.unitValues.w;
    };

    Timestring.prototype.parse = function(string, returnUnit) {
        // reference to this
        var self = this;

        // get unit key helper
        function getUnitKey(unit) {
            for (var key in self.units) {
                for (var u in self.units[key]) {
                    if (unit === self.units[key][u]) {
                        return key;
                    }
                }
            }

            // throw exception if invalid unit is passed
            throw 'The unit [' + unit + '] is not supported by timestring';
        }

        // convert a value to a specific unit
        function convert(value, unit) {
            var baseValue = self.unitValues[getUnitKey(unit)];
            return value / baseValue;
        }

        // get a value in seconds based on a specific unit
        function getSeconds(value, unit) {
            var baseValue = self.unitValues[getUnitKey(unit)];
            return value * baseValue;
        }

        // seconds counter
        var totalSeconds = 0;

        // split string into groups and get total seconds for each group
        var groups = string
                        .toLowerCase() // convert words to lower case
                        .replace(/[^\.\w+-]+/g, '') // remove white space
                        .match(/[-+]?[0-9]+[a-z]+/g); // match time groups (digit followed by time unit - i.e 5d 15m = 2 time groups)

        if (groups !== null) {
            for( var i = 0; i < groups.length; i++ ) {
                var g = groups[i],
                    value = g.match(/[0-9]+/g)[0],
                    unit = g.match(/[a-z]+/g)[0];
                totalSeconds += getSeconds(value, unit);
            }
        }

        // return total, convert if needed
        return (returnUnit) ? convert(totalSeconds, returnUnit) : totalSeconds;
    }

    // add convenience method to string proto
    String.prototype.parseTime = function (unit, settings) {
        return (new Timestring(settings)).parse(this, unit);
    }

    // export Timestring object for either the browser or node.js
    if (typeof module !== 'undefined' && module.exports) {
        module.exports = Timestring;
    }
    else {
        this.Timestring = Timestring;
    }

}).call(this);
<|endoftext|>


<commit_before>/**
 * animation-mixer
 *
 * Player for animation clips. Intended to be compatible with any model format that supports
 * skeletal or morph animations through THREE.AnimationMixer.
 * See: https://threejs.org/docs/?q=animation#Reference/Animation/AnimationMixer
 */
module.exports = {
  schema: {
    clip:  {default: '*'},
    duration: {default: 0}
  },

  init: function () {
    /** @type {THREE.Mesh} */
    this.model = null;
    /** @type {THREE.AnimationMixer} */
    this.mixer = null;
    /** @type {Array<THREE.AnimationAction>} */
    this.activeActions = [];

    var model = this.el.getObject3D('mesh');

    if (model) {
      this.load(model);
    } else {
      this.el.addEventListener('model-loaded', function(e) {
        this.load(e.detail.model);
      }.bind(this));
    }
  },

  load: function (model) {
    this.model = model;
    this.mixer = new THREE.AnimationMixer(model);
    if (this.data.clip) this.update({});
  },

  remove: function () {
    if (this.mixer) this.mixer.stopAllAction();
  },

  update: function (previousData) {
    if (!previousData) return;

    var data = this.data,
        activeActions = this.activeActions;

    if (data.clip !== previousData.clip) {
      if (activeActions.length) this.mixer.stopAllAction();
      if (data.clip) this.playClip(data.clip);
    }

    if (!activeActions.length) return;

    if (data.duration) {
      for (var action, i = 0; (action = activeActions[i]); i++) {
        action.setDuration(data.duration);
      }
    }
  },

  playClip: function (clipName) {
    if (!this.mixer) return;

    var model = this.model,
        clips = model.animations || (model.geometry || {}).animations || [];

    if (!clips.length) return;

    var re = wildcardToRegExp(clipName);

    this.activeActions.length = 0;
    for (var clip, action, i = 0; (clip = clips[i]); i++) {
      if (clip.name.match(re)) {
        action = this.mixer.clipAction(clip, model);
        action.play();
        this.activeActions.push(action);
      }
    }
  },

  tick: function (t, dt) {
    if (this.mixer && !isNaN(dt)) this.mixer.update(dt / 1000);
  }
};

/**
 * Creates a RegExp from the given string, converting asterisks to .* expressions,
 * and escaping all other characters.
 */
function wildcardToRegExp (s) {
  return new RegExp('^' + s.split(/\*+/).map(regExpEscape).join('.*') + '$');
}

/**
 * RegExp-escapes all characters in the given string.
 */
function regExpEscape (s) {
  return s.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&');
}
<commit_msg>[animation-mixer] Add 'crossFadeDuration' property.<commit_after>/**
 * animation-mixer
 *
 * Player for animation clips. Intended to be compatible with any model format that supports
 * skeletal or morph animations through THREE.AnimationMixer.
 * See: https://threejs.org/docs/?q=animation#Reference/Animation/AnimationMixer
 */
module.exports = {
  schema: {
    clip:  {default: '*'},
    duration: {default: 0},
    crossFadeDuration: {default: 0}
  },

  init: function () {
    /** @type {THREE.Mesh} */
    this.model = null;
    /** @type {THREE.AnimationMixer} */
    this.mixer = null;
    /** @type {Array<THREE.AnimationAction>} */
    this.activeActions = [];

    var model = this.el.getObject3D('mesh');

    if (model) {
      this.load(model);
    } else {
      this.el.addEventListener('model-loaded', function(e) {
        this.load(e.detail.model);
      }.bind(this));
    }
  },

  load: function (model) {
    this.model = model;
    this.mixer = new THREE.AnimationMixer(model);
    if (this.data.clip) this.update({});
  },

  remove: function () {
    if (this.mixer) this.mixer.stopAllAction();
  },

  update: function (previousData) {
    if (!previousData) return;

    var data = this.data,
        activeActions = this.activeActions;

    if (data.clip !== previousData.clip) {
      if (activeActions.length) this.stopAction();
      if (data.clip) this.playAction();
    }

    if (!activeActions.length) return;

    if (data.duration) {
      for (var action, i = 0; (action = activeActions[i]); i++) {
        action.setDuration(data.duration);
      }
    }
  },

  stopAction: function () {
    var data = this.data;
    for (var i = 0; i < this.activeActions.length; i++) {
      data.crossFadeDuration
        ? this.activeActions[i].fadeOut(data.crossFadeDuration / 1000)
        : this.activeActions[i].stop();
    }
    this.activeActions.length = 0;
  },

  playAction: function () {
    if (!this.mixer) return;

    var model = this.model,
        data = this.data,
        clips = model.animations || (model.geometry || {}).animations || [];

    if (!clips.length) return;

    var re = wildcardToRegExp(data.clip);

    for (var clip, i = 0; (clip = clips[i]); i++) {
      if (clip.name.match(re)) {
        var action = this.mixer.clipAction(clip, model);
        action.enabled = true;
        action
          .fadeIn(data.crossFadeDuration / 1000)
          .play();
        this.activeActions.push(action);
      }
    }
  },

  tick: function (t, dt) {
    if (this.mixer && !isNaN(dt)) this.mixer.update(dt / 1000);
  }
};

/**
 * Creates a RegExp from the given string, converting asterisks to .* expressions,
 * and escaping all other characters.
 */
function wildcardToRegExp (s) {
  return new RegExp('^' + s.split(/\*+/).map(regExpEscape).join('.*') + '$');
}

/**
 * RegExp-escapes all characters in the given string.
 */
function regExpEscape (s) {
  return s.replace(/[|\\{}()[\]^$+*?.]/g, '\\$&');
}
<|endoftext|>