<commit_before>var ArrayExtensions = {
    init: function() {
        if (!Array.prototype.remove) {
            Array.prototype.remove = function(value) {
                var index = this.indexOf(value);
                if (index === -1)
                    return false;

                this.splice(index, 1);
                return true;
            };
        }

        if (!Array.prototype.addDistinct) {
            Array.prototype.addDistinct = function(value) {
                var index = this.indexOf(value);
                if (index !== -1)
                    return false;
                this.push(value);
                return true;
            };
        }
    }
};

var Filters = {
    pinnedTabs: function(x) {
        return !!x.pinned;
    },
    tabsWithUrl: function(url) {
        return function(x) {
            return x.url == url;
        };
    }
};

var GlobalPinnedTabs = {

    globalPinnedTabUrls: [],

    tabIdToUrlMapping: {},
    urlToTabIdMapping: {},

    init: function() {

        ArrayExtensions.init();
        GlobalPinnedTabs.loadData();
        GlobalPinnedTabs.registerForChromeEvents();
        GlobalPinnedTabs.displayTabsOnCurrentWindow();
    },

    registerForChromeEvents: function() {
        chrome.windows.onFocusChanged.addListener(GlobalPinnedTabs.activeWindowChanged);
        chrome.tabs.onUpdated.addListener(GlobalPinnedTabs.onTabUpdate);
        chrome.tabs.onRemoved.addListener(GlobalPinnedTabs.onTabClose);
        });

        chrome.alarms.onAlarm.addListener(function(alarm) {
            if (alarm.name === 'Try moving tab again') {
                GlobalPinnedTabs.moveTabs(GlobalPinnedTabs.tabsToMove.target, GlobalPinnedTabs.tabsToMove.ids);
            }
        });
    },

    displayTabsOnCurrentWindow: function() {
        chrome.windows.getCurrent({
            populate: true
        }, function(window) {
            GlobalPinnedTabs.displayTabs(window);
        });
    },

    pinTabs: function(tabs) {

        var tabsPinned = 0;
        var enableUpdateHandling = function(tab) {
            tabsPinned++;
            if (tabsPinned === tabs.length)
                GlobalPinnedTabs.disableTabUpdateHandling = false;
        };

        for (var i = 0; i < tabs.length; ++i) {
            GlobalPinnedTabs.disableTabUpdateHandling = true;
            chrome.tabs.update(tabs[i].id, {
                pinned: true
            }, GlobalPinnedTabs.enableUpdateHandling);
        }
    },

    pinTab: function(tabs) {
        var lastError = chrome.runtime.lastError;
        if (tabs === undefined || lastError !== undefined) {
            console.log("Couldn't move tabs.");
            if (lastError !== undefined && lastError.message)
                console.log('Reason: ' + lastError.message);
            chrome.alarms.create('Try moving tabs again', {
                when: Date.now() + 1000
            });

        } else {
            GlobalPinnedTabs.pinTabs(tabs);
            GlobalPinnedTabs.tabsToMove.target = undefined;
            GlobalPinnedTabs.tabsToMove.ids = [];
        }
    },

    tabsToMove: {
        target: undefined,
        ids: []
    },

    moveTabs: function(windowId, tabIds) {
        GlobalPinnedTabs.tabsToMove.target = windowId;
        GlobalPinnedTabs.tabsToMove.ids = tabIds;

        if (tabIds.length === 0)
            return;

        chrome.tabs.move(tabIds, {
            windowId: windowId,
            index: 0
        }, GlobalPinnedTabs.pinTab);
    },

    activeWindowChanged: function(windowId) {
        if (windowId === chrome.windows.WINDOW_ID_NONE)
            return;
        chrome.windows.get(parseInt(windowId), {
            populate: true
        }, function(window) {
            GlobalPinnedTabs.displayTabs(window);
        });
    },

    windowId: undefined,
    tabId: undefined,
    disableTabUpdateHandling: false,

    displayTabs: function(window) {
        if (window.type !== 'normal')
            return;

        var url;
        var tabsToMove = [];
        for (var key in GlobalPinnedTabs.tabIdToUrlMapping) {
            url = GlobalPinnedTabs.tabIdToUrlMapping[key];
            var matchingTab = GlobalPinnedTabs.getMatchingTab(url, window);
            if (matchingTab === undefined) {
                tabsToMove.push(parseInt(key));
            } else if (key != matchingTab.id) {
                delete GlobalPinnedTabs.tabIdToUrlMapping[key];
                GlobalPinnedTabs.tabIdToUrlMapping[matchingTab.id] = url;
                GlobalPinnedTabs.urlToTabIdMapping[url] = matchingTab.id;
                chrome.tabs.remove(parseInt(key));
            }
        }

        GlobalPinnedTabs.moveTabs(window.id, tabsToMove);

        for (var i = 0; i < GlobalPinnedTabs.globalPinnedTabUrls.length; i++) {
            url = GlobalPinnedTabs.globalPinnedTabUrls[i];
            if (GlobalPinnedTabs.urlToTabIdMapping[url] === undefined)
                GlobalPinnedTabs.createTab(url, window);
        }
    },

    createTabCallback: function(tab) {
        GlobalPinnedTabs.tabIdToUrlMapping[tab.id] = tab.url;
        GlobalPinnedTabs.urlToTabIdMapping[tab.url] = tab.id;
    },

    onTabUpdate: function(tabId, changeInfo, tab) {
        if (GlobalPinnedTabs.disableTabUpdateHandling)
            return;
        if (changeInfo.pinned !== undefined) {
            if (changeInfo.pinned === true) {
                if (GlobalPinnedTabs.tabIdToUrlMapping[tabId] === undefined && confirm('Make this a globally pinned tab that is visible in all windows?')) {
                    GlobalPinnedTabs.tabIdToUrlMapping[tabId] = tab.url;
                    GlobalPinnedTabs.urlToTabIdMapping[tab.url] = tabId;
                    GlobalPinnedTabs.globalPinnedTabUrls.addDistinct(tab.url);
                    GlobalPinnedTabs.persistData();
                }
            } else {
                GlobalPinnedTabs.handleRemovedTab(tabId);
            }
        }
    },

    onTabClose: function(tabId, removeInfo) {
        GlobalPinnedTabs.handleRemovedTab(tabId, !removeInfo.isWindowClosing);
    },

    handleRemovedTab: function(tabId, removeUrl) {
        var url = GlobalPinnedTabs.tabIdToUrlMapping[tabId];
        if (url) {
            delete GlobalPinnedTabs.tabIdToUrlMapping[tabId];
            delete GlobalPinnedTabs.urlToTabIdMapping[url];
            console.log('deleted tab');
            if (removeUrl) {
                GlobalPinnedTabs.globalPinnedTabUrls.remove(url);
                GlobalPinnedTabs.persistData();
                console.log('deleted url');
            }
        }
    },

    getMatchingTab: function(url, window) {
        return window.tabs.filter(function(x) {
            return x.pinned && x.url === url;
        })[0];
    },

    createTab: function(url, window) {
        var matchingTab = GlobalPinnedTabs.getMatchingTab(url, window);
        if (matchingTab !== undefined)
            GlobalPinnedTabs.createTabCallback(matchingTab);
        else {
            console.log('Creating tab with URL ' + url);
            chrome.tabs.create({
                'url': url,
                'pinned': true,
                'active': false,
                'windowId': window.id
            }, GlobalPinnedTabs.createTabCallback);
        }
    },

    loadData: function() {
        chrome.storage.sync.get('globalPinnedTabUrls', function(items) {
            GlobalPinnedTabs.globalPinnedTabUrls = items.globalPinnedTabUrls;
        });
    },

    persistData: function() {
        chrome.storage.sync.set({
            globalPinnedTabUrls: GlobalPinnedTabs.globalPinnedTabUrls
        });
    }
};

GlobalPinnedTabs.init();<commit_msg>Reformat<commit_after>var ArrayExtensions = {
    init: function() {
        if (!Array.prototype.remove) {
            Array.prototype.remove = function(value) {
                var index = this.indexOf(value);
                if (index === -1)
                    return false;

                this.splice(index, 1);
                return true;
            };
        }

        if (!Array.prototype.addDistinct) {
            Array.prototype.addDistinct = function(value) {
                var index = this.indexOf(value);
                if (index !== -1)
                    return false;
                this.push(value);
                return true;
            };
        }
    }
};

var Filters = {
    pinnedTabs: function(x) {
        return !!x.pinned;
    },
    tabsWithUrl: function(url) {
        return function(x) {
            return x.url == url;
        };
    }
};

var GlobalPinnedTabs = {

    globalPinnedTabUrls: [],
    tabIdToUrlMapping: {},
    urlToTabIdMapping: {},

    init: function() {
        ArrayExtensions.init();
        GlobalPinnedTabs.loadData();
        GlobalPinnedTabs.registerForChromeEvents();
        GlobalPinnedTabs.displayTabsOnCurrentWindow();
    },

    registerForChromeEvents: function() {
        chrome.windows.onFocusChanged.addListener(GlobalPinnedTabs.activeWindowChanged);
        chrome.tabs.onUpdated.addListener(GlobalPinnedTabs.onTabUpdate);
        chrome.tabs.onRemoved.addListener(GlobalPinnedTabs.onTabClose);
        });

        chrome.alarms.onAlarm.addListener(function(alarm) {
            if (alarm.name === 'Try moving tab again') {
                GlobalPinnedTabs.moveTabs(GlobalPinnedTabs.tabsToMove.target, GlobalPinnedTabs.tabsToMove.ids);
            }
        });
    },

    displayTabsOnCurrentWindow: function() {
        chrome.windows.getCurrent({
            populate: true
        }, function(window) {
            GlobalPinnedTabs.displayTabs(window);
        });
    },

    pinTabs: function(tabs) {

        var tabsPinned = 0;
        var enableUpdateHandling = function(tab) {
            tabsPinned++;
            if (tabsPinned === tabs.length)
                GlobalPinnedTabs.disableTabUpdateHandling = false;
        };

        for (var i = 0; i < tabs.length; ++i) {
            GlobalPinnedTabs.disableTabUpdateHandling = true;
            chrome.tabs.update(tabs[i].id, {
                pinned: true
            }, GlobalPinnedTabs.enableUpdateHandling);
        }
    },

    pinTab: function(tabs) {
        var lastError = chrome.runtime.lastError;
        if (tabs === undefined || lastError !== undefined) {
            console.log("Couldn't move tabs.");
            if (lastError !== undefined && lastError.message)
                console.log('Reason: ' + lastError.message);
            chrome.alarms.create('Try moving tabs again', {
                when: Date.now() + 1000
            });

        } else {
            GlobalPinnedTabs.pinTabs(tabs);
            GlobalPinnedTabs.tabsToMove.target = undefined;
            GlobalPinnedTabs.tabsToMove.ids = [];
        }
    },

    tabsToMove: {
        target: undefined,
        ids: []
    },

    moveTabs: function(windowId, tabIds) {
        GlobalPinnedTabs.tabsToMove.target = windowId;
        GlobalPinnedTabs.tabsToMove.ids = tabIds;

        if (tabIds.length === 0)
            return;

        chrome.tabs.move(tabIds, {
            windowId: windowId,
            index: 0
        }, GlobalPinnedTabs.pinTab);
    },

    activeWindowChanged: function(windowId) {
        if (windowId === chrome.windows.WINDOW_ID_NONE)
            return;
        chrome.windows.get(parseInt(windowId), {
            populate: true
        }, function(window) {
            GlobalPinnedTabs.displayTabs(window);
        });
    },

    windowId: undefined,
    tabId: undefined,
    disableTabUpdateHandling: false,

    displayTabs: function(window) {
        if (window.type !== 'normal')
            return;

        var url;
        var tabsToMove = [];
        for (var key in GlobalPinnedTabs.tabIdToUrlMapping) {
            url = GlobalPinnedTabs.tabIdToUrlMapping[key];
            var matchingTab = GlobalPinnedTabs.getMatchingTab(url, window);
            if (matchingTab === undefined) {
                tabsToMove.push(parseInt(key));
            } else if (key != matchingTab.id) {
                delete GlobalPinnedTabs.tabIdToUrlMapping[key];
                GlobalPinnedTabs.tabIdToUrlMapping[matchingTab.id] = url;
                GlobalPinnedTabs.urlToTabIdMapping[url] = matchingTab.id;
                chrome.tabs.remove(parseInt(key));
            }
        }

        GlobalPinnedTabs.moveTabs(window.id, tabsToMove);

        for (var i = 0; i < GlobalPinnedTabs.globalPinnedTabUrls.length; i++) {
            url = GlobalPinnedTabs.globalPinnedTabUrls[i];
            if (GlobalPinnedTabs.urlToTabIdMapping[url] === undefined)
                GlobalPinnedTabs.createTab(url, window);
        }
    },

    createTabCallback: function(tab) {
        GlobalPinnedTabs.tabIdToUrlMapping[tab.id] = tab.url;
        GlobalPinnedTabs.urlToTabIdMapping[tab.url] = tab.id;
    },

    onTabUpdate: function(tabId, changeInfo, tab) {
        if (GlobalPinnedTabs.disableTabUpdateHandling)
            return;
        if (changeInfo.pinned !== undefined) {
            if (changeInfo.pinned === true) {
                if (GlobalPinnedTabs.tabIdToUrlMapping[tabId] === undefined && confirm('Make this a globally pinned tab that is visible in all windows?')) {
                    GlobalPinnedTabs.tabIdToUrlMapping[tabId] = tab.url;
                    GlobalPinnedTabs.urlToTabIdMapping[tab.url] = tabId;
                    GlobalPinnedTabs.globalPinnedTabUrls.addDistinct(tab.url);
                    GlobalPinnedTabs.persistData();
                }
            } else {
                GlobalPinnedTabs.handleRemovedTab(tabId);
            }
        }
    },

    onTabClose: function(tabId, removeInfo) {
        GlobalPinnedTabs.handleRemovedTab(tabId, !removeInfo.isWindowClosing);
    },

    handleRemovedTab: function(tabId, removeUrl) {
        var url = GlobalPinnedTabs.tabIdToUrlMapping[tabId];
        if (url) {
            delete GlobalPinnedTabs.tabIdToUrlMapping[tabId];
            delete GlobalPinnedTabs.urlToTabIdMapping[url];
            console.log('deleted tab');
            if (removeUrl) {
                GlobalPinnedTabs.globalPinnedTabUrls.remove(url);
                GlobalPinnedTabs.persistData();
                console.log('deleted url');
            }
        }
    },

    getMatchingTab: function(url, window) {
        return window.tabs.filter(function(x) {
            return x.pinned && x.url === url;
        })[0];
    },

    createTab: function(url, window) {
        var matchingTab = GlobalPinnedTabs.getMatchingTab(url, window);
        if (matchingTab !== undefined)
            GlobalPinnedTabs.createTabCallback(matchingTab);
        else {
            console.log('Creating tab with URL ' + url);
            chrome.tabs.create({
                'url': url,
                'pinned': true,
                'active': false,
                'windowId': window.id
            }, GlobalPinnedTabs.createTabCallback);
        }
    },

    loadData: function() {
        chrome.storage.sync.get('globalPinnedTabUrls', function(items) {
            GlobalPinnedTabs.globalPinnedTabUrls = items.globalPinnedTabUrls;
        });
    },

    persistData: function() {
        chrome.storage.sync.set({
            globalPinnedTabUrls: GlobalPinnedTabs.globalPinnedTabUrls
        });
    }
};

GlobalPinnedTabs.init();<|endoftext|>


<commit_before>'use strict';
var _ = require('lodash');
var Trick = require('./Trick');
var ShengJi = require('./ShengJi')();

/**
 *    Create a new game, initialize all states
 *    @constructor
 *    @param {int} numPlayers - The number of players in this game.
 *    @param {int} level - The level of this game.
 *    @param {int} startingTrump - The starting trump suit.
 *    @param {int} startingDealer - The id of the starting dealer.
 */
function Round({numPlayers, level, startingTrump, startingDealer}) {
  // round data
  this.level = level;
  this.DECKS = ShengJi.numDecks(numPlayers);
  this.DECKSIZE = this.DECKS * 54; //TODO: fix this according to rules
  this.trick = null;
  this.trumpSuit = startingTrump || ShengJi.cardSuit.JOKER;

  // player data
  this.dealer = startingDealer || 0; // jscs fails on destructured default param
  this.playerPoints = _.range(numPlayers).reduce((obj, x) => { obj[x] = 0; return obj; }, {});
  this.attackers = [];
  this.defenders = [];

  // card piles
  this.kittyPile = [];
  this.playedPile = [];
  this.history = [];
}

/**
*   Sets the trump for this game
*   @param {int} suit - The suit to set as trump.
*/
Round.prototype.setTrump = function(suit) {
  this.trumpSuit = suit;
};

/**
*   Starts a new trick
*   @param {array} play - The leading cards played in the new trick.
*/
Round.prototype.startTrick = function(play) {
  this.trick = new Trick(play, this.trumpSuit);
};

/**
*   Called every time someone plays cards, updates the current trick
*   @param {array} newPlay - The latest cards played in the current trick.
*/
Round.prototype.play = function(newPlay) {
  this.trick.play(newPlay, this.level, this.trumpSuit);
};

/**
*   Ends the current trick, if this is the last trick, ends the game
*   @return {object} An object containing the points, point cards, and the winner of the current trick.
*/
Round.prototype.endTrick = function() {
  var points = this.trick.points();
  var pointCards = this.trick.pointCards();
  var winner = this.trick.winner();

  this.playerPoints[winner] += points;
  this.playedPile = this.playedPile.concat(this.trick.cards);
  this.history.push(this.trick);

  // Round is finished, count kitty pile
  if (this.playedPile.length === this.DECKSIZE) {
    this.playerPoints[winner] += ShengJi.calcKittyPoints(this.kittyPile);
    return this.endRound();
  }

  return {
    points: points,
    pointCards: pointCards,
    winner: winner
  };
};

/**
*   Ends the game, counts up points for each team. Only called in endTrick.
*   @return {object} The winning team's player ids, and the number of levels they gain.
*/
Round.prototype.endRound = function() {
  // point calculation
  var attackingPoints = 0;
  _.each(this.attackers, p => { attackingPoints += this.playerPoints[p]; });
  var defendingPoints = ShengJi.maxPoints(this.DECKS) - attackingPoints;

  // level calculation, defenders first
  var levelsGained = (defendingPoints / 40) - 2;
  var winningTeam = this.defenders;
  if (levelsGained < 0) {
    levelsGained *= -1;
    winningTeam = this.attackers;
  }
  return {
    winningTeam: winningTeam,
    levelsGained: levelsGained
  };
};

module.exports = Round;

<commit_msg>refactor(Round): add chaining<commit_after>'use strict';
var _ = require('lodash');
var Trick = require('./Trick');
var ShengJi = require('./ShengJi')();

/**
 *    Create a new game, initialize all states
 *    @constructor
 *    @param {int} numPlayers - The number of players in this game.
 *    @param {int} level - The level of this game.
 *    @param {int} startingTrump - The starting trump suit.
 *    @param {int} startingDealer - The id of the starting dealer.
 */
function Round({numPlayers, level, startingTrump, startingDealer}) {
  // round data
  this.level = level;
  this.DECKS = ShengJi.numDecks(numPlayers);
  this.DECKSIZE = this.DECKS * 54; //TODO: fix this according to rules
  this.trick = null;
  this.trumpSuit = startingTrump || ShengJi.cardSuit.JOKER;

  // player data
  this.dealer = startingDealer || 0; // jscs fails on destructured default param
  this.playerPoints = _.range(numPlayers).reduce((obj, x) => { obj[x] = 0; return obj; }, {});
  this.attackers = [];
  this.defenders = [];

  // card piles
  this.kittyPile = [];
  this.playedPile = [];
  this.history = [];
  return this;
}

/**
*   Sets the trump for this game
*   @param {int} suit - The suit to set as trump.
*/
Round.prototype.setTrump = function(suit) {
  this.trumpSuit = suit;
  return this;
};

/**
*   Starts a new trick
*   @param {array} play - The leading cards played in the new trick.
*/
Round.prototype.startTrick = function(play) {
  this.trick = new Trick(play, this.trumpSuit);
  return this;
};

/**
*   Called every time someone plays cards, updates the current trick
*   @param {array} newPlay - The latest cards played in the current trick.
*/
Round.prototype.play = function(newPlay) {
  this.trick.play(newPlay, this.level, this.trumpSuit);
  return this;
};

/**
*   Ends the current trick, if this is the last trick, ends the game
*   @return {object} An object containing the points, point cards, and the winner of the current trick.
*/
Round.prototype.endTrick = function() {
  var points = this.trick.points();
  var pointCards = this.trick.pointCards();
  var winner = this.trick.winner();

  this.playerPoints[winner] += points;
  this.playedPile = this.playedPile.concat(this.trick.cards);
  this.history.push(this.trick);

  // Round is finished, count kitty pile
  if (this.playedPile.length === this.DECKSIZE) {
    this.playerPoints[winner] += ShengJi.calcKittyPoints(this.kittyPile);
    return this.endRound();
  }

  return {
    points: points,
    pointCards: pointCards,
    winner: winner
  };
};

/**
*   Ends the game, counts up points for each team. Only called in endTrick.
*   @return {object} The winning team's player ids, and the number of levels they gain.
*/
Round.prototype.endRound = function() {
  // point calculation
  var attackingPoints = 0;
  _.each(this.attackers, p => { attackingPoints += this.playerPoints[p]; });
  var defendingPoints = ShengJi.maxPoints(this.DECKS) - attackingPoints;

  // level calculation, defenders first
  var levelsGained = (defendingPoints / 40) - 2;
  var winningTeam = this.defenders;
  if (levelsGained < 0) {
    levelsGained *= -1;
    winningTeam = this.attackers;
  }
  return {
    winningTeam: winningTeam,
    levelsGained: levelsGained
  };
};

module.exports = Round;

<|endoftext|>


<commit_before>"use strict";

class claraConfigurator {
  constructor(config) {
    this.api                    = null;
    this.claraSceneId           = null;
    this.playerDivId            = null;
    this.configuratorDivId      = null;
    this.configuratorInputDivId = null;
    this.configuratorForm       = null;
    this.addtocartClassName     = null;
    this.addtocartButton        = null;
    /*
    *
    */
    this.attributes           = null;
    /*
    *
    */
    this.available_attributes = null;

    if (config) {
      // init variables
      this.playerDivId            = config.playerDivId;
      this.configuratorDivId      = config.configuratorDivId;
      this.claraSceneId           = config.claraSceneId;
      this.attributes             = config.attributes;
      this.available_attributes   = config.available_attributes;
      this.configuratorInputDivId = config.configuratorInputDivId;
      this.addtocartClassName     = config.addtocartClassName;

      this.addtocartButton = document.getElementsByClassName(this.addtocartClassName)[0];
    }
    console.log(this.attributes);
    console.log(this.available_attributes);
    this._initClara();
  }

  _initClara() {
    var self = this;
    // Fetch and initialize the sceneId
    this.api = claraplayer(this.playerDivId);
    this.api.sceneIO
      .fetchAndUse(this.claraSceneId, null, { waitForPublish: true })
      .then(() => {

        // use the first form in the scene
        self._getConfiguratorForm();

        var configuratorEl = document.getElementById(self.configuratorDivId);

        if (self.configuratorForm && configuratorEl) {
          self.api.configuration.initConfigurator({
            id    : self.claraSceneId,
            form  : self.configuratorForm,
            el    : configuratorEl
          });

          self.api.on('configurationChange', (ev) => {
            self._onConfigurationChange();
          });
        }
      });
  }

  _getConfiguratorForm() {
    if (!this.api) {
      return;
    }
    var forms = this.api.configuration.getForms();
    if (forms.length > 0) {
      this.configuratorForm = forms[0].name;
    }
  }

  _onConfigurationChange() {
    var self = this;
    var config = this.api.configuration.getConfiguration();
    console.log(config);

    var configuratorInputDiv = document.getElementById(this.configuratorInputDivId);
    if (!configuratorInputDiv) {
      return;
    }

    // check if config attribute name and value exist for the current product
    var additionalAttrs = [];
    if (Object.keys(this.attributes).length < Object.keys(config).length) {
      console.warn("Threekit attribute number is smaller than in WooCommerce, product will not be able to added to cart");
    }
    for (var key in config) {
      // looking for "key" in attributes
      var found = false;
      var legal = true;
      for (var ele in this.attributes) {
        // remove "pa_"
        var trimEle = ele;
        if (trimEle.startsWith('pa_')) {
          trimEle = trimEle.substr(3);
        }
        if (this.ignoreCaseStrcmp(trimEle, key)) {
          found = true;
          if (!this.ignoreCaseIncludes(this.attributes[ele], config[key])) {
            // config attribute value is illegal
            legal = false;
          }
          break;
        }
      }
      if (!legal) {
        this._disableAddtocartButton();
        return;
      }
      if (!found) {
        // additional attributes will be posted to server as text
        additionalAttrs.push(key);
      }
    }
    this._enableAddtocartButton();
    /*
    *  Check if the product is available
    *  Attributes in WooCommerce can be overlapping,
    *  using the first matching attribute in this.available_attributes
    */

    // calculate price

  }

  _disableAddtocartButton() {
    if (!this.addtocartButton) {
      return;
    }
    this.addtocartButton.classList.add('disabled');
  }

  _enableAddtocartButton() {
    if (!this.addtocartButton) {
      return;
    }
    this.addtocartButton.classList.remove('disabled');
  }

  /*
  * Utility functions
  */
  ignoreCaseStrcmp(str1, str2) {
    return str1.toLowerCase() === str2.toLowerCase();
  }
  ignoreCaseIncludes(arr, ele) {
    var self = this;
    for (var iter in arr) {
      if (self.ignoreCaseStrcmp(arr[iter], ele)) {
        return true;
      }
    }
    return false;
  }
}

(function() {
  var opts = {
    addtocartClassName    : 'single_add_to_cart_button',
    playerDivId           : 'clara-player',
    configuratorDivId     : 'panel-embed',
    configuratorInputDivId: 'threekit-add-to-cart-inputs',
    claraSceneId          : php_vars.clarauuid,
    available_attributes  : php_vars.available_attributes,
    attributes            : php_vars.attributes
  };
  var cc = new claraConfigurator(opts);

}());
<commit_msg>match attributes<commit_after>"use strict";

class claraConfigurator {
  constructor(config) {
    this.api                    = null;
    this.claraSceneId           = null;
    this.playerDivId            = null;
    this.configuratorDivId      = null;
    this.configuratorInputDivId = null;
    this.configuratorForm       = null;
    this.addtocartClassName     = null;
    this.addtocartButton        = null;
    /*
    *
    */
    this.attributes           = null;
    /*
    *
    */
    this.available_attributes = null;

    if (config) {
      // init variables
      this.playerDivId            = config.playerDivId;
      this.configuratorDivId      = config.configuratorDivId;
      this.claraSceneId           = config.claraSceneId;
      this.attributes             = config.attributes;
      this.available_attributes   = config.available_attributes;
      this.configuratorInputDivId = config.configuratorInputDivId;
      this.addtocartClassName     = config.addtocartClassName;

      this.addtocartButton = document.getElementsByClassName(this.addtocartClassName)[0];
    }
    console.log(this.attributes);
    console.log(this.available_attributes);
    this._initClara();
  }

  _initClara() {
    var self = this;
    // Fetch and initialize the sceneId
    this.api = claraplayer(this.playerDivId);
    this.api.sceneIO
      .fetchAndUse(this.claraSceneId, null, { waitForPublish: true })
      .then(() => {

        // use the first form in the scene
        self._getConfiguratorForm();

        var configuratorEl = document.getElementById(self.configuratorDivId);

        if (self.configuratorForm && configuratorEl) {
          self.api.configuration.initConfigurator({
            id    : self.claraSceneId,
            form  : self.configuratorForm,
            el    : configuratorEl
          });

          self.api.on('configurationChange', (ev) => {
            self._onConfigurationChange();
          });
        }
      });
  }

  _getConfiguratorForm() {
    if (!this.api) {
      return;
    }
    var forms = this.api.configuration.getForms();
    if (forms.length > 0) {
      this.configuratorForm = forms[0].name;
    }
  }

  _onConfigurationChange() {
    var self = this;
    var config = this.api.configuration.getConfiguration();
    console.log(config);

    var configuratorInputDiv = document.getElementById(this.configuratorInputDivId);
    if (!configuratorInputDiv) {
      return;
    }

    // check if config attribute name and value exist for the current product
    var additionalAttrs = [];
    if (Object.keys(this.attributes).length < Object.keys(config).length) {
      console.warn("Threekit attribute number is smaller than in WooCommerce, product will not be able to added to cart");
    }
    for (var key in config) {
      // looking for "key" in attributes
      var found = false;
      var legal = true;
      for (var ele in this.attributes) {
        // remove "pa_"
        var trimEle = ele;
        if (trimEle.startsWith('pa_')) {
          trimEle = trimEle.substr(3);
        }
        if (this.ignoreCaseStrcmp(trimEle, key)) {
          found = true;
          if (!this.ignoreCaseIncludes(this.attributes[ele], config[key])) {
            // config attribute value is illegal
            legal = false;
          }
          break;
        }
      }
      if (!legal) {
        this._disableAddtocartButton();
        return;
      }
      if (!found) {
        // additional attributes will be posted to server as text
        additionalAttrs.push(key);
      }
    }
    this._enableAddtocartButton();
    /*
    *  Check if the product is available
    *  Attributes in WooCommerce can be overlapping,
    *  using the first matching attribute in this.available_attributes
    */
    for (var i = 0; i < this.available_attributes.length; i++) {
      var attrs = this.available_attributes[i].attributes;
      if (Object.keys(attrs).length != Object.keys(config).length) {
        continue;
      }
      var match = true;
      for (var key in config) {
        var found = false;
        for(var ele in attrs) {
          // remove "attribute_pa_"
          var trimEle = ele;
          if (trimEle.startsWith('attribute_pa_')) {
            trimEle = trimEle.substr(12);
          }
          if (this.ignoreCaseStrcmp(trimEle, key)) {
            if (attrs[ele] === "" || this.ignoreCaseStrcmp(attrs[ele], config[key])) {
              found = true;
            }
          }
        }
        if (!found) {
          // matching fail
          match = false;
          break;
        }
      }
      if (match) {
        // find a match!
        console.log(this.available_attributes[i].variation_id);
        break;
      }
    }

    // calculate price

  }

  _disableAddtocartButton() {
    if (!this.addtocartButton) {
      return;
    }
    this.addtocartButton.classList.add('disabled');
  }

  _enableAddtocartButton() {
    if (!this.addtocartButton) {
      return;
    }
    this.addtocartButton.classList.remove('disabled');
  }

  /*
  * Utility functions
  */
  ignoreCaseStrcmp(str1, str2) {
    return str1.toLowerCase() === str2.toLowerCase();
  }
  ignoreCaseIncludes(arr, ele) {
    var self = this;
    for (var iter in arr) {
      if (self.ignoreCaseStrcmp(arr[iter], ele)) {
        return true;
      }
    }
    return false;
  }
}

(function() {
  var opts = {
    addtocartClassName    : 'single_add_to_cart_button',
    playerDivId           : 'clara-player',
    configuratorDivId     : 'panel-embed',
    configuratorInputDivId: 'threekit-add-to-cart-inputs',
    claraSceneId          : php_vars.clarauuid,
    available_attributes  : php_vars.available_attributes,
    attributes            : php_vars.attributes
  };
  var cc = new claraConfigurator(opts);

}());
<|endoftext|>


<commit_before>MODEL({
  name: 'ModelFileDAO',
  package: 'foam.core.bootstrap',
  methods: {
    find: function (key, sink) {
      var X = this.X;
      var model = FOAM.lookup(key, X);

      var tag = this.X.document.createElement('script');
      tag.src = '/js/' + key.replace(/\./g, '/') + '.js';
      this.X.document.head.appendChild(tag);

      tag.onload = function() {
//        this.removeChild(tag);

        model = FOAM.lookup(key, X);
        if ( ! model ) {
          sink && sink.error && sink.error('Model load failed for: ', key);
          return;
        }
        sink && sink.put && sink.put(model);
      }.bind(this.X.document.head);
    }
  }
});

X.ModelDAO = X.foam.core.bootstrap.ModelFileDAO.create();
<commit_msg>Fix path resolution in ModelFileDAO loading on gh-pages and other sites that will load foam not from the root path.<commit_after>MODEL({
  name: 'ModelFileDAO',
  package: 'foam.core.bootstrap',
  methods: {
    find: function (key, sink) {
      var X = this.X;
      var model = FOAM.lookup(key, X);

      var tag = this.X.document.createElement('script');
      tag.src = FOAM_BOOT_DIR + '../js/' + key.replace(/\./g, '/') + '.js';
      this.X.document.head.appendChild(tag);

      tag.onload = function() {
//        this.removeChild(tag);

        model = FOAM.lookup(key, X);
        if ( ! model ) {
          sink && sink.error && sink.error('Model load failed for: ', key);
          return;
        }
        sink && sink.put && sink.put(model);
      }.bind(this.X.document.head);
    }
  }
});

X.ModelDAO = X.foam.core.bootstrap.ModelFileDAO.create();
<|endoftext|>


<commit_before>/*global $,cyberDojo*/

var cyberDojo = (function(cd, $) {
  "use strict";

  cd.reJoin = function(id, avatarName) {
    var url = '/kata/edit/' + id + '?avatar=' + avatarName;
    window.open(url);
    cd.closeReJoinDialog();
    return false;
  };

  //- - - - - - - - - - - - - - - - - - - - -

  cd.dialog_reJoin = function(title, cancel ,dialogHtml) {
    var buttons = { };
    buttons[cancel] = function() { $(this).dialog('close'); };
    var reEnter = $('
')
      .html(dialogHtml)
      .dialog({
        title: cd.dialogTitle(title),
        autoOpen: false,
        width: 500,
        modal: true,
        buttons: buttons
      });
    cd.closeReJoinDialog = function() { reJoin.dialog('close'); };
    return reEnter;
  };

  return cd;
})(cyberDojo || {}, $);
<commit_msg>s/enter/join rename refactoring<commit_after>/*global $,cyberDojo*/

var cyberDojo = (function(cd, $) {
  "use strict";

  cd.reJoin = function(id, avatarName) {
    var url = '/kata/edit/' + id + '?avatar=' + avatarName;
    window.open(url);
    cd.closeReJoinDialog();
    return false;
  };

  //- - - - - - - - - - - - - - - - - - - - -

  cd.dialog_reJoin = function(title, cancel ,dialogHtml) {
    var buttons = { };
    buttons[cancel] = function() { $(this).dialog('close'); };
    var reJoin = $('
')
      .html(dialogHtml)
      .dialog({
        title: cd.dialogTitle(title),
        autoOpen: false,
        width: 500,
        modal: true,
        buttons: buttons
      });
    cd.closeReJoinDialog = function() { reJoin.dialog('close'); };
    return reJoin;
  };

  return cd;
})(cyberDojo || {}, $);
<|endoftext|>


<commit_before>(function( window, document, undefined ) {
  'use strict';

  function clamp( value, min, max ) {
    return Math.min( Math.max( value, min ), max );
  }

  var hslEl = document.querySelector( '.hsl' );
  var palettesEl = document.querySelector( '.palettes' );
  var currentPaletteEl;

  var addPaletteBtn = document.querySelector( '.add-palette-btn' );

  var palettes = [];

  var h = 0,
      s = 50,
      l = 50;

  function hslString( h, s, l ) {
    return 'hsl(' +
      Math.round( h ) + ', ' +
      Math.round( s ) + '%, ' +
      Math.round( l ) + '%)';
  }

  function update() {
    var hsl = hslString( h, s, l );

    document.body.style.backgroundColor = hsl;
    hslEl.textContent = hsl;
  }

  update();

  // Update background color.
  window.addEventListener( 'mousemove', function( event ) {
    var x = event.pageX,
        y = event.pageY;

    h = x / window.innerWidth * 360;
    s = ( window.innerHeight - y ) / window.innerHeight * 100;

    update();
  });

  window.addEventListener( 'wheel', function( event ) {
    event.preventDefault();
    l = clamp( l - event.deltaY, 0, 100 );
    update();
  });

  function nodeIndexOf( el ) {
    if ( el.parentNode ) {
      return [].indexOf.call( el.parentNode.childNodes, el );
    }

    return -1;
  }

  function logPalettes() {
    var str = '';

    palettes.forEach(function( palette, index, array ) {
      // Log a '*' for each palette.
      str += '[: ' + new Array( palette.length + 1 ).join( '*' );

      if ( index < array.length - 1 ) {
        str += '\n';
      }
    });

    console.log( str );
  }

  // Add color to palette.
  function rectMouseDown( event ) {
    event.stopPropagation();

    var el = event.currentTarget;
    var parentEl = el.parentNode;
    var index, parentIndex;
    if ( parentEl ) {
      index = nodeIndexOf( el );

      if ( parentEl.parentNode ) {
        parentIndex = nodeIndexOf( parentEl );
      }

      parentEl.removeChild( el );
      el.removeEventListener( 'mousedown', rectMouseDown );

      // Remove entire palette element if it's empty.
      if ( parentEl.parentNode && !parentEl.childNodes.length ) {
        parentEl.parentNode.removeChild( parentEl );
      }

      if ( index !== -1 && parentIndex !== -1 ) {
        console.log( '[' + parentIndex + ', ' + index + ']' );
        palettes[ parentIndex ].splice( index, 1 );

        if ( !palettes[ parentIndex ].length ) {
          palettes.splice( parentIndex, 1 );
        }

        logPalettes();
      }
    }
  }

  window.addEventListener( 'mousedown', function() {
    if ( !palettes.length ) {
      addPalette();
    }

    var rectEl = createRectEl( h, s, l );
    rectEl.addEventListener( 'mousedown', rectMouseDown );
    currentPaletteEl.appendChild( rectEl );

    palettes[ palettes.length - 1 ].push({
      h: h,
      s: s,
      l: l
    });

    logPalettes();
  });

  // Laod/save.
  /**
   * Returns an array of saved palettes.
   */
  function getSavedPalettes() {
    var savedPalettes = window.localStorage.getItem( 'palettes' );
    savedPalettes = savedPalettes ? JSON.parse( savedPalettes ) : [];
    return savedPalettes;
  }

  function load() {
    palettes = getSavedPalettes();

    palettes.forEach(function( palette ) {
      if ( !palette.length ) {
        return;
      }

      currentPaletteEl = createPaletteEl();

      palette.forEach(function( rect ) {
        var rectEl = createRectEl( rect.h, rect.s, rect.l );
        rectEl.addEventListener( 'mousedown', rectMouseDown );
        currentPaletteEl.appendChild( rectEl );
      });

      palettesEl.appendChild( currentPaletteEl );
    });
  }

  window.addEventListener( 'beforeunload', function() {
    palettes = palettes.filter(function( palette ) {
      return palette.length;
    });

    window.localStorage.setItem( 'palettes', JSON.stringify( palettes ) );
  });

  function createPaletteEl() {
    var paletteEl = document.createElement( 'div' );
    paletteEl.classList.add( 'palette', 'clearfix' );
    return paletteEl;
  }

  function createRectEl( h, s, l ) {
    var rectEl = document.createElement( 'div' );

    var hsl = hslString( h, s, l );
    rectEl.classList.add( 'rect' );
    rectEl.style.backgroundColor = hsl;
    rectEl.setAttribute( 'data-background-color', hsl );

    return rectEl;
  }

  function addPalette() {
    currentPaletteEl = createPaletteEl();
    palettesEl.appendChild( currentPaletteEl );
    palettes.push( [] );
  }

  addPaletteBtn.addEventListener( 'mousedown',  function( event ) {
    event.stopPropagation();
    // Don't add if the last palette is already empty.
    if ( palettes.length && !palettes[ palettes.length - 1 ].length ) {
      return;
    }

    addPalette();
  });

  load();

}) ( window, document );
<commit_msg>palette[picker]: Use .color element mousemove for picking color.<commit_after>(function( window, document, undefined ) {
  'use strict';

  function clamp( value, min, max ) {
    return Math.min( Math.max( value, min ), max );
  }

  var hslEl = document.querySelector( '.hsl' );
  var palettesEl = document.querySelector( '.palettes' );
  var colorEl = document.querySelector( '.color' );
  var currentPaletteEl;

  var addPaletteBtn = document.querySelector( '.add-palette-btn' );

  var palettes = [];

  var h = 0,
      s = 50,
      l = 50;

  function hslString( h, s, l ) {
    return 'hsl(' +
      Math.round( h ) + ', ' +
      Math.round( s ) + '%, ' +
      Math.round( l ) + '%)';
  }

  function update() {
    var hsl = hslString( h, s, l );

    document.body.style.backgroundColor = hsl;
    hslEl.textContent = hsl;
  }

  update();

  // Update background color.
  colorEl.addEventListener( 'mousemove', function( event ) {
    var x = event.pageX - colorEl.offsetLeft,
        y = event.pageY - colorEl.offsetTop;

    h = x / colorEl.offsetWidth * 360;
    s = ( colorEl.offsetHeight - y ) / colorEl.offsetHeight * 100;

    update();
  });

  window.addEventListener( 'wheel', function( event ) {
    event.preventDefault();
    l = clamp( l - event.deltaY, 0, 100 );
    update();
  });

  function nodeIndexOf( el ) {
    if ( el.parentNode ) {
      return [].indexOf.call( el.parentNode.childNodes, el );
    }

    return -1;
  }

  function logPalettes() {
    var str = '';

    palettes.forEach(function( palette, index, array ) {
      // Log a '*' for each palette.
      str += '[: ' + new Array( palette.length + 1 ).join( '*' );

      if ( index < array.length - 1 ) {
        str += '\n';
      }
    });

    console.log( str );
  }

  // Add color to palette.
  function rectMouseDown( event ) {
    event.stopPropagation();

    var el = event.currentTarget;
    var parentEl = el.parentNode;
    var index, parentIndex;
    if ( parentEl ) {
      index = nodeIndexOf( el );

      if ( parentEl.parentNode ) {
        parentIndex = nodeIndexOf( parentEl );
      }

      parentEl.removeChild( el );
      el.removeEventListener( 'mousedown', rectMouseDown );

      // Remove entire palette element if it's empty.
      if ( parentEl.parentNode && !parentEl.childNodes.length ) {
        parentEl.parentNode.removeChild( parentEl );
      }

      if ( index !== -1 && parentIndex !== -1 ) {
        console.log( '[' + parentIndex + ', ' + index + ']' );
        palettes[ parentIndex ].splice( index, 1 );

        if ( !palettes[ parentIndex ].length ) {
          palettes.splice( parentIndex, 1 );
        }

        logPalettes();
      }
    }
  }

  colorEl.addEventListener( 'mousedown', function() {
    if ( !palettes.length ) {
      addPalette();
    }

    var rectEl = createRectEl( h, s, l );
    rectEl.addEventListener( 'mousedown', rectMouseDown );
    currentPaletteEl.appendChild( rectEl );

    palettes[ palettes.length - 1 ].push({
      h: h,
      s: s,
      l: l
    });

    logPalettes();
  });

  // Laod/save.
  /**
   * Returns an array of saved palettes.
   */
  function getSavedPalettes() {
    var savedPalettes = window.localStorage.getItem( 'palettes' );
    savedPalettes = savedPalettes ? JSON.parse( savedPalettes ) : [];
    return savedPalettes;
  }

  function load() {
    palettes = getSavedPalettes();

    palettes.forEach(function( palette ) {
      if ( !palette.length ) {
        return;
      }

      currentPaletteEl = createPaletteEl();

      palette.forEach(function( rect ) {
        var rectEl = createRectEl( rect.h, rect.s, rect.l );
        rectEl.addEventListener( 'mousedown', rectMouseDown );
        currentPaletteEl.appendChild( rectEl );
      });

      palettesEl.appendChild( currentPaletteEl );
    });
  }

  window.addEventListener( 'beforeunload', function() {
    palettes = palettes.filter(function( palette ) {
      return palette.length;
    });

    window.localStorage.setItem( 'palettes', JSON.stringify( palettes ) );
  });

  function createPaletteEl() {
    var paletteEl = document.createElement( 'div' );
    paletteEl.classList.add( 'palette', 'clearfix' );
    return paletteEl;
  }

  function createRectEl( h, s, l ) {
    var rectEl = document.createElement( 'div' );

    var hsl = hslString( h, s, l );
    rectEl.classList.add( 'rect' );
    rectEl.style.backgroundColor = hsl;
    rectEl.setAttribute( 'data-background-color', hsl );

    return rectEl;
  }

  function addPalette() {
    currentPaletteEl = createPaletteEl();
    palettesEl.appendChild( currentPaletteEl );
    palettes.push( [] );
  }

  addPaletteBtn.addEventListener( 'mousedown',  function( event ) {
    event.stopPropagation();
    // Don't add if the last palette is already empty.
    if ( palettes.length && !palettes[ palettes.length - 1 ].length ) {
      return;
    }

    addPalette();
  });

  load();

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


<commit_before>'use strict'

var _ = require('lodash')
var React = require('react')
var Router = require('react-router')
var Link = Router.Link

var SVGCollection = require('./SVGCollection')
var htmlutil = require('../htmlutil')
var PredictionRow = require('./PredictionRow')

var reactable = require('reactable')
var Tr = reactable.Tr
var Td = reactable.Td
var Th = reactable.Th
var Thead = reactable.Thead
var Table = reactable.Table
var unsafe = reactable.unsafe

var DataTable = React.createClass({

    propTypes: {
        data: React.PropTypes.object.isRequired,
        db: React.PropTypes.string.isRequired
    },

    getInitialState: function() {
        return {
            annotationsOnly: false
        }
    },

    handleAnnotationsClick: function() {
        console.log('handleAnnotationsClick')
        this.setState({
            annotationsOnly: !this.state.annotationsOnly
        })
    },

    render: function() {

        // console.log('pdt render, state:', this.state)
        var that = this
        var pathways = this.state.annotationsOnly ? this.props.data.pathways.annotated : this.props.data.pathways.predicted

        pathways = _.filter(pathways, function(pathway) {
            return pathway.term.database.toUpperCase() === that.props.db
        })

        if (this.state.annotationsOnly) {
            pathways = _.sortBy(pathways, 'pValue')
        }

        var rows = _.map(pathways, function(pathway, i) {

            var isAnnotated = that.state.annotationsOnly || pathway.annotated

            var key= pathway.term.id
            var gene= that.props.data.gene
            var data= pathway
            var isAnnotated= isAnnotated
            var num= i

            return (

                    <Link className='nodecoration black' title={data.term.numAnnotatedGenes + ' annotated genes, prediction accuracy ' + Math.round(100 * data.term.auc) / 100} to={`/term/${data.term.id}`}>
                    {data.term.name}
                    </Link>

                {unsafe(htmlutil.pValueToReadable(data.pValue))}

                    {data.zScore > 0 ? <SVGCollection.TriangleUp className='directiontriangleup' /> : <SVGCollection.TriangleDown className='directiontriangledown' />}

                    {isAnnotated ? <SVGCollection.Annotated /> : <SVGCollection.NotAnnotated />}

                        <SVGCollection.NetworkIcon />

            )
        })

        if (rows.length === 0) {
            rows = (
No {this.props.db} {this.state.annotationsOnly ? 'annotations' : 'predictions'} for {this.props.data.gene.name}
)
        }

        if (false && rows.length === 0) {
            return (

{'No ' + this.props.db + (this.props.type == 'prediction' ? ' predictions' : ' annotations') + ' for ' + this.props.data.gene.name}

                )
        } else {
            var annotatedClass = this.state.annotationsOnly ? 'clickable underline' : 'clickable'
            return (

            <Table className='gn-gene-table datatable'

            sortable={[

                {
                    column: 'TERM',
                    sortFunction: function (a, b) {
                        var newA = a.props.children
                        var newB = b.props.children
                        return newA.localeCompare(newB)
                    }
                },

                {
                    column: "P-VALUE",
                    sortFunction: function(a, b) {

                        if (a.length < 5) {
                            if (b.length < 5) {             {/* a ?? b */}
                                return a - b
                            } else if (b[0] != '<') {    {/* a > b */}
                                return 1
                            } else {                        {/* a > b */}
                                return 1
                            }
                        } else if (a[0] != '<') {
                            if (b.length < 5) {             {/* a < b */}
                                return -1
                            } else if (b[0] != '<') {    {/* a ?? b */}

                                a = a.toString()
                                var aExponent = a.slice(53)
                                var aExp = aExponent.slice(0, aExponent.indexOf("<"))
                                var aNumber = a.slice(0,3)

                                b = b.toString()
                                var bExponent = b.slice(53)
                                var bExp = bExponent.slice(0, bExponent.indexOf("<"))
                                var bNumber = b.slice(0,3)

                                return aExp - bExp || aNumber - bNumber

                            } else {                        {/* a > b */}
                                return 1
                            }
                        } else {
                            if (b.length < 5) {             {/* a < b */}
                                return -1
                            } else if (b[0] != '<') {    {/* a <b */}
                                return -1
                            } else {

                                a = a.toString()
                                var aExponent = a.slice(55)
                                var aExp = aExponent.slice(0, aExponent.indexOf("<"))
                                var aNumber = a.slice(2,5)

                                b = b.toString()
                                var bExponent = b.slice(55)
                                var bExp = bExponent.slice(0, bExponent.indexOf("<"))
                                var bNumber = b.slice(2,5)

                                return aExp - bExp || aNumber - bNumber

                            }
                        }

                        return b - a
                    }
                },

                {
                    column: 'DIRECTION',
                    sortFunction: function(a, b) {

                        console.log(a.props.className)
                        return a.props.className.localeCompare(b.props.className)
                    }
                },

                {
                    column: 'ANNOTATED',
                    sortFunction: function(a, b) {

                        console.log(a.props.className)
                        return a.props.className.localeCompare(b.props.className)
                    }
                }

            ]}
            >

                TERM
                P-VALUE
                DIRECTION
                ANNOTATED
                NETWORK

            {rows}

            )
                {/*

                TERM
                P-VALUE
                DIRECTION
                ANNOTATED	 // still need to get this back!!
                NETWORK

                {rows}

 */}

        }
    }
})

module.exports = DataTable
<commit_msg>updated datatable<commit_after>'use strict'

var _ = require('lodash')
var React = require('react')
var Router = require('react-router')
var Link = Router.Link

var SVGCollection = require('./SVGCollection')
var htmlutil = require('../htmlutil')
var PredictionRow = require('./PredictionRow')

var reactable = require('reactable')
var Tr = reactable.Tr
var Td = reactable.Td
var Th = reactable.Th
var Thead = reactable.Thead
var Table = reactable.Table
var unsafe = reactable.unsafe

var DataTable = React.createClass({

    propTypes: {
        data: React.PropTypes.object.isRequired,
        db: React.PropTypes.string.isRequired
    },

    getInitialState: function() {
        return {
            annotationsOnly: false
        }
    },

    handleAnnotationsClick: function() {
        console.log('handleAnnotationsClick')
        this.setState({
            annotationsOnly: !this.state.annotationsOnly
        })
    },

    render: function() {

        // console.log('pdt render, state:', this.state)
        var that = this
        var pathways = this.state.annotationsOnly ? this.props.data.pathways.annotated : this.props.data.pathways.predicted

        pathways = _.filter(pathways, function(pathway) {
            return pathway.term.database.toUpperCase() === that.props.db
        })

        if (this.state.annotationsOnly) {
            pathways = _.sortBy(pathways, 'pValue')
        }

        var rows = _.map(pathways, function(pathway, i) {

            var isAnnotated = that.state.annotationsOnly || pathway.annotated

            var key= pathway.term.id
            var gene= that.props.data.gene
            var data= pathway
            var isAnnotated= isAnnotated
            var num= i
        //       <Link className='nodecoration black' title={data.term.numAnnotatedGenes + ' annotated genes, prediction accuracy ' + Math.round(100 * data.term.auc) / 100} to={`/term/${data.term.id}`}>
                    // {data.term.name}
                    // </Link>
            return (

                    {data.term.name}

                {unsafe(htmlutil.pValueToReadable(data.pValue))}

                    {data.zScore > 0 ? <SVGCollection.TriangleUp className='directiontriangleup' /> : <SVGCollection.TriangleDown className='directiontriangledown' />}

                    {isAnnotated ? <SVGCollection.Annotated /> : <SVGCollection.NotAnnotated />}

                        <SVGCollection.NetworkIcon />

            )
        })

        if (rows.length === 0) {
            rows = (
No {this.props.db} {this.state.annotationsOnly ? 'annotations' : 'predictions'} for {this.props.data.gene.name}
)
        }

        if (false && rows.length === 0) {
            return (

{'No ' + this.props.db + (this.props.type == 'prediction' ? ' predictions' : ' annotations') + ' for ' + this.props.data.gene.name}

                )
        } else {
            var annotatedClass = this.state.annotationsOnly ? 'clickable underline' : 'clickable'
            return (

            <Table className='gn-gene-table datatable'

            sortable={[

                {
                    column: 'TERM',
                    sortFunction: function (a, b) {
                        var newA = a.props.children
                        var newB = b.props.children
                        return newA.localeCompare(newB)
                    }
                },

                {
                    column: "P-VALUE",
                    sortFunction: function(a, b) {

                        if (a.length < 5) {
                            if (b.length < 5) {             {/* a ?? b */}
                                return a - b
                            } else if (b[0] != '<') {    {/* a > b */}
                                return 1
                            } else {                        {/* a > b */}
                                return 1
                            }
                        } else if (a[0] != '<') {
                            if (b.length < 5) {             {/* a < b */}
                                return -1
                            } else if (b[0] != '<') {    {/* a ?? b */}

                                a = a.toString()
                                var aExponent = a.slice(53)
                                var aExp = aExponent.slice(0, aExponent.indexOf("<"))
                                var aNumber = a.slice(0,3)

                                b = b.toString()
                                var bExponent = b.slice(53)
                                var bExp = bExponent.slice(0, bExponent.indexOf("<"))
                                var bNumber = b.slice(0,3)

                                return aExp - bExp || aNumber - bNumber

                            } else {                        {/* a > b */}
                                return 1
                            }
                        } else {
                            if (b.length < 5) {             {/* a < b */}
                                return -1
                            } else if (b[0] != '<') {    {/* a <b */}
                                return -1
                            } else {

                                a = a.toString()
                                var aExponent = a.slice(55)
                                var aExp = aExponent.slice(0, aExponent.indexOf("<"))
                                var aNumber = a.slice(2,5)

                                b = b.toString()
                                var bExponent = b.slice(55)
                                var bExp = bExponent.slice(0, bExponent.indexOf("<"))
                                var bNumber = b.slice(2,5)

                                return aExp - bExp || aNumber - bNumber

                            }
                        }

                        return b - a
                    }
                },

                {
                    column: 'DIRECTION',
                    sortFunction: function(a, b) {

                        console.log(a.props.className)
                        return a.props.className.localeCompare(b.props.className)
                    }
                },

                {
                    column: 'ANNOTATED',
                    sortFunction: function(a, b) {

                        console.log(a.props.className)
                        return a.props.className.localeCompare(b.props.className)
                    }
                }

            ]}
            >

                TERM
                P-VALUE
                DIRECTION
                ANNOTATED
                NETWORK

            {rows}

            )
                {/*

                TERM
                P-VALUE
                DIRECTION
                ANNOTATED	 // still need to get this back!!
                NETWORK

                {rows}

 */}

        }
    }
})

module.exports = DataTable
<|endoftext|>


<commit_before>/* eslint-disable object-shorthand */
module.exports = {
  // We need to make sure that the transpiler hit the linoleum source since we are
  // not building to npm or simliar.
  ignore: function(filename) {
    return ((/node_modules/.test(filename))
        && !(/linoleum\/src/.test(filename))
        && !(/linoleum\/tasks/.test(filename)))
        || (/\$.*\$/.test(filename));
  },
  sourceMap: 'inline',
  auxiliaryCommentBefore: 'istanbul ignore next'
};
<commit_msg>Fix babel transpile for electron runner<commit_after>/* eslint-disable object-shorthand */
module.exports = {
  // We need to make sure that the transpiler hit the linoleum source since we are
  // not building to npm or simliar.
  ignore: function(filename) {
    return ((/node_modules/.test(filename))
        && !(/linoleum\/electron/.test(filename))
        && !(/linoleum\/src/.test(filename))
        && !(/linoleum\/tasks/.test(filename)))
        || (/\$.*\$/.test(filename));
  },
  sourceMap: 'inline',
  auxiliaryCommentBefore: 'istanbul ignore next'
};
<|endoftext|>


<commit_before>/**
 * The Stories view.
 */
define([
  'jquery',
  'backbone',
  'underscore',
  'mps',
  'handlebars',
  'text!landing/templates/stories.handlebars'
], function($, Backbone, _, mps, Handlebars, tpl) {

  'use strict';

  var StoriesModel = Backbone.Model.extend({
    defaults:{
      stories: null,
    }
  });

  var StoriesView = Backbone.View.extend({

    el: '#storiesView',

    template: Handlebars.compile(tpl),

    initialize: function() {

      //Init Vars
      this.url = 'https://gfw-huggin.herokuapp.com/users/1/web_requests/15/keepupdatedgfwrss.json';
      this.items = {};
      mps.publish('Spinner:start');

      //Init Fn
      this._loadStories();
    },

    render: function(){
      this.$el.html(this.template({stories: this.items}));
    },

    _loadStories: function() {
      $.ajax({
        url: this.url,
        success: _.bind(function(data) {
          this.parse(data.items);
        },this),
        error: function(status, error) {
          mps.publish('Spinner:stop');
        }
      });
    },
    parse: function(data) {
      var self = this;
      this.items = _.map(data,_.bind(function(item) {
        var result = null;
        if (item.link) {
          //check if it's a blog post
          result = self.parseItem(item,'post');
        } else {
          // user story here
          result = self.parseItem(item,'story');
        }
        return result;
      },this));
      self.render(this.items);
      mps.publish('Spinner:stop');
    },

    parseItem: function(item, slug) {
      if (slug === 'story') {
        if (! item.media.length) {
          var img = null;
        } else {
          var img = item.media[item.media.length -1].preview_url;
        }
        return {
          title: item.title,
          description: item.details,
          link: '/stories/'+item.cartodb_id,
          target: false,
          map: (img) ? 'http://gfw2stories.s3.amazonaws.com/uploads/' + img : 'https://maps.googleapis.com/maps/api/staticmap?center=' + item.the_geom.coordinates[1] + ',' + item.the_geom.coordinates[0] + '&zoom=2&size=80x80',
          type: slug
        }
      } else {
        return {
          title: item.title,
          description: item.description,
          link: item.link,
          target:true,
          avatar: item.category[0].replace(' ','-'),
          type: slug
        }
      }
    }
  });
  return StoriesView;

});
<commit_msg>stories feed ajax working<commit_after>/**
 * The Stories view.
 */
define([
  'jquery',
  'backbone',
  'underscore',
  'mps',
  'handlebars',
  'text!landing/templates/stories.handlebars'
], function($, Backbone, _, mps, Handlebars, tpl) {

  'use strict';

  var StoriesModel = Backbone.Model.extend({
    defaults:{
      stories: null,
    }
  });

  var StoriesView = Backbone.View.extend({

    el: '#storiesView',

    template: Handlebars.compile(tpl),

    initialize: function() {

      //Init Vars
      this.url = 'https://gfw-huggin.herokuapp.com/users/1/web_requests/15/keepupdatedgfwrss.json';
      this.items = {};
      mps.publish('Spinner:start');

      //Init Fn
      this._loadStories();
    },

    render: function(){
      this.$el.html(this.template({stories: this.items}));
    },

    _loadStories: function() {
      $.ajax({
        url: this.url,
        success: _.bind(function(data) {
          this.parse(data.items);
        },this),
        error: function(status, error) {
          mps.publish('Spinner:stop');
        }
      });
    },
    parse: function(data) {
      var self = this;
      data = data.slice(0,3);
      this.items = _.map(data,_.bind(function(item) {
        return self.parseItem(item);;
      },this));
      self.render(this.items);
      mps.publish('Spinner:stop');
    },

    parseItem: function(item, slug) {
      if (item.media.length && !!JSON.parse(item.media)[1]) {
        var img = 'http://gfw2stories.s3.amazonaws.com/uploads/' + JSON.parse(item.media)[1]['url'];
      } else {
        var img = '/assets/blog-categories/news.png';
      }
      console.log(img);
      return {
        title: item.title,
        description: item.description,
        link: (item.link.length) ? item.link : (isNaN(item.gfwid)) ? item.gfwid :  '/stories/'+item.gfwid,
        target: false,
        date: item.pubDate,
        avatar: img,
        id: (isNaN(item.gfwid)) ? item.gfwid :  '/stories/'+item.gfwid
      }
    }
  });
  return StoriesView;

});
<|endoftext|>


<commit_before>/**
 * StopFlash
 *
 * https://github.com/JWhile/StopFlash
 *
 * background.js
 */

// class BackgroundFlashCollection
function BackgroundFlashCollection(id, port)
{
    this.id = id; // :int

    this.port = port; // :chrome.runtime.Port

    var self = this;

    port.onDisconnect.addListener(function()
    {
        self.port = null;
    });
};

// class BackgroundFlashData
function BackgroundFlashData(id)
{
    this.id = id; // :int

    this.data = []; // :Array<Object>

    this.collectionId = 0; // :int

    this.collections = []; // :Array<BackgroundFlashCollection>

    this.popupPort = null; // :chrome.runtime.Port
}
// function setData(Object data):void
BackgroundFlashData.prototype.setData = function(data)
{
    if(data.length > 0)
    {
        Array.prototype.unshift.apply(this.data, data);

        this.sendToPopup();
    }
};
// function setPopup(chrome.runtime.Port popupPort):void
BackgroundFlashData.prototype.setPopup = function(popupPort)
{
    this.popupPort = popupPort;

    var self = this;

    this.popupPort.onDisconnect.addListener(function()
    {
        self.popupPort = null;
    });

    this.sendToPopup();
};
// function setContentScript(chrome.runtime.Port contentPort):void
BackgroundFlashData.prototype.setContentScript = function(contentPort)
{
    this.collections.push(new BackgroundFlashCollection(++this.collectionId, contentPort));

    contentPort.postMessage({'stopflashWhitelist': whitelist, 'stopflashContentId': 0});
};
// function sendToPopup():void
BackgroundFlashData.prototype.sendToPopup = function()
{
    if(this.popupPort != null)
    {
        this.popupPort.postMessage({'stopflashData': this.data});
    }
};
// function sendToContent(Object data):void
BackgroundFlashData.prototype.sendToContent = function(data)
{
    for(var i = 0; i < this.collections.length; ++i)
    {
        this.collections[i].port.postMessage(data);
    }
};
// function clear():void
BackgroundFlashData.prototype.clear = function()
{
    this.data = null;

    if(this.popupPort != null)
    {
        this.popupPort.disconnect();
    }

    this.popupPort = null;

    if(this.collections.length > 0)
    {
        for(var i = 0; i < this.collections.length; ++i)
        {
            this.collections[i].port.disconnect();
        }
    }

    this.collections = [];
};

var flashData = []; // :Array<BackgroundFlashData>
var whitelist = []; // :Array<String>

// function getFlashData(int id):BackgroundFlashData
var getFlashData = function(id)
{
    for(var i = 0; i < flashData.length; ++i)
    {
        if(flashData[i].id === id)
        {
            return flashData[i];
        }
    }

    return null;
};

chrome.runtime.onConnect.addListener(function(port)
{
    if(port.name === 'stopflashContentScript' && port.sender.tab != null)
    {
        var data = null;

        port.onMessage.addListener(function(rep)
        {
            if(rep['stopflashInit'])
            {
                data = getFlashData(port.sender.tab.id);

                if(data != null)
                {
                    if(rep['stopflashIsMainFrame'])
                    {
                        data.clear();
                    }
                }
                else
                {
                    data = new BackgroundFlashData(port.sender.tab.id);

                    flashData.push(data);
                }

                data.setContentScript(port);
            }

            if(rep['stopflashHaveChange'])
            {
                if(rep['stopflashIsMainFrame'])
                {
                    data.data = [];
                }

                data.sendToContent({'stopflashDataUpdate': true});
            }

            if(rep['stopflashDataUpdate'] && rep['stopflashData'])
            {
                data.setData(rep.stopflashData);
            }
        });
    }
    else if(port.name === 'stopflashPopup')
    {
        var data = null;

        port.onMessage.addListener(function(rep)
        {
            if(rep['stopflashInit'])
            {
                data = getFlashData(rep['stopflashInit']);

                if(data != null)
                {
                    data.setPopup(port);
                }
            }

            if(rep['stopflashBlock'])
            {

                data.sendToContent({'stopflashBlock': rep['stopflashBlock']});
            }

            if(rep['stopflashUnblock'])
            {
                data.sendToContent({'stopflashUnblock': rep['stopflashUnblock']});
            }
        });
    }
});
<commit_msg>Rename BackgroundFlashData to StopFlashBackground + Rename flashData to backgrounds & getFlashData() to getBackground()<commit_after>/**
 * StopFlash
 *
 * https://github.com/JWhile/StopFlash
 *
 * background.js
 */

// class BackgroundFlashCollection
function BackgroundFlashCollection(id, port)
{
    this.id = id; // :int

    this.port = port; // :chrome.runtime.Port

    var self = this;

    port.onDisconnect.addListener(function()
    {
        self.port = null;
    });
};

// class StopFlashBackground
function StopFlashBackground(id)
{
    this.id = id; // :int

    this.data = []; // :Array<Object>

    this.collectionId = 0; // :int

    this.collections = []; // :Array<BackgroundFlashCollection>

    this.popupPort = null; // :chrome.runtime.Port
}
// function setData(Object data):void
StopFlashBackground.prototype.setData = function(data)
{
    if(data.length > 0)
    {
        Array.prototype.unshift.apply(this.data, data);

        this.sendToPopup();
    }
};
// function setPopup(chrome.runtime.Port popupPort):void
StopFlashBackground.prototype.setPopup = function(popupPort)
{
    this.popupPort = popupPort;

    var self = this;

    this.popupPort.onDisconnect.addListener(function()
    {
        self.popupPort = null;
    });

    this.sendToPopup();
};
// function setContentScript(chrome.runtime.Port contentPort):void
StopFlashBackground.prototype.setContentScript = function(contentPort)
{
    this.collections.push(new BackgroundFlashCollection(++this.collectionId, contentPort));

    contentPort.postMessage({'stopflashWhitelist': whitelist, 'stopflashContentId': 0});
};
// function sendToPopup():void
StopFlashBackground.prototype.sendToPopup = function()
{
    if(this.popupPort != null)
    {
        this.popupPort.postMessage({'stopflashData': this.data});
    }
};
// function sendToContent(Object data):void
StopFlashBackground.prototype.sendToContent = function(data)
{
    for(var i = 0; i < this.collections.length; ++i)
    {
        this.collections[i].port.postMessage(data);
    }
};
// function clear():void
StopFlashBackground.prototype.clear = function()
{
    this.data = null;

    if(this.popupPort != null)
    {
        this.popupPort.disconnect();
    }

    this.popupPort = null;

    if(this.collections.length > 0)
    {
        for(var i = 0; i < this.collections.length; ++i)
        {
            this.collections[i].port.disconnect();
        }
    }

    this.collections = [];
};

var backgrounds = []; // :Array<StopFlashBackground>
var whitelist = []; // :Array<String>

// function getBackground(int id):StopFlashBackground
var getBackground = function(id)
{
    for(var i = 0; i < backgrounds.length; ++i)
    {
        if(backgrounds[i].id === id)
        {
            return backgrounds[i];
        }
    }

    return null;
};

chrome.runtime.onConnect.addListener(function(port)
{
    if(port.name === 'stopflashContentScript' && port.sender.tab != null)
    {
        var data = null;

        port.onMessage.addListener(function(rep)
        {
            if(rep['stopflashInit'])
            {
                data = getBackground(port.sender.tab.id);

                if(data != null)
                {
                    if(rep['stopflashIsMainFrame'])
                    {
                        data.clear();
                    }
                }
                else
                {
                    data = new StopFlashBackground(port.sender.tab.id);

                    backgrounds.push(data);
                }

                data.setContentScript(port);
            }

            if(rep['stopflashHaveChange'])
            {
                if(rep['stopflashIsMainFrame'])
                {
                    data.data = [];
                }

                data.sendToContent({'stopflashDataUpdate': true});
            }

            if(rep['stopflashDataUpdate'] && rep['stopflashData'])
            {
                data.setData(rep.stopflashData);
            }
        });
    }
    else if(port.name === 'stopflashPopup')
    {
        var data = null;

        port.onMessage.addListener(function(rep)
        {
            if(rep['stopflashInit'])
            {
                data = getFlashData(rep['stopflashInit']);

                if(data != null)
                {
                    data.setPopup(port);
                }
            }

            if(rep['stopflashBlock'])
            {

                data.sendToContent({'stopflashBlock': rep['stopflashBlock']});
            }

            if(rep['stopflashUnblock'])
            {
                data.sendToContent({'stopflashUnblock': rep['stopflashUnblock']});
            }
        });
    }
});
<|endoftext|>


<commit_before>/*global Tablesaw:true */

/*
* tablesaw: A set of plugins for responsive tables
* Stack and Column Toggle tables
* Copyright (c) 2013 Filament Group, Inc.
* MIT License
*/

if( typeof Tablesaw === "undefined" ) {
	Tablesaw = {
		i18n: {
			modes: [ 'Stack', 'Swipe', 'Toggle' ],
			columns: 'Columns',
			columnBtnText: 'Columns',
			columnsDialogError: 'No eligible columns.',
			sort: 'Sort'
		},
		// cut the mustard
		mustard: 'querySelector' in document &&
			( !window.blackberry || window.WebKitPoint ) &&
			!window.operamini
	};
}
if( !Tablesaw.config ) {
	Tablesaw.config = {};
}
if( Tablesaw.mustard ) {
	jQuery( document.documentElement ).addClass( 'tablesaw-enhanced' );
}

;(function( $ ) {
	var pluginName = "table",
		classes = {
			toolbar: "tablesaw-bar"
		},
		events = {
			create: "tablesawcreate",
			destroy: "tablesawdestroy",
			refresh: "tablesawrefresh"
		},
		defaultMode = "stack",
		initSelector = "table[data-tablesaw-mode],table[data-tablesaw-sortable]";

	var Table = function( element ) {
		if( !element ) {
			throw new Error( "Tablesaw requires an element." );
		}

		this.table = element;
		this.$table = $( element );

		this.mode = this.$table.attr( "data-tablesaw-mode" ) || defaultMode;

		this.init();
	};

	Table.prototype.init = function() {
		// assign an id if there is none
		if ( !this.$table.attr( "id" ) ) {
			this.$table.attr( "id", pluginName + "-" + Math.round( Math.random() * 10000 ) );
		}

		this.createToolbar();

		var colstart = this._initCells();

		this.$table.trigger( events.create, [ this, colstart ] );
	};

	Table.prototype._initCells = function() {
		var colstart,
			thrs = this.table.querySelectorAll( "thead tr" ),
			self = this;

		$( thrs ).each( function(){
			var coltally = 0;

			$( this ).children().each( function(){
				var span = parseInt( this.getAttribute( "colspan" ), 10 ),
					sel = ":nth-child(" + ( coltally + 1 ) + ")";

				colstart = coltally + 1;

				if( span ){
					for( var k = 0; k < span - 1; k++ ){
						coltally++;
						sel += ", :nth-child(" + ( coltally + 1 ) + ")";
					}
				}

				// Store "cells" data on header as a reference to all cells in the same column as this TH
				this.cells = self.$table.find("tr").not( thrs[0] ).not( this ).children().filter( sel );
				coltally++;
			});
		});

		return colstart;
	};

	Table.prototype.refresh = function() {
		this._initCells();

		this.$table.trigger( events.refresh );
	};

	Table.prototype.createToolbar = function() {
		// Insert the toolbar
		// TODO move this into a separate component
		var $toolbar = this.$table.prev().filter( '.' + classes.toolbar );
		if( !$toolbar.length ) {
			$toolbar = $( '
' )
				.addClass( classes.toolbar )
				.insertBefore( this.$table );
		}
		this.$toolbar = $toolbar;

		if( this.mode ) {
			this.$toolbar.addClass( 'mode-' + this.mode );
		}
	};

	Table.prototype.destroy = function() {
		// Don’t remove the toolbar. Some of the table features are not yet destroy-friendly.
		this.$table.prev().filter( '.' + classes.toolbar ).each(function() {
			this.className = this.className.replace( /\bmode\-\w*\b/gi, '' );
		});

		var tableId = this.$table.attr( 'id' );
		$( document ).unbind( "." + tableId );
		$( window ).unbind( "." + tableId );

		// other plugins
		this.$table.trigger( events.destroy, [ this ] );

		this.$table.removeAttr( 'data-tablesaw-mode' );

		this.$table.removeData( pluginName );
	};

	// Collection method.
	$.fn[ pluginName ] = function() {
		return this.each( function() {
			var $t = $( this );

			if( $t.data( pluginName ) ){
				return;
			}

			var table = new Table( this );
			$t.data( pluginName, table );
		});
	};

	$( document ).on( "enhance.tablesaw", function( e ) {
		// Cut the mustard
		if( Tablesaw.mustard ) {
			$( e.target ).find( initSelector )[ pluginName ]();
		}
	});

}( jQuery ));
<commit_msg>Don’t remove mode on destroy!<commit_after>/*global Tablesaw:true */

/*
* tablesaw: A set of plugins for responsive tables
* Stack and Column Toggle tables
* Copyright (c) 2013 Filament Group, Inc.
* MIT License
*/

if( typeof Tablesaw === "undefined" ) {
	Tablesaw = {
		i18n: {
			modes: [ 'Stack', 'Swipe', 'Toggle' ],
			columns: 'Columns',
			columnBtnText: 'Columns',
			columnsDialogError: 'No eligible columns.',
			sort: 'Sort'
		},
		// cut the mustard
		mustard: 'querySelector' in document &&
			( !window.blackberry || window.WebKitPoint ) &&
			!window.operamini
	};
}
if( !Tablesaw.config ) {
	Tablesaw.config = {};
}
if( Tablesaw.mustard ) {
	jQuery( document.documentElement ).addClass( 'tablesaw-enhanced' );
}

;(function( $ ) {
	var pluginName = "table",
		classes = {
			toolbar: "tablesaw-bar"
		},
		events = {
			create: "tablesawcreate",
			destroy: "tablesawdestroy",
			refresh: "tablesawrefresh"
		},
		defaultMode = "stack",
		initSelector = "table[data-tablesaw-mode],table[data-tablesaw-sortable]";

	var Table = function( element ) {
		if( !element ) {
			throw new Error( "Tablesaw requires an element." );
		}

		this.table = element;
		this.$table = $( element );

		this.mode = this.$table.attr( "data-tablesaw-mode" ) || defaultMode;

		this.init();
	};

	Table.prototype.init = function() {
		// assign an id if there is none
		if ( !this.$table.attr( "id" ) ) {
			this.$table.attr( "id", pluginName + "-" + Math.round( Math.random() * 10000 ) );
		}

		this.createToolbar();

		var colstart = this._initCells();

		this.$table.trigger( events.create, [ this, colstart ] );
	};

	Table.prototype._initCells = function() {
		var colstart,
			thrs = this.table.querySelectorAll( "thead tr" ),
			self = this;

		$( thrs ).each( function(){
			var coltally = 0;

			$( this ).children().each( function(){
				var span = parseInt( this.getAttribute( "colspan" ), 10 ),
					sel = ":nth-child(" + ( coltally + 1 ) + ")";

				colstart = coltally + 1;

				if( span ){
					for( var k = 0; k < span - 1; k++ ){
						coltally++;
						sel += ", :nth-child(" + ( coltally + 1 ) + ")";
					}
				}

				// Store "cells" data on header as a reference to all cells in the same column as this TH
				this.cells = self.$table.find("tr").not( thrs[0] ).not( this ).children().filter( sel );
				coltally++;
			});
		});

		return colstart;
	};

	Table.prototype.refresh = function() {
		this._initCells();

		this.$table.trigger( events.refresh );
	};

	Table.prototype.createToolbar = function() {
		// Insert the toolbar
		// TODO move this into a separate component
		var $toolbar = this.$table.prev().filter( '.' + classes.toolbar );
		if( !$toolbar.length ) {
			$toolbar = $( '
' )
				.addClass( classes.toolbar )
				.insertBefore( this.$table );
		}
		this.$toolbar = $toolbar;

		if( this.mode ) {
			this.$toolbar.addClass( 'mode-' + this.mode );
		}
	};

	Table.prototype.destroy = function() {
		// Don’t remove the toolbar. Some of the table features are not yet destroy-friendly.
		this.$table.prev().filter( '.' + classes.toolbar ).each(function() {
			this.className = this.className.replace( /\bmode\-\w*\b/gi, '' );
		});

		var tableId = this.$table.attr( 'id' );
		$( document ).unbind( "." + tableId );
		$( window ).unbind( "." + tableId );

		// other plugins
		this.$table.trigger( events.destroy, [ this ] );

		this.$table.removeData( pluginName );
	};

	// Collection method.
	$.fn[ pluginName ] = function() {
		return this.each( function() {
			var $t = $( this );

			if( $t.data( pluginName ) ){
				return;
			}

			var table = new Table( this );
			$t.data( pluginName, table );
		});
	};

	$( document ).on( "enhance.tablesaw", function( e ) {
		// Cut the mustard
		if( Tablesaw.mustard ) {
			$( e.target ).find( initSelector )[ pluginName ]();
		}
	});

}( jQuery ));
<|endoftext|>