<commit_before>var racer = require('racer');
var $ = require('jquery');
var WAMS = require('wams');

var rndColor = (function() {
   var bg_colour = Math.floor(Math.random() * 16777215).toString(16);
   bg_colour = "#"+("000000" + bg_colour).slice(-6);
   return bg_colour;
}());
var rndName = (function() {
   var sampleNames = [
      'Fe', 'Thomas', 'Kirstie', 'Wynell', 'Mario', 'Aretha', 'Cherryl', 'Ta',
      'Lindy', 'Karina', 'Sacha', 'Latesha', 'Miki', 'Janel', 'Leola', 'Romeo',
      'Roderick', 'Felica', 'Ilona', 'Nila', 'Patrina', 'Wes', 'Henry', 'Elvera',
      'Karrie', 'Jacklyn', 'Alethea', 'Emogene', 'Alphonso', 'Chandra', 'Beryl',
      'Lilly', 'Georgetta', 'Darrin', 'Deane', 'Rocio', 'Charissa', 'Simona',
      'Don', 'Arianne', 'Esther', 'Leonia', 'Karma', 'Rosemarie', 'Carolyn',
      'Miriam', 'Chastity', 'Vesta', 'Christian', 'Lashaun'
   ].sort();

   return sampleNames[Math.floor(Math.random() * sampleNames.length)];
}());

function clone(obj) {
   // Handle the 2 simple types, and null or undefined
   if (null === obj || "object" !== typeof obj) { return obj; }

   var copy, i, len, attr;
   // Handle Array
   if (obj instanceof Array) {
      copy = [];
      for (i = 0, len = obj.length; i < len; i++) {
         copy[i] = clone(obj[i]);
      }
      return copy;
   }

   // Handle Object
   if (obj instanceof Object) {
      copy = {};
      for (attr in obj) {
         if (obj.hasOwnProperty(attr)) { copy[attr] = clone(obj[attr]); }
      }
      return copy;
   }

   throw new Error("Unable to copy obj! Its type isn't supported.");
}

function displayScreenMode(screen) {
   var screenMode = $('#mode');
   screenMode.text(screen.w + 'x' + screen.h +
      (screen.x >= 0 ? '+' + screen.x : "" + screen.x) +
      (screen.y >= 0 ? '+' + screen.y : "" + screen.y) + ':' +
      screen.s
   );
}

function extractColor(data) {
   var needToDelete = false, elem = $('#' + data.attributes.id);

   // object does not exist
   if (!elem.length) {
      needToDelete = true;

      elem = document.createElement(data.tag);
      elem.setAttribute('id', data.attributes.id);

      var body = document.getElementsByTagName('body');
      body[0].appendChild(elem);

      elem = $(elem);
   }

   var color = elem.css('background-color');
   if (needToDelete) {
      elem.remove();
   }
   return color;
}

function showElements(elements) {
   elements.forEach(function (element) {
      var elem = document.createElement(element.tag),
         attr;
      for (attr in element.attributes) {
         if (element.attributes.hasOwnProperty(attr)) {
            elem.setAttribute(attr, element.attributes[attr]);
         }
      }
      elem.innerHTML = element.innerHTML || "";

      elem.style.left = element.x + 'px';
      elem.style.top = element.y + 'px';
      elem.style.width = element.w + 'px';
      elem.style.height = element.h + 'px';
      elem.style.borderRadius = (element.w / 2) + 'px';

      var body = document.getElementsByTagName('body')[0];
      body.appendChild(elem);
   });
}

function moveElements(newEls, oldEls) {
   if (oldEls) {
      oldEls.forEach(function(el) {
         var elem = $('#' + el.attributes.id);
         elem.remove();
      });
      if (newEls) {
         showElements(newEls);
      }
   }
}

var MAX_CANVAS_HEIGHT = 450,
   MAX_CANVAS_WIDTH = 250,
   MIN_SCALE = 25,
   MAX_SCALE = 500,
   SCALE_DELTA = 5,
   wams = new WAMS({}),
   canvas = document.getElementById('minimap'),
   ctx = canvas.getContext('2d'),
   minimapScale;

racer.ready(function(model) {
   var room = 'sharedWorkspace';
   model.subscribe(room, function() {
      window.model = model;
      // model = model.at('sharedWorkspace');

      var id = model.id();
      model.add(room + '.users', {
         id: id,
         color: rndColor,
         name: rndName,
         screen: {
            w: window.innerWidth,
            h: window.innerHeight,
            x: 0,
            y: 0,
            s: 100
         }
      });
      model.ref(room + '.screens.' + id, room + '.users.' + id + '.screen');
      model.ref('_page.me', room + '.users.' + id);
      model.ref('_page.users', room + '.users');
      model.ref('_page.settings', room + '.settings');
      model.ref('_page.workspace', room + '.workspace');

      model.fn('convertElements', function (els) {
         if (!els) { return []; }

         var s = model.get('_page.me.screen'),
            r = [];

         els.forEach(function(el) {
            el = clone(el);
            el.x = (el.x - s.x) / (s.s / 100);
            el.y = (el.y - s.y) / (s.s / 100);
            el.w = el.w / (s.s / 100);
            el.h = el.h / (s.s / 100);

            if (el.x + el.w > 0 &&
                el.y + el.h > 0 &&
                el.x < s.w &&
                el.y < s.h) {
               r.push(el);
            }
         });

         return r;
      });

      function updateElements() {
         var convertedEls = model.evaluate('convertElements', room + '.elements');
         model.set('_page.elements', convertedEls);
      }

      model.on('change', '_page.me.screen**', function() {
         displayScreenMode( model.get('_page.me.screen') );
         updateElements();
      });

      model.on('change', room + '.elements**', function() {
         updateElements();
         drawMinimap();
      });

      model.on('change', '_page.elements**', function(path, value, previous, passed) {
         moveElements( value, previous );
      });

      model.on('change', '_page.workspace**', function(path, value, previous, passed) {
         if (path !== 'w' && path !== 'h' && path !== '') { return; }

         var w, h, dimensions;

         if (path === 'w') {
            dimensions = {
               w: value,
               h: model.get('_page.workspace.h')
            };
         } else if (path === 'h') {
            dimensions = {
               w: model.get('_page.workspace.w'),
               h: value
            };
         } else if (path === '') {
            dimensions = value;
         }

         if (MAX_CANVAS_HEIGHT / MAX_CANVAS_WIDTH < dimensions.h / dimensions.w) {
            minimapScale = MAX_CANVAS_HEIGHT / dimensions.h;
            h = MAX_CANVAS_HEIGHT;
            w = dimensions.w * minimapScale;
         } else {
            minimapScale = MAX_CANVAS_WIDTH / dimensions.w;
            h = dimensions.h * minimapScale;
            w = MAX_CANVAS_WIDTH;
         }

         canvas.width = w;
         canvas.height = h;

         drawMinimap();
      });

      // model.on('change', room + '.minimap**', function() {
      //    drawMinimap();
      // });

      window.onbeforeunload = function() {
         model.del(room + '.users.' + id);
         model.removeRef(room + '.screens.' + id);
      };

      $(document).ready(function() {
         var userID = $('#userID');
         userID.text( model.get('_page.me.name') );
         userID.css({ background: model.get('_page.me.color') });
         displayScreenMode( model.get('_page.me.screen') );

         updateElements();
         showElements( model.get('_page.elements') );

         restartMT();
      });

      $(window).resize(function() {
         model.set('_page.me.screen.w', window.innerWidth);
         model.set('_page.me.screen.h', window.innerHeight);
      });

      function onMouseWheel(ev) {
         var screen = model.get('_page.me.screen');
         if ((screen.s === MIN_SCALE && ev.wheelDeltaY > 0) ||
            (screen.s > MIN_SCALE && screen.s < MAX_SCALE && ev.whellDeltaY !== 0) ||
            (screen.s === MAX_SCALE && ev.wheelDeltaY < 0))
         {
            var delta = Math.floor(ev.wheelDeltaY / 120);
            model.increment('_page.me.screen.s', SCALE_DELTA * delta);
         }
      }
      var html = document.getElementsByTagName('html')[0];
      html.addEventListener('mousewheel', onMouseWheel, false);

      function drawClients() {
         var id, screen, color,
            users = model.get('_page.users'),
            w = model.get('_page.workspace'),
            dx = -w.x, dy = -w.y,
            drawGap = model.get('_page.settings.minimap.gapBetweenClients');

         for (id in users) {
            if (users.hasOwnProperty(id)) {
               screen = users[id].screen;
               color = users[id].color;

               ctx.beginPath();
                  ctx.strokeStyle = color;
                  ctx.setLineDash([7, 3]);
                  if (drawGap) {
                     ctx.rect((dx + screen.x) * minimapScale + 1,
                        (dy + screen.y) * minimapScale + 1,
                        screen.w * minimapScale * screen.s / 100 - 2,
                        screen.h * minimapScale * screen.s / 100 - 2);
                  } else {
                     ctx.rect((dx + screen.x) * minimapScale,
                        (dy + screen.y) * minimapScale,
                        screen.w * minimapScale * screen.s / 100,
                        screen.h * minimapScale * screen.s / 100);
                  }
               ctx.stroke();
            }
         }
      }
      function drawBalls() {
         var color, x, y, r,
            w = model.get('_page.workspace'),
            dx = -w.x, dy = -w.y,
            elements = model.get(room + '.elements');

         elements.forEach(function(element) {
            color = extractColor(element);

            ctx.beginPath();
               ctx.fillStyle = color;
               x = dx + element.x + element.w / 2;
               y = dy + element.y + element.h / 2;
               r = element.w / 2;
               ctx.arc(x * minimapScale, y * minimapScale, r * minimapScale, 0, 360);
            ctx.fill();
         });
      }
      function drawMinimap() {
         canvas.width = canvas.width;
         canvas.height = canvas.height;
         ctx.translate(0.5, 0.5);
         drawClients(ctx);
         if (model.get('_page.settings.minimap.showElements')) {
            drawBalls(ctx);
         }
      }

      function restartMT() {
         wams.dispose();

         wams.addMT(document);
         var rst_wrkspc_btn = document.getElementById('rst_wrkspc_btn');
         wams.addMT(rst_wrkspc_btn);

         var balls = document.getElementsByClassName('ball');
         wams.addMT(balls);

         wams.MTObjects.forEach(function(mt) {
            if (mt.element.nodeName === '#document') {
               mt.on('touch', onDocumentTouch);
               mt.on('drag', onDocumentDrag);
               mt.on('release', onDocumentRelease);
            } else if (mt.element.tagName === 'DIV' &&
                       mt.element.className.indexOf('ball') > -1) {
               mt.on('touch', onElementTouch);
               mt.on('drag', onElementDrag);
               mt.on('release', onElementRelease);
            } else if (mt.element.id === 'rst_wrkspc_btn') {
               mt.on('touch', onButtonPress);
            }
         });
      }

      function onDocumentTouch(ev) {
         var x = ev.gesture.center.pageX,
            y = ev.gesture.center.pageY,
            scr = model.get('_page.me.screen');

         model.set('_page.tmp.touchPoint', {x: x, y: y});
         model.set('_page.tmp.beforeMove', {x: scr.x, y: scr.y});
      }
      function onDocumentDrag(ev) {
         var x = ev.gesture.center.pageX,
            y = ev.gesture.center.pageY,
            scr = model.get('_page.me.screen'),
            tmp = model.get('_page.tmp'),
            scrBefore = tmp.beforeMove,
            pt = tmp.touchPoint,
            dx = x - pt.x, dy = y - pt.y;

         model.increment('_page.me.screen.x', (scrBefore.x - dx) - scr.x);
         model.increment('_page.me.screen.y', (scrBefore.y - dy) - scr.y);
      }
      function onDocumentRelease(ev) {
         model.del('_page.tmp.touchPoint');
         model.del('_page.tmp.beforeMove');
      }
      function onButtonPress(ev) {
         model.set('_page.me.screen.x', 0);
         model.set('_page.me.screen.y', 0);
         model.set('_page.me.screen.w', window.innerWidth);
         model.set('_page.me.screen.h', window.innerHeight);
         model.set('_page.me.screen.s', 100);
      }
      function onElementTouch(ev) {
      }
      function onElementDrag(ev) {
      }
      function onElementRelease(ev) {
      }
   });
});

<commit_msg>refactor: rename tmp var in model to make more sence<commit_after>var racer = require('racer');
var $ = require('jquery');
var WAMS = require('wams');

var rndColor = (function() {
   var bg_colour = Math.floor(Math.random() * 16777215).toString(16);
   bg_colour = "#"+("000000" + bg_colour).slice(-6);
   return bg_colour;
}());
var rndName = (function() {
   var sampleNames = [
      'Fe', 'Thomas', 'Kirstie', 'Wynell', 'Mario', 'Aretha', 'Cherryl', 'Ta',
      'Lindy', 'Karina', 'Sacha', 'Latesha', 'Miki', 'Janel', 'Leola', 'Romeo',
      'Roderick', 'Felica', 'Ilona', 'Nila', 'Patrina', 'Wes', 'Henry', 'Elvera',
      'Karrie', 'Jacklyn', 'Alethea', 'Emogene', 'Alphonso', 'Chandra', 'Beryl',
      'Lilly', 'Georgetta', 'Darrin', 'Deane', 'Rocio', 'Charissa', 'Simona',
      'Don', 'Arianne', 'Esther', 'Leonia', 'Karma', 'Rosemarie', 'Carolyn',
      'Miriam', 'Chastity', 'Vesta', 'Christian', 'Lashaun'
   ].sort();

   return sampleNames[Math.floor(Math.random() * sampleNames.length)];
}());

function clone(obj) {
   // Handle the 2 simple types, and null or undefined
   if (null === obj || "object" !== typeof obj) { return obj; }

   var copy, i, len, attr;
   // Handle Array
   if (obj instanceof Array) {
      copy = [];
      for (i = 0, len = obj.length; i < len; i++) {
         copy[i] = clone(obj[i]);
      }
      return copy;
   }

   // Handle Object
   if (obj instanceof Object) {
      copy = {};
      for (attr in obj) {
         if (obj.hasOwnProperty(attr)) { copy[attr] = clone(obj[attr]); }
      }
      return copy;
   }

   throw new Error("Unable to copy obj! Its type isn't supported.");
}

function displayScreenMode(screen) {
   var screenMode = $('#mode');
   screenMode.text(screen.w + 'x' + screen.h +
      (screen.x >= 0 ? '+' + screen.x : "" + screen.x) +
      (screen.y >= 0 ? '+' + screen.y : "" + screen.y) + ':' +
      screen.s
   );
}

function extractColor(data) {
   var needToDelete = false, elem = $('#' + data.attributes.id);

   // object does not exist
   if (!elem.length) {
      needToDelete = true;

      elem = document.createElement(data.tag);
      elem.setAttribute('id', data.attributes.id);

      var body = document.getElementsByTagName('body');
      body[0].appendChild(elem);

      elem = $(elem);
   }

   var color = elem.css('background-color');
   if (needToDelete) {
      elem.remove();
   }
   return color;
}

function showElements(elements) {
   elements.forEach(function (element) {
      var elem = document.createElement(element.tag),
         attr;
      for (attr in element.attributes) {
         if (element.attributes.hasOwnProperty(attr)) {
            elem.setAttribute(attr, element.attributes[attr]);
         }
      }
      elem.innerHTML = element.innerHTML || "";

      elem.style.left = element.x + 'px';
      elem.style.top = element.y + 'px';
      elem.style.width = element.w + 'px';
      elem.style.height = element.h + 'px';
      elem.style.borderRadius = (element.w / 2) + 'px';

      var body = document.getElementsByTagName('body')[0];
      body.appendChild(elem);
   });
}

function moveElements(newEls, oldEls) {
   if (oldEls) {
      oldEls.forEach(function(el) {
         var elem = $('#' + el.attributes.id);
         elem.remove();
      });
      if (newEls) {
         showElements(newEls);
      }
   }
}

var MAX_CANVAS_HEIGHT = 450,
   MAX_CANVAS_WIDTH = 250,
   MIN_SCALE = 25,
   MAX_SCALE = 500,
   SCALE_DELTA = 5,
   wams = new WAMS({}),
   canvas = document.getElementById('minimap'),
   ctx = canvas.getContext('2d'),
   minimapScale;

racer.ready(function(model) {
   var room = 'sharedWorkspace';
   model.subscribe(room, function() {
      window.model = model;
      // model = model.at('sharedWorkspace');

      var id = model.id();
      model.add(room + '.users', {
         id: id,
         color: rndColor,
         name: rndName,
         screen: {
            w: window.innerWidth,
            h: window.innerHeight,
            x: 0,
            y: 0,
            s: 100
         }
      });
      model.ref(room + '.screens.' + id, room + '.users.' + id + '.screen');
      model.ref('_page.me', room + '.users.' + id);
      model.ref('_page.users', room + '.users');
      model.ref('_page.settings', room + '.settings');
      model.ref('_page.workspace', room + '.workspace');

      model.fn('convertElements', function (els) {
         if (!els) { return []; }

         var s = model.get('_page.me.screen'),
            r = [];

         els.forEach(function(el) {
            el = clone(el);
            el.x = (el.x - s.x) / (s.s / 100);
            el.y = (el.y - s.y) / (s.s / 100);
            el.w = el.w / (s.s / 100);
            el.h = el.h / (s.s / 100);

            if (el.x + el.w > 0 &&
                el.y + el.h > 0 &&
                el.x < s.w &&
                el.y < s.h) {
               r.push(el);
            }
         });

         return r;
      });

      function updateElements() {
         var convertedEls = model.evaluate('convertElements', room + '.elements');
         model.set('_page.elements', convertedEls);
      }

      model.on('change', '_page.me.screen**', function() {
         displayScreenMode( model.get('_page.me.screen') );
         updateElements();
      });

      model.on('change', room + '.elements**', function() {
         updateElements();
         drawMinimap();
      });

      model.on('change', '_page.elements**', function(path, value, previous, passed) {
         moveElements( value, previous );
      });

      model.on('change', '_page.workspace**', function(path, value, previous, passed) {
         if (path !== 'w' && path !== 'h' && path !== '') { return; }

         var w, h, dimensions;

         if (path === 'w') {
            dimensions = {
               w: value,
               h: model.get('_page.workspace.h')
            };
         } else if (path === 'h') {
            dimensions = {
               w: model.get('_page.workspace.w'),
               h: value
            };
         } else if (path === '') {
            dimensions = value;
         }

         if (MAX_CANVAS_HEIGHT / MAX_CANVAS_WIDTH < dimensions.h / dimensions.w) {
            minimapScale = MAX_CANVAS_HEIGHT / dimensions.h;
            h = MAX_CANVAS_HEIGHT;
            w = dimensions.w * minimapScale;
         } else {
            minimapScale = MAX_CANVAS_WIDTH / dimensions.w;
            h = dimensions.h * minimapScale;
            w = MAX_CANVAS_WIDTH;
         }

         canvas.width = w;
         canvas.height = h;

         drawMinimap();
      });

      // model.on('change', room + '.minimap**', function() {
      //    drawMinimap();
      // });

      window.onbeforeunload = function() {
         model.del(room + '.users.' + id);
         model.removeRef(room + '.screens.' + id);
      };

      $(document).ready(function() {
         var userID = $('#userID');
         userID.text( model.get('_page.me.name') );
         userID.css({ background: model.get('_page.me.color') });
         displayScreenMode( model.get('_page.me.screen') );

         updateElements();
         showElements( model.get('_page.elements') );

         restartMT();
      });

      $(window).resize(function() {
         model.set('_page.me.screen.w', window.innerWidth);
         model.set('_page.me.screen.h', window.innerHeight);
      });

      function onMouseWheel(ev) {
         var screen = model.get('_page.me.screen');
         if ((screen.s === MIN_SCALE && ev.wheelDeltaY > 0) ||
            (screen.s > MIN_SCALE && screen.s < MAX_SCALE && ev.whellDeltaY !== 0) ||
            (screen.s === MAX_SCALE && ev.wheelDeltaY < 0))
         {
            var delta = Math.floor(ev.wheelDeltaY / 120);
            model.increment('_page.me.screen.s', SCALE_DELTA * delta);
         }
      }
      var html = document.getElementsByTagName('html')[0];
      html.addEventListener('mousewheel', onMouseWheel, false);

      function drawClients() {
         var id, screen, color,
            users = model.get('_page.users'),
            w = model.get('_page.workspace'),
            dx = -w.x, dy = -w.y,
            drawGap = model.get('_page.settings.minimap.gapBetweenClients');

         for (id in users) {
            if (users.hasOwnProperty(id)) {
               screen = users[id].screen;
               color = users[id].color;

               ctx.beginPath();
                  ctx.strokeStyle = color;
                  ctx.setLineDash([7, 3]);
                  if (drawGap) {
                     ctx.rect((dx + screen.x) * minimapScale + 1,
                        (dy + screen.y) * minimapScale + 1,
                        screen.w * minimapScale * screen.s / 100 - 2,
                        screen.h * minimapScale * screen.s / 100 - 2);
                  } else {
                     ctx.rect((dx + screen.x) * minimapScale,
                        (dy + screen.y) * minimapScale,
                        screen.w * minimapScale * screen.s / 100,
                        screen.h * minimapScale * screen.s / 100);
                  }
               ctx.stroke();
            }
         }
      }
      function drawBalls() {
         var color, x, y, r,
            w = model.get('_page.workspace'),
            dx = -w.x, dy = -w.y,
            elements = model.get(room + '.elements');

         elements.forEach(function(element) {
            color = extractColor(element);

            ctx.beginPath();
               ctx.fillStyle = color;
               x = dx + element.x + element.w / 2;
               y = dy + element.y + element.h / 2;
               r = element.w / 2;
               ctx.arc(x * minimapScale, y * minimapScale, r * minimapScale, 0, 360);
            ctx.fill();
         });
      }
      function drawMinimap() {
         canvas.width = canvas.width;
         canvas.height = canvas.height;
         ctx.translate(0.5, 0.5);
         drawClients(ctx);
         if (model.get('_page.settings.minimap.showElements')) {
            drawBalls(ctx);
         }
      }

      function restartMT() {
         wams.dispose();

         wams.addMT(document);
         var rst_wrkspc_btn = document.getElementById('rst_wrkspc_btn');
         wams.addMT(rst_wrkspc_btn);

         var balls = document.getElementsByClassName('ball');
         wams.addMT(balls);

         wams.MTObjects.forEach(function(mt) {
            if (mt.element.nodeName === '#document') {
               mt.on('touch', onDocumentTouch);
               mt.on('drag', onDocumentDrag);
               mt.on('release', onDocumentRelease);
            } else if (mt.element.tagName === 'DIV' &&
                       mt.element.className.indexOf('ball') > -1) {
               mt.on('touch', onElementTouch);
               mt.on('drag', onElementDrag);
               mt.on('release', onElementRelease);
            } else if (mt.element.id === 'rst_wrkspc_btn') {
               mt.on('touch', onButtonPress);
            }
         });
      }

      function onDocumentTouch(ev) {
         var x = ev.gesture.center.pageX,
            y = ev.gesture.center.pageY,
            scr = model.get('_page.me.screen');

         model.set('_page.tmp.touchPoint', {x: x, y: y});
         model.set('_page.tmp.scrBeforeMove', {x: scr.x, y: scr.y});
      }
      function onDocumentDrag(ev) {
         var x = ev.gesture.center.pageX,
            y = ev.gesture.center.pageY,
            scr = model.get('_page.me.screen'),
            tmp = model.get('_page.tmp'),
            scrBefore = tmp.scrBeforeMove,
            pt = tmp.touchPoint,
            dx = x - pt.x, dy = y - pt.y;

         model.increment('_page.me.screen.x', (scrBefore.x - dx) - scr.x);
         model.increment('_page.me.screen.y', (scrBefore.y - dy) - scr.y);
      }
      function onDocumentRelease(ev) {
         model.del('_page.tmp.touchPoint');
         model.del('_page.tmp.scrBeforeMove');
      }
      function onButtonPress(ev) {
         model.set('_page.me.screen.x', 0);
         model.set('_page.me.screen.y', 0);
         model.set('_page.me.screen.w', window.innerWidth);
         model.set('_page.me.screen.h', window.innerHeight);
         model.set('_page.me.screen.s', 100);
      }
      function onElementTouch(ev) {
      }
      function onElementDrag(ev) {
      }
      function onElementRelease(ev) {
      }
   });
});

<|endoftext|>


<commit_before>'use strict';

angular.module('argus.directives.charts.chart', [])
.directive('agChart', ['Metrics', 'Annotations', 'ChartRenderingService', 'ChartDataProcessingService', 'ChartOptionService', 'DateHandlerService', 'CONFIG', 'VIEWELEMENT', '$compile',
function(Metrics, Annotations, ChartRenderingService, ChartDataProcessingService, ChartOptionService, DateHandlerService, CONFIG, VIEWELEMENT, $compile) {
    var chartNameIndex = 1;

    function compileLineChart(scope, newChartId, series, dateConfig) {
        // empty any previous content
        $("#" + newChartId).empty();

        // create a new scope to pass to compiled line-chart directive
        var lineChartScope = scope.$new(false);     // true will set isolate scope, false = inherit

        // assign items to new $scope
        lineChartScope.chartConfig = {
            chartId: newChartId,
            chartTitle: scope.options.title || ''   // title is an attribute of <option>, and could be undefined
        };
        lineChartScope.series = series;
        lineChartScope.dateConfig = dateConfig;

        // give each series an unique ID if it has data
        for (var i = 0; i < series.length; i++) {
            // use graphClassName to bind all the graph element of a metric together
            lineChartScope.series[i].graphClassName = newChartId + "_graph" + (i + 1);
        }
        // sort series alphabetically
        lineChartScope.series = lineChartScope.series.sort(function(a, b) {
            var textA = a.name.toUpperCase();
            var textB = b.name.toUpperCase();
            return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;
        });

        scope.seriesDataLoaded = true; //

        // append, compile, & attach new scope to line-chart directive
        angular.element("#" + newChartId).append( $compile('<line-chart chartConfig="chartConfig" series="series" dateconfig="dateConfig"></line-chart>')(lineChartScope) );
    }

    function setupAnnotations(scope, newChartId, series, updatedAnnotationList, dateConfig) {

        if (updatedAnnotationList.length === 0) {
            // no annotations list, continue to render chart as normal
            compileLineChart(scope, newChartId, series, dateConfig);
        } else {
            // check annotations & add to series data for line-chart
            for (var i=0; i < updatedAnnotationList.length; i++) {
                Annotations.query({expression: updatedAnnotationList[i]}, function (data) {
                    if (data && data.length > 0) {
                        var forName = ChartDataProcessingService.createSeriesName(data[0]);
                        var flagSeries = ChartDataProcessingService.copyFlagSeries(data);
                        flagSeries.linkedTo = forName;

                        // add flagSeries if any data exists
                        //TODO: handle undefined flagSeries situation
                        series[0].flagSeries = (flagSeries) ? flagSeries: null;
                    }

                    // append, compile, & attach new scope to line-chart directive
                    compileLineChart(scope, newChartId, series, dateConfig);

                }, function (error) {
                    console.log( 'no data found', error.data.message );
                    // append, compile, & attach new scope to line-chart directive
                    compileLineChart(scope, newChartId, series, dateConfig);
                });
            }
        }
    }

    function queryMetricData(scope, metricItem, metricCount, newChartId, series, updatedAnnotationList, dateConfig, attributes) {
        if (!metricItem) return;

        var smallChart = !!attributes.smallchart;

        Metrics.query({expression: metricItem.expression}).$promise.then(function(data) {
            var tempSeries;

            if (data && data.length > 0) {
                // check to update statusIndicator with correct status color
                if (smallChart) {
                    // get the last data point
                    var lastStatusVal = ChartDataProcessingService.getLastDataPoint(data[0].datapoints);

                    // update status indicator
                    ChartRenderingService.updateIndicatorStatus(attributes, lastStatusVal);

                    // add 'smallChart' flag to scope
                    scope.chartOptions = {smallChart: smallChart};
                }

                // metric item attributes are assigned to the data (i.e. name, color, etc.)
                tempSeries = ChartDataProcessingService.copySeriesDataNSetOptions(data, metricItem);

                Array.prototype.push.apply(series, tempSeries);
            } else {
                // growl.info('No data found for the metric expression: ' + JSON.stringify(metricItem.expression));
                console.log('Empty result returned for the metric expression');
                tempSeries = [{
                    noData: true,
                    errorMessage: 'Empty result returned for the metric expression',
                    name: JSON.stringify(metricItem.expression).slice(1, -1),
                    color: 'Maroon'
                }];
            }

            // decrement metric count each time an expression is added to the series.
            metricCount = metricCount - 1;

            if (metricCount === 0) {
                // check for Annotations
                setupAnnotations(scope, newChartId, series, updatedAnnotationList, dateConfig);
            }
        }, function (error) {
            // growl.error(error.message);
            console.log('Metric expression does not exist in database');
            var tempSeries = [{
                invalidMetric: true,
                errorMessage: error.statusText + '(' + error.status + ') - ' + error.data.message.substring(0, 31),
                name: error.config.params.expression,
                color: 'Black'
            }];
            Array.prototype.push.apply(series, tempSeries);

            metricCount = metricCount - 1;

            if (metricCount === 0) {
                // display chart with series data and populate annotations
                setupAnnotations(scope, newChartId, series, updatedAnnotationList, dateConfig);
            }
        });
    }

    // TODO: below functions 'should' be refactored to the chart services.
    function setupChart(scope, element, attributes, controls) {
        // remove/clear any previous chart rendering from DOM
        element.empty();
        // generate a new chart ID, set css options for main chart container
        var newChartId = 'element_' + VIEWELEMENT.chart + chartNameIndex++;
        var chartType = attributes.type ? attributes.type : 'LINE';
        var cssOpts = ( attributes.smallChart ) ? 'smallChart' : '';

        // set the charts container for rendering
        ChartRenderingService.setChartContainer(element, newChartId, cssOpts);

        var data = {
            metrics: scope.metrics,
            annotations: scope.annotations,
            options: scope.options
        };

        // get start and end time for the charts as well as whether GMT/UTC scale is used or not
        var dateConfig = {};
        var GMTon = false;
        for (var i = 0; i < controls.length; i++) {
            if (controls[i].type === "agDate") {
                var timeValue = controls[i].value;
                if (controls[i].name === "start") {
                    dateConfig.startTime = DateHandlerService.timeProcessingHelper(timeValue);
                    GMTon = GMTon || DateHandlerService.GMTVerifier(timeValue);
                } else if (controls[i].name === "end"){
                    dateConfig.endTime = DateHandlerService.timeProcessingHelper(timeValue);
                    GMTon = GMTon || DateHandlerService.GMTVerifier(timeValue);
                }
            }
        }
        dateConfig.gmt = GMTon;

        // process data for: metrics, annotations, options
        var processedData = ChartDataProcessingService.processMetricData(data, event, controls);

        // re-assign each list for: metrics, annotations, options
        // TODO: updatedMetricList is not defined sometimes
        var updatedMetricList = processedData.updatedMetricList;
        var updatedAnnotationList = processedData.updatedAnnotationList;
        var updatedOptionList = processedData.updatedOptionList;

        // define series first, then build list for each metric expression
        var series = [];
        var metricCount = updatedMetricList.length;

        scope.seriesDataLoaded = false; //used for load spinner
        angular.element("#" + newChartId).append( $compile('

')(scope) );

        for (var i = 0; i < updatedMetricList.length; i++) {
            var metricItem = updatedMetricList[i];

            // get data for each metric item, bind optional data with metric data
            metricCount = metricCount-[i];
            queryMetricData(scope, metricItem, metricCount, newChartId, series, updatedAnnotationList, dateConfig, attributes);
        }
    }

    return {
        restrict: 'E',
        transclude: true,
        scope: {},
        require: '^agDashboard',
        controller: 'ViewElements',
        template: '

',
        compile: function (element, attrs, transclude) {
            return {
                post: function postLink(scope, element, attributes, dashboardCtrl, transcludeFn) {
                    scope.$on(dashboardCtrl.getSubmitBtnEventName(), function(event, controls) {
                        setupChart(scope, element, attributes, controls);
                    });
                }
            };
        }
    };
}]);
<commit_msg>bug fix: 3553612 - metric list undefined if no metrics are present. e.g. data center not fully operational yet. update Annotation query to return  with closure.<commit_after>'use strict';

angular.module('argus.directives.charts.chart', [])
.directive('agChart', ['Metrics', 'Annotations', 'ChartRenderingService', 'ChartDataProcessingService', 'ChartOptionService', 'DateHandlerService', 'CONFIG', 'VIEWELEMENT', '$compile',
function(Metrics, Annotations, ChartRenderingService, ChartDataProcessingService, ChartOptionService, DateHandlerService, CONFIG, VIEWELEMENT, $compile) {
    var chartNameIndex = 1;

    function compileLineChart(scope, newChartId, series, dateConfig) {
        // empty any previous content
        $("#" + newChartId).empty();

        // create a new scope to pass to compiled line-chart directive
        var lineChartScope = scope.$new(false);     // true will set isolate scope, false = inherit

        // assign items to new $scope
        lineChartScope.chartConfig = {
            chartId: newChartId,
            chartTitle: scope.options.title || ''   // title is an attribute of <option>, and could be undefined
        };
        lineChartScope.series = series;
        lineChartScope.dateConfig = dateConfig;

        // give each series an unique ID if it has data
        for (var i = 0; i < series.length; i++) {
            // use graphClassName to bind all the graph element of a metric together
            lineChartScope.series[i].graphClassName = newChartId + "_graph" + (i + 1);
        }
        // sort series alphabetically
        lineChartScope.series = lineChartScope.series.sort(function(a, b) {
            var textA = a.name.toUpperCase();
            var textB = b.name.toUpperCase();
            return (textA < textB) ? -1 : (textA > textB) ? 1 : 0;
        });

        scope.seriesDataLoaded = true; //

        // append, compile, & attach new scope to line-chart directive
        angular.element("#" + newChartId).append( $compile('<line-chart chartConfig="chartConfig" series="series" dateconfig="dateConfig"></line-chart>')(lineChartScope) );
    }

    function queryAnnotationData(scope, annotationItem, newChartId, series, dateConfig) {
        Annotations.query({expression: annotationItem}).$promise.then(function(data) {
            if (data && data.length > 0) {
                var forName = ChartDataProcessingService.createSeriesName(data[0]);
                var flagSeries = ChartDataProcessingService.copyFlagSeries(data);
                flagSeries.linkedTo = forName;

                // add flagSeries if any data exists
                //TODO: handle undefined flagSeries situation
                series[0].flagSeries = (flagSeries) ? flagSeries: null;
            }

            // append, compile, & attach new scope to line-chart directive
            compileLineChart(scope, newChartId, series, dateConfig);

        }, function (error) {
            console.log( 'no data found', error.data.message );
            // append, compile, & attach new scope to line-chart directive
            compileLineChart(scope, newChartId, series, dateConfig);
        });
    }

    function setupAnnotations(scope, newChartId, series, updatedAnnotationList, dateConfig) {

        if (updatedAnnotationList.length === 0) {
            // no annotations list, continue to render chart as normal
            compileLineChart(scope, newChartId, series, dateConfig);
        } else {
            // check annotations & add to series data for line-chart
            for (var i=0; i < updatedAnnotationList.length; i++) {
                var annotationItem = updatedAnnotationList[i];
                queryAnnotationData(scope, annotationItem, newChartId, series, dateConfig);
            }
        }
    }

    function queryMetricData(scope, metricItem, metricCount, newChartId, series, updatedAnnotationList, dateConfig, attributes) {
        if (!metricItem) return;

        var smallChart = !!attributes.smallchart;

        Metrics.query({expression: metricItem.expression}).$promise.then(function(data) {
            var tempSeries;

            if (data && data.length > 0) {
                // check to update statusIndicator with correct status color
                if (smallChart) {
                    // get the last data point
                    var lastStatusVal = ChartDataProcessingService.getLastDataPoint(data[0].datapoints);

                    // update status indicator
                    ChartRenderingService.updateIndicatorStatus(attributes, lastStatusVal);

                    // add 'smallChart' flag to scope
                    scope.chartOptions = {smallChart: smallChart};
                }

                // metric item attributes are assigned to the data (i.e. name, color, etc.)
                tempSeries = ChartDataProcessingService.copySeriesDataNSetOptions(data, metricItem);

                Array.prototype.push.apply(series, tempSeries);
            } else {
                // growl.info('No data found for the metric expression: ' + JSON.stringify(metricItem.expression));
                console.log('Empty result returned for the metric expression');
                tempSeries = [{
                    noData: true,
                    errorMessage: 'Empty result returned for the metric expression',
                    name: JSON.stringify(metricItem.expression).slice(1, -1),
                    color: 'Maroon'
                }];
            }

            // decrement metric count each time an expression is added to the series.
            metricCount = metricCount - 1;

            if (metricCount === 0) {
                // check for Annotations
                setupAnnotations(scope, newChartId, series, updatedAnnotationList, dateConfig);
            }
        }, function (error) {
            // growl.error(error.message);
            console.log('Metric expression does not exist in database');
            var tempSeries = [{
                invalidMetric: true,
                errorMessage: error.statusText + '(' + error.status + ') - ' + error.data.message.substring(0, 31),
                name: error.config.params.expression,
                color: 'Black'
            }];
            Array.prototype.push.apply(series, tempSeries);

            metricCount = metricCount - 1;

            if (metricCount === 0) {
                // display chart with series data and populate annotations
                setupAnnotations(scope, newChartId, series, updatedAnnotationList, dateConfig);
            }
        });
    }

    // TODO: below functions 'should' be refactored to the chart services.
    function setupChart(scope, element, attributes, controls) {
        // remove/clear any previous chart rendering from DOM
        element.empty();
        // generate a new chart ID, set css options for main chart container
        var newChartId = 'element_' + VIEWELEMENT.chart + chartNameIndex++;
        var chartType = attributes.type ? attributes.type : 'LINE';
        var cssOpts = ( attributes.smallChart ) ? 'smallChart' : '';

        // set the charts container for rendering
        ChartRenderingService.setChartContainer(element, newChartId, cssOpts);

        var data = {
            metrics: scope.metrics,
            annotations: scope.annotations,
            options: scope.options
        };

        // get start and end time for the charts as well as whether GMT/UTC scale is used or not
        var dateConfig = {};
        var GMTon = false;
        for (var i = 0; i < controls.length; i++) {
            if (controls[i].type === "agDate") {
                var timeValue = controls[i].value;
                if (controls[i].name === "start") {
                    dateConfig.startTime = DateHandlerService.timeProcessingHelper(timeValue);
                    GMTon = GMTon || DateHandlerService.GMTVerifier(timeValue);
                } else if (controls[i].name === "end"){
                    dateConfig.endTime = DateHandlerService.timeProcessingHelper(timeValue);
                    GMTon = GMTon || DateHandlerService.GMTVerifier(timeValue);
                }
            }
        }
        dateConfig.gmt = GMTon;

        // process data for: metrics, annotations, options
        var processedData = ChartDataProcessingService.processMetricData(data, event, controls);

        if (!processedData) {
            console.log('no processed data returned: ' + newChartId);
            return;
        }

        // re-assign each list for: metrics, annotations, options
        // TODO: updatedMetricList is not defined sometimes
        var updatedMetricList = processedData.updatedMetricList;
        var updatedAnnotationList = processedData.updatedAnnotationList;
        var updatedOptionList = processedData.updatedOptionList;

        // define series first, then build list for each metric expression
        var series = [];
        var metricCount = updatedMetricList.length;

        scope.seriesDataLoaded = false; //used for load spinner
        angular.element("#" + newChartId).append( $compile('

')(scope) );

        for (var i = 0; i < updatedMetricList.length; i++) {
            var metricItem = updatedMetricList[i];

            // get data for each metric item, bind optional data with metric data
            metricCount = metricCount-[i];
            queryMetricData(scope, metricItem, metricCount, newChartId, series, updatedAnnotationList, dateConfig, attributes);
        }
    }

    return {
        restrict: 'E',
        transclude: true,
        scope: {},
        require: '^agDashboard',
        controller: 'ViewElements',
        template: '

',
        compile: function (element, attrs, transclude) {
            return {
                post: function postLink(scope, element, attributes, dashboardCtrl, transcludeFn) {
                    scope.$on(dashboardCtrl.getSubmitBtnEventName(), function(event, controls) {
                        setupChart(scope, element, attributes, controls);
                    });
                }
            };
        }
    };
}]);
<|endoftext|>


<commit_before>'use strict'
var merge = require('lodash/object/merge')

exports.carousel = merge(require('../../../../../lib/carousel'), {
  items: {
    $collection: 'items',
    Child: {
      type: 'item-carousel'
    }
  },
  indicator: {
    Child: {}
  },
  buttons: {
    Child: {
      row: {
        type: 'row',
        icon: {
          type: 'icon'
        }
      }
    },
    left: {
      row: {
        icon: {
          css: 'icon-left',
          order: -1
        },
        title: {
          text: 'Previous'
        }
      },
      on: {
        down (e, event) {
          this.parent.previous()
        }
      }
    },
    right: {
      row: {
        icon: {
          css: 'icon-right'
        },
        title: {
          text: 'Next'
        }
      },
      on: {
        down (e, event) {
          this.parent.next()
        }
      }
    }
  }
})

exports['item-carousel'] = {
  type: 'item',
  img: {
    img: { src: { $: 'img.spotlight' } }
  },
  title: {
    img: {
      type: 'thumb',
      img: { src: { $: 'img.spotlight' } }
    }
  }
}
<commit_msg>parent fix<commit_after>'use strict'
var merge = require('lodash/object/merge')

exports.carousel = merge(require('../../../../../lib/carousel'), {
  items: {
    $collection: 'items',
    Child: {
      type: 'item-carousel'
    }
  },
  indicator: {
    Child: {}
  },
  buttons: {
    Child: {
      row: {
        type: 'row',
        icon: {
          type: 'icon'
        }
      }
    },
    left: {
      row: {
        icon: {
          css: 'icon-left',
          order: -1
        },
        title: {
          text: 'Previous'
        }
      },
      on: {
        down (e, event) {
          this.parent.parent.previous()
        }
      }
    },
    right: {
      row: {
        icon: {
          css: 'icon-right'
        },
        title: {
          text: 'Next'
        }
      },
      on: {
        down (e, event) {
          this.parent.parent.next()
        }
      }
    }
  }
})

exports['item-carousel'] = {
  type: 'item',
  img: {
    img: { src: { $: 'img.spotlight' } }
  },
  title: {
    img: {
      type: 'thumb',
      img: { src: { $: 'img.spotlight' } }
    }
  }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
var { Windows } = require("../util/windows");

const keys = require("../core/key");
const { Overlay, Overlays } = require("../core/overlay");
const { PreferenceTree, customXULTree } = require("../prefs/tree");
const utils = require("sdk/window/utils");
const events = require("sdk/system/events");
const { ActionButton } = require("sdk/ui/button/action");
var _ = require("sdk/l10n").get;

const extensionPrefs = require("sdk/simple-prefs");

const { windowMediator, prompterService } = require("../util/functions");

function occurrences(string, subString, allowOverlapping) {
    /** Function count the occurrences of substring in a string;
     * @param {String} string   Required. The string;
     * @param {String} subString    Required. The string to search for;
     * @param {Boolean} allowOverlapping    Optional. Default: false;
     */
    string += "";
    subString += "";
    if (subString.length <= 0) return string.length + 1;

    var n = 0,
        pos = 0;
    var step = (allowOverlapping) ? (1) : (subString.length);

    while (true) {
        pos = string.indexOf(subString, pos);
        if (pos >= 0) {
            n++;
            pos += step;
        } else break;
    }
    return (n);
}

function ValidURL(str) {
    var strictPattern = new RegExp(/^((https?:\/\/(?!\*))|(\*\.))((([a-z\d]([a-z\d-]*[a-z\d])*|(\*))\.)+[a-z]{2,}|((\d{1,3}\.){3}\d{1,3}))(\:\d+)?(\/[-a-z\d%_.~+]*)*(\?[;&a-z\d%_.~+=-]*)?(\#[-a-z\d_]*)?$/i); // Strict URL matching pattern.
    var commonError_1 = new RegExp(/(^https?:\/\/){0}(\d{1,3}\.){3}\d(\:\d{2,5})?/i); // Catch IP without protocol, will try prepending 'http://' before failing.
    var commonError_2 = new RegExp(/^(https?:\/\/){0}([-a-z\d%_~+]{2,})\.([a-z-_]){2,}([0-9])*(\/|\:)?/i) // Catch domain.tld without protocol or wildcard; // will try prepending '*.' before failing.
    if ("" == str) {
        return false;
    }
    if (occurrences(str, '*') > 1) {
        return false;
    }
    if ('*' == str) {
        return str;
    } else if (!strictPattern.test(str)) {
        if (true == commonError_1.test(str)) {
            return String.concat("http://", str);
        } else if (true == commonError_2.test(str)) {
            return String.concat("*.", str);
        } else {
            return false;
        }
    } else {
        return str;
    }
}

function MenuItem(window, kind) {
	if (!utils.isBrowser(window)) { return } // Catch non-browser windows.
    this.window = window;
    if ("tabSwitching" == kind) {
		if (this.window.document.getElementById("prevTab-command")) { return; } // Prevent creating duplicate menu items.
        let parentmenu = this.window.document.getElementById("windowPopup");
        if (!parentmenu) { return; } // Only add the menu items if the Windows menu exists.
        let windowsep = this.window.document.getElementById("sep-window-list");
        this.separator = this._createElement("menuseparator");
        parentmenu.insertBefore(this.separator, windowsep);
        this.separator.setAttribute("id", "sep-switch-tabs");

        this.prevtab = this._createElement("menuitem");
        parentmenu.insertBefore(this.prevtab, this.separator.nextSibling);
        this.prevtab.setAttribute("id", "prevTab-command");
        this.prevtab.setAttribute("command", "Browser:PrevTab");
        this.prevtab.setAttribute("label", _("previousTab_label"));

        this.nexttab = this._createElement("menuitem");
        parentmenu.insertBefore(this.nexttab, this.prevtab.nextSibling);
        this.nexttab.setAttribute("id", "nextTab-command");
        this.nexttab.setAttribute("command", "Browser:NextTab");
        this.nexttab.setAttribute("label", _("nextTab_label"));
    } else {
        let self = this;
		if (this.window.document.getElementById("ttshortcutsMenuItem")) { return; } // Prevent creating duplicate menu items.
        this.element = this._createElement("menuitem");
        this.element.setAttribute("id", "ttshortcutsMenuItem");
        this.element.setAttribute("class", "menu-iconic");
        this.element.setAttribute("image", require("sdk/self").data.url("icon18.png"));
        this.element.setAttribute("label", _("MenuItem_label"));
        this.element.setAttribute("insertBefore", "sanitizeSeparator");
        this.element.setAttribute("oncommand", "if (!Cc[\"@mozilla.org/appshell/window-mediator;1\"]            .getService(Ci.nsIWindowMediator).getMostRecentWindow('Keybinder:config')) { window.openDialog('chrome://keybinder/content/ttShortcuts_preferences.xul','Keybinder','chrome,titlebar=yes,close=no,toolbar=no,centerscreen,dialog=yes') } else { Cc[\"@mozilla.org/appshell/window-mediator;1\"]            .getService(Ci.nsIWindowMediator).getMostRecentWindow('Keybinder:config').focus() }");
        let parentmenu = this.window.document.getElementById("menu_ToolsPopup");
        parentmenu.appendChild(this.element);
    }
}

MenuItem.prototype = {
    _built: false,

    _createStylesheet: function(href) {
        let doc = this.window.document;
        let style = doc.createProcessingInstruction("xml-stylesheet", 'href="' + href + '"');
        doc.insertBefore(style, doc.querySelector("window"));
    },

    _createElement: function(tag, parent) {
        let element = this.window.document.createElementNS(XUL_NS, tag);
        parent && parent.appendChild(element);
        return element;
    },

    _build: function() {
        return;
    },
};

function warnforConflicting() {
    prompterService.alert(window, _("conflictWarning.title"), _("conflictWarning.text"));
}

let createNewMenuItem = exports.createNewMenuItem = function (window, kind) {
new MenuItem (window, kind);
}

events.on("toplevel-window-ready",function(event) {
	event.subject.setTimeout(function() {
		let id = event.subject.window.document.documentElement.getAttribute("id");
		if ("ttShortcutsPrefsDialog" == id) {
			preferenceDialogInit(event.subject.window);
		}
		else if ("urlPatternsDialog" == id) {
			let window = event.subject.window;
            window.validateUrls = function() {
                let tempArray = (window.document.getElementById("textbox").value).split('\n');
                let arraySize = tempArray.length;
                let i = 0;
                for (let l of tempArray) {
                    if (!ValidURL(l)) {
                        tempArray[i] = "";
                    } else {
                        tempArray[i] = ValidURL(l);
                    }
                    i++;
                }
                tempArray = tempArray.filter(function(i) {
                    return i != ""
                });
                extensionPrefs.prefs['domainUrlPattern'] = JSON.stringify(tempArray);
            }
		}
	else if ("KeybinderCustomXULDialog" == id) {
		customXULDialogInit(event.subject.window);

	}
},7);
}, true);

function keybinderDialog (id, uri, name, options, extras = null) {
	if (!windowMediator.getMostRecentWindow(id)) {
		Windows.getMostRecentWindow().openDialog(uri, name, options, extras);
	}
	else {
		windowMediator.getMostRecentWindow(id).focus();
	}
}

extensionPrefs.on("UrlPatternsDialog", function() {
keybinderDialog('Keybinder:URLPatterns', 'chrome://keybinder/content/urlpatterns.xul', 'UrlPatterns', 'chrome,titlebar=yes,close=no,toolbar=no,centerscreen,dialog=yes', (JSON.parse(extensionPrefs.prefs['domainUrlPattern'])).join("\n"));
});

extensionPrefs.on("ShortcutsDialog", function() {
keybinderDialog('Keybinder:config', 'chrome://keybinder/content/ttShortcuts_preferences.xul', 'Keybinder', 'chrome,titlebar=yes,close=no,toolbar=no,centerscreen,dialog=yes');
});

extensionPrefs.on("customXULDialog", function() {
keybinderDialog('Keybinder:CustomXUL', 'chrome://keybinder/content/customXulKeys.xul', 'CustomXUL', 'chrome,titlebar=yes,close=no,toolbar=no,centerscreen,dialog=yes');
});

var keybinderButton = ActionButton({
id: "keybinderToolbarButton",
label: "Keybinber",
icon: {
"18":"resource://keybinder-at-fail-dot-cl/data/icon18.png",
"32":"resource://keybinder-at-fail-dot-cl/data/icon32.png",
"36":"resource://keybinder-at-fail-dot-cl/data/icon36.png",
"64":"resource://keybinder-at-fail-dot-cl/data/icon64.png"
},
onClick: handleKeybinderClick
});

function handleKeybinderClick () {
keybinderDialog('Keybinder:config', 'chrome://keybinder/content/ttShortcuts_preferences.xul', 'Keybinder', 'chrome,titlebar=yes,close=no,toolbar=no,centerscreen,dialog=yes');
}

function preferenceDialogInit (window) {
    let self = this;
    this.window = window;
    this.filter = this.window.document.getElementById("ttCustomizableShortcuts_Filter");
    this.resetButton = this.window.document.getElementById("ttCustomizableShortcuts_Reset");
    this.editButton = this.window.document.getElementById("ttCustomizableShortcuts_Edit");
    this.disableButton = this.window.document.getElementById("ttCustomizableShortcuts_Disable");
    this.acceptButton = this.window.document.getElementById("ttCustomizableShortcuts_Accept");

    let tree = new PreferenceTree(this.window);
    this.treeElement = tree.toElement();
    this.window.setTimeout(function() { self.treeElement.view = new TreeView(), 0});

    this.acceptButton.addEventListener("command", function() {
        if ("undefined" != typeof(Overlays.overlays.conflicting)) {
            let checkForConflicting = Object.keys(Overlays.overlays.conflicting).length;
            if (checkForConflicting >= 1) { warnforConflicting(); }
            else { windowMediator.getMostRecentWindow("Keybinder:config").window.close(); }
        }
        else { windowMediator.getMostRecentWindow("Keybinder:config").window.close(); }
    }, false);

    this.resetButton.addEventListener("command", function() {
        let row = self.treeElement.currentIndex;
        let column = self.treeElement.columns.getLastColumn();
        let id = self.treeElement.view.getCellValue(row, column);
        let key = keys.find(id);
        Overlays.removeByKey(key);
        self.resetButton.setAttribute("disabled", true);
        self.treeElement.treeBoxObject.invalidateRow(row);
    }, false);

    this.editButton.addEventListener("command", function() {
        let row = self.treeElement.currentIndex;
        let column = self.treeElement.columns.getLastColumn();
        self.treeElement.startEditing(row, column);
    }, false);

    this.disableButton.addEventListener("command", function() {
        let row = self.treeElement.currentIndex;
        let column = self.treeElement.columns.getLastColumn();
        let id = self.treeElement.view.getCellValue(row, column);
        let key = keys.find(id);
        if (!Overlays.findByDisabledKey(key)) {
            new Overlay({
                key: key,
                shortcut: {
                    disabled: true
                }
            });
            self.disableButton.label = _("disableButton_true");
            self.disableButton.acesskey = _("disableButton_true_key");
            self.treeElement.treeBoxObject.invalidateRow(row);
        } else {
            Overlays.removeByKey(key);
            self.disableButton.label = _("disableButton_false");
            self.disableButton.acesskey = _("disableButton_false_key");
		    self.treeElement.treeBoxObject.invalidateRow(row);
    }

    let isDisabled = ( !! Overlays.findByDisabledKey(key)).toString();
Windows.toggleKey(key, isDisabled);
}, false);

this.filter.addEventListener("command", function() {
    self.treeElement.view = new TreeView(self.filter.value);
}, false);
}

function customXULDialogInit (window) {
    let self = this;
    this.window = window;
    this.filter = this.window.document.getElementById("KeybinderCustomXUL_Filter");
    this.addButton = this.window.document.getElementById("KeybinderCustomXUL_Add");
    this.editButton = this.window.document.getElementById("KeybinderCustomXUL_Edit");
    this.deleteButton = this.window.document.getElementById("KeybinderCustomXUL_Delete");
    this.acceptButton = this.window.document.getElementById("KeybinderCustomXUL_Accept");
    let customXULKeys = extensionPrefs.prefs['customXULKeys'];
    let conflictingKeys = [];

    let tree = new customXULTree(this.window);
    this.treeElement = tree.toElement();
    this.window.setTimeout(function() { self.treeElement.view = new customXULTreeView(), 0});

    this.acceptButton.addEventListener("command", function() {
        var { windowMediator } = require("../util/functions");

        if ("undefined" != typeof(Overlays.overlays.conflicting)) {
            let checkForConflicting = Object.keys(Overlays.overlays.conflicting).length;
            if (checkForConflicting >= 1) { warnforConflicting(); }
            else { windowMediator.getMostRecentWindow("Keybinder:config").window.close(); }
        } else { windowMediator.getMostRecentWindow("Keybinder:config").window.close(); }
    }, false);

    this.editButton.addEventListener("command", function() {
        let row = self.treeElement.currentIndex;
        let column = self.treeElement.columns.getNamedColumn("KeybinderCustomXUL_NameCol");
        self.treeElement.startEditing(row, column);
    }, false);

    this.deleteButton.addEventListener("command", function() {
        let row = self.treeElement.currentIndex;
        let column = self.treeElement.columns.getLastColumn();
        let id = self.treeElement.view.getCellValue(row, column);
        let key = keys.find(id);
        if (!Overlays.findByDisabledKey(key)) {
            new Overlay({
                key: key,
                shortcut: {
                    disabled: true
                }
            });
            self.disableButton.label = _("disableButton_true");
            self.disableButton.acesskey = _("disableButton_true_key");
            self.treeElement.treeBoxObject.invalidateRow(row);
        } else {
            Overlays.removeByKey(key);
            self.disableButton.label = _("disableButton_false");
            self.disableButton.acesskey = _("disableButton_false_key");
		    self.treeElement.treeBoxObject.invalidateRow(row);
    }

    let isDisabled = ( !! Overlays.findByDisabledKey(key)).toString();

Windows.toggleKey(key, isDisabled);
}, false);

this.filter.addEventListener("command", function() {
    self.treeElement.view = new customXULTreeView(self.filter.value);
}, false);
}

<commit_msg>Fix unnoticed syntax error.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
var { Windows } = require("../util/windows");

const keys = require("../core/key");
const { Overlay, Overlays } = require("../core/overlay");
const { PreferenceTree, customXULTree } = require("../prefs/tree");
const utils = require("sdk/window/utils");
const events = require("sdk/system/events");
const { ActionButton } = require("sdk/ui/button/action");
var _ = require("sdk/l10n").get;

const extensionPrefs = require("sdk/simple-prefs");

const { windowMediator, prompterService } = require("../util/functions");

function occurrences(string, subString, allowOverlapping) {
    /** Function count the occurrences of substring in a string;
     * @param {String} string   Required. The string;
     * @param {String} subString    Required. The string to search for;
     * @param {Boolean} allowOverlapping    Optional. Default: false;
     */
    string += "";
    subString += "";
    if (subString.length <= 0) return string.length + 1;

    var n = 0,
        pos = 0;
    var step = (allowOverlapping) ? (1) : (subString.length);

    while (true) {
        pos = string.indexOf(subString, pos);
        if (pos >= 0) {
            n++;
            pos += step;
        } else break;
    }
    return (n);
}

function ValidURL(str) {
    var strictPattern = new RegExp(/^((https?:\/\/(?!\*))|(\*\.))((([a-z\d]([a-z\d-]*[a-z\d])*|(\*))\.)+[a-z]{2,}|((\d{1,3}\.){3}\d{1,3}))(\:\d+)?(\/[-a-z\d%_.~+]*)*(\?[;&a-z\d%_.~+=-]*)?(\#[-a-z\d_]*)?$/i); // Strict URL matching pattern.
    var commonError_1 = new RegExp(/(^https?:\/\/){0}(\d{1,3}\.){3}\d(\:\d{2,5})?/i); // Catch IP without protocol, will try prepending 'http://' before failing.
    var commonError_2 = new RegExp(/^(https?:\/\/){0}([-a-z\d%_~+]{2,})\.([a-z-_]){2,}([0-9])*(\/|\:)?/i) // Catch domain.tld without protocol or wildcard; // will try prepending '*.' before failing.
    if ("" == str) {
        return false;
    }
    if (occurrences(str, '*') > 1) {
        return false;
    }
    if ('*' == str) {
        return str;
    } else if (!strictPattern.test(str)) {
        if (true == commonError_1.test(str)) {
            return String.concat("http://", str);
        } else if (true == commonError_2.test(str)) {
            return String.concat("*.", str);
        } else {
            return false;
        }
    } else {
        return str;
    }
}

function MenuItem(window, kind) {
	if (!utils.isBrowser(window)) { return } // Catch non-browser windows.
    this.window = window;
    if ("tabSwitching" == kind) {
		if (this.window.document.getElementById("prevTab-command")) { return; } // Prevent creating duplicate menu items.
        let parentmenu = this.window.document.getElementById("windowPopup");
        if (!parentmenu) { return; } // Only add the menu items if the Windows menu exists.
        let windowsep = this.window.document.getElementById("sep-window-list");
        this.separator = this._createElement("menuseparator");
        parentmenu.insertBefore(this.separator, windowsep);
        this.separator.setAttribute("id", "sep-switch-tabs");

        this.prevtab = this._createElement("menuitem");
        parentmenu.insertBefore(this.prevtab, this.separator.nextSibling);
        this.prevtab.setAttribute("id", "prevTab-command");
        this.prevtab.setAttribute("command", "Browser:PrevTab");
        this.prevtab.setAttribute("label", _("previousTab_label"));

        this.nexttab = this._createElement("menuitem");
        parentmenu.insertBefore(this.nexttab, this.prevtab.nextSibling);
        this.nexttab.setAttribute("id", "nextTab-command");
        this.nexttab.setAttribute("command", "Browser:NextTab");
        this.nexttab.setAttribute("label", _("nextTab_label"));
    } else {
        let self = this;
		if (this.window.document.getElementById("ttshortcutsMenuItem")) { return; } // Prevent creating duplicate menu items.
        this.element = this._createElement("menuitem");
        this.element.setAttribute("id", "ttshortcutsMenuItem");
        this.element.setAttribute("class", "menu-iconic");
        this.element.setAttribute("image", require("sdk/self").data.url("icon18.png"));
        this.element.setAttribute("label", _("MenuItem_label"));
        this.element.setAttribute("insertBefore", "sanitizeSeparator");
        this.element.setAttribute("oncommand", "if (!Cc[\"@mozilla.org/appshell/window-mediator;1\"]            .getService(Ci.nsIWindowMediator).getMostRecentWindow('Keybinder:config')) { window.openDialog('chrome://keybinder/content/ttShortcuts_preferences.xul','Keybinder','chrome,titlebar=yes,close=no,toolbar=no,centerscreen,dialog=yes') } else { Cc[\"@mozilla.org/appshell/window-mediator;1\"]            .getService(Ci.nsIWindowMediator).getMostRecentWindow('Keybinder:config').focus() }");
        let parentmenu = this.window.document.getElementById("menu_ToolsPopup");
        parentmenu.appendChild(this.element);
    }
}

MenuItem.prototype = {
    _built: false,

    _createStylesheet: function(href) {
        let doc = this.window.document;
        let style = doc.createProcessingInstruction("xml-stylesheet", 'href="' + href + '"');
        doc.insertBefore(style, doc.querySelector("window"));
    },

    _createElement: function(tag, parent) {
        let element = this.window.document.createElementNS(XUL_NS, tag);
        parent && parent.appendChild(element);
        return element;
    },

    _build: function() {
        return;
    },
};

function warnforConflicting() {
    prompterService.alert(window, _("conflictWarning.title"), _("conflictWarning.text"));
}

let createNewMenuItem = exports.createNewMenuItem = function (window, kind) {
new MenuItem (window, kind);
}

events.on("toplevel-window-ready",function(event) {
	event.subject.setTimeout(function() {
		let id = event.subject.window.document.documentElement.getAttribute("id");
		if ("ttShortcutsPrefsDialog" == id) {
			preferenceDialogInit(event.subject.window);
		}
		else if ("urlPatternsDialog" == id) {
			let window = event.subject.window;
            window.validateUrls = function() {
                let tempArray = (window.document.getElementById("textbox").value).split('\n');
                let arraySize = tempArray.length;
                let i = 0;
                for (let l of tempArray) {
                    if (!ValidURL(l)) {
                        tempArray[i] = "";
                    } else {
                        tempArray[i] = ValidURL(l);
                    }
                    i++;
                }
                tempArray = tempArray.filter(function(i) {
                    return i != ""
                });
                extensionPrefs.prefs['domainUrlPattern'] = JSON.stringify(tempArray);
            }
		}
	else if ("KeybinderCustomXULDialog" == id) {
		customXULDialogInit(event.subject.window);

	}
},7);
}, true);

function keybinderDialog (id, uri, name, options, extras = null) {
	if (!windowMediator.getMostRecentWindow(id)) {
		Windows.getMostRecentWindow().openDialog(uri, name, options, extras);
	}
	else {
		windowMediator.getMostRecentWindow(id).focus();
	}
}

extensionPrefs.on("UrlPatternsDialog", function() {
keybinderDialog('Keybinder:URLPatterns', 'chrome://keybinder/content/urlpatterns.xul', 'UrlPatterns', 'chrome,titlebar=yes,close=no,toolbar=no,centerscreen,dialog=yes', (JSON.parse(extensionPrefs.prefs['domainUrlPattern'])).join("\n"));
});

extensionPrefs.on("ShortcutsDialog", function() {
keybinderDialog('Keybinder:config', 'chrome://keybinder/content/ttShortcuts_preferences.xul', 'Keybinder', 'chrome,titlebar=yes,close=no,toolbar=no,centerscreen,dialog=yes');
});

extensionPrefs.on("customXULDialog", function() {
keybinderDialog('Keybinder:CustomXUL', 'chrome://keybinder/content/customXulKeys.xul', 'CustomXUL', 'chrome,titlebar=yes,close=no,toolbar=no,centerscreen,dialog=yes');
});

var keybinderButton = ActionButton({
id: "keybinderToolbarButton",
label: "Keybinber",
icon: {
"18":"resource://keybinder-at-fail-dot-cl/data/icon18.png",
"32":"resource://keybinder-at-fail-dot-cl/data/icon32.png",
"36":"resource://keybinder-at-fail-dot-cl/data/icon36.png",
"64":"resource://keybinder-at-fail-dot-cl/data/icon64.png"
},
onClick: handleKeybinderClick
});

function handleKeybinderClick () {
keybinderDialog('Keybinder:config', 'chrome://keybinder/content/ttShortcuts_preferences.xul', 'Keybinder', 'chrome,titlebar=yes,close=no,toolbar=no,centerscreen,dialog=yes');
}

function preferenceDialogInit (window) {
    let self = this;
    this.window = window;
    this.filter = this.window.document.getElementById("ttCustomizableShortcuts_Filter");
    this.resetButton = this.window.document.getElementById("ttCustomizableShortcuts_Reset");
    this.editButton = this.window.document.getElementById("ttCustomizableShortcuts_Edit");
    this.disableButton = this.window.document.getElementById("ttCustomizableShortcuts_Disable");
    this.acceptButton = this.window.document.getElementById("ttCustomizableShortcuts_Accept");

    let tree = new PreferenceTree(this.window);
    this.treeElement = tree.toElement();
    this.window.setTimeout(function() { self.treeElement.view = new TreeView() }, 0);

    this.acceptButton.addEventListener("command", function() {
        if ("undefined" != typeof(Overlays.overlays.conflicting)) {
            let checkForConflicting = Object.keys(Overlays.overlays.conflicting).length;
            if (checkForConflicting >= 1) { warnforConflicting(); }
            else { windowMediator.getMostRecentWindow("Keybinder:config").window.close(); }
        }
        else { windowMediator.getMostRecentWindow("Keybinder:config").window.close(); }
    }, false);

    this.resetButton.addEventListener("command", function() {
        let row = self.treeElement.currentIndex;
        let column = self.treeElement.columns.getLastColumn();
        let id = self.treeElement.view.getCellValue(row, column);
        let key = keys.find(id);
        Overlays.removeByKey(key);
        self.resetButton.setAttribute("disabled", true);
        self.treeElement.treeBoxObject.invalidateRow(row);
    }, false);

    this.editButton.addEventListener("command", function() {
        let row = self.treeElement.currentIndex;
        let column = self.treeElement.columns.getLastColumn();
        self.treeElement.startEditing(row, column);
    }, false);

    this.disableButton.addEventListener("command", function() {
        let row = self.treeElement.currentIndex;
        let column = self.treeElement.columns.getLastColumn();
        let id = self.treeElement.view.getCellValue(row, column);
        let key = keys.find(id);
        if (!Overlays.findByDisabledKey(key)) {
            new Overlay({
                key: key,
                shortcut: {
                    disabled: true
                }
            });
            self.disableButton.label = _("disableButton_true");
            self.disableButton.acesskey = _("disableButton_true_key");
            self.treeElement.treeBoxObject.invalidateRow(row);
        } else {
            Overlays.removeByKey(key);
            self.disableButton.label = _("disableButton_false");
            self.disableButton.acesskey = _("disableButton_false_key");
		    self.treeElement.treeBoxObject.invalidateRow(row);
    }

    let isDisabled = ( !! Overlays.findByDisabledKey(key)).toString();
Windows.toggleKey(key, isDisabled);
}, false);

this.filter.addEventListener("command", function() {
    self.treeElement.view = new TreeView(self.filter.value);
}, false);
}

function customXULDialogInit (window) {
    let self = this;
    this.window = window;
    this.filter = this.window.document.getElementById("KeybinderCustomXUL_Filter");
    this.addButton = this.window.document.getElementById("KeybinderCustomXUL_Add");
    this.editButton = this.window.document.getElementById("KeybinderCustomXUL_Edit");
    this.deleteButton = this.window.document.getElementById("KeybinderCustomXUL_Delete");
    this.acceptButton = this.window.document.getElementById("KeybinderCustomXUL_Accept");
    let customXULKeys = extensionPrefs.prefs['customXULKeys'];
    let conflictingKeys = [];

    let tree = new customXULTree(this.window);
    this.treeElement = tree.toElement();
    this.window.setTimeout(function() { self.treeElement.view = new customXULTreeView() }, 0);

    this.acceptButton.addEventListener("command", function() {
        var { windowMediator } = require("../util/functions");

        if ("undefined" != typeof(Overlays.overlays.conflicting)) {
            let checkForConflicting = Object.keys(Overlays.overlays.conflicting).length;
            if (checkForConflicting >= 1) { warnforConflicting(); }
            else { windowMediator.getMostRecentWindow("Keybinder:config").window.close(); }
        } else { windowMediator.getMostRecentWindow("Keybinder:config").window.close(); }
    }, false);

    this.editButton.addEventListener("command", function() {
        let row = self.treeElement.currentIndex;
        let column = self.treeElement.columns.getNamedColumn("KeybinderCustomXUL_NameCol");
        self.treeElement.startEditing(row, column);
    }, false);

    this.deleteButton.addEventListener("command", function() {
        let row = self.treeElement.currentIndex;
        let column = self.treeElement.columns.getLastColumn();
        let id = self.treeElement.view.getCellValue(row, column);
        let key = keys.find(id);
        if (!Overlays.findByDisabledKey(key)) {
            new Overlay({
                key: key,
                shortcut: {
                    disabled: true
                }
            });
            self.disableButton.label = _("disableButton_true");
            self.disableButton.acesskey = _("disableButton_true_key");
            self.treeElement.treeBoxObject.invalidateRow(row);
        } else {
            Overlays.removeByKey(key);
            self.disableButton.label = _("disableButton_false");
            self.disableButton.acesskey = _("disableButton_false_key");
		    self.treeElement.treeBoxObject.invalidateRow(row);
    }

    let isDisabled = ( !! Overlays.findByDisabledKey(key)).toString();

Windows.toggleKey(key, isDisabled);
}, false);

this.filter.addEventListener("command", function() {
    self.treeElement.view = new customXULTreeView(self.filter.value);
}, false);
}

<|endoftext|>


<commit_before>/*jslint node: true */
'use strict';

var mongoose = require('mongoose');
var util = require('../util');

function validateResponses (val) {
  return val !== undefined;
}

var responseSchema = new mongoose.Schema({
  __v: { type: Number, select: false },
  properties: {
    survey: String,
    humanReadableName: String,
    object_id: String,
    entries: [ {
      source: {
        type: { type: String },
        collector: String,
        started: Date,
        finished: Date
      },
      created: Date,
      files: [String],
      responses: {
        type: Object,
        validate: validateResponses
      }
    } ],
    centroid: [],
    indexedGeometry: {
      type: {
        type: { type: String },
        coordinates: []
      },
      select: false
    }
  },
  geometry: {
    type: { type: String },
    coordinates: []
  }
}, {
  autoIndex: false
});

// Indexes

// Ensure we have a geo index on the centroid field.
// We always restrict based on survey ID, so we use a compound index.
responseSchema.index({ survey: 1, 'properties.indexedGeometry': '2dsphere', created: 1 });

// Index the survey ID + creation date, which we use to sort
responseSchema.index({ survey: 1, created: 1 });

// Index the collector name
responseSchema.index({ survey: 1, 'source.collector': 1, created: 1 });

// Index the object ID
responseSchema.index({ survey: 1, object_id: 1 });

responseSchema.set('toObject', {
  transform: function (doc, ret, options) {
    return {
      type: 'Feature',
      id: ret._id,
      properties: ret.properties,
      geometry: ret.geometry
    };
  }
});

responseSchema.pre('save', function parseCentroid(next) {
  // check if there is a centroid. if yes, make sure the values are floats
  // TODO: abstract into a testable function.
  if (this.geo_info !== undefined) {
    var centroid = this.geo_info.centroid;
    if (centroid !== undefined) {
      centroid[0] = parseFloat(centroid[0]);
      centroid[1] = parseFloat(centroid[1]);
    }
  }
  next();
});

function simplify(ring) {
  // FIXME: Simplify the ring
  return ring;
}

function collectRingPoints(memo, ring) {
  simplify(ring).forEach(function (point) {
    memo.push(point);
  });
}

function collectPolygonPoints(memo, polygon) {
  polygon.forEach(function (ring) {
    collectRingPoints(memo, ring);
  });
}

function collectMultiPolygonPoints(memo, multiPolygon) {
  multiPolygon.forEach(function (polygon) {
    collectPolygonPoints(memo, polygon);
  });
}

// Collect all of the coordinates into one array, so we can index them.
responseSchema.pre('save', function collectPoints(next) {
  if (this.geometry !== undefined) {
    if (this.geometry.type === 'MultiPolygon') {
      this.geo_info.points = [];
      collectMultiPolygonPoints(this.geo_info.points, this.geo_info.geometry.coordinates);
    } else if (this.geometry.type === 'Polygon') {
      this.geo_info.points = [];
      collectPolygonPoints(this.geo_info.points, this.geo_info.geometry.coordinates);
    } else if (this.geometry.type === 'Point') {
      this.geo_info.points = this.geo_info.geometry.coordinates;
    }
  }
  next();
});

// Set the creation date.
responseSchema.pre('save', function setCreated(next) {
  if (this.created === undefined) {
    this.created = new Date();
  }
  next();
});

// Allow either parcel_id or object_id.
// Eventually we'll deprecate parcel_id.
responseSchema.pre('save', function setObjectId(next) {
  if (this.parcel_id !== undefined && this.object_id === undefined) {
    this.object_id = this.parcel_id;
  } else if (this.object_id !== undefined && this.parcel_id === undefined) {
    this.parcel_id = this.object_id;
  }
  next();
});

responseSchema.statics.getBounds = function getBounds(survey, done) {
  var bbox = [[-180, -89], [180, 89]];
  this.aggregate([
    {
      $match: { survey: survey }
    },
    {
      $project: {
        _id: '$_id',
        point: '$geo_info.centroid'
      }
    },
    {
      $unwind: '$point'
    },
    {
      $group: {
        _id: '$_id',
        x: { $first: '$point' },
        y: { $last: '$point' }
      }
    },
    {
      $group: {
        _id: 'bbox',
        minx: { $min: '$x' },
        miny: { $min: '$y' },
        maxx: { $max: '$x' },
        maxy: { $max: '$y' }
      }
    }
  ], function (error, response) {
    if (error) { return done(error); }

    if (response.length === 0) {
      return done(null, null);
    }

    var data = response[0];
    var bbox = [[ data.minx, data.miny ], [ data.maxx, data.maxy ]];
    done(null, bbox);
  });
};

var Response = module.exports = mongoose.model('Response', responseSchema, 'responseCollection');
<commit_msg>Tweak some references to old fields<commit_after>/*jslint node: true */
'use strict';

var mongoose = require('mongoose');
var util = require('../util');

function validateResponses (val) {
  return val !== undefined;
}

var responseSchema = new mongoose.Schema({
  __v: { type: Number, select: false },
  properties: {
    survey: String,
    humanReadableName: String,
    object_id: String,
    entries: [ {
      source: {
        type: { type: String },
        collector: String,
        started: Date,
        finished: Date
      },
      created: Date,
      files: [String],
      responses: {
        type: Object,
        validate: validateResponses
      }
    } ],
    centroid: [],
    indexedGeometry: {
      type: {
        type: { type: String },
        coordinates: []
      },
      select: false
    }
  },
  geometry: {
    type: { type: String },
    coordinates: []
  }
}, {
  autoIndex: false
});

// Indexes

// Ensure we have a geo index on the centroid field.
// We always restrict based on survey ID, so we use a compound index.
responseSchema.index({ survey: 1, 'properties.indexedGeometry': '2dsphere', created: 1 });

// Index the survey ID + creation date, which we use to sort
responseSchema.index({ survey: 1, created: 1 });

// Index the collector name
responseSchema.index({ survey: 1, 'source.collector': 1, created: 1 });

// Index the object ID
responseSchema.index({ survey: 1, object_id: 1 });

responseSchema.set('toObject', {
  transform: function (doc, ret, options) {
    return {
      type: 'Feature',
      id: ret._id,
      properties: ret.properties,
      geometry: ret.geometry
    };
  }
});

responseSchema.pre('save', function parseCentroid(next) {
  // check if there is a centroid. if yes, make sure the values are floats
  // TODO: abstract into a testable function.
  if (this.geo_info !== undefined) {
    var centroid = this.geo_info.centroid;
    if (centroid !== undefined) {
      centroid[0] = parseFloat(centroid[0]);
      centroid[1] = parseFloat(centroid[1]);
    }
  }
  next();
});

function simplify(ring) {
  // FIXME: Simplify the ring
  return ring;
}

function collectRingPoints(memo, ring) {
  simplify(ring).forEach(function (point) {
    memo.push(point);
  });
}

function collectPolygonPoints(memo, polygon) {
  polygon.forEach(function (ring) {
    collectRingPoints(memo, ring);
  });
}

function collectMultiPolygonPoints(memo, multiPolygon) {
  multiPolygon.forEach(function (polygon) {
    collectPolygonPoints(memo, polygon);
  });
}

// Collect all of the coordinates into one array, so we can index them.
responseSchema.pre('save', function collectPoints(next) {
  if (this.geometry !== undefined) {
    if (this.geometry.type === 'MultiPolygon') {
      this.geo_info.points = [];
      collectMultiPolygonPoints(this.geo_info.points, this.geo_info.geometry.coordinates);
    } else if (this.geometry.type === 'Polygon') {
      this.geo_info.points = [];
      collectPolygonPoints(this.geo_info.points, this.geo_info.geometry.coordinates);
    } else if (this.geometry.type === 'Point') {
      this.geo_info.points = this.geo_info.geometry.coordinates;
    }
  }
  next();
});

// Set the creation date.
responseSchema.pre('save', function setCreated(next) {
  if (this.properties.created === undefined) {
    this.properties.created = new Date();
  }
  next();
});

// Allow either parcel_id or object_id in the input, but only store object_id
// in the database.
// parcel_id is deprecated.
responseSchema.pre('save', function setObjectId(next) {
  if (this.parcel_id !== undefined && this.object_id === undefined) {
    this.object_id = this.parcel_id;
    delete this.parcel_id;
    console.log('warning issue=deprecated feature=response_parcel_id');
  }
  next();
});

responseSchema.statics.getBounds = function getBounds(survey, done) {
  var bbox = [[-180, -89], [180, 89]];
  this.aggregate([
    {
      $match: { survey: survey }
    },
    {
      $project: {
        _id: '$_id',
        point: '$geo_info.centroid'
      }
    },
    {
      $unwind: '$point'
    },
    {
      $group: {
        _id: '$_id',
        x: { $first: '$point' },
        y: { $last: '$point' }
      }
    },
    {
      $group: {
        _id: 'bbox',
        minx: { $min: '$x' },
        miny: { $min: '$y' },
        maxx: { $max: '$x' },
        maxy: { $max: '$y' }
      }
    }
  ], function (error, response) {
    if (error) { return done(error); }

    if (response.length === 0) {
      return done(null, null);
    }

    var data = response[0];
    var bbox = [[ data.minx, data.miny ], [ data.maxx, data.maxy ]];
    done(null, bbox);
  });
};

var Response = module.exports = mongoose.model('Response', responseSchema, 'responseCollection');
<|endoftext|>


<commit_before>// Resolving namespace conflicts
if (typeof majascan == "undefined") var majascan = {};

// xssTest module (example module). Searches in the response source
// for usual XSS test alerts like alert("xss");

// add Components.classes, interfaces, etc.
const {Cc,Ci,Cr,components} = require("chrome");

majascan.xssTest =
{
	incomingResponse: function(context, url, source) {
		var searchResult = source.search(/alert\(("xss"|"test"|"lol")\);/i);
		if (searchResult != -1) {
			var response = new require("./../moduleResponse").getmoduleResponse();
			response.setScore(100);
			response.setMessage("Typical XSS test code was found in the source of "+url);
			response.setVerboseMessage("JavaScript code indicating that "+
				"this website is vulnerable to XSS was found. The code was "+
				"found in the source of '"+url+"'");
			return response;
		}
		return null;
	}
}

majascan.getModule = function () {
	return majascan.xssTest;
}
// make gettabController accessible for other modules
exports.getModule = majascan.getModule;<commit_msg>Broaden scope of xssText module<commit_after>// Resolving namespace conflicts
if (typeof majascan == "undefined") var majascan = {};

// xssTest module (example module). Searches in the response source
// for usual XSS test alerts like alert("xss");

// add Components.classes, interfaces, etc.
const {Cc,Ci,Cr,components} = require("chrome");

majascan.xssTest =
{
	incomingResponse: function(context, url, source) {
		var searchResult = source.search(/alert\(("|').+?xss.+?("|')\);/i);
		if (searchResult != -1) {
			var response = new require("./../moduleResponse").getmoduleResponse();
			response.setScore(100);
			response.setMessage("Typical XSS test code was found in the source of "+url);
			response.setVerboseMessage("JavaScript code indicating that "+
				"this website is vulnerable to XSS was found. The code was "+
				"found in the source of '"+url+"'");
			return response;
		}
		return null;
	}
}

majascan.getModule = function () {
	return majascan.xssTest;
}
// make gettabController accessible for other modules
exports.getModule = majascan.getModule;<|endoftext|>


<commit_before>'use strict';

var fs        = require('fs')
  , resolve   = require('path').resolve
  , deferred  = require('deferred')
  , delay     = deferred.delay
  , promisify = deferred.promisify
  , mkdir     = promisify(fs.mkdir)
  , open      = promisify(fs.open)
  , rename    = promisify(fs.rename)
  , write     = promisify(fs.write)
  , close     = promisify(fs.close)
  , writeFile = promisify(fs.writeFile)
  , unlink    = promisify(fs.unlink)
  , rmdir     = promisify(fs.rmdir)

  , pgPath = resolve(__dirname, './__playground/_watch-alt');

module.exports = function (t, a, d) {
	var ondirchange = 0, onfilechange = 0, ondirend = 0, onfileend = 0
	  , DELAY = 200, DELAYWAIT = 2000
	  , dirPath = resolve(pgPath, 'tmpdir')
	  , filePath = resolve(dirPath, 'tmpfile');

	a.throws(function () {
		t(filePath);
	}, "Not existing");

	delay(function () {
		return mkdir(dirPath);
	}, DELAY)()(delay(function () {
		var dirWatch;
		dirWatch = t(dirPath);
		dirWatch.on('change', function () { ++ondirchange; });
		dirWatch.on('end', function () { ++ondirend; });
	}, DELAY))(delay(function () {
		return writeFile(filePath, 'raz');
	}, DELAY))(delay(function () {
		var fileWatch;
		a(ondirchange, 1, "Dir change: File created");
		a(ondirend, 0, "Dir end: File created");
		ondirchange = ondirend = 0;
		fileWatch = t(filePath);
		fileWatch.on('change', function () { ++onfilechange; });
		fileWatch.on('end', function () { ++onfileend; });
	}, DELAYWAIT))(delay(function () {
		return open(filePath, 'a')(function (fd) {
			return write(fd, new Buffer('dwatrzy'), 0, 3, null)(function () {
				return close(fd);
			});
		});
	}, DELAY))(delay(function () {
		a(ondirchange, 0, "Dir change: File changed");
		a(ondirend, 0, "Dir end: File changed");
		a(onfilechange, 1, "File change: File created");
		a(onfileend, 0, "File end: File created");
		ondirchange = ondirend = onfilechange = onfileend = 0;
		return rename(filePath, filePath + 'r');
	}, DELAYWAIT))(delay(function () {
		a(ondirchange, 1, "Dir change: File renamed");
		a(ondirend, 0, "Dir end: File renamed");
		a(onfilechange, 0, "File change: File renamed");
		a(onfileend, 1, "File end: File renamed");
		ondirchange = ondirend = onfilechange = onfileend = 0;
		return rename(filePath + 'r', filePath);
	}, DELAYWAIT))(delay(function () {
		a(ondirchange, 1, "Dir change: File renamed back");
		a(ondirend, 0, "Dir end: File renamed back");
		a(onfilechange, 0, "File change: File renamed back");
		a(onfileend, 0, "File end: File renamed back");
		ondirchange = ondirend = onfilechange = onfileend = 0;
		return unlink(filePath);
	}, DELAYWAIT))(delay(function () {
		a(ondirchange, 1, "Dir change: File removed");
		a(ondirend, 0, "Dir end: File removed");
		a(onfilechange, 0, "File change: File removed");
		a(onfileend, 0, "File end: File removed");
		ondirchange = ondirend = onfilechange = onfileend = 0;
		return rmdir(dirPath);
	}, DELAYWAIT))(delay(function () {
		a(ondirchange, 0, "Dir change: Dir removed");
		a(ondirend, 1, "Dir end: Dir removed");
		a(onfilechange, 0, "File change: Dir removed");
		a(onfileend, 0, "File end: Dir removed");
	}, DELAYWAIT)).end(d, d);
};
<commit_msg>Increase delay<commit_after>'use strict';

var fs        = require('fs')
  , resolve   = require('path').resolve
  , deferred  = require('deferred')
  , delay     = deferred.delay
  , promisify = deferred.promisify
  , mkdir     = promisify(fs.mkdir)
  , open      = promisify(fs.open)
  , rename    = promisify(fs.rename)
  , write     = promisify(fs.write)
  , close     = promisify(fs.close)
  , writeFile = promisify(fs.writeFile)
  , unlink    = promisify(fs.unlink)
  , rmdir     = promisify(fs.rmdir)

  , pgPath = resolve(__dirname, './__playground/_watch-alt');

module.exports = function (t, a, d) {
	var ondirchange = 0, onfilechange = 0, ondirend = 0, onfileend = 0
	  , DELAY = 200, DELAYWAIT = 2000
	  , dirPath = resolve(pgPath, 'tmpdir')
	  , filePath = resolve(dirPath, 'tmpfile');

	a.throws(function () {
		t(filePath);
	}, "Not existing");

	delay(function () {
		return mkdir(dirPath);
	}, DELAY)()(delay(function () {
		var dirWatch;
		dirWatch = t(dirPath);
		dirWatch.on('change', function () { ++ondirchange; });
		dirWatch.on('end', function () { ++ondirend; });
	}, DELAY))(delay(function () {
		return writeFile(filePath, 'raz');
	}, DELAYWAIT))(delay(function () {
		var fileWatch;
		a(ondirchange, 1, "Dir change: File created");
		a(ondirend, 0, "Dir end: File created");
		ondirchange = ondirend = 0;
		fileWatch = t(filePath);
		fileWatch.on('change', function () { ++onfilechange; });
		fileWatch.on('end', function () { ++onfileend; });
	}, DELAYWAIT))(delay(function () {
		return open(filePath, 'a')(function (fd) {
			return write(fd, new Buffer('dwatrzy'), 0, 3, null)(function () {
				return close(fd);
			});
		});
	}, DELAY))(delay(function () {
		a(ondirchange, 0, "Dir change: File changed");
		a(ondirend, 0, "Dir end: File changed");
		a(onfilechange, 1, "File change: File created");
		a(onfileend, 0, "File end: File created");
		ondirchange = ondirend = onfilechange = onfileend = 0;
		return rename(filePath, filePath + 'r');
	}, DELAYWAIT))(delay(function () {
		a(ondirchange, 1, "Dir change: File renamed");
		a(ondirend, 0, "Dir end: File renamed");
		a(onfilechange, 0, "File change: File renamed");
		a(onfileend, 1, "File end: File renamed");
		ondirchange = ondirend = onfilechange = onfileend = 0;
		return rename(filePath + 'r', filePath);
	}, DELAYWAIT))(delay(function () {
		a(ondirchange, 1, "Dir change: File renamed back");
		a(ondirend, 0, "Dir end: File renamed back");
		a(onfilechange, 0, "File change: File renamed back");
		a(onfileend, 0, "File end: File renamed back");
		ondirchange = ondirend = onfilechange = onfileend = 0;
		return unlink(filePath);
	}, DELAYWAIT))(delay(function () {
		a(ondirchange, 1, "Dir change: File removed");
		a(ondirend, 0, "Dir end: File removed");
		a(onfilechange, 0, "File change: File removed");
		a(onfileend, 0, "File end: File removed");
		ondirchange = ondirend = onfilechange = onfileend = 0;
		return rmdir(dirPath);
	}, DELAYWAIT))(delay(function () {
		a(ondirchange, 0, "Dir change: Dir removed");
		a(ondirend, 1, "Dir end: Dir removed");
		a(onfilechange, 0, "File change: Dir removed");
		a(onfileend, 0, "File end: Dir removed");
	}, DELAYWAIT)).end(d, d);
};
<|endoftext|>


<commit_before>(function (Array) {
	var extensions = [each, where, any, select, take, skip];

	extensions.forEach(element => {
		if(!Array.prototype[element.name]) {
			Array.prototype[element.name] = element;
		} else {
			throw `Function "${element.name}" already exists`;
		}
	});

	function each(callback) {
		var length = this.length;
		var index = 0;

		while (index < length) {
			callback.call(null, this[index], index);
			index++;
		}
	}

	function where(callback) {
		var length = this.length;
		var index = 0;
		var newArray = [];

		while (index < length) {
			let response = callback.call(null, this[index]);
			if (response === true) {
				newArray.push(this[index])
			}
			index++;
		}
		return newArray;
	}

	function any(spec) {
		var length = this.length;
		var index = 0;
		var isFunction = (typeof spec === 'function');

		while (index < length) {
			let result = isFunction ? spec(this[index]) : this[index] === spec;
			if (result) return true;
			index++
		}
		return false;
	}

	function select(callback) {
		return this.map(callback);
	}

	function take(size, callback) {
		var length = this.length;
		var index = 0;
		var newArray = [];

		if (typeof size !== 'number') {
			throw new TypeError('Excepted a number');
		}

		while (index < length) {
			let response = callback.call(null, this[index]);
			if (response) {
				newArray.push(this[index]);
				if(newArray.length === size) {
					return newArray;
				}
			}
			index++;
		}
	}

	function skip(start) {
		var isNotNumber = typeof start !== 'number';
		if (isNotNumber) {
			throw new TypeError('Excepted a number');
		}

		return this.slice(start, this.length);
	}
})(global.Array);
<commit_msg>Fix merge conflicts<commit_after>(function (Array) {
	var extensions = [each, where, any, select, take, skip];

	extensions.forEach(element => {
		if(!Array.prototype[element.name]) {
			Array.prototype[element.name] = element;
		} else {
			throw `Function "${element.name}" already exists`;
		}
	});

	function each(callback) {
		var length = this.length;
		var index = 0;

		while (index < length) {
			callback.call(null, this[index], index);
			index++;
		}
	}

	function where(callback) {
		var length = this.length;
		var index = 0;
		var newArray = [];

		while (index < length) {
			let response = callback.call(null, this[index]);
			if (response === true) {
				newArray.push(this[index])
			}
			index++;
		}
		return newArray;
	}

	function any(spec) {
		var length = this.length;
		var index = 0;
		var isFunction  = (typeof spec === 'function');

		while (index < length) {
			let result = isFunction ? spec(this[index]) : this[index] === spec;
			if (result) return true;
			index++
		}
		return false;
	}

	function select(callback) {
		return this.map(callback);
	}

	function take(size, callback) {
		var length = this.length;
		var index = 0;
		var newArray = [];

		if (typeof size !== 'number') {
			throw new TypeError('Excepted a number');
		}

		while (index < length) {
			let response = callback.call(null, this[index]);
			if (response) {
				newArray.push(this[index]);
				if(newArray.length === size) {
					return newArray;
				}
			}
			index++;
		}
	}

	function skip(start) {
		var isNotNumber = typeof start !== 'number';
		if (isNotNumber) {
			throw new TypeError('Excepted a number');
		}

		return this.slice(start, this.length);
	}
})(global.Array);
<|endoftext|>