<commit_before>
var utils = require('./utils'),
    Parser = require('xmldom').DOMParser,
    SignedXml = require('xml-crypto').SignedXml,
    moment = require('moment');

var fs = require('fs');
var path = require('path');
var saml11 = fs.readFileSync(path.join(__dirname, 'saml20.template')).toString();

var NAMESPACE = 'urn:oasis:names:tc:SAML:2.0:assertion';

var algorithms = {
  signature: {
    'rsa-sha256': 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256',
    'rsa-sha1':  'http://www.w3.org/2000/09/xmldsig#rsa-sha1'
  },
  digest: {
    'sha256': 'http://www.w3.org/2001/04/xmlenc#sha256',
    'sha1': 'http://www.w3.org/2000/09/xmldsig#sha1'
  }
};

exports.create = function(options) {
  if (!options.key)
    throw new Error('Expect a private key in pem format');

  if (!options.cert)
    throw new Error('Expect a public key cert in pem format');

  options.signatureAlgorithm = options.signatureAlgorithm || 'rsa-sha256';
  options.digestAlgorithm = options.digestAlgorithm || 'sha256';

  var cert = utils.pemToCert(options.cert);

  var sig = new SignedXml(null, { signatureAlgorithm: algorithms.signature[options.signatureAlgorithm], idAttribute: 'ID' });
  sig.addReference("//*[local-name(.)='Assertion']",
                  ["http://www.w3.org/2000/09/xmldsig#enveloped-signature", "http://www.w3.org/2001/10/xml-exc-c14n#"],
                  algorithms.digest[options.digestAlgorithm]);

  sig.signingKey = options.key;

  sig.keyInfoProvider = {
    getKeyInfo: function () {
      return "<X509Data><X509Certificate>" + cert + "</X509Certificate></X509Data>";
    }
  };

  var doc = new Parser().parseFromString(saml11.toString());
  doc.documentElement.setAttribute('ID', '_' + utils.uid(32));
  if (options.issuer) {
    var issuer = doc.documentElement.getElementsByTagName('saml:Issuer');
    issuer[0].textContent = options.issuer;
  }

  var now = moment.utc();
  doc.documentElement.setAttribute('IssueInstant', now.format('YYYY-MM-DDTHH:mm:ss.SSS[Z]'));
  var conditions = doc.documentElement.getElementsByTagName('saml:Conditions');
  var confirmationData = doc.documentElement.getElementsByTagName('saml:SubjectConfirmationData');

  if (options.lifetimeInSeconds) {
    conditions[0].setAttribute('NotBefore', now.format('YYYY-MM-DDTHH:mm:ss.SSS[Z]'));
    conditions[0].setAttribute('NotOnOrAfter', now.clone().add('seconds', options.lifetimeInSeconds).format('YYYY-MM-DDTHH:mm:ss.SSS[Z]'));

    confirmationData[0].setAttribute('NotOnOrAfter', now.clone().add('seconds', options.lifetimeInSeconds).format('YYYY-MM-DDTHH:mm:ss.SSS[Z]'));
  }

  if (options.audiences) {
    var audiences = options.audiences instanceof Array ? options.audiences : [options.audiences];
    audiences.forEach(function (audience) {
      var element = doc.createElementNS(NAMESPACE, 'saml:Audience');
      element.textContent = audience;
      var audienceCondition = conditions[0].getElementsByTagNameNS(NAMESPACE, 'AudienceRestriction')[0];
      audienceCondition.appendChild(element);
    });
  }

  if (options.recipient)
    confirmationData[0].setAttribute('Recipient', options.recipient);

  if (options.attributes) {
    var statement = doc.documentElement.getElementsByTagNameNS(NAMESPACE, 'AttributeStatement')[0];
    Object.keys(options.attributes).forEach(function(prop) {
      if(typeof options.attributes[prop] === 'undefined') return;
      // <saml:Attribute AttributeName="name" AttributeNamespace="http://schemas.xmlsoap.org/claims/identity">
      //    <saml:AttributeValue>Foo Bar</saml:AttributeValue>
      // </saml:Attribute>
      var attributeElement = doc.createElementNS(NAMESPACE, 'saml:Attribute');
      attributeElement.setAttribute('Name', prop);
      var values = options.attributes[prop] instanceof Array ? options.attributes[prop] : [options.attributes[prop]];
      values.forEach(function (value) {
        var valueElement = doc.createElementNS(NAMESPACE, 'saml:AttributeValue');
        valueElement.setAttribute('xsi:type', 'xs:anyType');
        valueElement.textContent = value;
        attributeElement.appendChild(valueElement);
      });

      statement.appendChild(attributeElement);
    });
  }

  doc.getElementsByTagName('saml:AuthnStatement')[0]
    .setAttribute('AuthnInstant', now.format('YYYY-MM-DDTHH:mm:ss.SSS[Z]'));

  var nameID = doc.documentElement.getElementsByTagNameNS(NAMESPACE, 'NameID')[0];

  if (options.nameIdentifier) {
    nameID.textContent = options.nameIdentifier;
  }

  if (options.nameIdentifierFormat) {
    nameID.setAttribute('Format', options.nameIdentifierFormat);
  }

  var token = doc.toString()
                .replace(/\r\n/g, '')
                .replace(/\n/g,'')
                .replace(/>(\s*)</g, '><') //unindent
                .trim();
  sig.computeSignature(token, options.xpathToNodeBeforeSignature || "//*[local-name(.)='Issuer']");
  var signed = sig.getSignedXml();

  return signed;
};

<commit_msg>add inresponseto support and bump 0.4.1<commit_after>
var utils = require('./utils'),
    Parser = require('xmldom').DOMParser,
    SignedXml = require('xml-crypto').SignedXml,
    moment = require('moment');

var fs = require('fs');
var path = require('path');
var saml11 = fs.readFileSync(path.join(__dirname, 'saml20.template')).toString();

var NAMESPACE = 'urn:oasis:names:tc:SAML:2.0:assertion';

var algorithms = {
  signature: {
    'rsa-sha256': 'http://www.w3.org/2001/04/xmldsig-more#rsa-sha256',
    'rsa-sha1':  'http://www.w3.org/2000/09/xmldsig#rsa-sha1'
  },
  digest: {
    'sha256': 'http://www.w3.org/2001/04/xmlenc#sha256',
    'sha1': 'http://www.w3.org/2000/09/xmldsig#sha1'
  }
};

exports.create = function(options) {
  if (!options.key)
    throw new Error('Expect a private key in pem format');

  if (!options.cert)
    throw new Error('Expect a public key cert in pem format');

  options.signatureAlgorithm = options.signatureAlgorithm || 'rsa-sha256';
  options.digestAlgorithm = options.digestAlgorithm || 'sha256';

  var cert = utils.pemToCert(options.cert);

  var sig = new SignedXml(null, { signatureAlgorithm: algorithms.signature[options.signatureAlgorithm], idAttribute: 'ID' });
  sig.addReference("//*[local-name(.)='Assertion']",
                  ["http://www.w3.org/2000/09/xmldsig#enveloped-signature", "http://www.w3.org/2001/10/xml-exc-c14n#"],
                  algorithms.digest[options.digestAlgorithm]);

  sig.signingKey = options.key;

  sig.keyInfoProvider = {
    getKeyInfo: function () {
      return "<X509Data><X509Certificate>" + cert + "</X509Certificate></X509Data>";
    }
  };

  var doc = new Parser().parseFromString(saml11.toString());
  doc.documentElement.setAttribute('ID', '_' + utils.uid(32));
  if (options.issuer) {
    var issuer = doc.documentElement.getElementsByTagName('saml:Issuer');
    issuer[0].textContent = options.issuer;
  }

  var now = moment.utc();
  doc.documentElement.setAttribute('IssueInstant', now.format('YYYY-MM-DDTHH:mm:ss.SSS[Z]'));
  var conditions = doc.documentElement.getElementsByTagName('saml:Conditions');
  var confirmationData = doc.documentElement.getElementsByTagName('saml:SubjectConfirmationData');

  if (options.lifetimeInSeconds) {
    conditions[0].setAttribute('NotBefore', now.format('YYYY-MM-DDTHH:mm:ss.SSS[Z]'));
    conditions[0].setAttribute('NotOnOrAfter', now.clone().add('seconds', options.lifetimeInSeconds).format('YYYY-MM-DDTHH:mm:ss.SSS[Z]'));

    confirmationData[0].setAttribute('NotOnOrAfter', now.clone().add('seconds', options.lifetimeInSeconds).format('YYYY-MM-DDTHH:mm:ss.SSS[Z]'));
  }

  if (options.audiences) {
    var audiences = options.audiences instanceof Array ? options.audiences : [options.audiences];
    audiences.forEach(function (audience) {
      var element = doc.createElementNS(NAMESPACE, 'saml:Audience');
      element.textContent = audience;
      var audienceCondition = conditions[0].getElementsByTagNameNS(NAMESPACE, 'AudienceRestriction')[0];
      audienceCondition.appendChild(element);
    });
  }

  if (options.recipient)
    confirmationData[0].setAttribute('Recipient', options.recipient);

  if (options.inResponseTo)
    confirmationData[0].setAttribute('InResponseTo', options.inResponseTo);

  if (options.attributes) {
    var statement = doc.documentElement.getElementsByTagNameNS(NAMESPACE, 'AttributeStatement')[0];
    Object.keys(options.attributes).forEach(function(prop) {
      if(typeof options.attributes[prop] === 'undefined') return;
      // <saml:Attribute AttributeName="name" AttributeNamespace="http://schemas.xmlsoap.org/claims/identity">
      //    <saml:AttributeValue>Foo Bar</saml:AttributeValue>
      // </saml:Attribute>
      var attributeElement = doc.createElementNS(NAMESPACE, 'saml:Attribute');
      attributeElement.setAttribute('Name', prop);
      var values = options.attributes[prop] instanceof Array ? options.attributes[prop] : [options.attributes[prop]];
      values.forEach(function (value) {
        var valueElement = doc.createElementNS(NAMESPACE, 'saml:AttributeValue');
        valueElement.setAttribute('xsi:type', 'xs:anyType');
        valueElement.textContent = value;
        attributeElement.appendChild(valueElement);
      });

      statement.appendChild(attributeElement);
    });
  }

  doc.getElementsByTagName('saml:AuthnStatement')[0]
    .setAttribute('AuthnInstant', now.format('YYYY-MM-DDTHH:mm:ss.SSS[Z]'));

  var nameID = doc.documentElement.getElementsByTagNameNS(NAMESPACE, 'NameID')[0];

  if (options.nameIdentifier) {
    nameID.textContent = options.nameIdentifier;
  }

  if (options.nameIdentifierFormat) {
    nameID.setAttribute('Format', options.nameIdentifierFormat);
  }

  var token = doc.toString()
                .replace(/\r\n/g, '')
                .replace(/\n/g,'')
                .replace(/>(\s*)</g, '><') //unindent
                .trim();
  sig.computeSignature(token, options.xpathToNodeBeforeSignature || "//*[local-name(.)='Issuer']");
  var signed = sig.getSignedXml();

  return signed;
};

<|endoftext|>


<commit_before>export function json(obj) {
  return new Promise((resolve, reject) => {
    const url = encodeUrlXhr(obj.url, obj.data);
    const config = {
      method: 'GET',
      mode: 'cors',
    };

    if (obj.jsonp) {
      jsonp(url, obj.callbackName, resolve);
    } else {
      fetch(url, config)
        .then(r => r.json())
        .then(resolve)
        .catch(reject);
    }

  });
}

function toQueryString(obj) {
  return Object.keys(obj).reduce((a, k) => {
    a.push(
      typeof obj[k] === 'object'
        ? toQueryString(obj[k])
        : `${encodeURIComponent(k)}=${encodeURIComponent(obj[k])}`
    );
    return a;
  }, []).join('&');
}

function encodeUrlXhr(url, data) {
  if (data && typeof data === 'object') {
    url += (/\?/.test(url) ? '&' : '?') + toQueryString(data);
  }
  return url;
}

function jsonp(url, key, callback) {
  // https://github.com/Fresheyeball/micro-jsonp/blob/master/src/jsonp.js
  let head = document.head,
      script = document.createElement('script'),
      // generate minimally unique name for callback function
      callbackName = 'f' + Math.round(Math.random() * Date.now());

  // set request url
  script.setAttribute('src',
    /*  add callback parameter to the url
          where key is the parameter key supplied
          and callbackName is the parameter value */
    (url + (url.indexOf('?') > 0 ? '&' : '?') + key + '=' + callbackName));

  /*  place jsonp callback on window,
      the script sent by the server should call this
      function as it was passed as a url parameter */
  window[callbackName] = data => {
    window[callbackName] = undefined;

    // clean up script tag created for request
    setTimeout(() => head.removeChild(script), 0);

    // hand data back to the user
    callback(data);
  };

  // actually make the request
  head.appendChild(script);
}
<commit_msg>add credentials: same-origin<commit_after>export function json(obj) {
  return new Promise((resolve, reject) => {
    const url = encodeUrlXhr(obj.url, obj.data);
    const config = {
      method: 'GET',
      mode: 'cors',
      credentials: 'same-origin',
    };

    if (obj.jsonp) {
      jsonp(url, obj.callbackName, resolve);
    } else {
      fetch(url, config)
        .then(r => r.json())
        .then(resolve)
        .catch(reject);
    }

  });
}

function toQueryString(obj) {
  return Object.keys(obj).reduce((a, k) => {
    a.push(
      typeof obj[k] === 'object'
        ? toQueryString(obj[k])
        : `${encodeURIComponent(k)}=${encodeURIComponent(obj[k])}`
    );
    return a;
  }, []).join('&');
}

function encodeUrlXhr(url, data) {
  if (data && typeof data === 'object') {
    url += (/\?/.test(url) ? '&' : '?') + toQueryString(data);
  }
  return url;
}

function jsonp(url, key, callback) {
  // https://github.com/Fresheyeball/micro-jsonp/blob/master/src/jsonp.js
  let head = document.head,
      script = document.createElement('script'),
      // generate minimally unique name for callback function
      callbackName = 'f' + Math.round(Math.random() * Date.now());

  // set request url
  script.setAttribute('src',
    /*  add callback parameter to the url
          where key is the parameter key supplied
          and callbackName is the parameter value */
    (url + (url.indexOf('?') > 0 ? '&' : '?') + key + '=' + callbackName));

  /*  place jsonp callback on window,
      the script sent by the server should call this
      function as it was passed as a url parameter */
  window[callbackName] = data => {
    window[callbackName] = undefined;

    // clean up script tag created for request
    setTimeout(() => head.removeChild(script), 0);

    // hand data back to the user
    callback(data);
  };

  // actually make the request
  head.appendChild(script);
}
<|endoftext|>


<commit_before>// boundaries
// Robot 1.5 m by .75 m
// Container 7.38 m long by 3.88 m wide
// Scale: 2/3 pixel = 1 cm
// Adjusted Container Size: 490 pixels by 259
// Adjusted Robot Size = 75 pixels by 38 pixels

// 284.9 x 539 - Scale 11/15 pixel = 1 cm

// canvas properties
var setup = {
  "width" : 259,
  "height" : 490,
  "left" : 37,
  "right" : 39,
  "down" : 40,
  "up" : 38
};

var ctx;
var canvas;

// overarching object literal for robot
var robot = {
  setup : {
    "width" : 75,
    "height" : 38
  },
  location : {
    "x" : setup.width/2 - 75/2,
    "y" : setup.height/2 + 38/2,
    "velocity" : 20,
    "angle" : 0,
    "angadjust" : 15,
    get xMid () {
      return this.x + robot.setup.width/2;
    },
    get yMid () {
      return this.y - robot.setup.height/2;
    }
  },
  corners : {
    get tL () {

    },
    get tR () {

    },
    get bL () {

    },
    get bR () {

    }
  }
};

function visualCanvas ()
{
  canvas = document.getElementById("robotMap");

  if (canvas.getContext)
  {
    ctx = canvas.getContext("2d");

    ctx.fillStyle = "#D7D2CB";
    ctx.rect(0, 0, setup.width, setup.height);
    ctx.fill();
  }

  canvasUpdate();

  window.addEventListener('keydown', arrowKey, true);
}

function obj_Update (xMid, yMid, width, height, deg)
{
  var rad = -deg * Math.PI/180;

  var xRestore = -(xMid + width/2);
  var yRestore = -(yMid + height/2);

  ctx.save();
  ctx.fillRect(0, 0, setup.width, setup.height);

  // center canvas on robot, rotate canvas to degree, draw, move canvas back
  ctx.translate (xMid, yMid);
  ctx.rotate (rad);

  ctx.translate (xRestore, yRestore);

  ctx.strokeRect (xMid, yMid, width, height);

  ctx.restore();
}

function canvasUpdate ()
{
  requestAnimationFrame(canvasUpdate);
  obj_Update(robot.location.xMid, robot.location.yMid, robot.setup.width,
             robot.setup.height, robot.location.angle);
}

function arrowKey (evt)
{

  switch (evt.keyCode)
  {
    case setup.left:
      robot.location.angle += robot.location.angadjust;
      // bounds?
      break;
    case setup.right:
      robot.location.angle -= robot.location.angadjust;
      // bounds?
      break;
    case setup.down:
      robot.location.x += robot.location.velocity *
                          Math.sin (robot.location.angle * Math.PI/180);
      robot.location.y += robot.location.velocity *
                          Math.cos (robot.location.angle * Math.PI/180);
      // bounds?
      break;
    case setup.up:
      robot.location.x -= robot.location.velocity *
                          Math.sin (robot.location.angle * Math.PI/180);
      robot.location.y -= robot.location.velocity *
                          Math.cos (robot.location.angle * Math.PI/180);
      // bounds?
      break;
  }
}
<commit_msg>Consistant naming convention and indentation<commit_after>//  Boundaries
//      Robot 1.5 m by .75 m
//      Container 7.38 m long by 3.88 m wide
//  Scale: 2/3 pixel = 1 cm
//      Adjusted Container Size: 490 pixels by 259
//      Adjusted Robot Size = 75 pixels by 38 pixels
//  284.9 x 539 - Scale 11/15 pixel = 1 cm

// canvas properties
var setup =
{
  "width" : 259,
  "height" : 490,
  "left" : 37,
  "right" : 39,
  "down" : 40,
  "up" : 38
};

var ctx;
var canvas;

// overarching object literal for robot
var robot =
{
    setup :
    {
        "width" : 75,
        "height" : 38
    },
    location :
    {
        "x" : setup.width/2 - 75/2,
        "y" : setup.height/2 + 38/2,
        "velocity" : 20,
        "angle" : 0,
        "angadjust" : 15,
        get xMid ()
        {
            return this.x + robot.setup.width/2;
        },
        get yMid ()
        {
            return this.y - robot.setup.height/2;
        }
    },
    corners :
    {
        get tL ()
        {

        },
    get tR ()
        {

        },
    get bL ()
        {

        },
    get bR ()
        {

        }
    }
};

function visual_canvas ()
{
    canvas = document.getElementById("robotMap");

  if (canvas.getContext)
  {
    ctx = canvas.getContext("2d");
    ctx.fillStyle = "#D7D2CB";
    ctx.rect(0, 0, setup.width, setup.height);
    ctx.fill();
  }

    canvasUpdate();

    window.addEventListener('keydown', arrowKey, true);
}

function obj_update (xMid, yMid, width, height, deg)
{
    var rad = -deg * Math.PI/180;

    var xRestore = -(xMid + width/2);
    var yRestore = -(yMid + height/2);

    ctx.save();
    ctx.fillRect(0, 0, setup.width, setup.height);

    // center canvas on robot, rotate canvas to degree, draw, move canvas back
    ctx.translate (xMid, yMid);
    ctx.rotate (rad);

    ctx.translate (xRestore, yRestore);

    ctx.strokeRect (xMid, yMid, width, height);

    ctx.restore();
}

function canvas_update ()
{
    requestAnimationFrame(canvasUpdate);
    obj_Update(robot.location.xMid, robot.location.yMid, robot.setup.width,
             robot.setup.height, robot.location.angle);
}

function arrow_key (evt)
{

  switch (evt.keyCode)
  {
        case setup.left:
            robot.location.angle += robot.location.angadjust;
      // bounds?
        break;
        case setup.right:
            robot.location.angle -= robot.location.angadjust;
      // bounds?
        break;
        case setup.down:
            robot.location.x += robot.location.velocity *
                          Math.sin (robot.location.angle * Math.PI/180);
            robot.location.y += robot.location.velocity *
                          Math.cos (robot.location.angle * Math.PI/180);
      // bounds?
        break;
        case setup.up:
            robot.location.x -= robot.location.velocity *
                          Math.sin (robot.location.angle * Math.PI/180);
            robot.location.y -= robot.location.velocity *
                          Math.cos (robot.location.angle * Math.PI/180);
      // bounds?
        break;
  }
}
<|endoftext|>


<commit_before>// WebSocket vs. Socket.IO example - common backend - from:
// https://github.com/rsp/node-websocket-vs-socket.io
// Copyright (c) 2015, 2016 Rafał Pocztarski
// Released under MIT License (Expat) - see:
// https://github.com/rsp/node-websocket-vs-socket.io/blob/master/LICENSE.md

var express = require('express');
var log = function (m) {
  console.error(new Date().toISOString()+' '+this.pre+m);
}

console.error("node-websocket-vs-socket.io\n"
+"WebSocket vs. Socket.IO on Node.js with Express.js - see:\n"
+"https://github.com/rsp/node-websocket-vs-socket.io#readme\n"
+"Copyright (c) 2015, 2016 Rafał Pocztarski\n"
+"Released under MIT License (Expat) - see:\n"
+"https://github.com/rsp/node-websocket-vs-socket.io/blob/master/LICENSE.md\n");

// WebSocket:
var ws = {app: express(), pre: "websocket app: ", log: log};
ws.ws = require('express-ws')(ws.app);
ws.app.get('/', (req, res) => {
  ws.log('express connection - sending html');
  res.sendFile(__dirname + '/ws.html');
});
ws.app.ws('/', (s, req) => {
  ws.log('incoming websocket connection');
  for (var t = 0; t < 3; t++)
    setTimeout(() => {
      ws.log('sending message to client');
      s.send(ws.pre+'message from server', ()=>{});
    }, 1000*t);
});
ws.app.listen(3001, () =>
  ws.log('listening on http://localhost:3001/'));
ws.log('starting server');

// Socket.IO:
var si = {app: express(), pre: "socket.io app: ", log: log};
si.http = require('http').Server(si.app);
si.io = require('socket.io')(si.http);
si.app.get('/', (req, res) => {
  si.log('express connection - sending html');
  res.sendFile(__dirname + '/si.html');
});
si.io.on('connection', s => {
  si.log('incoming socket.io connection');
  for (var t = 0; t < 3; t++)
    setTimeout(() => {
      si.log('sending message to client');
      s.emit('message', si.pre+'message from server');
    }, 1000*t);
});
si.http.listen(3002, () =>
  si.log('listening on http://localhost:3002/'));
si.log('starting server');
<commit_msg>add shebang<commit_after>#!/usr/bin/env node

// WebSocket vs. Socket.IO example - common backend - from:
// https://github.com/rsp/node-websocket-vs-socket.io
// Copyright (c) 2015, 2016 Rafał Pocztarski
// Released under MIT License (Expat) - see:
// https://github.com/rsp/node-websocket-vs-socket.io/blob/master/LICENSE.md

var express = require('express');
var log = function (m) {
  console.error(new Date().toISOString()+' '+this.pre+m);
}

console.error("node-websocket-vs-socket.io\n"
+"WebSocket vs. Socket.IO on Node.js with Express.js - see:\n"
+"https://github.com/rsp/node-websocket-vs-socket.io#readme\n"
+"Copyright (c) 2015, 2016 Rafał Pocztarski\n"
+"Released under MIT License (Expat) - see:\n"
+"https://github.com/rsp/node-websocket-vs-socket.io/blob/master/LICENSE.md\n");

// WebSocket:
var ws = {app: express(), pre: "websocket app: ", log: log};
ws.ws = require('express-ws')(ws.app);
ws.app.get('/', (req, res) => {
  ws.log('express connection - sending html');
  res.sendFile(__dirname + '/ws.html');
});
ws.app.ws('/', (s, req) => {
  ws.log('incoming websocket connection');
  for (var t = 0; t < 3; t++)
    setTimeout(() => {
      ws.log('sending message to client');
      s.send(ws.pre+'message from server', ()=>{});
    }, 1000*t);
});
ws.app.listen(3001, () =>
  ws.log('listening on http://localhost:3001/'));
ws.log('starting server');

// Socket.IO:
var si = {app: express(), pre: "socket.io app: ", log: log};
si.http = require('http').Server(si.app);
si.io = require('socket.io')(si.http);
si.app.get('/', (req, res) => {
  si.log('express connection - sending html');
  res.sendFile(__dirname + '/si.html');
});
si.io.on('connection', s => {
  si.log('incoming socket.io connection');
  for (var t = 0; t < 3; t++)
    setTimeout(() => {
      si.log('sending message to client');
      s.emit('message', si.pre+'message from server');
    }, 1000*t);
});
si.http.listen(3002, () =>
  si.log('listening on http://localhost:3002/'));
si.log('starting server');
<|endoftext|>


<commit_before>'use strict';

angular.module('lr.upload.iframe', []).factory('iFrameUpload', function ($q, $http, $document, $rootScope) {

  function indexOf(array, obj) {
    if (array.indexOf) {
      return array.indexOf(obj);
    }

    for ( var i = 0; i < array.length; i++) {
      if (obj === array[i]) {
        return i;
      }
    }
    return -1;
  }

  function iFrameUpload(config) {
    var files = [];

    var deferred = $q.defer(),
    promise = deferred.promise;

    // Extract file elements from the within config.data
    angular.forEach(config.data || {}, function (value, key) {
      if (angular.isElement(value)) {
        delete config.data[key];
        value.attr('name', key);
        files.push(value);
      }
    });

    // If the method is something else than POST append the _method parameter
    var addParamChar = /\?/.test(config.url) ? '&' : '?';
    // XDomainRequest only supports GET and POST:
    if (config.method === 'DELETE') {
      config.url = config.url + addParamChar + '_method=DELETE';
      config.method = 'POST';
    } else if (config.method === 'PUT') {
      config.url = config.url + addParamChar + '_method=PUT';
      config.method = 'POST';
    } else if (config.method === 'PATCH') {
      config.url = config.url + addParamChar + '_method=PATCH';
      config.method = 'POST';
    }

    var body = angular.element($document[0].body);

    // Generate a unique name using getUid() https://github.com/angular/angular.js/blob/master/src/Angular.js#L292
    // But since getUid isn't exported we get it from a temporary scope
    var uniqueScope = $rootScope.$new();
    var uniqueName = 'iframe-transport-' + uniqueScope.$id;
    uniqueScope.$destroy();

    var form = angular.element('<form></form>');
    form.attr('target', uniqueName);
    form.attr('action', config.url);
    form.attr('method', config.method || 'POST');
    form.css('display', 'none');

    if (files.length) {
      form.attr('enctype', 'multipart/form-data');
      // enctype must be set as encoding for IE:
      form.attr('encoding', 'multipart/form-data');
    }

    // Add iframe that we will post to
    var iframe = angular.element('');

    // The first load is called when the javascript:false is loaded,
    // that means we can continue with adding the hidden form and posting it to the iframe;
    iframe.on('load', function () {
      iframe
        .off('load')
        .on('load', function () {
          // The upload is complete and we not need to parse the contents and resolve the deferred

          var response;
          // Wrap in a try/catch block to catch exceptions thrown
          // when trying to access cross-domain iframe contents:
          try {
            var doc = this.contentWindow ? this.contentWindow.document : this.contentDocument;
            response = angular.element(doc.body).text();
            // Google Chrome and Firefox do not throw an
            // exception when calling iframe.contents() on
            // cross-domain requests, so we unify the response:
            if (!response.length) {
              throw new Error();
            }
          } catch (e) {}

          // Fix for IE endless progress bar activity bug
          // (happens on form submits to iframe targets):
          form.append(angular.element(''));

          // Convert response into JSON
          try {
            response = transformData(response, $http.defaults.transformResponse);
          } catch (e) {}

          deferred.resolve({
            data: response,
            status: 200,
            headers: [],
            config: config
          });
        });

      // Move file inputs to hidden form
      angular.forEach(files, function (input) {

        // Clone the original input also cloning it's event
        // @fix jQuery supports the option of cloning with events, but angular doesn't
        // this means that if you don't use jQuery the input will only work the first time.
        // because when we place the clone in the originals place we will not have a
        // change event hooked on to it.
        var clone = input.clone(true);

        // Insert clone directly after input
        input.after(clone);

        // Move original input to hidden form
        form.append(input);
      });

      // Add all existing data as hidden variables
      angular.forEach(config.data, function (value, name) {
        var input = angular.element('<input type="hidden" />');
        input.attr('name', name);
        input.val(value);
        form.append(input);
      });

      config.$iframeTransportForm = form;

      // Add the config to the $http pending requests to indicate that we are doing a request via the iframe
      $http.pendingRequests.push(config);

      // Transform data using $http.defaults.response
      function transformData(data, fns) {
        // An iframe doesn't support headers :(
        var headers = [];
        if (angular.isFunction(fns)) {
          return fns(data, headers);
        }

        angular.forEach(fns, function(fn) {
          data = fn(data, headers);
        });

        return data;
      }

      // Remove everything when we are done
      function removePendingReq() {
        var idx = indexOf($http.pendingRequests, config);
        if (idx !== -1) {
          $http.pendingRequests.splice(idx, 1);
          config.$iframeTransportForm.remove();
          delete config.$iframeTransportForm;
        }
      }

      // submit the form and wait for a response
      form[0].submit();

      promise.then(removePendingReq, removePendingReq);
    });

    form.append(iframe);
    body.append(form);

    return promise;
  }

  return iFrameUpload;
});
<commit_msg>in iframeupload, append files to form last<commit_after>'use strict';

angular.module('lr.upload.iframe', []).factory('iFrameUpload', function ($q, $http, $document, $rootScope) {

  function indexOf(array, obj) {
    if (array.indexOf) {
      return array.indexOf(obj);
    }

    for ( var i = 0; i < array.length; i++) {
      if (obj === array[i]) {
        return i;
      }
    }
    return -1;
  }

  function iFrameUpload(config) {
    var files = [];

    var deferred = $q.defer(),
    promise = deferred.promise;

    // Extract file elements from the within config.data
    angular.forEach(config.data || {}, function (value, key) {
      if (angular.isElement(value)) {
        delete config.data[key];
        value.attr('name', key);
        files.push(value);
      }
    });

    // If the method is something else than POST append the _method parameter
    var addParamChar = /\?/.test(config.url) ? '&' : '?';
    // XDomainRequest only supports GET and POST:
    if (config.method === 'DELETE') {
      config.url = config.url + addParamChar + '_method=DELETE';
      config.method = 'POST';
    } else if (config.method === 'PUT') {
      config.url = config.url + addParamChar + '_method=PUT';
      config.method = 'POST';
    } else if (config.method === 'PATCH') {
      config.url = config.url + addParamChar + '_method=PATCH';
      config.method = 'POST';
    }

    var body = angular.element($document[0].body);

    // Generate a unique name using getUid() https://github.com/angular/angular.js/blob/master/src/Angular.js#L292
    // But since getUid isn't exported we get it from a temporary scope
    var uniqueScope = $rootScope.$new();
    var uniqueName = 'iframe-transport-' + uniqueScope.$id;
    uniqueScope.$destroy();

    var form = angular.element('<form></form>');
    form.attr('target', uniqueName);
    form.attr('action', config.url);
    form.attr('method', config.method || 'POST');
    form.css('display', 'none');

    if (files.length) {
      form.attr('enctype', 'multipart/form-data');
      // enctype must be set as encoding for IE:
      form.attr('encoding', 'multipart/form-data');
    }

    // Add iframe that we will post to
    var iframe = angular.element('');

    // The first load is called when the javascript:false is loaded,
    // that means we can continue with adding the hidden form and posting it to the iframe;
    iframe.on('load', function () {
      iframe
        .off('load')
        .on('load', function () {
          // The upload is complete and we not need to parse the contents and resolve the deferred

          var response;
          // Wrap in a try/catch block to catch exceptions thrown
          // when trying to access cross-domain iframe contents:
          try {
            var doc = this.contentWindow ? this.contentWindow.document : this.contentDocument;
            response = angular.element(doc.body).text();
            // Google Chrome and Firefox do not throw an
            // exception when calling iframe.contents() on
            // cross-domain requests, so we unify the response:
            if (!response.length) {
              throw new Error();
            }
          } catch (e) {}

          // Fix for IE endless progress bar activity bug
          // (happens on form submits to iframe targets):
          form.append(angular.element(''));

          // Convert response into JSON
          try {
            response = transformData(response, $http.defaults.transformResponse);
          } catch (e) {}

          deferred.resolve({
            data: response,
            status: 200,
            headers: [],
            config: config
          });
        });

      // Add all existing data as hidden variables
      angular.forEach(config.data, function (value, name) {
        var input = angular.element('<input type="hidden" />');
        input.attr('name', name);
        input.val(value);
        form.append(input);
      });

      // Move file inputs to hidden form, adding files last, as this is a
      // requirement for uploading to S3
      angular.forEach(files, function (input) {

        // Clone the original input also cloning it's event
        // @fix jQuery supports the option of cloning with events, but angular doesn't
        // this means that if you don't use jQuery the input will only work the first time.
        // because when we place the clone in the originals place we will not have a
        // change event hooked on to it.
        var clone = input.clone(true);

        // Insert clone directly after input
        input.after(clone);

        // Move original input to hidden form
        form.append(input);
      });

      config.$iframeTransportForm = form;

      // Add the config to the $http pending requests to indicate that we are doing a request via the iframe
      $http.pendingRequests.push(config);

      // Transform data using $http.defaults.response
      function transformData(data, fns) {
        // An iframe doesn't support headers :(
        var headers = [];
        if (angular.isFunction(fns)) {
          return fns(data, headers);
        }

        angular.forEach(fns, function(fn) {
          data = fn(data, headers);
        });

        return data;
      }

      // Remove everything when we are done
      function removePendingReq() {
        var idx = indexOf($http.pendingRequests, config);
        if (idx !== -1) {
          $http.pendingRequests.splice(idx, 1);
          config.$iframeTransportForm.remove();
          delete config.$iframeTransportForm;
        }
      }

      // submit the form and wait for a response
      form[0].submit();

      promise.then(removePendingReq, removePendingReq);
    });

    form.append(iframe);
    body.append(form);

    return promise;
  }

  return iFrameUpload;
});
<|endoftext|>


<commit_before>
var server_url = "http://127.0.0.1:5000/";
var file_icon = "images/document_icon.png"
var logged_name = null;
var logged_auth = null;
var last_visited_id = null;
var last_visited_type = null;

// HTML MANAGEMENT
function read_form(type) {
    var name = $("#name").val();
    var psw = $("#psw").val();
    if(!name || !psw) {
        alert("Inserisci i campi richiesti");
        return false;
    }
    if(type == "login") {
        return [name, psw];
    }
    else {
        var email = $("#email").val();
        if(! /^.+@.+\..+$/.test(email)) {
            alert("Email non valida");
            return false;
        }
        return [name, psw, email];
    }
}

function pop_the_popup(data, e) {
    var obj = data.features[0].properties;

    if(obj.id_ritrovamento != null) {
        last_visited_id = obj.id_ritrovamento;
        last_visited_type = "ritrovamento";

        $("#popup_ritrovamento h3").html(obj.definizione || null);
        $("#popup_ritrovamento p").html(obj.descrizione_min || null);
        $("#popup_ritrovamento #periodo").html(obj.periodo_fine || null);
        $("#popup_ritrovamento #tipologia_ritrov").html(obj.tipologia_ritrov || null);

        popup.setContent(
            $("#popup_ritrovamento").html()
        );
    }
    else {
        last_visited_id = obj.id_interv_nuovo;
        last_visited_type = "intervento";

        $("#popup_intervento h3").html(obj.tipo_intervento || null);
        $("#popup_intervento time").html(obj.data_compilazione || null);
        $("#popup_intervento #metodo").html(obj.metodo || null);
        $("#popup_intervento #dir_scentifica").html(obj.dir_scentifica || null);
        $("#popup_intervento #ente_resp").html(obj.ente_resp || null);
        $("#popup_intervento #ente_schedatore").html(obj.ente_schedatore || null);
        $("#popup_intervento #esecutore_intervento").html(obj.esecutore_intervento || null);
        $("#popup_intervento #tipo_particella").html(obj.tipo_particella || null);

        popup.setContent(
            $("#popup_intervento").html()
        );
    }

    popup.setLatLng(e.latlng);
    map.openPopup(popup);
}

function opengeo_make_link(link) {
    return link.replace("/home/archeofi/homes", "http://opengeo.eu/archeofi2");
}

function display_opengeo(data) {
    // clean-up from the previous info displayed
    $("#descri").empty();
    $("#bibliography").hide();
    $("#biblio").empty();
    $("#gallery").hide();
    $("#image").empty();

    // add new infos
    $("#descri").html(data[0]["descr"]);

    var bibliography = data[0]["bibliografia"];
    if(bibliography) {
        for(var i=0, l=bibliography.length; i<l; i++) {
            var content = bibliography[i]["biblio"] + " " + bibliography[i]["pagine"] + "
";
        }
        $("#biblio").html( content);
        $("#bibliography").show();
    }

    var images = data[0]["images"];
    if(images.length > 0) {
        for(var i=0, l=images.length; i<l; i++) {
            var link = opengeo_make_link(images[i]["link"]);
            var thumb = opengeo_make_link(images[i]["thumbnail"]);
            $("#image").append( " \
                     \
                ");
        }
        $("#gallery").show();
    }
}

function file_thumb(entry) {
    // TODO: correggere in 'data:image/jpeg;base64,' + entry["photo_thumb"];
    var thumb = (
            ''
        +   '   "
        +   ''
    )
    return thumb
}

function display_contents(contents) {
    // 'contents' is a map with keys: 'num_results', 'objects', 'page', 'total_pages'
    $("#contents").empty();

    console.log(contents);

    contents["objects"].forEach( function(entry) {
        console.log(entry);

        $("#contents").append(
                '
'
            +   '
'
            +           entry["id_"]
            +   '
'
            +   (entry["comment"] ? '' + entry["comment"] + '' : '')
            +   (entry["filename"] ? file_thumb(entry) : '')
            +   '
'
            +   '       '
            +               entry["user"]
            +   '       '
            +   '       '
            +               entry["creation_time"]
            +   '       '
            +   '
'
            +   '
'
            +   '       <button class="ui-btn ui-icon-like ui-btn-icon-notext ui-corner-all ui-nodisc-icon ui-btn-inline">'
            +   '           mi piace'
            +   '       </button>'
            +   '       <button class="ui-btn ui-icon-dislike ui-btn-icon-notext ui-corner-all ui-nodisc-icon ui-btn-inline">'
            +   '           non mi piace'
            +   '       </button>'
            +   '
'
            +   '
'
            +   '       '
            +   '           +' + entry["like"]
            +   '       '
            +   '       '
            +   '           -' + entry["unlike"]
            +   '       '
            +   '
'
            +   '
'
        );
    });
}

$(document).on('pageshow', '#info', function() {
    ask_opengeo(last_visited_type, last_visited_id);
    // TODO: risolvere problema doppi id
    get_contents(last_visited_id);

    if(!logged_auth) {
        $("#add_content").hide();
        $("#login_required").show();
    }
    else {
        $("#add_content").show();
        $("#login_required").hide();
    }
});

// INDIANA SERVER
function register(name, psw, email) {
    $.ajax({
        type: "POST",
        url: server_url + "api/indiana_user",
        data: JSON.stringify({ "name": name, "psw": psw, "email": email }),
        dataType: "json",
        contentType: "application/json",
        success: function(data) {
            alert("ok");
            return data.objects;
        },
        error: function() {
            alert("ops, something went wrong..");
        }
    });
}

function login(name, psw) {
    var auth = "Basic " + btoa(name + ":" + psw);
    $.ajax({
        type: "GET",
        url: server_url + "api/login/",
        headers: {
          "Authorization": auth
        },
        success: function(logged) {
            console.log("successfully logged");
            if(logged) {
                logged_auth = auth;
                logged_name = name;
                alert("User and psw saved.");
            }
        },
        error: function() {
            alert("ops, something went wrong..");
        }
    });
}

function post_a_comment(poi, comment) {
    $.ajax({
        type: "POST",
        url: server_url + "api/content",
        headers: {
          "Authorization": logged_auth
        },
        data: JSON.stringify({ "comment": comment, "poi": poi }),
        dataType: "json",
        contentType: "application/json",
        success: function() {
            console.log("comment published!");
        },
        error: function() {
            console.log("ops, something went wrong..");
        }
    });
}

function get_contents(poi) {
    $.ajax({
        type: "GET",
        url: server_url + "api/content",
        data: {
            "q": JSON.stringify({
                "filters": [{
                    "name": "poi",
                    "op": "==",
                    "val": poi
                }]
            })
        },
        dataType: "json",
        contentType: "application/json",
        success: function(received) {
            console.log("contents received.");
            display_contents(received);
        },
        error: function() {
            console.log("ops, something went wrong..");
        }
    });
}

function modify_comment(content_id, modified_content) {
    $.ajax({
        type: "PATCH",
        url: server_url + "api/content/" + content_id,
        headers: {
          "Authorization": logged_auth
        },
        data: JSON.stringify ({
            "comment": modified_content
        }),
        contentType: "application/json",
        success: function() {
            console.log("content modified.");
        },
        error: function() {
            console.log("ops, something went wrong..");
        },
        complete: function(data_response) {
            return data_response.responseText;
        }
    });
}

function remove_content(content_id) {
    $.ajax({
        type: "DELETE",
        url: server_url + "api/content/" + content_id,
        headers: {
          "Authorization": logged_auth
        },
        contentType: "application/json",
        success: function() {
            console.log("content deleted.");
        },
        error: function() {
            console.log("ops, something went wrong..");
        },
        complete: function(data_response) {
            return data_response.responseText;
        }
    });
}

function like(content_id, do_like) {
    $.ajax({
        type: "POST",
        url: server_url + "api/like",
        headers: {
          "Authorization": logged_auth
        },
        data: JSON.stringify ({
            "content_id": content_id,
            "do_like": do_like
        }),
        contentType: "application/json",
        success: function() {
            console.log("liked.");
        },
        error: function() {
            console.log("ops, something went wrong..");
        },
        complete: function(data_response) {
            return data_response.responseText;
        }
    });
}

function upload(poi, comment, form_data, file_description) {
    var file_id = null;

    // posting announcement
    $.ajax({
        type: "POST",
        url: server_url + "api/content",
        headers: {
          "Authorization": logged_auth
        },
        data: JSON.stringify ({
            "poi": poi,
            "comment": comment,
            "upload_announcement": true,
            "file_description": file_description
        }),
        dataType: "json",
        contentType: "application/json",
        success: function(data) {
            console.log("file announced.");
            file_id = data["filename"];
            upload2(file_id, form_data);
        },
        error: function() {
            console.log("ops, something went wrong..");
        }
    });
}

function upload2(file_id, form_data) {
    // actually post the file
    $.ajax({
        type: "POST",
        url: server_url + "api/file/" + file_id,
        headers: {
          "Authorization": logged_auth
        },
        data: form_data,
        async: false,
        cache: false,
        processData: false, // Don't process the files
        contentType: false, // Set content type to false as jQuery will tell the server its a query string request
        dataType: 'json',
        success: function() {
            console.log("file uploaded.");
        },
        error: function(x, t, m) {
            console.log(t);
        }
    });
}

function wms_proxy(bbox, width, height, x, y, e) {
    $.ajax({
        type: "GET",
        url: server_url + "api/proxy/" + bbox + '&' + width + '&' + height + '&' + x + '&' + y,
        success: function(data) {
            console.log("proxied.");
            console.log(data);
            pop_the_popup(data, e);
        },
        error: function() {
            console.log("ops, something went wrong..");
        }
    });
}

// OPENGEO SERVER
function ask_opengeo(type, id) {
    if(type == "ritrovamento")
        var prefix = "rit_id=";
    else if(type == "intervento")
        var prefix = "interv_id=";
    else
        return;
    $.getJSON(
        "http://opengeo.eu/archeofi2/api/archeofi_api.php?" + prefix + id + "&jsoncallback=?",
        function(data) {
            console.log(data);
            display_opengeo(data);
        }
    );
}
<commit_msg>fix: quote missing and a link was doubled (!!)<commit_after>
var server_url = "http://127.0.0.1:5000/";
var file_icon = "images/document_icon.png"
var logged_name = null;
var logged_auth = null;
var last_visited_id = null;
var last_visited_type = null;

// HTML MANAGEMENT
function read_form(type) {
    var name = $("#name").val();
    var psw = $("#psw").val();
    if(!name || !psw) {
        alert("Inserisci i campi richiesti");
        return false;
    }
    if(type == "login") {
        return [name, psw];
    }
    else {
        var email = $("#email").val();
        if(! /^.+@.+\..+$/.test(email)) {
            alert("Email non valida");
            return false;
        }
        return [name, psw, email];
    }
}

function pop_the_popup(data, e) {
    var obj = data.features[0].properties;

    if(obj.id_ritrovamento != null) {
        last_visited_id = obj.id_ritrovamento;
        last_visited_type = "ritrovamento";

        $("#popup_ritrovamento h3").html(obj.definizione || null);
        $("#popup_ritrovamento p").html(obj.descrizione_min || null);
        $("#popup_ritrovamento #periodo").html(obj.periodo_fine || null);
        $("#popup_ritrovamento #tipologia_ritrov").html(obj.tipologia_ritrov || null);

        popup.setContent(
            $("#popup_ritrovamento").html()
        );
    }
    else {
        last_visited_id = obj.id_interv_nuovo;
        last_visited_type = "intervento";

        $("#popup_intervento h3").html(obj.tipo_intervento || null);
        $("#popup_intervento time").html(obj.data_compilazione || null);
        $("#popup_intervento #metodo").html(obj.metodo || null);
        $("#popup_intervento #dir_scentifica").html(obj.dir_scentifica || null);
        $("#popup_intervento #ente_resp").html(obj.ente_resp || null);
        $("#popup_intervento #ente_schedatore").html(obj.ente_schedatore || null);
        $("#popup_intervento #esecutore_intervento").html(obj.esecutore_intervento || null);
        $("#popup_intervento #tipo_particella").html(obj.tipo_particella || null);

        popup.setContent(
            $("#popup_intervento").html()
        );
    }

    popup.setLatLng(e.latlng);
    map.openPopup(popup);
}

function opengeo_make_link(link) {
    return link.replace("/home/archeofi/homes", "http://opengeo.eu/archeofi2");
}

function display_opengeo(data) {
    // clean-up from the previous info displayed
    $("#descri").empty();
    $("#bibliography").hide();
    $("#biblio").empty();
    $("#gallery").hide();
    $("#image").empty();

    // add new infos
    $("#descri").html(data[0]["descr"]);

    var bibliography = data[0]["bibliografia"];
    if(bibliography) {
        for(var i=0, l=bibliography.length; i<l; i++) {
            var content = bibliography[i]["biblio"] + " " + bibliography[i]["pagine"] + "
";
        }
        $("#biblio").html( content);
        $("#bibliography").show();
    }

    var images = data[0]["images"];
    if(images.length > 0) {
        for(var i=0, l=images.length; i<l; i++) {
            var link = opengeo_make_link(images[i]["link"]);
            var thumb = opengeo_make_link(images[i]["thumbnail"]);
            $("#image").append( " \
                     \
                ");
        }
        $("#gallery").show();
    }
}

function file_thumb(entry) {
    // TODO: correggere in 'data:image/jpeg;base64,' + entry["photo_thumb"];
    var thumb = (
            ''
        +   '   '
        +   '\n'
    )
    return thumb;
}
}

function display_contents(contents) {
    // 'contents' is a map with keys: 'num_results', 'objects', 'page', 'total_pages'
    $("#contents").empty();

    console.log(contents);

    contents["objects"].forEach( function(entry) {
        console.log(entry);

        $("#contents").append(
                '
'
            +   '
'
            +           entry["id_"]
            +   '
'
            +   (entry["comment"] ? '' + entry["comment"] + '' : '')
            +   (entry["filename"] ? file_thumb(entry) : '')
            +   '
'
            +   '       '
            +               entry["user"]
            +   '       '
            +   '       '
            +               entry["creation_time"]
            +   '       '
            +   '
'
            +   '
'
            +   '       <button class="ui-btn ui-icon-like ui-btn-icon-notext ui-corner-all ui-nodisc-icon ui-btn-inline">'
            +   '           mi piace'
            +   '       </button>'
            +   '       <button class="ui-btn ui-icon-dislike ui-btn-icon-notext ui-corner-all ui-nodisc-icon ui-btn-inline">'
            +   '           non mi piace'
            +   '       </button>'
            +   '
'
            +   '
'
            +   '       '
            +   '           +' + entry["like"]
            +   '       '
            +   '       '
            +   '           -' + entry["unlike"]
            +   '       '
            +   '
'
            +   '
'
        );
    });
}

$(document).on('pageshow', '#info', function() {
    ask_opengeo(last_visited_type, last_visited_id);
    // TODO: risolvere problema doppi id
    get_contents(last_visited_id);

    if(!logged_auth) {
        $("#add_content").hide();
        $("#login_required").show();
    }
    else {
        $("#add_content").show();
        $("#login_required").hide();
    }
});

// INDIANA SERVER
function register(name, psw, email) {
    $.ajax({
        type: "POST",
        url: server_url + "api/indiana_user",
        data: JSON.stringify({ "name": name, "psw": psw, "email": email }),
        dataType: "json",
        contentType: "application/json",
        success: function(data) {
            alert("ok");
            return data.objects;
        },
        error: function() {
            alert("ops, something went wrong..");
        }
    });
}

function login(name, psw) {
    var auth = "Basic " + btoa(name + ":" + psw);
    $.ajax({
        type: "GET",
        url: server_url + "api/login/",
        headers: {
          "Authorization": auth
        },
        success: function(logged) {
            console.log("successfully logged");
            if(logged) {
                logged_auth = auth;
                logged_name = name;
                alert("User and psw saved.");
            }
        },
        error: function() {
            alert("ops, something went wrong..");
        }
    });
}

function post_a_comment(poi, comment) {
    $.ajax({
        type: "POST",
        url: server_url + "api/content",
        headers: {
          "Authorization": logged_auth
        },
        data: JSON.stringify({ "comment": comment, "poi": poi }),
        dataType: "json",
        contentType: "application/json",
        success: function() {
            console.log("comment published!");
        },
        error: function() {
            console.log("ops, something went wrong..");
        }
    });
}

function get_contents(poi) {
    $.ajax({
        type: "GET",
        url: server_url + "api/content",
        data: {
            "q": JSON.stringify({
                "filters": [{
                    "name": "poi",
                    "op": "==",
                    "val": poi
                }]
            })
        },
        dataType: "json",
        contentType: "application/json",
        success: function(received) {
            console.log("contents received.");
            display_contents(received);
        },
        error: function() {
            console.log("ops, something went wrong..");
        }
    });
}

function modify_comment(content_id, modified_content) {
    $.ajax({
        type: "PATCH",
        url: server_url + "api/content/" + content_id,
        headers: {
          "Authorization": logged_auth
        },
        data: JSON.stringify ({
            "comment": modified_content
        }),
        contentType: "application/json",
        success: function() {
            console.log("content modified.");
        },
        error: function() {
            console.log("ops, something went wrong..");
        },
        complete: function(data_response) {
            return data_response.responseText;
        }
    });
}

function remove_content(content_id) {
    $.ajax({
        type: "DELETE",
        url: server_url + "api/content/" + content_id,
        headers: {
          "Authorization": logged_auth
        },
        contentType: "application/json",
        success: function() {
            console.log("content deleted.");
        },
        error: function() {
            console.log("ops, something went wrong..");
        },
        complete: function(data_response) {
            return data_response.responseText;
        }
    });
}

function like(content_id, do_like) {
    $.ajax({
        type: "POST",
        url: server_url + "api/like",
        headers: {
          "Authorization": logged_auth
        },
        data: JSON.stringify ({
            "content_id": content_id,
            "do_like": do_like
        }),
        contentType: "application/json",
        success: function() {
            console.log("liked.");
        },
        error: function() {
            console.log("ops, something went wrong..");
        },
        complete: function(data_response) {
            return data_response.responseText;
        }
    });
}

function upload(poi, comment, form_data, file_description) {
    var file_id = null;

    // posting announcement
    $.ajax({
        type: "POST",
        url: server_url + "api/content",
        headers: {
          "Authorization": logged_auth
        },
        data: JSON.stringify ({
            "poi": poi,
            "comment": comment,
            "upload_announcement": true,
            "file_description": file_description
        }),
        dataType: "json",
        contentType: "application/json",
        success: function(data) {
            console.log("file announced.");
            file_id = data["filename"];
            upload2(file_id, form_data);
        },
        error: function() {
            console.log("ops, something went wrong..");
        }
    });
}

function upload2(file_id, form_data) {
    // actually post the file
    $.ajax({
        type: "POST",
        url: server_url + "api/file/" + file_id,
        headers: {
          "Authorization": logged_auth
        },
        data: form_data,
        async: false,
        cache: false,
        processData: false, // Don't process the files
        contentType: false, // Set content type to false as jQuery will tell the server its a query string request
        dataType: 'json',
        success: function() {
            console.log("file uploaded.");
        },
        error: function(x, t, m) {
            console.log(t);
        }
    });
}

function wms_proxy(bbox, width, height, x, y, e) {
    $.ajax({
        type: "GET",
        url: server_url + "api/proxy/" + bbox + '&' + width + '&' + height + '&' + x + '&' + y,
        success: function(data) {
            console.log("proxied.");
            console.log(data);
            pop_the_popup(data, e);
        },
        error: function() {
            console.log("ops, something went wrong..");
        }
    });
}

// OPENGEO SERVER
function ask_opengeo(type, id) {
    if(type == "ritrovamento")
        var prefix = "rit_id=";
    else if(type == "intervento")
        var prefix = "interv_id=";
    else
        return;
    $.getJSON(
        "http://opengeo.eu/archeofi2/api/archeofi_api.php?" + prefix + id + "&jsoncallback=?",
        function(data) {
            console.log(data);
            display_opengeo(data);
        }
    );
}
<|endoftext|>


<commit_before>'use strict';

var Immutable         = require('immutable');
var {is, fromJS, Map} = Immutable;
var invariant         = require('./invariant');
var messages          = require('./messages');
var emptyFunction     = require('./emptyFunction');
var ValidationResult  = require('./ValidationResult');

/**
 * Node represent schema for data.
 *
 * Hierarchy is the following:
 *
 *                       ScalarNode
 *                      /
 *   Node - ConcreteNode               MappingNode
 *                      \             /
 *                       CompositeNode
 *                                    \
 *                                     ListNode
 */
class Node {

  constructor(props) {
    this.props = props;
  }

  equals(node) {
    if (
      node === null || node === undefined ||
      node.constructor !== undefined &&
      node.constructor !== this.constructor
    ) {
      return false;
    }
    return is(this.props, node.props) && is(this.children, node.children);
  }

  get defaultValue() {
    if (this.__defaultValue === undefined) {
      this.__defaultValue = fromJS(this.props.get('defaultValue'));
    }
    return this.__defaultValue;
  }

  instantiate(value) {
    throw new Error('instantiate(value): not implemented');
  }

  validate(value, childrenValidation) {
    throw new Error('validate(value, childrenValidation): not implemented');
  }

  toString() {
    var props = this.props.map((v, k) => `${k}: ${v}`).toList().join(', ');
    return `${this.constructor.name} { ${props} }`;
  }

  static create(props) {
    props = Map(props || {});
    return new this(props);
  }
}

class ConcreteNode extends Node {

  validate(value, childrenValidation) {
    if (!childrenValidation.isSuccess) {
      return childrenValidation;
    }
    var result;
    var validate = this.props.get('validate');
    // `validate` could be an array for convenienve
    if (Array.isArray(validate)) {
      for (var i = 0, len = validate.length; i < len; i++) {
        result = validate[i](this, value);
        if (result instanceof Error) {
          result;
        }
      }
    } else  if (validate) {
      result = validate(this, value);
    }
    return result;
  }

  instantiate(value) {
    return this;
  }
}

class CompositeNode extends ConcreteNode {

  get children() {
    if (this.__children === undefined) {
      this.__children = this.getChildren();
    }
    return this.__children;
  }

  getChildren() {
    throw new Error('getChildren(): not implemented');
  }

  get(key) {
    throw new Error('get(key): not implemented');
  }

  has(key) {
    throw new Error('has(key): not implemented');
  }

  keys(value) {
    throw new Error('keys(value): not implemented');
  }
}

class ScalarNode extends ConcreteNode {

  validate(value, childrenValidation) {
    value = this.deserialize(value);
    if (value instanceof Error) {
      return value;
    } else {
      return super(value, childrenValidation)
    }
  }

  serialize(value) {
    return value === null ? '' : value;
  }

  deserialize(value) {
    return value === '' ? null : value;
  }
}

class NumberNode extends ScalarNode {

  deserialize(value) {
    if (value === '') {
      return null;
    // based on http://stackoverflow.com/a/1830844/182954
    } else if (!isNaN(parseFloat(value)) && isFinite(value)) {
      return parseFloat(value);
    } else {
      return new Error(messages.INVALID_VALUE);
    }
  }
}

class ArrayNode extends ScalarNode {

  serialize(value) {
    return value ? value : [];
  }

  deserialize(value) {
    return value;
  }
}

function Scalar(props) {
  switch (props && props.type || 'string') {
    case 'string':
      return ScalarNode.create(props);
    case 'number':
      return NumberNode.create(props);
    case 'array':
      return ArrayNode.create(props);
    default:
      invariant(
        false,
        `invalid type "${props.type}" supplied to Scalar`
      );
  }
}

var VALUE_IS_REQUIRED = ValidationResult.error(messages.VALUE_IS_REQUIRED);

class MappingNode extends CompositeNode {

  constructor(props) {
    super(props);
    this.__requiredKeys = props.get('children')
      .toSeq()
      .filter(child => child.props.get('required'))
      .keySeq()
      .toSet();
  }

  validate(value, childrenValidation) {
    var missingKeys = this.__requiredKeys.subtract(value.filter(v => v != null).keys());
    if (missingKeys.size > 0) {
      var missingKeysValidation = Map().asMutable();
      missingKeys.forEach(k =>
        missingKeysValidation = missingKeysValidation.set(k, VALUE_IS_REQUIRED));
      return ValidationResult.children(childrenValidation.children.merge(missingKeysValidation));
    }
    return super(value, childrenValidation);
  }

  getChildren() {
    return this.props.get('children');
  }

  get(key) {
    return this.children.get(key);
  }

  has(key) {
    return this.children.has(key);
  }

  keys(value) {
    return this.children.keys();
  }

  static create(props, children) {
    if (children === undefined) {
      children = props;
      children = Map(children);
      props = {children};
    } else {
      children = Map(children);
      var newProps = {children};
      for (var k in props) {
        if (props.hasOwnProperty(k)) {
          newProps[k] = props[k];
        }
      }
      props = newProps;
    }
    props = Map(props);
    return new this(props);
  }
}

var Mapping = MappingNode.create.bind(MappingNode);

class ListNode extends CompositeNode {

  getChildren() {
    return this.props.get('children');
  }

  get(key) {
    return this.children;
  }

  has(key) {
    return true;
  }

  keys(value) {
    return value.keys();
  }

  static create(props, children) {
    if (children === undefined) {
      children = props;
      props = {children};
    } else {
      var newProps = {};
      for (var k in props) {
        if (props.hasOwnProperty(k)) {
          newProps[k] = props[k];
        }
        newProps.children = children;
      }
      props = newProps;
    }
    props = Map(props);
    return new ListNode(props);
  }
}

var List = ListNode.create.bind(List);

module.exports = {
  Node,
  ScalarNode, NumberNode, ArrayNode,
  CompositeNode,
  MappingNode, ListNode,
  Scalar, Mapping, List
};
<commit_msg>schema: add "date" scalar node<commit_after>'use strict';

var Immutable         = require('immutable');
var {is, fromJS, Map} = Immutable;
var invariant         = require('./invariant');
var messages          = require('./messages');
var emptyFunction     = require('./emptyFunction');
var ValidationResult  = require('./ValidationResult');

/**
 * Node represent schema for data.
 *
 * Hierarchy is the following:
 *
 *                       ScalarNode
 *                      /
 *   Node - ConcreteNode               MappingNode
 *                      \             /
 *                       CompositeNode
 *                                    \
 *                                     ListNode
 */
class Node {

  constructor(props) {
    this.props = props;
  }

  equals(node) {
    if (
      node === null || node === undefined ||
      node.constructor !== undefined &&
      node.constructor !== this.constructor
    ) {
      return false;
    }
    return is(this.props, node.props) && is(this.children, node.children);
  }

  get defaultValue() {
    if (this.__defaultValue === undefined) {
      this.__defaultValue = fromJS(this.props.get('defaultValue'));
    }
    return this.__defaultValue;
  }

  instantiate(value) {
    throw new Error('instantiate(value): not implemented');
  }

  validate(value, childrenValidation) {
    throw new Error('validate(value, childrenValidation): not implemented');
  }

  toString() {
    var props = this.props.map((v, k) => `${k}: ${v}`).toList().join(', ');
    return `${this.constructor.name} { ${props} }`;
  }

  static create(props) {
    props = Map(props || {});
    return new this(props);
  }
}

class ConcreteNode extends Node {

  validate(value, childrenValidation) {
    if (!childrenValidation.isSuccess) {
      return childrenValidation;
    }
    var result;
    var validate = this.props.get('validate');
    // `validate` could be an array for convenienve
    if (Array.isArray(validate)) {
      for (var i = 0, len = validate.length; i < len; i++) {
        result = validate[i](this, value);
        if (result instanceof Error) {
          result;
        }
      }
    } else  if (validate) {
      result = validate(this, value);
    }
    return result;
  }

  instantiate(value) {
    return this;
  }
}

class CompositeNode extends ConcreteNode {

  get children() {
    if (this.__children === undefined) {
      this.__children = this.getChildren();
    }
    return this.__children;
  }

  getChildren() {
    throw new Error('getChildren(): not implemented');
  }

  get(key) {
    throw new Error('get(key): not implemented');
  }

  has(key) {
    throw new Error('has(key): not implemented');
  }

  keys(value) {
    throw new Error('keys(value): not implemented');
  }
}

class ScalarNode extends ConcreteNode {

  validate(value, childrenValidation) {
    value = this.deserialize(value);
    if (value instanceof Error) {
      return value;
    } else {
      return super(value, childrenValidation)
    }
  }

  serialize(value) {
    return value === null ? '' : value;
  }

  deserialize(value) {
    return value === '' ? null : value;
  }
}

class NumberNode extends ScalarNode {

  deserialize(value) {
    if (value === '') {
      return null;
    // based on http://stackoverflow.com/a/1830844/182954
    } else if (!isNaN(parseFloat(value)) && isFinite(value)) {
      return parseFloat(value);
    } else {
      return new Error(messages.INVALID_VALUE);
    }
  }
}

class ArrayNode extends ScalarNode {

  serialize(value) {
    return value ? value : [];
  }

  deserialize(value) {
    return value;
  }
}

var IS_DATE_RE =  /^\d\d\d\d-\d\d-\d\d$/;

class DateNode extends ScalarNode {

  serialize(value) {
    if (value == null) {
      return '';
    }
    var year = value.getFullYear();
    var month = value.getMonth() + 1;
    var day = value.getDate();
    return `${year}-${this.pad(month, 2)}-${this.pad(day, 2)}`;
  }

  deserialize(value) {
    if (value === '') {
      return null;
    }

    if (value instanceof Date) {
      return value;
    }

    if (!IS_DATE_RE.exec(value)) {
      return new Error(messages.IS_NOT_A_DATE);
    }

    value = new Date(value);

    if (isNaN(value.getTime())) {
      return new Error(messages.INVALID_VALUE);
    }

    return value;
  }

  pad(num, size) {
    return ('0000' + num).substr(-size);
  }
}

function Scalar(props) {
  switch (props && props.type || 'string') {
    case 'string':
      return ScalarNode.create(props);
    case 'number':
      return NumberNode.create(props);
    case 'array':
      return ArrayNode.create(props);
    case 'date':
      return DateNode.create(props);
    default:
      invariant(
        false,
        `invalid type "${props.type}" supplied to Scalar`
      );
  }
}

var VALUE_IS_REQUIRED = ValidationResult.error(messages.VALUE_IS_REQUIRED);

class MappingNode extends CompositeNode {

  constructor(props) {
    super(props);
    this.__requiredKeys = props.get('children')
      .toSeq()
      .filter(child => child.props.get('required'))
      .keySeq()
      .toSet();
  }

  validate(value, childrenValidation) {
    var missingKeys = this.__requiredKeys.subtract(value.filter(v => v != null).keys());
    if (missingKeys.size > 0) {
      var missingKeysValidation = Map().asMutable();
      missingKeys.forEach(k =>
        missingKeysValidation = missingKeysValidation.set(k, VALUE_IS_REQUIRED));
      return ValidationResult.children(childrenValidation.children.merge(missingKeysValidation));
    }
    return super(value, childrenValidation);
  }

  getChildren() {
    return this.props.get('children');
  }

  get(key) {
    return this.children.get(key);
  }

  has(key) {
    return this.children.has(key);
  }

  keys(value) {
    return this.children.keys();
  }

  static create(props, children) {
    if (children === undefined) {
      children = props;
      children = Map(children);
      props = {children};
    } else {
      children = Map(children);
      var newProps = {children};
      for (var k in props) {
        if (props.hasOwnProperty(k)) {
          newProps[k] = props[k];
        }
      }
      props = newProps;
    }
    props = Map(props);
    return new this(props);
  }
}

var Mapping = MappingNode.create.bind(MappingNode);

class ListNode extends CompositeNode {

  getChildren() {
    return this.props.get('children');
  }

  get(key) {
    return this.children;
  }

  has(key) {
    return true;
  }

  keys(value) {
    return value.keys();
  }

  static create(props, children) {
    if (children === undefined) {
      children = props;
      props = {children};
    } else {
      var newProps = {};
      for (var k in props) {
        if (props.hasOwnProperty(k)) {
          newProps[k] = props[k];
        }
        newProps.children = children;
      }
      props = newProps;
    }
    props = Map(props);
    return new ListNode(props);
  }
}

var List = ListNode.create.bind(List);

module.exports = {
  Node,
  ScalarNode, NumberNode, ArrayNode,
  CompositeNode,
  MappingNode, ListNode,
  Scalar, Mapping, List
};
<|endoftext|>


<commit_before>//@ts-check

import SpeedTestWorker from "worker-loader!./worker";

/**
 * Speed Test web UI
 *
 * @class WebUI
 */
export default class WebUI {
    /**
     * Create an instance of WebUI.
     */
    constructor() {
        this.STATUS = {
            WAITING: 0,
            STARTING: 1,
            RUNNING: 2,
            DONE: 3,
            ABORTED: 4,
            FAILED: -1
        };

        this.statusInterval = null;

        this.config = {
            updateDelay: 150,
            endless: false // false
        };

        this.worker = new SpeedTestWorker();
        this.worker.onmessage = event => {
            this.processResponse(event);
        };

        this.$startButton = document.querySelector("#commands button#start");
        this.$stopButton = document.querySelector("#commands button#stop");
        this.$progress = document.querySelector("#progress");
        this.$progressBar = document.querySelector("#progress .progress-bar");
        this.$ipValue = document.querySelector("#ip span.value");
        this.$latencyValue = document.querySelector("#latency span.value");
        this.$jitterValue = document.querySelector("#jitter span.value");
        this.$downloadValue = document.querySelector("#download span.value");
        this.$uploadValue = document.querySelector("#upload span.value");

        this.$startButton.addEventListener("click", this.startTest.bind(this));
        this.$stopButton.addEventListener("click", this.stopTest.bind(this));
    }

    /**
     * Start a speed test.
     */
    startTest() {
        if (this.running) {
            return;
        }

        this.running = true;

        this.$startButton.setAttribute("hidden", "");
        this.$stopButton.removeAttribute("hidden");

        this.resetMeters();
        this.resetResults();

        if (this.config.updateDelay && !this.statusInterval) {
            this.statusInterval = window.setInterval(() => {
                this.worker.postMessage("status");
                // this.worker.processMessage({data: 'status'});
            }, this.config.updateDelay);
        }
        this.worker.postMessage("start");
        // this.worker.processMessage({data: 'start'});
    }

    /**
     * Abort a running speed test.
     */
    stopTest() {
        if (!this.running) {
            return;
        }

        this.running = false;

        window.clearInterval(this.statusInterval);
        this.statusInterval = null;

        if (this.worker) {
            this.worker.postMessage("abort");
        }

        this.resetMeters();
    }

    /**
     * Process an event response from the speed test Worker
     *
     * @param {MessageEvent} event
     */
    processResponse(event) {
        switch (event.data.status) {
            case this.STATUS.RUNNING:
                this.processData(event.data || {});
                break;
            case this.STATUS.DONE:
                window.clearInterval(this.statusInterval);

                this.processData(event.data || {});
                if (this.config.endless) {
                    this.startTest();
                    return;
                }

                this.resetMeters();

                this.$startButton.removeAttribute("hidden");
                this.$stopButton.setAttribute("hidden", "");

                this.running = false;
                break;
            case this.STATUS.ABORTED:
                window.clearInterval(this.statusInterval);

                this.processData(event.data || {});
                this.$startButton.removeAttribute("hidden");
                this.$stopButton.setAttribute("hidden", "");
                break;
        }
    }

    /**
     * Reset the current meters.
     */
    resetMeters() {
        this.setProgressBar(0);
    }

    /**
     * Reset the current results.
     */
    resetResults() {
        this.$ipValue.innerHTML = "";
        this.$latencyValue.innerHTML = "";
        this.$jitterValue.innerHTML = "";
        this.$downloadValue.innerHTML = "";
        this.$uploadValue.innerHTML = "";
    }

    /**
     * Process a set of data.
     *
     * @param {any} data
     */
    processData(data) {
        if (!this.running) {
            return;
        }

        switch (data.step) {
            case "ip":
                this.$ipValue.innerHTML = data.results.ip;
                break;
            case "latency":
                this.$latencyValue.innerHTML = data.results.latency.avg || "";
                this.$jitterValue.innerHTML = data.results.latency.jitter || "";
                this.setProgressBar(data.results.latency.progress);
                break;
            case "download":
                const downloadValue = data.results.download
                    ? +data.results.download.speed / (1024 * 1024)
                    : 0;
                this.$downloadValue.innerHTML = downloadValue
                    ? downloadValue.toFixed(2)
                    : "";
                this.setProgressBar(data.results.download.progress, "download");
                break;
            case "upload":
                const uploadValue = data.results.upload
                    ? +data.results.upload.speed / (1024 * 1024)
                    : 0;
                this.$uploadValue.innerHTML = uploadValue
                    ? uploadValue.toFixed(2)
                    : "";
                this.setProgressBar(data.results.upload.progress);
                break;
        }
    }

    /**
     * Set a value on the progress bar
     *
     * @param {*} progress
     * @param {*} mode
     */
    setProgressBar(progress, mode = "") {
        this.$progress.style.flexDirection =
            mode === "download" ? "row-reverse" : "row";
        this.$progressBar.style.width = progress * 100 + "%";
    }
}
<commit_msg>Remove obsolete test code<commit_after>//@ts-check

import SpeedTestWorker from "worker-loader!./worker";

/**
 * Speed Test web UI
 *
 * @class WebUI
 */
export default class WebUI {
    /**
     * Create an instance of WebUI.
     */
    constructor() {
        this.STATUS = {
            WAITING: 0,
            STARTING: 1,
            RUNNING: 2,
            DONE: 3,
            ABORTED: 4,
            FAILED: -1
        };

        this.statusInterval = null;

        this.config = {
            updateDelay: 150,
            endless: false // false
        };

        this.worker = new SpeedTestWorker();
        this.worker.onmessage = event => {
            this.processResponse(event);
        };

        this.$startButton = document.querySelector("#commands button#start");
        this.$stopButton = document.querySelector("#commands button#stop");
        this.$progress = document.querySelector("#progress");
        this.$progressBar = document.querySelector("#progress .progress-bar");
        this.$ipValue = document.querySelector("#ip span.value");
        this.$latencyValue = document.querySelector("#latency span.value");
        this.$jitterValue = document.querySelector("#jitter span.value");
        this.$downloadValue = document.querySelector("#download span.value");
        this.$uploadValue = document.querySelector("#upload span.value");

        this.$startButton.addEventListener("click", this.startTest.bind(this));
        this.$stopButton.addEventListener("click", this.stopTest.bind(this));
    }

    /**
     * Start a speed test.
     */
    startTest() {
        if (this.running) {
            return;
        }

        this.running = true;

        this.$startButton.setAttribute("hidden", "");
        this.$stopButton.removeAttribute("hidden");

        this.resetMeters();
        this.resetResults();

        if (this.config.updateDelay && !this.statusInterval) {
            this.statusInterval = window.setInterval(() => {
                this.worker.postMessage("status");
            }, this.config.updateDelay);
        }
        this.worker.postMessage("start");
    }

    /**
     * Abort a running speed test.
     */
    stopTest() {
        if (!this.running) {
            return;
        }

        this.running = false;

        window.clearInterval(this.statusInterval);
        this.statusInterval = null;

        if (this.worker) {
            this.worker.postMessage("abort");
        }

        this.resetMeters();
    }

    /**
     * Process an event response from the speed test Worker
     *
     * @param {MessageEvent} event
     */
    processResponse(event) {
        switch (event.data.status) {
            case this.STATUS.RUNNING:
                this.processData(event.data || {});
                break;
            case this.STATUS.DONE:
                window.clearInterval(this.statusInterval);

                this.processData(event.data || {});
                if (this.config.endless) {
                    this.startTest();
                    return;
                }

                this.resetMeters();

                this.$startButton.removeAttribute("hidden");
                this.$stopButton.setAttribute("hidden", "");

                this.running = false;
                break;
            case this.STATUS.ABORTED:
                window.clearInterval(this.statusInterval);

                this.processData(event.data || {});
                this.$startButton.removeAttribute("hidden");
                this.$stopButton.setAttribute("hidden", "");
                break;
        }
    }

    /**
     * Reset the current meters.
     */
    resetMeters() {
        this.setProgressBar(0);
    }

    /**
     * Reset the current results.
     */
    resetResults() {
        this.$ipValue.innerHTML = "";
        this.$latencyValue.innerHTML = "";
        this.$jitterValue.innerHTML = "";
        this.$downloadValue.innerHTML = "";
        this.$uploadValue.innerHTML = "";
    }

    /**
     * Process a set of data.
     *
     * @param {any} data
     */
    processData(data) {
        if (!this.running) {
            return;
        }

        switch (data.step) {
            case "ip":
                this.$ipValue.innerHTML = data.results.ip;
                break;
            case "latency":
                this.$latencyValue.innerHTML = data.results.latency.avg || "";
                this.$jitterValue.innerHTML = data.results.latency.jitter || "";
                this.setProgressBar(data.results.latency.progress);
                break;
            case "download":
                const downloadValue = data.results.download
                    ? +data.results.download.speed / (1024 * 1024)
                    : 0;
                this.$downloadValue.innerHTML = downloadValue
                    ? downloadValue.toFixed(2)
                    : "";
                this.setProgressBar(data.results.download.progress, "download");
                break;
            case "upload":
                const uploadValue = data.results.upload
                    ? +data.results.upload.speed / (1024 * 1024)
                    : 0;
                this.$uploadValue.innerHTML = uploadValue
                    ? uploadValue.toFixed(2)
                    : "";
                this.setProgressBar(data.results.upload.progress);
                break;
        }
    }

    /**
     * Set a value on the progress bar
     *
     * @param {*} progress
     * @param {*} mode
     */
    setProgressBar(progress, mode = "") {
        this.$progress.style.flexDirection =
            mode === "download" ? "row-reverse" : "row";
        this.$progressBar.style.width = progress * 100 + "%";
    }
}
<|endoftext|>


<commit_before>(function() {
  seajs.config({
    alias: {
      '$': 'gallery/jquery/1.7.2/jquery',
      'popup': 'arale/popup/0.9.8/popup',
      'autocomplete': 'arale/autocomplete/0.9.0/autocomplete',
      'afc163': '/sea-modules/afc163'
    },
    comboExcludes: /word\-color\.js/
  });

  seajs.use(
    ['$', 'popup', 'autocomplete', 'afc163/word-color/1.0.0/word-color', 'http://aralejs.org/package.js'],
    function($, Popup, Autocomplete, wordColor, araleModules) {

      var modules;

      insertAraleModules(araleModules);

      // 搜索组件自动完成
      var ac = new Autocomplete({
        trigger: '#search',
        selectFirst: true,
        dataSource: function() {
          if (modules) {
            this.trigger('data', modules);
          } else {
            this.trigger('data', araleModules);
          }
        },
        filter: function(data, query) {
          var result = [];
          $.each(data, function(index, value) {
            var temp = value.root + '.' + value.name;
            if (temp.indexOf(query) > -1) {
              result.push({matchKey: temp, url: value.homepage});
            }
          });
          return result;
        }
      }).render();

      ac.on('itemSelect', function(value, data) {
        ac.get('trigger').val('正转到 ' + value).attr('disabled', 'disabled');
        value = value.split('.');
        if (value[0] === 'arale') {
          location.href = '/' + value[1];
        } else if (value[0] === 'alipay') {
          location.href = 'http://aralejs.alipay.im/' + value[1];
        } else {
          location.href = data.url;
        }
      });

        /*
      $('#search').focus().on('keyup', function(e) {
        if (e.keyCode !== 38 && e.keyCode !== 40) {
          ac.set('selectedIndex', 0);
        }
      });*/

      seajs.use(['http://aralejs.alipay.im/package.js'], function(alipayModules) {
        if (!alipayModules) {
          return;
        }
        insertAlipayModules(alipayModules);
        modules = araleModules.concat(alipayModules);

        $('#J-alipay').show();
      });

      function insertAraleModules(data) {
        // 按字母顺序排序
        data = data.sort(function(a, b) {
          return a.name[0] > b.name[0];
        });

        if ($('#module-wrapper').length === 0) {
          return;
        }
        $('.modules').empty();
        for(var i=0; i<data.length; i++) {
          var item = $('');
          var module = data[i];
          item.html(module.name)
          .attr('href', '/' + module.name + '/')
          .data('description', module.description)
          .data('version', module.version);
          if (module.root === 'gallery') {
            item.attr('href', module.homepage);
            $('.modules-gallery').append(item).prev().show();
          } else {
            $('.modules-' + module.tag).append(item).prev().show();
          }
          cardPopup(item);
        }
        color('.module');
      }

      function insertAlipayModules(data) {
        data = data.sort(function(a, b) {
          return a.name[0] > b.name[0];
        });

        if ($('#module-wrapper').length === 0) {
          return;
        }

        for(var i=0; i<data.length; i++) {
          var item = $('');
          item.html(data[i].name)
          .attr('href', 'http://aralejs.alipay.im/' + data[i].name + '/')
          .data('description', data[i].description || '暂无描述')
          .data('version', data[i].version);

          $('.modules-alipay').append(item);
          $('.modules-alipay').prev().show();
          cardPopup(item);
        }
        color('.modules-alipay .module');
      }

      function cardPopup(item) {
        // 卡片
        var popup = new Popup({
          element: '#card',
          trigger: item,
          align: {
            baseXY: [0, -2],
            selfXY: [0, '100%']
          }
        });
        popup.on('before:show', function() {
          $('#card .card-name').html(item.html());
          $('#card .card-description').html(item.data('description') || '');
          $('#card .card-version').html(item.data('version') || '');
        });
      }

      function color(items) {
        items = $(items);
        items.each(function(index, item) {
            item = $(item);
            item.css('border-color', toRgba(wordColor(item.html()), 0.65));
        });
      }

      function toRgba(rgb, opacity) {
        if ($.browser.msie && $.browser.version < 9) {
            return rgb;
        }
        return rgb.replace('rgb', 'rgba').replace(')', ',' + opacity + ')');
      }

    });
})();
<commit_msg>add placeholder<commit_after>(function() {
  seajs.config({
    alias: {
      '$': 'gallery/jquery/1.7.2/jquery',
      'popup': 'arale/popup/0.9.8/popup',
      'autocomplete': 'arale/autocomplete/0.9.0/autocomplete',
      'placeholder': 'arale/placeholder/1.0.0/placeholder',
      'afc163': '/sea-modules/afc163'
    },
    comboExcludes: /word\-color\.js/
  });

  seajs.use(
    ['$', 'popup', 'autocomplete', 'placeholder', 'afc163/word-color/1.0.0/word-color', 'http://aralejs.org/package.js'],
    function($, Popup, Autocomplete, Placeholder, wordColor, araleModules) {

      var modules;

      insertAraleModules(araleModules);

      // 搜索组件自动完成
      var ac = new Autocomplete({
        trigger: '#search',
        selectFirst: true,
        dataSource: function() {
          if (modules) {
            this.trigger('data', modules);
          } else {
            this.trigger('data', araleModules);
          }
        },
        filter: function(data, query) {
          var result = [];
          $.each(data, function(index, value) {
            var temp = value.root + '.' + value.name;
            if (temp.indexOf(query) > -1) {
              result.push({matchKey: temp, url: value.homepage});
            }
          });
          return result;
        }
      }).render();

      ac.on('itemSelect', function(value, data) {
        ac.get('trigger').val('正转到 ' + value).attr('disabled', 'disabled');
        value = value.split('.');
        if (value[0] === 'arale') {
          location.href = '/' + value[1];
        } else if (value[0] === 'alipay') {
          location.href = 'http://aralejs.alipay.im/' + value[1];
        } else {
          location.href = data.url;
        }
      });

        /*
      $('#search').focus().on('keyup', function(e) {
        if (e.keyCode !== 38 && e.keyCode !== 40) {
          ac.set('selectedIndex', 0);
        }
      });*/

      seajs.use(['http://aralejs.alipay.im/package.js'], function(alipayModules) {
        if (!alipayModules) {
          return;
        }
        insertAlipayModules(alipayModules);
        modules = araleModules.concat(alipayModules);

        $('#J-alipay').show();
      });

      function insertAraleModules(data) {
        // 按字母顺序排序
        data = data.sort(function(a, b) {
          return a.name[0] > b.name[0];
        });

        if ($('#module-wrapper').length === 0) {
          return;
        }
        $('.modules').empty();
        for(var i=0; i<data.length; i++) {
          var item = $('');
          var module = data[i];
          item.html(module.name)
          .attr('href', '/' + module.name + '/')
          .data('description', module.description)
          .data('version', module.version);
          if (module.root === 'gallery') {
            item.attr('href', module.homepage);
            $('.modules-gallery').append(item).prev().show();
          } else {
            $('.modules-' + module.tag).append(item).prev().show();
          }
          cardPopup(item);
        }
        color('.module');
      }

      function insertAlipayModules(data) {
        data = data.sort(function(a, b) {
          return a.name[0] > b.name[0];
        });

        if ($('#module-wrapper').length === 0) {
          return;
        }

        for(var i=0; i<data.length; i++) {
          var item = $('');
          item.html(data[i].name)
          .attr('href', 'http://aralejs.alipay.im/' + data[i].name + '/')
          .data('description', data[i].description || '暂无描述')
          .data('version', data[i].version);

          $('.modules-alipay').append(item);
          $('.modules-alipay').prev().show();
          cardPopup(item);
        }
        color('.modules-alipay .module');
      }

      function cardPopup(item) {
        // 卡片
        var popup = new Popup({
          element: '#card',
          trigger: item,
          align: {
            baseXY: [0, -2],
            selfXY: [0, '100%']
          }
        });
        popup.on('before:show', function() {
          $('#card .card-name').html(item.html());
          $('#card .card-description').html(item.data('description') || '');
          $('#card .card-version').html(item.data('version') || '');
        });
      }

      function color(items) {
        items = $(items);
        items.each(function(index, item) {
            item = $(item);
            item.css('border-color', toRgba(wordColor(item.html()), 0.65));
        });
      }

      function toRgba(rgb, opacity) {
        if ($.browser.msie && $.browser.version < 9) {
            return rgb;
        }
        return rgb.replace('rgb', 'rgba').replace(')', ',' + opacity + ')');
      }

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


<commit_before>/* globals console require Promise */
'use strict';

// comment this when deploy application
process.env.mode = 'DEVELOPMENT';

const db = require('./config/mongoose'),
    connectionStrings = require('./config/connection-strings'),
    carBrands = require('./scrapers/car-brands-scraper'),
    carBrandsDetails = require('./scrapers/car-brands-details-scraper'),
    timeMeasurement = require('./utils/time-measurement');

const startTime = Date.now();

Promise.resolve()
    .then(() => {
        if(process.env.mode === 'DEVELOPMENT') {
            process.env.MONGOLAB_URI = connectionStrings.uri;
        }

        return db.open(process.env.MONGOLAB_URI);
    })
    .then(() => {
        console.log(`\r\n${new Date().toLocaleString()}`);
        console.log('IDBM scraping started.\r\n');

        return carBrands.fillDatabaseWithCarBrands();
    })
    .then(() => {
        console.log(timeMeasurement.getElapsedTime(Date.now() - startTime));

        return carBrandsDetails.fillDatabaseWithCarBrandsDetails();
    })
    .then(() => {
        db.close();
        console.log('DB closed.\r\n');
        console.log(new Date().toLocaleString());
        console.log('Cars scraping finished.\r\n');

        console.log(timeMeasurement.getElapsedTime(Date.now() - startTime));
    })
    .catch(error => {
        console.log(`Error: ${error}`);

        db.close();
        console.log('DB closed.\r\n');
    });<commit_msg>disable ESLint no-process-env warning<commit_after>/* globals console require Promise */
/* eslint-disable no-process-env */
'use strict';

// comment this when deploy application
process.env.mode = 'DEVELOPMENT';

const db = require('./config/mongoose'),
    connectionStrings = require('./config/connection-strings'),
    carBrands = require('./scrapers/car-brands-scraper'),
    carBrandsDetails = require('./scrapers/car-brands-details-scraper'),
    timeMeasurement = require('./utils/time-measurement');

const startTime = Date.now();

Promise.resolve()
    .then(() => {
        if (process.env.mode === 'DEVELOPMENT') {
            process.env.MONGOLAB_URI = connectionStrings.uri;
        }

        return db.open(process.env.MONGOLAB_URI);
    })
    .then(() => {
        console.log(`\r\n${new Date().toLocaleString()}`);
        console.log('IDBM scraping started.\r\n');

        return carBrands.fillDatabaseWithCarBrands();
    })
    .then(() => {
        console.log(timeMeasurement.getElapsedTime(Date.now() - startTime));

        return carBrandsDetails.fillDatabaseWithCarBrandsDetails();
    })
    .then(() => {
        db.close();
        console.log('DB closed.\r\n');
        console.log(new Date().toLocaleString());
        console.log('Cars scraping finished.\r\n');

        console.log(timeMeasurement.getElapsedTime(Date.now() - startTime));
    })
    .catch(error => {
        console.log(`Error: ${error}`);

        db.close();
        console.log('DB closed.\r\n');
    });<|endoftext|>