<commit_before>(function(doc, win) {

    var watchArray = [],
        scroll = {
            top: 0,
            left: 0
        },
        initialized = false,
        docElem = doc.documentElement,
        noop = function() {};

    //test getComputedStyle
    if (!window.getComputedStyle) {
        win.Stickyfill = noop;
        return;
    }

    //test for native support
    var prefixes = ['', '-webkit-', '-moz-', '-ms-'],
        block = document.createElement('div');

    for (var i = prefixes.length - 1; i >= 0; i--) {
        try {
            block.style.position = prefixes[i] + 'sticky';
        }
        catch(e) {}
        if (block.style.position != '') {
            win.Stickyfill = noop;
            return;
        }
    }

    function updateScrollPos() {
        var queuReinit,
            currentScroll = {
            top: docElem.scrollTop || document.body.scrollTop,
            left: docElem.scrollLeft || document.body.scrollLeft
        }

        if (currentScroll.left != scroll.left) {
            scroll = currentScroll;
            reinit();
        }
        else {
            scroll = currentScroll;
            //window.requestAnimationFrmae? requestAnimationFrmae(recalcPos): recalcPos();
            recalcPos();
        }
    }

    function recalcPos() {
        for (var i = watchArray.length - 1; i >= 0; i--) {
            var currentMode = (scroll.top <= watchArray[i].limit.start || isNaN(parseFloat(watchArray[i].computed.top))? 0: scroll.top >= watchArray[i].limit.end? 2: 1);

            if (watchArray[i].mode != currentMode) {
                switchElementMode(watchArray[i], currentMode);
            }
        };
    }

    function switchElementMode(el, mode) {
        switch (mode) {
            case 0:
                if (el.clone) {
                    el.clone.parentNode.insertBefore(el.node, el.clone);
                    el.clone.parentNode.removeChild(el.clone);
                    el.clone = undefined;
                }
                el.node.style.position = '';
                el.node.style.width = el.css.width;
                el.node.style.top = el.css.top;
                el.node.style.bottom = el.css.bottom;
                el.node.style.left = el.css.left;
                el.node.style.marginTop = el.css.marginTop;
                //el.node.style.marginBottom = el.css.marginBottom;
                break;
            case 1:
                if (!el.clone) {
                    el.clone = clone(el);
                    el.node.parentNode.insertBefore(el.clone, el.node);
                    el.clone.appendChild(el.node);
                }
                el.node.style.position = 'fixed';
                el.node.style.left = el.box.left + 'px';
                el.node.style.top = el.computed.top;
                el.node.style.bottom = 'auto';
                el.node.style.width = el.width + 'px';
                el.node.style.marginTop = 0;
                break;
            case 2:
                if (!el.clone) {
                    el.clone = clone(el);
                    el.node.parentNode.insertBefore(el.clone, el.node);
                    el.clone.appendChild(el.node);
                }
                el.node.style.position = 'absolute';
                el.node.style.left = 'auto';
                el.node.style.top = 'auto';
                el.node.style.bottom = 0;
                el.node.style.width = el.width + 'px';
                //el.node.style.marginBottom = 0;
                break;
        }

        el.mode = mode;
    }

    function getElementParams(node) {
        if (!node.parentNode) return;

        var parent = node.offsetParent,
            nodeOffset = getElementOffset(node),
            parentOffset = getElementOffset(parent);

        var el = {
            node: node,
            box: nodeOffset.win,
            css: {
                top: node.style.top,
                bottom: node.style.bottom,
                left: node.style.left,
                right: node.style.right,
                width: node.style.width,
                marginTop: node.style.marginTop,
                marginBottom: node.style.marginBottom
            },
            computed: getElementStyleProps(node, 'top marginTop marginBottom'),
            width: node.offsetWidth,
            height: node.offsetHeight,
            mode: 0,
            clone: undefined
        };

        var numericTop = parseFloat(el.computed.top) || 0,
            numericMarginBottom = parseFloat(el.computed.marginBottom) || 0,
            numericParentBorderBottomWidth = parseFloat(getElementStyleProps(parent, 'borderBottomWidth')) || 0;

        el.limit = {
            start: nodeOffset.doc.top - numericTop,
            end: parentOffset.doc.top + parent.offsetHeight - numericParentBorderBottomWidth - node.offsetHeight - numericTop - numericMarginBottom
        }

        return el;
    }

    function getElementStyleProps(node, props) {
        var absProps = (!!window.opera || node.tagName == 'TH' || node.tagName == 'TD'),
            result = {};

        props = props.split(' ');

        absProps && (node.style.position = 'absolute');
        for (var i = props.length - 1; i >= 0; i--) {
            result[props[i]] = getComputedStyle(node)[props[i]];
        }
        absProps && (node.style.position = '');

        return props.length > 1? result: result[props[0]];
    }

    function getElementOffset(node) {
        var client = {
                top: document.documentElement.clientTop || document.body.clientTop || 0,
                left: document.documentElement.clientLeft || document.body.clientLeft || 0
            },
            scroll = {
                top: win.pageYOffset || docElem.scrollTop,
                left: win.pageXOffset || docElem.scrollLeft
            },
            box = node.getBoundingClientRect();

            return {
                doc: {
                    left: box.left + scroll.left - client.left,
                    top: box.top + scroll.top - client.top
                },
                win: box
            };
    }

    function clone(el) {
        var clone = document.createElement(el.node.tagName);

        clone.style.height = el.height + 'px';
        clone.style.width = el.width + 'px';
        clone.style.marginTop = el.computed.marginTop;
        clone.style.marginBottom = el.computed.marginBottom;
        clone.style.paddingTop = clone.style.paddingRight =
            clone.style.paddingBottom = clone.style.paddingLeft = 0;

        return clone;
    }

    function recalcAllParams() {
        for (var i = watchArray.length - 1; i >= 0; i--) {
            switchElementMode(watchArray[i], 0);
            watchArray[i] = getElementParams(watchArray[i].node);
        };
    }

    function reinit() {
        recalcAllParams();
        updateScrollPos();
    }

    function init() {
        updateScrollPos();
        win.addEventListener('scroll', updateScrollPos);

        //watch for width changes
        win.addEventListener('resize', reinit);
        win.addEventListener('orientationchange', reinit);
    }

    win.Stickyfill = function(node) {
        watchArray.push(getElementParams(node));
        if (!initialized) init();

        return {
            elements: watchArray,
            reinit: reinit,
            removeListeners: function() {
                win.removeEventListener('scroll', updateScrollPos);
                win.removeEventListener('resize', reinit);
                win.removeEventListener('orientationchange', reinit);
            }
        }
    }

})(document, window);
<commit_msg>implement 2 different clone types (blocks/table-cells), performance optimizations<commit_after>(function(doc, win) {

    var watchArray = [],
        scroll = {
            top: 0,
            left: 0
        },
        initialized = false,
        docElem = doc.documentElement,
        noop = function() {};

    //test getComputedStyle
    if (!window.getComputedStyle) {
        win.Stickyfill = noop;
        return;
    }

    //test for native support
    var prefixes = ['', '-webkit-', '-moz-', '-ms-'],
        block = document.createElement('div');

    for (var i = prefixes.length - 1; i >= 0; i--) {
        try {
            block.style.position = prefixes[i] + 'sticky';
        }
        catch(e) {}
        if (block.style.position != '') {
            win.Stickyfill = noop;
            return;
        }
    }

    function updateScrollPos() {
        var queuReinit,
            currentScroll = {
            top: docElem.scrollTop || document.body.scrollTop,
            left: docElem.scrollLeft || document.body.scrollLeft
        }

        if (currentScroll.left != scroll.left) {
            scroll = currentScroll;
            reinit();
        }
        else {
            scroll = currentScroll;
            recalcAllPos();
        }
    }

    function recalcAllPos() {
        for (var i = watchArray.length - 1; i >= 0; i--) {
            recalcElementPos(watchArray[i]);
        }
    }

    function recalcElementPos(el) {
        var currentMode = (scroll.top <= el.limit.start || isNaN(parseFloat(el.computed.top))? 0: scroll.top >= el.limit.end? 2: 1);

        if (el.mode != currentMode) {
            switchElementMode(el, currentMode);
        }
    }

    function switchElementMode(el, mode) {
        switch (mode) {
            case 0:
                if (el.clone) {
                    killClone(el);
                }
                el.node.style.position = '';
                el.node.style.width = el.css.width;
                el.node.style.top = el.css.top;
                el.node.style.bottom = el.css.bottom;
                el.node.style.left = el.css.left;
                el.node.style.marginTop = el.css.marginTop;
                //el.node.style.marginBottom = el.css.marginBottom;
                break;
            case 1:
                if (!el.clone) {
                    clone(el);
                }
                el.node.style.position = 'fixed';
                el.node.style.left = el.box.left + 'px';
                el.node.style.top = el.computed.top;
                el.node.style.bottom = 'auto';
                el.node.style.width = el.width + 'px';
                el.node.style.marginTop = 0;
                break;
            case 2:
                if (!el.clone) {
                    clone(el);
                }
                el.node.style.position = 'absolute';
                el.node.style.left = 'auto';
                el.node.style.top = 'auto';
                el.node.style.bottom = 0;
                el.node.style.width = el.width + 'px';
                //el.node.style.marginBottom = 0;
                break;
        }

        el.mode = mode;
    }

    function clone(el) {
        var refElement = el.node.nextSibling || el.node;

        el.clone = document.createElement(el.node.tagName);

        el.clone.style.height = el.height + 'px';
        el.clone.style.width = el.width + 'px';
        el.clone.style.marginTop = el.computed.marginTop;
        el.clone.style.marginBottom = el.computed.marginBottom;
        el.clone.style.paddingTop = el.clone.style.paddingRight =
            el.clone.style.paddingBottom = el.clone.style.paddingLeft = 0;

        el.node.parentNode.insertBefore(el.clone, refElement);

        if (el.cell) el.clone.appendChild(el.node);
    }

    function killClone(el) {
        if (el.cell) el.clone.parentNode.insertBefore(el.node, el.clone);
        el.clone.parentNode.removeChild(el.clone);
        el.clone = undefined;
    }

    function getElementParams(node) {
        if (!node.parentNode) return;

        var parent = node.offsetParent,
            nodeOffset = getElementOffset(node),
            parentOffset = getElementOffset(parent);

        var el = {
            node: node,
            box: nodeOffset.win,
            css: {
                top: node.style.top,
                bottom: node.style.bottom,
                left: node.style.left,
                right: node.style.right,
                width: node.style.width,
                marginTop: node.style.marginTop,
                marginBottom: node.style.marginBottom
            },
            cell: getComputedStyle(node).display == 'table-cell',
            computed: getElementStyleProps(node, 'top marginTop marginBottom'),
            width: node.offsetWidth,
            height: node.offsetHeight,
            mode: 0,
            clone: undefined
        };

        var numericTop = parseFloat(el.computed.top) || 0,
            numericMarginBottom = parseFloat(el.computed.marginBottom) || 0,
            numericParentBorderBottomWidth = parseFloat(getElementStyleProps(parent, 'borderBottomWidth')) || 0;

        el.limit = {
            start: nodeOffset.doc.top - numericTop,
            end: parentOffset.doc.top + parent.offsetHeight - numericParentBorderBottomWidth - node.offsetHeight - numericTop - numericMarginBottom
        }

        el.cell = getComputedStyle(node).display == 'table-cell';

        return el;
    }

    function getElementStyleProps(node, props) {
        var absProps = (!!window.opera || getComputedStyle(node).display == 'table-cell'),
            result = {};

        props = props.split(' ');

        absProps && (node.style.position = 'absolute');
        for (var i = props.length - 1; i >= 0; i--) {
            result[props[i]] = getComputedStyle(node)[props[i]];
        }
        absProps && (node.style.position = '');

        return props.length > 1? result: result[props[0]];
    }

    function getElementOffset(node) {
        var client = {
                top: document.documentElement.clientTop || document.body.clientTop || 0,
                left: document.documentElement.clientLeft || document.body.clientLeft || 0
            },
            scroll = {
                top: win.pageYOffset || docElem.scrollTop,
                left: win.pageXOffset || docElem.scrollLeft
            },
            box = node.getBoundingClientRect();

            return {
                doc: {
                    left: box.left + scroll.left - client.left,
                    top: box.top + scroll.top - client.top
                },
                win: box
            };
    }

    function recalcAllParams() {
        for (var i = watchArray.length - 1; i >= 0; i--) {
            switchElementMode(watchArray[i], 0);
            watchArray[i] = getElementParams(watchArray[i].node);
        };
    }

    function reinit() {
        recalcAllParams();
        updateScrollPos();
    }

    function init() {
        updateScrollPos();
        win.addEventListener('scroll', updateScrollPos);

        //watch for width changes
        win.addEventListener('resize', reinit);
        win.addEventListener('orientationchange', reinit);

        initialized = true;
    }

    win.Stickyfill = function(node) {
        watchArray.push(getElementParams(node));
        if (!initialized) {
            init();
        }
        else {
            recalcElementPos(watchArray[watchArray.length - 1]);
        }

        return {
            elements: watchArray,
            reinit: reinit,
            removeListeners: function() {
                win.removeEventListener('scroll', updateScrollPos);
                win.removeEventListener('resize', reinit);
                win.removeEventListener('orientationchange', reinit);
            }
        }
    }

})(document, window);
<|endoftext|>


<commit_before>
(function() {

    /**
     * table view shown in admin
     */
    cdb.admin.TableView = cdb.ui.common.Table.extend({

      events: cdb.core.View.extendEvents({
          'click .sqlview .clearview': '_clearView',
          'click .sqlview .export_query': '_tableFromQuery',
          'click .noRows': 'addEmptyRow'
      }),

      rowView: cdb.admin.RowView,

      initialize: function() {
         var self = this;
         this.elder('initialize');
         this.options.row_header = true;
         this.model.data().bind('newPage', this.newPage, this);

          _.bindAll(this, "render", "addEmptyRow", "_checkEmptyTable", "rowChanged", "rowSynched", "rowFailed");
          window.a = this;
         var topReached = false;
         this._editorsOpened = null;

         // pagination
         setInterval(function() {
           if(!self.$el.is(":visible") || self.model.data().isFetchingPage()) {
             return;
           }
           var pos = $(this).scrollTop();
           var d = self.model.data();
           // do not let to fetch previous pages
           // until the user dont scroll back a little bit
           if(pos > 2) {
             topReached = false;
           }
           var pageSize = $(window).height() - self.$el.offset().top;
           var tableHeight = this.$('tbody').height();
           var realPos = pos + pageSize;
           if(tableHeight < pageSize) {
             return;
           }
           if(realPos > tableHeight) {
//              console.log(realPos, tableHeight, tableHeight - realPos);
              d.setPage(d.getPage() + 1);
           } else if (pos <= 0) {
             if(!topReached) {
               d.setPage(d.getPage() - 1);
             }
             topReached = true;
           }

         }, 2000);

        // Moving header and loaders when scrolls
        $(window).scroll(function(ev){
          // move header
          self.$el.find("thead > tr > th > div").css({marginLeft: -$(window).scrollLeft() + "px"});
        });

        this.model.data().bind('loadingRows', function(updown) {
          var fn = updown === 'up'? 'prepend': 'append';
          console.log('lalalla');
          self.$el[fn]("

Loading more rows

Now viewing 120 of 264

");
        });

        this.model.data().bind('endLoadingRows', function() {
          //self.$el.find('.page_loader').remove();
        });

        this.bind('cellDblClick', this._editCell, this);
        this.model.bind('change:dataSource', this._onSQLView, this);
        // when model changes the header is re rendered so the notice should be added
        this.model.bind('change', this._onSQLView, this);
        this._models[0].bind('remove', this._checkEmptyTable);
        this._models[0].bind('add', this._checkEmptyTable);

      },

      _onSQLView: function() {
        // if we are in a SQL view add a header
        this.$('.sqlview').remove();
        if(this.model.isInSQLView()) {
          this.$('thead').append(
            this.getTemplate('table/views/sql_view_notice')()
          );
          this.$('thead > tr').css('height', 64 + 42);
        }
      },

      _clearView: function(e) {
        e.preventDefault();
        this.model.useSQLView(null);
        return false;
      },

      _tableFromQuery: function(e) {
        var self = this;
        e.preventDefault();
        //this.model.useSQLView(null);
        var dlg = new cdb.admin.TableNameDialog({
          ok: function(name) {
            var sql = self.model.data().getSQL();
            alert('to be done in backend');
            /*
            var table = cdb.admin.CartoDBTableMetadata.createFromQuery(name, sql);

            table.save(null, {
              success: function() {
              },
              error: function() {
                cdb.log.error("problem creating table from query");
              }
            });
            */
          }
        });
        dlg.appendToBody().show();
        return false;
        /*
        from_query:SELECT * FROM cb_municipios_5000_e limit 1
        name:asdasdasd
        */
      },

      _getEditor: function(columnType, opts) {
        var editors = {
          'string': cdb.admin.EditStringDialog,
          'number': cdb.admin.EditNumberDialog,
          'date': cdb.admin.EditDateDialog,
          'geometry': cdb.admin.EditGeometryDialog,
          'boolean': cdb.admin.EditBooleanDialog
        };

        // clean previous if exits
        var view = this._editorsOpened;
        if(view) {
          view.clean();
        }

        var Editor = editors[columnType];
        this._editorsOpened = new Editor(opts);
        return this._editorsOpened;

      },

      _editCell: function(e, cell, x, y) {
        var self = this;
        if(this.model.data().isReadOnly()) {
          return;
        }
        var column = self.model.columnName(x-1);
        var columnType = this.model.getColumnType(column);

        if(this.model.isReservedColumn(column)) {
          return;
        }

        var row = self.model.data().getRowAt(y);
        var dlg = this._getEditor(columnType, {
          initial_value: self.model.data().getCell(y, column) || '',
          row: row,
          res: function(val) {
            var update = {};
            update[column] = val;
            row.set(update).save();
          }
        });

        if(!dlg) {
          cdb.log.error("editor not defined for column type " + columnType);
          return;
        }

        // auto add to table view
        // Check first if the row is the first or the cell is the last :)
        var $td = $(e.target).closest("td")
          , offset = $td.position()
          , width = $td.outerWidth();

        if ($td.parent().index() == 0) {
          offset.top += 5;
        } else {
          offset.top -= 11;
        }

        if ($td.index() == ($td.size() - 1)) {
          offset.left -= 22;
        } else {
          offset.left -= 11;
        }

        dlg.showAt(offset.left, offset.top, width, true);
      },

      /**
       * called when a new page is loaded
       */
      newPage: function(currentPage, direction) {
         var d = this.model.data();
         var rowspp = d.options.get('rows_per_page');
         var max_items = rowspp*4;
         if(d.size() > max_items) {
           var idx = currentPage*rowspp;
           cdb.log.debug("removing rows: " + d.size() + " " + idx);
           if(direction == 'up') {
             d.remove(d.models.slice(max_items, d.size()));
           } else {
             d.remove(d.models.slice(0, idx));
           }
         }
      },

      headerView: function(column) {
        if(column[1] !== 'header') {
          var v = new cdb.admin.HeaderView({
            column: column,
            table: this.model,
            sqlView: this.options.sqlView
          });
          this.addView(v);
          return v.render().el;
        } else {
          return '

';
        }
      },

      /**
      * Checks if the table has any rows, and if not, launch the method for showing the appropiate view elements
      * @method _checkEmptyTable
      */
      _checkEmptyTable: function() {
        if(this.isEmptyTable()) {
          this.addEmptyTableInfo();
        } else {
          this.cleanEmptyTableInfo();
        }
      },

      /**
      * Adds the view elements associated with no content in the table
      * @method addemptyTableInfo
      */
      addEmptyTableInfo: function() {
        if(this.$('.noRows').length == 0) {
          this.elder('addEmptyTableInfo');

          this.$el.hide();
          var columnsNumber = this.model.get('schema').length;
          var columns = '
+	';
          for(var i = 1; i < columnsNumber; i++) {
            columns += '	';
          }
          columns += '
';
          var columnsFooter = '
';
          for(var i = 0; i < columnsNumber; i++) {
            columnsFooter += '	';
          }
          columnsFooter += '
';

          var $columns = $(columns+columnsFooter)
          this.$el.append($columns);

          this.template_base = cdb.templates.getTemplate('table/views/empty_table');
          var content = this.template_base(this.import_);
          var $footer = $('

'+content+'

');
          this.$el.append($footer);

          this.$el.fadeIn();
        }
      },

      /**
      * Removes from the view the no-content elements
      * @method cleanEmptyTableInfo
      */
      cleanEmptyTableInfo: function() {
        this.$('tfoot').fadeOut('fast', function() {
          $(this).remove();
        })
        this.$('.noRows').slideUp('fast', function() {
            $(this).remove();
        })
      },

      /**
      * Add a new row and removes the empty table view elemetns
      * @method addEmptyRow
      * @todo: (xabel) refactor this to include a "addRow" method in _models[0]
      */
      addEmptyRow: function() {
        this._models[0].table.data().addRow({ at: 0});
        this.cleanEmptyTableInfo();
      },

      /**
      * Captures the change event from the row and produces a notification
      * @method rowChanged
      * @todo (xabel) i'm pretty sure there has to be a less convulted way of doing this, without capturing a event
      * to throw another event in the model to be captured by some view
      */
      rowChanged: function() {
        this.model.notice('Saving your edit.');
      },

      /**
      * Captures the change event from the row and produces a notification
      * @method rowSynched
      * @todo (xabel) i'm pretty sure there has to be a less convulted way of doing this, without capturing a event
      * to throw another event in the model to be captured by some view
      */
      rowSynched: function() {
        this.model.notice('Sucessfully saved');
      },

      /**
      * Captures the change event from the row and produces a notification
      * @method rowSynched
      * @todo (xabel) i'm pretty sure there has to be a less convulted way of doing this, without capturing a event
      * to throw another event in the model to be captured by some view
      */
      rowFailed: function() {
        this.model.notice('Oops, there has been an error saving your changes.');
      }

    });

    cdb.admin.TableTab = cdb.core.View.extend({

      className: 'table',

      initialize: function() {
        this.tableView = new cdb.admin.TableView({
          dataModel: this.model.data(),
          model: this.model,
          sqlView: this.options.sqlView
        });

      },

      render: function() {
        this.$el.append(this.tableView.el);
        return this;
      }

    });

})();
<commit_msg>empty table notification not shown when filtered<commit_after>
(function() {

    /**
     * table view shown in admin
     */
    cdb.admin.TableView = cdb.ui.common.Table.extend({

      events: cdb.core.View.extendEvents({
          'click .sqlview .clearview': '_clearView',
          'click .sqlview .export_query': '_tableFromQuery',
          'click .noRows': 'addEmptyRow'
      }),

      rowView: cdb.admin.RowView,

      initialize: function() {
         var self = this;
         this.elder('initialize');
         this.options.row_header = true;
         this.model.data().bind('newPage', this.newPage, this);

          _.bindAll(this, "render", "addEmptyRow", "_checkEmptyTable", "rowChanged", "rowSynched", "rowFailed");
          window.a = this;
         var topReached = false;
         this._editorsOpened = null;

         // pagination
         setInterval(function() {
           if(!self.$el.is(":visible") || self.model.data().isFetchingPage()) {
             return;
           }
           var pos = $(this).scrollTop();
           var d = self.model.data();
           // do not let to fetch previous pages
           // until the user dont scroll back a little bit
           if(pos > 2) {
             topReached = false;
           }
           var pageSize = $(window).height() - self.$el.offset().top;
           var tableHeight = this.$('tbody').height();
           var realPos = pos + pageSize;
           if(tableHeight < pageSize) {
             return;
           }
           if(realPos > tableHeight) {
//              console.log(realPos, tableHeight, tableHeight - realPos);
              d.setPage(d.getPage() + 1);
           } else if (pos <= 0) {
             if(!topReached) {
               d.setPage(d.getPage() - 1);
             }
             topReached = true;
           }

         }, 2000);

        // Moving header and loaders when scrolls
        $(window).scroll(function(ev){
          // move header
          self.$el.find("thead > tr > th > div").css({marginLeft: -$(window).scrollLeft() + "px"});
        });

        this.model.data().bind('loadingRows', function(updown) {
          var fn = updown === 'up'? 'prepend': 'append';
          console.log('lalalla');
          self.$el[fn]("

Loading more rows

Now viewing 120 of 264

");
        });

        this.model.data().bind('endLoadingRows', function() {
          //self.$el.find('.page_loader').remove();
        });

        this.bind('cellDblClick', this._editCell, this);
        this.model.bind('change:dataSource', this._onSQLView, this);
        // when model changes the header is re rendered so the notice should be added
        this.model.bind('change', this._onSQLView, this);
        this._models[0].bind('remove', this._checkEmptyTable);
        this._models[0].bind('add', this._checkEmptyTable);

      },

      _onSQLView: function() {
        // if we are in a SQL view add a header
        this.$('.sqlview').remove();
        if(this.model.isInSQLView()) {
          this.$('thead').append(
            this.getTemplate('table/views/sql_view_notice')()
          );
          this.$('thead > tr').css('height', 64 + 42);
        }
      },

      _clearView: function(e) {
        e.preventDefault();
        this.model.useSQLView(null);
        return false;
      },

      _tableFromQuery: function(e) {
        var self = this;
        e.preventDefault();
        //this.model.useSQLView(null);
        var dlg = new cdb.admin.TableNameDialog({
          ok: function(name) {
            var sql = self.model.data().getSQL();
            alert('to be done in backend');
            /*
            var table = cdb.admin.CartoDBTableMetadata.createFromQuery(name, sql);

            table.save(null, {
              success: function() {
              },
              error: function() {
                cdb.log.error("problem creating table from query");
              }
            });
            */
          }
        });
        dlg.appendToBody().show();
        return false;
        /*
        from_query:SELECT * FROM cb_municipios_5000_e limit 1
        name:asdasdasd
        */
      },

      _getEditor: function(columnType, opts) {
        var editors = {
          'string': cdb.admin.EditStringDialog,
          'number': cdb.admin.EditNumberDialog,
          'date': cdb.admin.EditDateDialog,
          'geometry': cdb.admin.EditGeometryDialog,
          'boolean': cdb.admin.EditBooleanDialog
        };

        // clean previous if exits
        var view = this._editorsOpened;
        if(view) {
          view.clean();
        }

        var Editor = editors[columnType];
        this._editorsOpened = new Editor(opts);
        return this._editorsOpened;

      },

      _editCell: function(e, cell, x, y) {
        var self = this;
        if(this.model.data().isReadOnly()) {
          return;
        }
        var column = self.model.columnName(x-1);
        var columnType = this.model.getColumnType(column);

        if(this.model.isReservedColumn(column)) {
          return;
        }

        var row = self.model.data().getRowAt(y);
        var dlg = this._getEditor(columnType, {
          initial_value: self.model.data().getCell(y, column) || '',
          row: row,
          res: function(val) {
            var update = {};
            update[column] = val;
            row.set(update).save();
          }
        });

        if(!dlg) {
          cdb.log.error("editor not defined for column type " + columnType);
          return;
        }

        // auto add to table view
        // Check first if the row is the first or the cell is the last :)
        var $td = $(e.target).closest("td")
          , offset = $td.position()
          , width = $td.outerWidth();

        if ($td.parent().index() == 0) {
          offset.top += 5;
        } else {
          offset.top -= 11;
        }

        if ($td.index() == ($td.size() - 1)) {
          offset.left -= 22;
        } else {
          offset.left -= 11;
        }

        dlg.showAt(offset.left, offset.top, width, true);
      },

      /**
       * called when a new page is loaded
       */
      newPage: function(currentPage, direction) {
         var d = this.model.data();
         var rowspp = d.options.get('rows_per_page');
         var max_items = rowspp*4;
         if(d.size() > max_items) {
           var idx = currentPage*rowspp;
           cdb.log.debug("removing rows: " + d.size() + " " + idx);
           if(direction == 'up') {
             d.remove(d.models.slice(max_items, d.size()));
           } else {
             d.remove(d.models.slice(0, idx));
           }
         }
      },

      headerView: function(column) {
        if(column[1] !== 'header') {
          var v = new cdb.admin.HeaderView({
            column: column,
            table: this.model,
            sqlView: this.options.sqlView
          });
          this.addView(v);
          return v.render().el;
        } else {
          return '

';
        }
      },

      /**
      * Checks if the table has any rows, and if not, launch the method for showing the appropiate view elements
      * @method _checkEmptyTable
      */
      _checkEmptyTable: function() {
        if(this.isEmptyTable()) {
          this.addEmptyTableInfo();
        } else {
          this.cleanEmptyTableInfo();
        }
      },

      /**
      * Adds the view elements associated with no content in the table
      * @method addemptyTableInfo
      */
      addEmptyTableInfo: function() {
        if(this.$('.noRows').length == 0 && !this.model.isInSQLView()) {
          this.elder('addEmptyTableInfo');

          this.$el.hide();
          var columnsNumber = this.model.get('schema').length;
          var columns = '
+	';
          for(var i = 1; i < columnsNumber; i++) {
            columns += '	';
          }
          columns += '
';
          var columnsFooter = '
';
          for(var i = 0; i < columnsNumber; i++) {
            columnsFooter += '	';
          }
          columnsFooter += '
';

          var $columns = $(columns+columnsFooter)
          this.$el.append($columns);

          this.template_base = cdb.templates.getTemplate('table/views/empty_table');
          var content = this.template_base(this.import_);
          var $footer = $('

' + content + '

');
          this.$el.append($footer);

          this.$el.fadeIn();
        }
      },

      /**
      * Removes from the view the no-content elements
      * @method cleanEmptyTableInfo
      */
      cleanEmptyTableInfo: function() {
        this.$('tfoot').fadeOut('fast', function() {
          $(this).remove();
        })
        this.$('.noRows').slideUp('fast', function() {
            $(this).remove();
        })
      },

      /**
      * Add a new row and removes the empty table view elemetns
      * @method addEmptyRow
      * @todo: (xabel) refactor this to include a "addRow" method in _models[0]
      */
      addEmptyRow: function() {
        this._models[0].table.data().addRow({ at: 0});
        this.cleanEmptyTableInfo();
      },

      /**
      * Captures the change event from the row and produces a notification
      * @method rowChanged
      * @todo (xabel) i'm pretty sure there has to be a less convulted way of doing this, without capturing a event
      * to throw another event in the model to be captured by some view
      */
      rowChanged: function() {
        this.model.notice('Saving your edit.');
      },

      /**
      * Captures the change event from the row and produces a notification
      * @method rowSynched
      * @todo (xabel) i'm pretty sure there has to be a less convulted way of doing this, without capturing a event
      * to throw another event in the model to be captured by some view
      */
      rowSynched: function() {
        this.model.notice('Sucessfully saved');
      },

      /**
      * Captures the change event from the row and produces a notification
      * @method rowSynched
      * @todo (xabel) i'm pretty sure there has to be a less convulted way of doing this, without capturing a event
      * to throw another event in the model to be captured by some view
      */
      rowFailed: function() {
        this.model.notice('Oops, there has been an error saving your changes.');
      }

    });

    cdb.admin.TableTab = cdb.core.View.extend({

      className: 'table',

      initialize: function() {
        this.tableView = new cdb.admin.TableView({
          dataModel: this.model.data(),
          model: this.model,
          sqlView: this.options.sqlView
        });

      },

      render: function() {
        this.$el.append(this.tableView.el);
        return this;
      }

    });

})();
<|endoftext|>


<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import {CompositeDisposable} from 'event-kit';
import {graphql, createFragmentContainer} from 'react-relay';

import AggregatedReviewsContainer from '../containers/aggregated-reviews-container';
import EditorCommentDecorationsController from './editor-comment-decorations-controller';
import {EndpointPropType} from '../prop-types';

export class BareCommentDecorationsController extends React.Component {
  static propTypes = {
    endpoint: EndpointPropType.isRequired,
    owner: PropTypes.string.isRequired,
    repo: PropTypes.string.isRequired,

    workspace: PropTypes.object.isRequired,
    localRepository: PropTypes.object.isRequired,

    // Relay response
    relay: PropTypes.object.isRequired,
    results: PropTypes.arrayOf(PropTypes.object),
  };

  constructor(props, context) {
    super(props, context);

    this.state = {openEditors: this.props.workspace.getTextEditors()};
    this.subscriptions = new CompositeDisposable();
  }

  componentDidMount() {
    const updateState = () => {
      this.setState({
        openEditors: this.props.workspace.getTextEditors(),
      });
    };

    this.subscriptions.add(
      this.props.workspace.observeTextEditors(updateState),
      this.props.workspace.onDidDestroyPaneItem(updateState),
    );
  }

  // Determine if we already have this PR checked out.
  // todo: if this is similar enough to pr-checkout-controller, extract a single
  // helper function to do this check.
  isCheckedOutPullRequest(branches, remotes, pullRequest) {
    // determine if pullRequest.headRepository is null
    // this can happen if a repository has been deleted.
    if (!pullRequest.headRepository) {
      return false;
    }

    const {repository} = pullRequest;

    const headPush = branches.getHeadBranch().getPush();
    const headRemote = remotes.withName(headPush.getRemoteName());

    // (detect checkout from pull/### refspec)
    const fromPullRefspec =
      headRemote.getOwner() === repository.owner.login &&
      headRemote.getRepo() === repository.name &&
      headPush.getShortRemoteRef() === `pull/${pullRequest.number}/head`;

    // (detect checkout from head repository)
    const fromHeadRepo =
      headRemote.getOwner() === pullRequest.headRepository.owner.login &&
      headRemote.getRepo() === pullRequest.headRepository.name &&
      headPush.getShortRemoteRef() === pullRequest.headRefName;

    if (fromPullRefspec || fromHeadRepo) {
      return true;
    }
    return false;
  }

  render() {
    if (this.props.results.length === 0) {
      return null;
    }

    const pullRequest = this.props.results[0];

    // only show comment decorations if we're on a checked out pull request
    // otherwise, we'd have no way of knowing which comments to show.
    if (!this.isCheckedOutPullRequest(
      this.props.localRepository.branches,
      this.props.localRepository.remotes,
      pullRequest)) {
      return null;
    }

    return (
      <AggregatedReviewsContainer pullRequest={pullRequest}>
        {({errors, commentThreads}) => {
          if (errors.length > 0) {
            // eslint-disable-next-line no-console
            console.warn(`error fetching CommentDecorationsController data: ${errors}`);
          }

          const rootCommentsByPath = new Map();
          const workdirPath = this.props.localRepository.workingDirectoryPath;
          commentThreads.forEach(commentThread => {
            // there might be multiple comments in the thread but we really only
            // care about the root comment when rendering decorations
            const rootComment = commentThread.comments[0];

            const commentPath = `${workdirPath}/${rootComment.path}`;

            if (rootCommentsByPath.get(commentPath)) {
              rootCommentsByPath.get(commentPath).push(rootComment);
            } else {
              rootCommentsByPath.set(commentPath, [rootComment]);
            }
          });

          if (rootCommentsByPath.size === 0) {
            return null;
          }

          const openEditorsWithCommentThreads = this.getOpenEditorsWithCommentThreads(rootCommentsByPath);

          return openEditorsWithCommentThreads.map(editor => {
            return (
              <EditorCommentDecorationsController
                key={editor.id}
                endpoint={this.props.endpoint}
                owner={this.props.owner}
                repo={this.props.repo}
                number={pullRequest.number}
                workdir={workdirPath}
                workspace={this.props.workspace}
                editor={editor}
                fileName={editor.getPath()}
                headSha={pullRequest.headRefOid}
                comments={rootCommentsByPath.get(editor.getPath())}
              />
            );
          });
        }}
      </AggregatedReviewsContainer>
    );
  }

  getOpenEditorsWithCommentThreads(rootCommentsByPath) {
    return this.state.openEditors.filter(editor => rootCommentsByPath.get(editor.getPath()));
  }

  componentWillUnmount() {
    this.subscriptions.dispose();
  }
}

export default createFragmentContainer(BareCommentDecorationsController, {
  results: graphql`
    fragment commentDecorationsController_results on PullRequest
    @relay(plural: true)
    {
      ...aggregatedReviewsContainer_pullRequest @arguments(
        reviewCount: $reviewCount
        reviewCursor: $reviewCursor
        threadCount: $threadCount
        threadCursor: $threadCursor
        commentCount: $commentCount
        commentCursor: $commentCursor
      )
      number
      headRefName
      headRefOid
      headRepository {
        name
        owner {
          login
        }
      }
      repository {
        id
        owner {
          login
        }
      }
    }
  `,
});
<commit_msg>Append the thread ID to the fetched root comment properties<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import {CompositeDisposable} from 'event-kit';
import {graphql, createFragmentContainer} from 'react-relay';

import AggregatedReviewsContainer from '../containers/aggregated-reviews-container';
import EditorCommentDecorationsController from './editor-comment-decorations-controller';
import {EndpointPropType} from '../prop-types';

export class BareCommentDecorationsController extends React.Component {
  static propTypes = {
    endpoint: EndpointPropType.isRequired,
    owner: PropTypes.string.isRequired,
    repo: PropTypes.string.isRequired,

    workspace: PropTypes.object.isRequired,
    localRepository: PropTypes.object.isRequired,

    // Relay response
    relay: PropTypes.object.isRequired,
    results: PropTypes.arrayOf(PropTypes.object),
  };

  constructor(props, context) {
    super(props, context);

    this.state = {openEditors: this.props.workspace.getTextEditors()};
    this.subscriptions = new CompositeDisposable();
  }

  componentDidMount() {
    const updateState = () => {
      this.setState({
        openEditors: this.props.workspace.getTextEditors(),
      });
    };

    this.subscriptions.add(
      this.props.workspace.observeTextEditors(updateState),
      this.props.workspace.onDidDestroyPaneItem(updateState),
    );
  }

  // Determine if we already have this PR checked out.
  // todo: if this is similar enough to pr-checkout-controller, extract a single
  // helper function to do this check.
  isCheckedOutPullRequest(branches, remotes, pullRequest) {
    // determine if pullRequest.headRepository is null
    // this can happen if a repository has been deleted.
    if (!pullRequest.headRepository) {
      return false;
    }

    const {repository} = pullRequest;

    const headPush = branches.getHeadBranch().getPush();
    const headRemote = remotes.withName(headPush.getRemoteName());

    // (detect checkout from pull/### refspec)
    const fromPullRefspec =
      headRemote.getOwner() === repository.owner.login &&
      headRemote.getRepo() === repository.name &&
      headPush.getShortRemoteRef() === `pull/${pullRequest.number}/head`;

    // (detect checkout from head repository)
    const fromHeadRepo =
      headRemote.getOwner() === pullRequest.headRepository.owner.login &&
      headRemote.getRepo() === pullRequest.headRepository.name &&
      headPush.getShortRemoteRef() === pullRequest.headRefName;

    if (fromPullRefspec || fromHeadRepo) {
      return true;
    }
    return false;
  }

  render() {
    if (this.props.results.length === 0) {
      return null;
    }

    const pullRequest = this.props.results[0];

    // only show comment decorations if we're on a checked out pull request
    // otherwise, we'd have no way of knowing which comments to show.
    if (!this.isCheckedOutPullRequest(
      this.props.localRepository.branches,
      this.props.localRepository.remotes,
      pullRequest)) {
      return null;
    }

    return (
      <AggregatedReviewsContainer pullRequest={pullRequest}>
        {({errors, commentThreads}) => {
          if (errors.length > 0) {
            // eslint-disable-next-line no-console
            console.warn(`error fetching CommentDecorationsController data: ${errors}`);
          }

          const rootCommentsByPath = new Map();
          const workdirPath = this.props.localRepository.workingDirectoryPath;
          commentThreads.forEach(commentThread => {
            // there might be multiple comments in the thread but we really only
            // care about the root comment when rendering decorations
            const rootComment = {
              ...commentThread.comments[0],
              threadID: commentThread.thread.id,
            };

            const commentPath = `${workdirPath}/${rootComment.path}`;

            if (rootCommentsByPath.get(commentPath)) {
              rootCommentsByPath.get(commentPath).push(rootComment);
            } else {
              rootCommentsByPath.set(commentPath, [rootComment]);
            }
          });

          if (rootCommentsByPath.size === 0) {
            return null;
          }

          const openEditorsWithCommentThreads = this.getOpenEditorsWithCommentThreads(rootCommentsByPath);

          return openEditorsWithCommentThreads.map(editor => {
            return (
              <EditorCommentDecorationsController
                key={editor.id}
                endpoint={this.props.endpoint}
                owner={this.props.owner}
                repo={this.props.repo}
                number={pullRequest.number}
                workdir={workdirPath}
                workspace={this.props.workspace}
                editor={editor}
                fileName={editor.getPath()}
                headSha={pullRequest.headRefOid}
                comments={rootCommentsByPath.get(editor.getPath())}
              />
            );
          });
        }}
      </AggregatedReviewsContainer>
    );
  }

  getOpenEditorsWithCommentThreads(rootCommentsByPath) {
    return this.state.openEditors.filter(editor => rootCommentsByPath.get(editor.getPath()));
  }

  componentWillUnmount() {
    this.subscriptions.dispose();
  }
}

export default createFragmentContainer(BareCommentDecorationsController, {
  results: graphql`
    fragment commentDecorationsController_results on PullRequest
    @relay(plural: true)
    {
      ...aggregatedReviewsContainer_pullRequest @arguments(
        reviewCount: $reviewCount
        reviewCursor: $reviewCursor
        threadCount: $threadCount
        threadCursor: $threadCursor
        commentCount: $commentCount
        commentCursor: $commentCursor
      )
      number
      headRefName
      headRefOid
      headRepository {
        name
        owner {
          login
        }
      }
      repository {
        id
        owner {
          login
        }
      }
    }
  `,
});
<|endoftext|>


<commit_before>module.exports = {
	basePath: '../../../html/',
	outputDirectory: 'docs/indx-collection/',

	require: [
		'../lib/docs/abstracts/*',
		'js/indx.js'
	],

	files: [
		'js/indx-collection.js'
	],

	project: {
		title: 'INDX Collection',
		version: '0.01',
		description: ''
	},

	template: 'clean'
};
<commit_msg>corrected path in manifest<commit_after>module.exports = {
	basePath: '../../html/',
	outputDirectory: 'docs/indx-collection/',

	require: [
		'../lib/docs/abstracts/*',
		'js/indx.js'
	],

	files: [
		'js/indx-collection.js'
	],

	project: {
		title: 'INDX Collection',
		version: '0.01',
		description: ''
	},

	template: 'clean'
};
<|endoftext|>


<commit_before>/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/

"use strict";

var $installedChunks$ = undefined;
var $loadUpdateChunk$ = undefined;
var $moduleCache$ = undefined;
var $moduleFactories$ = undefined;
var $ensureChunkHandlers$ = undefined;
var $hasOwnProperty$ = undefined;
var $hmrModuleData$ = undefined;
var $hmrDownloadUpdateHandlers$ = undefined;
var $hmrInvalidateModuleHandlers$ = undefined;
var __webpack_require__ = undefined;

module.exports = function () {
	var currentUpdateChunks;
	var currentUpdate;
	var currentUpdateRemovedChunks;
	var currentUpdateRuntime;
	function applyHandler(options) {
		if ($ensureChunkHandlers$) delete $ensureChunkHandlers$.$key$Hmr;
		currentUpdateChunks = undefined;
		function getAffectedModuleEffects(updateModuleId) {
			var outdatedModules = [updateModuleId];
			var outdatedDependencies = {};

			var queue = outdatedModules.map(function (id) {
				return {
					chain: [id],
					id: id
				};
			});
			while (queue.length > 0) {
				var queueItem = queue.pop();
				var moduleId = queueItem.id;
				var chain = queueItem.chain;
				var module = $moduleCache$[moduleId];
				if (
					!module ||
					(module.hot._selfAccepted && !module.hot._selfInvalidated)
				)
					continue;
				if (module.hot._selfDeclined) {
					return {
						type: "self-declined",
						chain: chain,
						moduleId: moduleId
					};
				}
				if (module.hot._main) {
					return {
						type: "unaccepted",
						chain: chain,
						moduleId: moduleId
					};
				}
				for (var i = 0; i < module.parents.length; i++) {
					var parentId = module.parents[i];
					var parent = $moduleCache$[parentId];
					if (!parent) continue;
					if (parent.hot._declinedDependencies[moduleId]) {
						return {
							type: "declined",
							chain: chain.concat([parentId]),
							moduleId: moduleId,
							parentId: parentId
						};
					}
					if (outdatedModules.indexOf(parentId) !== -1) continue;
					if (parent.hot._acceptedDependencies[moduleId]) {
						if (!outdatedDependencies[parentId])
							outdatedDependencies[parentId] = [];
						addAllToSet(outdatedDependencies[parentId], [moduleId]);
						continue;
					}
					delete outdatedDependencies[parentId];
					outdatedModules.push(parentId);
					queue.push({
						chain: chain.concat([parentId]),
						id: parentId
					});
				}
			}

			return {
				type: "accepted",
				moduleId: updateModuleId,
				outdatedModules: outdatedModules,
				outdatedDependencies: outdatedDependencies
			};
		}

		function addAllToSet(a, b) {
			for (var i = 0; i < b.length; i++) {
				var item = b[i];
				if (a.indexOf(item) === -1) a.push(item);
			}
		}

		// at begin all updates modules are outdated
		// the "outdated" status can propagate to parents if they don't accept the children
		var outdatedDependencies = {};
		var outdatedModules = [];
		var appliedUpdate = {};

		var warnUnexpectedRequire = function warnUnexpectedRequire() {
			console.warn(
				"[HMR] unexpected require(" + result.moduleId + ") to disposed module"
			);
		};

		for (var moduleId in currentUpdate) {
			if ($hasOwnProperty$(currentUpdate, moduleId)) {
				var newModuleFactory = currentUpdate[moduleId];
				/** @type {TODO} */
				var result;
				if (newModuleFactory) {
					result = getAffectedModuleEffects(moduleId);
				} else {
					result = {
						type: "disposed",
						moduleId: moduleId
					};
				}
				/** @type {Error|false} */
				var abortError = false;
				var doApply = false;
				var doDispose = false;
				var chainInfo = "";
				if (result.chain) {
					chainInfo = "\nUpdate propagation: " + result.chain.join(" -> ");
				}
				switch (result.type) {
					case "self-declined":
						if (options.onDeclined) options.onDeclined(result);
						if (!options.ignoreDeclined)
							abortError = new Error(
								"Aborted because of self decline: " +
									result.moduleId +
									chainInfo
							);
						break;
					case "declined":
						if (options.onDeclined) options.onDeclined(result);
						if (!options.ignoreDeclined)
							abortError = new Error(
								"Aborted because of declined dependency: " +
									result.moduleId +
									" in " +
									result.parentId +
									chainInfo
							);
						break;
					case "unaccepted":
						if (options.onUnaccepted) options.onUnaccepted(result);
						if (!options.ignoreUnaccepted)
							abortError = new Error(
								"Aborted because " + moduleId + " is not accepted" + chainInfo
							);
						break;
					case "accepted":
						if (options.onAccepted) options.onAccepted(result);
						doApply = true;
						break;
					case "disposed":
						if (options.onDisposed) options.onDisposed(result);
						doDispose = true;
						break;
					default:
						throw new Error("Unexception type " + result.type);
				}
				if (abortError) {
					return {
						error: abortError
					};
				}
				if (doApply) {
					appliedUpdate[moduleId] = newModuleFactory;
					addAllToSet(outdatedModules, result.outdatedModules);
					for (moduleId in result.outdatedDependencies) {
						if ($hasOwnProperty$(result.outdatedDependencies, moduleId)) {
							if (!outdatedDependencies[moduleId])
								outdatedDependencies[moduleId] = [];
							addAllToSet(
								outdatedDependencies[moduleId],
								result.outdatedDependencies[moduleId]
							);
						}
					}
				}
				if (doDispose) {
					addAllToSet(outdatedModules, [result.moduleId]);
					appliedUpdate[moduleId] = warnUnexpectedRequire;
				}
			}
		}
		currentUpdate = undefined;

		// Store self accepted outdated modules to require them later by the module system
		var outdatedSelfAcceptedModules = [];
		for (var j = 0; j < outdatedModules.length; j++) {
			var outdatedModuleId = outdatedModules[j];
			if (
				$moduleCache$[outdatedModuleId] &&
				$moduleCache$[outdatedModuleId].hot._selfAccepted &&
				// removed self-accepted modules should not be required
				appliedUpdate[outdatedModuleId] !== warnUnexpectedRequire &&
				// when called invalidate self-accepting is not possible
				!$moduleCache$[outdatedModuleId].hot._selfInvalidated
			) {
				outdatedSelfAcceptedModules.push({
					module: outdatedModuleId,
					require: $moduleCache$[outdatedModuleId].hot._requireSelf,
					errorHandler: $moduleCache$[outdatedModuleId].hot._selfAccepted
				});
			}
		}

		var moduleOutdatedDependencies;

		return {
			dispose: function () {
				currentUpdateRemovedChunks.forEach(function (chunkId) {
					delete $installedChunks$[chunkId];
				});
				currentUpdateRemovedChunks = undefined;

				var idx;
				var queue = outdatedModules.slice();
				while (queue.length > 0) {
					var moduleId = queue.pop();
					var module = $moduleCache$[moduleId];
					if (!module) continue;

					var data = {};

					// Call dispose handlers
					var disposeHandlers = module.hot._disposeHandlers;
					for (j = 0; j < disposeHandlers.length; j++) {
						disposeHandlers[j].call(null, data);
					}
					$hmrModuleData$[moduleId] = data;

					// disable module (this disables requires from this module)
					module.hot.active = false;

					// remove module from cache
					delete $moduleCache$[moduleId];

					// when disposing there is no need to call dispose handler
					delete outdatedDependencies[moduleId];

					// remove "parents" references from all children
					for (j = 0; j < module.children.length; j++) {
						var child = $moduleCache$[module.children[j]];
						if (!child) continue;
						idx = child.parents.indexOf(moduleId);
						if (idx >= 0) {
							child.parents.splice(idx, 1);
						}
					}
				}

				// remove outdated dependency from module children
				var dependency;
				for (var outdatedModuleId in outdatedDependencies) {
					if ($hasOwnProperty$(outdatedDependencies, outdatedModuleId)) {
						module = $moduleCache$[outdatedModuleId];
						if (module) {
							moduleOutdatedDependencies =
								outdatedDependencies[outdatedModuleId];
							for (j = 0; j < moduleOutdatedDependencies.length; j++) {
								dependency = moduleOutdatedDependencies[j];
								idx = module.children.indexOf(dependency);
								if (idx >= 0) module.children.splice(idx, 1);
							}
						}
					}
				}
			},
			apply: function (reportError) {
				// insert new code
				for (var updateModuleId in appliedUpdate) {
					if ($hasOwnProperty$(appliedUpdate, updateModuleId)) {
						$moduleFactories$[updateModuleId] = appliedUpdate[updateModuleId];
					}
				}

				// run new runtime modules
				for (var i = 0; i < currentUpdateRuntime.length; i++) {
					currentUpdateRuntime[i](__webpack_require__);
				}

				// call accept handlers
				for (var outdatedModuleId in outdatedDependencies) {
					if ($hasOwnProperty$(outdatedDependencies, outdatedModuleId)) {
						var module = $moduleCache$[outdatedModuleId];
						if (module) {
							moduleOutdatedDependencies =
								outdatedDependencies[outdatedModuleId];
							var callbacks = [];
							var dependenciesForCallbacks = [];
							for (var j = 0; j < moduleOutdatedDependencies.length; j++) {
								var dependency = moduleOutdatedDependencies[j];
								var acceptCallback =
									module.hot._acceptedDependencies[dependency];
								if (acceptCallback) {
									if (callbacks.indexOf(acceptCallback) !== -1) continue;
									callbacks.push(acceptCallback);
									dependenciesForCallbacks.push(dependency);
								}
							}
							for (var k = 0; k < callbacks.length; k++) {
								try {
									callbacks[k].call(null, moduleOutdatedDependencies);
								} catch (err) {
									if (options.onErrored) {
										options.onErrored({
											type: "accept-errored",
											moduleId: outdatedModuleId,
											dependencyId: dependenciesForCallbacks[k],
											error: err
										});
									}
									if (!options.ignoreErrored) {
										reportError(err);
									}
								}
							}
						}
					}
				}

				// Load self accepted modules
				for (var o = 0; o < outdatedSelfAcceptedModules.length; o++) {
					var item = outdatedSelfAcceptedModules[o];
					var moduleId = item.module;
					try {
						item.require(moduleId);
					} catch (err) {
						if (typeof item.errorHandler === "function") {
							try {
								item.errorHandler(err);
							} catch (err2) {
								if (options.onErrored) {
									options.onErrored({
										type: "self-accept-error-handler-errored",
										moduleId: moduleId,
										error: err2,
										originalError: err
									});
								}
								if (!options.ignoreErrored) {
									reportError(err2);
								}
								reportError(err);
							}
						} else {
							if (options.onErrored) {
								options.onErrored({
									type: "self-accept-errored",
									moduleId: moduleId,
									error: err
								});
							}
							if (!options.ignoreErrored) {
								reportError(err);
							}
						}
					}
				}

				return outdatedModules;
			}
		};
	}
	$hmrInvalidateModuleHandlers$.$key$ = function (moduleId, applyHandlers) {
		if (!currentUpdate) {
			currentUpdate = {};
			currentUpdateRuntime = [];
			currentUpdateRemovedChunks = [];
			applyHandlers.push(applyHandler);
		}
		if (!$hasOwnProperty$(currentUpdate, moduleId)) {
			currentUpdate[moduleId] = $moduleFactories$[moduleId];
		}
	};
	$hmrDownloadUpdateHandlers$.$key$ = function (
		chunkIds,
		removedChunks,
		removedModules,
		promises,
		applyHandlers,
		updatedModulesList
	) {
		applyHandlers.push(applyHandler);
		currentUpdateChunks = {};
		currentUpdateRemovedChunks = removedChunks;
		currentUpdate = removedModules.reduce(function (obj, key) {
			obj[key] = false;
			return obj;
		}, {});
		currentUpdateRuntime = [];
		chunkIds.forEach(function (chunkId) {
			if (
				$hasOwnProperty$($installedChunks$, chunkId) &&
				$installedChunks$[chunkId] !== undefined
			) {
				promises.push($loadUpdateChunk$(chunkId, updatedModulesList));
				currentUpdateChunks[chunkId] = true;
			}
		});
		if ($ensureChunkHandlers$) {
			$ensureChunkHandlers$.$key$Hmr = function (chunkId, promises) {
				if (
					currentUpdateChunks &&
					!$hasOwnProperty$(currentUpdateChunks, chunkId) &&
					$hasOwnProperty$($installedChunks$, chunkId) &&
					$installedChunks$[chunkId] !== undefined
				) {
					promises.push($loadUpdateChunk$(chunkId));
					currentUpdateChunks[chunkId] = true;
				}
			};
		}
	};
};
<commit_msg>fix: warnUnexpectedRequire binds wrong variable in for-loop<commit_after>/*
	MIT License http://www.opensource.org/licenses/mit-license.php
	Author Tobias Koppers @sokra
*/

"use strict";

var $installedChunks$ = undefined;
var $loadUpdateChunk$ = undefined;
var $moduleCache$ = undefined;
var $moduleFactories$ = undefined;
var $ensureChunkHandlers$ = undefined;
var $hasOwnProperty$ = undefined;
var $hmrModuleData$ = undefined;
var $hmrDownloadUpdateHandlers$ = undefined;
var $hmrInvalidateModuleHandlers$ = undefined;
var __webpack_require__ = undefined;

module.exports = function () {
	var currentUpdateChunks;
	var currentUpdate;
	var currentUpdateRemovedChunks;
	var currentUpdateRuntime;
	function applyHandler(options) {
		if ($ensureChunkHandlers$) delete $ensureChunkHandlers$.$key$Hmr;
		currentUpdateChunks = undefined;
		function getAffectedModuleEffects(updateModuleId) {
			var outdatedModules = [updateModuleId];
			var outdatedDependencies = {};

			var queue = outdatedModules.map(function (id) {
				return {
					chain: [id],
					id: id
				};
			});
			while (queue.length > 0) {
				var queueItem = queue.pop();
				var moduleId = queueItem.id;
				var chain = queueItem.chain;
				var module = $moduleCache$[moduleId];
				if (
					!module ||
					(module.hot._selfAccepted && !module.hot._selfInvalidated)
				)
					continue;
				if (module.hot._selfDeclined) {
					return {
						type: "self-declined",
						chain: chain,
						moduleId: moduleId
					};
				}
				if (module.hot._main) {
					return {
						type: "unaccepted",
						chain: chain,
						moduleId: moduleId
					};
				}
				for (var i = 0; i < module.parents.length; i++) {
					var parentId = module.parents[i];
					var parent = $moduleCache$[parentId];
					if (!parent) continue;
					if (parent.hot._declinedDependencies[moduleId]) {
						return {
							type: "declined",
							chain: chain.concat([parentId]),
							moduleId: moduleId,
							parentId: parentId
						};
					}
					if (outdatedModules.indexOf(parentId) !== -1) continue;
					if (parent.hot._acceptedDependencies[moduleId]) {
						if (!outdatedDependencies[parentId])
							outdatedDependencies[parentId] = [];
						addAllToSet(outdatedDependencies[parentId], [moduleId]);
						continue;
					}
					delete outdatedDependencies[parentId];
					outdatedModules.push(parentId);
					queue.push({
						chain: chain.concat([parentId]),
						id: parentId
					});
				}
			}

			return {
				type: "accepted",
				moduleId: updateModuleId,
				outdatedModules: outdatedModules,
				outdatedDependencies: outdatedDependencies
			};
		}

		function addAllToSet(a, b) {
			for (var i = 0; i < b.length; i++) {
				var item = b[i];
				if (a.indexOf(item) === -1) a.push(item);
			}
		}

		// at begin all updates modules are outdated
		// the "outdated" status can propagate to parents if they don't accept the children
		var outdatedDependencies = {};
		var outdatedModules = [];
		var appliedUpdate = {};

		var warnUnexpectedRequire = function warnUnexpectedRequire(moduleId) {
			console.warn(
				"[HMR] unexpected require(" + moduleId + ") to disposed module"
			);
		};

		for (var moduleId in currentUpdate) {
			if ($hasOwnProperty$(currentUpdate, moduleId)) {
				var newModuleFactory = currentUpdate[moduleId];
				/** @type {TODO} */
				var result;
				if (newModuleFactory) {
					result = getAffectedModuleEffects(moduleId);
				} else {
					result = {
						type: "disposed",
						moduleId: moduleId
					};
				}
				/** @type {Error|false} */
				var abortError = false;
				var doApply = false;
				var doDispose = false;
				var chainInfo = "";
				if (result.chain) {
					chainInfo = "\nUpdate propagation: " + result.chain.join(" -> ");
				}
				switch (result.type) {
					case "self-declined":
						if (options.onDeclined) options.onDeclined(result);
						if (!options.ignoreDeclined)
							abortError = new Error(
								"Aborted because of self decline: " +
									result.moduleId +
									chainInfo
							);
						break;
					case "declined":
						if (options.onDeclined) options.onDeclined(result);
						if (!options.ignoreDeclined)
							abortError = new Error(
								"Aborted because of declined dependency: " +
									result.moduleId +
									" in " +
									result.parentId +
									chainInfo
							);
						break;
					case "unaccepted":
						if (options.onUnaccepted) options.onUnaccepted(result);
						if (!options.ignoreUnaccepted)
							abortError = new Error(
								"Aborted because " + moduleId + " is not accepted" + chainInfo
							);
						break;
					case "accepted":
						if (options.onAccepted) options.onAccepted(result);
						doApply = true;
						break;
					case "disposed":
						if (options.onDisposed) options.onDisposed(result);
						doDispose = true;
						break;
					default:
						throw new Error("Unexception type " + result.type);
				}
				if (abortError) {
					return {
						error: abortError
					};
				}
				if (doApply) {
					appliedUpdate[moduleId] = newModuleFactory;
					addAllToSet(outdatedModules, result.outdatedModules);
					for (moduleId in result.outdatedDependencies) {
						if ($hasOwnProperty$(result.outdatedDependencies, moduleId)) {
							if (!outdatedDependencies[moduleId])
								outdatedDependencies[moduleId] = [];
							addAllToSet(
								outdatedDependencies[moduleId],
								result.outdatedDependencies[moduleId]
							);
						}
					}
				}
				if (doDispose) {
					addAllToSet(outdatedModules, [result.moduleId]);
					appliedUpdate[moduleId] = warnUnexpectedRequire.bind(
						null,
						result.moduleId
					);
					appliedUpdate[moduleId].isDisposed = true;
				}
			}
		}
		currentUpdate = undefined;

		// Store self accepted outdated modules to require them later by the module system
		var outdatedSelfAcceptedModules = [];
		for (var j = 0; j < outdatedModules.length; j++) {
			var outdatedModuleId = outdatedModules[j];
			if (
				$moduleCache$[outdatedModuleId] &&
				$moduleCache$[outdatedModuleId].hot._selfAccepted &&
				// removed self-accepted modules should not be required
				(!appliedUpdate[outdatedModuleId] ||
					!appliedUpdate[outdatedModuleId].isDisposed) &&
				// when called invalidate self-accepting is not possible
				!$moduleCache$[outdatedModuleId].hot._selfInvalidated
			) {
				outdatedSelfAcceptedModules.push({
					module: outdatedModuleId,
					require: $moduleCache$[outdatedModuleId].hot._requireSelf,
					errorHandler: $moduleCache$[outdatedModuleId].hot._selfAccepted
				});
			}
		}

		var moduleOutdatedDependencies;

		return {
			dispose: function () {
				currentUpdateRemovedChunks.forEach(function (chunkId) {
					delete $installedChunks$[chunkId];
				});
				currentUpdateRemovedChunks = undefined;

				var idx;
				var queue = outdatedModules.slice();
				while (queue.length > 0) {
					var moduleId = queue.pop();
					var module = $moduleCache$[moduleId];
					if (!module) continue;

					var data = {};

					// Call dispose handlers
					var disposeHandlers = module.hot._disposeHandlers;
					for (j = 0; j < disposeHandlers.length; j++) {
						disposeHandlers[j].call(null, data);
					}
					$hmrModuleData$[moduleId] = data;

					// disable module (this disables requires from this module)
					module.hot.active = false;

					// remove module from cache
					delete $moduleCache$[moduleId];

					// when disposing there is no need to call dispose handler
					delete outdatedDependencies[moduleId];

					// remove "parents" references from all children
					for (j = 0; j < module.children.length; j++) {
						var child = $moduleCache$[module.children[j]];
						if (!child) continue;
						idx = child.parents.indexOf(moduleId);
						if (idx >= 0) {
							child.parents.splice(idx, 1);
						}
					}
				}

				// remove outdated dependency from module children
				var dependency;
				for (var outdatedModuleId in outdatedDependencies) {
					if ($hasOwnProperty$(outdatedDependencies, outdatedModuleId)) {
						module = $moduleCache$[outdatedModuleId];
						if (module) {
							moduleOutdatedDependencies =
								outdatedDependencies[outdatedModuleId];
							for (j = 0; j < moduleOutdatedDependencies.length; j++) {
								dependency = moduleOutdatedDependencies[j];
								idx = module.children.indexOf(dependency);
								if (idx >= 0) module.children.splice(idx, 1);
							}
						}
					}
				}
			},
			apply: function (reportError) {
				// insert new code
				for (var updateModuleId in appliedUpdate) {
					if ($hasOwnProperty$(appliedUpdate, updateModuleId)) {
						$moduleFactories$[updateModuleId] = appliedUpdate[updateModuleId];
					}
				}

				// run new runtime modules
				for (var i = 0; i < currentUpdateRuntime.length; i++) {
					currentUpdateRuntime[i](__webpack_require__);
				}

				// call accept handlers
				for (var outdatedModuleId in outdatedDependencies) {
					if ($hasOwnProperty$(outdatedDependencies, outdatedModuleId)) {
						var module = $moduleCache$[outdatedModuleId];
						if (module) {
							moduleOutdatedDependencies =
								outdatedDependencies[outdatedModuleId];
							var callbacks = [];
							var dependenciesForCallbacks = [];
							for (var j = 0; j < moduleOutdatedDependencies.length; j++) {
								var dependency = moduleOutdatedDependencies[j];
								var acceptCallback =
									module.hot._acceptedDependencies[dependency];
								if (acceptCallback) {
									if (callbacks.indexOf(acceptCallback) !== -1) continue;
									callbacks.push(acceptCallback);
									dependenciesForCallbacks.push(dependency);
								}
							}
							for (var k = 0; k < callbacks.length; k++) {
								try {
									callbacks[k].call(null, moduleOutdatedDependencies);
								} catch (err) {
									if (options.onErrored) {
										options.onErrored({
											type: "accept-errored",
											moduleId: outdatedModuleId,
											dependencyId: dependenciesForCallbacks[k],
											error: err
										});
									}
									if (!options.ignoreErrored) {
										reportError(err);
									}
								}
							}
						}
					}
				}

				// Load self accepted modules
				for (var o = 0; o < outdatedSelfAcceptedModules.length; o++) {
					var item = outdatedSelfAcceptedModules[o];
					var moduleId = item.module;
					try {
						item.require(moduleId);
					} catch (err) {
						if (typeof item.errorHandler === "function") {
							try {
								item.errorHandler(err);
							} catch (err2) {
								if (options.onErrored) {
									options.onErrored({
										type: "self-accept-error-handler-errored",
										moduleId: moduleId,
										error: err2,
										originalError: err
									});
								}
								if (!options.ignoreErrored) {
									reportError(err2);
								}
								reportError(err);
							}
						} else {
							if (options.onErrored) {
								options.onErrored({
									type: "self-accept-errored",
									moduleId: moduleId,
									error: err
								});
							}
							if (!options.ignoreErrored) {
								reportError(err);
							}
						}
					}
				}

				return outdatedModules;
			}
		};
	}
	$hmrInvalidateModuleHandlers$.$key$ = function (moduleId, applyHandlers) {
		if (!currentUpdate) {
			currentUpdate = {};
			currentUpdateRuntime = [];
			currentUpdateRemovedChunks = [];
			applyHandlers.push(applyHandler);
		}
		if (!$hasOwnProperty$(currentUpdate, moduleId)) {
			currentUpdate[moduleId] = $moduleFactories$[moduleId];
		}
	};
	$hmrDownloadUpdateHandlers$.$key$ = function (
		chunkIds,
		removedChunks,
		removedModules,
		promises,
		applyHandlers,
		updatedModulesList
	) {
		applyHandlers.push(applyHandler);
		currentUpdateChunks = {};
		currentUpdateRemovedChunks = removedChunks;
		currentUpdate = removedModules.reduce(function (obj, key) {
			obj[key] = false;
			return obj;
		}, {});
		currentUpdateRuntime = [];
		chunkIds.forEach(function (chunkId) {
			if (
				$hasOwnProperty$($installedChunks$, chunkId) &&
				$installedChunks$[chunkId] !== undefined
			) {
				promises.push($loadUpdateChunk$(chunkId, updatedModulesList));
				currentUpdateChunks[chunkId] = true;
			}
		});
		if ($ensureChunkHandlers$) {
			$ensureChunkHandlers$.$key$Hmr = function (chunkId, promises) {
				if (
					currentUpdateChunks &&
					!$hasOwnProperty$(currentUpdateChunks, chunkId) &&
					$hasOwnProperty$($installedChunks$, chunkId) &&
					$installedChunks$[chunkId] !== undefined
				) {
					promises.push($loadUpdateChunk$(chunkId));
					currentUpdateChunks[chunkId] = true;
				}
			};
		}
	};
};
<|endoftext|>


<commit_before>// @flow

import moment from 'moment'
import React, {Component} from 'react'
import {Row, Col, Tabs, Tab, ListGroupItem, Label} from 'react-bootstrap'
import numeral from 'numeral'

import {getComponentMessages, isModuleEnabled} from '../../../common/util/config'
import Patterns from '../reporter/containers/Patterns'
import Routes from '../reporter/containers/Routes'
import Stops from '../reporter/containers/Stops'
import Timetables from '../reporter/containers/Timetables'
import ServicePerModeChart from '../validation/ServicePerModeChart'
import TripsChart from '../validation/TripsChart'
import FeedVersionAccessibility from './FeedVersionAccessibility'

import type {Element} from 'react'

import type {FeedVersion} from '../../../types'

type Props = {
  comparedVersion: FeedVersion,
  comparedVersionIndex: number,
  feedVersionIndex: number,
  isochroneBand: any,
  onChangeIsochroneBand: number => void,
  selectTab: string => void,
  tab: string,
  version: FeedVersion
}

export default class FeedVersionTabs extends Component<Props> {
  messages = getComponentMessages('FeedVersionTabs')

  _onClickTab = (key: string) => {
    if (this.props.tab !== key) {
      this.props.selectTab(key)
    }
  }

  renderValidatorTabs = (
    version: any,
    feedVersionIndex: number,
    isochroneBand: any,
    onChangeIsochroneBand: number => void
  ) => {
    type ValidatorTab = {
      component: Element<*>,
      key: string,
      title: string
    }
    const VALIDATOR_TABS: Array<ValidatorTab> = []
    if (isModuleEnabled('validator')) {
      // Show accessibility isochrones if validator enabled
      VALIDATOR_TABS.push({
        title: 'Accessibility',
        key: 'accessibility',
        component: <FeedVersionAccessibility
          isochroneBand={isochroneBand}
          changeIsochroneBand={onChangeIsochroneBand}
          version={version} />
      })
    }
    return (VALIDATOR_TABS.map(t => (
      <Tab eventKey={t.key} title={t.title} key={t.key}>
        {t.component}
      </Tab>
    )): Array<Element<*>>)
  }

  render () {
    const {
      feedVersionIndex,
      comparedVersionIndex,
      isochroneBand,
      onChangeIsochroneBand,
      tab,
      version,
      comparedVersion
    } = this.props
    const tableOptions = {
      striped: true,
      hover: true,
      exportCSV: true,
      pagination: true,
      options: {
        paginationShowsTotal: true,
        sizePerPageList: [10, 20, 50, 100]
      }
    }
    const timeTableOptions = {...tableOptions}
    // Add default page zie for timetable options
    timeTableOptions.options = {...timeTableOptions.options, sizePerPage: 50}
    const countFields = ['agencyCount', 'routeCount', 'stopCount', 'tripCount', 'stopTimesCount' /*, 'errorCount'*/]
    const daysActive = moment(version.validationSummary.endDate)
      .diff(moment(version.validationSummary.startDate), 'days')
    return (
      <ListGroupItem>
        {/* Tabs - Summary, Routes, Patterns, Stops, (Validation, Accessibility, Timeline) */}
        <Tabs
          activeKey={tab}
          onSelect={this._onClickTab}
          id='validator-tabs'
          bsStyle='pills'
          unmountOnExit>
          <Tab eventKey={'feed'} title='Summary'>
            <Row>
              {countFields.map(c => {
                const summary = version.validationSummary
                const diff = comparedVersion ? (summary[c] - comparedVersion.validationSummary[c]) : 0

                return (
                  <Col xs={2} className='text-center' key={c}>
                    <div
                      title={`${summary[c]}` /* do we need this? */}
                      style={{marginBottom: '0px', fontSize: '200%'}}>
                      {numeral(summary[c]).format('0a')}
                      {comparedVersion
                        ?
                           0 ? 'success' : (diff < 0 ? 'danger' : 'default')}
                            title={`Compared to Version ${comparedVersionIndex}`}>
                            {diff === 0 ? '=' : ((diff > 0 ? '+' : '') + numeral(diff).format('0a')) /* refactor */}

                        : null}

{this.messages(c)}

                  </Col>
                )
              })}
              <Col xs={2} className='text-center'>

                  {numeral(daysActive).format('0 a')}

{this.messages('daysActive')}

              </Col>
            </Row>

              <Row>
                <Col xs={12}>

Number of trips per date.

                </Col>
              </Row>
              <TripsChart validationResult={version.validationResult} />
              <Row>
                <Col xs={12}>

Service hours per date by mode.

                </Col>
              </Row>
              <ServicePerModeChart validationResult={version.validationResult} />

          </Tab>
          <Tab eventKey={'routes'} title='Routes'>
            <Routes
              version={version}
              selectTab={this.props.selectTab}
              tableOptions={tableOptions} />
          </Tab>
          <Tab eventKey={'patterns'} title='Patterns'>
            <Patterns
              version={version}
              selectTab={this.props.selectTab}
              tableOptions={tableOptions} />
          </Tab>
          <Tab eventKey={'stops'} title='Stops'>
            <Stops
              version={version}
              selectTab={this.props.selectTab}
              tableOptions={{...tableOptions, search: true}} />
          </Tab>
          <Tab eventKey={'timetables'} title='Timetables'>
            <Timetables
              version={version}
              selectTab={this.props.selectTab}
              tableOptions={timeTableOptions} />
          </Tab>
          {this.renderValidatorTabs(version, feedVersionIndex, isochroneBand, onChangeIsochroneBand)}
        </Tabs>
      </ListGroupItem>
    )
  }
}
<commit_msg>fix(FeedVersionTabs): Fix github lint checks<commit_after>// @flow

import moment from 'moment'
import React, {Component} from 'react'
import {Row, Col, Tabs, Tab, ListGroupItem, Label} from 'react-bootstrap'
import numeral from 'numeral'

import {getComponentMessages, isModuleEnabled} from '../../../common/util/config'
import Patterns from '../reporter/containers/Patterns'
import Routes from '../reporter/containers/Routes'
import Stops from '../reporter/containers/Stops'
import Timetables from '../reporter/containers/Timetables'
import ServicePerModeChart from '../validation/ServicePerModeChart'
import TripsChart from '../validation/TripsChart'
import FeedVersionAccessibility from './FeedVersionAccessibility'

import type {Element} from 'react'

import type {FeedVersion} from '../../../types'

type Props = {
  comparedVersion: FeedVersion,
  comparedVersionIndex: number,
  feedVersionIndex: number,
  isochroneBand: any,
  onChangeIsochroneBand: number => void,
  selectTab: string => void,
  tab: string,
  version: FeedVersion
}

export default class FeedVersionTabs extends Component<Props> {
  messages = getComponentMessages('FeedVersionTabs')

  _onClickTab = (key: string) => {
    if (this.props.tab !== key) {
      this.props.selectTab(key)
    }
  }

  renderValidatorTabs = (
    version: any,
    feedVersionIndex: number,
    isochroneBand: any,
    onChangeIsochroneBand: number => void
  ) => {
    type ValidatorTab = {
      component: Element<*>,
      key: string,
      title: string
    }
    const VALIDATOR_TABS: Array<ValidatorTab> = []
    if (isModuleEnabled('validator')) {
      // Show accessibility isochrones if validator enabled
      VALIDATOR_TABS.push({
        title: 'Accessibility',
        key: 'accessibility',
        component: <FeedVersionAccessibility
          isochroneBand={isochroneBand}
          changeIsochroneBand={onChangeIsochroneBand}
          version={version} />
      })
    }
    return (VALIDATOR_TABS.map(t => (
      <Tab eventKey={t.key} title={t.title} key={t.key}>
        {t.component}
      </Tab>
    )): Array<Element<*>>)
  }

  render () {
    const {
      feedVersionIndex,
      comparedVersionIndex,
      isochroneBand,
      onChangeIsochroneBand,
      tab,
      version,
      comparedVersion
    } = this.props
    const tableOptions = {
      striped: true,
      hover: true,
      exportCSV: true,
      pagination: true,
      options: {
        paginationShowsTotal: true,
        sizePerPageList: [10, 20, 50, 100]
      }
    }
    const timeTableOptions = {...tableOptions}
    // Add default page zie for timetable options
    timeTableOptions.options = {...timeTableOptions.options, sizePerPage: 50}
    const countFields = ['agencyCount', 'routeCount', 'stopCount', 'tripCount', 'stopTimesCount']
    const daysActive = moment(version.validationSummary.endDate)
      .diff(moment(version.validationSummary.startDate), 'days')
    return (
      <ListGroupItem>
        {/* Tabs - Summary, Routes, Patterns, Stops, (Validation, Accessibility, Timeline) */}
        <Tabs
          activeKey={tab}
          onSelect={this._onClickTab}
          id='validator-tabs'
          bsStyle='pills'
          unmountOnExit>
          <Tab eventKey={'feed'} title='Summary'>
            <Row>
              {countFields.map(c => {
                const summary = version.validationSummary
                const diff = comparedVersion ? (summary[c] - comparedVersion.validationSummary[c]) : 0

                return (
                  <Col xs={2} className='text-center' key={c}>
                    <div
                      title={`${summary[c]}` /* do we need this? */}
                      style={{marginBottom: '0px', fontSize: '200%'}}>
                      {numeral(summary[c]).format('0a')}
                      {comparedVersion
                        ?
                           0 ? 'success' : (diff < 0 ? 'danger' : 'default')}
                            title={`Compared to Version ${comparedVersionIndex}`}>
                            {diff === 0 ? '=' : ((diff > 0 ? '+' : '') + numeral(diff).format('0a')) /* refactor */}

                        : null}

{this.messages(c)}

                  </Col>
                )
              })}
              <Col xs={2} className='text-center'>

                  {numeral(daysActive).format('0 a')}

{this.messages('daysActive')}

              </Col>
            </Row>

              <Row>
                <Col xs={12}>

Number of trips per date.

                </Col>
              </Row>
              <TripsChart validationResult={version.validationResult} />
              <Row>
                <Col xs={12}>

Service hours per date by mode.

                </Col>
              </Row>
              <ServicePerModeChart validationResult={version.validationResult} />

          </Tab>
          <Tab eventKey={'routes'} title='Routes'>
            <Routes
              version={version}
              selectTab={this.props.selectTab}
              tableOptions={tableOptions} />
          </Tab>
          <Tab eventKey={'patterns'} title='Patterns'>
            <Patterns
              version={version}
              selectTab={this.props.selectTab}
              tableOptions={tableOptions} />
          </Tab>
          <Tab eventKey={'stops'} title='Stops'>
            <Stops
              version={version}
              selectTab={this.props.selectTab}
              tableOptions={{...tableOptions, search: true}} />
          </Tab>
          <Tab eventKey={'timetables'} title='Timetables'>
            <Timetables
              version={version}
              selectTab={this.props.selectTab}
              tableOptions={timeTableOptions} />
          </Tab>
          {this.renderValidatorTabs(version, feedVersionIndex, isochroneBand, onChangeIsochroneBand)}
        </Tabs>
      </ListGroupItem>
    )
  }
}
<|endoftext|>


<commit_before>'use strict';

/**
* Unzip a zipped array (i.e., a nested array of tuples).
*
* @module @stdlib/math/generics/utils/unzip
*
* @example
* var unzip = require( '@stdlib/math/generics/utils/unzip' );
*
* var arr = [ [1,'a',3], [2,'b',4] ];
* var out = unzip( arr );
* // returns [ [1,2], ['a','b'], [3,4] ];
*
* arr = [ [1,'a',3], [2,'b',4] ];
* out = unzip( arr, [0,2] );
* // returns [ [1,2], [3,4] ];
*
*/

// MODULES //

var unzip = require( './unzip.js' );

// EXPORTS //

module.exports = unzip;
<commit_msg>Fix module path<commit_after>'use strict';

/**
* Unzip a zipped array (i.e., a nested array of tuples).
*
* @module @stdlib/utils/unzip
*
* @example
* var unzip = require( '@stdlib/utils/unzip' );
*
* var arr = [ [1,'a',3], [2,'b',4] ];
* var out = unzip( arr );
* // returns [ [1,2], ['a','b'], [3,4] ];
*
* arr = [ [1,'a',3], [2,'b',4] ];
* out = unzip( arr, [0,2] );
* // returns [ [1,2], [3,4] ];
*/

// MODULES //

var unzip = require( './unzip.js' );

// EXPORTS //

module.exports = unzip;
<|endoftext|>