<commit_before>defineClass('Tada.Git.Dialog.AbstractDialog', 'Consoloid.Ui.Dialog',
  {
    __constructor: function(options)
    {
      this.__base($.extend({
        requestedRepositories: [],
        responseTemplateId: 'Tada-Git-Dialog-AbstractDialog',
        shouldUpdateContext: true
      }, options));

      if (!this.repositoryTemplate && this.repositoryTemplateId) {
        this.__createRepositoryTemplate();
      } else  if (!this.repositoryTemplate){
        throw new Error('repositoryTemplateId or repositoryTemplate required property')
      }
    },

    __createRepositoryTemplate: function()
    {
      this.repositoryTemplate = this.create('Consoloid.Widget.JQoteTemplate', {
        id: this.repositoryTemplateId,
        container: this.container
      });
    },

    setup: function()
    {
      if (this.arguments.repo) {
        this.requestedRepositories = [ this.arguments.repo.value ];
        this.__mentionRepo(this.arguments.repo.value);
      } else {
        this.requestedRepositories = Object.keys(this.container.get('tada').getConfig('repositories'));
      }
    },

    __mentionRepo: function(repoName)
    {
      this.get("git.project").getRepository(repoName).mention();
    },

    render: function()
    {
      this.__base();
      this.__processRequestedRepositories();
    },

    __processRequestedRepositories: function()
    {
      this.requestedRepositories.forEach(function(name) {
        this._processRepository(name);
      }.bind(this));
    },

    _processRepository: function(name)
    {
      this._renderRepository(name, {});
    },

    _renderRepository: function(name, data)
    {
      var baseHeight = this.node.height();
      data.name = name;
      this.response.find('div[data-repo-name="'+name+'"]')
        .empty()
        .jqoteapp(this.repositoryTemplate.get(), data);
      this.get('console').animateMarginTopIfNecessary(0);

      this.__adjustConsoleScrollTop(baseHeight);
    },

    __adjustConsoleScrollTop: function(baseHeight)
    {
      if (this.get("console").getLastDialog() == this) {
        var topOfDialog = $('body').height() - this.node.height();
        var scrollTo = topOfDialog - (window.innerHeight - this.get('console').getVisibleDialogsHeight());

        $('body,html').stop().animate({ scrollTop: scrollTo }, 400);
      } else if (this.node.position().top + this.node.height() < $('body,html').scrollTop() + $(window).height()) {
        var heightDifference = this.node.height() - baseHeight;
        $('body,html').scrollTop($('body,html').scrollTop() + heightDifference);
      }
    },
  },
  {
    MESSAGE_INFO: 1,
    MESSAGE_ERROR: 2
  }
);
<commit_msg>Git.Tada.Dialog.AbstractDialog will now call the _animateDialogResize of ...Ui.Dialog, which does the same thing<commit_after>defineClass('Tada.Git.Dialog.AbstractDialog', 'Consoloid.Ui.Dialog',
  {
    __constructor: function(options)
    {
      this.__base($.extend({
        requestedRepositories: [],
        responseTemplateId: 'Tada-Git-Dialog-AbstractDialog',
        shouldUpdateContext: true
      }, options));

      if (!this.repositoryTemplate && this.repositoryTemplateId) {
        this.__createRepositoryTemplate();
      } else  if (!this.repositoryTemplate){
        throw new Error('repositoryTemplateId or repositoryTemplate required property')
      }
    },

    __createRepositoryTemplate: function()
    {
      this.repositoryTemplate = this.create('Consoloid.Widget.JQoteTemplate', {
        id: this.repositoryTemplateId,
        container: this.container
      });
    },

    setup: function()
    {
      if (this.arguments.repo) {
        this.requestedRepositories = [ this.arguments.repo.value ];
        this.__mentionRepo(this.arguments.repo.value);
      } else {
        this.requestedRepositories = Object.keys(this.container.get('tada').getConfig('repositories'));
      }
    },

    __mentionRepo: function(repoName)
    {
      this.get("git.project").getRepository(repoName).mention();
    },

    render: function()
    {
      this.__base();
      this.__processRequestedRepositories();
    },

    __processRequestedRepositories: function()
    {
      this.requestedRepositories.forEach(function(name) {
        this._processRepository(name);
      }.bind(this));
    },

    _processRepository: function(name)
    {
      this._renderRepository(name, {});
    },

    _renderRepository: function(name, data)
    {
      var baseHeight = this.node.height();
      data.name = name;
      this.response.find('div[data-repo-name="'+name+'"]')
        .empty()
        .jqoteapp(this.repositoryTemplate.get(), data);
      this.get('console').animateMarginTopIfNecessary(0);

      this._animateDialogResize(baseHeight);
    },
  },
  {
    MESSAGE_INFO: 1,
    MESSAGE_ERROR: 2
  }
);
<|endoftext|>


<commit_before>// Queue design document
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

require('defaultable')(module,
  {
  }, function(module, exports, DEFS, require) {

var fs = require('fs')
  , lib = require('./lib')
  , path = require('path')
  , util = require('util')
  , assert = require('assert')
  ;

module.exports = { "DDoc" : DDoc

                 // For importing and unit testing.
                 , 'validate_doc_update': validate_doc_update
                 , 'visible_at'         : visible_at
                 }

//
// Constants
//

var TEMPLATE =
  // _id
  // _rev
{ 'queues': {}

, views: { "visible_at": { map: visible_at
                         , reduce: '_count'
                         }
         }

, "validate_doc_update": validate_doc_update
}

function validate_doc_update(newDoc, oldDoc, userCtx, secObj) {
  var ddoc = this
  var msg_id_re = /^CQS\/(.+?)\/([0-9a-f]{32})($|\/(.*)$)/

  if(! newDoc._id.match(/^CQS\//)) // A simple test, hopefully future-proof
    throw {'forbidden': 'This database is for CQS only'}

  var match = newDoc._id.match(msg_id_re)
  if(!match)
    throw {'forbidden':'Invalid message id'}

  var queue_id = match[1]
    , msg_id   = match[2]

  if(! (queue_id in ddoc.queues))
    throw {'forbidden':'Queue does not exist: '+queue_id}

  var IS_DB_ADMIN = false;

  secObj.admins = secObj.admins || {};
  secObj.admins.names = secObj.admins.names || [];
  secObj.admins.roles = secObj.admins.roles || [];

  if(userCtx.roles.indexOf('_admin') !== -1)
    IS_DB_ADMIN = true;
  if(secObj.admins.names.indexOf(userCtx.name) !== -1)
    IS_DB_ADMIN = true;
  for(i = 0; i < userCtx.roles; i++)
    if(secObj.admins.roles.indexOf(userCtx.roles[i]) !== -1)
      IS_DB_ADMIN = true;

  var good_keys = [ "_id", "_rev", "_revisions", "_deleted"
                  , 'SenderId'
                  , 'SentTimestamp'
                  , 'visible_at'
                  , 'ApproximateReceiveCount'
                  , 'ApproximateFirstReceiveTimestamp'
                  , 'MD5OfMessageBody'
                  , 'Body'

                  // Some extensions
                  , 'ReceiverId'
                  ];

  var key;
  for (key in newDoc)
    if(good_keys.indexOf(key) === -1)
      throw({forbidden: "Invalid field: " + key});

  if(! newDoc._deleted) {
    if(newDoc.Body === null || newDoc.Body === undefined)
      throw {forbidden: 'Invalid .Body: ' + JSON.stringify(newDoc.Body)};
  } else {
    if(oldDoc.ReceiverId !== userCtx.name) {
      if(IS_DB_ADMIN)
        log('Allowing db admin "'+userCtx.name+'" to delete: ' + newDoc._id);
      else
        throw {forbidden: 'You may not delete this document'};
    }

    return;
  }

  if(!newDoc.visible_at)
    throw {forbidden: 'Must set visible_at'};

  if(oldDoc) {
    // Checkout ("receive")
    if(newDoc.ReceiverId !== userCtx.name)
      throw({forbidden: 'Must set ReceiverId to your name: ' + JSON.stringify(userCtx.name)});

  } else {
    // Message send
    if(newDoc.SenderId !== userCtx.name)
      throw({forbidden: 'Must set SenderId to your name: ' + JSON.stringify(userCtx.name)});
  }
}

function visible_at(doc) {
  var msg_id_re = /^CQS\/(.+?)\/([0-9a-f]{32})($|\/(.*)$)/

  var match = doc._id.match(msg_id_re)
  if(!match || !doc.visible_at)
    return

  var queue_id = match[1]
    , msg_id   = match[2]

  // The client must be able to check out ("receive") the message using this view data,
  // which means MVCC stuff and anything else necessary.
  var val = {"_id":doc._id, "_rev":doc._rev};
  for(var a in doc)
    if(a.match(/^[A-Z]/))
      val[a] = doc[a]

  var key = [queue_id, doc.visible_at]
  emit(key, val)
}

//
// API
//

function DDoc () {
  var self = this;

  self.copy_template();

  self._id = "_design/cqs"
}

// One common logger for them all, just so it won't get stored in couch.
DDoc.prototype.log = lib.log4js.getLogger('ddoc');
DDoc.prototype.log.setLevel(lib.LOG_LEVEL);

DDoc.prototype.copy_template = function() {
  var self = this;

//  if(self.name.length < 1 || self.name.length > 80)
//    throw new Error("Queue name exceeds length max of 80: " + self.name.length)

  var ddoc = templated_ddoc()
  lib.copy(ddoc, self);
}

// Attach the web browser test suite.
DDoc.prototype.add_browser = function(callback) {
  var self = this;

  if(require.isBrowser) {
    // Browsers installing the browser suite is not supported.
    return callback();
  }

  var home = __dirname
    , include_dirs = [ home
                     , home + '/test'
                     , home + '/test/browser/node'
                     , home + '/test/browser'
                     ];

  self._attachments = self._attachments || {};
  var requirejs_paths = { 'request' : '../request.jquery'
                        //, 'foo' : 'bar'
                        };

  function finish() {
    var opts = { baseUrl: "cqs"
               , paths  : requirejs_paths
               }
    var boot_js = [ 'require('
                  ,   '// Options'
                  ,   lib.JS(opts) + ','
                  ,   ''
                  ,   '// Modules'
                  ,   '["main.js"],'
                  ,   ''
                  ,   '// Code to run when ready'
                  ,   'function(main) { return main(); }'
                  , ');'
                  ].join('\n');

    self._attachments['boot.js'] = { content_type: 'application/javascript'
                                   , data        : new Buffer(boot_js).toString('base64')
                                   }
    return callback();
  }

  // Load serially because error handling is simpler.
  get_dir();
  function get_dir() {
    var dir_path = include_dirs.shift();
    if(!dir_path)
      return finish();

    self.log.debug('Fetching files from: ' + dir_path);
    fs.readdir(dir_path, function(er, files) {
      if(er) return callback(er);
      self.log.debug('Files: ' + lib.JS(files));

      files = files.filter(function(file) { return /\.js$/.test(file) || /\.html$/.test(file) });

      get_file();
      function get_file() {
        var filename = files.shift();
        if(!filename)
          return get_dir(); // done with this dir

        self.log.debug('Loading file: ' + filename);
        fs.readFile(dir_path+'/'+filename, null, function(er, content) {
          if(er && er.errno) er = new Error(er.stack); // Make a better stack trace.
          if(er) return callback(er);

          var match , require_re = /\brequire\(['"]([\w\d\-_\/\.]+?)['"]\)/g
            , dependencies = {};
            ;

          if(dir_path === home + '/test' && filename === 'run.js') {
            // Strip the shebang.
            content = content.toString('utf8').split(/\n/).map(function(line) {
              // Replace the line instead of removing it, to keep the line numbers the same.
              return line.replace(/^(#!.*)$/, '// $1');
            }).join('\n');
            content = new Buffer(content);
          }

          if(dir_path === home || dir_path === home + '/test') {
            // Try converting the Node modules to RequireJS on the fly.
            content = content.toString('utf8');
            while(match = require_re.exec(content))
              dependencies[ match[1] ] = true;
            dependencies = Object.keys(dependencies);

            // In order to keep the error message line numbers correct, this makes an ugly final file.
            content = [ 'require.def(function(require, exports, module) {'
                      //, 'var module = {};'
                      //, 'var exports = {};'
                      //, 'module.exports = exports;'
                      , ''
                      , content
                      , '; return(module.exports);'
                      , '}); // define'
                      ].join('');
            content = new Buffer(content);
          }

          var att_dir = dir_path.replace(new RegExp('^' + home + '/?'), "");

          if(att_dir == "" || att_dir == 'test/browser/node')
            att_dir = "cqs/";

          else if(att_dir == 'test')
            att_dir = 'cqs/test/';

          else if(att_dir == 'test/browser')
            att_dir = "";

          else
            return callback(new Error('Unknown directory: ' + att_dir));

          var att = att_dir + filename;
          var type = /\.html$/.test(filename) ? 'text/html; charset=utf-8' : 'application/javascript';
          self._attachments[att] = { 'content_type':type, 'data':content.toString('base64') };

          get_file();
        })
      }
    })
  }
}

//
// Utilities
//

function templated_ddoc(name) {
  return stringify_functions(TEMPLATE)
  function stringify_functions(obj) {
    var copy = {};

    if(Array.isArray(obj))
      return obj.map(stringify_functions)

    else if(typeof obj === 'object' && obj !== null) {
      Object.keys(obj).forEach(function(key) {
        copy[key] = stringify_functions(obj[key]);
      })
      return copy;
    }

    else if(typeof obj === 'function')
      return func_from_template(obj)

    else
      return lib.JDUP(obj);
  }
}

function func_from_template(func) {
  var src = func.toString();
  src = src.replace(/^function.*?\(/, 'function (');
  return src;
}

}) // defaultable
<commit_msg>Protect against missing old docs when replicating<commit_after>// Queue design document
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

require('defaultable')(module,
  {
  }, function(module, exports, DEFS, require) {

var fs = require('fs')
  , lib = require('./lib')
  , path = require('path')
  , util = require('util')
  , assert = require('assert')
  ;

module.exports = { "DDoc" : DDoc

                 // For importing and unit testing.
                 , 'validate_doc_update': validate_doc_update
                 , 'visible_at'         : visible_at
                 }

//
// Constants
//

var TEMPLATE =
  // _id
  // _rev
{ 'queues': {}

, views: { "visible_at": { map: visible_at
                         , reduce: '_count'
                         }
         }

, "validate_doc_update": validate_doc_update
}

function validate_doc_update(newDoc, oldDoc, userCtx, secObj) {
  var ddoc = this
  var msg_id_re = /^CQS\/(.+?)\/([0-9a-f]{32})($|\/(.*)$)/

  if(! newDoc._id.match(/^CQS\//)) // A simple test, hopefully future-proof
    throw {'forbidden': 'This database is for CQS only'}

  var match = newDoc._id.match(msg_id_re)
  if(!match)
    throw {'forbidden':'Invalid message id'}

  var queue_id = match[1]
    , msg_id   = match[2]

  if(! (queue_id in ddoc.queues))
    throw {'forbidden':'Queue does not exist: '+queue_id}

  var IS_DB_ADMIN = false;

  secObj.admins = secObj.admins || {};
  secObj.admins.names = secObj.admins.names || [];
  secObj.admins.roles = secObj.admins.roles || [];

  if(userCtx.roles.indexOf('_admin') !== -1)
    IS_DB_ADMIN = true;
  if(secObj.admins.names.indexOf(userCtx.name) !== -1)
    IS_DB_ADMIN = true;
  for(i = 0; i < userCtx.roles; i++)
    if(secObj.admins.roles.indexOf(userCtx.roles[i]) !== -1)
      IS_DB_ADMIN = true;

  var good_keys = [ "_id", "_rev", "_revisions", "_deleted"
                  , 'SenderId'
                  , 'SentTimestamp'
                  , 'visible_at'
                  , 'ApproximateReceiveCount'
                  , 'ApproximateFirstReceiveTimestamp'
                  , 'MD5OfMessageBody'
                  , 'Body'

                  // Some extensions
                  , 'ReceiverId'
                  ];

  var key;
  for (key in newDoc)
    if(good_keys.indexOf(key) === -1)
      throw({forbidden: "Invalid field: " + key});

  if(! newDoc._deleted) {
    if(newDoc.Body === null || newDoc.Body === undefined)
      throw {forbidden: 'Invalid .Body: ' + JSON.stringify(newDoc.Body)};
  } else {
    if(!oldDoc || oldDoc.ReceiverId !== userCtx.name) {
      if(IS_DB_ADMIN)
        log('Allowing db admin "'+userCtx.name+'" to delete: ' + newDoc._id);
      else
        throw {forbidden: 'You may not delete this document'};
    }

    return;
  }

  if(!newDoc.visible_at)
    throw {forbidden: 'Must set visible_at'};

  if(oldDoc) {
    // Checkout ("receive")
    if(newDoc.ReceiverId !== userCtx.name)
      throw({forbidden: 'Must set ReceiverId to your name: ' + JSON.stringify(userCtx.name)});

  } else {
    // Message send
    if(newDoc.SenderId !== userCtx.name)
      throw({forbidden: 'Must set SenderId to your name: ' + JSON.stringify(userCtx.name)});
  }
}

function visible_at(doc) {
  var msg_id_re = /^CQS\/(.+?)\/([0-9a-f]{32})($|\/(.*)$)/

  var match = doc._id.match(msg_id_re)
  if(!match || !doc.visible_at)
    return

  var queue_id = match[1]
    , msg_id   = match[2]

  // The client must be able to check out ("receive") the message using this view data,
  // which means MVCC stuff and anything else necessary.
  var val = {"_id":doc._id, "_rev":doc._rev};
  for(var a in doc)
    if(a.match(/^[A-Z]/))
      val[a] = doc[a]

  var key = [queue_id, doc.visible_at]
  emit(key, val)
}

//
// API
//

function DDoc () {
  var self = this;

  self.copy_template();

  self._id = "_design/cqs"
}

// One common logger for them all, just so it won't get stored in couch.
DDoc.prototype.log = lib.log4js.getLogger('ddoc');
DDoc.prototype.log.setLevel(lib.LOG_LEVEL);

DDoc.prototype.copy_template = function() {
  var self = this;

//  if(self.name.length < 1 || self.name.length > 80)
//    throw new Error("Queue name exceeds length max of 80: " + self.name.length)

  var ddoc = templated_ddoc()
  lib.copy(ddoc, self);
}

// Attach the web browser test suite.
DDoc.prototype.add_browser = function(callback) {
  var self = this;

  if(require.isBrowser) {
    // Browsers installing the browser suite is not supported.
    return callback();
  }

  var home = __dirname
    , include_dirs = [ home
                     , home + '/test'
                     , home + '/test/browser/node'
                     , home + '/test/browser'
                     ];

  self._attachments = self._attachments || {};
  var requirejs_paths = { 'request' : '../request.jquery'
                        //, 'foo' : 'bar'
                        };

  function finish() {
    var opts = { baseUrl: "cqs"
               , paths  : requirejs_paths
               }
    var boot_js = [ 'require('
                  ,   '// Options'
                  ,   lib.JS(opts) + ','
                  ,   ''
                  ,   '// Modules'
                  ,   '["main.js"],'
                  ,   ''
                  ,   '// Code to run when ready'
                  ,   'function(main) { return main(); }'
                  , ');'
                  ].join('\n');

    self._attachments['boot.js'] = { content_type: 'application/javascript'
                                   , data        : new Buffer(boot_js).toString('base64')
                                   }
    return callback();
  }

  // Load serially because error handling is simpler.
  get_dir();
  function get_dir() {
    var dir_path = include_dirs.shift();
    if(!dir_path)
      return finish();

    self.log.debug('Fetching files from: ' + dir_path);
    fs.readdir(dir_path, function(er, files) {
      if(er) return callback(er);
      self.log.debug('Files: ' + lib.JS(files));

      files = files.filter(function(file) { return /\.js$/.test(file) || /\.html$/.test(file) });

      get_file();
      function get_file() {
        var filename = files.shift();
        if(!filename)
          return get_dir(); // done with this dir

        self.log.debug('Loading file: ' + filename);
        fs.readFile(dir_path+'/'+filename, null, function(er, content) {
          if(er && er.errno) er = new Error(er.stack); // Make a better stack trace.
          if(er) return callback(er);

          var match , require_re = /\brequire\(['"]([\w\d\-_\/\.]+?)['"]\)/g
            , dependencies = {};
            ;

          if(dir_path === home + '/test' && filename === 'run.js') {
            // Strip the shebang.
            content = content.toString('utf8').split(/\n/).map(function(line) {
              // Replace the line instead of removing it, to keep the line numbers the same.
              return line.replace(/^(#!.*)$/, '// $1');
            }).join('\n');
            content = new Buffer(content);
          }

          if(dir_path === home || dir_path === home + '/test') {
            // Try converting the Node modules to RequireJS on the fly.
            content = content.toString('utf8');
            while(match = require_re.exec(content))
              dependencies[ match[1] ] = true;
            dependencies = Object.keys(dependencies);

            // In order to keep the error message line numbers correct, this makes an ugly final file.
            content = [ 'require.def(function(require, exports, module) {'
                      //, 'var module = {};'
                      //, 'var exports = {};'
                      //, 'module.exports = exports;'
                      , ''
                      , content
                      , '; return(module.exports);'
                      , '}); // define'
                      ].join('');
            content = new Buffer(content);
          }

          var att_dir = dir_path.replace(new RegExp('^' + home + '/?'), "");

          if(att_dir == "" || att_dir == 'test/browser/node')
            att_dir = "cqs/";

          else if(att_dir == 'test')
            att_dir = 'cqs/test/';

          else if(att_dir == 'test/browser')
            att_dir = "";

          else
            return callback(new Error('Unknown directory: ' + att_dir));

          var att = att_dir + filename;
          var type = /\.html$/.test(filename) ? 'text/html; charset=utf-8' : 'application/javascript';
          self._attachments[att] = { 'content_type':type, 'data':content.toString('base64') };

          get_file();
        })
      }
    })
  }
}

//
// Utilities
//

function templated_ddoc(name) {
  return stringify_functions(TEMPLATE)
  function stringify_functions(obj) {
    var copy = {};

    if(Array.isArray(obj))
      return obj.map(stringify_functions)

    else if(typeof obj === 'object' && obj !== null) {
      Object.keys(obj).forEach(function(key) {
        copy[key] = stringify_functions(obj[key]);
      })
      return copy;
    }

    else if(typeof obj === 'function')
      return func_from_template(obj)

    else
      return lib.JDUP(obj);
  }
}

function func_from_template(func) {
  var src = func.toString();
  src = src.replace(/^function.*?\(/, 'function (');
  return src;
}

}) // defaultable
<|endoftext|>


<commit_before>import styled, { css } from "styled-components";
import { colors } from "@crave/farmblocks-theme";

const border = `1px solid ${colors.GREY_16}`;

const Table = styled.table`
  border-collapse: collapse;
  border: ${border};
  padding: 8px 16px;

  .cell {
    box-sizing: border-box;
    height: ${props => props.rowHeight};
    border-bottom: ${border};
    padding-left: 16px;

    &:last-child {
      padding-right: 16px;
    }

    /* @HACK checkbox component already have a left padding,
     so we use negative margin to keep only the table padding */
    & .checkbox {
      margin-left: -8px;
    }
  }

  .body .cell {
    ${props =>
      props.emptySelection && css`background-color: white !important;`};
  }
`;

export default Table;
<commit_msg>fix(checkbox): fix alignment on Firefox<commit_after>import styled, { css } from "styled-components";
import { colors } from "@crave/farmblocks-theme";

const border = `1px solid ${colors.GREY_16}`;

const Table = styled.table`
  border-collapse: collapse;
  border: ${border};
  padding: 8px 16px;

  .cell {
    box-sizing: border-box;
    height: ${props => props.rowHeight};
    border-bottom: ${border};
    padding-left: 16px;

    &:last-child {
      padding-right: 16px;
    }

    /* @HACK checkbox component already have a left padding,
     so we use negative margin to keep only the table padding */
    & .checkbox {
      height: 16px;
      margin-left: -8px;
    }
  }

  .body .cell {
    ${props =>
      props.emptySelection && css`background-color: white !important;`};
  }
`;

export default Table;
<|endoftext|>


<commit_before>/**
 * Object djs for namespace
 */
if (typeof djs != "undefined") {
	window.djs = {};
}
/**
 * This class manage an ordered callback stack
 * This class is chainable
 */
djs.CallStack = function() {
	//Vars
	this.reversed = false;
	this.order = null; //Array, includes ordered callback's names
	this.stack = {};
	this.debug = false;
	//Callbacks
	this.willExecute = function(namespace) {};
	this.didExecute = function(namespace) {};
}

//------------------------------------------------------------------------------
//	MEHTODS
//------------------------------------------------------------------------------
/**
 * Add a callback to the call stack
 *
 * @param {String} namespace
 * @param {Function} callback
 * @return {Object}
 */
djs.CallStack.prototype.add = function(namespace, callback) {
	//Add the callback
	this.stack[namespace] = callback;
	//End
	return this;
};
/**
 * Remove a callback from the call stack
 *
 * @param {String} namespace
 * @return {Object}
 */
djs.CallStack.prototype.delete = function(namespace) {
	//Remove the callback
	delete this.stack[namespace];
	//End
	return this;
};
/**
 * Reverse call stack execution
 *
 * @return {Object}
 */
djs.CallStack.prototype.reverse = function() {
	//Reverse
	this.reversed = true;
	//End
	return this;
};
/**
 * Restore call stack execution order
 *
 * @return {Object}
 */
djs.CallStack.prototype.restore = function() {
	//Restore
	this.reversed = false;
	//End
	return this;
};
/**
 * Execute the whole stack
 *
 * @return {Object}
 */
djs.CallStack.prototype.run = function() {
	//If no order is defined
	if (this.order == null) {
		//Execute each function stored in the stack
		$.each(this.stack, function(i,e){
			this._execute(i);
		}.bind(this));
	}
	//If an order is defined
	else {
		//If we should execute the stack from the end
		if (this.reversed) {
			for(var i=this.order.length - 1; i >= 0; i--) {
				this._execute(this.order[i]);
			}
		}
		//We execute the stack using the order
		else {
			for(var i=0; i < this.order.length; i++) {
				this._execute(this.order[i]);
			}
		}
	}
	//End
	return this;
};
/**
 * Internal function
 * Execute a function stored in the stack
 *
 * @private
 * @callback willExecute
 * @callback didExecute
 * @param {String} namespace
 * @return {Object}
 */
djs.CallStack.prototype._execute = function(namespace) {
	//Check if the function exsits
	if (typeof this.stack[namespace] == "function") {
		//Debug logging
		if (this.debug)
			console.log('[djs.CallStack] Will execute ' + namespace);
		//Pre callback
		this.willExecute(namespace);
		//Execute function
		this.stack[namespace]();
		//After callback
		this.didExecute(namespace);
		//Debug logging
		if (this.debug)
			console.log('[djs.CallStack] Did execute ' + namespace);
	}
	//End
	return this;
};<commit_msg>change "namespace" to "name"<commit_after>/**
 * Object djs for namespace
 */
if (typeof djs != "undefined") {
	window.djs = {};
}
/**
 * This class manage an ordered callback stack
 * This class is chainable
 */
djs.CallStack = function() {
	//Vars
	this.reversed = false;
	this.order = null; //Array, includes ordered callback's names
	this.stack = {};
	this.debug = false;
	//Callbacks
	this.willExecute = function(name) {};
	this.didExecute = function(name) {};
}

//------------------------------------------------------------------------------
//	MEHTODS
//------------------------------------------------------------------------------
/**
 * Add a callback to the call stack
 *
 * @param {String} name
 * @param {Function} callback
 * @return {Object}
 */
djs.CallStack.prototype.add = function(name, callback) {
	//Add the callback
	this.stack[name] = callback;
	//End
	return this;
};
/**
 * Remove a callback from the call stack
 *
 * @param {String} name
 * @return {Object}
 */
djs.CallStack.prototype.delete = function(name) {
	//Remove the callback
	delete this.stack[name];
	//End
	return this;
};
/**
 * Reverse call stack execution
 *
 * @return {Object}
 */
djs.CallStack.prototype.reverse = function() {
	//Reverse
	this.reversed = true;
	//End
	return this;
};
/**
 * Restore call stack execution order
 *
 * @return {Object}
 */
djs.CallStack.prototype.restore = function() {
	//Restore
	this.reversed = false;
	//End
	return this;
};
/**
 * Execute the whole stack
 *
 * @return {Object}
 */
djs.CallStack.prototype.run = function() {
	//If no order is defined
	if (this.order == null) {
		//Execute each function stored in the stack
		$.each(this.stack, function(i,e){
			this._execute(i);
		}.bind(this));
	}
	//If an order is defined
	else {
		//If we should execute the stack from the end
		if (this.reversed) {
			for(var i=this.order.length - 1; i >= 0; i--) {
				this._execute(this.order[i]);
			}
		}
		//We execute the stack using the order
		else {
			for(var i=0; i < this.order.length; i++) {
				this._execute(this.order[i]);
			}
		}
	}
	//End
	return this;
};
/**
 * Internal function
 * Execute a function stored in the stack
 *
 * @private
 * @callback willExecute
 * @callback didExecute
 * @param {String} name
 * @return {Object}
 */
djs.CallStack.prototype._execute = function(name) {
	//Check if the function exsits
	if (typeof this.stack[name] == "function") {
		//Debug logging
		if (this.debug)
			console.log('[djs.CallStack] Will execute ' + name);
		//Pre callback
		this.willExecute(name);
		//Execute function
		this.stack[name]();
		//After callback
		this.didExecute(name);
		//Debug logging
		if (this.debug)
			console.log('[djs.CallStack] Did execute ' + name);
	}
	//End
	return this;
};<|endoftext|>


<commit_before>'use strict';

// uses some functions from collectFormData.js
//import {collectFormData} from 'collectFormData.js';

browser.runtime.onMessage.addListener(receiveEvents);

function receiveEvents(fhcEvent, sender, sendResponse) {
    if (fhcEvent.action) {
        console.log("Received action event " + fhcEvent.action);

        switch (fhcEvent.action) {
            case "showformfields":
                showformfields();
                break;

            case "getformfields":
                let fields = [];
                getCurrentFields(document, fields);
                const thisHost = document.location.protocol === "file:" ? "localhost" :  document.location.host;
                sendResponse({fields: fields, host: thisHost});
                break;
        }
    }
}

function _getHost(aLocation) {
    if (aLocation.protocol === "file:") {
        return "localhost";
    } else {
        return aLocation.host;
    }
}

/**
 * Get the formfields for this page as an array of name + type objects.
 */
function getCurrentFields(aDocument, aFields) {

    aDocument.querySelectorAll("input,textarea").forEach( (node) => {
        if (_isTextInputSubtype(node.type) && _isDisplayed(node)) {
            let name = (node.name) ? node.name : ((node.id) ? node.id : "");
            if (name) {
                aFields.push({
                    name: name,
                    type: node.nodeName.toLowerCase()
                });
            }
        }
    });

    aDocument.querySelectorAll("html,div,iframe,body").forEach( (node) => {
        if ((_isContentEditable(node) && _isDisplayed(node)) || _isDesignModeOn(node)) {
            let name = (node.name) ? node.name : ((node.id) ? node.id : "");
            if (name) {
                aFields.push({
                    name: name,
                    type: node.nodeName.toLowerCase()
                });
            }
        }
    });

    // need to visit iframes inside this method in order to return a single Array of all elements
    aDocument.querySelectorAll('iframe').forEach( item => {
        try {
            getCurrentFields(item.contentWindow.document.body, aFields)
        } catch (e) {
            // probably: Permission denied to access property "document" on cross-origin object
        }
    });
}

function showformfields() {
    let ii = 0, id, div;
    document.querySelectorAll("input,textarea").forEach( (elem) => {
        //console.log("adding info for elem-id: " + elem.id);

        if (_isTextInputSubtype(elem.type) && _isDisplayed(elem)) {
            id = 'fhcFldInfo' + ++ii;

            // toggle info
            if (document.getElementById(id)) {
                // Remove info element
                document.body.removeChild(document.getElementById(id));
            } else {
                // Insert info element
                div = _createInfoElement(id, elem, true);
                // console.log("Adding div for " + elem.id + " of type " + elem.type + " div id " + id);
                document.body.appendChild(div);
            }
        }
    });

    document.querySelectorAll("html,div,iframe,body").forEach( (elem) => {
        if ((_isContentEditable(elem) && _isDisplayed(elem)) || _isDesignModeOn(elem)) {
            id = 'fhcFldInfo' + ++ii;
            //console.log("elem-id: " + elem.id + " of type ?");

            // toggle info
            if (document.getElementById(id)) {
                // Remove info element
                document.body.removeChild(document.getElementById(id));
            } else {
                // Insert info element
                div = _createInfoElement(id, elem, false);
                // console.log("Adding div for " + elem.id + " of type " + elem.type + " div id " + id);
                document.body.appendChild(div);
            }
        }
    });
}

/**
 * Create a div element for displaying the fieldname next to a formfield.
 *
 * @param id {String}
 *        the unique id for the div element
 *
 * @param sourceElem {Element}
 *        the inputfield determining the position for the new div element
 *
 * @param includeForm boolean
 *        whether or not to include info about te containing form
 *
 * @return {Element}
 *         the newly created div, absolute positioned next to the sourceElem
 */
function _createInfoElement(id, sourceElem, includeForm) {
    let fldName = _getElementNameOrId(sourceElem);
    if (fldName === '') {
        fldName = '\u00a0'; //
    }

    let style = 'display:block; border:1px solid #000; padding: 0 4px; ' +
        'background-color:#FFFFAA; color:#000; opacity: 0.75; ' +
        'font: bold 11px sans-serif; text-decoration:none; text-align:left; ' +
        'z-index: 2147483647; cursor:default; box-shadow: 3px 3px 2px black; ';

    let compstyle = document.defaultView.getComputedStyle(sourceElem, null);
    let width = 0;
    if ('BODY' !== sourceElem.nodeName && 'HTML' !== sourceElem.nodeName) {
        // do need place info about body or html next to (and outside) the element
        width = parseInt(compstyle.getPropertyValue("width").replace('px', ''));
    }
    let padding = parseInt(compstyle.getPropertyValue("padding-right").replace('px', ''));
    let border = parseInt(compstyle.getPropertyValue("border-right-width").replace('px', ''));

    let left = 0, top = 0, elem = sourceElem;
    if (elem.offsetParent) {
        do {
            left += elem.offsetLeft;
            top += elem.offsetTop;
        } while ((elem = elem.offsetParent));
    }
    style += 'position:absolute; top:' + top + 'px; ';
    style += 'left:' + (left + width + padding + border + 4) + 'px; ';

    let div = document.createElement('div');
    div.setAttribute('id', id);
    div.setAttribute('title', _getFormInfoText(sourceElem, includeForm));
    div.setAttribute('style', style);
    div.setAttribute('contenteditable', 'false');
    div.addEventListener("mouseenter", function(){this.style.opacity=1;this.style.zIndex=1002;}, false);
    div.addEventListener("mouseleave", function(){this.style.opacity=0.75;this.style.zIndex=1001;}, false);
    div.appendChild(document.createTextNode(fldName));

    let innerDiv = document.createElement('div');
    div.appendChild(innerDiv);
    div.addEventListener("click", function(){
        let e=document.getElementById(this.id + 'inner');
        if(e.style.display==='none') {
            e.style.display='block';
            this.style.zIndex=1001;
        } else {
            e.style.display='none';
            this.style.zIndex=1000;
        }
    }, false);
    innerDiv.setAttribute('id', id + 'inner');
    innerDiv.setAttribute('title', ' ');
    innerDiv.setAttribute('style',
        'display:none; background-color:#FFDCCF; margin:5px; padding:5px; ' +
        'font-weight: normal; border:1px inset #FFDCCF; ' +
        'box-shadow: inset 0 0 8px rgba(55, 20, 7, 0.5)');
    innerDiv.appendChild(_getFormInfoHTML(sourceElem, includeForm));

    return div;
}

/**
 * Collect the attributes for the element and its form container and return as String.
 *
 * @param element {Element}
 *        the inputfield
 *
 * @param includeForm boolean
 *        whether or not to include info about te containing form
 *
 * @return {Element}
 *         info about element and form
 */
function _getFormInfoHTML(element, includeForm) {
    let info = document.createElement('div');

    let inputBold = document.createElement('b');
    inputBold.textContent = '<' + element.nodeName + '>';
    info.appendChild(inputBold);

    info.appendChild(document.createElement('br'));

    for (let j = 0; j < element.attributes.length; j++) {
        info.appendChild(document.createTextNode(element.attributes[j].name + '=' + element.attributes[j].value));
        info.appendChild(document.createElement('br'));
    }

    if (includeForm) {
        let form = element;
        while (form.parentNode && form.localName !== 'form') {
            form = form.parentNode;
        }
        if (form && form.localName === 'form') {
            info.appendChild(document.createElement('br'));
            let formBold = document.createElement('b');
            formBold.textContent = '<FORM>';
            info.appendChild(formBold);
            info.appendChild(document.createElement('br'));
            for (let i = 0; i < form.attributes.length; i++) {
                info.appendChild(document.createTextNode(form.attributes[i].name + '=' + form.attributes[i].value));
                info.appendChild(document.createElement('br'));
            }
        }
    }
    return info;
}

/**
 * Collect the attributes for the element and its form container and return as String.
 *
 * @param element {Element}
 *        the inputfield
 *
 * @param includeForm boolean
 *        whether or not to include info about te containing form
 *
 * @return {String}
 *         info about element and form
 */
function _getFormInfoText(element, includeForm) {
    let sep = ' ';

    let result = element.nodeName + ': ';
    for (let j = 0; j < element.attributes.length; j++) {
        result += element.attributes[j].name + '=' + element.attributes[j].value + sep;
    }

    if (includeForm) {
        let form = element;
        while (form.parentNode && form.localName !== 'form') {
            form = form.parentNode;
        }
        if (form && form.localName === 'form') {
            result += ' # FORM: ';
            for (let i = 0; i < form.attributes.length; i++) {
                result += form.attributes[i].name + '=' + form.attributes[i].value + sep;
            }
        }
    }
    return result;
}

/**
 * Determine the name of an element (either name if it has one, otherwise its id).
 *
 * @param  element {Element}
 *         the DOM element
 *
 * @return {String}
 *         the name of the element, if no name then return its id
 */
function _getElementNameOrId(element) {
    return (element.name && element.name.length > 0) ? element.name : element.id;
}

/**
 * Test whether the element is displayed according to its display property.
 *
 * @param  elem {Element}
 * @return {boolean} whether or not the element is displayed
 */
function _isDisplayed(elem) {
    let display = _getEffectiveStyle(elem, "display");
    if ("none" === display) return false;

    let visibility = _getEffectiveStyle(elem, "visibility");
    if ("hidden" === visibility || "collapse" === visibility) return false;

    let opacity = _getEffectiveStyle(elem, "opacity");
    if (0 === opacity) return false;

    if (elem.parentNode.style) {
        return _isDisplayed(elem.parentNode);
    }
    return true;
}

/**
 * Get the effective css style of an element.
 *
 * @param  element {Element}
 * @param  property {String} the css property to obtain
 * @return {String} the effective css style
 */
function _getEffectiveStyle(element, property) {
    if (element.style === undefined) {
        return undefined; // not a styled element
    }

    let doc = element.ownerDocument;
    let effectiveStyle = doc.defaultView.getComputedStyle(element, null);
    let propertyValue = effectiveStyle.getPropertyValue(property);
    if ("inherit" === propertyValue && element.parentNode.style) {
        return _getEffectiveStyle(element.parentNode, property);
    }
    return propertyValue;
}
<commit_msg>Moved logging statements<commit_after>'use strict';

// uses some functions from collectFormData.js
//import {collectFormData} from 'collectFormData.js';

browser.runtime.onMessage.addListener(receiveEvents);

function receiveEvents(fhcEvent, sender, sendResponse) {
    if (fhcEvent.action) {

        switch (fhcEvent.action) {
            case "showformfields":
                console.log("Received action event " + fhcEvent.action);
                showformfields();
                break;

            case "getformfields":
                console.log("Received action event " + fhcEvent.action);
                let fields = [];
                getCurrentFields(document, fields);
                const thisHost = document.location.protocol === "file:" ? "localhost" :  document.location.host;
                sendResponse({fields: fields, host: thisHost});
                break;
        }
    }
}

function _getHost(aLocation) {
    if (aLocation.protocol === "file:") {
        return "localhost";
    } else {
        return aLocation.host;
    }
}

/**
 * Get the formfields for this page as an array of name + type objects.
 */
function getCurrentFields(aDocument, aFields) {

    aDocument.querySelectorAll("input,textarea").forEach( (node) => {
        if (_isTextInputSubtype(node.type) && _isDisplayed(node)) {
            let name = (node.name) ? node.name : ((node.id) ? node.id : "");
            if (name) {
                aFields.push({
                    name: name,
                    type: node.nodeName.toLowerCase()
                });
            }
        }
    });

    aDocument.querySelectorAll("html,div,iframe,body").forEach( (node) => {
        if ((_isContentEditable(node) && _isDisplayed(node)) || _isDesignModeOn(node)) {
            let name = (node.name) ? node.name : ((node.id) ? node.id : "");
            if (name) {
                aFields.push({
                    name: name,
                    type: node.nodeName.toLowerCase()
                });
            }
        }
    });

    // need to visit iframes inside this method in order to return a single Array of all elements
    aDocument.querySelectorAll('iframe').forEach( item => {
        try {
            getCurrentFields(item.contentWindow.document.body, aFields)
        } catch (e) {
            // probably: Permission denied to access property "document" on cross-origin object
        }
    });
}

function showformfields() {
    let ii = 0, id, div;
    document.querySelectorAll("input,textarea").forEach( (elem) => {
        //console.log("adding info for elem-id: " + elem.id);

        if (_isTextInputSubtype(elem.type) && _isDisplayed(elem)) {
            id = 'fhcFldInfo' + ++ii;

            // toggle info
            if (document.getElementById(id)) {
                // Remove info element
                document.body.removeChild(document.getElementById(id));
            } else {
                // Insert info element
                div = _createInfoElement(id, elem, true);
                // console.log("Adding div for " + elem.id + " of type " + elem.type + " div id " + id);
                document.body.appendChild(div);
            }
        }
    });

    document.querySelectorAll("html,div,iframe,body").forEach( (elem) => {
        if ((_isContentEditable(elem) && _isDisplayed(elem)) || _isDesignModeOn(elem)) {
            id = 'fhcFldInfo' + ++ii;
            //console.log("elem-id: " + elem.id + " of type ?");

            // toggle info
            if (document.getElementById(id)) {
                // Remove info element
                document.body.removeChild(document.getElementById(id));
            } else {
                // Insert info element
                div = _createInfoElement(id, elem, false);
                // console.log("Adding div for " + elem.id + " of type " + elem.type + " div id " + id);
                document.body.appendChild(div);
            }
        }
    });
}

/**
 * Create a div element for displaying the fieldname next to a formfield.
 *
 * @param id {String}
 *        the unique id for the div element
 *
 * @param sourceElem {Element}
 *        the inputfield determining the position for the new div element
 *
 * @param includeForm boolean
 *        whether or not to include info about te containing form
 *
 * @return {Element}
 *         the newly created div, absolute positioned next to the sourceElem
 */
function _createInfoElement(id, sourceElem, includeForm) {
    let fldName = _getElementNameOrId(sourceElem);
    if (fldName === '') {
        fldName = '\u00a0'; //
    }

    let style = 'display:block; border:1px solid #000; padding: 0 4px; ' +
        'background-color:#FFFFAA; color:#000; opacity: 0.75; ' +
        'font: bold 11px sans-serif; text-decoration:none; text-align:left; ' +
        'z-index: 2147483647; cursor:default; box-shadow: 3px 3px 2px black; ';

    let compstyle = document.defaultView.getComputedStyle(sourceElem, null);
    let width = 0;
    if ('BODY' !== sourceElem.nodeName && 'HTML' !== sourceElem.nodeName) {
        // do need place info about body or html next to (and outside) the element
        width = parseInt(compstyle.getPropertyValue("width").replace('px', ''));
    }
    let padding = parseInt(compstyle.getPropertyValue("padding-right").replace('px', ''));
    let border = parseInt(compstyle.getPropertyValue("border-right-width").replace('px', ''));

    let left = 0, top = 0, elem = sourceElem;
    if (elem.offsetParent) {
        do {
            left += elem.offsetLeft;
            top += elem.offsetTop;
        } while ((elem = elem.offsetParent));
    }
    style += 'position:absolute; top:' + top + 'px; ';
    style += 'left:' + (left + width + padding + border + 4) + 'px; ';

    let div = document.createElement('div');
    div.setAttribute('id', id);
    div.setAttribute('title', _getFormInfoText(sourceElem, includeForm));
    div.setAttribute('style', style);
    div.setAttribute('contenteditable', 'false');
    div.addEventListener("mouseenter", function(){this.style.opacity=1;this.style.zIndex=1002;}, false);
    div.addEventListener("mouseleave", function(){this.style.opacity=0.75;this.style.zIndex=1001;}, false);
    div.appendChild(document.createTextNode(fldName));

    let innerDiv = document.createElement('div');
    div.appendChild(innerDiv);
    div.addEventListener("click", function(){
        let e=document.getElementById(this.id + 'inner');
        if(e.style.display==='none') {
            e.style.display='block';
            this.style.zIndex=1001;
        } else {
            e.style.display='none';
            this.style.zIndex=1000;
        }
    }, false);
    innerDiv.setAttribute('id', id + 'inner');
    innerDiv.setAttribute('title', ' ');
    innerDiv.setAttribute('style',
        'display:none; background-color:#FFDCCF; margin:5px; padding:5px; ' +
        'font-weight: normal; border:1px inset #FFDCCF; ' +
        'box-shadow: inset 0 0 8px rgba(55, 20, 7, 0.5)');
    innerDiv.appendChild(_getFormInfoHTML(sourceElem, includeForm));

    return div;
}

/**
 * Collect the attributes for the element and its form container and return as String.
 *
 * @param element {Element}
 *        the inputfield
 *
 * @param includeForm boolean
 *        whether or not to include info about te containing form
 *
 * @return {Element}
 *         info about element and form
 */
function _getFormInfoHTML(element, includeForm) {
    let info = document.createElement('div');

    let inputBold = document.createElement('b');
    inputBold.textContent = '<' + element.nodeName + '>';
    info.appendChild(inputBold);

    info.appendChild(document.createElement('br'));

    for (let j = 0; j < element.attributes.length; j++) {
        info.appendChild(document.createTextNode(element.attributes[j].name + '=' + element.attributes[j].value));
        info.appendChild(document.createElement('br'));
    }

    if (includeForm) {
        let form = element;
        while (form.parentNode && form.localName !== 'form') {
            form = form.parentNode;
        }
        if (form && form.localName === 'form') {
            info.appendChild(document.createElement('br'));
            let formBold = document.createElement('b');
            formBold.textContent = '<FORM>';
            info.appendChild(formBold);
            info.appendChild(document.createElement('br'));
            for (let i = 0; i < form.attributes.length; i++) {
                info.appendChild(document.createTextNode(form.attributes[i].name + '=' + form.attributes[i].value));
                info.appendChild(document.createElement('br'));
            }
        }
    }
    return info;
}

/**
 * Collect the attributes for the element and its form container and return as String.
 *
 * @param element {Element}
 *        the inputfield
 *
 * @param includeForm boolean
 *        whether or not to include info about te containing form
 *
 * @return {String}
 *         info about element and form
 */
function _getFormInfoText(element, includeForm) {
    let sep = ' ';

    let result = element.nodeName + ': ';
    for (let j = 0; j < element.attributes.length; j++) {
        result += element.attributes[j].name + '=' + element.attributes[j].value + sep;
    }

    if (includeForm) {
        let form = element;
        while (form.parentNode && form.localName !== 'form') {
            form = form.parentNode;
        }
        if (form && form.localName === 'form') {
            result += ' # FORM: ';
            for (let i = 0; i < form.attributes.length; i++) {
                result += form.attributes[i].name + '=' + form.attributes[i].value + sep;
            }
        }
    }
    return result;
}

/**
 * Determine the name of an element (either name if it has one, otherwise its id).
 *
 * @param  element {Element}
 *         the DOM element
 *
 * @return {String}
 *         the name of the element, if no name then return its id
 */
function _getElementNameOrId(element) {
    return (element.name && element.name.length > 0) ? element.name : element.id;
}

/**
 * Test whether the element is displayed according to its display property.
 *
 * @param  elem {Element}
 * @return {boolean} whether or not the element is displayed
 */
function _isDisplayed(elem) {
    let display = _getEffectiveStyle(elem, "display");
    if ("none" === display) return false;

    let visibility = _getEffectiveStyle(elem, "visibility");
    if ("hidden" === visibility || "collapse" === visibility) return false;

    let opacity = _getEffectiveStyle(elem, "opacity");
    if (0 === opacity) return false;

    if (elem.parentNode.style) {
        return _isDisplayed(elem.parentNode);
    }
    return true;
}

/**
 * Get the effective css style of an element.
 *
 * @param  element {Element}
 * @param  property {String} the css property to obtain
 * @return {String} the effective css style
 */
function _getEffectiveStyle(element, property) {
    if (element.style === undefined) {
        return undefined; // not a styled element
    }

    let doc = element.ownerDocument;
    let effectiveStyle = doc.defaultView.getComputedStyle(element, null);
    let propertyValue = effectiveStyle.getPropertyValue(property);
    if ("inherit" === propertyValue && element.parentNode.style) {
        return _getEffectiveStyle(element.parentNode, property);
    }
    return propertyValue;
}
<|endoftext|>


<commit_before>/* @flow */
import { hot } from "react-hot-loader";

import * as React from "react";
import { DatabaseOcticon, Beaker } from "@nteract/octicons";

import { colors } from "./settings";
import { semioticSettings } from "./charts/settings";
import { DataResourceTransformGrid } from "./charts/grid";
import VizControls from "./VizControls";

import {
  TreeIcon,
  NetworkIcon,
  BoxplotIcon,
  ScatterplotIcon,
  LineChartIcon,
  BarChartIcon,
  HexbinIcon,
  ParallelCoordinatesIcon
} from "./icons";

import { chartHelpText } from "./docs/chart-docs";

type Props = {
  data: Object,
  metadata: Object,
  theme?: string,
  expanded?: boolean,
  height?: number
};

type LineType = "line" | "stackedarea" | "bumparea" | "stackedpercent";

type State = {
  view:
    | "line"
    | "bar"
    | "scatter"
    | "grid"
    | "network"
    | "summary"
    | "hexbin"
    | "parallel"
    | "hierarchy",
  colors: Array<string>,
  metrics: Array<Object>,
  dimensions: Array<Object>,
  selectedMetrics: Array<string>,
  selectedDimensions: Array<string>,
  networkType: "force" | "sankey",
  hierarchyType: "dendrogram" | "treemap" | "partition",
  pieceType: "bar" | "point" | "swarm" | "clusterbar",
  colorValue: string,
  sizeValue: string,
  xValue: string,
  yValue: string,
  targetDimension: string,
  sourceDimension: string,
  labelValue: string,
  summaryType: "violin" | "joy" | "histogram" | "heatmap" | "boxplot",
  lineType: LineType,
  chart: Object,
  displayChart: Object,
  primaryKey: Array<string>,
  data: Array<Object>
};

const generateChartKey = ({
  view,
  lineType,
  selectedDimensions,
  selectedMetrics,
  pieceType,
  summaryType,
  networkType,
  hierarchyType,
  chart
}) =>
  `${view}-${lineType}-${selectedDimensions.join(",")}-${selectedMetrics.join(
    ","
  )}-${pieceType}-${summaryType}-${networkType}-${hierarchyType}-${JSON.stringify(
    chart
  )}`;

/*
  contour is an option for scatterplot
  pie is a transform on bar
*/

const MetadataWarning = ({ metadata }) => {
  const warning =
    metadata && metadata.sampled ? (

        NOTE: This data is sampled

    ) : null;

  return (

        This interactive data explorer is in the works.{" "}

          Help us improve it!

        <Beaker
          style={{
            color: "#111",
            verticalAlign: "center",
            textAlign: "center",
            paddingLeft: "10px"
          }}
        />

      {warning ? (

          {warning}

      ) : null}

  );
};

///////////////////////////////

class DataResourceTransform extends React.Component<Props, State> {
  static MIMETYPE = "application/vnd.dataresource+json";

  static defaultProps = {
    metadata: {},
    height: 500
  };

  constructor(props: Props) {
    super(props);
    //DEFAULT FROM PROPS

    const { fields = [], primaryKey = [] } = props.data.schema;

    const dimensions = fields.filter(
      d => d.type === "string" || d.type === "boolean" || d.type === "datetime"
    );

    //Should datetime data types be transformed into js dates before getting to this resource?
    const data = props.data.data.map(d => {
      const mappedD = { ...d };
      fields.forEach(p => {
        if (p.type === "datetime") {
          mappedD[p.name] = new Date(mappedD[p.name]);
        }
      });
      return mappedD;
    });

    const metrics = fields
      .filter(
        d =>
          d.type === "integer" || d.type === "number" || d.type === "datetime"
      )
      .filter(d => !primaryKey.find(p => p === d.name));

    this.state = {
      view: "grid",
      lineType: "line",
      areaType: "hexbin",
      selectedDimensions: [],
      selectedMetrics: [],
      pieceType: "bar",
      summaryType: "violin",
      networkType: "force",
      hierarchyType: "dendrogram",
      colorValue: "none",
      labelValue: "none",
      sizeValue: "none",
      sourceDimension: "none",
      targetDimension: "none",
      xValue: "none",
      yValue: "none",
      dimensions,
      metrics,
      colors,
      ui: {},
      chart: {
        metric1: (metrics[0] && metrics[0].name) || "none",
        metric2: (metrics[1] && metrics[1].name) || "none",
        metric3: "none",
        dim1: (dimensions[0] && dimensions[0].name) || "none",
        dim2: (dimensions[1] && dimensions[1].name) || "none",
        dim3: "none",
        timeseriesSort: "array-order"
      },
      displayChart: {},
      primaryKey,
      data
    };
  }

  //SET STATE WHENEVER CHANGES

  //HELD IN STATE LIKE SO
  //UI CHOICES
  //CHART CHOICES
  //DERIVED DATA

  shouldComponentUpdate(): boolean {
    return true;
  }

  updateChart = (updatedState: Object) => {
    const {
      view,
      dimensions,
      metrics,
      chart,
      lineType,
      areaType,
      selectedDimensions,
      selectedMetrics,
      pieceType,
      summaryType,
      networkType,
      hierarchyType,
      colors,
      primaryKey,
      data: stateData
    } = { ...this.state, ...updatedState };

    const { data, height = 500 } = this.props;

    const { Frame, chartGenerator } = semioticSettings[view];

    const chartKey = generateChartKey({
      view,
      lineType,
      areaType,
      selectedDimensions,
      selectedMetrics,
      pieceType,
      summaryType,
      networkType,
      hierarchyType,
      chart
    });

    const frameSettings = chartGenerator(stateData, data.schema, {
      metrics,
      dimensions,
      chart,
      colors,
      height,
      lineType,
      areaType,
      selectedDimensions,
      selectedMetrics,
      pieceType,
      summaryType,
      networkType,
      hierarchyType,
      primaryKey,
      setColor: this.setColor
    });

    const display = (

        <Frame
          responsiveWidth={true}
          size={[500, height - 200]}
          {...frameSettings}
        />
        <VizControls
          {...{
            view,
            chart,
            metrics,
            dimensions,
            selectedDimensions,
            selectedMetrics,
            hierarchyType,
            summaryType,
            networkType,
            updateChart: this.updateChart,
            updateDimensions: this.updateDimensions,
            setLineType: this.setLineType,
            updateMetrics: this.updateMetrics,
            lineType,
            setAreaType: this.setAreaType,
            areaType
          }}
        />

    );

    this.setState({
      displayChart: {
        ...this.state.displayChart,
        [chartKey]: display
      },
      ...updatedState
    });
  };
  setView = view => {
    this.updateChart({ view });
  };

  setGrid = () => {
    this.setState({ view: "grid" });
  };

  setColor = newColorArray => {
    this.updateChart({ colors: newColorArray });
  };

  setLineType = (e: LineType) => {
    this.updateChart({ lineType: e });
  };

  setAreaType = (e: LineType) => {
    this.updateChart({ areaType: e });
  };

  updateDimensions = (e: string) => {
    const oldDims = this.state.selectedDimensions;
    const newDimensions =
      oldDims.indexOf(e) === -1
        ? [...oldDims, e]
        : oldDims.filter(d => d !== e);
    this.updateChart({ selectedDimensions: newDimensions });
  };
  updateMetrics = (e: string) => {
    const oldDims = this.state.selectedMetrics;
    const newMetrics =
      oldDims.indexOf(e) === -1
        ? [...oldDims, e]
        : oldDims.filter(d => d !== e);
    this.updateChart({ selectedMetrics: newMetrics });
  };

  render(): ?React$Element<any> {
    const {
      view,
      dimensions,
      chart,
      lineType,
      selectedDimensions,
      selectedMetrics,
      pieceType,
      summaryType,
      networkType,
      hierarchyType
    } = this.state;

    let display = null;

    if (view === "grid") {
      display = <DataResourceTransformGrid {...this.props} />;
    } else if (
      [
        "line",
        "scatter",
        "bar",
        "network",
        "summary",
        "hierarchy",
        "hexbin",
        "parallel"
      ].includes(view)
    ) {
      const chartKey = generateChartKey({
        view,
        lineType,
        selectedDimensions,
        selectedMetrics,
        pieceType,
        summaryType,
        networkType,
        hierarchyType,
        chart
      });

      display = this.state.displayChart[chartKey];
    }

    return (

        <MetadataWarning metadata={this.props.metadata} />

            {display}

            <IconButton
              title={chartHelpText.grid}
              onClick={this.setGrid}
              message={"Data Table"}
            >
              <DatabaseOcticon />
            </IconButton>
            {dimensions.length > 0 && (
              <IconButton
                title={chartHelpText.bar}
                onClick={() => this.setView("bar")}
                message={"Bar Graph"}
              >
                <BarChartIcon />
              </IconButton>
            )}
            <IconButton
              title={chartHelpText.summary}
              onClick={() => this.setView("summary")}
              message={"Summary"}
            >
              <BoxplotIcon />
            </IconButton>
            <IconButton
              title={chartHelpText.scatter}
              onClick={() => this.setView("scatter")}
              message={"Scatter Plot"}
            >
              <ScatterplotIcon />
            </IconButton>
            <IconButton
              title={chartHelpText.hexbin}
              onClick={() => this.setView("hexbin")}
              message={"Area Plot"}
            >
              <HexbinIcon />
            </IconButton>
            {dimensions.length > 1 && (
              <IconButton
                title={chartHelpText.network}
                onClick={() => this.setView("network")}
                message={"Network"}
              >
                <NetworkIcon />
              </IconButton>
            )}
            {dimensions.length > 0 && (
              <IconButton
                title={chartHelpText.hierarchy}
                onClick={() => this.setView("hierarchy")}
                message={"Hierarchy"}
              >
                <TreeIcon />
              </IconButton>
            )}
            {dimensions.length > 0 && (
              <IconButton
                title={chartHelpText.parallel}
                onClick={() => this.setView("parallel")}
                message={"Parallel Coordinates"}
              >
                <ParallelCoordinatesIcon />
              </IconButton>
            )}
            <IconButton
              title={chartHelpText.line}
              onClick={() => this.setView("line")}
              message={"Line Graph"}
            >
              <LineChartIcon />
            </IconButton>

    );
  }
}

/////////////////////////////

type IconButtonProps = {
  message: string,
  onClick: () => void,
  children?: React.Node
};

export class IconButton extends React.Component<IconButtonProps> {
  render() {
    const { message, onClick, children, title = messsage } = this.props;
    return (
      <button
        onClick={onClick}
        key={message}
        title={title}
        style={{
          width: "32px",
          height: "32px"
        }}
      >
        {children}
      </button>
    );
  }
}

export default hot(module)(DataResourceTransform);
<commit_msg>Flow fix<commit_after>/* @flow */
import { hot } from "react-hot-loader";

import * as React from "react";
import { DatabaseOcticon, Beaker } from "@nteract/octicons";

import { colors } from "./settings";
import { semioticSettings } from "./charts/settings";
import { DataResourceTransformGrid } from "./charts/grid";
import VizControls from "./VizControls";

import {
  TreeIcon,
  NetworkIcon,
  BoxplotIcon,
  ScatterplotIcon,
  LineChartIcon,
  BarChartIcon,
  HexbinIcon,
  ParallelCoordinatesIcon
} from "./icons";

import { chartHelpText } from "./docs/chart-docs";

type Props = {
  data: Object,
  metadata: Object,
  theme?: string,
  expanded?: boolean,
  height?: number
};

type LineType = "line" | "stackedarea" | "bumparea" | "stackedpercent";

type State = {
  view:
    | "line"
    | "bar"
    | "scatter"
    | "grid"
    | "network"
    | "summary"
    | "hexbin"
    | "parallel"
    | "hierarchy",
  colors: Array<string>,
  metrics: Array<Object>,
  dimensions: Array<Object>,
  selectedMetrics: Array<string>,
  selectedDimensions: Array<string>,
  networkType: "force" | "sankey",
  hierarchyType: "dendrogram" | "treemap" | "partition",
  pieceType: "bar" | "point" | "swarm" | "clusterbar",
  colorValue: string,
  sizeValue: string,
  xValue: string,
  yValue: string,
  targetDimension: string,
  sourceDimension: string,
  labelValue: string,
  summaryType: "violin" | "joy" | "histogram" | "heatmap" | "boxplot",
  lineType: LineType,
  chart: Object,
  displayChart: Object,
  primaryKey: Array<string>,
  data: Array<Object>
};

const generateChartKey = ({
  view,
  lineType,
  selectedDimensions,
  selectedMetrics,
  pieceType,
  summaryType,
  networkType,
  hierarchyType,
  chart
}) =>
  `${view}-${lineType}-${selectedDimensions.join(",")}-${selectedMetrics.join(
    ","
  )}-${pieceType}-${summaryType}-${networkType}-${hierarchyType}-${JSON.stringify(
    chart
  )}`;

/*
  contour is an option for scatterplot
  pie is a transform on bar
*/

const MetadataWarning = ({ metadata }) => {
  const warning =
    metadata && metadata.sampled ? (

        NOTE: This data is sampled

    ) : null;

  return (

        This interactive data explorer is in the works.{" "}

          Help us improve it!

        <Beaker
          style={{
            color: "#111",
            verticalAlign: "center",
            textAlign: "center",
            paddingLeft: "10px"
          }}
        />

      {warning ? (

          {warning}

      ) : null}

  );
};

///////////////////////////////

class DataResourceTransform extends React.Component<Props, State> {
  static MIMETYPE = "application/vnd.dataresource+json";

  static defaultProps = {
    metadata: {},
    height: 500
  };

  constructor(props: Props) {
    super(props);
    //DEFAULT FROM PROPS

    const { fields = [], primaryKey = [] } = props.data.schema;

    const dimensions = fields.filter(
      d => d.type === "string" || d.type === "boolean" || d.type === "datetime"
    );

    //Should datetime data types be transformed into js dates before getting to this resource?
    const data = props.data.data.map(d => {
      const mappedD = { ...d };
      fields.forEach(p => {
        if (p.type === "datetime") {
          mappedD[p.name] = new Date(mappedD[p.name]);
        }
      });
      return mappedD;
    });

    const metrics = fields
      .filter(
        d =>
          d.type === "integer" || d.type === "number" || d.type === "datetime"
      )
      .filter(d => !primaryKey.find(p => p === d.name));

    this.state = {
      view: "grid",
      lineType: "line",
      areaType: "hexbin",
      selectedDimensions: [],
      selectedMetrics: [],
      pieceType: "bar",
      summaryType: "violin",
      networkType: "force",
      hierarchyType: "dendrogram",
      colorValue: "none",
      labelValue: "none",
      sizeValue: "none",
      sourceDimension: "none",
      targetDimension: "none",
      xValue: "none",
      yValue: "none",
      dimensions,
      metrics,
      colors,
      ui: {},
      chart: {
        metric1: (metrics[0] && metrics[0].name) || "none",
        metric2: (metrics[1] && metrics[1].name) || "none",
        metric3: "none",
        dim1: (dimensions[0] && dimensions[0].name) || "none",
        dim2: (dimensions[1] && dimensions[1].name) || "none",
        dim3: "none",
        timeseriesSort: "array-order"
      },
      displayChart: {},
      primaryKey,
      data
    };
  }

  //SET STATE WHENEVER CHANGES

  //HELD IN STATE LIKE SO
  //UI CHOICES
  //CHART CHOICES
  //DERIVED DATA

  shouldComponentUpdate(): boolean {
    return true;
  }

  updateChart = (updatedState: Object) => {
    const {
      view,
      dimensions,
      metrics,
      chart,
      lineType,
      areaType,
      selectedDimensions,
      selectedMetrics,
      pieceType,
      summaryType,
      networkType,
      hierarchyType,
      colors,
      primaryKey,
      data: stateData
    } = { ...this.state, ...updatedState };

    const { data, height = 500 } = this.props;

    const { Frame, chartGenerator } = semioticSettings[view];

    const chartKey = generateChartKey({
      view,
      lineType,
      areaType,
      selectedDimensions,
      selectedMetrics,
      pieceType,
      summaryType,
      networkType,
      hierarchyType,
      chart
    });

    const frameSettings = chartGenerator(stateData, data.schema, {
      metrics,
      dimensions,
      chart,
      colors,
      height,
      lineType,
      areaType,
      selectedDimensions,
      selectedMetrics,
      pieceType,
      summaryType,
      networkType,
      hierarchyType,
      primaryKey,
      setColor: this.setColor
    });

    const display = (

        <Frame
          responsiveWidth={true}
          size={[500, height - 200]}
          {...frameSettings}
        />
        <VizControls
          {...{
            view,
            chart,
            metrics,
            dimensions,
            selectedDimensions,
            selectedMetrics,
            hierarchyType,
            summaryType,
            networkType,
            updateChart: this.updateChart,
            updateDimensions: this.updateDimensions,
            setLineType: this.setLineType,
            updateMetrics: this.updateMetrics,
            lineType,
            setAreaType: this.setAreaType,
            areaType
          }}
        />

    );

    this.setState({
      displayChart: {
        ...this.state.displayChart,
        [chartKey]: display
      },
      ...updatedState
    });
  };
  setView = view => {
    this.updateChart({ view });
  };

  setGrid = () => {
    this.setState({ view: "grid" });
  };

  setColor = newColorArray => {
    this.updateChart({ colors: newColorArray });
  };

  setLineType = (e: LineType) => {
    this.updateChart({ lineType: e });
  };

  setAreaType = (e: LineType) => {
    this.updateChart({ areaType: e });
  };

  updateDimensions = (e: string) => {
    const oldDims = this.state.selectedDimensions;
    const newDimensions =
      oldDims.indexOf(e) === -1
        ? [...oldDims, e]
        : oldDims.filter(d => d !== e);
    this.updateChart({ selectedDimensions: newDimensions });
  };
  updateMetrics = (e: string) => {
    const oldDims = this.state.selectedMetrics;
    const newMetrics =
      oldDims.indexOf(e) === -1
        ? [...oldDims, e]
        : oldDims.filter(d => d !== e);
    this.updateChart({ selectedMetrics: newMetrics });
  };

  render(): ?React$Element<any> {
    const {
      view,
      dimensions,
      chart,
      lineType,
      selectedDimensions,
      selectedMetrics,
      pieceType,
      summaryType,
      networkType,
      hierarchyType
    } = this.state;

    let display = null;

    if (view === "grid") {
      display = <DataResourceTransformGrid {...this.props} />;
    } else if (
      [
        "line",
        "scatter",
        "bar",
        "network",
        "summary",
        "hierarchy",
        "hexbin",
        "parallel"
      ].includes(view)
    ) {
      const chartKey = generateChartKey({
        view,
        lineType,
        selectedDimensions,
        selectedMetrics,
        pieceType,
        summaryType,
        networkType,
        hierarchyType,
        chart
      });

      display = this.state.displayChart[chartKey];
    }

    return (

        <MetadataWarning metadata={this.props.metadata} />

            {display}

            <IconButton
              title={chartHelpText.grid}
              onClick={this.setGrid}
              message={"Data Table"}
            >
              <DatabaseOcticon />
            </IconButton>
            {dimensions.length > 0 && (
              <IconButton
                title={chartHelpText.bar}
                onClick={() => this.setView("bar")}
                message={"Bar Graph"}
              >
                <BarChartIcon />
              </IconButton>
            )}
            <IconButton
              title={chartHelpText.summary}
              onClick={() => this.setView("summary")}
              message={"Summary"}
            >
              <BoxplotIcon />
            </IconButton>
            <IconButton
              title={chartHelpText.scatter}
              onClick={() => this.setView("scatter")}
              message={"Scatter Plot"}
            >
              <ScatterplotIcon />
            </IconButton>
            <IconButton
              title={chartHelpText.hexbin}
              onClick={() => this.setView("hexbin")}
              message={"Area Plot"}
            >
              <HexbinIcon />
            </IconButton>
            {dimensions.length > 1 && (
              <IconButton
                title={chartHelpText.network}
                onClick={() => this.setView("network")}
                message={"Network"}
              >
                <NetworkIcon />
              </IconButton>
            )}
            {dimensions.length > 0 && (
              <IconButton
                title={chartHelpText.hierarchy}
                onClick={() => this.setView("hierarchy")}
                message={"Hierarchy"}
              >
                <TreeIcon />
              </IconButton>
            )}
            {dimensions.length > 0 && (
              <IconButton
                title={chartHelpText.parallel}
                onClick={() => this.setView("parallel")}
                message={"Parallel Coordinates"}
              >
                <ParallelCoordinatesIcon />
              </IconButton>
            )}
            <IconButton
              title={chartHelpText.line}
              onClick={() => this.setView("line")}
              message={"Line Graph"}
            >
              <LineChartIcon />
            </IconButton>

    );
  }
}

/////////////////////////////

type IconButtonProps = {
  message: string,
  onClick: () => void,
  children?: React.Node,
  title: string
};

export class IconButton extends React.Component<IconButtonProps> {
  render() {
    const { message, onClick, children, title = message } = this.props;

    return (
      <button
        onClick={onClick}
        key={message}
        title={title}
        style={{
          width: "32px",
          height: "32px"
        }}
      >
        {children}
      </button>
    );
  }
}

export default hot(module)(DataResourceTransform);
<|endoftext|>


<commit_before>import pointInPolygon from '@turf/boolean-point-in-polygon';
import { featureCollection } from '@turf/helpers';
import { geomEach, featureEach } from '@turf/meta';

/**
 * Finds {@link Points} that fall within {@link (Multi)Polygon(s)}.
 *
 * @name pointsWithinPolygon
 * @param {Feauture|FeatureCollection<Point>} points Points as input search
 * @param {FeatureCollection|Geometry|Feature<Polygon|MultiPolygon>} polygons Points must be within these (Multi)Polygon(s)
 * @returns {FeatureCollection<Point>} points that land within at least one polygon
 * @example
 * var points = turf.points([
 *     [-46.6318, -23.5523],
 *     [-46.6246, -23.5325],
 *     [-46.6062, -23.5513],
 *     [-46.663, -23.554],
 *     [-46.643, -23.557]
 * ]);
 *
 * var searchWithin = turf.polygon([[
 *     [-46.653,-23.543],
 *     [-46.634,-23.5346],
 *     [-46.613,-23.543],
 *     [-46.614,-23.559],
 *     [-46.631,-23.567],
 *     [-46.653,-23.560],
 *     [-46.653,-23.543]
 * ]]);
 *
 * var ptsWithin = turf.pointsWithinPolygon(points, searchWithin);
 *
 * //addToMap
 * var addToMap = [points, searchWithin, ptsWithin]
 * turf.featureEach(ptsWithin, function (currentFeature) {
 *   currentFeature.properties['marker-size'] = 'large';
 *   currentFeature.properties['marker-color'] = '#000';
 * });
 */
function pointsWithinPolygon(points, polygons) {
    var results = [];
    geomEach(polygons, function (polygon) {
        featureEach(points, function (point) {
            if (pointInPolygon(point, polygon)) results.push(point);
        });
    });
    return featureCollection(results);
}

export default pointsWithinPolygon;
<commit_msg>Dedupe results before returning points within polygon<commit_after>import pointInPolygon from '@turf/boolean-point-in-polygon';
import { featureCollection } from '@turf/helpers';
import { geomEach, featureEach } from '@turf/meta';

/**
 * Finds {@link Points} that fall within {@link (Multi)Polygon(s)}.
 *
 * @name pointsWithinPolygon
 * @param {Feauture|FeatureCollection<Point>} points Points as input search
 * @param {FeatureCollection|Geometry|Feature<Polygon|MultiPolygon>} polygons Points must be within these (Multi)Polygon(s)
 * @returns {FeatureCollection<Point>} points that land within at least one polygon
 * @example
 * var points = turf.points([
 *     [-46.6318, -23.5523],
 *     [-46.6246, -23.5325],
 *     [-46.6062, -23.5513],
 *     [-46.663, -23.554],
 *     [-46.643, -23.557]
 * ]);
 *
 * var searchWithin = turf.polygon([[
 *     [-46.653,-23.543],
 *     [-46.634,-23.5346],
 *     [-46.613,-23.543],
 *     [-46.614,-23.559],
 *     [-46.631,-23.567],
 *     [-46.653,-23.560],
 *     [-46.653,-23.543]
 * ]]);
 *
 * var ptsWithin = turf.pointsWithinPolygon(points, searchWithin);
 *
 * //addToMap
 * var addToMap = [points, searchWithin, ptsWithin]
 * turf.featureEach(ptsWithin, function (currentFeature) {
 *   currentFeature.properties['marker-size'] = 'large';
 *   currentFeature.properties['marker-color'] = '#000';
 * });
 */
function pointsWithinPolygon(points, polygons) {
    var results = [];
    geomEach(polygons, function (polygon) {
        featureEach(points, function (point) {
            if (pointInPolygon(point, polygon)) results.push(point);
        });
    });
    var unique = results.filter(function (point, pos, arr) {
        return arr.indexOf(point) === pos;
    });
    return featureCollection(unique);
}

export default pointsWithinPolygon;
<|endoftext|>


<commit_before>/**
 * Author: Vinayak Rangnathrao Jadhav
 * Project: jRCarousel
 * Version: 0.1
 */
(function(f){"function"===typeof define&&define.amd?define(["jquery"],f):"object"===typeof exports?module.exports=f(require("jquery")):f(jQuery)})(function(f){f.fn.jRCarousel=function(y){function e(){return c.find(".slide").last()}function q(){return c.find(".slide").first()}function r(b){return c.find(".slide[data-index="+b+"]")}function v(){this.animations={slide:z,scroll:A,fade:B,zoomInSlide:C,zoomInScroll:D}}function l(d){d=d||q();a=e();g=d.data("index");var f=a.data("index");if(f==g)return-1;
c.find(".slide").not(a[0]).hide();d.show();if(f<g){for(;e().data("index")!=g;)a=q().detach().appendTo(c);w.run(b.animation,1)}else w.run(b.animation,-1);h.find(".nav").css({borderWidth:0}).eq(g).css({borderWidth:"2px"})}function k(){n||c.find(".controls").show();b.onSlideShow.call(this,a)}function z(d){1==d?a.css({left:m+"px"}).animate({left:0},{duration:b.animationSpeed,complete:function(){k()}}):a.animate({left:m+"px"},{duration:b.animationSpeed,complete:function(){for(a.css({left:0});e().data("index")!=
g;)a=e().detach().prependTo(c);a=e();k()}})}function A(d){1==d?a.css({top:p+"px"}).animate({top:0},{duration:b.animationSpeed,complete:function(){k()}}):a.animate({top:p+"px"},{duration:b.animationSpeed,complete:function(){for(a.css({top:0});e().data("index")!=g;)a=e().detach().prependTo(c);a=e();k()}})}function B(d){1==d?a.css({opacity:0}).animate({opacity:1},{duration:b.animationSpeed,complete:function(){k()}}):a.animate({opacity:0},{duration:b.animationSpeed,complete:function(){for(a.css({opacity:1});e().data("index")!=
g;)a=e().detach().prependTo(c);a=e();k()}})}function D(d){1==d?a.css({height:0}).animate({height:"100%"},{duration:b.animationSpeed,complete:function(){k()}}):a.animate({height:0},{duration:b.animationSpeed,complete:function(){for(a.css({height:"100%"});e().data("index")!=g;)a=e().detach().prependTo(c);a=e();k()}})}function C(d){1==d?a.css({width:0,left:m+"px"}).animate({width:"100%",left:0},{duration:b.animationSpeed,complete:function(){k()}}):a.animate({width:0},{duration:b.animationSpeed,complete:function(){for(a.css({width:"100%"});e().data("index")!=
g;)a=e().detach().prependTo(c);a=e();k()}})}function x(){h.width("100%");m=h.width()<b.width?h.width():b.width;p=m/E;h.css({width:m+"px",height:p+"px"})}var b=f.extend(!0,{},{width:1349,height:668,slides:[],slideLayout:"cover",animation:"slide",animationSpeed:700,animationInterval:2E3,autoplay:!0,controls:!0,navigation:null,onSlideShow:function(){}},y),h=this,m=b.width,p=b.height,E=b.width/b.height,c=f("
").css({display:"block",position:"relative",overflow:"hidden",width:"100%",
height:"100%"}).appendTo(h),a,g,w=new v,t,u,n;(function(){function d(){t=f("

");u=f("

");t.add(u).appendTo(c).css({position:"absolute",top:"42%",zIndex:1,display:"inline-block",padding:"18px",boxShadow:"7px 7px 0 1px #777 inset",cursor:"pointer",opacity:"0.7"}).hide();t.on("click",function(){c.find(".controls").hide();l(c.find(".slide").eq(-2))});
u.on("click",function(){c.find(".controls").hide();l(q())});h.hover(function(){c.find(".controls").fadeIn()},function(){c.find(".controls").fadeOut()})}function e(){for(var a=b.navigation,d=f("
").css({textAlign:"right"}),g=0;g<c.find(".slide").length;g++)d.append("

");"circles"==a?d.find(".nav").css({border:"0 dashed #ccc",borderRadius:"12px"}):"squares"==a&&d.find(".nav").css({border:"0 dotted #fff"});d.find(".nav").css({display:"inline-block",margin:"4px",
cursor:"pointer",backgroundColor:"#777",width:"12px",height:"12px"}).first().css({borderWidth:"2px"});c.after(d);h.on("click",".nav",function(){l(r(f(this).index()))}).css({marginBottom:"24px"})}function g(){n=setInterval(l,b.animationInterval+b.animationSpeed);c.find(".controls").hide();h.hover(function(){clearInterval(n);n=0;c.find(".controls").fadeIn()},function(){c.find(".controls").fadeOut();n=setInterval(l,b.animationInterval+b.animationSpeed)})}(function(){if(b.slides.length)for(var d=0;d<
b.slides.length;d++){var e=f("").prop({src:b.slides[d].src,alt:"'"+b.slides[d].src+"'"}).detach();c.append(e)}else h.find(".slide").each(function(a){a=f(this).attr("data-index",a).detach();c.append(a)});c.find(".slide").css({position:"absolute",left:0,top:0,width:"100%",height:"100%",objectFit:b.slideLayout,backgroundColor:"#fff"});c.find(".slide img").css({width:"100%",height:"100%",objectFit:b.slideLayout});a=c.find(".slide").first().detach();c.append(a);h.css({width:m+
"px",height:p+"px"})})();b.controls&&d();b.navigation&&e();b.autoplay&&g();addEventListener("resize",x);x()})();v.prototype.run=function(a,b){this.animations[a](b)};this.showSlide=function(a){l(r(a))};this.getCurrentSlide=function(){return e()};this.getSlideByIndex=function(a){return r(a)};this.showPreviousSlide=function(){l(c.find(".slide").eq(-2))};this.showNextSlide=function(){l(q())};return this}});<commit_msg>Added smooth Animation fire rate<commit_after>/**
 * Author: Vinayak Rangnathrao Jadhav
 * Project: jRCarousel
 * Version: 0.1
 */
(function(f){"function"===typeof define&&define.amd?define(["jquery"],f):"object"===typeof exports?module.exports=f(require("jquery")):f(jQuery)})(function(f){f.fn.jRCarousel=function(y){function e(){return c.find(".slide").last()}function q(){return c.find(".slide").first()}function r(b){return c.find(".slide[data-index="+b+"]")}function v(){this.animations={slide:z,scroll:A,fade:B,zoomInSlide:C,zoomInScroll:D}}function l(d){d=d||q();a=e();g=d.data("index");var f=a.data("index");if(f==g)return-1;
c.find(".slide").not(a[0]).hide();d.show();if(f<g){for(;e().data("index")!=g;)a=q().detach().appendTo(c);w.run(b.animation,1)}else w.run(b.animation,-1);h.find(".nav").css({borderWidth:0}).eq(g).css({borderWidth:"2px"})}function k(){n||c.find(".controls").show();b.onSlideShow.call(this,a)}function z(d){1==d?a.css({left:m+"px"}).animate({left:0},{duration:b.animationSpeed,complete:function(){k()}}):a.animate({left:m+"px"},{duration:b.animationSpeed,complete:function(){for(a.css({left:0});e().data("index")!=
g;)a=e().detach().prependTo(c);a=e();k()}})}function A(d){1==d?a.css({top:p+"px"}).animate({top:0},{duration:b.animationSpeed,complete:function(){k()}}):a.animate({top:p+"px"},{duration:b.animationSpeed,complete:function(){for(a.css({top:0});e().data("index")!=g;)a=e().detach().prependTo(c);a=e();k()}})}function B(d){1==d?a.css({opacity:0}).animate({opacity:1},{duration:b.animationSpeed,complete:function(){k()}}):a.animate({opacity:0},{duration:b.animationSpeed,complete:function(){for(a.css({opacity:1});e().data("index")!=
g;)a=e().detach().prependTo(c);a=e();k()}})}function D(d){1==d?a.css({height:0}).animate({height:"100%"},{duration:b.animationSpeed,complete:function(){k()}}):a.animate({height:0},{duration:b.animationSpeed,complete:function(){for(a.css({height:"100%"});e().data("index")!=g;)a=e().detach().prependTo(c);a=e();k()}})}function C(d){1==d?a.css({width:0,left:m+"px"}).animate({width:"100%",left:0},{duration:b.animationSpeed,complete:function(){k()}}):a.animate({width:0},{duration:b.animationSpeed,complete:function(){for(a.css({width:"100%"});e().data("index")!=
g;)a=e().detach().prependTo(c);a=e();k()}})}function x(){h.width("100%");m=h.width()<b.width?h.width():b.width;p=m/E;h.css({width:m+"px",height:p+"px"})}var b=f.extend(!0,{},{width:1349,height:668,slides:[],slideLayout:"fill",animation:"slide",animationSpeed:700,animationInterval:2E3,autoplay:!0,controls:!0,navigation:null,onSlideShow:function(){}},y),h=this,m=b.width,p=b.height,E=b.width/b.height,c=f("
").css({display:"block",position:"relative",overflow:"hidden",width:"100%",
height:"100%"}).appendTo(h),a,g,w=new v,t,u,n;(function(){function d(){t=f("

");u=f("

");t.add(u).appendTo(c).css({position:"absolute",top:"42%",zIndex:1,display:"inline-block",padding:"18px",boxShadow:"7px 7px 0 1px #777 inset",cursor:"pointer",opacity:"0.7"}).hide();t.on("click",function(){c.find(".controls").hide();l(c.find(".slide").eq(-2))});
u.on("click",function(){c.find(".controls").hide();l(q())});h.hover(function(){c.find(".controls").fadeIn()},function(){c.find(".controls").fadeOut()})}function e(){for(var a=b.navigation,d=f("
").css({textAlign:"right"}),g=0;g<c.find(".slide").length;g++)d.append("

");"circles"==a?d.find(".nav").css({border:"0 dashed #ccc",borderRadius:"12px"}):"squares"==a&&d.find(".nav").css({border:"0 dotted #fff"});d.find(".nav").css({display:"inline-block",margin:"4px",
cursor:"pointer",backgroundColor:"#777",width:"12px",height:"12px"}).first().css({borderWidth:"2px"});c.after(d);h.on("click",".nav",function(){l(r(f(this).index()))}).css({marginBottom:"24px"})}function g(){n=setInterval(l,b.animationInterval+b.animationSpeed);c.find(".controls").hide();h.hover(function(){clearInterval(n);n=0;c.find(".controls").fadeIn()},function(){c.find(".controls").fadeOut();n=setInterval(l,b.animationInterval+b.animationSpeed)})}(function(){if(b.slides.length)for(var d=0;d<
b.slides.length;d++){var e=f("").prop({src:b.slides[d].src,alt:"'"+b.slides[d].src+"'"}).detach();c.append(e)}else h.find(".slide").each(function(a){a=f(this).attr("data-index",a).detach();c.append(a)});c.find(".slide").css({position:"absolute",left:0,top:0,width:"100%",height:"100%",objectFit:b.slideLayout,backgroundColor:"#fff"});c.find(".slide img").css({width:"100%",height:"100%",objectFit:b.slideLayout});a=c.find(".slide").first().detach();c.append(a);h.css({width:m+
"px",height:p+"px"})})();b.controls&&d();b.navigation&&e();b.autoplay&&g();addEventListener("resize",x);x();jQuery.fx.interval=7})();v.prototype.run=function(a,b){this.animations[a](b)};this.showSlide=function(a){l(r(a))};this.getCurrentSlide=function(){return e()};this.getSlideByIndex=function(a){return r(a)};this.showPreviousSlide=function(){l(c.find(".slide").eq(-2))};this.showNextSlide=function(){l(q())};return this}});<|endoftext|>


<commit_before>'use strict';

Object.defineProperty(exports, '__esModule', {
  value: true
});

var _keys = require('./keys');

var modKeys = Object.keys(_keys.modifiers);

function matchKeys(_ref) {
  var _ref$keySet = _ref.keySet;
  var key = _ref$keySet.key;
  var _ref$keySet$modifiers = _ref$keySet.modifiers;
  var modifiers = _ref$keySet$modifiers === undefined ? [] : _ref$keySet$modifiers;
  var event = _ref.event;

  var keysMatch = false;
  if (key === event.which) {
    (function () {
      var evtModKeys = modKeys.filter(function (modKey) {
        return event[modKey + 'Key'];
      }).sort();
      keysMatch = modifiers.length === evtModKeys.length && modifiers.every(function (modKey, index) {
        return evtModKeys[index];
      });
    })();
  }
  return keysMatch;
}

exports['default'] = matchKeys;
module.exports = exports['default'];<commit_msg>compile bug fix for dist<commit_after>'use strict';

Object.defineProperty(exports, '__esModule', {
  value: true
});

var _keys = require('./keys');

var modKeys = Object.keys(_keys.modifiers);

function matchKeys(_ref) {
  var _ref$keySet = _ref.keySet;
  var key = _ref$keySet.key;
  var _ref$keySet$modifiers = _ref$keySet.modifiers;
  var modifiers = _ref$keySet$modifiers === undefined ? [] : _ref$keySet$modifiers;
  var event = _ref.event;

  var keysMatch = false;
  if (key === event.which) {
    (function () {
      var evtModKeys = modKeys.filter(function (modKey) {
        return event[modKey + 'Key'];
      }).sort();
      keysMatch = modifiers.length === evtModKeys.length && modifiers.every(function (modKey, index) {
        return evtModKeys[index] === modKey;
      });
    })();
  }
  return keysMatch;
}

exports['default'] = matchKeys;
module.exports = exports['default'];<|endoftext|>