<commit_before>/*
  Map browser based on OpenLayers 4.
  Popup windows

  Copyright (C) 2017 Øyvind Hanssen, LA7ECA, ohanssen@acm.org

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published
  by the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU Affero General Public License for more details.

  You should have received a copy of the GNU Affero General Public License
  along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

// FIXME
var isMobile = false;

/**
 * @classdesc
 * Popup window manager class.
 * For now, there is only one active popup at a time.
 *
 * @constructor
 * @param {polaric.MapBrowser} mb - Map browser instance.
 */

polaric.Popup = function(mb) {
   this.mb            = mb;
   this.onDiv         = document.getElementById("map");
   this.activepopup   = null;
   this.psubdiv       = null;
   this.allowedPopups = 1;
   this.onCallback    = null;
   this.offCallback   = null;
   this.geoPos        = false;
   this.image         = null;
   var t = this;

   this.mb.view.on('change:center', onChangeCenter);
   this.mb.map.on('click', onClick);
   this.mb.map.on('change:view', onChangeView);

   function onChangeCenter() {
       if (t.geoPos && t.geoPos != null) t.setPositionGeo(t.geoPos);
    }

   function onClick() {
       t.removePopup();
   }

   function onChangeView() {
       t.removePopup();
       t.mb.view.on('change:center', onChangeCenter);
       // FIXME: Unregister handler on previous view?
   }
}

/**
 * Deactivate popup.
 */
polaric.Popup.prototype.removePopup = function()
{
  if (this.activepopup == null)
    return;
  if (this.offCallback != null)
    this.offCallback();
  this.isMenu = false;
  this.allowedPopups++;

  this.activepopup.style.display = "none" ;
  this.activepopup.parentNode.removeChild(this.activepopup);
  this.activepopup = null;
  this.geoPos = null;
}

/**
 * Return true if popup is active.
 * @returns {boolean}
 */

polaric.Popup.prototype.popupActive = function()
   { return (this.activepopup != null); }

/**
 * Register callback functions
 * For popup activation (on) and deactivation (off)
 * @param {function} on - Callback to be invoked when popup is activated.
 * @param {function} off - Callback to be invoked when popup is deactivated.
 */

polaric.Popup.prototype.onPopup = function(on, off)
   { this.onCallback = on; this.offCallback = off; }

/**
 * Activate popup.
 * @param {Object.<string,*>} props - Options
 * @param {string|undefined} props.html - HTML code to render inside the popup.
 * @param {ol.Pixel|undefined} props.pixPos - Pixel position of upper left corner of popup.
 * @param {ol.Coordinate|undefined} props.geoPos - LatLong position of upper left corner of popup.
 * @param {boolean|undefined} props.image - true if we want a cross to be displayed at the position.
 * @param {boolean|undefined} props.draggable - true if we want the popup to be draggable and pinnable.
 * @param {string|undefined} props.id - unique identifier (used as id of element).
 *
 */

polaric.Popup.prototype.showPopup = function (props)
{
    var t = this;
    var x, y;
    if (props.id && props.id != null && document.getElementById(props.id) != null) {
        $('#'+props.id).effect('bounce');
        return null;
    }

    var pdiv = ((props.elem && props.elem!=null)
        ? props.elem : document.createElement('div'));
    if (props.html)
        pdiv.innerHTML = props.html;
    if (props.vnode)
        m.mount(pdiv, props.vnode);

    if (props.id && props.id != null) pdiv.id = props.id;

    pdiv.className = 'POPUP' +
       ((props.cclass && props.cclass != null) ? " "+props.cclass : "");

    setTimeout( function() {
       if (props.geoPos && props.geoPos != null) {
           t.geoPos = props.geoPos;
           props.pixPos = t.mb.map.getPixelFromCoordinate
             (ol.proj.fromLonLat(props.geoPos, t.mb.view.getProjection()));
       }
       else
           t.geoPos = null;

       if (props.pixPos && props.pixPos != null)
          { x = props.pixPos[0]; y=props.pixPos[1]; }
       t.popup_(pdiv, x, y, props.image);
    }, 200);

    if (props.draggable) {
       if (props.pinned)
           pdiv._pinned = true;
       var pinimage = document.createElement('img');
       pinimage.className = "popup_pin";
       if (pdiv._pinned) {
           pinimage.src = "images/pin-red.png";
           t.allowedPopups++;
           t.activepopup = null;
       } else
           pinimage.src = "images/pin-green.png";
       pdiv.appendChild(pinimage);

       pinimage.onclick = function(e) {
          pdiv._pinned = (pdiv._pinned ? false : true);
	      if (props.pin)
	   	     props.pin(pdiv._pinned); // Pin callback
          if (pdiv._pinned) {
             pinimage.src = "images/pin-red.png";
             t.activepopup = null;
             t.allowedPopups++;
          }
          else {
             pinimage.src = "images/pin-green.png";
       //      t.removePopup();
             t.activepopup = pdiv;
             t.allowedPopups--;
          }
       };
    }

    pdiv.onmousedown = function(e)
       { e = (e)?e:((event)?event:null); e.stopPropagation(); return null; };
    pdiv.onmouseup = function(e)
       { e = (e)?e:((event)?event:null); return null; };
    pdiv.onclick = function(e)
       { e = (e)?e:((event)?event:null); e.stopPropagation(); return null; };

   if (props.resizable)
       $(pdiv).resizable();
   if (props.draggable)
       $(pdiv).draggable({ delay: 100, opacity: 0.7, start: props.dragStart, stop: props.dragStop }  );
   return pdiv;

}

/**
 * Activate popup with content from remote server.
 * @param {string} url - URL of remote content.
 * @param {Object.<string,*>} props - Options, see showPopup()
 */
// FIXME: Needs testing.

polaric.Popup.prototype.remotePopup = function(url, props)
{
    var d =  this.showPopup(props);
    call(url, null, function(txt) { d.innerHTML = txt; } );
    return d;
}

/**
 * Activate popup with content from remote server and with
 * a stylesheet.
 * @param {string} url - URL of remote content.
 * @param {string} css - CSS-class to add to the popup.
 * @param {Object.<string,*>} props - Options, see showPopup()
 *
 */
// FIXME: Needs testing.

polaric.Popup.prototype.remotePopupCSS = function(url, css, props)
{
   var d = this.remotePopup(url, props)
        if (css != null)
           setTimeout(function() {
              div.className = css;
           }, 900);

}

/**
 * Show a cross at a given map position.
 * @param {ol.Coordinate} geoPos - LatLong position of where to put upper left corner of popup.
 */

polaric.Popup.prototype.showImageGeo = function(geoPos) {
   var t = this;
   setTimeout( function() {
      t.geoPos = geoPos;
      var pixPos = t.mb.map.getPixelFromCoordinate
         (ol.proj.fromLonLat(geoPos, t.mb.view.getProjection()));
      t.popup_(null, pixPos[0], pixPos[1], true);
   }, 900);
}

/**
 * Change the position of a popup or image.
 * @param {ol.Coordinate} geoPos - LatLong position of upper left corner of popup.
 */

polaric.Popup.prototype.setPositionGeo = function(geoPos) {
    if (this.activepopup && this.activepopup != null) {
        var pixPos = this.mb.map.getPixelFromCoordinate
             (ol.proj.fromLonLat(geoPos, this.mb.view.getProjection()));
        this.setPosition_(pixPos[0], pixPos[1]);
    }
}

/**
 * Change the position of a popup or image. Pixel position on screen.
 * @param {ol.Coordinate} pixPos - Pixel position of upper left corner of popup.
 */

polaric.Popup.prototype.setPositionPix = function(pixPos) {
    if (this.activepopup && this.activepopup != null)
        this.setPosition_(pixPos[0], pixPos[1]);
}

/**
 * Set the position of a popup or image. Pixel position on screen.
 * @private
 */

polaric.Popup.prototype.setPosition_ = function(x, y)
  {
      var xoff=0;
      var yoff=0;
      var xoffs = yoffs = false;

      if (this.image != null) {
         this.image.style.left= -9+'px';
         this.image.style.top= -12+'px';
      }

     /*
      * If part if window is outside the viewport, we may adjust the
      * position of the window. It may be easier to just move the map, but
      * sometimes it is desirable not to..
      */
      xoff = x + 4 + this.psubdiv.clientWidth - this.onDiv.clientWidth;
      if (xoff > 0) {
        xoffs = true;
        x -= xoff;
        if (x < 1) x=1;
        if (this.image!=null)
          this.image.style.left = (xoff-9)+'px';
      }

      yoff = y + 4 + this.psubdiv.clientHeight - this.onDiv.clientHeight;
      if (yoff > 0) {
	    yoffs = true;
        y -= yoff;
        if (y < 1) y=1;
        if (this.image!=null)
          this.image.style.top =(yoff-12)+'px';
      }

      this.activepopup.style.left = x-3+"px";
      this.activepopup.style.top  = y-3+"px";

      if (xoffs && yoffs && this.image != null)
         this.image.style.display = "none";
  }

/**
 * Activate a popup - show it on the screen.
 * @private
 */

polaric.Popup.prototype.popup_ = function(elem, x, y, img)
{
     var t = this;
     if (this.allowedPopups <= 0)
         return;
     ;

     if (elem == null)
         elem = document.createElement('div');

     this.psubdiv = this.activepopup = elem;
     if (img != null && img) {
         this.image = document.createElement('img');
         this.activepopup.appendChild(this.image);
      	 this.image.src='images/cross.png';
    	 this.image.style.position='absolute';
         this.image.style.zIndex = 1001;
     }

     /* Add the popup window div to the viewport */
     this.onDiv.appendChild(this.activepopup);

     this.activepopup.style.position   = 'absolute';
     this.activepopup.style.display    = 'block';
     this.activepopup.style.padding    = '2px';
     this.activepopup.style.cursor     = 'default';

     /* If viewport is less than 500 pixels wide and content is
      * wider than the viewport, let popup be as wide as the viewport
      */
     if (this.onDiv.clientWidth < 500 && this.elem.clientWidth > this.onDiv.clientWidth)
        this.activepopup.style.minWidth = this.onDiv.clientWidth+'px';

     /* Is the height of the content more than the available height?
      * Then we need a scroller
      */
     if (elem.clientHeight+10 > this.onDiv.clientHeight) {
         this.activepopup.style.maxHeight = this.onDiv.clientHeight-5 + "px";
         elem.id = 'wrapper'; // FIXME?

         /* Activate scroller */
         /* FIXME: Special treatment of mobile devices? */
         if (isMobile)
            setTimeout(function () {
              myScroll = new IScroll(activepopup, {
                    scrollbars : true,
                    tap : true
                 });
            }, 1000);
         else
            this.activepopup.style.overflowY  = 'scroll';
     }
     else
        this.activepopup.style.overflowY = 'visible';

     this.setPosition_(x, y);
     this.activepopup.style.zIndex  = 1301;

     this.allowedPopups--;
     if (this.onCallback != null)
        this.onCallback();
}
<commit_msg>Popup fix<commit_after>/*
  Map browser based on OpenLayers 4.
  Popup windows

  Copyright (C) 2017 Øyvind Hanssen, LA7ECA, ohanssen@acm.org

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU Affero General Public License as published
  by the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU Affero General Public License for more details.

  You should have received a copy of the GNU Affero General Public License
  along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

// FIXME
var isMobile = false;

/**
 * @classdesc
 * Popup window manager class.
 * For now, there is only one active popup at a time.
 *
 * @constructor
 * @param {polaric.MapBrowser} mb - Map browser instance.
 */

polaric.Popup = function(mb) {
   this.mb            = mb;
   this.onDiv         = document.getElementById("map");
   this.activepopup   = null;
   this.psubdiv       = null;
   this.allowedPopups = 1;
   this.onCallback    = null;
   this.offCallback   = null;
   this.geoPos        = false;
   this.image         = null;
   var t = this;

   this.mb.view.on('change:center', onChangeCenter);
   this.mb.map.on('click', onClick);
   this.mb.map.on('change:view', onChangeView);

   function onChangeCenter() {
       if (t.geoPos && t.geoPos != null) t.setPositionGeo(t.geoPos);
    }

   function onClick() {
       t.removePopup();
   }

   function onChangeView() {
       t.removePopup();
       t.mb.view.on('change:center', onChangeCenter);
       // FIXME: Unregister handler on previous view?
   }
}

/**
 * Deactivate popup.
 */
polaric.Popup.prototype.removePopup = function()
{
  if (this.activepopup == null)
    return;
  if (this.offCallback != null)
    this.offCallback();
  this.isMenu = false;
  this.allowedPopups++;

  this.activepopup.style.display = "none" ;
  this.activepopup.parentNode.removeChild(this.activepopup);
  this.activepopup = null;
  this.geoPos = null;
}

/**
 * Return true if popup is active.
 * @returns {boolean}
 */

polaric.Popup.prototype.popupActive = function()
   { return (this.activepopup != null); }

/**
 * Register callback functions
 * For popup activation (on) and deactivation (off)
 * @param {function} on - Callback to be invoked when popup is activated.
 * @param {function} off - Callback to be invoked when popup is deactivated.
 */

polaric.Popup.prototype.onPopup = function(on, off)
   { this.onCallback = on; this.offCallback = off; }

/**
 * Activate popup.
 * @param {Object.<string,*>} props - Options
 * @param {string|undefined} props.html - HTML code to render inside the popup.
 * @param {ol.Pixel|undefined} props.pixPos - Pixel position of upper left corner of popup.
 * @param {ol.Coordinate|undefined} props.geoPos - LatLong position of upper left corner of popup.
 * @param {boolean|undefined} props.image - true if we want a cross to be displayed at the position.
 * @param {boolean|undefined} props.draggable - true if we want the popup to be draggable and pinnable.
 * @param {string|undefined} props.id - unique identifier (used as id of element).
 *
 */

polaric.Popup.prototype.showPopup = function (props)
{
    var t = this;
    var x, y;
    if (props.id && props.id != null && document.getElementById(props.id) != null) {
        $('#'+props.id).effect('bounce');
        return null;
    }

    var pdiv = ((props.elem && props.elem!=null)
        ? props.elem : document.createElement('div'));
    if (props.html)
        pdiv.innerHTML = props.html;
    if (props.vnode)
        m.mount(pdiv, props.vnode);

    if (props.id && props.id != null) pdiv.id = props.id;

    pdiv.className = 'POPUP' +
       ((props.cclass && props.cclass != null) ? " "+props.cclass : "");

    setTimeout( function() {
       if (props.geoPos && props.geoPos != null) {
           t.geoPos = props.geoPos;
           props.pixPos = t.mb.map.getPixelFromCoordinate
             (ol.proj.fromLonLat(props.geoPos, t.mb.view.getProjection()));
       }
       else
           t.geoPos = null;

       if (props.pixPos && props.pixPos != null)
          { x = props.pixPos[0]; y=props.pixPos[1]; }
       t.popup_(pdiv, x, y, props.image);

       if (props.draggable) {
          if (props.pinned)
              pdiv._pinned = true;
          var pinimage = document.createElement('img');
          pinimage.className = "popup_pin";
          if (pdiv._pinned) {
              pinimage.src = "images/pin-red.png";
              t.allowedPopups++;
              t.activepopup = null;
          } else
             pinimage.src = "images/pin-green.png";
          pdiv.appendChild(pinimage);

         pinimage.onclick = function(e) {
             pdiv._pinned = (pdiv._pinned ? false : true);
	         if (props.pin)
                props.pin(pdiv._pinned); // Pin callback
             if (pdiv._pinned) {
                pinimage.src = "images/pin-red.png";
                t.activepopup = null;
                t.allowedPopups++;
             }
             else {
                pinimage.src = "images/pin-green.png";
                t.removePopup();
                t.activepopup = pdiv;
                t.allowedPopups--;
             }
         };
    }  }, 200);

    pdiv.onmousedown = function(e)
       { e = (e)?e:((event)?event:null); e.stopPropagation(); return null; };
    pdiv.onmouseup = function(e)
       { e = (e)?e:((event)?event:null); return null; };
    pdiv.onclick = function(e)
       { e = (e)?e:((event)?event:null); e.stopPropagation(); return null; };

   if (props.resizable)
       $(pdiv).resizable();
   if (props.draggable)
       $(pdiv).draggable({ delay: 100, opacity: 0.7, start: props.dragStart, stop: props.dragStop }  );
   return pdiv;

}

/**
 * Activate popup with content from remote server.
 * @param {string} url - URL of remote content.
 * @param {Object.<string,*>} props - Options, see showPopup()
 */
// FIXME: Needs testing.

polaric.Popup.prototype.remotePopup = function(url, props)
{
    var d =  this.showPopup(props);
    call(url, null, function(txt) { d.innerHTML = txt; } );
    return d;
}

/**
 * Activate popup with content from remote server and with
 * a stylesheet.
 * @param {string} url - URL of remote content.
 * @param {string} css - CSS-class to add to the popup.
 * @param {Object.<string,*>} props - Options, see showPopup()
 *
 */
// FIXME: Needs testing.

polaric.Popup.prototype.remotePopupCSS = function(url, css, props)
{
   var d = this.remotePopup(url, props)
        if (css != null)
           setTimeout(function() {
              div.className = css;
           }, 900);

}

/**
 * Show a cross at a given map position.
 * @param {ol.Coordinate} geoPos - LatLong position of where to put upper left corner of popup.
 */

polaric.Popup.prototype.showImageGeo = function(geoPos) {
   var t = this;
   setTimeout( function() {
      t.geoPos = geoPos;
      var pixPos = t.mb.map.getPixelFromCoordinate
         (ol.proj.fromLonLat(geoPos, t.mb.view.getProjection()));
      t.popup_(null, pixPos[0], pixPos[1], true);
   }, 900);
}

/**
 * Change the position of a popup or image.
 * @param {ol.Coordinate} geoPos - LatLong position of upper left corner of popup.
 */

polaric.Popup.prototype.setPositionGeo = function(geoPos) {
    if (this.activepopup && this.activepopup != null) {
        var pixPos = this.mb.map.getPixelFromCoordinate
             (ol.proj.fromLonLat(geoPos, this.mb.view.getProjection()));
        this.setPosition_(pixPos[0], pixPos[1]);
    }
}

/**
 * Change the position of a popup or image. Pixel position on screen.
 * @param {ol.Coordinate} pixPos - Pixel position of upper left corner of popup.
 */

polaric.Popup.prototype.setPositionPix = function(pixPos) {
    if (this.activepopup && this.activepopup != null)
        this.setPosition_(pixPos[0], pixPos[1]);
}

/**
 * Set the position of a popup or image. Pixel position on screen.
 * @private
 */

polaric.Popup.prototype.setPosition_ = function(x, y)
  {
      var xoff=0;
      var yoff=0;
      var xoffs = yoffs = false;

      if (this.image != null) {
         this.image.style.left= -9+'px';
         this.image.style.top= -12+'px';
      }

     /*
      * If part if window is outside the viewport, we may adjust the
      * position of the window. It may be easier to just move the map, but
      * sometimes it is desirable not to..
      */
      xoff = x + 4 + this.psubdiv.clientWidth - this.onDiv.clientWidth;
      if (xoff > 0) {
        xoffs = true;
        x -= xoff;
        if (x < 1) x=1;
        if (this.image!=null)
          this.image.style.left = (xoff-9)+'px';
      }

      yoff = y + 4 + this.psubdiv.clientHeight - this.onDiv.clientHeight;
      if (yoff > 0) {
	    yoffs = true;
        y -= yoff;
        if (y < 1) y=1;
        if (this.image!=null)
          this.image.style.top =(yoff-12)+'px';
      }

      this.activepopup.style.left = x-3+"px";
      this.activepopup.style.top  = y-3+"px";

      if (xoffs && yoffs && this.image != null)
         this.image.style.display = "none";
  }

/**
 * Activate a popup - show it on the screen.
 * @private
 */

polaric.Popup.prototype.popup_ = function(elem, x, y, img)
{
     var t = this;
     if (this.allowedPopups <= 0)
         return;
     ;

     if (elem == null)
         elem = document.createElement('div');

     this.psubdiv = this.activepopup = elem;
     if (img != null && img) {
         this.image = document.createElement('img');
         this.activepopup.appendChild(this.image);
      	 this.image.src='images/cross.png';
    	 this.image.style.position='absolute';
         this.image.style.zIndex = 1001;
     }

     /* Add the popup window div to the viewport */
     this.onDiv.appendChild(this.activepopup);

     this.activepopup.style.position   = 'absolute';
     this.activepopup.style.display    = 'block';
     this.activepopup.style.padding    = '2px';
     this.activepopup.style.cursor     = 'default';

     /* If viewport is less than 500 pixels wide and content is
      * wider than the viewport, let popup be as wide as the viewport
      */
     if (this.onDiv.clientWidth < 500 && this.elem.clientWidth > this.onDiv.clientWidth)
        this.activepopup.style.minWidth = this.onDiv.clientWidth+'px';

     /* Is the height of the content more than the available height?
      * Then we need a scroller
      */
     if (elem.clientHeight+10 > this.onDiv.clientHeight) {
         this.activepopup.style.maxHeight = this.onDiv.clientHeight-5 + "px";
         elem.id = 'wrapper'; // FIXME?

         /* Activate scroller */
         /* FIXME: Special treatment of mobile devices? */
         if (isMobile)
            setTimeout(function () {
              myScroll = new IScroll(activepopup, {
                    scrollbars : true,
                    tap : true
                 });
            }, 1000);
         else
            this.activepopup.style.overflowY  = 'scroll';
     }
     else
        this.activepopup.style.overflowY = 'visible';

     this.setPosition_(x, y);
     this.activepopup.style.zIndex  = 1301;

     this.allowedPopups--;
     if (this.onCallback != null)
        this.onCallback();
}
<|endoftext|>


<commit_before>const path = require('path');
const webpack = require('webpack');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
const StyleExtHtmlWebpackPlugin = require('style-ext-html-webpack-plugin');
const OfflinePlugin = require('offline-plugin');
const WebpackDashboardPlugin = require('webpack-dashboard/plugin');

const { isDevelopment, port } = require('./configuration');

const baseEntry = ['babel-polyfill', './src/client/index.jsx'];
const devEntry = [
  'react-hot-loader/patch',
  `webpack-dev-server/client?http://localhost:${port}`,
  'webpack/hot/only-dev-server',
];
const entry = isDevelopment ? devEntry.concat(baseEntry) : baseEntry;

const basePlugins = [
  new webpack.EnvironmentPlugin(['NODE_ENV']),
  new webpack.DefinePlugin({ __DEV__: isDevelopment }),
  new CopyWebpackPlugin([{ from: 'src/shared/assets/favicon' }]),
  new HtmlWebpackPlugin({
    filename: isDevelopment ? 'index.html' : '../build/index.html',
    template: 'src/shared/index.html',
    inject: 'body',
    minify: { collapseWhitespace: true },
  }),
  new ExtractTextWebpackPlugin('[name].[hash].css'),
  new StyleExtHtmlWebpackPlugin({ minify: true }),
];
const devPlugins = [
  new webpack.HotModuleReplacementPlugin(),
  new webpack.NamedModulesPlugin(),
  new WebpackDashboardPlugin(),
];
const prodPlugins = [
  new webpack.LoaderOptionsPlugin({ minimize: true, debug: false }),
  new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false } }),
  new OfflinePlugin({
    publicPath: '/',
    relativePaths: false,
    ServiceWorker: {
      events: true,
      navigateFallbackURL: '/',
      minify: true,
    },
    AppCache: false,
    externals: ['index.html'],
  }),
];
const plugins = basePlugins.concat(isDevelopment ? devPlugins : prodPlugins);

module.exports = {
  entry,
  output: {
    path: path.join(__dirname, 'public'),
    publicPath: '/',
    filename: '[name].[hash].js',
  },
  devtool: isDevelopment ? 'eval-source-map' : false,
  resolve: { extensions: ['.js', '.jsx'] },
  plugins,
  module: {
    rules: [
      { test: /\.jsx?$/, loader: 'eslint-loader', enforce: 'pre' },
      { test: /\.jsx?$/, loader: 'babel-loader', exclude: /node_modules/, options: { babelrc: false, presets: [['env', { modules: false }], 'stage-0', 'react'], plugins: ['react-hot-loader/babel'] } },
      { test: /\.css$/, use: ExtractTextWebpackPlugin.extract({ fallback: 'style-loader', use: 'css-loader' }) },
      { test: /\.md$/, use: [{ loader: 'raw-loader' }, { loader: 'remarkable-loader', options: { html: true } }] },
      { test: /\.(jpe?g|png)$/, use: [{ loader: 'file-loader', options: { name: 'assets/[name].[ext]' } }, { loader: 'image-webpack-loader', options: { mozjpeg: { quality: 80 } } }], include: /assets/ },
      { test: /\.(woff2?|ttf|eot|svg)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000 } },
    ],
  },
  devServer: {
    port,
    compress: true,
    hot: true,
    historyApiFallback: true,
  },
};
<commit_msg>Remove the build folder from the service worker<commit_after>const path = require('path');
const webpack = require('webpack');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
const StyleExtHtmlWebpackPlugin = require('style-ext-html-webpack-plugin');
const OfflinePlugin = require('offline-plugin');
const WebpackDashboardPlugin = require('webpack-dashboard/plugin');

const { isDevelopment, port } = require('./configuration');

const baseEntry = ['babel-polyfill', './src/client/index.jsx'];
const devEntry = [
  'react-hot-loader/patch',
  `webpack-dev-server/client?http://localhost:${port}`,
  'webpack/hot/only-dev-server',
];
const entry = isDevelopment ? devEntry.concat(baseEntry) : baseEntry;

const basePlugins = [
  new webpack.EnvironmentPlugin(['NODE_ENV']),
  new webpack.DefinePlugin({ __DEV__: isDevelopment }),
  new CopyWebpackPlugin([{ from: 'src/shared/assets/favicon' }]),
  new HtmlWebpackPlugin({
    filename: isDevelopment ? 'index.html' : '../build/index.html',
    template: 'src/shared/index.html',
    inject: 'body',
    minify: { collapseWhitespace: true },
  }),
  new ExtractTextWebpackPlugin('[name].[hash].css'),
  new StyleExtHtmlWebpackPlugin({ minify: true }),
];
const devPlugins = [
  new webpack.HotModuleReplacementPlugin(),
  new webpack.NamedModulesPlugin(),
  new WebpackDashboardPlugin(),
];
const prodPlugins = [
  new webpack.LoaderOptionsPlugin({ minimize: true, debug: false }),
  new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false } }),
  new OfflinePlugin({
    publicPath: '/',
    relativePaths: false,
    ServiceWorker: {
      events: true,
      navigateFallbackURL: '/',
      minify: true,
    },
    AppCache: false,
    excludes: ['build/**/*'],
  }),
];
const plugins = basePlugins.concat(isDevelopment ? devPlugins : prodPlugins);

module.exports = {
  entry,
  output: {
    path: path.join(__dirname, 'public'),
    publicPath: '/',
    filename: '[name].[hash].js',
  },
  devtool: isDevelopment ? 'eval-source-map' : false,
  resolve: { extensions: ['.js', '.jsx'] },
  plugins,
  module: {
    rules: [
      { test: /\.jsx?$/, loader: 'eslint-loader', enforce: 'pre' },
      { test: /\.jsx?$/, loader: 'babel-loader', exclude: /node_modules/, options: { babelrc: false, presets: [['env', { modules: false }], 'stage-0', 'react'], plugins: ['react-hot-loader/babel'] } },
      { test: /\.css$/, use: ExtractTextWebpackPlugin.extract({ fallback: 'style-loader', use: 'css-loader' }) },
      { test: /\.md$/, use: [{ loader: 'raw-loader' }, { loader: 'remarkable-loader', options: { html: true } }] },
      { test: /\.(jpe?g|png)$/, use: [{ loader: 'file-loader', options: { name: 'assets/[name].[ext]' } }, { loader: 'image-webpack-loader', options: { mozjpeg: { quality: 80 } } }], include: /assets/ },
      { test: /\.(woff2?|ttf|eot|svg)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000 } },
    ],
  },
  devServer: {
    port,
    compress: true,
    hot: true,
    historyApiFallback: true,
  },
};
<|endoftext|>


<commit_before>var spritesmith = require('spritesmith'),
    json2css = require('json2css'),
    _ = require('underscore'),
    fs = require('fs'),
    path = require('path'),
    url = require('url2');

function ExtFormat() {
  this.formatObj = {};
}
ExtFormat.prototype = {
  'add': function (name, val) {
    this.formatObj[name] = val;
  },
  'get': function (filepath) {
    // Grab the extension from the filepath
    var ext = path.extname(filepath),
        lowerExt = ext.toLowerCase();

    // Look up the file extenion from our format object
    var formatObj = this.formatObj,
        format = formatObj[lowerExt];
    return format;
  }
};

// Create img and css formats
var imgFormats = new ExtFormat(),
    cssFormats = new ExtFormat();

// Add our img formats
imgFormats.add('.png', 'png');
imgFormats.add('.jpg', 'jpeg');
imgFormats.add('.jpeg', 'jpeg');

// Add our css formats
cssFormats.add('.styl', 'stylus');
cssFormats.add('.stylus', 'stylus');
cssFormats.add('.sass', 'sass');
cssFormats.add('.scss', 'scss');
cssFormats.add('.less', 'less');
cssFormats.add('.json', 'json');
cssFormats.add('.css', 'css');

module.exports = function (grunt) {
  // Create a SpriteMaker function
  function SpriteMaker() {
    var data = this.data,
        src = data.src,
        destImg = data.destImg,
        destCSS = data.destCSS,
        cssTemplate = data.cssTemplate,
        that = this;

    // Verify all properties are here
    if (!src || !destImg || !destCSS) {
      return grunt.fatal('grunt.sprite requires a src, destImg, and destCSS property');
    }

    // Load in all images from the src
    var srcFiles = grunt.file.expand(src);

    // Create an async callback
    var cb = this.async();

    // Determine the format of the image
    var imgOpts = data.imgOpts || {},
        imgFormat = imgOpts.format || imgFormats.get(destImg) || 'png';

    // Set up the defautls for imgOpts
    _.defaults(imgOpts, {'format': imgFormat});

    // Run through spritesmith
    var spritesmithParams = {
          'src': srcFiles,
          'engine': data.engine || 'auto',
          'algorithm': data.algorithm || 'top-down',
          'padding': data.padding || 0,
          'algorithmOpts': data.algorithmOpts || {},
          'engineOpts': data.engineOpts || {},
          'exportOpts': imgOpts
        };
    spritesmith(spritesmithParams, function (err, result) {
      // If an error occurred, callback with it
      if (err) {
        grunt.fatal(err);
        return cb(err);
      }

      // Otherwise, write out the result to destImg
      var destImgDir = path.dirname(destImg);
      grunt.file.mkdir(destImgDir);
      fs.writeFileSync(destImg, result.image, 'binary');

      // Generate a listing of CSS variables
      var coordinates = result.coordinates,
          properties = result.properties,
          spritePath = data.imgPath || url.relative(destCSS, destImg),
          cssVarMap = data.cssVarMap || function noop () {},
          cleanCoords = [];

      // Clean up the file name of the file
      Object.getOwnPropertyNames(coordinates).sort().forEach(function (file) {
        // Extract the image name (exlcuding extension)
        var fullname = path.basename(file),
            nameParts = fullname.split('.');

        // If there is are more than 2 parts, pop the last one
        if (nameParts.length >= 2) {
          nameParts.pop();
        }

        // Extract out our name
        var name = nameParts.join('.'),
            coords = coordinates[file];

        // Specify the image for the sprite
        coords.name = name;
        coords.source_image = file;
        coords.image = spritePath;
        coords.total_width = properties.width;
        coords.total_height = properties.height;

        // Map the coordinates through cssVarMap
        coords = cssVarMap(coords) || coords;

        // Save the cleaned name and coordinates
        cleanCoords.push(coords);
      });

      var cssFormat = 'spritesmith-custom',
          cssOptions = data.cssOpts || {};

      // If there's a custom template, use it
      if (cssTemplate) {
        if (typeof cssTemplate === 'function') {
          json2css.addTemplate(cssFormat, cssTemplate);
        } else {
          json2css.addMustacheTemplate(cssFormat, fs.readFileSync(cssTemplate, 'utf8'));
        }
      } else {
      // Otherwise, override the cssFormat and fallback to 'json'
        cssFormat = data.cssFormat || cssFormats.get(destCSS) || 'json';
      }

      // Render the variables via json2css
      var cssStr = json2css(cleanCoords, {'format': cssFormat, 'formatOpts': cssOptions});

      // Write it out to the CSS file
      var destCSSDir = path.dirname(destCSS);
      grunt.file.mkdir(destCSSDir);
      fs.writeFileSync(destCSS, cssStr, 'utf8');

      // Fail task if errors were logged.
      if (that.errorCount) { cb(false); }

      // Otherwise, print a success message.
      grunt.log.writeln('Files "' + destCSS + '", "' + destImg + '" created.');

      // Callback
      cb(true);
    });
  }

  // Export the SpriteMaker function
  grunt.registerMultiTask('sprite', 'Spritesheet making utility', SpriteMaker);
};
<commit_msg>Fixing up quotes and indentation<commit_after>var spritesmith = require('spritesmith'),
    json2css = require('json2css'),
    _ = require('underscore'),
    fs = require('fs'),
    path = require('path'),
    url = require('url2');

function ExtFormat() {
  this.formatObj = {};
}
ExtFormat.prototype = {
  'add': function (name, val) {
    this.formatObj[name] = val;
  },
  'get': function (filepath) {
    // Grab the extension from the filepath
    var ext = path.extname(filepath),
        lowerExt = ext.toLowerCase();

    // Look up the file extenion from our format object
    var formatObj = this.formatObj,
        format = formatObj[lowerExt];
    return format;
  }
};

// Create img and css formats
var imgFormats = new ExtFormat(),
    cssFormats = new ExtFormat();

// Add our img formats
imgFormats.add('.png', 'png');
imgFormats.add('.jpg', 'jpeg');
imgFormats.add('.jpeg', 'jpeg');

// Add our css formats
cssFormats.add('.styl', 'stylus');
cssFormats.add('.stylus', 'stylus');
cssFormats.add('.sass', 'sass');
cssFormats.add('.scss', 'scss');
cssFormats.add('.less', 'less');
cssFormats.add('.json', 'json');
cssFormats.add('.css', 'css');

module.exports = function (grunt) {
  // Create a SpriteMaker function
  function SpriteMaker() {
    var data = this.data,
        src = data.src,
        destImg = data.destImg,
        destCSS = data.destCSS,
        cssTemplate = data.cssTemplate,
        that = this;

    // Verify all properties are here
    if (!src || !destImg || !destCSS) {
      return grunt.fatal('grunt.sprite requires a src, destImg, and destCSS property');
    }

    // Load in all images from the src
    var srcFiles = grunt.file.expand(src);

    // Create an async callback
    var cb = this.async();

    // Determine the format of the image
    var imgOpts = data.imgOpts || {},
        imgFormat = imgOpts.format || imgFormats.get(destImg) || 'png';

    // Set up the defautls for imgOpts
    _.defaults(imgOpts, {'format': imgFormat});

    // Run through spritesmith
    var spritesmithParams = {
      src: srcFiles,
      engine: data.engine || 'auto',
      algorithm: data.algorithm || 'top-down',
      padding: data.padding || 0,
      algorithmOpts: data.algorithmOpts || {},
      engineOpts: data.engineOpts || {},
      exportOpts: imgOpts
    };
    spritesmith(spritesmithParams, function (err, result) {
      // If an error occurred, callback with it
      if (err) {
        grunt.fatal(err);
        return cb(err);
      }

      // Otherwise, write out the result to destImg
      var destImgDir = path.dirname(destImg);
      grunt.file.mkdir(destImgDir);
      fs.writeFileSync(destImg, result.image, 'binary');

      // Generate a listing of CSS variables
      var coordinates = result.coordinates,
          properties = result.properties,
          spritePath = data.imgPath || url.relative(destCSS, destImg),
          cssVarMap = data.cssVarMap || function noop () {},
          cleanCoords = [];

      // Clean up the file name of the file
      Object.getOwnPropertyNames(coordinates).sort().forEach(function (file) {
        // Extract the image name (exlcuding extension)
        var fullname = path.basename(file),
            nameParts = fullname.split('.');

        // If there is are more than 2 parts, pop the last one
        if (nameParts.length >= 2) {
          nameParts.pop();
        }

        // Extract out our name
        var name = nameParts.join('.'),
            coords = coordinates[file];

        // Specify the image for the sprite
        coords.name = name;
        coords.source_image = file;
        coords.image = spritePath;
        coords.total_width = properties.width;
        coords.total_height = properties.height;

        // Map the coordinates through cssVarMap
        coords = cssVarMap(coords) || coords;

        // Save the cleaned name and coordinates
        cleanCoords.push(coords);
      });

      var cssFormat = 'spritesmith-custom',
          cssOptions = data.cssOpts || {};

      // If there's a custom template, use it
      if (cssTemplate) {
        if (typeof cssTemplate === 'function') {
          json2css.addTemplate(cssFormat, cssTemplate);
        } else {
          json2css.addMustacheTemplate(cssFormat, fs.readFileSync(cssTemplate, 'utf8'));
        }
      } else {
      // Otherwise, override the cssFormat and fallback to 'json'
        cssFormat = data.cssFormat || cssFormats.get(destCSS) || 'json';
      }

      // Render the variables via json2css
      var cssStr = json2css(cleanCoords, {format: cssFormat, formatOpts: cssOptions});

      // Write it out to the CSS file
      var destCSSDir = path.dirname(destCSS);
      grunt.file.mkdir(destCSSDir);
      fs.writeFileSync(destCSS, cssStr, 'utf8');

      // Fail task if errors were logged.
      if (that.errorCount) { cb(false); }

      // Otherwise, print a success message.
      grunt.log.writeln('Files "' + destCSS + '", "' + destImg + '" created.');

      // Callback
      cb(true);
    });
  }

  // Export the SpriteMaker function
  grunt.registerMultiTask('sprite', 'Spritesheet making utility', SpriteMaker);
};
<|endoftext|>


<commit_before>var Pagination = function(collection, perPage, current) {
	this.collection = collection;
	this.total = this.collection.length;
	this.perPage = perPage || 10;
	this.pageCount = Math.ceil(collection.length / this.perPage);
	this.current = Math.min(Math.max(current || 1, 1), this.pageCount);
};

Pagination.prototype = {
	hasNext: function() {
		return this.current < this.pageCount;
	},

	next: function() {
		if (this.hasNext())
			return this.current + 1;
	},

	hasPrevious: function() {
		return this.current > 1;
	},

	previous: function() {
		if (this.hasPrevious())
			return this.current - 1;
	},

	atFirstPage: function() {
		return this.current == 1;
	},

	atLastPage: function() {
		return this.current == this.pageCount;
	},

	firstIndex: function() {
		return Math.max(0, this.perPage * (this.current - 1));
	},

	lastIndex: function() {
		return Math.min(
			Math.max(0, this.perPage * this.current),
			Math.max(this.total, 0)
		);
	}
};

module.exports = Pagination;
<commit_msg>Make Pagination work if collection.length changes.<commit_after>var Pagination = function(collection, perPage, index) {
	this.collection = collection;
	this.perPage = perPage || 10;
	this._index = index;
};

Pagination.prototype = {
	getIndex: function() {
		return Math.min(Math.max(this._index, 1), this.pageCount());
	},

	pageCount: function() {
		return Math.ceil(this.collection.length / this.perPage);
	},

	hasNext: function() {
		return this.getIndex() < this.pageCount();
	},

	next: function() {
		if (this.hasNext())
			return this.getIndex() + 1;
	},

	hasPrevious: function() {
		return this.getIndex() > 1;
	},

	previous: function() {
		if (this.hasPrevious())
			return this.getIndex() - 1;
	},

	atFirstPage: function() {
		return this.getIndex() == 1;
	},

	atLastPage: function() {
		return this.getIndex() == this.pageCount();
	},

	firstIndex: function() {
		return Math.max(0, this.perPage * (this.getIndex() - 1));
	},

	lastIndex: function() {
		return Math.min(
			Math.max(0, this.perPage * this.getIndex()),
			Math.max(this.collection.length, 0)
		);
	}
};

module.exports = Pagination;
<|endoftext|>


<commit_before>import React from 'react';
import classNames from 'classnames';
import suggestUsers from '../../../actions/search/suggestUsers';
/**
 * Properties:
 *  placeholder: placeholder text
 *  returnType: username if specified else user _id
 */

class UsersInput extends React.Component {
    initDropdown(){
        let returnType = (this.props.returnType === 'username') ? 'username' : '_id';

        $('#users_input_div').dropdown({
            fields: {
                name: 'username',
                value: returnType
            },
            minCharacters: 1,
            allowAdditions: false,
            apiSettings:{
                responseAsync: function(settings, callback) {
                    const query = settings.urlData.query;

                    context.executeAction(suggestUsers, {
                        query: query,
                    }).then( (response) => {
                        callback(response);
                    });
                }
            }
        });
    }
    componentDidMount(){
        this.initDropdown();
    }
    componentDidUpdate(){
        this.initDropdown();
    }
    getSelected(){
        console.log(this.refs.users_input.value);
        return this.refs.users_input.value;
    }
    render(){
        let classes = classNames({
            'ui': true,
            'fluid': true,
            'multiple': true,
            'search': true,
            'selection': true,
            'dropdown': true
        });
        return (

              <input type="hidden" name="users_input" ref='users_input' id='users_input'></input>

{this.props.placeholder}

        );
    }
}

UsersInput.contextTypes = {
    executeAction: React.PropTypes.func.isRequired
};
export default UsersInput;
<commit_msg>users input minor fix<commit_after>import React from 'react';
import classNames from 'classnames';
import suggestUsers from '../../../actions/search/suggestUsers';
/**
 * Properties:
 *  placeholder: placeholder text
 *  returnType: username if specified else user _id
 */

class UsersInput extends React.Component {
    initDropdown(){
        let returnType = (this.props.returnType === 'username') ? 'username' : '_id';

        $('#users_input_div').dropdown({
            fields: {
                name: 'username',
                value: returnType
            },
            minCharacters: 1,
            allowAdditions: false,
            apiSettings:{
                responseAsync: function(settings, callback) {
                    const query = settings.urlData.query;

                    context.executeAction(suggestUsers, {
                        query: query,
                    }).then( (response) => {
                        callback(response);
                    });
                }
            }
        });
    }
    componentDidMount(){
        this.initDropdown();
    }
    componentDidUpdate(){
        this.initDropdown();
    }
    getSelected(){
        return this.refs.users_input.value;
    }
    render(){
        let classes = classNames({
            'ui': true,
            'fluid': true,
            'multiple': true,
            'search': true,
            'selection': true,
            'dropdown': true
        });
        return (

              <input type="hidden" name="users_input" ref='users_input' id='users_input'></input>

{this.props.placeholder}

        );
    }
}

UsersInput.contextTypes = {
    executeAction: React.PropTypes.func.isRequired
};
export default UsersInput;
<|endoftext|>


<commit_before>var progressTable = function(element, data) {

  this.container = element;

  if (data) {
    this.currentData = data;
  }
};

progressTable.prototype = {
  init: function () {

    this.duration = 750;

    this.parse_data(this.currentData);

    this.updateData();

    return this;
  },
  /**
   * Parse data
   * @param data [array of objects]
   * @return parsed data
   */
  parse_data: function(data) {
    var self = this;

    // escape if there are no data
    if (!data) {
      return false;
    }

    this.valuesSuma = 0;

    data.forEach(function(d) {
      self.valuesSuma += parseInt(d.value);
    });

    data.forEach(function(d) {
      d.name = d.name;
      d.value = +d.value;
      d.percents = d.value / self.valuesSuma * 100;
    });

    this.currentData = data;

    return data;
  },
  /**
   * Append row
   * @desc add row to table
   */
  appendRow: function(data) {
    var tr = this.container.append('tr');

    var name = tr.append('td')
        .attr('class', 'name');

    name.append('i')
        .attr('class', 'ico ico-document');

    name.text(data.name);

    tr.append('td')
      .attr('class', 'progress')
        .append('span')
          .attr('class', 'progress-container')
          .append('span')
            .attr('class', 'progress-bar')
            .style('width', data.percents + '%');

    tr.append('td')
      .attr('class', 'value')
      .text(data.value);

    tr.append('td')
      .attr('class', 'percents')
      .text(Math.round(data.percents)+ '%');
  },
  /**
   * Update data
   * @desc render table
   */
  updateData: function(data) {
    var self = this;

    if (!data) {
      data = this.currentData;
    }

    // escape if there is no data
    if (!data) {
      return false;
    }

    this.currentData.map(self.appendRow, this);
  },
  /**
   * Clean table
   * @desc clean all table rows
   */
  cleanTable: function() {
    this.container.selectAll('tr').remove();
  }
};
<commit_msg>progress-table - remove executable<commit_after>var progressTable = function(element, data) {

  this.container = element;

  if (data) {
    this.currentData = data;
  }
};

progressTable.prototype = {
  init: function () {

    this.duration = 750;

    this.parse_data(this.currentData);

    this.updateData();

    return this;
  },
  /**
   * Parse data
   * @param data [array of objects]
   * @return parsed data
   */
  parse_data: function(data) {
    var self = this;

    // escape if there are no data
    if (!data) {
      return false;
    }

    this.valuesSuma = 0;

    data.forEach(function(d) {
      self.valuesSuma += parseInt(d.value);
    });

    data.forEach(function(d) {
      d.name = d.name;
      d.value = +d.value;
      d.percents = d.value / self.valuesSuma * 100;
    });

    this.currentData = data;

    return data;
  },
  /**
   * Append row
   * @desc add row to table
   */
  appendRow: function(data) {
    var tr = this.container.append('tr');

    var name = tr.append('td')
        .attr('class', 'name');

    name.append('i')
        .attr('class', 'ico ico-document');

    name.text(data.name);

    tr.append('td')
      .attr('class', 'progress')
        .append('span')
          .attr('class', 'progress-container')
          .append('span')
            .attr('class', 'progress-bar')
            .style('width', data.percents + '%');

    tr.append('td')
      .attr('class', 'value')
      .text(data.value);

    tr.append('td')
      .attr('class', 'percents')
      .text(Math.round(data.percents)+ '%');
  },
  /**
   * Update data
   * @desc render table
   */
  updateData: function(data) {
    var self = this;

    if (!data) {
      data = this.currentData;
    }

    // escape if there is no data
    if (!data) {
      return false;
    }

    this.currentData.map(self.appendRow, this);
  },
  /**
   * Clean table
   * @desc clean all table rows
   */
  cleanTable: function() {
    this.container.selectAll('tr').remove();
  }
};
<|endoftext|>


<commit_before>export default [
	require('./aquaman').default,
	require('./wild-revolvers').default,
	require('./rhinebeck').default,
	require('./mirage-isle').default,
	// require('./class-lua').default,
	// require('./repo-import').default,
	// require('./echo-ridge').default,
	// require('./elixir').default,
	// require('./fireflies').default,
	// require('./snowy-mountain').default
];
<commit_msg>Show a couple other projects<commit_after>export default [
	require('./aquaman').default,
	require('./wild-revolvers').default,
	require('./rhinebeck').default,
	require('./mirage-isle').default,
	// require('./class-lua').default,
	// require('./repo-import').default,
	require('./echo-ridge').default,
	// require('./elixir').default,
	require('./fireflies').default,
	// require('./snowy-mountain').default
];
<|endoftext|>


<commit_before>OMAR.models.BBOX = Backbone.Model.extend(
{
    defaults:{
        "minx":-180.0,
        "miny":-90.0,
        "maxx":180.0,
        "maxy":90.0
    },
    initialize:function(options)
    {
    },
    toWmsString:function()
    {
        return (this.get("minx")+","+this.get("miny")+","+
                this.get("maxx")+","+this.get("maxy"));
    },
    validate:function(attrs)
    {
    },
    setFromWmsString:function(s)
    {
        var splitBounds = s.split(",");
        if(splitBounds.length == 4)
        {
            this.minx =parseFloat(splitBounds[0]);
            this.miny =parseFloat(splitBounds[1]);
            this.maxx =parseFloat(splitBounds[2]);
            this.maxy =parseFloat(splitBounds[3]);

        }

        return this;
    },
    toCql:function(columnName)
    {
        var result = "";
        var bad = this.validate(this.attributes);
        if(!bad)
        {
            result = "BBOX("+columnName+","+this.toWmsString()+")";
        }

        return result;
    }
}
);

OMAR.views.BBOX = Backbone.View.extend({
    el:"#BBOXId",
    initialize: function(params)
    {
        // this should create a variable for us called this.$el
        this.setElement(this.el);
        this.model = new OMAR.models.BBOX();
        this.lowerLeftBboxEl = $("#lowerLeftBbox");
        this.upperRightBboxEl = $("#upperRightBbox");
        this.model.on("error",
            function(model,err) {
                alert("BBOX Has errors: " + err);
            });
    },
    events:{
        "change #lowerLeftBbox" : "llOnChange"
    },
    llOnChange: function(e){
        var v = this.lowerLeftBboxEl.val();
        var values = v.split(",");
        if(values.length ==2)
        {
            this.model.set({minx:values[0],miny:values[1]});
        }
    },
    bboxError:function(model, err){
    },
    render:function()
    {
        this.lowerLeftBboxEl.val(this.model.get("minx")+","
            +this.model.get("miny"));
        this.upperRightBboxEl.val(this.model.get("maxx")+","
            +this.model.get("maxy"));
    }
});

<commit_msg>Added first stage of OpenLayers.<commit_after>OMAR.models.BBOX = Backbone.Model.extend(
{
    defaults:{
        "minx":-180.0,
        "miny":-90.0,
        "maxx":180.0,
        "maxy":90.0
    },
    initialize:function(options)
    {
    },
    toWmsString:function()
    {
        return (this.get("minx")+","+this.get("miny")+","+
                this.get("maxx")+","+this.get("maxy"));
    },
    validate:function(attrs)
    {
    },
    setFromWmsString:function(s)
    {
        var splitBounds = s.split(",");
        if(splitBounds.length == 4)
        {
            this.minx =parseFloat(splitBounds[0]);
            this.miny =parseFloat(splitBounds[1]);
            this.maxx =parseFloat(splitBounds[2]);
            this.maxy =parseFloat(splitBounds[3]);

        }

        return this;
    },
    toCql:function(columnName)
    {
        var result = "";
        var bad = this.validate(this.attributes);
        if(!bad)
        {
            result = "BBOX("+columnName+","+this.toWmsString()+")";
        }

        return result;
    }
}
);

OMAR.views.BBOX = Backbone.View.extend({
    el:"#BBOXId",
    initialize: function(params)
    {
        // this should create a variable for us called this.$el
        this.setElement(this.el);
        this.model = new OMAR.models.BBOX();
        this.lowerLeftBboxEl = $("#lowerLeftBbox");
        this.upperRightBboxEl = $("#upperRightBbox");
        this.model.on("change", function() {alert("here")});
        this.model.on("error",
            function(model,err) {
                alert("BBOX Has errors: " + err);
            });
    },
    events:{
        "change #lowerLeftBbox" : "llOnChange"
    },
    llOnChange: function(e){
        var v = this.lowerLeftBboxEl.val();
        var values = v.split(",");
        if(values.length ==2)
        {
            this.model.set({minx:values[0],miny:values[1]});
        }
    },
    bboxError:function(model, err){
    },
    render:function()
    {
        this.lowerLeftBboxEl.val(this.model.get("minx")+","
            +this.model.get("miny"));
        this.upperRightBboxEl.val(this.model.get("maxx")+","
            +this.model.get("maxy"));
    }
});

<|endoftext|>


<commit_before>/**
 * Created by mac002 on 1/2/17.
 */

const delimiter = "~";

module.exports = {
  // splits the id into an object with its three parts: library, topic, key
  getParts: (id) => {
    let IdParts = {}
    let parts = id.split(delimiter);
    if (parts.length === 3) {
      IdParts = {
        library: parts[0]
        , topic: parts[1]
        , key: parts[2]
      };
    } else {
      IdParts = undefined;
    }
      return IdParts;
    }
  // extracts the library part of an ID
  , getLibrary: (id) => {
    let parts = id.split(delimiter);
    if (parts.length === 3) {
      return parts[0];
    } else {
      return undefined;
    }
  }
  // extracts the topic part of an ID
  , getTopic: (id) => {
    let parts = id.split(delimiter);
    if (parts.length === 3) {
      return parts[1];
    } else {
      return undefined;
    }
  }
  // extracts the key part of an ID
  , getKey: (id) => {
    let parts = id.split(delimiter);
    if (parts.length === 3) {
      return parts[2];
    } else {
      return undefined;
    }
  }
  // creates an ID from the parameters.
  , toId: (library, topic, key) => {
    return library + delimiter + topic + delimiter + key;
  }
  , replaceLibrary: (id, newLibrary) => {
    let parts = id.split(delimiter);
    if (parts.length === 3) {
      return newLibrary + delimiter + parts[1] + delimiter + parts[2];
    } else {
      return undefined;
    }
  }
  , idToPaddedPath: function (id) {
    if (id) {
      return id.replace(/\|/g," / ");
    }
  }
  ,idToPath: function (id) {
    if (id.includes("~")) {
      return id.replace(/~/g,"/");
    } else {
      return id.replace(/\|/g,"/");
    }
  }
  , padPath: function (path) {
     return path.replace(/\//g, " / ");
  }
}
<commit_msg>Ability to parse chapter and verse parts<commit_after>/**
 * Created by mac002 on 1/2/17.
 */

const delimiter = "~";

module.exports = {
  // splits the id into an object with its three parts: library, topic, key
  getParts: (id) => {
    let IdParts = {}
    let parts = id.split(delimiter);
    if (parts.length === 3) {
      IdParts = {
        library: parts[0]
        , topic: parts[1]
        , key: parts[2]
      };
      let chapVerse = parts[2].split(":");
      if (chapVerse.length === 2) {
        IdParts.book = parts[1];
        IdParts.chapter = chapVerse[0];
        IdParts.verse = chapVerse[1];
      }
    } else {
      IdParts = undefined;
    }
      return IdParts;
    }
  // extracts the library part of an ID
  , getLibrary: (id) => {
    let parts = id.split(delimiter);
    if (parts.length === 3) {
      return parts[0];
    } else {
      return undefined;
    }
  }
  // extracts the topic part of an ID
  , getTopic: (id) => {
    let parts = id.split(delimiter);
    if (parts.length === 3) {
      return parts[1];
    } else {
      return undefined;
    }
  }
  // extracts the key part of an ID
  , getKey: (id) => {
    let parts = id.split(delimiter);
    if (parts.length === 3) {
      return parts[2];
    } else {
      return undefined;
    }
  }
  // creates an ID from the parameters.
  , toId: (library, topic, key) => {
    return library + delimiter + topic + delimiter + key;
  }
  , replaceLibrary: (id, newLibrary) => {
    let parts = id.split(delimiter);
    if (parts.length === 3) {
      return newLibrary + delimiter + parts[1] + delimiter + parts[2];
    } else {
      return undefined;
    }
  }
  , idToPaddedPath: function (id) {
    if (id) {
      return id.replace(/\|/g," / ");
    }
  }
  ,idToPath: function (id) {
    if (id.includes("~")) {
      return id.replace(/~/g,"/");
    } else {
      return id.replace(/\|/g,"/");
    }
  }
  , padPath: function (path) {
     return path.replace(/\//g, " / ");
  }
}
<|endoftext|>


<commit_before>
import { Basic, IsNull, IsIn, Between, Exists, Raw } from '../criterion'
import Expression, { Literal } from '../expression'
import { isArray, isString, uniq } from 'lodash'
import { SQ } from './expression'

/**
 *
 * @param {String|Expression} expr
 * @param {Any} value
 * @return {Criterion}
 */
export function EQ(expr, value) {
  return createBasicCriterion(expr, '=', value)
}

/**
 *
 * @param {String|Expression} expr
 * @param {Any} value
 * @return {Criterion}
 */
export function NE(expr, value) {
  return createBasicCriterion(expr, '!=', value)
}

/**
 *
 * @param {String|Expression} expr
 * @param {Any} value
 * @return {Criterion}
 */
export function GT(expr, value) {
  return createBasicCriterion(expr, '>', value)
}

/**
 *
 * @param {String|Expression} expr
 * @param {Any} value
 * @return {Criterion}
 */
export function LT(expr, value) {
  return createBasicCriterion(expr, '<', value)
}

/**
 *
 * @param {String|Expression} expr
 * @param {Any} value
 * @return {Criterion}
 */
export function GTE(expr, value) {
  return createBasicCriterion(expr, '>=', value)
}

/**
 *
 * @param {String|Expression} expr
 * @param {Any} value
 * @return {Criterion}
 */
export function LTE(expr, value) {
  return createBasicCriterion(expr, '<=', value)
}

/**
 *
 * @param {String|Expression} expr
 * @returns {Criterion}
 */
export function ISNULL(expr) {
  return new IsNull(ensureExpression(expr))
}

/**
 *
 * @returns {Criterion}
 */
export function ISTRUE() {
  return new Raw(Literal.from('1 = 1'))
}

/**
 *
 * @returns {Criterion}
 */
export function ISFALSE() {
  return new Raw(Literal.from('1 = 0'))
}

/**
 *
 * @param {String|Expression} expr
 * @param {Any} values
 * @returns {Criterion}
 */
export function IN(expr, values) {
  return new IsIn(ensureExpression(expr), isArray(values) ? uniq(values) : SQ(values))
}

/**
 *
 * @param {String|Expression} expr
 * @param {Any} lower
 * @param {Any} higher
 * @returns {Criterion}
 */
export function BETWEEN(expr, lower, higher) {
  return new Between(ensureExpression(expr), [lower, higher])
}

/**
 *
 * @param {Any} query
 * @returns {Criterion}
 */
export function EXISTS(query) {
  return new Exists(SQ(query))
}

/**
 *
 * @param {String|Expression} expr
 * @param {String} pattern
 * @returns {Criterion}
 */
export function LIKE(expr, pattern) {
  return createBasicCriterion(expr, 'like', pattern)
}

/**
 *
 * @param {String|Expression} expr
 * @param {String} value
 * @returns {Criterion}
 */
export function STARTSWITH(expr, value) {
  return LIKE(expr, value.replace(/(_|%)/g, '\\$1') + '%')
}

/**
 *
 * @param {String|Expression} expr
 * @param {String} value
 * @returns {Criterion}
 */
export function ENDSWITH(expr, value) {
  return LIKE(expr, '%' + value.replace(/(_|%)/g, '\\$1'))
}

/**
 *
 * @param {String|Expression} expr
 * @param {String} operator
 * @param {Any} value
 * @returns {Basic}
 */
function createBasicCriterion(expr, operator, value) {
  return new Basic(ensureExpression(expr), operator, value)
}

/**
 *
 * @param {Any} value
 * @returns {Expression}
 * @throws {TypeError}
 */
function ensureExpression(value) {
  if ( isString(value) )
    value = new Literal(value)

  if ( value instanceof Expression )
    return value

  throw new TypeError("Invalid condition operand")
}
<commit_msg>Update helpers/condition.js<commit_after>
import { Basic, Between, Exists, Raw } from '../criterion'
import Expression, { Literal } from '../expression'
import { isArray, isString, uniq } from 'lodash'
import { SQ } from './expression'

/**
 *
 * @param {String|Expression} expr
 * @param {Any} value
 * @return {Criterion}
 */
export function EQ(expr, value) {
  return createBasicCriterion(expr, '=', value)
}

/**
 *
 * @param {String|Expression} expr
 * @param {Any} value
 * @return {Criterion}
 */
export function NE(expr, value) {
  return createBasicCriterion(expr, '!=', value)
}

/**
 *
 * @param {String|Expression} expr
 * @param {Any} value
 * @return {Criterion}
 */
export function GT(expr, value) {
  return createBasicCriterion(expr, '>', value)
}

/**
 *
 * @param {String|Expression} expr
 * @param {Any} value
 * @return {Criterion}
 */
export function LT(expr, value) {
  return createBasicCriterion(expr, '<', value)
}

/**
 *
 * @param {String|Expression} expr
 * @param {Any} value
 * @return {Criterion}
 */
export function GTE(expr, value) {
  return createBasicCriterion(expr, '>=', value)
}

/**
 *
 * @param {String|Expression} expr
 * @param {Any} value
 * @return {Criterion}
 */
export function LTE(expr, value) {
  return createBasicCriterion(expr, '<=', value)
}

/**
 *
 * @param {String|Expression} expr
 * @returns {Criterion}
 */
export function ISNULL(expr) {
  return createBasicCriterion(expr, 'is', null)
}

/**
 *
 * @returns {Criterion}
 * @deprecated
 */
export function ISTRUE() {
  return new Raw(Literal.from('1 = 1'))
}

/**
 *
 * @returns {Criterion}
 * @deprecated
 */
export function ISFALSE() {
  return new Raw(Literal.from('1 = 0'))
}

/**
 *
 * @param {String|Expression} expr
 * @param {Any} values
 * @returns {Criterion}
 */
export function IN(expr, values) {
  return createBasicCriterion(expr, 'in', isArray(values) ? uniq(values) : SQ(values))
}

/**
 *
 * @param {String|Expression} expr
 * @param {Any} lower
 * @param {Any} higher
 * @returns {Criterion}
 */
export function BETWEEN(expr, lower, higher) {
  return new Between(ensureExpression(expr), [lower, higher])
}

/**
 *
 * @param {Any} query
 * @returns {Criterion}
 */
export function EXISTS(query) {
  return new Exists(SQ(query))
}

/**
 *
 * @param {String|Expression} expr
 * @param {String} pattern
 * @returns {Criterion}
 */
export function LIKE(expr, pattern) {
  return createBasicCriterion(expr, 'like', pattern)
}

/**
 *
 * @param {String|Expression} expr
 * @param {String} value
 * @returns {Criterion}
 */
export function STARTSWITH(expr, value) {
  return LIKE(expr, value.replace(/(_|%)/g, '\\$1') + '%')
}

/**
 *
 * @param {String|Expression} expr
 * @param {String} value
 * @returns {Criterion}
 */
export function ENDSWITH(expr, value) {
  return LIKE(expr, '%' + value.replace(/(_|%)/g, '\\$1'))
}

/**
 *
 * @param {String|Expression} expr
 * @param {String} operator
 * @param {Any} value
 * @returns {Basic}
 */
function createBasicCriterion(expr, operator, value) {
  return new Basic(ensureExpression(expr), operator, value)
}

/**
 *
 * @param {Any} value
 * @returns {Expression}
 * @throws {TypeError}
 */
function ensureExpression(value) {
  if ( isString(value) )
    value = new Literal(value)

  if ( value instanceof Expression )
    return value

  throw new TypeError("Invalid condition operand")
}<|endoftext|>


<commit_before>var Reaper = require('reaper').Reaper;
var EventEmitter = require('events').EventEmitter;
var index = require('../index');
var JsonResponder = index.JsonResponder;
var onBodyHelper = index.onBodyHelper;
var onJsonHelper = index.onJsonHelper;
var fetchHelper = index.FetchHelper;
var AuthenticateHelper = index.AuthenticateHelper;
var BasicAuthenticateHelper = index.BasicAuthenticateHelper;
var ObjectHelper = index.ObjectHelper;
var StatusManager = index.StatusManager;
var _ = require('underscore');
var fs = require('fs');
var Server = require('oneone');
var hyperjsonBrowser = require('hyperjson-browser');
var urlgrey = require('urlgrey');
var connect = require('connect');
var urlgreyConnect = require('urlgrey-connect');

Percolator = function(options){
  this.connectApp = connect();
  options = options || {};
  this.options = options;
  this.options.port = this.options.port || 3000;
  this.options.ip = this.options.ip || '0.0.0.0';
  if (this.options.autoLink !== false){
    this.options.autoLink = true;
  }
  this.options.protocol = this.options.protocol || 'http';
  this.options.resourcePath = this.options.resourcePath || '/';
  this.options.parseBody = this.options.parseBody || false;
  this.port = this.options.port;
  this.ip = this.options.ip;
  this.protocol = this.options.protocol;
  this.resourcePath = this.options.resourcePath;
  this.server = new Server(this.ip, this.port, this.protocol, this.resourcePath);
  if (!!options.staticDir){
    this.staticDir = options.staticDir;
  }
  var protocol = this.protocol;
  var that = this;
  this.statusman = new StatusManager();
  this.statusman.on('error', function(errorObject){
    that.emit("errorResponse", errorObject);
  });
  this.mediaTypes = new Reaper();
  this.onRequestHandler = function(req, res, handler, cb){
    cb();  // do nothing with it by default
  };
  this.onResponseHandler = function(req, res, handler){
    // do nothing with it by default
  };
  this.server.onRequest(function(handler, context, cb){
    var req = context.req;
    var res = context.res;
    that.connectApp(req, res, function(){
      req.app = that.options;
      var router = that.server.router;
      req.router = router;  // TODO is there any use-case for this?  delete?
      urlgreyConnect(protocol)(req, res, function(){
        ObjectHelper(req, res);
        res.status = that.statusman.createResponder(req, res);
        var oldEnd = res.end;
        res.end = function(data, encoding){
          oldEnd.apply(res, [data, encoding]);
          that.onResponseHandler(req, res, handler);
        };

        that.onRequestHandler(req, res, handler, function(){
          var accept = req.headers.accept || '*/*';
          if (!that.mediaTypes.isAcceptable(accept)){
            that.statusman.createResponder(req, res).notAcceptable();
          } else {
            that.defaultRequestHandler(req, res, handler, cb);
          }
        });
      });
    });
  });
  this._assignErrorHandlers();
  this.registerMediaTypes();

  this.server.onOPTIONS(function(resource){
    resource.OPTIONS = function($){
      var responder = that.statusman.createResponder($.req, $.res);
      return responder.OPTIONS(that._getMethods(resource));
    };
    return resource;
  });

};

Percolator.prototype = Object.create(EventEmitter.prototype);

Percolator.prototype.connectMiddleware = function(middleware){
  this.connectApp.use(middleware);
};

Percolator.prototype.defaultRequestHandler = function(req, res, handler, cb){
  var that = this;
  req.pause();
    AuthenticateHelper(req, res, handler, function(){
      BasicAuthenticateHelper(req, res, handler, function(){
        fetchHelper(req, res, handler, function(){
          if (!!that.options.parseBody){
            req.resume();
            var ctxt = context(req, res);
            that.mediaTypes.connectMiddleware(ctxt)(req, res, function(err){
              req.body = ctxt.body;
              req.rawBody = ctxt.rawBody;
              if (!!err) {
                if (err.match(/^Parse Error:/)){
                  that.statusman.createResponder(req, res).badRequest(err);
                  return;
                }
                if (err === "Missing Content-Type"){
                  that.statusman.createResponder(req, res).unsupportedMediaType("None provided.");
                  return;
                }
                if (err === "Unregistered content-type."){
                  that.statusman.createResponder(req, res).unsupportedMediaType(req.headers['content-type']);
                  return;
                }
                console.log("post mediaTypes middleware error:");
                console.log(err);
                return cb(err);
              } else {
                cb(null, context(req, res));
              }
            });
          } else {
            req.onBody = onBodyHelper(req, res, handler, function(){
              req.onJson = onJsonHelper(req, res, handler, function(){
                req.resume();
                cb(null, context(req, res));
              });
            });
          }
        });
      });
    });
};

Percolator.prototype.route = function(path, handler){
  return this.server.route(path, handler);
};

Percolator.prototype.before = function(handler){
  this.onRequestHandler = handler;
};

Percolator.prototype.after = function(handler){
  this.onResponseHandler = handler;
};

Percolator.prototype._getMethods = function(resource){
  var serverSupportedMethods = ["GET", "POST",
                                "PUT", "DELETE",
                                "HEAD", "OPTIONS"];
  var moduleMethods = _.functions(resource);
  var methods = _.intersection(moduleMethods, serverSupportedMethods);
  var additionalMethods = ['OPTIONS'];
  if (_.isFunction(resource.GET)){
    additionalMethods.push('HEAD');
  }
  methods = _.union(additionalMethods, methods);
  return methods;
};

// route a directory call the callback afterward
Percolator.prototype.routeDirectory = function(directory, path, cb){
  this.server.routeDirectory(directory, path, cb);
};

// register error handlers for each content type
Percolator.prototype._assignErrorHandlers = function(){
  // tell the server about the error handlers it can use
  var statusman = this.statusman;
  var that = this;

  this.server.on414(function($){
    statusman.createResponder($.req, $.res).requestUriTooLong();
  });

  this.server.on404(function($){
    // TODO fix resource.fetch to use this handle404 instead of default!!!

    var path = that.options.resourcePath;
    var browserPath = urlgrey(path).child('browser').path().toString();
    var responder = statusman.createResponder($.req, $.res);
    if (that.options.browser !== false){
      hyperjsonBrowser(browserPath, path)($.req, $.res, function(){
        responder.notFound($.req.url);
      });
    } else {
      responder.notFound($.req.url);
    }
  });

  this.server.on405(function($){
    statusman.createResponder($.req, $.res).methodNotAllowed();
  });

  this.server.on501(function($){
    statusman.createResponder($.req, $.res).notImplemented();
  });

  this.server.on500(function(context, err){
    var req = context.req;
    var res = context.res;
    console.log("===============================");
    console.log("Uncaught Exception");
    console.log(err);
    console.log(req.method, ' ', req.url);
    console.log(err.stack);
    try {
      statusman.createResponder(req, res).internalServerError();
    } catch(ex){
      console.log("error sending 500: ", ex);
    }
  });

};

Percolator.prototype.registerMediaType = function(type, instr, outobj){
  this.mediaTypes.register(type, instr, outobj);
};

Percolator.prototype.registerStatusResponder = function(type, responder){
  this.statusman.register(type, responder);
};

Percolator.prototype.registerMediaTypes = function(){
  var jsonType = require('./mediaTypes/json');
  this.registerMediaType('application/json', jsonType.fromString, jsonType.toString);
  this.registerStatusResponder('application/json',  JsonResponder);
};

Percolator.prototype.listen = function(cb){
  var that = this;
  if (!!this.staticDir){
    this.server.staticRoute(this.staticDir, function(err){
      if (!!err){
        cb("Your staticDir path could not be found.");
      }
      that.server.listen(cb);
    });
  } else {
      that.server.listen(cb);
  }
};

Percolator.prototype.close = function(cb){
  this.server.close(cb);
};

// what about body parsing based on content-type?
// example "accept only" (throws errors for unsupported types )
//   onBody(['application/json', application/xml'], function(err, type, body){ ... });
// example "accept all types"
//   onBody(function(err, type, body){ ... });
// TODO: max-size parameter?
// TODO: whether parseBody is true or not, we should use the same handler either way.

module.exports = Percolator;

function context(req, res){
  return {req : req, res : res};
}
<commit_msg>remove more context-dependent code<commit_after>var Reaper = require('reaper').Reaper;
var EventEmitter = require('events').EventEmitter;
var index = require('../index');
var JsonResponder = index.JsonResponder;
var onBodyHelper = index.onBodyHelper;
var onJsonHelper = index.onJsonHelper;
var fetchHelper = index.FetchHelper;
var AuthenticateHelper = index.AuthenticateHelper;
var BasicAuthenticateHelper = index.BasicAuthenticateHelper;
var ObjectHelper = index.ObjectHelper;
var StatusManager = index.StatusManager;
var _ = require('underscore');
var fs = require('fs');
var Server = require('oneone');
var hyperjsonBrowser = require('hyperjson-browser');
var urlgrey = require('urlgrey');
var connect = require('connect');
var urlgreyConnect = require('urlgrey-connect');

Percolator = function(options){
  this.connectApp = connect();
  options = options || {};
  this.options = options;
  this.options.port = this.options.port || 3000;
  this.options.ip = this.options.ip || '0.0.0.0';
  if (this.options.autoLink !== false){
    this.options.autoLink = true;
  }
  this.options.protocol = this.options.protocol || 'http';
  this.options.resourcePath = this.options.resourcePath || '/';
  this.options.parseBody = this.options.parseBody || false;
  this.port = this.options.port;
  this.ip = this.options.ip;
  this.protocol = this.options.protocol;
  this.resourcePath = this.options.resourcePath;
  this.server = new Server(this.ip, this.port, this.protocol, this.resourcePath);
  if (!!options.staticDir){
    this.staticDir = options.staticDir;
  }
  var protocol = this.protocol;
  var that = this;
  this.statusman = new StatusManager();
  this.statusman.on('error', function(errorObject){
    that.emit("errorResponse", errorObject);
  });
  this.mediaTypes = new Reaper();
  this.onRequestHandler = function(req, res, handler, cb){
    cb();  // do nothing with it by default
  };
  this.onResponseHandler = function(req, res, handler){
    // do nothing with it by default
  };
  this.server.onRequest(function(handler, context, cb){
    var req = context.req;
    var res = context.res;
    that.connectApp(req, res, function(){
      req.app = that.options;
      var router = that.server.router;
      req.router = router;  // TODO is there any use-case for this?  delete?
      urlgreyConnect(protocol)(req, res, function(){
        ObjectHelper(req, res);
        res.status = that.statusman.createResponder(req, res);
        var oldEnd = res.end;
        res.end = function(data, encoding){
          oldEnd.apply(res, [data, encoding]);
          that.onResponseHandler(req, res, handler);
        };

        that.onRequestHandler(req, res, handler, function(){
          var accept = req.headers.accept || '*/*';
          if (!that.mediaTypes.isAcceptable(accept)){
            that.statusman.createResponder(req, res).notAcceptable();
          } else {
            that.defaultRequestHandler(req, res, handler, cb);
          }
        });
      });
    });
  });
  this._assignErrorHandlers();
  this.registerMediaTypes();

  this.server.onOPTIONS(function(resource){
    resource.OPTIONS = function($){
      var responder = that.statusman.createResponder($.req, $.res);
      return responder.OPTIONS(that._getMethods(resource));
    };
    return resource;
  });

};

Percolator.prototype = Object.create(EventEmitter.prototype);

Percolator.prototype.connectMiddleware = function(middleware){
  this.connectApp.use(middleware);
};

Percolator.prototype.defaultRequestHandler = function(req, res, handler, cb){
  var that = this;
  req.pause();
    AuthenticateHelper(req, res, handler, function(){
      BasicAuthenticateHelper(req, res, handler, function(){
        fetchHelper(req, res, handler, function(){
          if (!!that.options.parseBody){
            req.resume();
            that.mediaTypes.connectMiddleware()(req, res, function(err){
              if (!!err) {
                if (err.match(/^Parse Error:/)){
                  that.statusman.createResponder(req, res).badRequest(err);
                  return;
                }
                if (err === "Missing Content-Type"){
                  that.statusman.createResponder(req, res).unsupportedMediaType("None provided.");
                  return;
                }
                if (err === "Unregistered content-type."){
                  that.statusman.createResponder(req, res).unsupportedMediaType(req.headers['content-type']);
                  return;
                }
                console.log("post mediaTypes middleware error:");
                console.log(err);
                return cb(err);
              } else {
                cb(null, context(req, res));
              }
            });
          } else {
            req.onBody = onBodyHelper(req, res, handler, function(){
              req.onJson = onJsonHelper(req, res, handler, function(){
                req.resume();
                cb(null, context(req, res));
              });
            });
          }
        });
      });
    });
};

Percolator.prototype.route = function(path, handler){
  return this.server.route(path, handler);
};

Percolator.prototype.before = function(handler){
  this.onRequestHandler = handler;
};

Percolator.prototype.after = function(handler){
  this.onResponseHandler = handler;
};

Percolator.prototype._getMethods = function(resource){
  var serverSupportedMethods = ["GET", "POST",
                                "PUT", "DELETE",
                                "HEAD", "OPTIONS"];
  var moduleMethods = _.functions(resource);
  var methods = _.intersection(moduleMethods, serverSupportedMethods);
  var additionalMethods = ['OPTIONS'];
  if (_.isFunction(resource.GET)){
    additionalMethods.push('HEAD');
  }
  methods = _.union(additionalMethods, methods);
  return methods;
};

// route a directory call the callback afterward
Percolator.prototype.routeDirectory = function(directory, path, cb){
  this.server.routeDirectory(directory, path, cb);
};

// register error handlers for each content type
Percolator.prototype._assignErrorHandlers = function(){
  // tell the server about the error handlers it can use
  var statusman = this.statusman;
  var that = this;

  this.server.on414(function($){
    statusman.createResponder($.req, $.res).requestUriTooLong();
  });

  this.server.on404(function($){
    // TODO fix resource.fetch to use this handle404 instead of default!!!

    var path = that.options.resourcePath;
    var browserPath = urlgrey(path).child('browser').path().toString();
    var responder = statusman.createResponder($.req, $.res);
    if (that.options.browser !== false){
      hyperjsonBrowser(browserPath, path)($.req, $.res, function(){
        responder.notFound($.req.url);
      });
    } else {
      responder.notFound($.req.url);
    }
  });

  this.server.on405(function($){
    statusman.createResponder($.req, $.res).methodNotAllowed();
  });

  this.server.on501(function($){
    statusman.createResponder($.req, $.res).notImplemented();
  });

  this.server.on500(function(context, err){
    var req = context.req;
    var res = context.res;
    console.log("===============================");
    console.log("Uncaught Exception");
    console.log(err);
    console.log(req.method, ' ', req.url);
    console.log(err.stack);
    try {
      statusman.createResponder(req, res).internalServerError();
    } catch(ex){
      console.log("error sending 500: ", ex);
    }
  });

};

Percolator.prototype.registerMediaType = function(type, instr, outobj){
  this.mediaTypes.register(type, instr, outobj);
};

Percolator.prototype.registerStatusResponder = function(type, responder){
  this.statusman.register(type, responder);
};

Percolator.prototype.registerMediaTypes = function(){
  var jsonType = require('./mediaTypes/json');
  this.registerMediaType('application/json', jsonType.fromString, jsonType.toString);
  this.registerStatusResponder('application/json',  JsonResponder);
};

Percolator.prototype.listen = function(cb){
  var that = this;
  if (!!this.staticDir){
    this.server.staticRoute(this.staticDir, function(err){
      if (!!err){
        cb("Your staticDir path could not be found.");
      }
      that.server.listen(cb);
    });
  } else {
      that.server.listen(cb);
  }
};

Percolator.prototype.close = function(cb){
  this.server.close(cb);
};

// what about body parsing based on content-type?
// example "accept only" (throws errors for unsupported types )
//   onBody(['application/json', application/xml'], function(err, type, body){ ... });
// example "accept all types"
//   onBody(function(err, type, body){ ... });
// TODO: max-size parameter?
// TODO: whether parseBody is true or not, we should use the same handler either way.

module.exports = Percolator;

function context(req, res){
  return {req : req, res : res};
}
<|endoftext|>


<commit_before>import fs from 'fs';
import dateFormat from 'dateformat';

export default class CSVLogger {
    constructor(filename) {
        this.filename = filename;
    }

    log = s => {
        let msg;
        if (s.type === "Daylight") {
            msg = (`${s.lastupdated},${s.id},${s.name},daylight,${s.daylight},,,${s.daylight}\n`);
        } else if (s.type === "ZGPSwitch") {
            msg = (`${s.lastupdated},${s.id},${s.name},button,${s.buttonevent}\n`);
        } else if (s.type === "ZLLSwitch") {
            msg = (`${s.lastupdated},${s.id},${s.name},button,${s.buttonevent},${s.battery}\n`);
        } else if (s.type === "ZLLTemperature") {
            msg = (`${s.lastupdated},${s.id},${s.name},temperature,${s.temperature / 100}\n`);
        } else if (s.type === "ZLLPresence") {
            msg = (`${s.lastupdated},${s.id},${s.name},presence,${s.presence},${s.battery}\n`);
        } else if (s.type === "ZLLLightLevel") {
            msg = (`${s.lastupdated},${s.id},${s.name},lightlevel,${s.lightlevel},,${s.dark},${s.daylight}\n`);
        }
        if (msg) {
            const filename = this.filename.replace("%date%", dateFormat(new Date(), "yyyy-mm-dd"));
            fs.appendFile(filename, msg, function (err) {
                if (err) {
                    console.log(`{err}: Could not log ${msg}`)
                }
            });
        }
    };
}<commit_msg>Fix log error message<commit_after>import fs from 'fs';
import dateFormat from 'dateformat';

export default class CSVLogger {
    constructor(filename) {
        this.filename = filename;
    }

    log = s => {
        let msg;
        if (s.type === "Daylight") {
            msg = (`${s.lastupdated},${s.id},${s.name},daylight,${s.daylight},,,${s.daylight}\n`);
        } else if (s.type === "ZGPSwitch") {
            msg = (`${s.lastupdated},${s.id},${s.name},button,${s.buttonevent}\n`);
        } else if (s.type === "ZLLSwitch") {
            msg = (`${s.lastupdated},${s.id},${s.name},button,${s.buttonevent},${s.battery}\n`);
        } else if (s.type === "ZLLTemperature") {
            msg = (`${s.lastupdated},${s.id},${s.name},temperature,${s.temperature / 100}\n`);
        } else if (s.type === "ZLLPresence") {
            msg = (`${s.lastupdated},${s.id},${s.name},presence,${s.presence},${s.battery}\n`);
        } else if (s.type === "ZLLLightLevel") {
            msg = (`${s.lastupdated},${s.id},${s.name},lightlevel,${s.lightlevel},,${s.dark},${s.daylight}\n`);
        }
        if (msg) {
            const filename = this.filename.replace("%date%", dateFormat(new Date(), "yyyy-mm-dd"));
            fs.appendFile(filename, msg, function (err) {
                if (err) {
                    console.err(`${err.message}: Could not log ${msg} to ${filename}`)
                    console.err(err)
                }
            });
        }
    };
}<|endoftext|>


<commit_before>// TapWatcher.js

//Black: gnd
//Red: Vdd
//White: SDA
//GReen / brown: SCL

const EventEmitter = require('events')
const util = require('util')
try {
  var mpu9250 = require('mpu9250');
  var mpu = new mpu9250();
} catch (er) {
  mpu = null;
}

try {
  var button = require("pi-pins").connect(config.GPIO_pin);
  button.mode('in');
  var led = require('pi-pins').connect(18);
  led.mode('high');
} catch (er) {
  button=null;
}
if (button) {
  console.log("button object OK")
}
if (mpu.initialize()) {
  console.log("mpu object OK")
  //mpu.printAccelSettings();
}
var ledmode='high';
setInterval(fucntion() {
  if (global.RecObj.RecStatus) {
    led.mode(ledmode);
    if (ledmode=='high') {
      ledmode='low';
    } else {
      ledmode='high';
    }
  }
}, 200);

// get a random string and emit the appropriate event every 3 seconds
function TapWatcher(watchwhat, threshold) {
  EventEmitter.call(this)
  const that = this
    if (mpu) {
      //do the accelerometer thing
      console.log("monitoring the accelerometer");
      var lastVal=0
      setInterval(function () {
        //test for high g reading
        var a = getAccel();
          if ((a-lastVal)> threshold) {
            that.emit('tap',a);
          }
          lastVal=a;
      }, 20)
    } else {
      console.log("Unable to access accelerometer");
    }
    if (button) {
      console.log("monitoring the switch");
      button.on('rise', function () {
        console.log("button handler");
        that.emit('tap')
      });
    } else {
      console.log("Unable to access switch");
    }
}

// conventionally, NodeJs uses util.inherits() for inheritance
util.inherits(TapWatcher, EventEmitter)

// simple function to randomly select a string from an array
function getAccel () {
  var r=mpu.getAccel();
  //console.log("Accel r:"+r[0]+"|"+ r[1] +"|"+ r[2]);
  return r[2];
}

module.exports = TapWatcher<commit_msg>spelling mistake<commit_after>// TapWatcher.js

//Black: gnd
//Red: Vdd
//White: SDA
//GReen / brown: SCL

const EventEmitter = require('events')
const util = require('util')
try {
  var mpu9250 = require('mpu9250');
  var mpu = new mpu9250();
} catch (er) {
  mpu = null;
}

try {
  var button = require("pi-pins").connect(config.GPIO_pin);
  button.mode('in');
  var led = require('pi-pins').connect(18);
  led.mode('high');
} catch (er) {
  button=null;
}
if (button) {
  console.log("button object OK")
}
if (mpu.initialize()) {
  console.log("mpu object OK")
  //mpu.printAccelSettings();
}
var ledmode='high';
setInterval(function() {
  if (global.RecObj.RecStatus) {
    led.mode(ledmode);
    if (ledmode=='high') {
      ledmode='low';
    } else {
      ledmode='high';
    }
  }
}, 200);

// get a random string and emit the appropriate event every 3 seconds
function TapWatcher(watchwhat, threshold) {
  EventEmitter.call(this)
  const that = this
    if (mpu) {
      //do the accelerometer thing
      console.log("monitoring the accelerometer");
      var lastVal=0
      setInterval(function () {
        //test for high g reading
        var a = getAccel();
          if ((a-lastVal)> threshold) {
            that.emit('tap',a);
          }
          lastVal=a;
      }, 20)
    } else {
      console.log("Unable to access accelerometer");
    }
    if (button) {
      console.log("monitoring the switch");
      button.on('rise', function () {
        console.log("button handler");
        that.emit('tap')
      });
    } else {
      console.log("Unable to access switch");
    }
}

// conventionally, NodeJs uses util.inherits() for inheritance
util.inherits(TapWatcher, EventEmitter)

// simple function to randomly select a string from an array
function getAccel () {
  var r=mpu.getAccel();
  //console.log("Accel r:"+r[0]+"|"+ r[1] +"|"+ r[2]);
  return r[2];
}

module.exports = TapWatcher<|endoftext|>