<commit_before> robot.router.get('/auth/github/callback', function (req, res) {
        var userid = JSON.parse(req.query.state).userid;
        var username = JSON.parse(req.query.state).username;

        var code = req.query.code;

        OAuth2.getOAuthAccessToken(code, {}, function (err, access_token) {
            if (err) {
                console.log(err);
            }

            // ****
            // TODO:
            // BETTER Handling of promises!!
            // ****

            var db = require('./mlab-login.js').db();

            github.authenticate({
                "type": "token",
                "token": access_token
            })
            github.users.get({}, function (err, res) {
                var github_username = res.data.login
                db.bind('users').findAndModifyAsync(
                    { _id: userid },
                    [["_id", 1]],
                    { $set: { github_username: github_username } },
                    { upsert: true })
                    .then(res => { })
                    .catch(err => {
                        robot.logger.error(err)
                        if (c.errorsChannel) {
                            robot.messageRoom(c.errorsChannel, c.errorMessage
                                + `Script: ${path.basename(__filename)}`)
                        }
                    })
                var values = {
                    github_username: github_username,
                    github_token: access_token
                }
                cache.set(userid, values)
            })
            encryption.encrypt(access_token).then(encryptedToken => {

                //TODO -> convert to promise
                db.bind('users').findAndModifyAsync(
                    { _id: userid },
                    [["_id", 1]],
                    { $set: { github_token: encryptedToken } },
                    { upsert: true })
                    .then(res => {
                        robot.logger.info(`${username}'s GitHub Token Added to DB!`)
                        robot.emit('refreshBrain') //refresh brain to update tokens
                    })
                    .catch(err => {
                        robot.logger.error(err)
                        if (c.errorsChannel) {
                            robot.messageRoom(c.errorsChannel, c.errorMessage
                                + `Script: ${path.basename(__filename)}`)
                        }
                    })
                    .done(() => {
                        db.close()
                    })
            });
        });
        res.redirect('');
    });<commit_msg>gh token.js<commit_after>var encryption = require('./encryption.js');

var client_id = process.env.GITHUB_APP_CLIENT_ID;
var client_secret = process.env.GITHUB_APP_CLIENT_SECRET;
var hostUrl = 'http://github.com/login/oauth/authorize';
var authorization_base_url = 'https://github.com/login/oauth/authorize'
var token_url = 'https://github.com/login/oauth/access_token'
var bot_host = process.env.HUBOT_HOST_URL
var GitHubApi = require('github')
var cache = require('./cache.js').getCache()

module.exports = (robot) => {

    robot.router.get('/auth/github/callback', function (req, res) {
        var userid = JSON.parse(req.query.state).userid;
        var username = JSON.parse(req.query.state).username;

        var code = req.query.code;

        OAuth2.getOAuthAccessToken(code, {}, function (err, access_token) {
            if (err) {
                console.log(err);
            }

            // ****
            // TODO:
            // BETTER Handling of promises!!
            // ****

            var db = require('./mlab-login.js').db();

            github.authenticate({
                "type": "token",
                "token": access_token
            })
            github.users.get({}, function (err, res) {
                var github_username = res.data.login
                db.bind('users').findAndModifyAsync(
                    { _id: userid },
                    [["_id", 1]],
                    { $set: { github_username: github_username } },
                    { upsert: true })
                    .then(res => { })
                    .catch(err => {
                        robot.logger.error(err)
                        if (c.errorsChannel) {
                            robot.messageRoom(c.errorsChannel, c.errorMessage
                                + `Script: ${path.basename(__filename)}`)
                        }
                    })
                var values = {
                    github_username: github_username,
                    github_token: access_token
                }
                cache.set(userid, values)
            })
            encryption.encrypt(access_token).then(encryptedToken => {

                //TODO -> convert to promise
                db.bind('users').findAndModifyAsync(
                    { _id: userid },
                    [["_id", 1]],
                    { $set: { github_token: encryptedToken } },
                    { upsert: true })
                    .then(res => {
                        robot.logger.info(`${username}'s GitHub Token Added to DB!`)
                        robot.emit('refreshBrain') //refresh brain to update tokens
                    })
                    .catch(err => {
                        robot.logger.error(err)
                        if (c.errorsChannel) {
                            robot.messageRoom(c.errorsChannel, c.errorMessage
                                + `Script: ${path.basename(__filename)}`)
                        }
                    })
                    .done(() => {
                        db.close()
                    })
            });
        });
        res.redirect('');
    });

}<|endoftext|>


<commit_before><commit_msg>PR feedback: remove unnecessary module and function name.<commit_after><|endoftext|>


<commit_before>"use strict";
const aws = require('aws-sdk');
const fetch = requure('node-fetch')
const fs = require('fs');
const lsc = require('./livesplit_core');
const pg = require('pg');
const s3 = new aws.S3();

exports.handler = function(event, context, callback) {
  const filename = event['Records'][0]['s3']['object']['key'].split('/')[1]
  fetch(`https://splits.io/api/webhooks/parse?s3_filename=${filename}`).then(function(response) {
    if(response.ok) {
      console.log("Complete")
    } else {
      console.error(`Bad status for parsing run ${filename}: ${response.status}`)
    }
  }).catch(function(error) {
    console.error(error)
  });
};

/* // The below code was written to actually parse runs. May want this later. Leaving here because it was a pain to get
 * // LiveSplit Core and Lambda set up, and it actually works below.
exports.handler = function (event, context, callback) {
  console.log(event);
  const promises = event['Records'].map((record) => {
    return new Promise((resolve, reject) => {
      const key = record['s3']['object']['key'];
      const params = {Bucket: 'splits.io', Key: key};

      s3.getObject(params, (err, data) => {
        if (err) {
          return reject(err);
        }

        const result = lsc.Run.parseArray(data['Body'], '', false);
        console.log(`parsed: ${result.parsedSuccessfully()}`);
        if (result.parsedSuccessfully()) {
          console.log(`timer: ${result.timerKind()}`);
          const run = result.unwrap();
          console.log(`game: ${run.gameName()}`);
          resolve();
        }
      });
    });
  });

  Promise.all(promises).then(function () {
    console.log("Complete!");
  }).catch(console.error);
};
*/
<commit_msg>Use internal.splits.io for Lambda job<commit_after>"use strict"
const aws = require('aws-sdk')
const fetch = require('node-fetch')
const fs = require('fs')
const lsc = require('./livesplit_core')
const pg = require('pg')
const s3 = new aws.S3()

exports.handler = function(event, context, callback) {
  const filename = event['Records'][0]['s3']['object']['key'].split('/')[1]
  fetch(`https://internal.splits.io/api/webhooks/parse?s3_filename=${filename}`).then(function(response) {
    if(response.ok) {
      console.log("Complete")
    } else {
      console.error(`Bad status for parsing run ${filename}: ${response.status}`)
    }
  }).catch(function(error) {
    console.error(error)
  });
};

/* // The below code was written to actually parse runs. May want this later. Leaving here because it was a pain to get
 * // LiveSplit Core and Lambda set up, and it actually works below.
exports.handler = function (event, context, callback) {
  console.log(event);
  const promises = event['Records'].map((record) => {
    return new Promise((resolve, reject) => {
      const key = record['s3']['object']['key'];
      const params = {Bucket: 'splits.io', Key: key};

      s3.getObject(params, (err, data) => {
        if (err) {
          return reject(err);
        }

        const result = lsc.Run.parseArray(data['Body'], '', false);
        console.log(`parsed: ${result.parsedSuccessfully()}`);
        if (result.parsedSuccessfully()) {
          console.log(`timer: ${result.timerKind()}`);
          const run = result.unwrap();
          console.log(`game: ${run.gameName()}`);
          resolve();
        }
      });
    });
  });

  Promise.all(promises).then(function () {
    console.log("Complete!");
  }).catch(console.error);
};
*/
<|endoftext|>


<commit_before>// https://github.com/ironwallaby/delaunay/blob/master/delaunay.js
function Triangle(a, b, c) {
  this.a = a
  this.b = b
  this.c = c

  var A = b.x - a.x,
      B = b.y - a.y,
      C = c.x - a.x,
      D = c.y - a.y,
      E = A * (a.x + b.x) + B * (a.y + b.y),
      F = C * (a.x + c.x) + D * (a.y + c.y),
      G = 2 * (A * (c.y - b.y) - B * (c.x - b.x)),
      minx, miny, dx, dy

  /* If the points of the triangle are collinear, then just find the
   * extremes and use the midpoint as the center of the circumcircle. */
  if(Math.abs(G) < 0.000001) {
    minx = Math.min(a.x, b.x, c.x)
    miny = Math.min(a.y, b.y, c.y)
    dx   = (Math.max(a.x, b.x, c.x) - minx) * 0.5
    dy   = (Math.max(a.y, b.y, c.y) - miny) * 0.5

    this.x = minx + dx
    this.y = miny + dy
    this.r = dx * dx + dy * dy
  }

  else {
    this.x = (D*E - B*F) / G
    this.y = (A*F - C*E) / G
    dx = this.x - a.x
    dy = this.y - a.y
    this.r = dx * dx + dy * dy
  }
}

Triangle.prototype.draw = function(ctx) {
  ctx.beginPath()
  ctx.moveTo(this.a.x, this.a.y)
  ctx.lineTo(this.b.x, this.b.y)
  ctx.lineTo(this.c.x, this.c.y)
  ctx.closePath()
  ctx.stroke()
}

function byX(a, b) {
  return b.x - a.x
}

function dedup(edges) {
  var j = edges.length,
      a, b, i, m, n

  outer: while(j) {
    b = edges[--j]
    a = edges[--j]
    i = j
    while(i) {
      n = edges[--i]
      m = edges[--i]
      if((a === m && b === n) || (a === n && b === m)) {
        edges.splice(j, 2)
        edges.splice(i, 2)
        j -= 2
        continue outer
      }
    }
  }
}

function triangulate(vertices) {
  /* Bail if there aren't enough vertices to form any triangles. */
  if(vertices.length < 3)
    return []

  /* Ensure the vertex array is in order of descending X coordinate
   * (which is needed to ensure a subquadratic runtime), and then find
   * the bounding box around the points. */
  vertices.sort(byX)

  var i    = vertices.length - 1,
      xmin = vertices[i].x,
      xmax = vertices[0].x,
      ymin = vertices[i].y,
      ymax = ymin

  while(i--) {
    if(vertices[i].y < ymin) ymin = vertices[i].y
    if(vertices[i].y > ymax) ymax = vertices[i].y
  }

  /* Find a supertriangle, which is a triangle that surrounds all the
   * vertices. This is used like something of a sentinel value to remove
   * cases in the main algorithm, and is removed before we return any
   * results.
   *
   * Once found, put it in the "open" list. (The "open" list is for
   * triangles who may still need to be considered; the "closed" list is
   * for triangles which do not.) */
  var dx     = xmax - xmin,
      dy     = ymax - ymin,
      dmax   = (dx > dy) ? dx : dy,
      xmid   = (xmax + xmin) * 0.5,
      ymid   = (ymax + ymin) * 0.5,
      open   = [
        new Triangle(
          {x: xmid - 20 * dmax, y: ymid -      dmax, __sentinel: true},
          {x: xmid            , y: ymid + 20 * dmax, __sentinel: true},
          {x: xmid + 20 * dmax, y: ymid -      dmax, __sentinel: true}
        )
      ],
      closed = [],
      edges = [],
      j, a, b

  /* Incrementally add each vertex to the mesh. */
  i = vertices.length
  while(i--) {
    /* For each open triangle, check to see if the current point is
     * inside it's circumcircle. If it is, remove the triangle and add
     * it's edges to an edge list. */
    edges.length = 0
    j = open.length
    while(j--) {
      /* If this point is to the right of this triangle's circumcircle,
       * then this triangle should never get checked again. Remove it
       * from the open list, add it to the closed list, and skip. */
      dx = vertices[i].x - open[j].x
      if(dx > 0 && dx * dx > open[j].r) {
        closed.push(open[j])
        open.splice(j, 1)
        continue
      }

      /* If not, skip this triangle. */
      dy = vertices[i].y - open[j].y
      if(dx * dx + dy * dy > open[j].r)
        continue

      /* Remove the triangle and add it's edges to the edge list. */
      edges.push(
        open[j].a, open[j].b,
        open[j].b, open[j].c,
        open[j].c, open[j].a
      )
      open.splice(j, 1)
    }

    /* Remove any doubled edges. */
    dedup(edges)

    /* Add a new triangle for each edge. */
    j = edges.length
    while(j) {
      b = edges[--j]
      a = edges[--j]
      open.push(new Triangle(a, b, vertices[i]))
    }
  }

  /* Copy any remaining open triangles to the closed list, and then
   * remove any triangles that share a vertex with the supertriangle. */
  Array.prototype.push.apply(closed, open)

  i = closed.length
  while(i--)
    if(closed[i].a.__sentinel ||
       closed[i].b.__sentinel ||
       closed[i].c.__sentinel)
      closed.splice(i, 1)

  /* Yay, we're done! */
  return closed
}

if (typeof module !== 'undefined') {
    module.exports = {
        Triangle: Triangle,
        triangulate: triangulate
    }
}
<commit_msg>add requirejs wrapper to delaunay.js lib<commit_after>/*global define*/
define(
  function()
  {
    // https://github.com/ironwallaby/delaunay/blob/master/delaunay.js
    function Triangle(a, b, c) {
      this.a = a
      this.b = b
      this.c = c

      var A = b.x - a.x,
          B = b.y - a.y,
          C = c.x - a.x,
          D = c.y - a.y,
          E = A * (a.x + b.x) + B * (a.y + b.y),
          F = C * (a.x + c.x) + D * (a.y + c.y),
          G = 2 * (A * (c.y - b.y) - B * (c.x - b.x)),
          minx, miny, dx, dy

      /* If the points of the triangle are collinear, then just find the
       * extremes and use the midpoint as the center of the circumcircle. */
      if(Math.abs(G) < 0.000001) {
        minx = Math.min(a.x, b.x, c.x)
        miny = Math.min(a.y, b.y, c.y)
        dx   = (Math.max(a.x, b.x, c.x) - minx) * 0.5
        dy   = (Math.max(a.y, b.y, c.y) - miny) * 0.5

        this.x = minx + dx
        this.y = miny + dy
        this.r = dx * dx + dy * dy
      }

      else {
        this.x = (D*E - B*F) / G
        this.y = (A*F - C*E) / G
        dx = this.x - a.x
        dy = this.y - a.y
        this.r = dx * dx + dy * dy
      }
    }

    Triangle.prototype.draw = function(ctx) {
      ctx.beginPath()
      ctx.moveTo(this.a.x, this.a.y)
      ctx.lineTo(this.b.x, this.b.y)
      ctx.lineTo(this.c.x, this.c.y)
      ctx.closePath()
      ctx.stroke()
    }

    function byX(a, b) {
      return b.x - a.x
    }

    function dedup(edges) {
      var j = edges.length,
          a, b, i, m, n

      outer: while(j) {
        b = edges[--j]
        a = edges[--j]
        i = j
        while(i) {
          n = edges[--i]
          m = edges[--i]
          if((a === m && b === n) || (a === n && b === m)) {
            edges.splice(j, 2)
            edges.splice(i, 2)
            j -= 2
            continue outer
          }
        }
      }
    }

    function triangulate(vertices) {
      /* Bail if there aren't enough vertices to form any triangles. */
      if(vertices.length < 3)
        return []

      /* Ensure the vertex array is in order of descending X coordinate
       * (which is needed to ensure a subquadratic runtime), and then find
       * the bounding box around the points. */
      vertices.sort(byX)

      var i    = vertices.length - 1,
          xmin = vertices[i].x,
          xmax = vertices[0].x,
          ymin = vertices[i].y,
          ymax = ymin

      while(i--) {
        if(vertices[i].y < ymin) ymin = vertices[i].y
        if(vertices[i].y > ymax) ymax = vertices[i].y
      }

      /* Find a supertriangle, which is a triangle that surrounds all the
       * vertices. This is used like something of a sentinel value to remove
       * cases in the main algorithm, and is removed before we return any
       * results.
       *
       * Once found, put it in the "open" list. (The "open" list is for
       * triangles who may still need to be considered; the "closed" list is
       * for triangles which do not.) */
      var dx     = xmax - xmin,
          dy     = ymax - ymin,
          dmax   = (dx > dy) ? dx : dy,
          xmid   = (xmax + xmin) * 0.5,
          ymid   = (ymax + ymin) * 0.5,
          open   = [
            new Triangle(
              {x: xmid - 20 * dmax, y: ymid -      dmax, __sentinel: true},
              {x: xmid            , y: ymid + 20 * dmax, __sentinel: true},
              {x: xmid + 20 * dmax, y: ymid -      dmax, __sentinel: true}
            )
          ],
          closed = [],
          edges = [],
          j, a, b

      /* Incrementally add each vertex to the mesh. */
      i = vertices.length
      while(i--) {
        /* For each open triangle, check to see if the current point is
         * inside it's circumcircle. If it is, remove the triangle and add
         * it's edges to an edge list. */
        edges.length = 0
        j = open.length
        while(j--) {
          /* If this point is to the right of this triangle's circumcircle,
           * then this triangle should never get checked again. Remove it
           * from the open list, add it to the closed list, and skip. */
          dx = vertices[i].x - open[j].x
          if(dx > 0 && dx * dx > open[j].r) {
            closed.push(open[j])
            open.splice(j, 1)
            continue
          }

          /* If not, skip this triangle. */
          dy = vertices[i].y - open[j].y
          if(dx * dx + dy * dy > open[j].r)
            continue

          /* Remove the triangle and add it's edges to the edge list. */
          edges.push(
            open[j].a, open[j].b,
            open[j].b, open[j].c,
            open[j].c, open[j].a
          )
          open.splice(j, 1)
        }

        /* Remove any doubled edges. */
        dedup(edges)

        /* Add a new triangle for each edge. */
        j = edges.length
        while(j) {
          b = edges[--j]
          a = edges[--j]
          open.push(new Triangle(a, b, vertices[i]))
        }
      }

      /* Copy any remaining open triangles to the closed list, and then
       * remove any triangles that share a vertex with the supertriangle. */
      Array.prototype.push.apply(closed, open)

      i = closed.length
      while(i--)
        if(closed[i].a.__sentinel ||
           closed[i].b.__sentinel ||
           closed[i].c.__sentinel)
          closed.splice(i, 1)

      /* Yay, we're done! */
      return closed
    }

    if (typeof module !== 'undefined') {
        module.exports = {
            Triangle: Triangle,
            triangulate: triangulate
        }
    }

    return triangulate;
  }
);<|endoftext|>


<commit_before>$("tr.file-diff-line > td.diff-line-num-addition.empty-cell").each(function (index, cell) {
  var line = $(cell).parent().attr('data-line');
  var path = $(cell).parent().attr('data-path');

  // Fill in the path to the repo on your computer here
  var repoRoot = '/Users/nick/reporoot/';
  var openInTextmateUrl = 'txmt://open?url=file://' + repoRoot + path + '&line=' + line;
  $(cell).html('Txmt');
})
<commit_msg>Wrap in IIFE<commit_after>(function (window, jQuery) {
  $("tr.file-diff-line > td.diff-line-num-addition.empty-cell").each(function (index, cell) {
    var line = $(cell).parent().attr('data-line');
    var path = $(cell).parent().attr('data-path');

    // Fill in the path to the repo on your computer here
    var repoRoot = '/Users/nick/reporoot/';
    var openInTextmateUrl = 'txmt://open?url=file://' + repoRoot + path + '&line=' + line;
    $(cell).html('Txmt');
  })
}(window, jQuery));
<|endoftext|>


<commit_before>import {
  combineReducers,
} from 'redux';
import {
  routerReducer as router,
} from 'react-router-redux';

export const makeRootReducer = (asyncReducers) => {
  return combineReducers({
    // Add sync reducers here
    router,
    ...asyncReducers,
  });
};

export const injectReducer = (store, {
  key,
  reducer,
}) => {
  store.asyncReducers[key] = reducer;
  store.replaceReducer(makeRootReducer(store.asyncReducers));
};

export default makeRootReducer;
<commit_msg>just some default reducers<commit_after>import {
  combineReducers,
} from 'redux';
import {
  routerReducer as router,
} from 'react-router-redux';
import initState from './initState';

export const makeRootReducer = (asyncReducers) => {
  return combineReducers({
    // Add sync reducers here
    router,
    shoppinglist: () => initState.shoppinglist,
    shoppingcard: () => initState.shoppingcard,
    ...asyncReducers,
  });
};

export const injectReducer = (store, {
  key,
  reducer,
}) => {
  store.asyncReducers[key] = reducer;
  store.replaceReducer(makeRootReducer(store.asyncReducers));
};

export default makeRootReducer;
<|endoftext|>


<commit_before>(function ($, count, window, document) {
    "use strict";
    var ajax = null,
    ef = function () {return;},
    methods = {
        init: function (opts) {
            var T = this,
            data = {
                instanceid: ++count,
                s: $.fn.extend({
                    delay: 250,
                    minlength: 2,
                    onajaxerror: ef,
                    onbeforeajaxsearch: ef,
                    onbeforesearch: ef,
                    onclose: ef,
                    onerror: ef,
                    oninit: ef,
                    onresponse: ef,
                    onsearch: ef,
                    onselect: ef,
                    src: []
                }, opts),
                searchterm: null
            },
            searchinterval = false,
            clear = false,
            keycodes = {
                DOWN: 40,
                ENTER: 13,
                SPACE: 32,
                TAB: 9,
                UP: 38,
                ESC: 27
            },
            selectpos = -1,
            cancelkeypress = false;
            if (!T.length || T.data('streamcomplete')) {
                // There are no elements or this object has already been initialised
                return T;
            }
            if (T.length > 1) {
                T.each(function () {
                    $(this).streamComplete(opts);
                });
                return T;
            }

            /**
             * Render a single result
             * @param {object(plain)} desc An object with necessary properties. The obejct MUST have the properties 'id' and 'value'
             * @returns {Element} The rendered element, in this case a div
             */
            data.renderResult = function (desc) {
                var elem = document.createElement('div');
                $(elem).html(desc.label).data('sc-desc', desc).addClass('streamcomplete-result');
                return elem;
            };

            /**
             * Render the full autocomplete
             * @param {array} results An array of objects in the form [{id: int, value: value}, ...], or an array of values
             */
            data.render = function (results) {
                var output = $('.streamcomplete-body').show(),
                offset = T.offset(),
                rect = T[0].getBoundingClientRect();
                output.css({width: rect.width, top: offset.top + rect.height, left: offset.left}).empty();
                for (var i = 0; results ? i < results.length : 0; i++) {
                    var desc = getAsObject(results[i]);

                    var res = data.renderResult(desc);
                    output.append(res);
                }
            };

            /**
             * The after render function. Seperate from the render function because the render function can be customised, whereas
             *  everything in this function is more or less always required. Makes customising the output easier
             */
            data.afterRender = function () {
                var output = $('.streamcomplete-body'),
                results = output.data('sc-results');
                output.data('sc-results', results);
                $('body').unbind('click.streamcomplete').bind('click.streamcomplete', data.close);
            };

            /**
             * Event after a user has made a selection
             * @param {Event} e
             */
            data.close = function (e) {
                var selection = null;
                if (e) {
                    // This function was called as a result of an event
                    var target = $(e.target);
                    if (target.closest('.streamcomplete-body').length) {
                        // The user has clicked on one of the selections
                        var selection = target.data('sc-desc');
                        if (data.s.onselect.call(T, selection) === false) {
                            // The caller has prevented continuation
                            return false;
                        }
                        T[0].value = selection.value;
                        T.data('value', selection.id);
                    }
                    $('body').unbind('click.streamcomplete');
                }
                data.s.onclose.call(T, {selection: selection, results: $('.streamcomplete-body').hide().data('sc-results')});
            };

            T.keydown(function (e) {
                // If there is need to return false, then the keyboard event listener has to be onkeydown.
                if (inObj(keycodes, e.which)) {
                    // The user is navigating using the keyboard
                    var ans = keyboardAction(e.which);
                    if (ans === false) {
                        // The keyboard action returned false, so prevent the default action
                        e.preventDefault();
                        cancelkeypress = true;
                        return false;
                    }
                }
            });

            /**
             * A callback if the source parameter is a function
             * @param {array} results An array of results
             */
            data.returnSource = function (results) {
                if (data.s.onsearch.call(T, results) === false) {
                    return false;
                }
                data.render(results);
                data.afterRender();
            };

            T.keyup(function () {
                if (cancelkeypress) {
                    // The keydown event listener says that the keyup event should not be registered
                    cancelkeypress = false;
                    return false;
                }
                data.searchterm = this.value;
                var payload = {
                    term: data.searchterm
                };
                selectpos = -1;
                if (data.s.onbeforesearch.call(T, payload) === false) {
                    // The caller cancelled the search: return
                    return false;
                }
                if (this.value.length >= +data.s.minlength) {
                    clear = false;
                    if (searchinterval !== false) {
                        // Clear the search interval
                        window.clearTimeout(searchinterval);
                    }
                    searchinterval = window.setTimeout(function () {
                        // Only perform searches in intervals as specified by the settings
                        if (clear) {
                            // A clear was called during the timeout
                            clear = false;
                            return;
                        }
                        switch (Object.prototype.toString.call(data.s.src)) {
                            case '[object String]':
                                // Assume that the given string is a URL to resolve
                                getDataAjax(data.s.src, payload);
                                break;
                            case '[object Function]':
                                // Call the source function
                                data.s.src(data.searchterm, data.returnSource);
                                break;
                            case '[object Array]':
                                var datasrc = data.s.src,
                                re = new RegExp(data.searchterm.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), 'i'),
                                results = [], i, line;
                                for (i = 0; i < datasrc.length; i++) {
                                    line = getAsObject(datasrc[i]);
                                    if (line.value.match(re)) {
                                        results[results.length] = line;
                                    }
                                }
                                if (data.s.onsearch.call(T, results) === false) {
                                    return false;
                                }
                                data.render(results);
                                data.afterRender();
                                break;
                        }
                    }, +data.s.delay);
                } else {
                    // No need to show the results because they are now wrong
                    clear = true;
                    data.close();
                }
                T.data('streamcomplete', data);
            });

            /**
             * Conform a line in an array so that it is an object with at least the propeties id, value and label
             * @param {mixed} line The line
             * @returns {object} An object with at least the properties id, value and label
             */
            function getAsObject(line) {
                switch (Object.prototype.toString.call(line)) {
                    case '[object String]':
                        // Make the string into an object
                        line = {id: i, value: line};
                        break;
                }
                if (!line.label && line.value) {
                    line.label = line.value;
                }
                if (!line.value && line.label) {
                    line.value = line.label;
                }
                return line;
            }

            /**
             * Get data for the autocomplete via AJAX
             * @param {string} url The url to get the AJAX results from
             * @param {object(plain)} payload The payload to pass to as post data
             */
            var getDataAjax = function (url, payload) {
                if (ajax) {
                    // There is a running ajax request
                    ajax.abort();
                }
                ajax = $.ajax({
                    url: url,
                    type: 'post',
                    dataType: 'json',
                    beforeSend: function (e) {
                        data.s.onbeforeajaxsearch.call(T, e);
                    },
                    data: {payload: JSON.stringify(payload)}
                }).always(function () {
                    ajax = null;
                }).done(function (e) {
                    if (e.result === 'OK') {
                        if (clear) {
                            // A clear was called during the request
                            clear = false;
                            return;
                        }
                        if (data.s.onresponse.call(T, e) === false) {
                            return false;
                        };
                        searchinterval = false;
                        if (data.s.onsearch.call(T, e.data) === false) {
                            return false;
                        }
                        data.render(e.data);
                        data.afterRender();
                    } else {
                        data.s.onerror.call(T, e);
                    }
                }).fail(function (e) {
                    data.s.onajaxerror.call(T, e);
                });
            };

            /**
             * Perform a strict comparison with object values to determine whether a value exists in an object
             * @param {object} obj The object to look in
             * @param {mixed} val  The value to search for
             * @returns {Boolean} True if the value is in the object
             */
            var inObj = function (obj, val) {
                for (var x in obj) {
                    if (obj[x] === val) {
                        return true;
                    }
                }
                return false;
            };

            /**
             * Process keyboard navigation
             * @param {int} which The id of the key that was pressed
             * @returns {Boolean} False if the navigation require
             */
            var keyboardAction = function (which) {
                var resultlist = $('.streamcomplete-result'),
                len = resultlist.length;
                switch (which) {
                    case keycodes.UP:
                        selectpos = (selectpos - 1 < 0 ? len : selectpos) - 1;
                        $('.streamcomplete-result-hover').removeClass('streamcomplete-result-hover');
                        $(resultlist[selectpos]).addClass('streamcomplete-result-hover');
                        return false;
                    case keycodes.DOWN:
                        selectpos = selectpos + 1 === len ? 0 : selectpos + 1;
                        $('.streamcomplete-result-hover').removeClass('streamcomplete-result-hover');
                        $(resultlist[selectpos]).addClass('streamcomplete-result-hover');
                        return false;
                    case keycodes.SPACE:
                    case keycodes.ENTER:
                    case keycodes.TAB:
                        var res = $('.streamcomplete-result-hover');
                        if (res.length) {
                            $('.streamcomplete-result-hover').removeClass('streamcomplete-result-hover');
                            data.close({target: res[0]});
                            return false;
                        }
                        return true;
                    case keycodes.ESC:
                        var res = $('.streamcomplete-result-hover');
                        if (res.length) {
                            selectpos = -1;
                            $('.streamcomplete-result-hover').removeClass('streamcomplete-result-hover');
                            return false;
                        }
                        return true;
                }
            };

            // Call user events longhand: this will allow a user to update opts successfully
            var funcs = ['focusin', 'focusout'];
            for (var i = 0; i < funcs.length; i++) {
                var funcname = funcs[i]; // E.g. focusin, change
                T[funcname](function (e) {
                    var scdata = $(this).data('streamcomplete');
                    if (Object.prototype.toString.call(scdata.s['on' + e.type]) === '[object Function]') {
                        scdata.s['on' + e.type].call(this, e);
                    }
                });
            }
            T.data('streamcomplete', data);
            draw();
            data.s.oninit.call(T);
            return T;
        },
        /**
         * Set the value for this autocomplete
         * @param {object} data An object with at least two properties, value (the human readable value for the input) and id
         *  (the system value). Any more properties will be added into data attributes of the given key
         * @returns {jQuery}
         */
        setValue: function (data) {
            // Test to see whether the plugin has been initialised here first
            var T = this;
            if (T.length > 1) {
                T.each(function () {
                    $(this).streamComplete('clearValue');
                });
                return T;
            }
            var scdata = T.data('streamcomplete');
            if (!scdata) {
                throw ex('InstanceError', "A call to 'setValue' on an uninitialised object");
            }
            T[0].value = data.value;
            T.data('value', data.id);
            // Add in data attributes for all of the other ones
            for (var x in data) {
                if (x !== 'id' && x !== 'value') {
                    T.data(x, data[x]);
                }
            }
            return T.change();
        },
        /**
         * Clear the value for this autocomplete
         * @param {array} properties An array of properties to remove
         * @returns {jQuery}
         */
        clearValue: function (properties) {
            var T = this;
            if (T.length > 1) {
                T.each(function () {
                    $(this).streamComplete('clearValue');
                });
                return T;
            }
            // Test to see whether the plugin has been initialised here first
            var scdata = T.data('streamcomplete'),
            i;
            if (!scdata) {
                throw ex('InstanceError', "A call to 'setValue' on an uninitialised object");
            }
            T[0].value = '';
            T.data('value', '');
            for (i = 0; i < (properties || []).length; i++) {
                this.data(properties[i], '');
            }
            return this.change();
        },
        /**
         * Update options for this autocomplete
         * @param {object} opts An object with properties that could have been supplied at plugin initialisation
         * @returns {jQuery}
         */
        updateOpts: function (opts) {
            var T = this;
            if (T.length > 1) {
                T.each(function () {
                    $(this).streamComplete('updateOpts', opts);
                });
                return T;
            }
            var scdata = this.data('streamcomplete');
            if (!scdata) {
                throw ex('InstanceError', "A call to 'setValue' on an uninitialised object");
            }
            scdata.s = $.extend(scdata.s, opts);
            T.data('streamcomplete', scdata);
            return this;
        }
    };

    /**
     * StreamConfirm exception handler
     * @param {string} exceptiontype The name of the exception to replace xxx in the string "Uncaught StreamComplete::xxx - message"
     * @param {string} message The exception message
     * @returns {StreamComplete::Exception}
     */
    function ex(exceptiontype, message) {
        return {
            name: 'StreamComplete::' + exceptiontype,
            level: "Cannot continue",
            message: message,
            htmlMessage: message,
            toString: function() {
                return ['StreamComplete::', exceptiontype, ' - ', message].join('');
            }
        };
    };

    /**
     *
     * @returns {undefined}
     */
    function draw() {
        if ($('.streamcomplete-body').length) {
            // The body has already been drawn
            return;
        }
        $('body').append('

');
    }

    $.fn.streamComplete = function(methodOrOpts) {
        var T = this;
        if (methods[methodOrOpts]) {
            // The first option passed is a method, therefore call this method
            return methods[methodOrOpts].apply(T, Array.prototype.slice.call(arguments, 1));
        } else if (Object.prototype.toString.call(methodOrOpts) === '[object Object]' || !methodOrOpts) {
            // The default action is to call the init function
            return methods.init.apply(T, arguments);
        } else {
            // The user has passed us something dodgy, throw an error
            $.error(['The method ', methodOrOpts, ' does not exist'].join(''));
        }
    };

})(jQuery, 0, this, this.document);
<commit_msg>Bug Fixes.<commit_after>(function ($, count, window, document) {
    "use strict";
    var ajax = null,
    ef = function () {return;},
    methods = {
        init: function (opts) {
            var T = this,
            data = {
                instanceid: ++count,
                s: $.fn.extend({
                    delay: 250,
                    minlength: 2,
                    onajaxerror: ef,
                    onbeforeajaxsearch: ef,
                    onbeforesearch: ef,
                    onclose: ef,
                    onerror: ef,
                    oninit: ef,
                    onresponse: ef,
                    onsearch: ef,
                    onselect: ef,
                    src: []
                }, opts),
                searchterm: null
            },
            searchinterval = false,
            clear = false,
            keycodes = {
                DOWN: 40,
                ENTER: 13,
                SPACE: 32,
                TAB: 9,
                UP: 38,
                ESC: 27
            },
            selectpos = -1,
            cancelkeypress = false;
            if (!T.length || T.data('streamcomplete')) {
                // There are no elements or this object has already been initialised
                return T;
            }
            if (T.length > 1) {
                T.each(function () {
                    $(this).streamComplete(opts);
                });
                return T;
            }

            /**
             * Render a single result
             * @param {object(plain)} desc An object with necessary properties. The obejct MUST have the properties 'id' and 'value'
             * @returns {Element} The rendered element, in this case a div
             */
            data.renderResult = function (desc) {
                var elem = document.createElement('div');
                $(elem).html(desc.label).data('sc-desc', desc).addClass('streamcomplete-result');
                return elem;
            };

            /**
             * Render the full autocomplete
             * @param {array} results An array of objects in the form [{id: int, value: value}, ...], or an array of values
             */
            data.render = function (results) {
                var output = $('.streamcomplete-body').show(),
                offset = T.offset(),
                rect = T[0].getBoundingClientRect();
                $('.streamcomplete-body').data({'sc-results': results});
                output.css({width: rect.width, top: offset.top + rect.height, left: offset.left}).empty();
                for (var i = 0; results ? i < results.length : 0; i++) {
                    var desc = getAsObject(results[i]);

                    var res = data.renderResult(desc);
                    output.append(res);
                }
            };

            /**
             * The after render function. Seperate from the render function because the render function can be customised, whereas
             *  everything in this function is more or less always required. Makes customising the output easier
             */
            data.afterRender = function () {
                var output = $('.streamcomplete-body'),
                results = output.data('sc-results');
                output.data('sc-results', results);
                $('body').unbind('click.streamcomplete').bind('click.streamcomplete', data.close);
            };

            /**
             * Event after a user has made a selection
             * @param {Event} e
             */
            data.close = function (e) {
                var selection = null;
                if (e) {
                    // This function was called as a result of an event
                    var target = $(e.target);
                    var sc = target.data('streamcomplete')
                    if (target.closest('.streamcomplete-body').length) {
                        // The user has clicked on one of the selections
                        var selection = target.data('sc-desc');
                        if (data.s.onselect.call(T, selection) === false) {
                            // The caller has prevented continuation
                            return false;
                        }
                        T[0].value = selection.value;
                        T.data('value', selection.id);
                    } else if (sc && sc.instanceid === data.instanceid) {
                        e.preventDefault();
                        return false;
                    }
                    $('body').unbind('click.streamcomplete');
                }
                data.s.onclose.call(T, {selection: selection, results: $('.streamcomplete-body').hide().data('sc-results') || []});
            };

            T.keydown(function (e) {
                // If there is need to return false, then the keyboard event listener has to be onkeydown.
                if (inObj(keycodes, e.which)) {
                    // The user is navigating using the keyboard
                    var ans = keyboardAction(e.which);
                    if (ans === false) {
                        // The keyboard action returned false, so prevent the default action
                        e.preventDefault();
                        cancelkeypress = true;
                        return false;
                    }
                }
            });

            /**
             * A callback if the source parameter is a function
             * @param {array} results An array of results
             */
            data.returnSource = function (results) {
                if (data.s.onsearch.call(T, results) === false) {
                    return false;
                }
                data.render(results);
                data.afterRender();
            };

            T.focus(function () {
                var curdata = $('.streamcomplete-body').data('sc-results');
                if (curdata && curdata.length) {
                    data.render(curdata);
                    data.afterRender();
                }
            });

            T.keyup(function () {
                if (cancelkeypress) {
                    // The keydown event listener says that the keyup event should not be registered
                    cancelkeypress = false;
                    return false;
                }
                data.searchterm = this.value;
                var payload = {
                    term: data.searchterm
                };
                selectpos = -1;
                if (data.s.onbeforesearch.call(T, payload) === false) {
                    // The caller cancelled the search: return
                    return false;
                }
                if (this.value.length >= +data.s.minlength) {
                    clear = false;
                    if (searchinterval !== false) {
                        // Clear the search interval
                        window.clearTimeout(searchinterval);
                    }
                    searchinterval = window.setTimeout(function () {
                        // Only perform searches in intervals as specified by the settings
                        if (clear) {
                            // A clear was called during the timeout
                            clear = false;
                            return;
                        }
                        $('.streamcomplete-body').data({'sc-results': []});
                        switch (Object.prototype.toString.call(data.s.src)) {
                            case '[object String]':
                                // Assume that the given string is a URL to resolve
                                getDataAjax(data.s.src, payload);
                                break;
                            case '[object Function]':
                                // Call the source function
                                data.s.src(data.searchterm, data.returnSource);
                                break;
                            case '[object Array]':
                                var datasrc = data.s.src,
                                re = new RegExp(data.searchterm.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"), 'i'),
                                results = [], i, line;
                                for (i = 0; i < datasrc.length; i++) {
                                    line = getAsObject(datasrc[i]);
                                    if (line.value.match(re)) {
                                        results[results.length] = line;
                                    }
                                }
                                if (data.s.onsearch.call(T, results) === false) {
                                    return false;
                                }
                                data.render(results);
                                data.afterRender();
                                break;
                        }
                    }, +data.s.delay);
                } else {
                    // No need to show the results because they are now wrong
                    clear = true;
                    data.close();
                }
                T.data('streamcomplete', data);
            });

            /**
             * Conform a line in an array so that it is an object with at least the propeties id, value and label
             * @param {mixed} line The line
             * @returns {object} An object with at least the properties id, value and label
             */
            function getAsObject(line) {
                switch (Object.prototype.toString.call(line)) {
                    case '[object String]':
                        // Make the string into an object
                        line = {id: i, value: line};
                        break;
                }
                if (!line.label && line.value) {
                    line.label = line.value;
                }
                if (!line.value && line.label) {
                    line.value = line.label;
                }
                return line;
            }

            /**
             * Get data for the autocomplete via AJAX
             * @param {string} url The url to get the AJAX results from
             * @param {object(plain)} payload The payload to pass to as post data
             */
            var getDataAjax = function (url, payload) {
                if (ajax) {
                    // There is a running ajax request
                    ajax.abort();
                }
                ajax = $.ajax({
                    url: url,
                    type: 'post',
                    dataType: 'json',
                    beforeSend: function (e) {
                        data.s.onbeforeajaxsearch.call(T, e);
                    },
                    data: {payload: JSON.stringify(payload)}
                }).always(function () {
                    ajax = null;
                }).done(function (e) {
                    if (e.result === 'OK') {
                        if (clear) {
                            // A clear was called during the request
                            clear = false;
                            return;
                        }
                        if (data.s.onresponse.call(T, e) === false) {
                            return false;
                        };
                        searchinterval = false;
                        if (data.s.onsearch.call(T, e.data) === false) {
                            return false;
                        }
                        data.render(e.data);
                        data.afterRender();
                    } else {
                        data.s.onerror.call(T, e);
                    }
                }).fail(function (e) {
                    data.s.onajaxerror.call(T, e);
                });
            };

            /**
             * Perform a strict comparison with object values to determine whether a value exists in an object
             * @param {object} obj The object to look in
             * @param {mixed} val  The value to search for
             * @returns {Boolean} True if the value is in the object
             */
            var inObj = function (obj, val) {
                for (var x in obj) {
                    if (obj[x] === val) {
                        return true;
                    }
                }
                return false;
            };

            /**
             * Process keyboard navigation
             * @param {int} which The id of the key that was pressed
             * @returns {Boolean} False if the navigation require
             */
            var keyboardAction = function (which) {
                var resultlist = $('.streamcomplete-result'),
                len = resultlist.length;
                switch (which) {
                    case keycodes.UP:
                        selectpos = (selectpos - 1 < 0 ? len : selectpos) - 1;
                        $('.streamcomplete-result-hover').removeClass('streamcomplete-result-hover');
                        $(resultlist[selectpos]).addClass('streamcomplete-result-hover');
                        return false;
                    case keycodes.DOWN:
                        selectpos = selectpos + 1 === len ? 0 : selectpos + 1;
                        $('.streamcomplete-result-hover').removeClass('streamcomplete-result-hover');
                        $(resultlist[selectpos]).addClass('streamcomplete-result-hover');
                        return false;
                    case keycodes.SPACE:
                    case keycodes.ENTER:
                    case keycodes.TAB:
                        var res = $('.streamcomplete-result-hover');
                        if (res.length) {
                            $('.streamcomplete-result-hover').removeClass('streamcomplete-result-hover');
                            data.close({target: res[0]});
                            return false;
                        }
                        return true;
                    case keycodes.ESC:
                        var res = $('.streamcomplete-result-hover');
                        if (res.length) {
                            selectpos = -1;
                            $('.streamcomplete-result-hover').removeClass('streamcomplete-result-hover');
                            return false;
                        }
                        return true;
                }
            };

            // Call user events longhand: this will allow a user to update opts successfully
            var funcs = ['focusin', 'focusout'];
            for (var i = 0; i < funcs.length; i++) {
                var funcname = funcs[i]; // E.g. focusin, change
                T[funcname](function (e) {
                    var scdata = $(this).data('streamcomplete');
                    if (Object.prototype.toString.call(scdata.s['on' + e.type]) === '[object Function]') {
                        scdata.s['on' + e.type].call(this, e);
                    }
                });
            }
            T.data('streamcomplete', data);
            draw();
            data.s.oninit.call(T);
            return T;
        },
        /**
         * Set the value for this autocomplete
         * @param {object} data An object with at least two properties, value (the human readable value for the input) and id
         *  (the system value). Any more properties will be added into data attributes of the given key
         * @returns {jQuery}
         */
        setValue: function (data) {
            // Test to see whether the plugin has been initialised here first
            var T = this;
            if (T.length > 1) {
                T.each(function () {
                    $(this).streamComplete('clearValue');
                });
                return T;
            }
            var scdata = T.data('streamcomplete');
            if (!scdata) {
                throw ex('InstanceError', "A call to 'setValue' on an uninitialised object");
            }
            T[0].value = data.value;
            T.data('value', data.id);
            // Add in data attributes for all of the other ones
            for (var x in data) {
                if (x !== 'id' && x !== 'value') {
                    T.data(x, data[x]);
                }
            }
            return T.change();
        },
        /**
         * Clear the value for this autocomplete
         * @param {array} properties An array of properties to remove
         * @returns {jQuery}
         */
        clearValue: function (properties) {
            var T = this;
            if (T.length > 1) {
                T.each(function () {
                    $(this).streamComplete('clearValue');
                });
                return T;
            }
            // Test to see whether the plugin has been initialised here first
            var scdata = T.data('streamcomplete'),
            i;
            if (!scdata) {
                throw ex('InstanceError', "A call to 'setValue' on an uninitialised object");
            }
            T[0].value = '';
            T.data('value', '');
            for (i = 0; i < (properties || []).length; i++) {
                this.data(properties[i], '');
            }
            return this.change();
        },
        /**
         * Update options for this autocomplete
         * @param {object} opts An object with properties that could have been supplied at plugin initialisation
         * @returns {jQuery}
         */
        updateOpts: function (opts) {
            var T = this;
            if (T.length > 1) {
                T.each(function () {
                    $(this).streamComplete('updateOpts', opts);
                });
                return T;
            }
            var scdata = this.data('streamcomplete');
            if (!scdata) {
                throw ex('InstanceError', "A call to 'setValue' on an uninitialised object");
            }
            scdata.s = $.extend(scdata.s, opts);
            T.data('streamcomplete', scdata);
            return this;
        }
    };

    /**
     * StreamConfirm exception handler
     * @param {string} exceptiontype The name of the exception to replace xxx in the string "Uncaught StreamComplete::xxx - message"
     * @param {string} message The exception message
     * @returns {StreamComplete::Exception}
     */
    function ex(exceptiontype, message) {
        return {
            name: 'StreamComplete::' + exceptiontype,
            level: "Cannot continue",
            message: message,
            htmlMessage: message,
            toString: function() {
                return ['StreamComplete::', exceptiontype, ' - ', message].join('');
            }
        };
    };

    /**
     *
     * @returns {undefined}
     */
    function draw() {
        if ($('.streamcomplete-body').length) {
            // The body has already been drawn
            return;
        }
        $('body').append('

');
    }

    $.fn.streamComplete = function(methodOrOpts) {
        var T = this;
        if (methods[methodOrOpts]) {
            // The first option passed is a method, therefore call this method
            return methods[methodOrOpts].apply(T, Array.prototype.slice.call(arguments, 1));
        } else if (Object.prototype.toString.call(methodOrOpts) === '[object Object]' || !methodOrOpts) {
            // The default action is to call the init function
            return methods.init.apply(T, arguments);
        } else {
            // The user has passed us something dodgy, throw an error
            $.error(['The method ', methodOrOpts, ' does not exist'].join(''));
        }
    };

})(jQuery, 0, this, this.document);
<|endoftext|>


<commit_before>const isTrue = require('./isTrue')
const parseLength = require('./parseLength')

const transforms = {
  stroke: {
    type: 'boolean'
  },
  fill: {
    type: 'boolean'
  },
  textRepeat: {
    type: 'boolean'
  },
  textBelow: {
    type: 'boolean'
  },
  noClip: {
    type: 'boolean'
  },
  width: {
    rename: 'weight',
    type: 'length'
  },
  opacity: {
    type: 'float'
  },
  fillOpacity: {
    type: 'float'
  },
  offset: {
    type: 'length'
  }
}

function styleToLeaflet (style, twigData) {
  const ret = JSON.parse(JSON.stringify(style))

  for (let k in ret) {
    let value = ret[k]

    if (k in transforms) {
      const transform = transforms[k]

      switch (transform.type) {
        case 'boolean':
          value = isTrue(ret[k])
          break
        case 'float':
          value = parseFloat(ret[k])
          break
        case 'length':
          value = parseLength(ret[k], twigData.map.metersPerPixel)
          break
      }

      if (transform.rename) {
        delete ret[k]
        k = transform.rename
      }
    }

    ret[k] = value
  }

  return ret
}

module.exports = styleToLeaflet
<commit_msg>styleToLeaflet: bugfix, avoid error when twigdata or twigdata.map is not defined<commit_after>const isTrue = require('./isTrue')
const parseLength = require('./parseLength')

const transforms = {
  stroke: {
    type: 'boolean'
  },
  fill: {
    type: 'boolean'
  },
  textRepeat: {
    type: 'boolean'
  },
  textBelow: {
    type: 'boolean'
  },
  noClip: {
    type: 'boolean'
  },
  width: {
    rename: 'weight',
    type: 'length'
  },
  opacity: {
    type: 'float'
  },
  fillOpacity: {
    type: 'float'
  },
  offset: {
    type: 'length'
  }
}

function styleToLeaflet (style, twigData) {
  const ret = JSON.parse(JSON.stringify(style))

  for (let k in ret) {
    let value = ret[k]

    if (k in transforms) {
      const transform = transforms[k]

      switch (transform.type) {
        case 'boolean':
          value = isTrue(ret[k])
          break
        case 'float':
          value = parseFloat(ret[k])
          break
        case 'length':
          if (twigData && twigData.map) {
            value = parseLength(ret[k], twigData.map.metersPerPixel)
          } else {
            value = parseFloat(ret[k])
          }
          break
      }

      if (transform.rename) {
        delete ret[k]
        k = transform.rename
      }
    }

    ret[k] = value
  }

  return ret
}

module.exports = styleToLeaflet
<|endoftext|>


<commit_before>d3plus.styles.default = {
  "background": "#ffffff",
  "color": {
    "heatmap": ["#27366C", "#7B91D3", "#9ED3E3", "#F3D261", "#B35C1E", "#843012"],
    "missing": "#eeeeee",
    "range": ["#ff0000","#888888","#00ff00"]
  },
  "data": {
    "donut": {
      "size": 0.35
    },
    "opacity": 0.9,
    "stroke": {
      "width": 1
    }
  },
  "edges": {
    "arrows": 8,
    "color": "#d0d0d0",
    "opacity": 1,
    "width": 1
  },
  "footer": {
    "font-align": "center",
    "font-color": "#444",
    "font-family": "sans-serif",
    "font-size": 10,
    "font-weight": "normal",
    "padding": 5,
    "position": "bottom",
    "text-decoration": "none",
    "text-transform": "none"
  },
  "font": {
    "family": "sans-serif",
    "weight": "normal"
  },
  "group": {
    "background": true,
  },
  "highlight": {
    "focus": "#444444",
    "primary": "#cc0000",
    "secondary": "#ffdddd"
  },
  "labels": {
    "align": "middle",
    "padding": 7,
    "segments": 2,
    "font": {
      "family": "sans-serif",
      "weight": "normal",
      "size": 10
    }
  },
  "legend": {
    "align": "middle",
    "gradient": {
      "height": 10
    },
    "label": {
      "color": "#444",
      "family": "sans-serif",
      "weight": "normal",
      "size": 12
    },
    "padding": 5,
    "size": [10,30],
    "tick": {
      "align": "middle",
      "color": "#444",
      "family": "sans-serif",
      "weight": "normal",
      "size": 10
    }
  },
  "link": {
    "font-color": "#444",
    "font-family": "sans-serif",
    "font-weight": "normal",
    "hover": {
      "font-color": "#444",
      "font-family": "sans-serif",
      "font-weight": "normal",
      "text-decoration": "underline",
      "text-transform": "none"
    },
    "text-decoration": "none",
    "text-transform": "none"
  },
  "message": {
    "font-color": "#444",
    "font-family": "sans-serif",
    "font-size": 18,
    "font-weight": "normal",
    "opacity": 0.75,
    "padding": 10,
    "text-decoration": "none",
    "text-transform": "none"
  },
  "rendering": "crispEdges",
  "ticks": {
    "color": "#ccc",
    "font": {
      "color": "#888",
      "size": 12
    },
    "size": 10,
    "width": 1
  },
  "timeline": {
    "align": "middle",
    "background": "#eeeeee",
    "brush": {
      "color": "#444",
      "opacity": 0.2
    },
    "handles": {
      "color": "#888",
      "hover": "#aaa",
      "size": 3
    },
    "height": 20,
    "label": {
      "color": "#444",
      "family": "sans-serif",
      "weight": "normal",
      "size": 12
    },
    "padding": 5,
    "tick": {
      "align": "middle",
      "color": "#444",
      "family": "sans-serif",
      "weight": "normal",
      "size": 10
    }
  },
  "timing": {
    "mouseevents": 60,
    "transitions": 600
  },
  "title": {
    "font-align": "center",
    "font-color": "#444",
    "font-family": "sans-serif",
    "font-size": 18,
    "font-weight": "normal",
    "height": null,
    "padding": 2,
    "position": "top",
    "sub": {
      "font-align": "center",
      "font-color": "#444",
      "font-family": "sans-serif",
      "font-size": 13,
      "font-weight": "normal",
      "padding": 1,
      "position": "top",
      "text-decoration": "none",
      "text-transform": "none"
    },
    "text-decoration": "none",
    "text-transform": "none",
    "total": {
      "font-align": "center",
      "font-color": "#444",
      "font-family": "sans-serif",
      "font-size": 13,
      "font-weight": "normal",
      "padding": 1,
      "position": "top",
      "text-decoration": "none",
      "text-transform": "none"
    },
    "width": null
  },
  "tooltip": {
    "anchor": "top center",
    "background": "white",
    "curtain": {
      "color": "#ffffff",
      "opacity": 0.8
    },
    "font": {
      "color": "#444",
      "family": "sans-serif",
      "size": 12,
      "weight": "normal"
    },
    "large": 250,
    "small": 200
  }
}
<commit_msg>updated heat map and range color scales in default style<commit_after>d3plus.styles.default = {
  "background": "#ffffff",
  "color": {
    "heatmap": ["#27366C", "#7B91D3", "#9ED3E3", "#F3D261", "#C9853A", "#D74B03"],
    "missing": "#eeeeee",
    "range": ["#D74B03","#eeeeee","#94B153"]
  },
  "data": {
    "donut": {
      "size": 0.35
    },
    "opacity": 0.9,
    "stroke": {
      "width": 1
    }
  },
  "edges": {
    "arrows": 8,
    "color": "#d0d0d0",
    "opacity": 1,
    "width": 1
  },
  "footer": {
    "font-align": "center",
    "font-color": "#444",
    "font-family": "sans-serif",
    "font-size": 10,
    "font-weight": "normal",
    "padding": 5,
    "position": "bottom",
    "text-decoration": "none",
    "text-transform": "none"
  },
  "font": {
    "family": "sans-serif",
    "weight": "normal"
  },
  "group": {
    "background": true,
  },
  "highlight": {
    "focus": "#444444",
    "primary": "#cc0000",
    "secondary": "#ffdddd"
  },
  "labels": {
    "align": "middle",
    "padding": 7,
    "segments": 2,
    "font": {
      "family": "sans-serif",
      "weight": "normal",
      "size": 10
    }
  },
  "legend": {
    "align": "middle",
    "gradient": {
      "height": 10
    },
    "label": {
      "color": "#444",
      "family": "sans-serif",
      "weight": "normal",
      "size": 12
    },
    "padding": 5,
    "size": [10,30],
    "tick": {
      "align": "middle",
      "color": "#444",
      "family": "sans-serif",
      "weight": "normal",
      "size": 10
    }
  },
  "link": {
    "font-color": "#444",
    "font-family": "sans-serif",
    "font-weight": "normal",
    "hover": {
      "font-color": "#444",
      "font-family": "sans-serif",
      "font-weight": "normal",
      "text-decoration": "underline",
      "text-transform": "none"
    },
    "text-decoration": "none",
    "text-transform": "none"
  },
  "message": {
    "font-color": "#444",
    "font-family": "sans-serif",
    "font-size": 18,
    "font-weight": "normal",
    "opacity": 0.75,
    "padding": 10,
    "text-decoration": "none",
    "text-transform": "none"
  },
  "rendering": "crispEdges",
  "ticks": {
    "color": "#ccc",
    "font": {
      "color": "#888",
      "size": 12
    },
    "size": 10,
    "width": 1
  },
  "timeline": {
    "align": "middle",
    "background": "#eeeeee",
    "brush": {
      "color": "#444",
      "opacity": 0.2
    },
    "handles": {
      "color": "#888",
      "hover": "#aaa",
      "size": 3
    },
    "height": 20,
    "label": {
      "color": "#444",
      "family": "sans-serif",
      "weight": "normal",
      "size": 12
    },
    "padding": 5,
    "tick": {
      "align": "middle",
      "color": "#444",
      "family": "sans-serif",
      "weight": "normal",
      "size": 10
    }
  },
  "timing": {
    "mouseevents": 60,
    "transitions": 600
  },
  "title": {
    "font-align": "center",
    "font-color": "#444",
    "font-family": "sans-serif",
    "font-size": 18,
    "font-weight": "normal",
    "height": null,
    "padding": 2,
    "position": "top",
    "sub": {
      "font-align": "center",
      "font-color": "#444",
      "font-family": "sans-serif",
      "font-size": 13,
      "font-weight": "normal",
      "padding": 1,
      "position": "top",
      "text-decoration": "none",
      "text-transform": "none"
    },
    "text-decoration": "none",
    "text-transform": "none",
    "total": {
      "font-align": "center",
      "font-color": "#444",
      "font-family": "sans-serif",
      "font-size": 13,
      "font-weight": "normal",
      "padding": 1,
      "position": "top",
      "text-decoration": "none",
      "text-transform": "none"
    },
    "width": null
  },
  "tooltip": {
    "anchor": "top center",
    "background": "white",
    "curtain": {
      "color": "#ffffff",
      "opacity": 0.8
    },
    "font": {
      "color": "#444",
      "family": "sans-serif",
      "size": 12,
      "weight": "normal"
    },
    "large": 250,
    "small": 200
  }
}
<|endoftext|>


<commit_before>function startApp() {
    showHideMenuLinks();
    showHomeView();

    // Bind the navigation menu links
    $("#linkHome").click(showHomeView);
    $("#linkLogin").click(showLoginView);
    $("#linkRegister").click(showRegisterView);
    $("#linkListAds").click(listAdverts);
    $("#linkLogout").click(logoutUser);

    // Bind the form submit buttons
    $("#buttonLoginUser").click(loginUser);
    $("#buttonRegisterUser").click(registerUser);

    const kinveyBaseUrl = "https://mock.api.com/";
    const kinveyAppKey = "kid_rk";
    const kinveyAppSecret = "736804a668";

    function showView(viewName) {
        // Hide all views and show the selected view only
        $('main > section').hide();
        $('#' + viewName).show();
    }

    function showHideMenuLinks() {
        $("#linkHome").show();
        if (sessionStorage.getItem('authToken') === null) {
            // No logged in user
            $("#linkLogin").show();
            $("#linkRegister").show();
            $("#linkListAds").hide();
            $("#linkLogout").hide();
        } else {
            // We have logged in user
            $("#linkLogin").hide();
            $("#linkRegister").hide();
            $("#linkListAds").show();
            $("#linkLogout").show();
        }
    }

    function showHomeView() {
        showView('viewHome');
    }

    function showLoginView() {
        showView('viewLogin');
        $('#formLogin').trigger('reset');
    }

    function showRegisterView() {
        $('#formRegister').trigger('reset');
        showView('viewRegister');
    }
    // user/login
    function loginUser() {
        const kinveyLoginUrl = kinveyBaseUrl + "user/" + kinveyAppKey + "/login";
        const kinveyAuthHeaders = {
            'Authorization': "Basic " + btoa(kinveyAppKey + ":" + kinveyAppSecret),
        };
        let userData = {
            username: $('#formLogin input[name=username]').val(),
            password: $('#formLogin input[name=passwd]').val()
        };

        $.ajax({
            method: "POST",
            url: kinveyLoginUrl,
            headers: kinveyAuthHeaders,
            data: userData,
            success: loginSuccess
        });

        function loginSuccess(userInfo) {
            saveAuthInSession(userInfo);
            showHideMenuLinks();
            listAdverts();
        }
    }

    // user/login
    function loginUser() {
        const kinveyLoginUrl = "https://mock.backend.com/user/kid_rk/login";
        const kinveyAuthHeaders = {
            'Authorization': "Basic " + btoa("kid_rk:736804a668"),
        };
        let userData = {
            username: $('#formLogin input[name=username]').val(),
            password: $('#formLogin input[name=passwd]').val()
        };

        $.ajax({
            method: "POST",
            url: kinveyLoginUrl,
            headers: kinveyAuthHeaders,
            data: userData,
            success: loginSuccess
        });

        function loginSuccess(userInfo) {
            saveAuthInSession(userInfo);
            showHideMenuLinks();
            showHomeView();
        }
    }

    function saveAuthInSession(userInfo) {
        let userAuth = userInfo._kmd.authtoken;
        sessionStorage.setItem('authToken', userAuth);
        let userId = userInfo._id;
        sessionStorage.setItem('userId', userId);
    }

    // user/register
    function registerUser() {
        const kinveyRegisterUrl = kinveyBaseUrl + "user/" + kinveyAppKey + "/";
        const kinveyAuthHeaders = {
            'Authorization': "Basic " + btoa(kinveyAppKey + ":" + kinveyAppSecret),
        };

        let userData = {
            username: $('#formRegister input[name=username]').val(),
            password: $('#formRegister input[name=passwd]').val()
        };

        $.ajax({
            method: "POST",
            url: kinveyRegisterUrl,
            headers: kinveyAuthHeaders,
            data: userData,
            success: registerSuccess
        });

        function registerSuccess(userInfo) {
            console.log(userInfo);
            saveAuthInSession(userInfo);
            showHideMenuLinks();
            listAdverts();
        }
    }

    // user/logout
    function logoutUser() {
        sessionStorage.clear();
        $('#loggedInUser').text("");
        showHideMenuLinks();
        showHomeView();
    }

    // advertisement/all
    function listAdverts() {
        $('#ads').empty();
        showView('viewAds');

        const kinveyAdvertsUrl = kinveyBaseUrl + "appdata/" + kinveyAppKey + "/adverts";
        const kinveyAuthHeaders = {
            'Authorization': "Kinvey " + sessionStorage.getItem('authToken'),
        };
        $.ajax({
            method: "GET",
            url: kinveyAdvertsUrl,
            headers: kinveyAuthHeaders,
            success: loadAdvertsSuccess
        });

        function loadAdvertsSuccess(adverts) {
            if (adverts.length === 0) {
                $('#ads').text('No advertisements available.');
            } else {
                let advertsTable = $('
')
                    .append($('
').append(
                        'Title	',
                        'Publisher	',
                        'Date Published	',
                        'Price	')
                    );

                for (let advert of adverts) {
                    advertsTable.append($('
').append(
                        $('').text(advert.title),
                        $('').text(advert.publisher),
                        $('').text(advert.datePublished),
                        $('').text(advert.price)
                    ));
                }

                $('#ads').append(advertsTable);
            }
        }
    }
}<commit_msg>completed task 4.1<commit_after>function startApp() {

    if (sessionStorage.getItem('authToken') !== null) {
        let username = sessionStorage.getItem('username');
        $('#loggedInUser').text("Welcome, " + username + "!");
    }

    showHideMenuLinks();
    showHomeView();

    // Bind the navigation menu links
    $("#linkHome").click(showHomeView);
    $("#linkLogin").click(showLoginView);
    $("#linkRegister").click(showRegisterView);
    $("#linkListAds").click(listAdverts);
    $("#linkLogout").click(logoutUser);

    // Bind the form submit buttons
    $("#buttonLoginUser").click(loginUser);
    $("#buttonRegisterUser").click(registerUser);

    const kinveyBaseUrl = "https://mock.api.com/";
    const kinveyAppKey = "kid_rk";
    const kinveyAppSecret = "736804a668";

    function showView(viewName) {
        // Hide all views and show the selected view only
        $('main > section').hide();
        $('#' + viewName).show();
    }

    function showHideMenuLinks() {
        $("#linkHome").show();
        if (sessionStorage.getItem('authToken') === null) {
            // No logged in user
            $("#linkLogin").show();
            $("#linkRegister").show();
            $("#linkListAds").hide();
            $("#linkLogout").hide();
            $("#loggedInUser").hide();
        } else {
            // We have logged in user
            $("#linkLogin").hide();
            $("#linkRegister").hide();
            $("#linkListAds").show();
            $("#linkLogout").show();
            $("#loggedInUser").show();
        }
    }

    function showHomeView() {
        showView('viewHome');
    }

    function showLoginView() {
        showView('viewLogin');
        $('#formLogin').trigger('reset');
    }

    function showRegisterView() {
        $('#formRegister').trigger('reset');
        showView('viewRegister');
    }
    // user/login
    function loginUser() {
        const kinveyLoginUrl = kinveyBaseUrl + "user/" + kinveyAppKey + "/login";
        const kinveyAuthHeaders = {
            'Authorization': "Basic " + btoa(kinveyAppKey + ":" + kinveyAppSecret),
        };
        let userData = {
            username: $('#formLogin input[name=username]').val(),
            password: $('#formLogin input[name=passwd]').val()
        };

        $.ajax({
            method: "POST",
            url: kinveyLoginUrl,
            headers: kinveyAuthHeaders,
            data: userData,
            success: loginSuccess
        });

        function loginSuccess(userInfo) {
            saveAuthInSession(userInfo);
            showHideMenuLinks();
            listAdverts();
        }
    }

    // user/login
    function loginUser() {
        const kinveyLoginUrl = "https://mock.backend.com/user/kid_rk/login";
        const kinveyAuthHeaders = {
            'Authorization': "Basic " + btoa("kid_rk:736804a668"),
        };
        let userData = {
            username: $('#formLogin input[name=username]').val(),
            password: $('#formLogin input[name=passwd]').val()
        };

        $.ajax({
            method: "POST",
            url: kinveyLoginUrl,
            headers: kinveyAuthHeaders,
            data: userData,
            success: loginSuccess
        });

        function loginSuccess(userInfo) {
            saveAuthInSession(userInfo);
            showHideMenuLinks();
            showHomeView();
        }
    }

    function saveAuthInSession(userInfo) {
        let userAuth = userInfo._kmd.authtoken;
        sessionStorage.setItem('authToken', userAuth);
        let userId = userInfo._id;
        sessionStorage.setItem('userId', userId);
        let username = userInfo.username;
        sessionStorage.setItem('username', username);
        $('#loggedInUser').text("Welcome, " + username + "!");

    }

    // user/register
    function registerUser() {
        const kinveyRegisterUrl = kinveyBaseUrl + "user/" + kinveyAppKey + "/";
        const kinveyAuthHeaders = {
            'Authorization': "Basic " + btoa(kinveyAppKey + ":" + kinveyAppSecret),
        };

        let userData = {
            username: $('#formRegister input[name=username]').val(),
            password: $('#formRegister input[name=passwd]').val()
        };

        $.ajax({
            method: "POST",
            url: kinveyRegisterUrl,
            headers: kinveyAuthHeaders,
            data: userData,
            success: registerSuccess
        });

        function registerSuccess(userInfo) {
            console.log(userInfo);
            saveAuthInSession(userInfo);
            showHideMenuLinks();
            listAdverts();
        }
    }

    // user/logout
    function logoutUser() {
        sessionStorage.clear();
        $('#loggedInUser').text("");
        showHideMenuLinks();
        showHomeView();
    }

    // advertisement/all
    function listAdverts() {
        $('#ads').empty();
        showView('viewAds');

        const kinveyAdvertsUrl = kinveyBaseUrl + "appdata/" + kinveyAppKey + "/adverts";
        const kinveyAuthHeaders = {
            'Authorization': "Kinvey " + sessionStorage.getItem('authToken'),
        };
        $.ajax({
            method: "GET",
            url: kinveyAdvertsUrl,
            headers: kinveyAuthHeaders,
            success: loadAdvertsSuccess
        });

        function loadAdvertsSuccess(adverts) {
            if (adverts.length === 0) {
                $('#ads').text('No advertisements available.');
            } else {
                let advertsTable = $('
')
                    .append($('
').append(
                        'Title	',
                        'Publisher	',
                        'Date Published	',
                        'Price	')
                    );

                for (let advert of adverts) {
                    advertsTable.append($('
').append(
                        $('').text(advert.title),
                        $('').text(advert.publisher),
                        $('').text(advert.datePublished),
                        $('').text(advert.price)
                    ));
                }

                $('#ads').append(advertsTable);
            }
        }
    }
}<|endoftext|>


<commit_before>module.exports = function(robot) {

  robot.respond(/trello/i, function(res_r) {

    var express = require('express');

    var http = require('http')
    var OAuth = require('oauth').OAuth
    var url = require('url')

    /*
    /     Express Server Setup
    */
    var app = express();

    app.use(express.static('public'));

    var server = app.listen("/hubot/trello-oauth");
    //var server = app.listen("/hubot/trello-oauth");
    app.listen('/tmp/sock');
    // var server = app.listen(3000, function () {
    //   console.log('Server up and running...🏃🏃');
    //   console.log("Listening on port %s", server.address().port);
    // });

    /*
    /     OAuth Setup and Functions
    */
    const requestURL = "https://trello.com/1/OAuthGetRequestToken";
    const accessURL = "https://trello.com/1/OAuthGetAccessToken";
    const authorizeURL = "https://trello.com/1/OAuthAuthorizeToken";
    const appName = "anbot team";

    // Be sure to include your key and secret in 🗝.env ↖ over there.
    // You can get your key and secret from Trello at: https://trello.com/app-key
    const key = process.env.HUBOT_TRELLO_KEY;
    //const token = process.env.HUBOT_TRELLO_TOKEN;
    const secret = process.env.HUBOT_TRELLO_OAUTH;

    // Trello redirects the user here after authentication
    const loginCallback = "https://andreasbot.herokuapp.com/hubot/trello-oauth";

    // You should {"token": "tokenSecret"} pairs in a real application
    // Storage should be more permanent (redis would be a good choice)
    const oauth_secrets = {};

    const oauth = new OAuth(requestURL, accessURL, key, secret, "1.0A", loginCallback, "HMAC-SHA1")

    const login = function(req, res) {
      oauth.getOAuthRequestToken(function(error, token, tokenSecret, results){
        // console.log(`in getOAuthRequestToken - token: ${token}, tokenSecret: ${tokenSecret}, resultes ${JSON.stringify(results)}, error: ${JSON.stringify(error)}`);
        oauth_secrets[token] = tokenSecret;
        res.redirect(`${authorizeURL}?oauth_token=${token}&name=${appName}`);
      });
    };

    var callback = function(request, response) {
      const query = url.parse(request.url, true).query;
      const token = query.oauth_token;
      const tokenSecret = oauth_secrets[token];
      const verifier = query.oauth_verifier;
      oauth.getOAuthAccessToken(token, tokenSecret, verifier, function(error, accessToken, accessTokenSecret, results){
        // In a real app, the accessToken and accessTokenSecret should be stored
        console.log(`in getOAuthAccessToken - accessToken: ${accessToken}, accessTokenSecret: ${accessTokenSecret}, error: ${error}`);
        oauth.getProtectedResource("https://api.trello.com/1/members/me", "GET", accessToken, accessTokenSecret, function(error, data, response){
          // Now we can respond with data to show that we have access to your Trello account via OAuth
          console.log(`in getProtectedResource - accessToken: ${accessToken}, accessTokenSecret: ${accessTokenSecret}`);
          response.send(data)
        });
      });
    };

    /*
    /     Routes
    */

    res_r.send("localhost:3000");

    // app.get("/", function (request, response) {
    //   console.log(`GET '/' 🤠 ${Date()}`);
    //   response.send("
Oh, hello there!
Login with OAuth!");
    // });

    app.get("/", function (request, response) {
      console.log(`GET '/' ${Date()}`);
      login(request, response);
    });

    app.get("/callback", function (request, response) {
      console.log(`GET '/callback' ${Date()}`);
      callback(request, response);
    });

  })
}<commit_msg>update trello oauth<commit_after>module.exports = function(robot) {

  robot.respond(/trello/i, function(res_r) {

    var express = require('express');

    var http = require('http')
    var OAuth = require('oauth').OAuth
    var url = require('url')

    /*
    /     Express Server Setup
    */
    var app = express();

    app.use(express.static('public'));

    // var server = app.listen("/hubot/trello-oauth");
    // app.listen('/tmp/sock');
    // var server = app.listen(process.env.PORT || 3000, function () {
    //   console.log('Server up and running...🏃🏃');
    //   console.log("Listening on port %s", server.address().port);
    // });

    /*
    /     OAuth Setup and Functions
    */
    const requestURL = "https://trello.com/1/OAuthGetRequestToken";
    const accessURL = "https://trello.com/1/OAuthGetAccessToken";
    const authorizeURL = "https://trello.com/1/OAuthAuthorizeToken";
    const appName = "anbot team";

    // Be sure to include your key and secret in 🗝.env ↖ over there.
    // You can get your key and secret from Trello at: https://trello.com/app-key
    const key = process.env.HUBOT_TRELLO_KEY;
    //const token = process.env.HUBOT_TRELLO_TOKEN;
    const secret = process.env.HUBOT_TRELLO_OAUTH;

    // Trello redirects the user here after authentication
    const loginCallback = "https://andreasbot.herokuapp.com/hubot/trello-oauth";

    // You should {"token": "tokenSecret"} pairs in a real application
    // Storage should be more permanent (redis would be a good choice)
    const oauth_secrets = {};

    const oauth = new OAuth(requestURL, accessURL, key, secret, "1.0A", loginCallback, "HMAC-SHA1")

    const login = function(req, res) {
      oauth.getOAuthRequestToken(function(error, token, tokenSecret, results){
        // console.log(`in getOAuthRequestToken - token: ${token}, tokenSecret: ${tokenSecret}, resultes ${JSON.stringify(results)}, error: ${JSON.stringify(error)}`);
        oauth_secrets[token] = tokenSecret;
        res.redirect(`${authorizeURL}?oauth_token=${token}&name=${appName}`);
      });
    };

    var callback = function(request, response) {
      const query = url.parse(request.url, true).query;
      const token = query.oauth_token;
      const tokenSecret = oauth_secrets[token];
      const verifier = query.oauth_verifier;
      oauth.getOAuthAccessToken(token, tokenSecret, verifier, function(error, accessToken, accessTokenSecret, results){
        // In a real app, the accessToken and accessTokenSecret should be stored
        console.log(`in getOAuthAccessToken - accessToken: ${accessToken}, accessTokenSecret: ${accessTokenSecret}, error: ${error}`);
        oauth.getProtectedResource("https://api.trello.com/1/members/me", "GET", accessToken, accessTokenSecret, function(error, data, response){
          // Now we can respond with data to show that we have access to your Trello account via OAuth
          console.log(`in getProtectedResource - accessToken: ${accessToken}, accessTokenSecret: ${accessTokenSecret}`);
          response.send(data)
        });
      });
    };

    /*
    /     Routes
    */

    res_r.send("localhost:3000");

    // app.get("/", function (request, response) {
    //   console.log(`GET '/' 🤠 ${Date()}`);
    //   response.send("
Oh, hello there!
Login with OAuth!");
    // });

    app.get("/", function (request, response) {
      console.log(`GET '/' ${Date()}`);
      login(request, response);
    });

    app.get("/callback", function (request, response) {
      console.log(`GET '/callback' ${Date()}`);
      callback(request, response);
    });

  })
}<|endoftext|>


<commit_before>/**
 * Webpack production configuration (merged with common config).
 * it overrides webpack.common.js configuration and:
 * - Set mode to production (allow to minify css, js etc...)
 * - Add content hash to files name -> This way, each time bundled files content changed, file name will be different.
 *   This allow browsers to keep cached files which did not change
 * - Minify/Uglify JS and CSS files
 * - Split js into two bundles: vendors (js comming from node_modules) and bundle (our own js)
 *   This way, when we change our js, only our bundle is changed so browsers can keep vendors js in cache
 * - Allow Load css files (import './myCssFile.css') -> Css rules will be automatically added to index.html into a <style></style> tag.
 * - Allow to load fonts and images (import './myFont.eot'; import './someImage.jpg')
 * - Allow to load html angularjs partials (i.e all html files under src folder) as url ->
 *
 */
const {merge} = require('webpack-merge');
const common = require('./webpack.common');
const path = require('path');
const TerserPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');

module.exports = merge(common, {
  mode: 'production',
  devtool: 'source-map',
  output: {
    // Add a chunkhash to file name so it will not be cached by browsers when content changed
    filename: 'hslayers-ng.[name].js',
    path: path.resolve(__dirname, '../dist'),
    library: 'hslayers-ng',
    libraryTarget: 'umd',
  },
  plugins: [],
  optimization: {
    minimizer: [
      // JS minifier/uglifier
      new TerserPlugin({
        parallel: true,
        sourceMap: true,
        // Remove comments as well
        terserOptions: {output: {comments: false}},
      }),
      // CSS minifier
      new OptimizeCSSAssetsPlugin({
        cssProcessorPluginOptions: {
          preset: ['default', {discardComments: {removeAll: true}}],
        },
      }),
    ],
  },
  module: {
    rules: [
      // CSS files are bundled togethers
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
      {
        test: /\.(woff(2)?|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/,
        use: ['url-loader'],
      },
      // Load images as URLs
      {
        test: /\.(png|svg|jpg|gif)$/,
        use: [
          {
            loader: 'url-loader',
          },
        ],
      },
      // AngularJS templates are cached using cache template
      {
        test: /\.html$/,
        exclude: path.resolve(__dirname, '../src/index.html'),
        use: [
          {
            loader: 'html-loader',
            options: {minimize: true},
          },
        ],
      },
    ],
  },
});
<commit_msg>Add usedExports optimization to webpack.prod<commit_after>/**
 * Webpack production configuration (merged with common config).
 * it overrides webpack.common.js configuration and:
 * - Set mode to production (allow to minify css, js etc...)
 * - Add content hash to files name -> This way, each time bundled files content changed, file name will be different.
 *   This allow browsers to keep cached files which did not change
 * - Minify/Uglify JS and CSS files
 * - Split js into two bundles: vendors (js comming from node_modules) and bundle (our own js)
 *   This way, when we change our js, only our bundle is changed so browsers can keep vendors js in cache
 * - Allow Load css files (import './myCssFile.css') -> Css rules will be automatically added to index.html into a <style></style> tag.
 * - Allow to load fonts and images (import './myFont.eot'; import './someImage.jpg')
 * - Allow to load html angularjs partials (i.e all html files under src folder) as url ->
 *
 */
const {merge} = require('webpack-merge');
const common = require('./webpack.common');
const path = require('path');
const TerserPlugin = require('terser-webpack-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');

module.exports = merge(common, {
  mode: 'production',
  devtool: 'source-map',
  output: {
    // Add a chunkhash to file name so it will not be cached by browsers when content changed
    filename: 'hslayers-ng.[name].js',
    path: path.resolve(__dirname, '../dist'),
    library: 'hslayers-ng',
    libraryTarget: 'umd',
  },
  plugins: [],
  optimization: {
    usedExports: true,
    minimizer: [
      // JS minifier/uglifier
      new TerserPlugin({
        parallel: true,
        sourceMap: true,
        // Remove comments as well
        terserOptions: {output: {comments: false}},
      }),
      // CSS minifier
      new OptimizeCSSAssetsPlugin({
        cssProcessorPluginOptions: {
          preset: ['default', {discardComments: {removeAll: true}}],
        },
      }),
    ],
  },
  module: {
    rules: [
      // CSS files are bundled togethers
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
      {
        test: /\.(woff(2)?|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/,
        use: ['url-loader'],
      },
      // Load images as URLs
      {
        test: /\.(png|svg|jpg|gif)$/,
        use: [
          {
            loader: 'url-loader',
          },
        ],
      },
      // AngularJS templates are cached using cache template
      {
        test: /\.html$/,
        exclude: path.resolve(__dirname, '../src/index.html'),
        use: [
          {
            loader: 'html-loader',
            options: {minimize: true},
          },
        ],
      },
    ],
  },
});
<|endoftext|>