<commit_before>$(document).ready(function() {
  // Get the credentials for use with PouchDB and Cloudant
  var getCredentials = function() {
    var url = getLocalUrl();
    return {
      remote: url,
      local: $('', { href: url })[0].pathname.substr(1),
    };
  };

  // Get details from lcoalStorage
  var getLocalUrl = function() {
    if (typeof Storage === 'object') {
      var url = localStorage.getItem('url');
      if (typeof url !== 'string') {
        var url = getFromApi();
        localStorage.setItem('url', url);
        return url;
      } else {
        return url;
      }
    } else {
      return getRemoteUrl();
    }
  };

  // Get details from API server
  var getRemoteUrl = function() {
    return JSON.parse($.ajax({
      url: 'https://droidconro.eu-gb.mybluemix.net?user=katytest',
      async: false,
    }).responseText).url;
  };

  // Database
  var dbConfig = getCredentials();

  // Local Pouch
  var db = PouchDB(dbConfig.local);

  // Sync to Cloudant
  db.sync(dbConfig.remote, {
    live: true,
    retry: true,
  });

  // Save new doc
  $('#chat').on('submit', function(e) {

    e.preventDefault();

    var doc = {
      user: $('#user').val(),
      message: $('#message').val(),
      timestamp: (new Date).toISOString(),
    };

    db.post(doc, function(err, body) {
      if (err) console.log(err);
      console.log(body);
    });

    return false;
  });

  // Display all IM's
  db.allDocs({include_docs: true},function(err, resp){
    for (var i = 0; i < resp.rows.length; i++) {
      var data = resp.rows[i];
      addMention(data);
      if(i==resp.rows.length-2) {
        sortMessage();
      }
    }
  });

  // See changes
  db.changes({
    since: 'now',
    live: true,
    include_docs: true,
  }).on('change', function(change) {
    // handle change
    if (change.deleted) {
      $('#' + change.doc._id).remove();
    } else {
      addMention(change);
      sortMessage();
    }
  }).on('complete', function(info) {
    // changes() was canceled
  }).on('error', function(err) {
    console.log(err);
  });

  // Template
  var addMention = function(data) {
    var dateObj = new Date(data.doc.timestamp);
    var html = '
';
    html += '
' + santise(data.doc.user) + ': ' + dateObj.toString() + '
';
    html += marked(data.doc.message);
    html += '
';
    html += '
';
    html += JSON.stringify(data.doc.insights, null, ' ');
    html += '
';
    html += '
';

    if (typeof $('#' + data.doc._id).html() == 'undefined') {
      $('#messageOutput').prepend(html);
    } else {
      $('#' + data.doc._id).html(html);
    }

    // View the extra data
    $('.open').on('click', function() {
      $(this).parent().children('pre').removeClass('hide');
    });

  };

  var sortMessage = function() {
    var ul = $('#messageOutput');
    var arr = $.makeArray(ul.children('div.row'));

    arr.sort(function(a, b) {
      var textA = +$(a).attr('data-timestamp');
      var textB = +$(b).attr('data-timestamp');

      if (textA < textB) return 1;
      if (textA > textB) return -1;

      return 0;
    });

    ul.empty();

    $.each(arr, function() {
      ul.append(this);
    });
  };

  var santise = function(str) {
    return str.replace(/(<([^>]+)>)/ig,"")
  };

});
<commit_msg>Add the delete function<commit_after>$(document).ready(function() {
  // Get the credentials for use with PouchDB and Cloudant
  var getCredentials = function() {
    var url = getLocalUrl();
    return {
      remote: url,
      local: $('', { href: url })[0].pathname.substr(1),
    };
  };

  // Get details from lcoalStorage
  var getLocalUrl = function() {
    if (typeof Storage === 'object') {
      var url = localStorage.getItem('url');
      if (typeof url !== 'string') {
        var url = getFromApi();
        localStorage.setItem('url', url);
        return url;
      } else {
        return url;
      }
    } else {
      return getRemoteUrl();
    }
  };

  // Get details from API server
  var getRemoteUrl = function() {
    return JSON.parse($.ajax({
      url: 'https://droidconro.eu-gb.mybluemix.net?user=katytest',
      async: false,
    }).responseText).url;
  };

  // Database
  var dbConfig = getCredentials();

  // Local Pouch
  var db = PouchDB(dbConfig.local);

  // Sync to Cloudant
  db.sync(dbConfig.remote, {
    live: true,
    retry: true,
  });

  // Save new doc
  $('#chat').on('submit', function(e) {

    e.preventDefault();

    var doc = {
      user: $('#user').val(),
      message: $('#message').val(),
      timestamp: (new Date).toISOString(),
    };

    db.post(doc, function(err, body) {
      if (err) console.log(err);
      console.log(body);
    });

    return false;
  });

  // Display all IM's
  db.allDocs({include_docs: true},function(err, resp){
    for (var i = 0; i < resp.rows.length; i++) {
      var data = resp.rows[i];
      addMention(data);
      if(i==resp.rows.length-2) {
        sortMessage();
      }
    }
  });

  // See changes
  db.changes({
    since: 'now',
    live: true,
    include_docs: true,
  }).on('change', function(change) {
    // handle change
    if (change.deleted) {
      $('#' + change.doc._id).remove();
    } else {
      addMention(change);
      sortMessage();
    }
  }).on('complete', function(info) {
    // changes() was canceled
  }).on('error', function(err) {
    console.log(err);
  });

  // Template
  var addMention = function(data) {
    var dateObj = new Date(data.doc.timestamp);
    var html = '
';
    html += '
' + santise(data.doc.user) + ': ' + dateObj.toString() + '
';
    html += marked(data.doc.message);
    html += '
';

    if ($('#user').val() === data.doc.user) {
      html += '';
    }

    html += '';
    html += '
';
    html += JSON.stringify(data.doc.insights, null, ' ');
    html += '
';
    html += '
';

    if (typeof $('#' + data.doc._id).html() == 'undefined') {
      $('#messageOutput').prepend(html);
    } else {
      $('#' + data.doc._id).html(html);
    }

    applyEvents();

  };

  var sortMessage = function() {
    var ul = $('#messageOutput');
    var arr = $.makeArray(ul.children('div.row'));

    arr.sort(function(a, b) {
      var textA = +$(a).attr('data-timestamp');
      var textB = +$(b).attr('data-timestamp');

      if (textA < textB) return 1;
      if (textA > textB) return -1;

      return 0;
    });

    ul.empty();

    $.each(arr, function() {
      ul.append(this);
    });

    applyEvents();
  };

  var santise = function(str) {
    return str.replace(/(<([^>]+)>)/ig, '');
  };

  var applyEvents = function() {

    // Delete Message
    $('.delete').on('click', function() {
      db.get($(this).parent().parent().attr('id'), function(err, doc) {
        if (err) { return console.log(err); }

        db.remove(doc, function(err, response) {
          if (err) { return console.log(err); }
        });
      });
    });

    // View the extra data
    $('.open').on('click', function() {
      $(this).parent().children('pre').removeClass('hide');
    });

  }

});
<|endoftext|>


<commit_before>/* Licensed under the MIT license:
 * http://www.opensource.org/licenses/mit-license.php
 * Copyright (c) 2010 Mr.doob, rhyolight, bebraw
 */
function ProxyCanvas(canvasId) {
    this.init(canvasId);
}
ProxyCanvas.prototype = {
    init: function (canvasId) {
        this.canvas = document.getElementById(canvasId);
        this.context = this.canvas.getContext("2d");

        this.width = this.canvas.width;
        this.height = this.canvas.height;

        this.strokes = new Strokes();
    },
    destroy: function () {},
    saveAs: function (format) {
        var isChrome =  navigator.userAgent.toLowerCase().indexOf('chrome')  > -1;

        if( isChrome ) {
            // apparently this work just with png?
            window.open(this.canvas.toDataURL('image/png'), 'mywindow');
        }
        else {
            // note that this spawns a save dialog! doesn't work in chrome!
            if(format == 'png') {
                Canvas2Image.saveAsPNG(this.canvas);
            }

            if(format == 'jpeg' || format == 'jpg') {
                Canvas2Image.saveAsJPEG(this.canvas);
            }

            if(format == 'bmp') {
                Canvas2Image.saveAsBMP(this.canvas);
            }
        }
    },
    getData: function () {
        return this.context.getImageData(0, 0, this.width, this.height);
    },
    setData: function (data) {
        this.context.putImageData(data, 0, 0);
    },
    fill: function (color) {
        this.context.fillStyle = "rgb(" + color[0] + ", " + color[1] +
            ", " + color[2] + ")";
        this.context.fillRect(0, 0, this.canvas.width, this.canvas.height);
    },
    text: function (label, colorName, font, x, y) {
        this.context.fillStyle = colorName;
        this.context.font = font;
        this.context.fillText(label, x, y);
    },
    stroke: function (startLoc, endLoc, color, alpha) {
        this.context.strokeStyle = "rgba(" + color[0] + ", " + color[1] +
            ", " + color[2] + ", " + alpha + ")";
        this.context.beginPath();
        this.context.moveTo(startLoc.x, startLoc.y);
        this.context.lineTo(endLoc.x, endLoc.y);
        this.context.stroke();
    },
    rect: function (xy1, xy2, xy3, xy4, color, alpha) {
        this.context.fillStyle = "rgb(255, 255, 255)"; // XXX: replace with fillColor
        this.context.strokeStyle = "rgba(" + color[0] + ", " + color[1] +
            ", " + color[2] + ", " + alpha + ")";
        this.context.beginPath();
        this.context.moveTo(xy1.x, xy1.y);
        this.context.lineTo(xy2.x, xy2.y);
        this.context.lineTo(xy3.x, xy3.y);
        this.context.lineTo(xy4.x, xy4.y);
        this.context.lineTo(xy1.x, xy1.y);
        this.context.fill();
        this.context.stroke();
    },
    bezierCurve: function (begin, cp1, cp2, end, color, alpha) {
        this.context.strokeStyle = "rgba(" + color[0] + ", " + color[1] +
            ", " + color[2] + ", " + alpha + ")";
        this.context.beginPath();
        this.context.moveTo(begin.x, begin.y);
        this.context.bezierCurveTo(cp1.x, cp1.y, cp2.x, cp2.y, end.x, end.y);
        this.context.stroke();
    },
    quadraticCurve: function (begin, cp, end, color, alpha) {
        this.context.strokeStyle = "rgba(" + color[0] + ", " + color[1] +
            ", " + color[2] + ", " + alpha + ")";
        this.context.beginPath();
        this.context.moveTo(begin.x, begin.y);
        this.context.quadraticCurveTo(cp.x, cp.y, end.x, end.y);
        this.context.stroke();
    },
    circle: function (center, radius, color, alpha) {
        this.context.strokeStyle = "rgba(" + color[0] + ", " + color[1] +
            ", " + color[2] + ", " + alpha + ")";
        this.context.beginPath();
        this.context.arc(center.x, center.y, radius, 0, Math.PI * 2, true);
        this.context.stroke()
    },
    getPointsInside: function (radius, location) { // TODO: change to work with current system! -> make a func?
        var points = panels['canvas'].points;
        var ret = [];

        for (var i = 0; i < points.length; i++) {
            point = points[i];

            if( Math.pow((location.x - point.x), 2) +
                    Math.pow((location.y - point.y), 2) <
                    Math.pow(radius, 2) ) {
                ret.push(point);
            }
        }

        return ret;
    },
    getAllPoints: function () { // XXX: cache?
        var ret = new Points();

        for( var brushName in this.strokes ) {
            ret.extend(this.getPointsOfType(brushName));
        }

        return ret;
    },
    getPointsOfType: function ( brushName ) {
        if( brushName in this.strokes ) {
            return this.strokes[brushName].points;
        }
    },
}

// XXX: separate derived strokes somehow?
function Strokes() {
    this.init();
}
Strokes.prototype = {
    init: function () {},
    destroy: function () {},
    push: function (brushName, points) {
        if( !this[brushName] ) {
            this[brushName] = new BrushStroke();
        }

        this[brushName].points.extend(points);
    }
}

function BrushStroke() {
    this.init();
}
BrushStroke.prototype = {
    init: function () {
        this.points = new Points();
    },
    destroy: function () {},
}
<commit_msg>Cached all points to speed up getAllPoints query.<commit_after>/* Licensed under the MIT license:
 * http://www.opensource.org/licenses/mit-license.php
 * Copyright (c) 2010 Mr.doob, rhyolight, bebraw
 */
function ProxyCanvas(canvasId) {
    this.init(canvasId);
}
ProxyCanvas.prototype = {
    init: function (canvasId) {
        this.canvas = document.getElementById(canvasId);
        this.context = this.canvas.getContext("2d");

        this.width = this.canvas.width;
        this.height = this.canvas.height;

        this.strokes = new Strokes();
    },
    destroy: function () {},
    saveAs: function (format) {
        var isChrome =  navigator.userAgent.toLowerCase().indexOf('chrome')  > -1;

        if( isChrome ) {
            // apparently this work just with png?
            window.open(this.canvas.toDataURL('image/png'), 'mywindow');
        }
        else {
            // note that this spawns a save dialog! doesn't work in chrome!
            if(format == 'png') {
                Canvas2Image.saveAsPNG(this.canvas);
            }

            if(format == 'jpeg' || format == 'jpg') {
                Canvas2Image.saveAsJPEG(this.canvas);
            }

            if(format == 'bmp') {
                Canvas2Image.saveAsBMP(this.canvas);
            }
        }
    },
    getData: function () {
        return this.context.getImageData(0, 0, this.width, this.height);
    },
    setData: function (data) {
        this.context.putImageData(data, 0, 0);
    },
    fill: function (color) {
        this.context.fillStyle = "rgb(" + color[0] + ", " + color[1] +
            ", " + color[2] + ")";
        this.context.fillRect(0, 0, this.canvas.width, this.canvas.height);
    },
    text: function (label, colorName, font, x, y) {
        this.context.fillStyle = colorName;
        this.context.font = font;
        this.context.fillText(label, x, y);
    },
    stroke: function (startLoc, endLoc, color, alpha) {
        this.context.strokeStyle = "rgba(" + color[0] + ", " + color[1] +
            ", " + color[2] + ", " + alpha + ")";
        this.context.beginPath();
        this.context.moveTo(startLoc.x, startLoc.y);
        this.context.lineTo(endLoc.x, endLoc.y);
        this.context.stroke();
    },
    rect: function (xy1, xy2, xy3, xy4, color, alpha) {
        this.context.fillStyle = "rgb(255, 255, 255)"; // XXX: replace with fillColor
        this.context.strokeStyle = "rgba(" + color[0] + ", " + color[1] +
            ", " + color[2] + ", " + alpha + ")";
        this.context.beginPath();
        this.context.moveTo(xy1.x, xy1.y);
        this.context.lineTo(xy2.x, xy2.y);
        this.context.lineTo(xy3.x, xy3.y);
        this.context.lineTo(xy4.x, xy4.y);
        this.context.lineTo(xy1.x, xy1.y);
        this.context.fill();
        this.context.stroke();
    },
    bezierCurve: function (begin, cp1, cp2, end, color, alpha) {
        this.context.strokeStyle = "rgba(" + color[0] + ", " + color[1] +
            ", " + color[2] + ", " + alpha + ")";
        this.context.beginPath();
        this.context.moveTo(begin.x, begin.y);
        this.context.bezierCurveTo(cp1.x, cp1.y, cp2.x, cp2.y, end.x, end.y);
        this.context.stroke();
    },
    quadraticCurve: function (begin, cp, end, color, alpha) {
        this.context.strokeStyle = "rgba(" + color[0] + ", " + color[1] +
            ", " + color[2] + ", " + alpha + ")";
        this.context.beginPath();
        this.context.moveTo(begin.x, begin.y);
        this.context.quadraticCurveTo(cp.x, cp.y, end.x, end.y);
        this.context.stroke();
    },
    circle: function (center, radius, color, alpha) {
        this.context.strokeStyle = "rgba(" + color[0] + ", " + color[1] +
            ", " + color[2] + ", " + alpha + ")";
        this.context.beginPath();
        this.context.arc(center.x, center.y, radius, 0, Math.PI * 2, true);
        this.context.stroke()
    },
    getPointsInside: function (radius, location) { // TODO: change to work with current system! -> make a func?
        var points = panels['canvas'].points;
        var ret = [];

        for (var i = 0; i < points.length; i++) {
            point = points[i];

            if( Math.pow((location.x - point.x), 2) +
                    Math.pow((location.y - point.y), 2) <
                    Math.pow(radius, 2) ) {
                ret.push(point);
            }
        }

        return ret;
    },
    getAllPoints: function () {
        return this.strokes.all;
    },
    getPointsOfType: function ( brushName ) {
        if( brushName in this.strokes ) {
            return this.strokes[brushName].points;
        }
    },
}

// XXX: separate derived strokes somehow?
function Strokes() {
    this.init();
}
Strokes.prototype = {
    init: function () {
        this.all = new Points();
    },
    destroy: function () {},
    push: function (brushName, points) {
        if( !this[brushName] ) {
            this[brushName] = new BrushStroke();
        }

        this[brushName].points.extend(points);

        this.all.extend(points);
    }
}

function BrushStroke() {
    this.init();
}
BrushStroke.prototype = {
    init: function () {
        this.points = new Points();
    },
    destroy: function () {},
}
<|endoftext|>


<commit_before>export default class GraphUtils {

  /**
   * Map from graphlib graph represnetation to d3 graph representation:
   *
   * for d3, links must be specified as pairs of d3 nodes array *indices*
   * via `source` and `target` attributes, as per:
   *
   *   https://github.com/mbostock/d3/wiki/Force-Layout#nodes
   *   https://github.com/mbostock/d3/wiki/Force-Layout#links
   *
   * other than that we pass on properties appended to the graphlib representation,
   * currently only the initial dagre computed initial location
   */
  mapToD3(displayGraph) {

    var nodeIdIndex = {};

    var nodes = displayGraph.nodes().map(function(id, index) {
      nodeIdIndex[id] = index;

      var d3Node = displayGraph.node(id);
      //d3Node.id = id // pass on the graphlib node id

      // set the initial location via px, py
      d3Node.px = displayGraph.node(id).x;
      d3Node.py = displayGraph.node(id).y;
      return d3Node;
    });

    var links = displayGraph.edges().map(function(edge) {
      return { source: nodeIdIndex[edge.v], // vertex specified as index into nodes array
               target: nodeIdIndex[edge.w], // vertex specified as index into nodes array
               v: edge.v,                   // pass on the graphlib node id
               w: edge.w,                   // pass on the graphlib node id
               edgeKind: displayGraph.edge(edge).edgeKind };
    });

    return { nodes, links };
  }

}
<commit_msg>switch to fat arrow syntax<commit_after>export default class GraphUtils {

  /**
   * Map from graphlib graph represnetation to d3 graph representation:
   *
   * for d3, links must be specified as pairs of d3 nodes array *indices*
   * via `source` and `target` attributes, as per:
   *
   *   https://github.com/mbostock/d3/wiki/Force-Layout#nodes
   *   https://github.com/mbostock/d3/wiki/Force-Layout#links
   *
   * other than that we pass on properties appended to the graphlib representation,
   * currently only the initial dagre computed initial location
   */
  mapToD3(displayGraph) {

    var nodeIdIndex = {};

    var nodes = displayGraph.nodes().map((id, index) => {
      nodeIdIndex[id] = index;

      var d3Node = displayGraph.node(id);
      //d3Node.id = id // pass on the graphlib node id

      // set the initial location via px, py
      d3Node.px = displayGraph.node(id).x;
      d3Node.py = displayGraph.node(id).y;
      return d3Node;
    });

    var links = displayGraph.edges().map(edge => {
      return { source: nodeIdIndex[edge.v], // vertex specified as index into nodes array
               target: nodeIdIndex[edge.w], // vertex specified as index into nodes array
               v: edge.v,                   // pass on the graphlib node id
               w: edge.w,                   // pass on the graphlib node id
               edgeKind: displayGraph.edge(edge).edgeKind };
    });

    return { nodes, links };
  }

}
<|endoftext|>


<commit_before>// Copyright 2013 Joyent, Inc. All rights reserved.

var fs = require('fs');
var path = require('path');

var assert = require('assert-plus');
var clone = require('clone');
var once = require('once');
var vasync = require('vasync');

var Queue = require('./queue').Queue;

///--- Helpers

function flatten_probes(opts) {
    assert.object(opts, 'options');
    assert.object(opts.probes, 'options.probes');
    assert.optionalArrayOfString(opts.role, 'options.role');

    var probes = [];

    Object.keys(opts.probes).forEach(function (k) {
        if (opts.role && opts.role.indexOf(k) === -1)
            return;

        opts.probes[k].forEach(function (p) {
            p.role = k;
        });

        probes = probes.concat(opts.probes[k]);
    });

    return (probes);
}

function read_role_files(opts, cb) {
    assert.object(opts, 'options');
    assert.object(opts.roles, 'options.roles');
    assert.func(cb, 'callback');

    vasync.forEachParallel({
        func: function (r, _cb) {
            _cb = once(_cb);

            var probes = {};
            probes[r] = [];
            var q = new Queue({
                limit: 5,
                worker: function (f, __cb) {
                    fs.readFile(f, 'utf8', function (err2, data) {
                        if (err2) {
                            __cb(err2);
                            return;
                        }

                        var obj;
                        try {
                            obj = JSON.parse(data);
                        } catch (e) {
                            __cb(e);
                            return;
                        }

                        if (Array.isArray(obj)) {
                            obj.forEach(function (o) {
                                if (probes[r].indexOf(o.name) === -1)
                                    probes[r].push(o);
                            });
                        } else {
                            if (probes[r].indexOf(obj.name) === -1)
                                probes[r].push(obj);
                        }

                        __cb();
                    });
                }
            });

            q.once('error', _cb);
            q.once('end', function () {
                _cb(null, probes);
            });

            var done = 0;
            function on_read_dir(err, files, root) {
                if (err) {
                    _cb(err);
                    return;
                }

                (files || []).filter(function (f) {
                    return (/\.json$/.test(f));
                }).map(function (f) {
                    return (path.resolve(root, f));
                }).forEach(function (f) {
                    q.push(f);
                });

                if (++done === opts.roles[r].files.length)
                    q.close();
            }

            opts.roles[r].files.forEach(function (f) {
                fs.readdir(f, function (err, files) {
                    on_read_dir(err, files || null, f);
                });
            });

        },
        inputs: Object.keys(opts.roles)
    }, function (err, results) {
        if (err) {
            cb(err);
            return;
        } else if (!results.successes.length) {
            cb(new Error('no probe definitions found'));
            return;
        }

        var probes = {};
        results.successes.forEach(function (p) {
            var k = Object.keys(p).pop();
            probes[k] = p[k];
        });

        opts.probes = probes;
        cb(null, probes);
    });
}

///--- API

function add_probes(opts, cb) {
    assert.object(opts, 'options');
    assert.object(opts.amon, 'options.amon');
    assert.object(opts.application, 'options.application');
    assert.number(opts.concurrency, 'options.concurrency');
    assert.arrayOfString(opts.contacts, 'options.contacts');
    assert.object(opts.levels, 'options.levels');
    assert.object(opts.probes, 'options.probes');
    assert.string(opts.user, 'options.user');
    assert.func(cb, 'callback');

    cb = once(cb);
    opts.count = 0;

    var roles = opts.application.roles;

    var q = new Queue({
        limit: opts.concurrency,
        worker: function (p, _cb) {
            var t = p.target;
            if (p.level)
                delete p.level;
            if (p.role)
                delete p.role;
            if (p.target)
                delete p.target;

            var re = /{{(.*)}}/;
            if (p.type === 'cmd' && re.test(p.config.cmd)) {
                opts.sapi.getInstance(t, function (err, instance) {
                    if (err) {
                        _cb(err);
                        return;
                    }

                    var md = instance.metadata;
                    var match = re.exec(p.config.cmd);

                    if (match && md[match[1]]) {
                        var re2 = new RegExp('{{' + match[1] +'}}');
                        p.config.cmd = p.config.cmd.replace(re2, md[match[1]]);
                    }

                    opts.amon.createProbe(opts.user, p, _cb);
                });
            } else {
                opts.amon.createProbe(opts.user, p, _cb);
            }
        }
    });
    q.once('error', cb);
    q.once('end', cb);

    if (!Object.keys(opts.probes).length) {
        q.close();
        return;
    }

    opts.amon.listProbeGroups(opts.user, function (err, groups) {
        if (err) {
            cb(err);
            return;
        }
        var _groups = {};
        var _gzs = {};
        var gq = new Queue({
            limit: 1,
            worker: function addGlobalProbes(probe, _cb) {
                function _push() {
                    opts.count++;
                    if (probe.level)
                        delete probe.level;
                    if (probe.role)
                        delete probe.role;
                    q.push(probe);
                    _cb();
                }

                var k = probe.role + '-' + probe.level;
                if (_groups[k]) {
                    probe.group = _groups[k].uuid;
                    _push();
                    return;
                }

                var u = opts.user;
                var _g = {
                    contacts: opts.levels[probe.level],
                    name: k
                };

                opts.amon.createProbeGroup(u, _g, function (e, g) {
                    if (e) {
                        _cb(e);
                    } else {
                        _groups[g.name] = g;
                        probe.group = g.uuid;
                        _push();
                    }
                });
            }
        });
        gq.once('error', cb);
        gq.once('end', function () {
            q.close();
        });

        (groups || []).forEach(function (g) {
            _groups[g.name] = g;
        });

        var pushed = 0;
        function push(p, vm) {
            var p2 = clone(p);

            if (p2.global) {
                p2.agent = vm.cn;
                delete p2.global;

                // If it's a GZ probe, we only want to
                // add once per probe per GZ so we just track
                // that here and drop if we've already run it.
                // Notably the marlin-agent would otherwise have
                // a logscan/etc per compute zone.
                var gzk = p2.agent + ':' + p2.name;
                if (_gzs[gzk])
                    return;
                _gzs[gzk] = true;
            } else if (p2.agent) {
                var _agent = roles[p2.agent];
                if (_agent) {
                    p2.agent = _agent[0].uuid;
                    p2.target = vm.uuid;
                } else {
                    console.error('agent %s not found (used in probe=%s)',
                                  p2.agent, JSON.stringify(p2, null, 2));
                    return;
                }
            } else {
                p2.agent = vm.uuid;
            }

            var l = p.level || 'alert';
            var g = _groups[p.role + '-' + l];

            if (!p2.level)
                p2.level = l;

            if (g) {
                delete p2.role;
                p2.group = g.uuid;
                opts.count++;
                q.push(p2);
            } else {
                gq.push(p2);
            }
            pushed++;
        }

        var probes = flatten_probes(opts);
        probes.forEach(function (p) {
            if (!roles[p.role])
                return;

            if (opts.role && opts.role.indexOf(p.role) === -1)
                return;

            if (opts.machine) {
                opts.machine.forEach(function (m) {
                    roles[p.role].forEach(function (vm) {
                        var id;
                        if (p.global) {
                            id = vm.cn;
                        } else {
                            id = vm.uuid;
                        }

                        if (id.contains(m))
                            push(p, vm);
                    });
                });
            } else {
                Object.keys(roles).forEach(function (k) {
                    var r = roles[k];
                    r.forEach(function (vm) {
                        if (p.role === vm.role)
                            push(p, vm);
                    });
                });
            }
        });

        gq.close();
        if (pushed === opts.count)
            q.close();
    });
}

function drop_probes(opts, cb) {
    assert.object(opts, 'options');
    assert.object(opts.amon, 'options.amon');
    assert.number(opts.concurrency, 'options.concurrency');
    assert.arrayOfObject(opts.probes, 'options.probes');
    assert.arrayOfObject(opts.probeGroups, 'options.probeGroups');
    assert.string(opts.user, 'options.user');
    assert.func(cb, 'callback');

    cb = once(cb);

    var q = new Queue({
        limit: opts.concurrency,
        worker: function (p, _cb) {
            opts.amon.deleteProbe(opts.user, p, _cb);
        }
    });

    opts.probes.forEach(function (p) {
        q.push(p.uuid);
    });

    q.once('error', cb);
    q.once('end', function () {
        var deleteQueue = new Queue({
            limit: opts.concurrency,
            worker: function (pg, _cb) {
                opts.amon.deleteProbeGroup(opts.user, pg.uuid, _cb);
            }
        });

        deleteQueue.once('error', cb);
        deleteQueue.once('end', cb);

        if (opts.role && opts.role.length) {
            opts.role.forEach(function (r) {
                opts.probeGroups.forEach(function (pg) {
                    if (r.test(pg.name))
                        deleteQueue.push(pg);
                });
            });
        } else {
            opts.probeGroups.forEach(function (pg) {
                deleteQueue.push(pg);
            });
        }
        deleteQueue.close();
    });
    q.close();
}

function filter_probes(opts, cb) {
    assert.object(opts, 'options');
    assert.object(opts.application, 'options.application');
    assert.object(opts.log, 'options.log');
    assert.optionalArrayOfString(opts.machine, 'options.machine');
    assert.optionalArrayOfString(opts.role, 'options.role');
    assert.func(cb, 'callback');

    cb = once(cb);

    // Here we're replacing `-$level` at the end of probe role
    // names back to just the role.
    opts.probes.forEach(function (p) {
        if (/-\w+$/.test(p.role)) {
            p.level = /-(\w+)$/.exec(p.role)[1];
            p.role = p.role.replace(/-\w+$/, '');
        }
    });

    if (opts.role && opts.role.length) {
        opts.probes = opts.probes.filter(function (p) {
            return (opts.role.indexOf(p.role) !== -1);
        });
    }

    if (opts.machine && opts.machine.length) {
        opts.probes = opts.probes.filter(function (p) {
            return (opts.machine.some(function (m) {
                return (p.agent.contains(m));
            }));
        });
    }

    cb(null, opts.probes);
}

function list_probes(opts, cb) {
    assert.object(opts, 'options');
    assert.object(opts.amon, 'options.amon');
    assert.object(opts.log, 'options.log');
    assert.string(opts.user, 'options.user');
    assert.func(cb, 'callback');

    cb = once(cb);

    opts.amon.listProbes(opts.user, function (err, probes) {
        if (err) {
            cb(err);
            return;
        }

        opts.amon.listProbeGroups(opts.user, function (err2, groups) {
            if (err) {
                cb(err);
                return;
            }

            probes = probes.map(function (p) {
                groups.some(function (g) {
                    if (g.uuid === p.group)
                        p.role = g.name;
                    return (p.role !== undefined);
                });
                return (p);
            });

            probes.sort(function (a, b) {
                if (a.role < b.role)
                    return (-1);
                if (a.role > b.role)
                    return (1);
                if (a.agent < b.agent)
                    return (-1);
                if (a.agent > b.agent)
                    return (1);
                if (a.uuid < b.uuid)
                    return (-1);
                if (a.uuid > b.uuid)
                    return (1);
                return (0);
            });

            opts.probes = probes;
            opts.probeGroups = groups;
            cb(null, probes);
        });
    });
}

function read_probe_files(opts, cb) {
    assert.object(opts, 'options');
    assert.object(opts.log, 'options.log');
    assert.optionalArrayOfString(opts.role, 'options.role');
    assert.func(cb, 'callback');

    cb = once(cb);

    opts.probes = [];
    var log = opts.log;
    var params = {
        log: log,
        roles: {}
    };

    function _cb(err, probes) {
        if (err) {
            cb(err);
        } else {
            opts.probes = probes;
            cb(err, probes);
        }
    }

    if (opts.role && opts.role.length) {
        opts.role.forEach(function (r) {
            // Ugh, special case "compute"
            params.roles[r] = {
                files: [
                    path.resolve(__dirname, '../', 'probes', r)
                ]
            };
            if (r !== 'compute') {
                var c = path.resolve(__dirname, '../', 'probes', 'common');
                params.roles[r].files.push(c);
            }
        });
        read_role_files(params, _cb);
        return;
    }

    fs.readdir(path.resolve(__dirname, '../', 'probes'), function (err, files) {
        if (err) {
            cb(err);
            return;
        }

        files.forEach(function (f) {
            if (f === 'common')
                return;

            params.roles[f] = {
                files: [
                    path.resolve(__dirname, '../', 'probes', f)
                ]
            };

            if (f !== 'compute') {
                var c = path.resolve(__dirname, '../', 'probes', 'common');
                params.roles[f].files.push(c);
            }
        });

        read_role_files(params, _cb);
    });
}

///--- Exports

module.exports = {
    add_probes: add_probes,
    drop_probes: drop_probes,
    filter_probes: filter_probes,
    list_probes: list_probes,
    read_probe_files: read_probe_files
};
<commit_msg>MANTA-2258: don't crash on mantamon drop -r<commit_after>// Copyright 2013 Joyent, Inc. All rights reserved.

var fs = require('fs');
var path = require('path');

var assert = require('assert-plus');
var clone = require('clone');
var once = require('once');
var vasync = require('vasync');

var Queue = require('./queue').Queue;

///--- Helpers

function flatten_probes(opts) {
    assert.object(opts, 'options');
    assert.object(opts.probes, 'options.probes');
    assert.optionalArrayOfString(opts.role, 'options.role');

    var probes = [];

    Object.keys(opts.probes).forEach(function (k) {
        if (opts.role && opts.role.indexOf(k) === -1)
            return;

        opts.probes[k].forEach(function (p) {
            p.role = k;
        });

        probes = probes.concat(opts.probes[k]);
    });

    return (probes);
}

function read_role_files(opts, cb) {
    assert.object(opts, 'options');
    assert.object(opts.roles, 'options.roles');
    assert.func(cb, 'callback');

    vasync.forEachParallel({
        func: function (r, _cb) {
            _cb = once(_cb);

            var probes = {};
            probes[r] = [];
            var q = new Queue({
                limit: 5,
                worker: function (f, __cb) {
                    fs.readFile(f, 'utf8', function (err2, data) {
                        if (err2) {
                            __cb(err2);
                            return;
                        }

                        var obj;
                        try {
                            obj = JSON.parse(data);
                        } catch (e) {
                            __cb(e);
                            return;
                        }

                        if (Array.isArray(obj)) {
                            obj.forEach(function (o) {
                                if (probes[r].indexOf(o.name) === -1)
                                    probes[r].push(o);
                            });
                        } else {
                            if (probes[r].indexOf(obj.name) === -1)
                                probes[r].push(obj);
                        }

                        __cb();
                    });
                }
            });

            q.once('error', _cb);
            q.once('end', function () {
                _cb(null, probes);
            });

            var done = 0;
            function on_read_dir(err, files, root) {
                if (err) {
                    _cb(err);
                    return;
                }

                (files || []).filter(function (f) {
                    return (/\.json$/.test(f));
                }).map(function (f) {
                    return (path.resolve(root, f));
                }).forEach(function (f) {
                    q.push(f);
                });

                if (++done === opts.roles[r].files.length)
                    q.close();
            }

            opts.roles[r].files.forEach(function (f) {
                fs.readdir(f, function (err, files) {
                    on_read_dir(err, files || null, f);
                });
            });

        },
        inputs: Object.keys(opts.roles)
    }, function (err, results) {
        if (err) {
            cb(err);
            return;
        } else if (!results.successes.length) {
            cb(new Error('no probe definitions found'));
            return;
        }

        var probes = {};
        results.successes.forEach(function (p) {
            var k = Object.keys(p).pop();
            probes[k] = p[k];
        });

        opts.probes = probes;
        cb(null, probes);
    });
}

///--- API

function add_probes(opts, cb) {
    assert.object(opts, 'options');
    assert.object(opts.amon, 'options.amon');
    assert.object(opts.application, 'options.application');
    assert.number(opts.concurrency, 'options.concurrency');
    assert.arrayOfString(opts.contacts, 'options.contacts');
    assert.object(opts.levels, 'options.levels');
    assert.object(opts.probes, 'options.probes');
    assert.string(opts.user, 'options.user');
    assert.func(cb, 'callback');

    cb = once(cb);
    opts.count = 0;

    var roles = opts.application.roles;

    var q = new Queue({
        limit: opts.concurrency,
        worker: function (p, _cb) {
            var t = p.target;
            if (p.level)
                delete p.level;
            if (p.role)
                delete p.role;
            if (p.target)
                delete p.target;

            var re = /{{(.*)}}/;
            if (p.type === 'cmd' && re.test(p.config.cmd)) {
                opts.sapi.getInstance(t, function (err, instance) {
                    if (err) {
                        _cb(err);
                        return;
                    }

                    var md = instance.metadata;
                    var match = re.exec(p.config.cmd);

                    if (match && md[match[1]]) {
                        var re2 = new RegExp('{{' + match[1] +'}}');
                        p.config.cmd = p.config.cmd.replace(re2, md[match[1]]);
                    }

                    opts.amon.createProbe(opts.user, p, _cb);
                });
            } else {
                opts.amon.createProbe(opts.user, p, _cb);
            }
        }
    });
    q.once('error', cb);
    q.once('end', cb);

    if (!Object.keys(opts.probes).length) {
        q.close();
        return;
    }

    opts.amon.listProbeGroups(opts.user, function (err, groups) {
        if (err) {
            cb(err);
            return;
        }
        var _groups = {};
        var _gzs = {};
        var gq = new Queue({
            limit: 1,
            worker: function addGlobalProbes(probe, _cb) {
                function _push() {
                    opts.count++;
                    if (probe.level)
                        delete probe.level;
                    if (probe.role)
                        delete probe.role;
                    q.push(probe);
                    _cb();
                }

                var k = probe.role + '-' + probe.level;
                if (_groups[k]) {
                    probe.group = _groups[k].uuid;
                    _push();
                    return;
                }

                var u = opts.user;
                var _g = {
                    contacts: opts.levels[probe.level],
                    name: k
                };

                opts.amon.createProbeGroup(u, _g, function (e, g) {
                    if (e) {
                        _cb(e);
                    } else {
                        _groups[g.name] = g;
                        probe.group = g.uuid;
                        _push();
                    }
                });
            }
        });
        gq.once('error', cb);
        gq.once('end', function () {
            q.close();
        });

        (groups || []).forEach(function (g) {
            _groups[g.name] = g;
        });

        var pushed = 0;
        function push(p, vm) {
            var p2 = clone(p);

            if (p2.global) {
                p2.agent = vm.cn;
                delete p2.global;

                // If it's a GZ probe, we only want to
                // add once per probe per GZ so we just track
                // that here and drop if we've already run it.
                // Notably the marlin-agent would otherwise have
                // a logscan/etc per compute zone.
                var gzk = p2.agent + ':' + p2.name;
                if (_gzs[gzk])
                    return;
                _gzs[gzk] = true;
            } else if (p2.agent) {
                var _agent = roles[p2.agent];
                if (_agent) {
                    p2.agent = _agent[0].uuid;
                    p2.target = vm.uuid;
                } else {
                    console.error('agent %s not found (used in probe=%s)',
                                  p2.agent, JSON.stringify(p2, null, 2));
                    return;
                }
            } else {
                p2.agent = vm.uuid;
            }

            var l = p.level || 'alert';
            var g = _groups[p.role + '-' + l];

            if (!p2.level)
                p2.level = l;

            if (g) {
                delete p2.role;
                p2.group = g.uuid;
                opts.count++;
                q.push(p2);
            } else {
                gq.push(p2);
            }
            pushed++;
        }

        var probes = flatten_probes(opts);
        probes.forEach(function (p) {
            if (!roles[p.role])
                return;

            if (opts.role && opts.role.indexOf(p.role) === -1)
                return;

            if (opts.machine) {
                opts.machine.forEach(function (m) {
                    roles[p.role].forEach(function (vm) {
                        var id;
                        if (p.global) {
                            id = vm.cn;
                        } else {
                            id = vm.uuid;
                        }

                        if (id.contains(m))
                            push(p, vm);
                    });
                });
            } else {
                Object.keys(roles).forEach(function (k) {
                    var r = roles[k];
                    r.forEach(function (vm) {
                        if (p.role === vm.role)
                            push(p, vm);
                    });
                });
            }
        });

        gq.close();
        if (pushed === opts.count)
            q.close();
    });
}

function drop_probes(opts, cb) {
    assert.object(opts, 'options');
    assert.object(opts.amon, 'options.amon');
    assert.number(opts.concurrency, 'options.concurrency');
    assert.arrayOfObject(opts.probes, 'options.probes');
    assert.arrayOfObject(opts.probeGroups, 'options.probeGroups');
    assert.string(opts.user, 'options.user');
    assert.func(cb, 'callback');

    cb = once(cb);

    var q = new Queue({
        limit: opts.concurrency,
        worker: function (p, _cb) {
            opts.amon.deleteProbe(opts.user, p, _cb);
        }
    });

    opts.probes.forEach(function (p) {
        q.push(p.uuid);
    });

    q.once('error', cb);
    q.once('end', function () {
        var deleteQueue = new Queue({
            limit: opts.concurrency,
            worker: function (pg, _cb) {
                opts.amon.deleteProbeGroup(opts.user, pg.uuid, _cb);
            }
        });

        deleteQueue.once('error', cb);
        deleteQueue.once('end', cb);

        if (opts.role && opts.role.length) {
            opts.role.forEach(function (r) {
                var re = new RegExp(r);
                opts.probeGroups.forEach(function (pg) {
                    if (re.test(pg.name))
                        deleteQueue.push(pg);
                });
            });
        } else {
            opts.probeGroups.forEach(function (pg) {
                deleteQueue.push(pg);
            });
        }
        deleteQueue.close();
    });
    q.close();
}

function filter_probes(opts, cb) {
    assert.object(opts, 'options');
    assert.object(opts.application, 'options.application');
    assert.object(opts.log, 'options.log');
    assert.optionalArrayOfString(opts.machine, 'options.machine');
    assert.optionalArrayOfString(opts.role, 'options.role');
    assert.func(cb, 'callback');

    cb = once(cb);

    // Here we're replacing `-$level` at the end of probe role
    // names back to just the role.
    opts.probes.forEach(function (p) {
        if (/-\w+$/.test(p.role)) {
            p.level = /-(\w+)$/.exec(p.role)[1];
            p.role = p.role.replace(/-\w+$/, '');
        }
    });

    if (opts.role && opts.role.length) {
        opts.probes = opts.probes.filter(function (p) {
            return (opts.role.indexOf(p.role) !== -1);
        });
    }

    if (opts.machine && opts.machine.length) {
        opts.probes = opts.probes.filter(function (p) {
            return (opts.machine.some(function (m) {
                return (p.agent.contains(m));
            }));
        });
    }

    cb(null, opts.probes);
}

function list_probes(opts, cb) {
    assert.object(opts, 'options');
    assert.object(opts.amon, 'options.amon');
    assert.object(opts.log, 'options.log');
    assert.string(opts.user, 'options.user');
    assert.func(cb, 'callback');

    cb = once(cb);

    opts.amon.listProbes(opts.user, function (err, probes) {
        if (err) {
            cb(err);
            return;
        }

        opts.amon.listProbeGroups(opts.user, function (err2, groups) {
            if (err) {
                cb(err);
                return;
            }

            probes = probes.map(function (p) {
                groups.some(function (g) {
                    if (g.uuid === p.group)
                        p.role = g.name;
                    return (p.role !== undefined);
                });
                return (p);
            });

            probes.sort(function (a, b) {
                if (a.role < b.role)
                    return (-1);
                if (a.role > b.role)
                    return (1);
                if (a.agent < b.agent)
                    return (-1);
                if (a.agent > b.agent)
                    return (1);
                if (a.uuid < b.uuid)
                    return (-1);
                if (a.uuid > b.uuid)
                    return (1);
                return (0);
            });

            opts.probes = probes;
            opts.probeGroups = groups;
            cb(null, probes);
        });
    });
}

function read_probe_files(opts, cb) {
    assert.object(opts, 'options');
    assert.object(opts.log, 'options.log');
    assert.optionalArrayOfString(opts.role, 'options.role');
    assert.func(cb, 'callback');

    cb = once(cb);

    opts.probes = [];
    var log = opts.log;
    var params = {
        log: log,
        roles: {}
    };

    function _cb(err, probes) {
        if (err) {
            cb(err);
        } else {
            opts.probes = probes;
            cb(err, probes);
        }
    }

    if (opts.role && opts.role.length) {
        opts.role.forEach(function (r) {
            // Ugh, special case "compute"
            params.roles[r] = {
                files: [
                    path.resolve(__dirname, '../', 'probes', r)
                ]
            };
            if (r !== 'compute') {
                var c = path.resolve(__dirname, '../', 'probes', 'common');
                params.roles[r].files.push(c);
            }
        });
        read_role_files(params, _cb);
        return;
    }

    fs.readdir(path.resolve(__dirname, '../', 'probes'), function (err, files) {
        if (err) {
            cb(err);
            return;
        }

        files.forEach(function (f) {
            if (f === 'common')
                return;

            params.roles[f] = {
                files: [
                    path.resolve(__dirname, '../', 'probes', f)
                ]
            };

            if (f !== 'compute') {
                var c = path.resolve(__dirname, '../', 'probes', 'common');
                params.roles[f].files.push(c);
            }
        });

        read_role_files(params, _cb);
    });
}

///--- Exports

module.exports = {
    add_probes: add_probes,
    drop_probes: drop_probes,
    filter_probes: filter_probes,
    list_probes: list_probes,
    read_probe_files: read_probe_files
};
<|endoftext|>


<commit_before>/*
 * Rapid Interface Builder (RIB) - A simple WYSIWYG HTML5 app creator
 * Copyright (c) 2011-2012, Intel Corporation.
 *
 * This program is licensed under the terms and conditions of the
 * Apache License, version 2.0.  The full text of the Apache License is at
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 */
"use strict";

// Layout view widget

(function ($, undefined) {

    $.widget('rib.layoutView', $.rib.baseView, {

        options: {
            iframe: null,
            contentDocument: null,
            customHeaders: {
                'meta': [
                    '<meta http-equiv="cache-control" content="no-cache">'
                ],
                'script': [
                    '',
                    ''
                ],
                'link': [
                    '<link href="src/css/composer.css" rel="stylesheet">'
                ]
            }
        },

        _create: function () {
            var o = this.options,
                e = this.element;

            // Chain up to base class _create()
            $.rib.baseView.prototype._create.call(this);

            this.options.iframe = this.element.find('iframe');
            if (!this.options.iframe.length) {
                this.options.iframe = $('');
            }

            this.options.iframe.addClass(this.widgetName)
                .addClass('flex1')
                .appendTo(this.element);

            this.options.contentDocument =
                $(this.options.iframe[0].contentDocument);

            $(window).resize(this, function (event) {
                var el = event.data.element,
                    doc = event.data.options.contentDocument,
                    iframe = event.data.options.iframe;

                // Nothing to resize if iframe contents has not been loaded
                if (!event || !event.data || !event.data.loaded) return;

                // Force resize of the stage when containing window resizes
                el.height(el.parent().height());
                el.find('div').height(el.parent().height());
                // Force resize of the iframe when containing window resizes
                iframe.height(doc.height());
                iframe.css('min-height',
                            el.height() - 2
                            - parseFloat(iframe.css('margin-top'))
                            - parseFloat(iframe.css('margin-bottom'))
                            - parseFloat(iframe.css('padding-bottom'))
                            - parseFloat(iframe.css('padding-bottom')));
            });

            return this;
        },

        _setOption: function (key, value) {
            // Chain up to base class _setOptions()
            // FIXME: In jquery UI 1.9 and above, instead use
            //    this._super('_setOption', key, value)
            $.rib.baseView.prototype._setOption.apply(this, arguments);

            switch (key) {
                // Should this REALLY be done here, or plugin registration in
                // the "host"... using the functions mapped in widget options?
                case 'model':
                    this._createDocument();
                    this.options.iframe.load(this, this._iframeLoaded);
                    break;
                default:
                    break;
            }
        },

        refresh: function (event, widget) {
            var name, visible;
            widget = widget || event && event.data || this;
            name = (event)?(event.name)?event.name:event.type:'';
            visible = widget.element.data('visible');

            if (!widget.loaded) {
                return;
            }

            if (event && (name !== 'designReset') && !visible) {
                return;
            }

            if ((!event) || (name === 'load' ||
                             name === 'designReset' ||
                             name === 'modelUpdated')) {
                // Update headers if Design's properties changed
                if (name === "designReset" || (name  === 'modelUpdated'
                            && event.node && event.node.getType() === 'Design')) {
                    widget._createDocument();
                }
                widget._serializeADMDesignToDOM();
/* FIXME: Calling serializeADMSubtreeToDom is not actually forcing the
          the DOM to update, but it should work...

                switch (event.type) {
                    case 'nodeAdded':
                    case 'nodeRemoved':
                        serializeADMSubtreeToDOM(event.parent, null,
                                                 widget._renderer);
                        break;
                    case 'nodeMoved':
                        serializeADMSubtreeToDOM(event.oldParent, null,
                                                 widget._renderer);
                        serializeADMSubtreeToDOM(event.newParent, null,
                                                 widget._renderer);
                        break;
                    case 'propertyChanged':
                        serializeADMSubtreeToDOM(event.node, null,
                                                 widget._renderer);
                        break;
                    default:
                        console.warn(widget.widgetName,
                                     ':: Unexpected modelUpdate type:',
                                     event.type);
                        return;
                        break;
                }
*/
            } else {
                console.warn(widget.widgetName,':: Unexpected event:',name);
                return;
            }

            if (widget.options.contentDocument.length) {
                widget.options.contentDocument[0].defaultView
                    .postMessage('reload', '*');
            } else {
                console.error(widget.widgetName, ':: Missing contentDocument');
            }
        },

        // Private functions
        _iframeLoaded: function (event) {
            event.data.loaded = true;
            event.data.refresh(null, event.data);
            $.rib.enableKeys(event.data.options.contentDocument);
            event.data.options.contentDocument[0].contentEditable = false;
        },

        _createPrimaryTools: function () {
            var doc, html, classes, selector,
                commands = ['undo', 'redo', 'cut', 'copy', 'paste'];

            classes = "buttonStyle primary-tools ui-state-default";
            html = $('
').addClass('hbox').hide();
            $.each(commands, function (index, command) {
                $('<button/>').addClass(classes)
                    .attr('id', 'btn' + command)
                    .appendTo(html);
            });

            doc = $((this.element)[0].ownerDocument);
            selector = "button.primary-tools"
            doc.delegate(selector, "click", jQuery.proxy(function (event) {
                var model = this.options.model;
                if (model) {
                    switch (event.currentTarget.id) {
                    case "btnundo":  model.undo();  break;
                    case "btnredo":  model.redo();  break;
                    case "btncut":   model.cut();   break;
                    case "btncopy":  model.copy();  break;
                    case "btnpaste": model.paste(); break;
                    default:
                        console.warn("Unhandled click on primary tool");
                        break;
                    }
                }
                else {
                    console.warn("No model while attempting undo");
                }
            }, this));

            return html;
        },

        _createSecondaryTools: function () {
            return $(null);
        },

        _selectionChangedHandler: function (event, widget) {
            var uid;
            widget = widget || this;

            // Always un-style currently selected nodes
            widget.options.contentDocument.find('.ui-selected')
                .removeClass('ui-selected');

            // Only apply selection style changes on valid nodes
            if (!event || (!event.uid && !event.node)) {
                return;
            }

            // Normally, ADM node id is provided in event.uid
            uid = event && event.uid;
            // Fallback is to try event.node.getUid()
            uid = uid || (event.node)?event.node.getUid():null;

            if (uid) {
                widget.options.contentDocument
                    .find('.adm-node[data-uid=\''+uid+'\']')
                    .not('[data-role=\'page\']')
                    .addClass('ui-selected').first().each(function () {
                        // Scroll selected node into view
                        setTimeout($.proxy(function () {
                            this.scrollIntoViewIfNeeded()
                        }, this), 100);
                    });
            }
        },

        _activePageChangedHandler: function (event, widget) {
            var win,
                newPage = event && event.page,
                id = newPage && newPage.getProperty('id');

            widget = widget || this;

            // Only change if new page is valid
            if (!newPage) {
                return;
            }

            win = widget.options.contentDocument[0].defaultView;

            if (win && win.$ && win.$.mobile) {
                if (win.$.mobile.activePage &&
                    win.$.mobile.activePage.attr('id') !== id) {
                    win.$.mobile.changePage("#"+id, {transition: "none"});
                }
            }
        },

        _modelUpdatedHandler: function (event, widget) {
            var win, aPage, pageNode,
                oldScrollTop = (widget.options.contentDocument.scrollTop());

            widget = widget || this;

            widget.refresh(event, widget);

            win = widget.options.contentDocument[0].defaultView;
            if (win && win.$ && win.$.mobile) {
                aPage = widget.options.model.getActivePage();
                if (aPage) {
                    pageNode = win.$('#' + aPage.getProperty('id'));
                    if (pageNode.length) {
                        win.$.mobile.changePage(pageNode);
                    } else {
                        // TODO: this is okay when last page is deleted, so
                        //       maybe this warning can be removed
                        console.warn("No such page found: ",
                                     aPage.getProperty('id'));
                    }
                } else {
                    win.$.mobile.initializePage();
                }
            } else {
                console.error(widget.widgetName, ':: Missing contentDocument');
            }
            widget.options.contentDocument.scrollTop(oldScrollTop);
            // Make sure Make sure selected node is visible
            widget.options.contentDocument.find('.ui-selected').first().each(function () {
                this.scrollIntoViewIfNeeded()
            });
        },

        _createDocument: function () {
            var contents, doc;

            if (!this.designRoot) return;

            doc = this.options.contentDocument[0];
            doc.open();
            contents = this._serializeFramework(this.designRoot);
            doc.writeln(contents);
            doc.close();
        },

        _serializeFramework: function () {
            var start, end, ret, headers;

            headers = this._getCustomHeaders();

            start = '<!DOCTYPE html>\n <title>Page Title</title>\n';
            end = "\n\n\n";

            if (headers && headers.length > 0) {
                ret = start + headers.join('\n') + end;
            } else {
                ret = start + end;
            }

            return ret;
        },

        // Great assumptions are being made here that the incoming default
        // headers are already "sorted" and in the order in which they should
        // be inserted into the  node of the document being created...
        _getCustomHeaders: function () {
            var dh = $.rib.getDesignHeaders(),   // default headers
                ch = this.options.customHeaders, // our custom headers
                m, s;

            $.each(dh, function (idx) {
                if (/<meta/.test(this)) {
                    m = idx+1; // Insert our Meta after LAST one
                    return;
                }
                if (/',
                    ''
                ],
                'link': [
                    '<link href="src/css/composer.css" rel="stylesheet">'
                ]
            }
        },

        _create: function () {
            var o = this.options,
                e = this.element;

            // Chain up to base class _create()
            $.rib.baseView.prototype._create.call(this);

            this.options.iframe = this.element.find('iframe');
            if (!this.options.iframe.length) {
                this.options.iframe = $('');
            }

            this.options.iframe.addClass(this.widgetName)
                .addClass('flex1')
                .appendTo(this.element);

            this.options.contentDocument =
                $(this.options.iframe[0].contentDocument);

            $(window).resize(this, function (event) {
                var el = event.data.element,
                    doc = event.data.options.contentDocument,
                    iframe = event.data.options.iframe;

                // Nothing to resize if iframe contents has not been loaded
                if (!event || !event.data || !event.data.loaded) return;

                // Force resize of the stage when containing window resizes
                el.height(el.parent().height());
                el.find('div').height(el.parent().height());
                // Force resize of the iframe when containing window resizes
                iframe.height(doc.height());
                iframe.css('min-height',
                            el.height() - 2
                            - parseFloat(iframe.css('margin-top'))
                            - parseFloat(iframe.css('margin-bottom'))
                            - parseFloat(iframe.css('padding-bottom'))
                            - parseFloat(iframe.css('padding-bottom')));
            });

            return this;
        },

        _setOption: function (key, value) {
            // Chain up to base class _setOptions()
            // FIXME: In jquery UI 1.9 and above, instead use
            //    this._super('_setOption', key, value)
            $.rib.baseView.prototype._setOption.apply(this, arguments);

            switch (key) {
                // Should this REALLY be done here, or plugin registration in
                // the "host"... using the functions mapped in widget options?
                case 'model':
                    this._createDocument();
                    this.options.iframe.load(this, this._iframeLoaded);
                    break;
                default:
                    break;
            }
        },

        refresh: function (event, widget) {
            var name, visible;
            widget = widget || event && event.data || this;
            name = (event)?(event.name)?event.name:event.type:'';
            visible = widget.element.data('visible');

            if (!widget.loaded) {
                return;
            }

            if (event && (name !== 'designReset') && !visible) {
                return;
            }

            if ((!event) || (name === 'load' ||
                             name === 'designReset' ||
                             name === 'modelUpdated')) {
                // Update headers if Design's properties changed
                if (name === "designReset" || (name  === 'modelUpdated'
                            && event.node && event.node.getType() === 'Design')) {
                    widget._createDocument();
                }
                widget._serializeADMDesignToDOM();
/* FIXME: Calling serializeADMSubtreeToDom is not actually forcing the
          the DOM to update, but it should work...

                switch (event.type) {
                    case 'nodeAdded':
                    case 'nodeRemoved':
                        serializeADMSubtreeToDOM(event.parent, null,
                                                 widget._renderer);
                        break;
                    case 'nodeMoved':
                        serializeADMSubtreeToDOM(event.oldParent, null,
                                                 widget._renderer);
                        serializeADMSubtreeToDOM(event.newParent, null,
                                                 widget._renderer);
                        break;
                    case 'propertyChanged':
                        serializeADMSubtreeToDOM(event.node, null,
                                                 widget._renderer);
                        break;
                    default:
                        console.warn(widget.widgetName,
                                     ':: Unexpected modelUpdate type:',
                                     event.type);
                        return;
                        break;
                }
*/
            } else {
                console.warn(widget.widgetName,':: Unexpected event:',name);
                return;
            }

            if (widget.options.contentDocument.length) {
                widget.options.contentDocument[0].defaultView
                    .postMessage('reload', '*');
            } else {
                console.error(widget.widgetName, ':: Missing contentDocument');
            }
        },

        // Private functions
        _iframeLoaded: function (event) {
            event.data.loaded = true;
            event.data.refresh(null, event.data);
            event.data.options.contentDocument[0].contentEditable = false;
        },

        _createPrimaryTools: function () {
            var doc, html, classes, selector,
                commands = ['undo', 'redo', 'cut', 'copy', 'paste'];

            classes = "buttonStyle primary-tools ui-state-default";
            html = $('
').addClass('hbox').hide();
            $.each(commands, function (index, command) {
                $('<button/>').addClass(classes)
                    .attr('id', 'btn' + command)
                    .appendTo(html);
            });

            doc = $((this.element)[0].ownerDocument);
            selector = "button.primary-tools"
            doc.delegate(selector, "click", jQuery.proxy(function (event) {
                var model = this.options.model;
                if (model) {
                    switch (event.currentTarget.id) {
                    case "btnundo":  model.undo();  break;
                    case "btnredo":  model.redo();  break;
                    case "btncut":   model.cut();   break;
                    case "btncopy":  model.copy();  break;
                    case "btnpaste": model.paste(); break;
                    default:
                        console.warn("Unhandled click on primary tool");
                        break;
                    }
                }
                else {
                    console.warn("No model while attempting undo");
                }
            }, this));

            return html;
        },

        _createSecondaryTools: function () {
            return $(null);
        },

        _selectionChangedHandler: function (event, widget) {
            var uid;
            widget = widget || this;

            // Always un-style currently selected nodes
            widget.options.contentDocument.find('.ui-selected')
                .removeClass('ui-selected');

            // Only apply selection style changes on valid nodes
            if (!event || (!event.uid && !event.node)) {
                return;
            }

            // Normally, ADM node id is provided in event.uid
            uid = event && event.uid;
            // Fallback is to try event.node.getUid()
            uid = uid || (event.node)?event.node.getUid():null;

            if (uid) {
                widget.options.contentDocument
                    .find('.adm-node[data-uid=\''+uid+'\']')
                    .not('[data-role=\'page\']')
                    .addClass('ui-selected').first().each(function () {
                        // Scroll selected node into view
                        setTimeout($.proxy(function () {
                            this.scrollIntoViewIfNeeded()
                        }, this), 100);
                    });
            }
        },

        _activePageChangedHandler: function (event, widget) {
            var win,
                newPage = event && event.page,
                id = newPage && newPage.getProperty('id');

            widget = widget || this;

            // Only change if new page is valid
            if (!newPage) {
                return;
            }

            win = widget.options.contentDocument[0].defaultView;

            if (win && win.$ && win.$.mobile) {
                if (win.$.mobile.activePage &&
                    win.$.mobile.activePage.attr('id') !== id) {
                    win.$.mobile.changePage("#"+id, {transition: "none"});
                }
            }
        },

        _modelUpdatedHandler: function (event, widget) {
            var win, aPage, pageNode,
                oldScrollTop = (widget.options.contentDocument.scrollTop());

            widget = widget || this;

            widget.refresh(event, widget);

            win = widget.options.contentDocument[0].defaultView;
            if (win && win.$ && win.$.mobile) {
                aPage = widget.options.model.getActivePage();
                if (aPage) {
                    pageNode = win.$('#' + aPage.getProperty('id'));
                    if (pageNode.length) {
                        win.$.mobile.changePage(pageNode);
                    } else {
                        // TODO: this is okay when last page is deleted, so
                        //       maybe this warning can be removed
                        console.warn("No such page found: ",
                                     aPage.getProperty('id'));
                    }
                } else {
                    win.$.mobile.initializePage();
                }
            } else {
                console.error(widget.widgetName, ':: Missing contentDocument');
            }
            widget.options.contentDocument.scrollTop(oldScrollTop);
            // Make sure Make sure selected node is visible
            widget.options.contentDocument.find('.ui-selected').first().each(function () {
                this.scrollIntoViewIfNeeded()
            });
        },

        _createDocument: function () {
            var contents, doc;

            if (!this.designRoot) return;

            doc = this.options.contentDocument[0];
            doc.open();
            contents = this._serializeFramework(this.designRoot);
            doc.writeln(contents);
            doc.close();
            $.rib.enableKeys($(doc.documentElement));
        },

        _serializeFramework: function () {
            var start, end, ret, headers;

            headers = this._getCustomHeaders();

            start = '<!DOCTYPE html>\n <title>Page Title</title>\n';
            end = "\n\n\n";

            if (headers && headers.length > 0) {
                ret = start + headers.join('\n') + end;
            } else {
                ret = start + end;
            }

            return ret;
        },

        // Great assumptions are being made here that the incoming default
        // headers are already "sorted" and in the order in which they should
        // be inserted into the  node of the document being created...
        _getCustomHeaders: function () {
            var dh = $.rib.getDesignHeaders(),   // default headers
                ch = this.options.customHeaders, // our custom headers
                m, s;

            $.each(dh, function (idx) {
                if (/<meta/.test(this)) {
                    m = idx+1; // Insert our Meta after LAST one
                    return;
                }
                if (/


<commit_before>import React from 'react'
import { connect } from 'react-redux'
import { markdown } from '../../util/text'

const LinkButton = ({ href, icon }) =>
  <i className={`icon-${icon}`}>

const AboutPerson = connect(
  (state, { params }) => ({person: state.people[params.id]})
)(({ person }) => {
  let { facebook_url, twitter_name, linkedin_url } = person
  let hasSocialMedia = !!(facebook_url || twitter_name || linkedin_url)

  return

About me

{person.bio}

      {hasSocialMedia &&

        {facebook_url && <LinkButton href={facebook_url} icon='facebook'/>}
        {twitter_name && <LinkButton href={`https://twitter.com/${twitter_name}`} icon='twitter'/>}
        {linkedin_url && <LinkButton href={linkedin_url} icon='linkedin'/>}

}

What I am doing

{person.work}

What I would like to do

{person.intention}

Skills

        {person.skills.map(skill =>

{skill}
)}

Affiliations

        {person.organizations.map(org =>

{org}
)}

    {person.extra_info &&

Other information

}

})

export default AboutPerson
<commit_msg>smaller components<commit_after>import React from 'react'
import { connect } from 'react-redux'
import { markdown } from '../../util/text'

const LinkButton = ({ href, icon }) =>
  <i className={`icon-${icon}`}>

const Section = ({ title, children }) =>

{title}

    {children}

const Tags = ({ children }) =>

    {children.map(tag =>
{tag}
)}

const AboutPerson = connect(
  (state, { params }) => ({person: state.people[params.id]})
)(({ person }) => {
  let { facebook_url, twitter_name, linkedin_url } = person
  let hasSocialMedia = !!(facebook_url || twitter_name || linkedin_url)

  return

{person.bio}

      {hasSocialMedia &&

        {facebook_url && <LinkButton href={facebook_url} icon='facebook'/>}
        {twitter_name && <LinkButton href={`https://twitter.com/${twitter_name}`} icon='twitter'/>}
        {linkedin_url && <LinkButton href={linkedin_url} icon='linkedin'/>}

}

{person.work}

{person.intention}

      <Tags>{person.skills}</Tags>

      <Tags>{person.organizations}</Tags>

    {person.extra_info &&

}

})

export default AboutPerson
<|endoftext|>


<commit_before>/**
 * @author David Corvoysier / Copyright Orange 2013
 *
 * Filter allowing to mix the input frame with a reference frame
 *
 * alpha: 0 to 1 (0 for a full replacement, 1 means no change)
 *
 */
(function(global) {

    // Register this filter
    global.addFilter(
        // Filter name
        'mix',
        // Vertex Shader (null uses default)
        null,
        // Fragment Shader (null uses default)
        '\
        uniform sampler2D texture;\
        uniform sampler2D reference;\
        uniform float alpha;\
        varying vec2 texCoord;\
        void main() {\
            vec4 color = texture2D(texture, texCoord);\
            vec4 rcolor = texture2D(reference, texCoord);\
            gl_FragColor = color*alpha + rcolor*(1.0-alpha);\
        }\
        ',
        // Uniforms callback
        function (gl, program, frameIn, frameOut, reference, alpha) {
            // Bind reference texture at position 1
            gl.activeTexture(gl.TEXTURE1);
            gl.bindTexture(gl.TEXTURE_2D, reference.texture);
            // Set reference uniform to position 1
            var refLocation = gl.getUniformLocation(program, "reference");
            gl.uniform1i(refLocation, 1);
            // Set alpha
            var alphaLocation = gl.getUniformLocation(program, "alpha");
            gl.uniform1f(alphaLocation, alpha);
        }
    );

})(glimp);
<commit_msg>mix: Use mix function instead of explicit calculation<commit_after>/**
 * @author David Corvoysier / Copyright Orange 2013
 *
 * Filter allowing to mix the input frame with a reference frame
 *
 * alpha: 0 to 1 (0 means no change, 1 a full replacement)
 *
 */
(function(global) {

    // Register this filter
    global.addFilter(
        // Filter name
        'mix',
        // Vertex Shader (null uses default)
        null,
        // Fragment Shader (null uses default)
        '\
        uniform sampler2D texture;\
        uniform sampler2D reference;\
        uniform float alpha;\
        varying vec2 texCoord;\
        void main() {\
            vec4 color = texture2D(texture, texCoord);\
            vec4 rcolor = texture2D(reference, texCoord);\
            gl_FragColor = mix(color,rcolor,alpha);\
        }\
        ',
        // Uniforms callback
        function (gl, program, frameIn, frameOut, reference, alpha) {
            // Bind reference texture at position 1
            gl.activeTexture(gl.TEXTURE1);
            gl.bindTexture(gl.TEXTURE_2D, reference.texture);
            // Set reference uniform to position 1
            var refLocation = gl.getUniformLocation(program, "reference");
            gl.uniform1i(refLocation, 1);
            // Set alpha
            var alphaLocation = gl.getUniformLocation(program, "alpha");
            gl.uniform1f(alphaLocation, alpha);
        }
    );

})(glimp);
<|endoftext|>