<commit_before>'use strict';

const version = require('../package.json').version;
const router = require('express').Router;
const app = router();

const ntb = require('turbasen');

const userAgent = `Hytteadmin/${version}`;
process.env.NTB_USER_AGENT = userAgent;
process.env.DNT_CONNECT_USER_AGENT = userAgent;
process.env.DNT_API_USER_AGENT = userAgent;

const Turbasen = require('turbasen-auth');
const DntConnect = require('dnt-connect');
const DntApi = require('dnt-api');

const connect = new DntConnect(
  process.env.DNT_CONNECT_CLIENT,
  process.env.DNT_CONNECT_KEY
);

const dntApi = new DntApi(
  process.env.DNT_API_USER_AGENT,
  process.env.DNT_API_KEY
);

app.get('/', (req, res) => {
  if (req.session && req.session.user) {
    res.json(req.session.user);
  } else {
    res.status(401);
    res.json({ authenticated: false });
  }
});

app.get('/login/dnt', connect.middleware('signon'));
app.get('/login/dnt', (req, res, next) => {
  if (!req.dntConnect) {
    const err = new Error('DNT Connect: unknown error');
    err.status = 500;
    return next(err);
  }

  if (req.dntConnect.err || !req.dntConnect.data.er_autentisert) {
    // @TODO redierect back to login page with error message
    return res.redirect('/login');
  }

  req.session.user = {
    id: `sherpa3:${req.dntConnect.data.sherpa_id}`,
    brukertype: 'DNT',
    navn: `${req.dntConnect.data.fornavn} ${req.dntConnect.data.etternavn}`,
    epost: req.dntConnect.data.epost,
    er_admin: false,
    grupper: [],
  };

  return next();
});

app.get('/login/dnt', (req, res) => {
  const user = {
    bruker_sherpa_id: req.dntConnect.data.sherpa_id,
  };

  // Find groups the user belongs to in Sherpa
  dntApi.getAssociationsFor(user, (err, statusCode, associations) => {
    let isAdmin = false;
    const groups = [];

    if (err) { throw err; }
    if (statusCode === 200) {
      for (let i = 0; i < associations.length; i++) {
        if (associations[i].object_id) {
          groups.push(associations[i]);
        }
        if (!isAdmin && associations[i].navn === 'Den Norske Turistforening') {
          isAdmin = true;
        }
      }

      req.session.user.er_admin = isAdmin;
    } else {
      throw new Error(`Request to DNT API failed: ${statusCode}`);
    }

    // Find groups that the user belongs to in Turbasen
    ntb.grupper({ 'privat.brukere.id': `sherpa3:${user.bruker_sherpa_id}` }, (ntbErr, ntbRes, body) => {
      if (ntbErr) {
        throw new Error(`Request to Turbasen API failed: ${ntbErr.message}`);
      } else if (body && body.documents && body.documents.length) {
        for (let i = 0; i < body.documents.length; i++) {
          groups.push(body.documents[i]);
        }
      }

      req.session.user.grupper = groups;

      res.redirect('/');
    });
  });
});

app.post('/login/turbasen', Turbasen.middleware);
app.post('/login/turbasen', (req, res, next) => {
  if (req.turbasenAuth) {
    req.session.user = req.turbasenAuth;
    req.session.user.brukertype = 'Gruppe';
    res.status(200);
    res.json(req.session.user);
  } else {
    req.session.destroy(err => {
      if (!err) {
        const error = new Error('Invalid email or password');
        error.status = 401;

        return next(error);
      }

      return next(err);
    });
  }
});

app.get('/logout', (req, res) => {
  req.session.destroy(err => {
    if (err) { throw err; }

    if (req.query.next) {
      res.redirect(req.query.next);
    } else {
      res.redirect('/');
    }
  });
});

app.post('/logout', (req, res) => {
  req.session.destroy(err => {
    if (err) { throw err; }

    res.status(204).end();
  });
});

module.exports = app;
<commit_msg>chore(auth): fix lint err<commit_after>'use strict';

const version = require('../package.json').version;
const router = require('express').Router;
const app = router();

const ntb = require('turbasen');

const userAgent = `Hytteadmin/${version}`;
process.env.NTB_USER_AGENT = userAgent;
process.env.DNT_CONNECT_USER_AGENT = userAgent;
process.env.DNT_API_USER_AGENT = userAgent;

const Turbasen = require('turbasen-auth');
const DntConnect = require('dnt-connect');
const DntApi = require('dnt-api');

const connect = new DntConnect(
  process.env.DNT_CONNECT_CLIENT,
  process.env.DNT_CONNECT_KEY
);

const dntApi = new DntApi(
  process.env.DNT_API_USER_AGENT,
  process.env.DNT_API_KEY
);

app.get('/', (req, res) => {
  if (req.session && req.session.user) {
    res.json(req.session.user);
  } else {
    res.status(401);
    res.json({ authenticated: false });
  }
});

app.get('/login/dnt', connect.middleware('signon'));
app.get('/login/dnt', (req, res, next) => {
  if (!req.dntConnect) {
    const err = new Error('DNT Connect: unknown error');
    err.status = 500;
    return next(err);
  }

  if (req.dntConnect.err || !req.dntConnect.data.er_autentisert) {
    // @TODO redierect back to login page with error message
    return res.redirect('/login');
  }

  req.session.user = {
    id: `sherpa3:${req.dntConnect.data.sherpa_id}`,
    brukertype: 'DNT',
    navn: `${req.dntConnect.data.fornavn} ${req.dntConnect.data.etternavn}`,
    epost: req.dntConnect.data.epost,
    er_admin: false,
    grupper: [],
  };

  return next();
});

app.get('/login/dnt', (req, res) => {
  const user = {
    bruker_sherpa_id: req.dntConnect.data.sherpa_id,
  };

  // Find groups the user belongs to in Sherpa
  dntApi.getAssociationsFor(user, (err, statusCode, associations) => {
    let isAdmin = false;
    const groups = [];

    if (err) { throw err; }
    if (statusCode === 200) {
      for (let i = 0; i < associations.length; i++) {
        if (associations[i].object_id) {
          groups.push(associations[i]);
        }
        if (!isAdmin && associations[i].navn === 'Den Norske Turistforening') {
          isAdmin = true;
        }
      }

      req.session.user.er_admin = isAdmin;
    } else {
      throw new Error(`Request to DNT API failed: ${statusCode}`);
    }

    // Find groups that the user belongs to in Turbasen
    const query = { 'privat.brukere.id': `sherpa3:${user.bruker_sherpa_id}` };

    ntb.grupper(query, (ntbErr, ntbRes, body) => {
      if (ntbErr) {
        throw new Error(`Request to Turbasen API failed: ${ntbErr.message}`);
      } else if (body && body.documents && body.documents.length) {
        for (let i = 0; i < body.documents.length; i++) {
          groups.push(body.documents[i]);
        }
      }

      req.session.user.grupper = groups;

      res.redirect('/');
    });
  });
});

app.post('/login/turbasen', Turbasen.middleware);
app.post('/login/turbasen', (req, res, next) => {
  if (req.turbasenAuth) {
    req.session.user = req.turbasenAuth;
    req.session.user.brukertype = 'Gruppe';
    res.status(200);
    res.json(req.session.user);
  } else {
    req.session.destroy(err => {
      if (!err) {
        const error = new Error('Invalid email or password');
        error.status = 401;

        return next(error);
      }

      return next(err);
    });
  }
});

app.get('/logout', (req, res) => {
  req.session.destroy(err => {
    if (err) { throw err; }

    if (req.query.next) {
      res.redirect(req.query.next);
    } else {
      res.redirect('/');
    }
  });
});

app.post('/logout', (req, res) => {
  req.session.destroy(err => {
    if (err) { throw err; }

    res.status(204).end();
  });
});

module.exports = app;
<|endoftext|>


<commit_before>(function(module) {
    module.directive('detailTabs', detailTabsDirective);
    function detailTabsDirective() {
        return {
            restrict: 'E',
            scope: {
                item: '='
            },
            controller: 'DetailTabsDirectiveController',
            controllerAs: 'ctrl',
            bindToController: true,
            templateUrl: 'application/directives/partials/detail-tabs.html'
        };
    }

    module.controller('DetailTabsDirectiveController', DetailTabsDirectiveController);
    DetailTabsDirectiveController.$inject = [];
    function DetailTabsDirectiveController() {
        var ctrl = this;
        ctrl.tabs = loadTabs();
        ctrl.activeTab = ctrl.tabs[0].name;
        ctrl.setActive = setActive;
        ctrl.isActive = isActive;

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

        function setActive(tab) {
            ctrl.activeTab = tab;
        }

        function isActive(tab) {
            return ctrl.activeTab === tab;
        }

        function loadTabs() {
            var tabs = [];

            if ('notes' in ctrl.item && ctrl.item.notes.length) {
                tabs.push(newTab('notes', 'fa-sticky-note', ctrl.item.notes.length));
            }

            if ('reviews' in ctrl.item && ctrl.item.reviews.length) {
                tabs.push(newTab('reviews', 'fa-comment', ctrl.item.reviews.length));
            }

            if ('processes' in ctrl.item && ctrl.item.processes.length) {
                tabs.push(newTab('processes', 'fa-code-fork', ctrl.item.processes.length));
            }

            if ('files' in ctrl.item && ctrl.item.files.length) {
                tabs.push(newTab('files', 'fa-files-o', ctrl.item.files.length));
            }

            if ('samples' in ctrl.item && ctrl.item.samples.length) {
                tabs.push(newTab('samples', 'fa-cubes', ctrl.item.samples.length));
            }

            if ('measurements' in ctrl.item && ctrl.item.measurements.length) {
                tabs.push(newTab('measurements', 'fa-flask', ctrl.item.measurements.length));
            } else if ('property_sets' in ctrl.item && ctrl.item.property_sets.length) {
                tabs.push(newTab('measurements', 'fa-flask', ctrl.item.property_sets.length));
            }

            if ('setup' in ctrl.item && ctrl.item.setup[0].properties.length) {
                tabs.push(newTab('setup', 'fa-cogs', ctrl.item.setup[0].properties.length));
            }

            tabs.sort(function compareByName(t1, t2) {
                if (t1.name < t2.name) {
                    return -1;
                }
                if (t1.name > t2.name) {
                    return 1;
                }
                return 0;
            });

            return tabs;
        }

        function newTab(name, icon, count) {
            return {
                name: name,
                icon: icon,
                count: count
            };
        }
    }
}(angular.module('materialscommons')));<commit_msg>Handle case where there are no tabs.<commit_after>(function(module) {
    module.directive('detailTabs', detailTabsDirective);
    function detailTabsDirective() {
        return {
            restrict: 'E',
            scope: {
                item: '='
            },
            controller: 'DetailTabsDirectiveController',
            controllerAs: 'ctrl',
            bindToController: true,
            templateUrl: 'application/directives/partials/detail-tabs.html'
        };
    }

    module.controller('DetailTabsDirectiveController', DetailTabsDirectiveController);
    DetailTabsDirectiveController.$inject = [];
    function DetailTabsDirectiveController() {
        var ctrl = this;
        ctrl.tabs = loadTabs();
        ctrl.activeTab = ctrl.tabs.length ? ctrl.tabs[0].name : '';
        ctrl.setActive = setActive;
        ctrl.isActive = isActive;

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

        function setActive(tab) {
            ctrl.activeTab = tab;
        }

        function isActive(tab) {
            return ctrl.activeTab === tab;
        }

        function loadTabs() {
            var tabs = [];

            if ('notes' in ctrl.item && ctrl.item.notes.length) {
                tabs.push(newTab('notes', 'fa-sticky-note', ctrl.item.notes.length));
            }

            if ('reviews' in ctrl.item && ctrl.item.reviews.length) {
                tabs.push(newTab('reviews', 'fa-comment', ctrl.item.reviews.length));
            }

            if ('processes' in ctrl.item && ctrl.item.processes.length) {
                tabs.push(newTab('processes', 'fa-code-fork', ctrl.item.processes.length));
            }

            if ('files' in ctrl.item && ctrl.item.files.length) {
                tabs.push(newTab('files', 'fa-files-o', ctrl.item.files.length));
            }

            if ('samples' in ctrl.item && ctrl.item.samples.length) {
                tabs.push(newTab('samples', 'fa-cubes', ctrl.item.samples.length));
            }

            if ('measurements' in ctrl.item && ctrl.item.measurements.length) {
                tabs.push(newTab('measurements', 'fa-flask', ctrl.item.measurements.length));
            } else if ('property_sets' in ctrl.item && ctrl.item.property_sets.length) {
                tabs.push(newTab('measurements', 'fa-flask', ctrl.item.property_sets.length));
            }

            if ('setup' in ctrl.item && ctrl.item.setup[0].properties.length) {
                tabs.push(newTab('setup', 'fa-cogs', ctrl.item.setup[0].properties.length));
            }

            tabs.sort(function compareByName(t1, t2) {
                if (t1.name < t2.name) {
                    return -1;
                }
                if (t1.name > t2.name) {
                    return 1;
                }
                return 0;
            });

            return tabs;
        }

        function newTab(name, icon, count) {
            return {
                name: name,
                icon: icon,
                count: count
            };
        }
    }
}(angular.module('materialscommons')));<|endoftext|>


<commit_before>const _ = require('underscore');

/**
 * Base class representing an ability that can be done by the player. This
 * includes card actions, reactions, interrupts, playing a card, marshaling a
 * card, or ambushing a card.
 *
 * Most of the methods take a context object. While the structure will vary from
 * inheriting classes, it is guaranteed to have at least the `game` object, the
 * `player` that is executing the action, and the `source` card object that the
 * ability is generated from.
 */
class BaseAbility {
    /**
     * Creates an ability.
     *
     * @param {Object} properties - An object with ability related properties.
     * @param {Object|Array} properties.cost - optional property that specifies
     * the cost for the ability. Can either be a cost object or an array of cost
     * objects.
     */
    constructor(properties) {
        this.cost = this.buildCost(properties.cost);
        this.targets = this.buildTargets(properties);
        this.cannotBeCanceled = !!properties.cannotBeCanceled;
        this.chooseOpponentFunc = properties.chooseOpponent;
    }

    buildCost(cost) {
        if(!cost) {
            return [];
        }

        if(!_.isArray(cost)) {
            return [cost];
        }

        return cost;
    }

    buildTargets(properties) {
        if(properties.target) {
            return {
                target: properties.target
            };
        }

        if(properties.targets) {
            return properties.targets;
        }

        return {};
    }

    /**
     * Return whether all costs are capable of being paid for the ability.
     *
     * @returns {Boolean}
     */
    canPayCosts(context) {
        return _.all(this.cost, cost => cost.canPay(context));
    }

    /**
     * Resolves all costs for the ability prior to payment. Some cost objects
     * have a `resolve` method in order to prompt the user to make a choice,
     * such as choosing a card to kneel. Consumers of this method should wait
     * until all costs have a `resolved` value of `true` before proceeding.
     *
     * @returns {Array} An array of cost resolution results.
     */
    resolveCosts(context) {
        return _.map(this.cost, cost => {
            if(cost.resolve) {
                return cost.resolve(context);
            }

            return { resolved: true, value: cost.canPay(context) };
        });
    }

    /**
     * Pays all costs for the ability simultaneously.
     */
    payCosts(context) {
        _.each(this.cost, cost => {
            cost.pay(context);
        });
    }

    /**
     * Return whether when unpay is implemented for the ability cost and the
     * cost can be unpaid.
     *
     * @returns {boolean}
     */
    canUnpayCosts(context) {
        return _.all(this.cost, cost => cost.unpay && cost.canUnpay(context));
    }

    /**
     * Unpays each cost associated with the ability.
     */
    unpayCosts(context) {
        _.each(this.cost, cost => {
            cost.unpay(context);
        });
    }

    /**
     * Returns whether the ability requires an opponent to be chosen.
     */
    needsChooseOpponent() {
        return !!this.chooseOpponentFunc;
    }

    /**
     * Returns whether there are opponents that can be chosen, if the ability
     * requires that an opponent be chosen.
     */
    canResolveOpponents(context) {
        if(!this.needsChooseOpponent()) {
            return true;
        }

        return _.any(context.game.getPlayers(), player => {
            return player !== context.player && this.canChooseOpponent(player);
        });
    }

    /**
     * Returns whether a specific player can be chosen as an opponent.
     */
    canChooseOpponent(opponent) {
        if(_.isFunction(this.chooseOpponentFunc)) {
            return this.chooseOpponentFunc(opponent);
        }

        return this.chooseOpponentFunc === true;
    }

    /**
     * Returns whether there are eligible cards available to fulfill targets.
     *
     * @returns {Boolean}
     */
    canResolveTargets(context) {
        const ValidTypes = ['character', 'attachment', 'location', 'event'];
        return _.all(this.targets, target => {
            return context.game.allCards.any(card => {
                if(!ValidTypes.includes(card.getType())) {
                    return false;
                }

                return target.cardCondition(card, context);
            });
        });
    }

    /**
     * Prompts the current player to choose each target defined for the ability.
     *
     * @returns {Array} An array of target resolution objects.
     */
    resolveTargets(context) {
        return _.map(this.targets, (targetProperties, name) => {
            return this.resolveTarget(context, name, targetProperties);
        });
    }

    resolveTarget(context, name, targetProperties) {
        let cardCondition = targetProperties.cardCondition;
        let otherProperties = _.omit(targetProperties, 'cardCondition');
        let result = { resolved: false, name: name, value: null };
        let promptProperties = {
            source: context.source,
            cardCondition: card => cardCondition(card, context),
            onSelect: (player, card) => {
                result.resolved = true;
                result.value = card;
                return true;
            },
            onCancel: () => {
                result.resolved = true;
                return true;
            }
        };
        context.game.promptForSelect(context.player, _.extend(promptProperties, otherProperties));
        return result;
    }

    /**
     * Executes the ability once all costs have been paid. Inheriting classes
     * should override this method to implement their behavior; by default it
     * does nothing.
     */
    executeHandler(context) { // eslint-disable-line no-unused-vars
    }

    isAction() {
        return true;
    }

    isPlayableEventAbility() {
        return false;
    }

    isCardAbility() {
        return true;
    }

    hasMax() {
        return false;
    }
}

module.exports = BaseAbility;
<commit_msg>Include faction card in target eligibility check (#1487)<commit_after>const _ = require('underscore');

/**
 * Base class representing an ability that can be done by the player. This
 * includes card actions, reactions, interrupts, playing a card, marshaling a
 * card, or ambushing a card.
 *
 * Most of the methods take a context object. While the structure will vary from
 * inheriting classes, it is guaranteed to have at least the `game` object, the
 * `player` that is executing the action, and the `source` card object that the
 * ability is generated from.
 */
class BaseAbility {
    /**
     * Creates an ability.
     *
     * @param {Object} properties - An object with ability related properties.
     * @param {Object|Array} properties.cost - optional property that specifies
     * the cost for the ability. Can either be a cost object or an array of cost
     * objects.
     */
    constructor(properties) {
        this.cost = this.buildCost(properties.cost);
        this.targets = this.buildTargets(properties);
        this.cannotBeCanceled = !!properties.cannotBeCanceled;
        this.chooseOpponentFunc = properties.chooseOpponent;
    }

    buildCost(cost) {
        if(!cost) {
            return [];
        }

        if(!_.isArray(cost)) {
            return [cost];
        }

        return cost;
    }

    buildTargets(properties) {
        if(properties.target) {
            return {
                target: properties.target
            };
        }

        if(properties.targets) {
            return properties.targets;
        }

        return {};
    }

    /**
     * Return whether all costs are capable of being paid for the ability.
     *
     * @returns {Boolean}
     */
    canPayCosts(context) {
        return _.all(this.cost, cost => cost.canPay(context));
    }

    /**
     * Resolves all costs for the ability prior to payment. Some cost objects
     * have a `resolve` method in order to prompt the user to make a choice,
     * such as choosing a card to kneel. Consumers of this method should wait
     * until all costs have a `resolved` value of `true` before proceeding.
     *
     * @returns {Array} An array of cost resolution results.
     */
    resolveCosts(context) {
        return _.map(this.cost, cost => {
            if(cost.resolve) {
                return cost.resolve(context);
            }

            return { resolved: true, value: cost.canPay(context) };
        });
    }

    /**
     * Pays all costs for the ability simultaneously.
     */
    payCosts(context) {
        _.each(this.cost, cost => {
            cost.pay(context);
        });
    }

    /**
     * Return whether when unpay is implemented for the ability cost and the
     * cost can be unpaid.
     *
     * @returns {boolean}
     */
    canUnpayCosts(context) {
        return _.all(this.cost, cost => cost.unpay && cost.canUnpay(context));
    }

    /**
     * Unpays each cost associated with the ability.
     */
    unpayCosts(context) {
        _.each(this.cost, cost => {
            cost.unpay(context);
        });
    }

    /**
     * Returns whether the ability requires an opponent to be chosen.
     */
    needsChooseOpponent() {
        return !!this.chooseOpponentFunc;
    }

    /**
     * Returns whether there are opponents that can be chosen, if the ability
     * requires that an opponent be chosen.
     */
    canResolveOpponents(context) {
        if(!this.needsChooseOpponent()) {
            return true;
        }

        return _.any(context.game.getPlayers(), player => {
            return player !== context.player && this.canChooseOpponent(player);
        });
    }

    /**
     * Returns whether a specific player can be chosen as an opponent.
     */
    canChooseOpponent(opponent) {
        if(_.isFunction(this.chooseOpponentFunc)) {
            return this.chooseOpponentFunc(opponent);
        }

        return this.chooseOpponentFunc === true;
    }

    /**
     * Returns whether there are eligible cards available to fulfill targets.
     *
     * @returns {Boolean}
     */
    canResolveTargets(context) {
        const ValidTypes = ['character', 'attachment', 'location', 'event', 'faction'];
        return _.all(this.targets, target => {
            return context.game.allCards.any(card => {
                if(!ValidTypes.includes(card.getType())) {
                    return false;
                }

                return target.cardCondition(card, context);
            });
        });
    }

    /**
     * Prompts the current player to choose each target defined for the ability.
     *
     * @returns {Array} An array of target resolution objects.
     */
    resolveTargets(context) {
        return _.map(this.targets, (targetProperties, name) => {
            return this.resolveTarget(context, name, targetProperties);
        });
    }

    resolveTarget(context, name, targetProperties) {
        let cardCondition = targetProperties.cardCondition;
        let otherProperties = _.omit(targetProperties, 'cardCondition');
        let result = { resolved: false, name: name, value: null };
        let promptProperties = {
            source: context.source,
            cardCondition: card => cardCondition(card, context),
            onSelect: (player, card) => {
                result.resolved = true;
                result.value = card;
                return true;
            },
            onCancel: () => {
                result.resolved = true;
                return true;
            }
        };
        context.game.promptForSelect(context.player, _.extend(promptProperties, otherProperties));
        return result;
    }

    /**
     * Executes the ability once all costs have been paid. Inheriting classes
     * should override this method to implement their behavior; by default it
     * does nothing.
     */
    executeHandler(context) { // eslint-disable-line no-unused-vars
    }

    isAction() {
        return true;
    }

    isPlayableEventAbility() {
        return false;
    }

    isCardAbility() {
        return true;
    }

    hasMax() {
        return false;
    }
}

module.exports = BaseAbility;
<|endoftext|>


<commit_before>const GithubStrategy = require('passport-github2').Strategy;
const mongoose = require('mongoose');
const passport = require('passport');
const User = require('../../server/db/dbmodel').Users;

module.exports = () => {
  passport.use(new GithubStrategy({
    clientID: process.env.GITHUBID || require('../../config').GITHUB.github.clientID,
    clientSecret: process.env.GITHUBSECRET || require('../../config').GITHUB.github.clientSecret,
    callbackURL: process.env.URL || require('../../config').GITHUB.github.callbackURL,
  }, (accessToken, refreshToken, profile, cb) => {
      User.findOne({ githubId: profile.id }, (err, user) => {
        if (err) {
          console.log(err);  // handle errors!
        } else if (!user) {
          console.log(profile);
          user = new User({
            accessToken,
            refreshToken,
            _id: mongoose.Types.ObjectId(),
            gitHandle: profile.login,
            githubId: profile.id,
            name: profile.displayName,
            created: Date.now(),
            company: profile._json.company,
            blog: profile._json.blog,
            location: profile._json.location,
            bio: profile._json.bio,
            html_url: profile._json.html_url,
            avatar_url: profile._json.avatar_url,
            authored_challenges: [],
            completed_challenges: [],
            tutorial_progress: '',
          });
          user.save((err) => {
            if (err) {
              console.log(err);  // handle errors!
            } else {
              //console.log('INSIDE USER SAVE!', user);
              cb(null, user);
            }
          });
        } else {
          //console.log('CCCCBBBB', cb, 'USER:', user);
          cb(null, user);
        }
      });
    }
  ));
};
<commit_msg>[ BUGFIX ] Change login to username on user model<commit_after>const GithubStrategy = require('passport-github2').Strategy;
const mongoose = require('mongoose');
const passport = require('passport');
const User = require('../../server/db/dbmodel').Users;

module.exports = () => {
  passport.use(new GithubStrategy({
    clientID: process.env.GITHUBID || require('../../config').GITHUB.github.clientID,
    clientSecret: process.env.GITHUBSECRET || require('../../config').GITHUB.github.clientSecret,
    callbackURL: process.env.URL || require('../../config').GITHUB.github.callbackURL,
  }, (accessToken, refreshToken, profile, cb) => {
      User.findOne({ githubId: profile.id }, (err, user) => {
        if (err) {
          console.log(err);  // handle errors!
        } else if (!user) {
          user = new User({
            accessToken,
            refreshToken,
            _id: mongoose.Types.ObjectId(),
            gitHandle: profile.username,
            githubId: profile.id,
            name: profile.displayName,
            created: Date.now(),
            company: profile._json.company,
            blog: profile._json.blog,
            location: profile._json.location,
            bio: profile._json.bio,
            html_url: profile._json.html_url,
            avatar_url: profile._json.avatar_url,
            authored_challenges: [],
            completed_challenges: [],
            tutorial_progress: '',
          });
          user.save((err) => {
            if (err) {
              console.log(err);  // handle errors!
            } else {
              //console.log('INSIDE USER SAVE!', user);
              cb(null, user);
            }
          });
        } else {
          //console.log('CCCCBBBB', cb, 'USER:', user);
          cb(null, user);
        }
      });
    }
  ));
};
<|endoftext|>


<commit_before>// utilities
// const _ = require('lodash');
const glob = require('glob');

// variables
const scenariosArr = [];
let defs = [];
const scenarioDefaults = {
  url: 'http://localhost:3000',
  misMatchThreshold: 0.1,
  readyEvent: null,
  onReadyScript: 'onReady.js',
};

// functions for creating scenarios
function createScenario(def) {
  const finalScenario = Object.assign({}, scenarioDefaults, def);
  scenariosArr.push(finalScenario);
}

function splitScenario(def, type = '', selectorsArr, extraOptions = {}) {
  const scenario = Object.assign({}, extraOptions, def);
  scenario.label = `${def.label} ${type}`;
  selectorsArr.forEach((s) => {
    scenario[`${type}Selector`] = true;
    scenario.selectors = [s];
    createScenario(scenario);
  });
}

// get backstop definition files and concat the contents
const files = glob.sync('./src/**/*.backstop.js', { ignore: ['./src/**/node_modules/**'] });

files.forEach((file) => {
  defs = defs.concat(require(file));
});

defs.forEach((def) => {
  const currDef = def;

  if (Object.prototype.hasOwnProperty.call(currDef, 'hoverSelectors')) {
    const { hoverSelectors } = currDef;
    delete currDef.hoverSelectors;
    splitScenario(currDef, 'hover', hoverSelectors, { hoverWait: 1000 });
  }

  if (Object.prototype.hasOwnProperty.call(currDef, 'focusSelectors')) {
    const { focusSelectors } = currDef;
    delete currDef.focusSelectors;
    splitScenario(currDef, 'focus', focusSelectors, { focusWait: 1000 });
  }

  createScenario(currDef);
});

module.exports = {
  id: 'cedar',
  viewports: [
    {
      label: 'xs',
      width: 360,
      height: 640,
    },
    {
      label: 'sm',
      width: 768,
      height: 1024,
    },
    {
      label: 'md',
      width: 1024,
      height: 768,
    },
    {
      label: 'lg',
      width: 1366,
      height: 768,
    },
  ],
  scenarios: scenariosArr,
  paths: {
    bitmaps_reference: 'backstop_data/bitmaps_reference',
    bitmaps_test: 'backstop_data/bitmaps_test',
    engine_scripts: 'backstop_data/engine_scripts',
    html_report: 'backstop_data/html_report',
    ci_report: 'backstop_data/ci_report',
  },
  asyncCaptureLimit: 5,
  asyncCompareLimit: 10,
  engine: 'chrome',
  report: ['browser'],
  debug: false,
  debugWindow: false,
};
<commit_msg>style(backstop): change 'chrome' to 'chromy'<commit_after>// utilities
// const _ = require('lodash');
const glob = require('glob');

// variables
const scenariosArr = [];
let defs = [];
const scenarioDefaults = {
  url: 'http://localhost:3000',
  misMatchThreshold: 0.1,
  readyEvent: null,
  onReadyScript: 'onReady.js',
};

// functions for creating scenarios
function createScenario(def) {
  const finalScenario = Object.assign({}, scenarioDefaults, def);
  scenariosArr.push(finalScenario);
}

function splitScenario(def, type = '', selectorsArr, extraOptions = {}) {
  const scenario = Object.assign({}, extraOptions, def);
  scenario.label = `${def.label} ${type}`;
  selectorsArr.forEach((s) => {
    scenario[`${type}Selector`] = true;
    scenario.selectors = [s];
    createScenario(scenario);
  });
}

// get backstop definition files and concat the contents
const files = glob.sync('./src/**/*.backstop.js', { ignore: ['./src/**/node_modules/**'] });

files.forEach((file) => {
  defs = defs.concat(require(file));
});

defs.forEach((def) => {
  const currDef = def;

  if (Object.prototype.hasOwnProperty.call(currDef, 'hoverSelectors')) {
    const { hoverSelectors } = currDef;
    delete currDef.hoverSelectors;
    splitScenario(currDef, 'hover', hoverSelectors, { hoverWait: 1000 });
  }

  if (Object.prototype.hasOwnProperty.call(currDef, 'focusSelectors')) {
    const { focusSelectors } = currDef;
    delete currDef.focusSelectors;
    splitScenario(currDef, 'focus', focusSelectors, { focusWait: 1000 });
  }

  createScenario(currDef);
});

module.exports = {
  id: 'cedar',
  viewports: [
    {
      label: 'xs',
      width: 360,
      height: 640,
    },
    {
      label: 'sm',
      width: 768,
      height: 1024,
    },
    {
      label: 'md',
      width: 1024,
      height: 768,
    },
    {
      label: 'lg',
      width: 1366,
      height: 768,
    },
  ],
  scenarios: scenariosArr,
  paths: {
    bitmaps_reference: 'backstop_data/bitmaps_reference',
    bitmaps_test: 'backstop_data/bitmaps_test',
    engine_scripts: 'backstop_data/engine_scripts',
    html_report: 'backstop_data/html_report',
    ci_report: 'backstop_data/ci_report',
  },
  asyncCaptureLimit: 5,
  asyncCompareLimit: 10,
  engine: 'chromy',
  report: ['browser'],
  debug: false,
  debugWindow: false,
};
<|endoftext|>


<commit_before>function clearErrors(context) {
    $('.errorlist', context).remove();
    $('.error', context).removeClass('error');
}

function populateErrors(context, o) {
    clearErrors(context);
    var $list = $('

');
    $.each(o, function(i, v) {
        var $row = $('[name=' + i + ']', context).closest('.row');
        $row.addClass('error');
        $row.append($list.append($(format('
{0}
', v))));
    });
}

function fieldFocused(e) {
    var tags = /input|keygen|meter|option|output|progress|select|textarea/i;
    return tags.test(e.target.nodeName);
}

function postUnsaved(data) {
    $('input[name="unsaved_data"]').val(JSON.stringify(data));
}

function loadUnsaved() {
    return JSON.parse($('input[name="unsaved_data"]').val() || '{}');
}
<commit_msg>Fix XSS in populateErrors<commit_after>function clearErrors(context) {
    $('.errorlist', context).remove();
    $('.error', context).removeClass('error');
}

function populateErrors(context, o) {
    clearErrors(context);
    var $list = $('

');
    $.each(o, function(i, v) {
        var $row = $('[name=' + i + ']', context).closest('.row');
        $row.addClass('error');
        $row.append($list.append($(format('
{0}
', _.escape(v)))));
    });
}

function fieldFocused(e) {
    var tags = /input|keygen|meter|option|output|progress|select|textarea/i;
    return tags.test(e.target.nodeName);
}

function postUnsaved(data) {
    $('input[name="unsaved_data"]').val(JSON.stringify(data));
}

function loadUnsaved() {
    return JSON.parse($('input[name="unsaved_data"]').val() || '{}');
}
<|endoftext|>


<commit_before>var the_prefix = "";
var kansascomet_session;
var eventQueues = {};   // TODO: add the use of the queue
var eventCallbacks = {};

(function($) {
//    var the_prefix = "";

   $.kc = {
	connect: function(prefix) {
		the_prefix = prefix;
		alert("Ha");
    		$.ajax({ url: the_prefix,
              		type: "POST",
              		data: "",
              		dataType: "script"});
	},
	session: function(session_id) {
		kansascomet_session = session_id;
		$.kc.redraw(0);
	},
	redraw: function (count) {
		$.ajax({ url: the_prefix + "/act/" + kansascomet_session + "/" + count,
            		type: "GET",
            		dataType: "script",
            		success: function success() { $.kc.redraw(count + 1); }
		       });
            	// TODO: Add failure; could happen
        },
	// This says someone is listening on a specific event
	register: function (eventname, fn) {
     		eventQueues[eventname] = [];
     		$("body").on(eventname, "." + eventname, function (event,aux) {
        		var e = fn(this,event,aux);
//			$("#log").append('{e:' + eventname  + '+' + $(this).slider('value') + ',' + $.toJSON(ui) + '}');
        		e.eventname = eventname;
			//      alert("EVENT " + e);
        		if (eventCallbacks[eventname] == undefined) {
				//              alert('pushing, no one is waiting (TO BE DONE)');
        			// These are effectively ignored (TODO: fix)
                		eventQueues[eventname].push(e);
        		} else {
                		eventCallbacks[eventname](e);
        		}
     		});
	},
	// This waits for an event. The second argument is the continuation
	waitFor: function (eventname, fn) {
   		// TODO: check to see if there is an event waiting
   		if (eventCallbacks[eventname] == undefined) {
       			eventCallbacks[eventname] = function (e) {
          			// delete the callback
          			delete eventCallbacks[eventname];
          			// and do the callback
          			fn(e);
       			}
   		} else {
        		alert("ABORT: reassigning the event queue callback");
   		}
	},
	// There is a requirement that obj be an object or array.
	// See RFC 4627 for details.
	reply: function (uq,obj) {
        	$.ajax({ url: the_prefix + "/reply/" + kansascomet_session + "/" + uq,
                 	type: "POST",
                 	data: $.toJSON(obj),
                 	contentType: "application/json; charset=utf-8",
                 	dataType: "json"});
	}
     };
})(jQuery);

<commit_msg>Adding the waiting for a (queued) event.<commit_after>// Kansas Comet jQuery plugin
(function($) {
   var the_prefix = "";
   var kansascomet_session;
   var eventQueues = {};   // TODO: add the use of the queue
   var eventCallbacks = {};

   $.kc = {
	connect: function(prefix) {
		the_prefix = prefix;
    		$.ajax({ url: the_prefix,
              		type: "POST",
              		data: "",
              		dataType: "script"});
	},
	session: function(session_id) {
		kansascomet_session = session_id;
		$.kc.redraw(0);
	},
	redraw: function (count) {
		$.ajax({ url: the_prefix + "/act/" + kansascomet_session + "/" + count,
            		type: "GET",
            		dataType: "script",
            		success: function success() { $.kc.redraw(count + 1); }
		       });
            	// TODO: Add failure; could happen
        },
	// This says someone is listening on a specific event
	register: function (eventname, fn) {
     		eventQueues[eventname] = [];
     		$("body").on(eventname, "." + eventname, function (event,aux) {
        		var e = fn(this,event,aux);
//			$("#log").append('{e:' + eventname  + '+' + $(this).slider('value') + ',' + $.toJSON(ui) + '}');
        		e.eventname = eventname;
			//      alert("EVENT " + e);
        		if (eventCallbacks[eventname] == undefined) {
                		eventQueues[eventname].push(e);
        		} else {
                		eventCallbacks[eventname](e);
        		}
     		});
	},
	// This waits for an event. The second argument is the continuation
	waitFor: function (eventname, fn) {
		var e = eventQueues[eventname].shift();
		if (e != undefined) {
			// call with event from queue
			fn(e);
		} else if (eventCallbacks[eventname] == undefined) {
       			eventCallbacks[eventname] = function (e) {
          			// delete the callback
          			delete eventCallbacks[eventname];
          			// and do the callback
          			fn(e);
       			}
   		} else {
        		alert("ABORT: reassigning the event queue callback");
   		}
	},
	// There is a requirement that obj be an object or array.
	// See RFC 4627 for details.
	reply: function (uq,obj) {
        	$.ajax({ url: the_prefix + "/reply/" + kansascomet_session + "/" + uq,
                 	type: "POST",
                 	data: $.toJSON(obj),
                 	contentType: "application/json; charset=utf-8",
                 	dataType: "json"});
	}
     };
})(jQuery);

<|endoftext|>


<commit_before>/**
 * Set up Pulsar's UI environment
 */

define([
  'jquery',
  'choice-matrix'
], function(
  $,
  FieldMatrix
) {

    $(document).ready(function() {

        // Set up Pulsar's UI environment
        require([
            'actions-menu',
            'bootstrap-tour',
            'codemirror',
            'tooltip',
            'sticky',
            'datagrid',
            'tooltip',
            'highlightjs',
            'jquery-placeholder',
            'summernote',
            'toggles',
            'uploader'
            ], function() {

            // tooltips (js/tooltip.js)
            //$('[data-toggle="tooltips"]').tooltip();

            // actions menu
            $('.actions-menu').actionsMenu();

            matrix = new FieldMatrix();
            matrix.init();

            // sticky toolbar
            //$('.toolbar').sticky({topSpacing: 0});

            $('.uploader').uploader();

            // tooltips (js/tooltip.js)
            $('[data-toggle="tooltips"]').tooltip();

            $('.summernote').summernote({
              codemirror: { // codemirror options
                theme: 'monokai'
              },
              minHeight: 400,
              toolbar: [
                //[groupname, [button list]]
                ['style', ['style']],
                ['style', ['bold', 'italic', 'underline', 'strikethrough', 'clear']],
                ['color', ['color']],
                ['para', ['ul', 'ol', 'paragraph']],
                ['insert', ['link', 'picture', 'video', 'table']],
                ['misc', ['codeview', 'help']]
              ]
            });

            $('[data-toggle=settings]').on('click', function() {
              $('.settings').toggleClass('open');
            });

            $('[data-toggle-checkbox]').each(function() {
              var $this = $(this),
                  $target = $('#' + $this.data('toggle-checkbox')),
                  $icon = $this.closest('.setting').find('.setting__icon'),
                  checked = false;

              if ($target.attr('checked')) {
                checked = true;

                $icon.addClass('is-enabled');
              } else {
                $icon.removeClass('is-enabled');
              }

              $this.toggles({
                animate: 100,
                on: checked
              });

              $this.on('toggle', function (e, active) {
                if (active) {
                  $icon.addClass('is-enabled');
                } else {
                  $icon.removeClass('is-enabled');
                }
              });

            });

            // datagrid
            $('.table--datagrid').each(function() {
                $(this).datagrid();
            });

            // syntax highlighting
            if (!$('html.ie7').size()) { // IE8 and up only
                var aCodes = document.getElementsByTagName('pre');
                for (var i=0; i < aCodes.length; i++) {
                    hljs.highlightBlock(aCodes[i]);
                }
            };

            // Don't allow disabled links, or links with popovers to be clicked
            $('a.disabled').on('click', function(e) {
                e.preventDefault();
                e.stopPropagation();
            });

            $('a.has-popover').on('click', function (e) {
                e.preventDefault();
                e.stopPropagation();

                $(this).addClass('active');
            });

            $('[data-toggle*=button]').on('click', function(e) {
                $(this).toggleClass('active');
            });

            // Add placholder support for browsers that don't support it
            $('input, textarea').placeholder();

            // Add placholder support for browsers that don't support it
            $('input:not([data-datepicker=true]), textarea').placeholder();

        });

// To clean up -----------------

        // date pickers
        require(['pikaday', 'sticky'], function(Pikaday) {
            $('[data-datepicker=true]').each(function() {
                new Pikaday({
                    field: this,
                    format: 'ddd DD/MM/YYYY'
                });
            });
        });

        // TODO: Move this to the dashboard view
        require(['dashboard'], function() {
            $('.dashboard').dashboard();
        });

        // Show and hide mobile-only elements
        function mobileToggle() {
            $('[data-mobile-toggle-button]').each(function() {
                var target = $(this).attr('data-toggle-target');

                if (!window.matchMedia('(min-width: 768px)').matches) {
                    $(target).each(function() {
                        if (!($(this).parents(target).length)) {
                            $(this).attr('data-mobile-togglable', '').show();
                        }
                    });

                    $(this).off('click.mobileToggle touchenter.mobileToggle').on('click.mobileToggle touchenter.mobileToggle', function(e) {
                        e.preventDefault();

                        if (target === '.tabs__list') {
                            $(target + '[data-mobile-togglable]').css({'top': ($('.toolbar').outerHeight())});
                        }

                        $(this).toggleClass('toggled');
                        $(target + '[data-mobile-togglable]').toggleClass('toggled');
                    });
                }
                else {
                    $(this).removeClass('toggled');
                    $(target + '[data-mobile-togglable]').removeAttr('data-mobile-togglable').removeClass('toggled');
                }
            });
        }
        mobileToggle();

        // Make datagrid tables look better on smaller viewports
        function mobileTables() {
            $('.table--datagrid tr td').each(function() {
                var tableCellPosition = $(this).index() + 1,
                    tableHeader = $(this).closest('table').find('th:nth-child(' + tableCellPosition + ')').text();

                $(this).attr('data-table-header', tableHeader);
            });
        }
        mobileTables();

        // Responsive actions menu positioning
        var mobileMenu = $('.actions-menu .dropdown__menu').clone()

        $('.toolbar').append(mobileMenu);
        // console.log($('.toolbar > .dropdown__menu'));
        // $('.toolbar > .dropdown__menu').addClass('mobile-actions-menu').show();

        // function actionsMenu() {
        //     if (window.matchMedia('(max-width: 767px)').matches) {
        //         var topHidden = -($('.mobile-actions-menu').outerHeight() + $('.toolbar').outerHeight()),
        //             topRevealed = $('.toolbar').outerHeight() - parseInt($('.actionsbar--left').css('marginTop'));

        //         // $('.actions-menu .dropdown__menu').hide();
        //         //if ($('.toolbar .dropdown__menu').length < 1) {
        //         //}
        //         // ({'top': topHidden}).show().parent().removeClass('open');

        //         $('.actions-menu [data-toggle=dropdown]').on('click touchenter', function() {
        //             if ((!$(this).parent().hasClass('open')) && window.matchMedia('(max-width: 767px)').matches) {
        //                 $('.mobile-actions-menu').css({'marginTop': 0});
        //             }
        //             else if (window.matchMedia('(max-width: 767px)').matches) {
        //                 $('.mobile-actions-menu').css({'marginTop': topHidden});
        //             }
        //         });
        //     }
        //     else {
        //         $('.actions-menu .dropdown__menu').removeAttr('style');
        //     }
        // }
        // actionsMenu();

        // Do these things whenever the window resizes
        $(window).resize(function() {
            mobileToggle();
            // actionsMenu();

            // Refresh positions of sticky elements
            console.log($('.is-sticky'));
            $('.is-sticky').sticky('update');

            $('.tabs__list[data-mobile-togglable]').css({'top': ($('.toolbar').outerHeight() - 3)});
        });

        // Show summary panels based on their data-tab value
        require(['tab'], function() {
            $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
                e.target // activated tab
                e.relatedTarget // previous tab

                $('.summary.open').removeClass('open').hide();

                var $summary = '';

                if ($(e.target).parent().has('.is-active').length != 0) {
                    var $pane = $($('.is-active > a', $(e.target).parent()).attr('href'));
                    if ($pane.attr('data-summary') != 'undefined') {
                        $summary = $('[data-tab="' + $pane.attr('data-summary') + '"]');
                    }
                } else {
                    $summary = $($(e.target).attr('data-summary'));
                }

                if ($summary.length) {
                    $summary.show().addClass('open');
                } else {
                    $summary.hide();
                }
            });
        });

        if ($('[data-summary]').hasClass('is-active')) {
            $('[data-tab="' + $('[data-summary]').attr('href') + '"]').show();
        }

        require(['daterange'], function() {
            $('[data-daterange]').daterangepicker(
                {
                  ranges: {
                     'Today': [moment(), moment()],
                     'Yesterday': [moment().subtract('days', 1), moment().subtract('days', 1)],
                     'Last 7 Days': [moment().subtract('days', 6), moment()],
                     'Last 30 Days': [moment().subtract('days', 29), moment()],
                     'This Month': [moment().startOf('month'), moment().endOf('month')],
                     'Last Month': [moment().subtract('month', 1).startOf('month'), moment().subtract('month', 1).endOf('month')]
                  },
                  startDate: moment().subtract('days', 29),
                  endDate: moment()
                },
                function(start, end) {
                    var label,
                        startLabel = start.format('MMMM D, YYYY'),
                        endLabel = end.format('MMMM D, YYYY');

                    if (startLabel === endLabel) {
                        label = startLabel;
                    } else {
                        label = startLabel + ' - ' + endLabel;
                    }
                    $('[data-daterange]').html('Created: ' + label);
                }
            );
        });

        // Switch a given element within the same data-group
        $('[data-switch]').on('click', function(e) {
            var $this = $(this);

            if ($this.hasClass('active')) {
                return false;
            } else {
                $this.siblings().removeClass('active');
            }

            $($this.data('group')).hide();
            $this.addClass('active');
            $($this.data('switch')).show();
        });

        $('[data-hide]').on('click', function(e) {
            $($(this).data('hide')).hide();
        });

        $('[data-show]').on('click', function(e) {
            $($(this).data('show')).show();
        });

    });

});

<commit_msg>Removed some old logs breaking IE9<commit_after>/**
 * Set up Pulsar's UI environment
 */

define([
  'jquery',
  'choice-matrix'
], function(
  $,
  FieldMatrix
) {

    $(document).ready(function() {

        // Set up Pulsar's UI environment
        require([
            'actions-menu',
            'bootstrap-tour',
            'codemirror',
            'tooltip',
            'sticky',
            'datagrid',
            'tooltip',
            'highlightjs',
            'jquery-placeholder',
            'summernote',
            'toggles',
            'uploader'
            ], function() {

            // tooltips (js/tooltip.js)
            //$('[data-toggle="tooltips"]').tooltip();

            // actions menu
            $('.actions-menu').actionsMenu();

            matrix = new FieldMatrix();
            matrix.init();

            // sticky toolbar
            //$('.toolbar').sticky({topSpacing: 0});

            $('.uploader').uploader();

            // tooltips (js/tooltip.js)
            $('[data-toggle="tooltips"]').tooltip();

            $('.summernote').summernote({
              codemirror: { // codemirror options
                theme: 'monokai'
              },
              minHeight: 400,
              toolbar: [
                //[groupname, [button list]]
                ['style', ['style']],
                ['style', ['bold', 'italic', 'underline', 'strikethrough', 'clear']],
                ['color', ['color']],
                ['para', ['ul', 'ol', 'paragraph']],
                ['insert', ['link', 'picture', 'video', 'table']],
                ['misc', ['codeview', 'help']]
              ]
            });

            $('[data-toggle=settings]').on('click', function() {
              $('.settings').toggleClass('open');
            });

            $('[data-toggle-checkbox]').each(function() {
              var $this = $(this),
                  $target = $('#' + $this.data('toggle-checkbox')),
                  $icon = $this.closest('.setting').find('.setting__icon'),
                  checked = false;

              if ($target.attr('checked')) {
                checked = true;

                $icon.addClass('is-enabled');
              } else {
                $icon.removeClass('is-enabled');
              }

              $this.toggles({
                animate: 100,
                on: checked
              });

              $this.on('toggle', function (e, active) {
                if (active) {
                  $icon.addClass('is-enabled');
                } else {
                  $icon.removeClass('is-enabled');
                }
              });

            });

            // datagrid
            $('.table--datagrid').each(function() {
                $(this).datagrid();
            });

            // syntax highlighting
            if (!$('html.ie7').size()) { // IE8 and up only
                var aCodes = document.getElementsByTagName('pre');
                for (var i=0; i < aCodes.length; i++) {
                    hljs.highlightBlock(aCodes[i]);
                }
            };

            // Don't allow disabled links, or links with popovers to be clicked
            $('a.disabled').on('click', function(e) {
                e.preventDefault();
                e.stopPropagation();
            });

            $('a.has-popover').on('click', function (e) {
                e.preventDefault();
                e.stopPropagation();

                $(this).addClass('active');
            });

            $('[data-toggle*=button]').on('click', function(e) {
                $(this).toggleClass('active');
            });

            // Add placholder support for browsers that don't support it
            $('input, textarea').placeholder();

            // Add placholder support for browsers that don't support it
            $('input:not([data-datepicker=true]), textarea').placeholder();

        });

// To clean up -----------------

        // date pickers
        require(['pikaday', 'sticky'], function(Pikaday) {
            $('[data-datepicker=true]').each(function() {
                new Pikaday({
                    field: this,
                    format: 'ddd DD/MM/YYYY'
                });
            });
        });

        // TODO: Move this to the dashboard view
        require(['dashboard'], function() {
            $('.dashboard').dashboard();
        });

        // Show and hide mobile-only elements
        function mobileToggle() {
            $('[data-mobile-toggle-button]').each(function() {
                var target = $(this).attr('data-toggle-target');

                if (!window.matchMedia('(min-width: 768px)').matches) {
                    $(target).each(function() {
                        if (!($(this).parents(target).length)) {
                            $(this).attr('data-mobile-togglable', '').show();
                        }
                    });

                    $(this).off('click.mobileToggle touchenter.mobileToggle').on('click.mobileToggle touchenter.mobileToggle', function(e) {
                        e.preventDefault();

                        if (target === '.tabs__list') {
                            $(target + '[data-mobile-togglable]').css({'top': ($('.toolbar').outerHeight())});
                        }

                        $(this).toggleClass('toggled');
                        $(target + '[data-mobile-togglable]').toggleClass('toggled');
                    });
                }
                else {
                    $(this).removeClass('toggled');
                    $(target + '[data-mobile-togglable]').removeAttr('data-mobile-togglable').removeClass('toggled');
                }
            });
        }
        mobileToggle();

        // Make datagrid tables look better on smaller viewports
        function mobileTables() {
            $('.table--datagrid tr td').each(function() {
                var tableCellPosition = $(this).index() + 1,
                    tableHeader = $(this).closest('table').find('th:nth-child(' + tableCellPosition + ')').text();

                $(this).attr('data-table-header', tableHeader);
            });
        }
        mobileTables();

        // Responsive actions menu positioning
        var mobileMenu = $('.actions-menu .dropdown__menu').clone()

        $('.toolbar').append(mobileMenu);
        // console.log($('.toolbar > .dropdown__menu'));
        // $('.toolbar > .dropdown__menu').addClass('mobile-actions-menu').show();

        // function actionsMenu() {
        //     if (window.matchMedia('(max-width: 767px)').matches) {
        //         var topHidden = -($('.mobile-actions-menu').outerHeight() + $('.toolbar').outerHeight()),
        //             topRevealed = $('.toolbar').outerHeight() - parseInt($('.actionsbar--left').css('marginTop'));

        //         // $('.actions-menu .dropdown__menu').hide();
        //         //if ($('.toolbar .dropdown__menu').length < 1) {
        //         //}
        //         // ({'top': topHidden}).show().parent().removeClass('open');

        //         $('.actions-menu [data-toggle=dropdown]').on('click touchenter', function() {
        //             if ((!$(this).parent().hasClass('open')) && window.matchMedia('(max-width: 767px)').matches) {
        //                 $('.mobile-actions-menu').css({'marginTop': 0});
        //             }
        //             else if (window.matchMedia('(max-width: 767px)').matches) {
        //                 $('.mobile-actions-menu').css({'marginTop': topHidden});
        //             }
        //         });
        //     }
        //     else {
        //         $('.actions-menu .dropdown__menu').removeAttr('style');
        //     }
        // }
        // actionsMenu();

        // Do these things whenever the window resizes
        $(window).resize(function() {
            mobileToggle();
            // actionsMenu();

            // Refresh positions of sticky elements
            //console.log($('.is-sticky'));
            $('.is-sticky').sticky('update');

            $('.tabs__list[data-mobile-togglable]').css({'top': ($('.toolbar').outerHeight() - 3)});
        });

        // Show summary panels based on their data-tab value
        require(['tab'], function() {
            $('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
                e.target // activated tab
                e.relatedTarget // previous tab

                $('.summary.open').removeClass('open').hide();

                var $summary = '';

                if ($(e.target).parent().has('.is-active').length != 0) {
                    var $pane = $($('.is-active > a', $(e.target).parent()).attr('href'));
                    if ($pane.attr('data-summary') != 'undefined') {
                        $summary = $('[data-tab="' + $pane.attr('data-summary') + '"]');
                    }
                } else {
                    $summary = $($(e.target).attr('data-summary'));
                }

                if ($summary.length) {
                    $summary.show().addClass('open');
                } else {
                    $summary.hide();
                }
            });
        });

        if ($('[data-summary]').hasClass('is-active')) {
            $('[data-tab="' + $('[data-summary]').attr('href') + '"]').show();
        }

        require(['daterange'], function() {
            $('[data-daterange]').daterangepicker(
                {
                  ranges: {
                     'Today': [moment(), moment()],
                     'Yesterday': [moment().subtract('days', 1), moment().subtract('days', 1)],
                     'Last 7 Days': [moment().subtract('days', 6), moment()],
                     'Last 30 Days': [moment().subtract('days', 29), moment()],
                     'This Month': [moment().startOf('month'), moment().endOf('month')],
                     'Last Month': [moment().subtract('month', 1).startOf('month'), moment().subtract('month', 1).endOf('month')]
                  },
                  startDate: moment().subtract('days', 29),
                  endDate: moment()
                },
                function(start, end) {
                    var label,
                        startLabel = start.format('MMMM D, YYYY'),
                        endLabel = end.format('MMMM D, YYYY');

                    if (startLabel === endLabel) {
                        label = startLabel;
                    } else {
                        label = startLabel + ' - ' + endLabel;
                    }
                    $('[data-daterange]').html('Created: ' + label);
                }
            );
        });

        // Switch a given element within the same data-group
        $('[data-switch]').on('click', function(e) {
            var $this = $(this);

            if ($this.hasClass('active')) {
                return false;
            } else {
                $this.siblings().removeClass('active');
            }

            $($this.data('group')).hide();
            $this.addClass('active');
            $($this.data('switch')).show();
        });

        $('[data-hide]').on('click', function(e) {
            $($(this).data('hide')).hide();
        });

        $('[data-show]').on('click', function(e) {
            $($(this).data('show')).show();
        });

    });

});

<|endoftext|>


<commit_before>var AbstractShaderClosure = require("./../abstractshaderclosure.js");
var JSShaderComposer = require("./jsshadercomposer.js");
var SystemNotifier = require("../../system/system-notifier.js");
var getJSSystemConfiguration = require("./jssystemconfiguration.js");
var XC = require("../../../../xflow/interface/constants.js");
var Options = require("../../../../utils/options.js");

var c_jsShaderCache = {};

function convertEnvName(name) {
    return ("_env_" + name).replace(/_+/g, "_");
}

function addDefaultChanneling(vsConfig, inputName) {
    var outputName = convertEnvName(inputName);
    vsConfig.channelAttribute(inputName, outputName, null);
}

function channelVsAttribute(vsConfig, inputName, spaceInfo) {
    if (!spaceInfo || !spaceInfo[inputName]) {
        addDefaultChanneling(vsConfig, inputName);
        return;
    }

    var i = spaceInfo[inputName].length;
    while (i--) {
        var entry = spaceInfo[inputName][i];
        var outputName = convertEnvName(entry.name), code = null;
        switch (entry.space) {
            case Shade.SPACE_VECTOR_TYPES.OBJECT:
                break;
            case Shade.SPACE_VECTOR_TYPES.VIEW_POINT:
                vsConfig.addInputParameter(XC.DATA_TYPE.FLOAT4X4, "modelViewMatrix", true);
                code = outputName + " = ( modelViewMatrix * vec4(#I{" + inputName + "}, 1.0) ).xyz;";
                break;
            case Shade.SPACE_VECTOR_TYPES.VIEW_NORMAL:
                vsConfig.addInputParameter(XC.DATA_TYPE.FLOAT3X3, "modelViewMatrixN", true);
                code = outputName + " = normalize( modelViewMatrixN * #I{" + inputName + "} );";
                break;
            case Shade.SPACE_VECTOR_TYPES.WORLD_POINT:
                vsConfig.addInputParameter(XC.DATA_TYPE.FLOAT4X4, "modelMatrix", true);
                code = outputName + " = ( modelMatrix * vec4(#I{" + inputName + "}, 1.0) ).xyz;";
                break;
            case Shade.SPACE_VECTOR_TYPES.WORLD_NORMAL:
                vsConfig.addInputParameter(XC.DATA_TYPE.FLOAT3X3, "modelMatrixN", true);
                code = outputName + " = normalize( modelMatrixN * #I{" + inputName + "} );";
                break;
            default:
                throw new Error("Can't handle Space Type: " + entry.space);
        }
        vsConfig.channelAttribute(inputName, outputName, code);
    }
}

/**
 * @param {XC.DATA_TYPE} xflowType
 */
var convertXflow2ShadeType = function (xflowType, source) {
    var result = {}
    switch (xflowType) {
        case XC.DATA_TYPE.BOOL:
            result.type = Shade.TYPES.BOOLEAN;
            break;
        case XC.DATA_TYPE.INT:
            result.type = Shade.TYPES.INT;
            break;
        case XC.DATA_TYPE.FLOAT:
            result.type = Shade.TYPES.NUMBER;
            break;
        case XC.DATA_TYPE.FLOAT2:
            result.type = Shade.TYPES.OBJECT;
            result.kind = Shade.OBJECT_KINDS.FLOAT2;
            break;
        case XC.DATA_TYPE.FLOAT3:
            result.type = Shade.TYPES.OBJECT;
            result.kind = Shade.OBJECT_KINDS.FLOAT3;
            break;
        case XC.DATA_TYPE.FLOAT4:
            result.type = Shade.TYPES.OBJECT;
            result.kind = Shade.OBJECT_KINDS.FLOAT4;
            break;
        case XC.DATA_TYPE.FLOAT3X3:
            result.type = Shade.TYPES.OBJECT;
            result.kind = Shade.OBJECT_KINDS.MATRIX3;
            break;
        case XC.DATA_TYPE.FLOAT4X4:
            result.type = Shade.TYPES.OBJECT;
            result.kind = Shade.OBJECT_KINDS.MATRIX4;
            break;
        case XC.DATA_TYPE.TEXTURE:
            result.type = Shade.TYPES.OBJECT;
            result.kind = Shade.OBJECT_KINDS.TEXTURE;
            break;
        case XC.DATA_TYPE.UNKNOWN:
        default:
            throw new Error("Unknown Xflow DataType: " + xflowType);
    }
    result.source = source;
    return result;
}

/**
 * @param context
 * @param sourceTemplate
 * @param dataCallback
 * @constructor
 */
var JSShaderClosure = function (context, sourceTemplate, extractedParams) {
    AbstractShaderClosure.call(this, context);
    this.sourceTemplate = sourceTemplate;
    this.extractedParams = extractedParams;
    this.uniformSetter = function () {
    };
    this.uniformConverter = [];
};

XML3D.createClass(JSShaderClosure, AbstractShaderClosure, {
    /**
     *
     * @param {GLScene} scene
     * @param {Xflow.ComputeResult} shaderResult
     * @param objectData
     */
    createSources: function (scene, shaderResult, vsRequest) {

        var vsDataResult = vsRequest.getResult();

        var systemParameters = getSystemParameters(this.context, scene.systemUniforms);
        var environmentParameters = {};

        var shaderEntries = shaderResult && shaderResult.getOutputMap(), vsShaderOutput = vsDataResult && vsDataResult.outputNames;

        for (var i = 0; i < this.extractedParams.length; ++i) {
            var paramName = this.extractedParams[i];
            if (vsShaderOutput && vsShaderOutput.indexOf(paramName) != -1) {
                environmentParameters[paramName] = convertXflow2ShadeType(vsDataResult.getOutputType(paramName), vsDataResult.isOutputUniform(paramName) ? Shade.SOURCES.UNIFORM : Shade.SOURCES.VERTEX);
            } else if (shaderEntries && shaderEntries[paramName]) {
                environmentParameters[paramName] = convertXflow2ShadeType(shaderEntries[paramName].type, Shade.SOURCES.UNIFORM);
            }
        }

        var contextData = {
            "this": { "type": "object", "kind": "any", "info": systemParameters },
            "global.shade": [{"extra": {"type": "object", "kind": "any", "global": true, "info": environmentParameters }}]
        };

        XML3D.debug.logDebug("CONTEXT:", contextData);

        var options = {
            propagateConstants: true,
            validate: true,
            sanitize: true,
            transformSpaces: Options.getValue("shadejs-transformSpaces"),
            extractUniformExpressions: Options.getValue("shadejs-extractUniformExpressions")
        };
        var compileOptions = {
            useStatic: true, uniformExpressions: options.uniformExpressions
        };
        var implementation = scene.deferred ? "xml3d-glsl-deferred" : "xml3d-glsl-forward";

        var jsShaderKey = implementation + ";" + JSON.stringify(options) + ";" + JSON.stringify(environmentParameters) + ";" + this.sourceTemplate;

        var cacheEntry;
        if (!(cacheEntry = c_jsShaderCache[jsShaderKey])) {
            try {
                var workSet = new Shade.WorkingSet();
                workSet.parse(this.sourceTemplate, {loc: true});
                workSet.analyze(contextData, implementation, options);
                var spaceInfo = workSet.getProcessingData('spaceInfo');
                var glslShader = workSet.compileFragmentShader(compileOptions);

                cacheEntry = {
                    source: glslShader.source, uniformSetter: glslShader.uniformSetter, spaceInfo: spaceInfo
                }

                this.uniformSetter = glslShader.uniformSetter;
                this.source = {
                    fragment: glslShader.source, vertex: this.createVertexShader(vsRequest, vsDataResult, spaceInfo)
                }
                if (scene.deferred) {
                    cacheEntry.signatures = workSet.getProcessingData("colorClosureSignatures");
                }
                if (Options.getValue("shadejs-cache"))
                    c_jsShaderCache[jsShaderKey] = cacheEntry;
            } catch (e) {
                SystemNotifier.sendEvent('shadejs', {
                    shadejsType: "error", event: e, code: this.sourceTemplate
                });

                var errorMessage = "Shade.js Compile Error:\n" + e.message + "\n------------\n" + "Shader Source:" + "\n------------\n" + XML3D.debug.formatSourceCode(this.sourceTemplate);
                throw new Error(errorMessage);
            }
        }
        this.source = {
            fragment: cacheEntry.source, vertex: this.createVertexShader(vsRequest, vsDataResult, cacheEntry.spaceInfo)
        }
        this.uniformSetter = cacheEntry.uniformSetter;
        if (scene.deferred) {
            scene.colorClosureSignatures.push.apply(scene.colorClosureSignatures, cacheEntry.signatures);
        }

        // TODO: Handle errors.
        XML3D.debug.logDebug(this.source.vertex);
        XML3D.debug.logDebug(this.source.fragment);

        SystemNotifier.sendEvent('shadejs', {
            shadejsType: "success", vertexShader: this.source.vertex, fragmentShader: this.source.fragment
        });

        return true;
    },

    createVertexShader: function (vsRequest, vsDataResult, spaceInfo) {
        var vsConfig = vsRequest.getConfig();
        var names = vsDataResult.outputNames;
        for (var i = 0; i < names.length; ++i) {
            channelVsAttribute(vsConfig, names[i], spaceInfo);
        }
        vsConfig.addInputParameter(XC.DATA_TYPE.FLOAT4X4, "modelViewProjectionMatrix", true);
        vsConfig.addCodeFragment("gl_Position = modelViewProjectionMatrix * vec4(#I{position}, 1.0);");
        return vsRequest.getVertexShader().getGLSLCode();
    },

    setUniformVariables: function (envNames, sysNames, inputCollection) {
        this.uniformSetter(envNames, sysNames, inputCollection, this.program.setUniformVariable.bind(this.program));
    },

    getTransparencyFromInputData: function (dataMap) {
        // TODO: Compute Transparency
        return false;
    },

    /* Default values are compiled into shade.js */
    setDefaultUniforms: function () {
    }

});

/**
 * @param {GLContext} context
 * @param {{}} globals
 * @returns {{}}
 */
function getSystemParameters(context, globals) {
    var result = getJSSystemConfiguration(context);

    // Update light parameters which vary in their size depending on number of lights defined
    ["point", "directional", "spot"].forEach(function(model) {
        var on = model + "LightOn";
        result["MAX_" + model.toUpperCase() + "LIGHTS"].staticValue = globals[on] && globals[on].length;
    });

    for (var global in globals) {
        var entry = result[global];
        if(entry && entry.staticSize) {
            var aLength = globals[global].length;
            var tupleSize = getTupleSize(entry);
            entry.staticSize = aLength / tupleSize;
        }

    }
    return result;
}

/**
 * @param {{}} desc Object type descriptor
 * @returns {number}
 */
function getTupleSize(desc) {
    if(desc.type == "array") {
        var elements = desc.elements;
        if (elements.type == "object") {
            switch(elements.kind) {
                case "texture":
                case "float": return 1;
                case "float2": return 2;
                case "float3": return 3;
                case "float4": return 4;
                case "matrix4": return 16;
                default: throw ("Unknown array element kind:" + elements.kind);
            }
        }
    }
    return 1;
}

module.exports = JSShaderClosure;

<commit_msg>add support for transparency in jsshaderclosure<commit_after>var AbstractShaderClosure = require("./../abstractshaderclosure.js");
var JSShaderComposer = require("./jsshadercomposer.js");
var SystemNotifier = require("../../system/system-notifier.js");
var getJSSystemConfiguration = require("./jssystemconfiguration.js");
var XC = require("../../../../xflow/interface/constants.js");
var Options = require("../../../../utils/options.js");

var c_jsShaderCache = {};

function convertEnvName(name) {
    return ("_env_" + name).replace(/_+/g, "_");
}

function addDefaultChanneling(vsConfig, inputName) {
    var outputName = convertEnvName(inputName);
    vsConfig.channelAttribute(inputName, outputName, null);
}

function channelVsAttribute(vsConfig, inputName, spaceInfo) {
    if (!spaceInfo || !spaceInfo[inputName]) {
        addDefaultChanneling(vsConfig, inputName);
        return;
    }

    var i = spaceInfo[inputName].length;
    while (i--) {
        var entry = spaceInfo[inputName][i];
        var outputName = convertEnvName(entry.name), code = null;
        switch (entry.space) {
            case Shade.SPACE_VECTOR_TYPES.OBJECT:
                break;
            case Shade.SPACE_VECTOR_TYPES.VIEW_POINT:
                vsConfig.addInputParameter(XC.DATA_TYPE.FLOAT4X4, "modelViewMatrix", true);
                code = outputName + " = ( modelViewMatrix * vec4(#I{" + inputName + "}, 1.0) ).xyz;";
                break;
            case Shade.SPACE_VECTOR_TYPES.VIEW_NORMAL:
                vsConfig.addInputParameter(XC.DATA_TYPE.FLOAT3X3, "modelViewMatrixN", true);
                code = outputName + " = normalize( modelViewMatrixN * #I{" + inputName + "} );";
                break;
            case Shade.SPACE_VECTOR_TYPES.WORLD_POINT:
                vsConfig.addInputParameter(XC.DATA_TYPE.FLOAT4X4, "modelMatrix", true);
                code = outputName + " = ( modelMatrix * vec4(#I{" + inputName + "}, 1.0) ).xyz;";
                break;
            case Shade.SPACE_VECTOR_TYPES.WORLD_NORMAL:
                vsConfig.addInputParameter(XC.DATA_TYPE.FLOAT3X3, "modelMatrixN", true);
                code = outputName + " = normalize( modelMatrixN * #I{" + inputName + "} );";
                break;
            default:
                throw new Error("Can't handle Space Type: " + entry.space);
        }
        vsConfig.channelAttribute(inputName, outputName, code);
    }
}

/**
 * @param {XC.DATA_TYPE} xflowType
 */
var convertXflow2ShadeType = function (xflowType, source) {
    var result = {}
    switch (xflowType) {
        case XC.DATA_TYPE.BOOL:
            result.type = Shade.TYPES.BOOLEAN;
            break;
        case XC.DATA_TYPE.INT:
            result.type = Shade.TYPES.INT;
            break;
        case XC.DATA_TYPE.FLOAT:
            result.type = Shade.TYPES.NUMBER;
            break;
        case XC.DATA_TYPE.FLOAT2:
            result.type = Shade.TYPES.OBJECT;
            result.kind = Shade.OBJECT_KINDS.FLOAT2;
            break;
        case XC.DATA_TYPE.FLOAT3:
            result.type = Shade.TYPES.OBJECT;
            result.kind = Shade.OBJECT_KINDS.FLOAT3;
            break;
        case XC.DATA_TYPE.FLOAT4:
            result.type = Shade.TYPES.OBJECT;
            result.kind = Shade.OBJECT_KINDS.FLOAT4;
            break;
        case XC.DATA_TYPE.FLOAT3X3:
            result.type = Shade.TYPES.OBJECT;
            result.kind = Shade.OBJECT_KINDS.MATRIX3;
            break;
        case XC.DATA_TYPE.FLOAT4X4:
            result.type = Shade.TYPES.OBJECT;
            result.kind = Shade.OBJECT_KINDS.MATRIX4;
            break;
        case XC.DATA_TYPE.TEXTURE:
            result.type = Shade.TYPES.OBJECT;
            result.kind = Shade.OBJECT_KINDS.TEXTURE;
            break;
        case XC.DATA_TYPE.UNKNOWN:
        default:
            throw new Error("Unknown Xflow DataType: " + xflowType);
    }
    result.source = source;
    return result;
}

/**
 * @param context
 * @param sourceTemplate
 * @param dataCallback
 * @constructor
 */
var JSShaderClosure = function (context, sourceTemplate, extractedParams) {
    AbstractShaderClosure.call(this, context);
    this.sourceTemplate = sourceTemplate;
    this.extractedParams = extractedParams;
    this.uniformSetter = function () {
    };
    this.uniformConverter = [];
};

XML3D.createClass(JSShaderClosure, AbstractShaderClosure, {
    /**
     *
     * @param {GLScene} scene
     * @param {Xflow.ComputeResult} shaderResult
     * @param objectData
     */
    createSources: function (scene, shaderResult, vsRequest) {

        var vsDataResult = vsRequest.getResult();

        var systemParameters = getSystemParameters(this.context, scene.systemUniforms);
        var environmentParameters = {};

        var shaderEntries = shaderResult && shaderResult.getOutputMap(), vsShaderOutput = vsDataResult && vsDataResult.outputNames;

        for (var i = 0; i < this.extractedParams.length; ++i) {
            var paramName = this.extractedParams[i];
            if (vsShaderOutput && vsShaderOutput.indexOf(paramName) != -1) {
                environmentParameters[paramName] = convertXflow2ShadeType(vsDataResult.getOutputType(paramName), vsDataResult.isOutputUniform(paramName) ? Shade.SOURCES.UNIFORM : Shade.SOURCES.VERTEX);
            } else if (shaderEntries && shaderEntries[paramName]) {
                environmentParameters[paramName] = convertXflow2ShadeType(shaderEntries[paramName].type, Shade.SOURCES.UNIFORM);
            }
        }

        var contextData = {
            "this": { "type": "object", "kind": "any", "info": systemParameters },
            "global.shade": [{"extra": {"type": "object", "kind": "any", "global": true, "info": environmentParameters }}]
        };

        XML3D.debug.logDebug("CONTEXT:", contextData);

        var options = {
            propagateConstants: true,
            validate: true,
            sanitize: true,
            transformSpaces: Options.getValue("shadejs-transformSpaces"),
            extractUniformExpressions: Options.getValue("shadejs-extractUniformExpressions")
        };
        var compileOptions = {
            useStatic: true, uniformExpressions: options.uniformExpressions
        };
        var implementation = scene.deferred ? "xml3d-glsl-deferred" : "xml3d-glsl-forward";

        var jsShaderKey = implementation + ";" + JSON.stringify(options) + ";" + JSON.stringify(environmentParameters) + ";" + this.sourceTemplate;

        var cacheEntry;
        if (!(cacheEntry = c_jsShaderCache[jsShaderKey])) {
            try {
                var workSet = new Shade.WorkingSet();
                workSet.parse(this.sourceTemplate, {loc: true});
                workSet.analyze(contextData, implementation, options);
                var spaceInfo = workSet.getProcessingData('spaceInfo');
                var glslShader = workSet.compileFragmentShader(compileOptions);

                cacheEntry = {
                    source: glslShader.source, uniformSetter: glslShader.uniformSetter, spaceInfo: spaceInfo
                };
                cacheEntry.hasTransparentShaderClosure = workSet.getProcessingData("isTransparent");

                this.uniformSetter = glslShader.uniformSetter;
                this.source = {
                    fragment: glslShader.source, vertex: this.createVertexShader(vsRequest, vsDataResult, spaceInfo)
                }

                if (scene.deferred) {
                    cacheEntry.signatures = workSet.getProcessingData("colorClosureSignatures");
                }
                if (Options.getValue("shadejs-cache"))
                    c_jsShaderCache[jsShaderKey] = cacheEntry;
            } catch (e) {
                SystemNotifier.sendEvent('shadejs', {
                    shadejsType: "error", event: e, code: this.sourceTemplate
                });

                var errorMessage = "Shade.js Compile Error:\n" + e.message + "\n------------\n" + "Shader Source:" + "\n------------\n" + XML3D.debug.formatSourceCode(this.sourceTemplate);
                throw new Error(errorMessage);
            }
        }
        this.source = {
            fragment: cacheEntry.source, vertex: this.createVertexShader(vsRequest, vsDataResult, cacheEntry.spaceInfo)
        };
        this.hasTransparentShaderClosure = cacheEntry.hasTransparentShaderClosure;

        this.uniformSetter = cacheEntry.uniformSetter;
        if (scene.deferred) {
            scene.colorClosureSignatures.push.apply(scene.colorClosureSignatures, cacheEntry.signatures);
        }

        // TODO: Handle errors.
        XML3D.debug.logDebug(this.source.vertex);
        XML3D.debug.logDebug(this.source.fragment);

        SystemNotifier.sendEvent('shadejs', {
            shadejsType: "success", vertexShader: this.source.vertex, fragmentShader: this.source.fragment
        });

        return true;
    },

    createVertexShader: function (vsRequest, vsDataResult, spaceInfo) {
        var vsConfig = vsRequest.getConfig();
        var names = vsDataResult.outputNames;
        for (var i = 0; i < names.length; ++i) {
            channelVsAttribute(vsConfig, names[i], spaceInfo);
        }
        vsConfig.addInputParameter(XC.DATA_TYPE.FLOAT4X4, "modelViewProjectionMatrix", true);
        vsConfig.addCodeFragment("gl_Position = modelViewProjectionMatrix * vec4(#I{position}, 1.0);");
        return vsRequest.getVertexShader().getGLSLCode();
    },

    setUniformVariables: function (envNames, sysNames, inputCollection) {
        this.uniformSetter(envNames, sysNames, inputCollection, this.program.setUniformVariable.bind(this.program));
    },

    getTransparencyFromInputData: function (dataMap) {
        // TODO: Compute Transparency
        return this.hasTransparentShaderClosure;
    },

    /* Default values are compiled into shade.js */
    setDefaultUniforms: function () {
    }

});

/**
 * @param {GLContext} context
 * @param {{}} globals
 * @returns {{}}
 */
function getSystemParameters(context, globals) {
    var result = getJSSystemConfiguration(context);

    // Update light parameters which vary in their size depending on number of lights defined
    ["point", "directional", "spot"].forEach(function(model) {
        var on = model + "LightOn";
        result["MAX_" + model.toUpperCase() + "LIGHTS"].staticValue = globals[on] && globals[on].length;
    });

    for (var global in globals) {
        var entry = result[global];
        if(entry && entry.staticSize) {
            var aLength = globals[global].length;
            var tupleSize = getTupleSize(entry);
            entry.staticSize = aLength / tupleSize;
        }

    }
    return result;
}

/**
 * @param {{}} desc Object type descriptor
 * @returns {number}
 */
function getTupleSize(desc) {
    if(desc.type == "array") {
        var elements = desc.elements;
        if (elements.type == "object") {
            switch(elements.kind) {
                case "texture":
                case "float": return 1;
                case "float2": return 2;
                case "float3": return 3;
                case "float4": return 4;
                case "matrix4": return 16;
                default: throw ("Unknown array element kind:" + elements.kind);
            }
        }
    }
    return 1;
}

module.exports = JSShaderClosure;

<|endoftext|>


<commit_before>import $ from 'jquery'
import Dropdown from '../../com/dropdown'
import NavTree from '../../com/nav-tree'
import './api.scss'

const DEFAULT_VERSION = '1.3';
const LOCAL_STORAGE_KEY = 'targetApi';

function getVersion(element) {

  let version = $(element).attr('data-kotlin-version');

  console.log($(element), version);
  return version
}

function updateTagByKind(rowElement, newTag, kind) {
  let tagsContainer = ($(rowElement).is("tr")) ? $(rowElement).find("td:first") : rowElement;
  let $tag = $(tagsContainer).find(`.tags__tag.${kind}`);
  $tag.text(newTag);
}

function updateState(state) {
  localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(state));
  const $platformDependentElements = $('[data-platform]');
  const $versionDependentElements = $('[data-kotlin-version]');
  $versionDependentElements.removeClass('hidden');
  $platformDependentElements.removeClass('hidden');
  $platformDependentElements.each((ind, element) => {
    $(element).parent().parent().removeClass('hidden')
  });

  if (state.platform.toLowerCase() != 'all') {
    $platformDependentElements.each((ind, element) => {
      const $element = $(element);

      let tags = $element.attr('data-platform').toLowerCase();

      if (tags.includes(state.platform.toLowerCase())) return;
      $element.addClass('hidden');
      })
  }

  $versionDependentElements.each((ind, element) => {
    const $element = $(element);
    const stateVersion = state.version ? state.version : DEFAULT_VERSION;
    const version = getVersion(element);
    const pureVersion = version.replace(/\+$/, '');
    if (pureVersion > stateVersion) {
        $element.addClass('hidden');
        if ($element.is("div") && $element.siblings().hasClass("hidden")) {
          $element.parent().parent().addClass("hidden")
        }
    } else if (version != pureVersion) {
      updateTagByKind($element, pureVersion == stateVersion ? pureVersion : version, 'kotlin-version');
    }
  })
}

function addSelectToPanel(panelElement, title, config) {
  const selectElement = $(`<div class="api-panel__select"><span class="api-panel__dropdown-title">${title}</span></div>`);
  $(panelElement).append(selectElement);
  new Dropdown(selectElement, config);
}

function initializeSelects() {
  const $breadcrumbs = $('.api-docs-breadcrumbs');
  if ($breadcrumbs.length > 0) {
    $breadcrumbs
      .wrap('

')
      .after('

');
  } else {
    $('.page-content').prepend('

');
  }

  const switchersPanel = $('.api-panel__switchers')[0];

  const state = localStorage.getItem(LOCAL_STORAGE_KEY) ?
    JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY)) :
    {
      platform: 'all'
    };
  updateState(state);

  addSelectToPanel(switchersPanel, "Platform", {
    items: {
      'all': 'All',
      'common': 'common',
      'jre6': 'jre6',
      'jre7': 'jre7',
      'jre8': 'jre8',
      'js': 'js',
      'native': 'native'
    },
    selected: state.platform,
    onSelect: (platform) => {
      state.platform = platform;
      updateState(state)
    }
  });

  addSelectToPanel(switchersPanel, "Version", {
    items: {
      '1.0': '1.0',
      '1.1': '1.1',
      '1.2': '1.2',
      '1.3': '1.3'
    },
    selected: state.version != null ? state.version : DEFAULT_VERSION,
    onSelect: (version) => {
      if(version != DEFAULT_VERSION){
        state.version = version;
      } else {
        delete state.version;
      }
      updateState(state)
    }
  })
}

function addTag(rowElement, tags, kind) {
  // let tagsContainer = ($(rowElement).is("tr")) ? $(rowElement).find("td:first") : rowElement;

  // let $tagsElement = $(tagsContainer).find(".tags");

  // if ($tagsElement.length == 0) {
  //   return;
  //   // $tagsElement = $('

');
  //   // let elementWithPlatforms = $(rowElement);
  //   // $(tagsContainer).append($tagsElement);
  // }

  // //if (!$(rowElement).is("tr") && kind != 'platform')
  // //  return;

  // tags.split(',').forEach(tag => $tagsElement.append(`<div class="tags__tag ${kind}">${tag}</div>`));

}

function addTags() {
  $('[data-platform]').each((ind, element) => {
    const platform = element.getAttribute('data-platform');
    addTag(element, platform, 'platform')
  });

  $('[data-kotlin-version]').each((ind, element) => addTag(element, getVersion(element), 'kotlin-version'));

  $('[data-jre-version]').each((ind, element) => {
    const version = element.getAttribute('data-jre-version');
    addTag(element, version, 'jre-version')
  });
}

$(document).ready(() => {
  addTags();
  initializeSelects();
  new NavTree(document.querySelector('.js-side-tree-nav'));
});
<commit_msg>Update version only in direct child tags of platform dependant block<commit_after>import $ from 'jquery'
import Dropdown from '../../com/dropdown'
import NavTree from '../../com/nav-tree'
import './api.scss'

const DEFAULT_VERSION = '1.3';
const LOCAL_STORAGE_KEY = 'targetApi';

function getVersion(element) {

  let version = $(element).attr('data-kotlin-version');

  console.log($(element), version);
  return version
}

function updateTagByKind(rowElement, newTag, kind) {
  let tagsContainer = ($(rowElement).is("tr")) ? $(rowElement).find("td:first") : rowElement;
  let $tag = $(tagsContainer).children(`.tags__tag.${kind}`);
  $tag.text(newTag);
}

function updateState(state) {
  localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(state));
  const $platformDependentElements = $('[data-platform]');
  const $versionDependentElements = $('[data-kotlin-version]');
  $versionDependentElements.removeClass('hidden');
  $platformDependentElements.removeClass('hidden');
  $platformDependentElements.each((ind, element) => {
    $(element).parent().parent().removeClass('hidden')
  });

  if (state.platform.toLowerCase() != 'all') {
    $platformDependentElements.each((ind, element) => {
      const $element = $(element);

      let tags = $element.attr('data-platform').toLowerCase();

      if (tags.includes(state.platform.toLowerCase())) return;
      $element.addClass('hidden');
      })
  }

  $versionDependentElements.each((ind, element) => {
    const $element = $(element);
    const stateVersion = state.version ? state.version : DEFAULT_VERSION;
    const version = getVersion(element);
    const pureVersion = version.replace(/\+$/, '');
    if (pureVersion > stateVersion) {
        $element.addClass('hidden');
        if ($element.is("div") && $element.siblings().hasClass("hidden")) {
          $element.parent().parent().addClass("hidden")
        }
    } else if (version != pureVersion) {
      updateTagByKind($element, pureVersion == stateVersion ? pureVersion : version, 'kotlin-version');
    }
  })
}

function addSelectToPanel(panelElement, title, config) {
  const selectElement = $(`<div class="api-panel__select"><span class="api-panel__dropdown-title">${title}</span></div>`);
  $(panelElement).append(selectElement);
  new Dropdown(selectElement, config);
}

function initializeSelects() {
  const $breadcrumbs = $('.api-docs-breadcrumbs');
  if ($breadcrumbs.length > 0) {
    $breadcrumbs
      .wrap('

')
      .after('

');
  } else {
    $('.page-content').prepend('

');
  }

  const switchersPanel = $('.api-panel__switchers')[0];

  const state = localStorage.getItem(LOCAL_STORAGE_KEY) ?
    JSON.parse(localStorage.getItem(LOCAL_STORAGE_KEY)) :
    {
      platform: 'all'
    };
  updateState(state);

  addSelectToPanel(switchersPanel, "Platform", {
    items: {
      'all': 'All',
      'common': 'common',
      'jre6': 'jre6',
      'jre7': 'jre7',
      'jre8': 'jre8',
      'js': 'js',
      'native': 'native'
    },
    selected: state.platform,
    onSelect: (platform) => {
      state.platform = platform;
      updateState(state)
    }
  });

  addSelectToPanel(switchersPanel, "Version", {
    items: {
      '1.0': '1.0',
      '1.1': '1.1',
      '1.2': '1.2',
      '1.3': '1.3'
    },
    selected: state.version != null ? state.version : DEFAULT_VERSION,
    onSelect: (version) => {
      if(version != DEFAULT_VERSION){
        state.version = version;
      } else {
        delete state.version;
      }
      updateState(state)
    }
  })
}

function addTag(rowElement, tags, kind) {
  // let tagsContainer = ($(rowElement).is("tr")) ? $(rowElement).find("td:first") : rowElement;

  // let $tagsElement = $(tagsContainer).find(".tags");

  // if ($tagsElement.length == 0) {
  //   return;
  //   // $tagsElement = $('

');
  //   // let elementWithPlatforms = $(rowElement);
  //   // $(tagsContainer).append($tagsElement);
  // }

  // //if (!$(rowElement).is("tr") && kind != 'platform')
  // //  return;

  // tags.split(',').forEach(tag => $tagsElement.append(`<div class="tags__tag ${kind}">${tag}</div>`));

}

function addTags() {
  $('[data-platform]').each((ind, element) => {
    const platform = element.getAttribute('data-platform');
    addTag(element, platform, 'platform')
  });

  $('[data-kotlin-version]').each((ind, element) => addTag(element, getVersion(element), 'kotlin-version'));

  $('[data-jre-version]').each((ind, element) => {
    const version = element.getAttribute('data-jre-version');
    addTag(element, version, 'jre-version')
  });
}

$(document).ready(() => {
  addTags();
  initializeSelects();
  new NavTree(document.querySelector('.js-side-tree-nav'));
});
<|endoftext|>