<commit_before>var Promise    = require('bluebird');
var rekt       = require('rekt').rekt;
var assert     = require('assert');
var _          = require('lodash');
var Book       = requireLocal('models/book.js');
var Page       = requireLocal('models/page.js');
var Difference = requireLocal('models/difference.js');

/** If difference with id exists we want to throw it out. */
function mergeBooks(books) {
  return new Promise(function(resolve, reject) {
    if (!_.isUndefined(books)) {
      var finalBooks = {};
      _.forEach(books, function(book) {
        var raw = book.items[0];
        finalBooks[raw.id] = finalBooks[raw.id] || {
          id: raw.id,
          barcode: raw.barcode,
          pages: []
        };
        _.forEach(raw.pages, function(page) {
          console.log(page.differences.length);
          if (page.differences.length > 0) {
            finalBooks[raw.id].pages.push(page);
          }
        });
      });
      resolve(finalBooks);
    } else {
      reject(new rekt.BadRequest('You must provide books to import'));
    }
  });
}

function prepareBooks(books) {
  return Promise.map(_.keys(books), function(bookKey) {
    var book = books[bookKey];
    var bookPages = books[bookKey].pages;
    var newPages = [];
    return Promise.map(bookPages, function(page) {
      Page.findOneAsync({
        id: page.id
      })
      .bind(page)
      .then(function(match) {
        if (match) {
          console.log('Page with that id exists');
          return undefined;
        } else {
          return prepareDifferences(page)
            .then(saveDifferences)
            .then(function(result) {
              page.differences = result;
              return savePage(page);
            })
            .then(function(savedPage) {
              newPages.push(savedPage);
              return savedPage;
            });
        }
      })
    })

  }).then(function() {
    console.log(bookKey, arguments);
  })
}

function savePage(page) {
  var newPage = new Page();
  newPage.id = page.id;
  newPage.url = page.url;
  newPage.differences = page.differences;

  return newPage.saveAsync().bind(page)
    .get(0)
    .then(function(result) {
      return result._id;
    });
}

function prepareDifferences(page) {
  return new Promise(function(resolve, reject) {
    var newDifferences = _.map(page.differences, function(difference) {
      difference.tags = difference.tags || [];
      difference.passes = 0;
      _.forEach(difference.texts, function(text) {
        this.tags.push({
          text: text,
          weight: 0
        });
      }, difference);
      return difference;
    });

    page.differences = newDifferences;
    resolve(page);
  });
}

function saveDifferences(page) {
  return Promise.map(page.differences, function(difference) {
    var newDifference = new Difference();
    newDifference.id = difference.id;
    newDifference.tags = difference.tags;
    newDifference.texts = difference.texts;
    newDifference.coords = difference.coords;
    return newDifference.saveAsync().bind(difference)
      .get(0)
      .then(function(result) {
        return result._id;
      });
  });
}

module.exports = function(router) {
  router.route('/book-import')
    .all(function(req, res, next) {
      if (req.token.subject === 'Tiltfactor' || req.token.subject === 'BHL') {
        next();
      } else {
        res.status(401);
        res.json({
          message: 'You don\'t have access to this.'
        });
      }
    })
    .post(function(req, res) {
      var books = req.body.items;
      mergeBooks(books)
        .then(prepareBooks)
        .then(function() {
          res.send('Successfully processed request.');
        })
        .catch(function(err) {
          res.send(err);
        });
    });
}
<commit_msg>Testing book write<commit_after>var Promise    = require('bluebird');
var rekt       = require('rekt').rekt;
var assert     = require('assert');
var _          = require('lodash');
var Book       = requireLocal('models/book.js');
var Page       = requireLocal('models/page.js');
var Difference = requireLocal('models/difference.js');

/** If difference with id exists we want to throw it out. */
function mergeBooks(books) {
  return new Promise(function(resolve, reject) {
    if (!_.isUndefined(books)) {
      var finalBooks = {};
      _.forEach(books, function(book) {
        var raw = book.items[0];
        finalBooks[raw.id] = finalBooks[raw.id] || {
          id: raw.id,
          barcode: raw.barcode,
          pages: []
        };
        _.forEach(raw.pages, function(page) {
          console.log(page.differences.length);
          if (page.differences.length > 0) {
            finalBooks[raw.id].pages.push(page);
          }
        });
      });
      resolve(finalBooks);
    } else {
      reject(new rekt.BadRequest('You must provide books to import'));
    }
  });
}

function prepareBooks(books) {
  return Promise.map(_.keys(books), function(bookKey) {
    var book = books[bookKey];
    var bookPages = books[bookKey].pages;
    var newPages = [];
    return Promise.map(bookPages, function(page) {
      Page.findOneAsync({
        id: page.id
      })
      .bind(page)
      .then(function(match) {
        if (match) {
          console.log('Page with that id exists');
          return undefined;
        } else {
          return prepareDifferences(page)
            .then(saveDifferences)
            .then(function(result) {
              page.differences = result;
              return savePage(page);
            })
            .then(function(savedPage) {
              newPages.push(savedPage);
              return savedPage;
            });
        }
      })
    }).then(function() {
    console.log(bookKey, arguments);
  })

  })
}

function savePage(page) {
  var newPage = new Page();
  newPage.id = page.id;
  newPage.url = page.url;
  newPage.differences = page.differences;

  return newPage.saveAsync().bind(page)
    .get(0)
    .then(function(result) {
      return result._id;
    });
}

function prepareDifferences(page) {
  return new Promise(function(resolve, reject) {
    var newDifferences = _.map(page.differences, function(difference) {
      difference.tags = difference.tags || [];
      difference.passes = 0;
      _.forEach(difference.texts, function(text) {
        this.tags.push({
          text: text,
          weight: 0
        });
      }, difference);
      return difference;
    });

    page.differences = newDifferences;
    resolve(page);
  });
}

function saveDifferences(page) {
  return Promise.map(page.differences, function(difference) {
    var newDifference = new Difference();
    newDifference.id = difference.id;
    newDifference.tags = difference.tags;
    newDifference.texts = difference.texts;
    newDifference.coords = difference.coords;
    return newDifference.saveAsync().bind(difference)
      .get(0)
      .then(function(result) {
        return result._id;
      });
  });
}

module.exports = function(router) {
  router.route('/book-import')
    .all(function(req, res, next) {
      if (req.token.subject === 'Tiltfactor' || req.token.subject === 'BHL') {
        next();
      } else {
        res.status(401);
        res.json({
          message: 'You don\'t have access to this.'
        });
      }
    })
    .post(function(req, res) {
      var books = req.body.items;
      mergeBooks(books)
        .then(prepareBooks)
        .then(function() {
          res.send('Successfully processed request.');
        })
        .catch(function(err) {
          res.send(err);
        });
    });
}
<|endoftext|>


<commit_before>var express = require('express');
var router = express.Router();
var passwordHash = require('password-hash');
var jwt = require('jsonWebToken');

var Company = require('../models/company');
var User = require('../models/user');

router.post('/', function (req, res, next) {
    var decoded = jwt.decode(req.headers.authorization);

    User.findById(decoded.user._id, function (err, doc) {
        if (err) {
            return res.status(404).json({
                title: 'An error occurred',
                error: err
            });
        }
        var company = new Company({
            name: req.body.name,
            secret: req.body.secret,
            user: doc
        });
        company.save(function (err, result) {
            if (err) {
                return res.status(404).json({
                    title: 'An error occured',
                    error: err
                });
            }
            res.status(200).json({
                message: 'Success',
                obj: result
            })
        });
    });
});

router.get('/', function (req, res, next) {
    var decoded = jwt.decode(req.headers.authorization);

    Company.find({ 'user': decoded.user._id }).exec(function (err, docs) {
        if (err) {
            return res.status(400).json({
                title: 'An error occurred',
                error: err
            });
        }
        res.status(200).json({
            message: 'Success',
            obj: docs
        });
    });
});

router.delete('/:id', function (req, res, next) {
    var decoded = jwt.decode(req.headers.authorization);

    Company.findById(req.params.id, function (err, doc) {
        if (err) {
            return res.status(404).json({
                title: 'An error occurred',
                error: err
            });
        }

        if (!doc) {
            return res.status(404).json({
                title: 'No company found',
                error: { message: 'Company could not be found' }
            });
        }

        if (doc.user != decoded.user._id) {
            return res.status(401).json({
                title: 'Not Authorized',
                error: { message: 'Company created by other user' }
            });
        }

        doc.remove(function (err, result) {
            if (err) {
                return res.status(404).json({
                    title: 'An error occurred',
                    error: err
                });
            }
            res.status(200).json({
                message: 'Success',
                obj: result
            });
        })
    });
});

module.exports = router;<commit_msg>Fixed so the secret is auto generated.<commit_after>var express = require('express');
var router = express.Router();
var passwordHash = require('password-hash');
var jwt = require('jsonWebToken');
var randomstring = require('randomstring');

var Company = require('../models/company');
var User = require('../models/user');

router.post('/', function (req, res, next) {
    var decoded = jwt.decode(req.headers.authorization);

    User.findById(decoded.user._id, function (err, doc) {
        if (err) {
            return res.status(404).json({
                title: 'An error occurred',
                error: err
            });
        }

         if (!doc) {
            return res.status(404).json({
                title: 'User not found',
                error: err
            });
        }

        var company = new Company({
            name: req.body.name,
            secret: randomstring.generate({
                length: 8,
                charset: 'alphanumeric'
            }),
            user: doc
        });
        company.save(function (err, result) {
            if (err) {
                return res.status(404).json({
                    title: 'An error occured',
                    error: err
                });
            }
            res.status(200).json({
                message: 'Success',
                obj: result
            })
        });
    });
});

router.get('/', function (req, res, next) {
    var decoded = jwt.decode(req.headers.authorization);

    Company.find({ 'user': decoded.user._id }).exec(function (err, docs) {
        if (err) {
            return res.status(400).json({
                title: 'An error occurred',
                error: err
            });
        }
        res.status(200).json({
            message: 'Success',
            obj: docs
        });
    });
});

router.delete('/:id', function (req, res, next) {
    var decoded = jwt.decode(req.headers.authorization);

    Company.findById(req.params.id, function (err, doc) {
        if (err) {
            return res.status(404).json({
                title: 'An error occurred',
                error: err
            });
        }

        if (!doc) {
            return res.status(404).json({
                title: 'No company found',
                error: { message: 'Company could not be found' }
            });
        }

        if (doc.user != decoded.user._id) {
            return res.status(401).json({
                title: 'Not Authorized',
                error: { message: 'Company created by other user' }
            });
        }

        doc.remove(function (err, result) {
            if (err) {
                return res.status(404).json({
                    title: 'An error occurred',
                    error: err
                });
            }
            res.status(200).json({
                message: 'Success',
                obj: result
            });
        })
    });
});

module.exports = router;<|endoftext|>


<commit_before>(function webpackUniversalModuleDefinition(root, factory) {
	if(typeof exports === 'object' && typeof module === 'object')
		module.exports = factory();
	else if(typeof define === 'function' && define.amd)
		define([], factory);
	else {
		var a = factory();
		for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];
	}
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ 	// The module cache
/******/ 	var installedModules = {};

/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {

/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId])
/******/ 			return installedModules[moduleId].exports;

/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			exports: {},
/******/ 			id: moduleId,
/******/ 			loaded: false
/******/ 		};

/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

/******/ 		// Flag the module as loaded
/******/ 		module.loaded = true;

/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}

/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;

/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;

/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";

/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(0);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ function(module, exports) {

	"use strict";

	Object.defineProperty(exports, "__esModule", {
	    value: true
	});
	exports.create = create;
	exports.just = just;
	exports.interval = interval;
	exports.fromEvent = fromEvent;
	exports.fromPromise = fromPromise;
	exports.fromIterable = fromIterable;

	function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

	var runFn = function runFn(fn) {
	    return fn();
	};

	function isDefined(x) {
	    return typeof x !== 'undefined';
	}

	function first(x) {
	    return x[0];
	}

	function create(executor) {
	    return {
	        subscribe: executor,

	        map: function map(fn) {
	            return create(function (sink) {
	                return executor(function (v) {
	                    return sink(fn(v));
	                });
	            });
	        },

	        filter: function filter(predicate) {
	            return create(function (sink) {
	                return executor(function (v) {
	                    return predicate(v) ? sink(v) : undefined;
	                });
	            });
	        },

	        scan: function scan(fn, seed) {
	            return create(function (sink) {
	                return executor(function (y) {
	                    return sink(seed = fn(seed, y));
	                });
	            });
	        },

	        flatMap: function flatMap(fn) {
	            return create(function (sink) {
	                var unsubs = [];
	                unsubs[0] = executor(function (x) {
	                    unsubs[1] = fn(x).subscribe(sink);
	                });

	                return function () {
	                    return unsubs.forEach(runFn);
	                };
	            });
	        },

	        startWith: function startWith(v) {
	            return create(function (sink) {
	                sink(v);
	                return executor(sink);
	            });
	        },

	        merge: function merge(stream2) {
	            return create(function (sink) {
	                var unsubs = [executor(sink), stream2.subscribe(sink)];
	                return function () {
	                    return unsubs.forEach(runFn);
	                };
	            });
	        },

	        take: function take(n) {
	            return create(function (sink) {
	                var unsub = executor(function (v) {
	                    if (--n >= 0) {
	                        sink(v);
	                    } else {
	                        runFn(unsub);
	                    }
	                });
	                return unsub;
	            });
	        },

	        combine: function combine(fn) {
	            for (var _len = arguments.length, streams = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
	                streams[_key - 1] = arguments[_key];
	            }

	            return create(function (sink) {
	                var values = [];
	                var clb = function clb(i) {
	                    return function (val) {
	                        values[i] = val;
	                        if (values.filter(isDefined).length === streams.length + 1) {
	                            sink(fn.apply(undefined, values));
	                        }
	                    };
	                };
	                var unsubs = [executor(clb(0))].concat(streams.map(function (s, i) {
	                    return s.subscribe(clb(i + 1));
	                }));
	                return function () {
	                    return unsubs.forEach(runFn);
	                };
	            });
	        },

	        zip: function zip(fn) {
	            for (var _len2 = arguments.length, streams = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
	                streams[_key2 - 1] = arguments[_key2];
	            }

	            var values = Array.from({ length: streams.length + 1 }, function () {
	                return [];
	            });
	            return create(function (sink) {
	                var clb = function clb(i) {
	                    return function (val) {
	                        values[i].push(val);
	                        if (values.map(first).filter(isDefined).length === streams.length + 1) {
	                            sink(fn.apply(undefined, _toConsumableArray(values.map(function (arr) {
	                                return arr.shift();
	                            }))));
	                        }
	                    };
	                };
	                var unsubs = [executor(clb(0))].concat(streams.map(function (s, i) {
	                    return s.subscribe(clb(i + 1));
	                }));
	                return function () {
	                    return unsubs.forEach(runFn);
	                };
	            });
	        },

	        multicast: function multicast() {
	            var sinks = [];
	            var started = false;

	            var broadcast = function broadcast(v) {
	                return sinks.forEach(function (fn) {
	                    return fn(v);
	                });
	            };
	            return create(function (sink) {
	                sinks.push(sink);
	                if (!started) {
	                    executor(broadcast);
	                    started = true;
	                }
	                return function () {
	                    sinks.splice(sinks.indexOf(sink), 1);
	                };
	            });
	        }
	    };
	}

	function just(v) {
	    return create(function (sink) {
	        sink(v);
	        return function () {};
	    });
	}

	function interval(t, v) {
	    return create(function (sink) {
	        var i = setInterval(sink, t, v);
	        return function () {
	            return clearInterval(i);
	        };
	    });
	}

	function fromEvent(el, event) {
	    return create(function (sink) {
	        el.addEventListener(event, sink);
	        return function () {
	            return el.removeEventListener(event, sink);
	        };
	    });
	}

	function fromPromise(promise) {
	    return create(function (sink) {
	        promise.then(sink);
	        return function () {};
	    });
	}

	function fromIterable(iterable) {
	    return create(function (sink) {
	        var _iteratorNormalCompletion = true;
	        var _didIteratorError = false;
	        var _iteratorError = undefined;

	        try {
	            for (var _iterator = iterable[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
	                var _v = _step.value;

	                sink(_v);
	            }
	        } catch (err) {
	            _didIteratorError = true;
	            _iteratorError = err;
	        } finally {
	            try {
	                if (!_iteratorNormalCompletion && _iterator.return) {
	                    _iterator.return();
	                }
	            } finally {
	                if (_didIteratorError) {
	                    throw _iteratorError;
	                }
	            }
	        }

	        return function () {};
	    });
	}

/***/ }
/******/ ])
});
;<commit_msg>fix bundle<commit_after><|endoftext|>


<commit_before>(function() {
  'use strict';
  var hasModule, udefine;

  hasModule = (typeof module !== "undefined" && module !== null) && module.exports;

  udefine = function(name, deps, factory) {
    var _ref, _ref1;

    if (Array.isArray(name)) {
      _ref = [void 0, name, deps], name = _ref[0], deps = _ref[1], factory = _ref[2];
    } else {
      if (typeof name === 'function') {
        _ref1 = [void 0, void 0, name], name = _ref1[0], deps = _ref1[1], factory = _ref1[2];
      }
    }
    return (function(factory) {
      if (typeof define !== "undefined" && define !== null) {
        if (define.amd || define.umd) {
          return define.apply(this, arguments);
        }
      } else {
        if (hasModule) {

        } else {

        }
      }
    })(factory);
  };

  udefine.globals = {};

}).call(this);
<commit_msg>udefine definition is now more independant<commit_after>(function() {
  'use strict';
  var hasModule, _ref;

  Array.isArray || (Array.isArray = function(a) {
    return a.push === Array.prototype.push && (a.length != null);
  });

  hasModule = (typeof module !== "undefined" && module !== null) && module.exports;

  (function(root) {
    root.udefine = function(name, deps, factory) {
      var _ref1, _ref2;

      if (Array.isArray(name)) {
        _ref1 = [void 0, name, deps], name = _ref1[0], deps = _ref1[1], factory = _ref1[2];
      } else {
        if (typeof name === 'function') {
          _ref2 = [void 0, void 0, name], name = _ref2[0], deps = _ref2[1], factory = _ref2[2];
        }
      }
      return (function(factory) {
        if (typeof define !== "undefined" && define !== null) {
          if (define.amd || define.umd) {
            return define.apply(this, arguments);
          }
        } else {
          if (hasModule) {

          } else {

          }
        }
      })(factory);
    };
    return root.udefine.globals = {};
  })((_ref = typeof module !== "undefined" && module !== null ? module.exports : void 0) != null ? _ref : this);

}).call(this);
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import TwemojiComp from 'react-twemoji';
import Fuse from 'fuse.js';
import EmojiPicker from '../emoji_picker/emoji_picker';

let active = false;
let pos = null;

let component = null;

class ContentEditable extends Component {
  constructor(props) {
    super(props);
    this.state = {
      pickerActive: false,
      content: '',
      previewContent: '',
      pickerStyle: {
        bottom: '5px',
        right: '0px',
      },
      mentions: [],
      selectedMention: 0,
    };
  }
  componentDidMount() {
    component = this;
    document.addEventListener('keydown', ContentEditable.handleArrowKeys, false);
  }
  shouldComponentUpdate() {
    return true;
  }
  componentDidUpdate() {
    const cursor = document.getElementById('cursor');
    const mentions = document.getElementById('mentions');
    let scrollOffset = this.textarea.scrollTop;
    if (scrollOffset <= 20) { scrollOffset = 0; }
    if (mentions && cursor) {
      mentions.style.bottom = `${parseInt(window.getComputedStyle(cursor).bottom, 10) + scrollOffset}px`;
      mentions.style.left = `${parseInt(window.getComputedStyle(cursor).left, 10) + 5}px`;
    }
  }
  componentWillUnmount() {
    document.removeEventListener('keydown', ContentEditable.handleArrowKeys, false);
  }
  static handleArrowKeys(e) {
    const { mentions, selectedMention } = component.state;
    const lastIndex = mentions.length - 1;
    switch (e.keyCode) {
      case 9:
        if (active) {
          e.preventDefault();
          component.addMention();
        }
        break;
      case 13: {
        if (active) {
          e.preventDefault();
          component.addMention();
        }
        break;
      }
      case 38: {
        if (active) {
          e.preventDefault();
          if (selectedMention === 0) {
            component.setState({ selectedMention: lastIndex });
            return;
          }
          component.setState({ selectedMention: selectedMention - 1 });
        }
        break;
      }
      case 39:
        if (active) {
          e.preventDefault();
          component.addMention();
        }
        break;
      case 40: {
        if (active) {
          e.preventDefault();
          if (selectedMention === lastIndex) {
            component.setState({ selectedMention: 0 });
            return;
          }
          component.setState({ selectedMention: selectedMention + 1 });
        }
        break;
      }
      default:
    }
  }
  addMention() {
    const { selectedMention, mentions } = this.state;
    const { users } = this.props;
    const index = mentions[selectedMention];
    if (typeof index !== 'undefined') {
      this.addStringToContent(users[index]);
    }
    active = false;
    pos = null;
    this.setState({ selectedMention: 0 });
  }
  addEmoji(emoji) {
    this.addStringToContent(emoji);
  }
  addStringToContent(string) {
    const caretPos = this.textarea.selectionStart;
    let content = this.state.content;
    content = `${content.slice(0, pos || caretPos)}${string} ${content.slice(caretPos, content.length)}`;
    this.onChange(content);
  }
  onChange(value) {
    this.setState({ content: value });
    let content = value;
    let caretPos = 0;
    if (this.textarea) {
      caretPos = this.textarea.selectionStart;
    }
    this.buildMentions(value, caretPos);
    this.previewNode.scrollTop = this.textarea.scrollTop;
    content = content.substr(0, caretPos);
    content = ContentEditable.moveCaret(content, caretPos);
    this.setState({ previewContent: content });
  }
  buildMentions(text, caretPos) {
    const lastChar = text.charAt(caretPos - 1);
    const { users } = this.props;
    if (lastChar === ' ' || lastChar === '') {
      active = false;
      pos = 0;
    }
    if (lastChar === '@') {
      pos = caretPos;
      active = true;
    }
    let mentions = null;
    if (active) {
      const searchText = text.substring(pos, caretPos);
      if (searchText === '') {
        const arraySize = users.length > 10 ? 10 : users.length;
        this.setState({
          mentions: [...Array(arraySize).keys()],
          selectedMention: arraySize - 1,
        });
        return;
      }
      const options = {
        shouldSort: true,
        threshold: 0.0,
        location: 0,
      };
      const fuse = new Fuse(users, options);
      mentions = new Set(fuse.search(searchText));
      this.setState({ mentions: Array.from(mentions), selectedMention: mentions.size - 1 });
      return;
    }
    this.setState({ mentions: [] });
  }
  static moveCaret(content, caretPos) {
    return `${content.slice(0, caretPos)}<span id="cursor">|</span>${content.slice(caretPos)}`;
  }
  toggleEmojiPicker() {
    const emojiTrigger = this.node;
    const triggerStyles = getComputedStyle(emojiTrigger);
    const bottom = `${parseInt(triggerStyles.bottom, 10) + emojiTrigger.clientHeight + 10}px`;
    this.setState({
      pickerActive: !this.state.pickerActive,
      pickerStyle: {
        bottom,
        right: '0px',
      },
    });
  }
  onPost() {
    const content = this.state.content;
    this.getAllEmojis(content);
  }
  getAllEmojis(content, index) {
    const modifiableContent = content;
    const firstIndex = modifiableContent.indexOf(':', index);
    const nextIndex = modifiableContent.indexOf(':', firstIndex + 1);
    const stringInBetween = content.substring(firstIndex, nextIndex + 1);
    const regSpace = /[ \n\r]+/g;
    if (nextIndex === -1 || firstIndex === -1) {
      return;
    }
    if (regSpace.test(stringInBetween)) {
      this.getAllEmojis(content, nextIndex);
    } else {
      console.log(stringInBetween);
      this.getAllEmojis(content, nextIndex + 1);
    }
  }
  render() {
    const { pickerActive, selectedMention } = this.state;
    return (
      <div
        className={`content_editable ${this.props.className}`}
        id={this.props.id}
        ref={(node) => { this.node = node; }}
      >
        <textarea
          className="textarea"
          onChange={(e) => { this.onChange(e.target.value); }}
          value={this.state.content}
          ref={(node) => { this.textarea = node; }}
        />

 { this.previewNode = node; }}
          dangerouslySetInnerHTML={{ __html: this.state.previewContent }}
        />

          {[...this.state.mentions].map((mention, index) => (
            <div
              className={`mention ${index === selectedMention ? 'active' : ''}`}
              key={mention}
            >
{this.props.users[mention]}

          ))}

        <TwemojiComp
          className="emoji_trigger"
          onClick={() => this.toggleEmojiPicker()}
        >
          🙂
        </TwemojiComp>
        { pickerActive ? <EmojiPicker
          style={this.state.pickerStyle}
          onPick={emoji => this.addEmoji(emoji)}
        /> : null }

          <button>Add Image</button>
          <button onClick={() => this.onPost()}>Add Comment</button>

    );
  }
}

ContentEditable.propTypes = {
  className: PropTypes.string, // eslint-disable-line
  id: PropTypes.string, // eslint-disable-line
  users: PropTypes.array //eslint-disable-line
};

export default ContentEditable;

          // {this.state.previewContent}
<commit_msg>emoji parsing is working great! Next is searching the emojis in file<commit_after>import React, { Component } from 'react';
import PropTypes from 'prop-types';
import TwemojiComp from 'react-twemoji';
import Fuse from 'fuse.js';
import EmojiPicker from '../emoji_picker/emoji_picker';
import emojiData from '../emoji_picker/emojis.json';

let active = false;
let pos = null;

let component = null;

class ContentEditable extends Component {
  constructor(props) {
    super(props);
    this.state = {
      pickerActive: false,
      content: '',
      previewContent: '',
      pickerStyle: {
        bottom: '5px',
        right: '0px',
      },
      mentions: [],
      selectedMention: 0,
    };
  }
  componentDidMount() {
    component = this;
    document.addEventListener('keydown', ContentEditable.handleArrowKeys, false);
  }
  shouldComponentUpdate() {
    return true;
  }
  componentDidUpdate() {
    const cursor = document.getElementById('cursor');
    const mentions = document.getElementById('mentions');
    let scrollOffset = this.textarea.scrollTop;
    if (scrollOffset <= 20) { scrollOffset = 0; }
    if (mentions && cursor) {
      mentions.style.bottom = `${parseInt(window.getComputedStyle(cursor).bottom, 10) + scrollOffset}px`;
      mentions.style.left = `${parseInt(window.getComputedStyle(cursor).left, 10) + 5}px`;
    }
  }
  componentWillUnmount() {
    document.removeEventListener('keydown', ContentEditable.handleArrowKeys, false);
  }
  static handleArrowKeys(e) {
    const { mentions, selectedMention } = component.state;
    const lastIndex = mentions.length - 1;
    switch (e.keyCode) {
      case 9:
        if (active) {
          e.preventDefault();
          component.addMention();
        }
        break;
      case 13: {
        if (active) {
          e.preventDefault();
          component.addMention();
        }
        break;
      }
      case 38: {
        if (active) {
          e.preventDefault();
          if (selectedMention === 0) {
            component.setState({ selectedMention: lastIndex });
            return;
          }
          component.setState({ selectedMention: selectedMention - 1 });
        }
        break;
      }
      case 39:
        if (active) {
          e.preventDefault();
          component.addMention();
        }
        break;
      case 40: {
        if (active) {
          e.preventDefault();
          if (selectedMention === lastIndex) {
            component.setState({ selectedMention: 0 });
            return;
          }
          component.setState({ selectedMention: selectedMention + 1 });
        }
        break;
      }
      default:
    }
  }
  addMention() {
    const { selectedMention, mentions } = this.state;
    const { users } = this.props;
    const index = mentions[selectedMention];
    if (typeof index !== 'undefined') {
      this.addStringToContent(users[index]);
    }
    active = false;
    pos = null;
    this.setState({ selectedMention: 0 });
  }
  addEmoji(emoji) {
    this.addStringToContent(emoji);
  }
  addStringToContent(string) {
    const caretPos = this.textarea.selectionStart;
    let content = this.state.content;
    content = `${content.slice(0, pos || caretPos)}${string} ${content.slice(caretPos, content.length)}`;
    this.onChange(content);
  }
  onChange(value) {
    this.setState({ content: value });
    let content = value;
    let caretPos = 0;
    if (this.textarea) {
      caretPos = this.textarea.selectionStart;
    }
    this.buildMentions(value, caretPos);
    this.previewNode.scrollTop = this.textarea.scrollTop;
    content = content.substr(0, caretPos);
    content = ContentEditable.moveCaret(content, caretPos);
    this.setState({ previewContent: content });
  }
  buildMentions(text, caretPos) {
    const lastChar = text.charAt(caretPos - 1);
    const { users } = this.props;
    if (lastChar === ' ' || lastChar === '') {
      active = false;
      pos = 0;
    }
    if (lastChar === '@') {
      pos = caretPos;
      active = true;
    }
    let mentions = null;
    if (active) {
      const searchText = text.substring(pos, caretPos);
      if (searchText === '') {
        const arraySize = users.length > 10 ? 10 : users.length;
        this.setState({
          mentions: [...Array(arraySize).keys()],
          selectedMention: arraySize - 1,
        });
        return;
      }
      const options = {
        shouldSort: true,
        threshold: 0.0,
        location: 0,
      };
      const fuse = new Fuse(users, options);
      mentions = new Set(fuse.search(searchText));
      this.setState({ mentions: Array.from(mentions), selectedMention: mentions.size - 1 });
      return;
    }
    this.setState({ mentions: [] });
  }
  static moveCaret(content, caretPos) {
    return `${content.slice(0, caretPos)}<span id="cursor">|</span>${content.slice(caretPos)}`;
  }
  toggleEmojiPicker() {
    const emojiTrigger = this.node;
    const triggerStyles = getComputedStyle(emojiTrigger);
    const bottom = `${parseInt(triggerStyles.bottom, 10) + emojiTrigger.clientHeight + 10}px`;
    this.setState({
      pickerActive: !this.state.pickerActive,
      pickerStyle: {
        bottom,
        right: '0px',
      },
    });
  }
  onPost() {
    const content = this.state.content;
    const emojis = new Set();
    this.getAllEmojis(content, 0, emojis);
    emojis.forEach((emoji) => {

    });
  }
  getAllEmojis(content, index, emojis) {
    const modifiableContent = content;
    const firstIndex = modifiableContent.indexOf(':', index);
    const nextIndex = modifiableContent.indexOf(':', firstIndex + 1);
    const stringInBetween = content.substring(firstIndex, nextIndex + 1);
    const regSpace = /[ \n\r]+/g;
    if (nextIndex === -1 || firstIndex === -1) {
      return;
    }
    if (regSpace.test(stringInBetween) || stringInBetween === '::') {
      this.getAllEmojis(content, nextIndex, emojis);
    } else {
      emojis.add(stringInBetween);
      this.getAllEmojis(content, nextIndex + 1, emojis);
    }
  }
  render() {
    const { pickerActive, selectedMention } = this.state;
    return (
      <div
        className={`content_editable ${this.props.className}`}
        id={this.props.id}
        ref={(node) => { this.node = node; }}
      >
        <textarea
          className="textarea"
          onChange={(e) => { this.onChange(e.target.value); }}
          value={this.state.content}
          ref={(node) => { this.textarea = node; }}
        />

 { this.previewNode = node; }}
          dangerouslySetInnerHTML={{ __html: this.state.previewContent }}
        />

          {[...this.state.mentions].map((mention, index) => (
            <div
              className={`mention ${index === selectedMention ? 'active' : ''}`}
              key={mention}
            >
{this.props.users[mention]}

          ))}

        <TwemojiComp
          className="emoji_trigger"
          onClick={() => this.toggleEmojiPicker()}
        >
          🙂
        </TwemojiComp>
        { pickerActive ? <EmojiPicker
          style={this.state.pickerStyle}
          onPick={emoji => this.addEmoji(emoji)}
        /> : null }

          <button>Add Image</button>
          <button onClick={() => this.onPost()}>Add Comment</button>

    );
  }
}

ContentEditable.propTypes = {
  className: PropTypes.string, // eslint-disable-line
  id: PropTypes.string, // eslint-disable-line
  users: PropTypes.array //eslint-disable-line
};

export default ContentEditable;

          // {this.state.previewContent}
<|endoftext|>


<commit_before>$.register({
  rule: {
    host: [
      /^img(fantasy|leech|\.pornleech|smile|say|nemo|sense)\.com$/,
      /^(imagedomino|lovechix)\.com$/,
      /^imageporn\.eu$/,
      /^0img\.net$/,
      /^daily-img\.com$/,
      /^picangel\.in$/,
    ],
    query: /^\?[pv]=/,
  },
  ready: function () {
    'use strict';

    if ($.window.confirmAge) {
      $.window.confirmAge(1);
      return;
    }
    var i = $('#container-home img[onclick]');
    $.openImage(i.src);
  },
});

// ex: ts=2 sts=2 sw=2 et
// sublime: tab_size 2; translate_tabs_to_spaces true; detect_indentation false; use_tab_stops true;
// kate: space-indent on; indent-width 2;
<commit_msg>imgsay.com<commit_after>(function () {
  'use strict';

  function helper (doReplace) {
    if ($.window.confirmAge) {
      $.window.confirmAge(1);
      return;
    }
    var i = $('#container-home img[onclick]');
    $.openImage(i.src, {
      replace: doReplace,
    });
  }

  $.register({
    rule: {
      host: [
        /^img(fantasy|leech|\.pornleech|smile|nemo|sense)\.com$/,
        /^(imagedomino|lovechix)\.com$/,
        /^imageporn\.eu$/,
        /^0img\.net$/,
        /^daily-img\.com$/,
        /^picangel\.in$/,
      ],
      query: /^\?[pv]=/,
    },
    ready: _.P(helper, false),
  });

  $.register({
    rule: {
      host: /^imgsay\.com$/,
      query: /^\?[pv]=/,
    },
    ready: _.P(helper, true),
  });

})();

// ex: ts=2 sts=2 sw=2 et
// sublime: tab_size 2; translate_tabs_to_spaces true; detect_indentation false; use_tab_stops true;
// kate: space-indent on; indent-width 2;
<|endoftext|>


<commit_before>
// TODO: This is really defined in the mode module. figure out how to get this double require level
function isTestMode() {
    var search = window.location.search;
    var matches = search.match(/test=([^&]*)&*/);
    if (matches && matches.length == 2) {
        if (matches[1] === "true") {
            return true;
        }
    }
    return false;
}

var questionsFile = "ryaml!config/questions";
if (isTestMode()) {
    var search = window.location.search;
    var matches = search.match(/questions=([^&]*)&*/);
    if (matches && matches.length === 2) {
        questionsFile = "ryaml!tests/functional/configs/" + matches[1];
    }
}

define (["lib/jquery", "lib/lodash", "lib/howler", "src/skinner/core/page", "src/skinner/core/loader", "src/skinner/core/keypath", questionsFile], function ($, _, howler, Page, loader, keyPath, allQuestionData) {
    "use strict";

    var States = {
        PreTest: 0,
        Test: 1,
        InlineTest: 2,
        PostTest: 3,
        ShowTestScore: 4,
        Exit: 5
    };

    function isQuestionGrouped(question) {
        var questionGroup = keyPath(question, "question group");
        return (!_.isUndefined(questionGroup));
    }

    var TestPage = Page.extend({
        init: function (data, task) {
            this._super(data, task);

            this.style = keyPath(this.data, "style", "multipleChoice");
            this.questionSet = keyPath(this.data, "question set");
            this.questionsData = allQuestionData[this.questionSet];
            this.order = keyPath(this.data, "order");
            this.requireCorrectAnswer = keyPath(this.data, "require correct answer", false);

            this.autoStartPageTimer = false;

            this.currentScore = 0;
            this.currentMaxScore = 0;

            this.testPerformsScoring = false;

            // Assign Question Ids
            var flattenedQuestions = _.flatten(_.map(this.questionsData, function (q) {
                if (isQuestionGrouped(q)) {
                    return keyPath(q, "questions", []);
                }
                else {
                    return q;
                }
            }));
            _.each(flattenedQuestions, function (q, index) {
                var displayIndex = index + 1;
                q.id = displayIndex.toString();
            });

            // TODO: Support randomizng inside a question group too
            if (this.order === "random") {
                this.questionsData = _.shuffle(this.questionsData);
            }

            this.state = States.PreTest;
        },
        id: function () {
            return this._super() + "-" + this.style + "-" + this.questionSet;
        },
        postShow: function () {
            console.log("Showing TestPage: " + this.style);

            this.nextState();
        },
        nextState: function () {
            if (this.state === States.PreTest) {
                if (keyPath(this.data, "inline", false)) {
                    this.state = States.InlineTest;
                    this.hasStartedInlineTest = false;
                }
                else {
                    this.state = States.Test;
                    this.currentQuestionIndex = -1;
                }

                this.nextState();
            }
            else if (this.state === States.Test) {
                this.currentQuestionIndex++;

                if (this.questionsData.length > this.currentQuestionIndex) {
                    this.showSingleQuestion(this.questionsData[this.currentQuestionIndex]);
                }
                else {
                    this.state = States.PostTest;
                    this.nextState();
                }
            }
            else if (this.state === States.InlineTest) {
                if (!this.hasStartedInlineTest) {
                    this.showAllQuestions();
                    this.hasStartedInlineTest = true;
                }
                else {
                    this.state = States.PostTest;
                    this.nextState();
                }
            }
            else if (this.state === States.PostTest) {
                this.onPostTest();

                if (keyPath(this.data, "show test results") === "on completion") {
                    this.state = States.ShowTestScore;
                    this.showTestScore();
                }
                else {
                    this.state = States.Exit;
                    this.nextState();
                }
            }
            else if (this.state === States.ShowTestScore) {
                this.state = States.Exit;
                this.nextState();
            }
            else if (this.state === States.Exit) {
                this.moveToNextPage();
            }
        },
        showQuestion: function (q, where, callback) {
            var base = this;

            var questionStyle = keyPath(q, "style", this.style);

            if (isQuestionGrouped(q)) {
                loader.loadModule(questionStyle, "question", function (Question) {
                    q.grouped = true;
                    var question = new Question(q, null, base.data, questionStyle);
                    question.show(where);
                    callback(question);
                });
            }
            else {
                loader.loadModule(questionStyle, "question", function (Question) {
                    var question = new Question(q, q.id, base.data, questionStyle);
                    question.show(where);
                    callback(question);
                });
            }
        },
        showSingleQuestion: function (q) {
            var base = this;
            this.showQuestion(q, "#test", function (question) {
                base.currentQuestion = question;
                base.startPageTimer();
                base.questionStartTime = _.now();
            });
        },
        showAllQuestions: function () {
            var base = this;

            this.currentQuestions = [];

            $("#test").addClass("inline");

            _.each(this.questionsData, function (q, index) {
                var elementId = "test_question_" + q.id;
                $("
", {
                    id: elementId,
                    class: "inline_question"
                }).appendTo("#test");

                base.showQuestion(q, "#" + elementId, function (question) {
                    base.currentQuestions[index] = question;
                });
            });

            // TODO: Can we get this to start after all questions have done their callbacks?
            this.startPageTimer();
            this.questionStartTime = _.now();
        },
        showTestScore: function () {
            // TODO: These should be exposed in experiment.yaml
            var bindings = {
                title: "Practice Test Score",
                content: "
Your score: " + this.currentScore + "

Max score: " + this.currentMaxScore + "
"
            };
            loader.loadLayoutInPackage("testresults", "src/skinner/core/", bindings, "#test");
        },
        onPostTest: function () {
            if (this.testPerformsScoring) {
                var pageId = this.id();
                var contextId = "final";
                this.task.subject.report(pageId, contextId, "final score", this.currentScore);
                this.task.subject.report(pageId, contextId, "final max score", this.currentMaxScore);
            }
        },
        next: function () {
            var base = this;
            function playOptionalSound(soundFile) {
                if (!_.isUndefined(soundFile)) {
                    new howler.Howl({
                        urls: ["content/sounds/" + soundFile]
                    }).play();
                }
            }

            var pageId = this.id();
            var questionEndTime = _.now();
            var questionTime = questionEndTime - this.questionStartTime;

            var reportResponseTime = keyPath(this.data, "report.response time", true);

            // TODO: This can use a lot of refactoring!!. lots of repetition
            if (this.state === States.InlineTest) {
                this.cancelPageTimer();
                _.each(this.currentQuestions, function (question) {
                    if (keyPath(question.data, "grouped", false)) {
                        if (keyPath(base.data, "report results", true)) {
                            question.reportResults(base.task.subject, pageId);
                            question.reportGroupedResults(base.task.subject, pageId);
                        }
                    }
                    else {
                        var isCorrect = question.isCorrect();

                        var performsScoring = question.performsScoring();
                        var currentQuestionScore = 0;
                        var currentQuestionMaxScore = 0;
                        if (performsScoring) {
                            this.testPerformsScoring = true;
                            currentQuestionScore = question.tallyScore();
                            currentQuestionMaxScore = question.maxScore();

                            base.currentScore += currentQuestionScore;
                            base.currentMaxScore += currentQuestionMaxScore;
                        }

                        if (keyPath(base.data, "report results", true)) {
                            var contextId = question.id;
                            base.task.subject.report(pageId, contextId, "answer", question.selectedAnswer());
                            if (!_.isEmpty(question.correctAnswers())) {
                                base.task.subject.report(pageId, contextId, "correct answer", question.correctAnswers());
                            }
                            if (performsScoring) {
                                base.task.subject.report(pageId, contextId, "score", currentQuestionScore);
                                base.task.subject.report(pageId, contextId, "max score", currentQuestionMaxScore);
                            }
                            if (reportResponseTime) {
                                base.task.subject.report(pageId, contextId, "time(ms)", questionTime);
                            }
                            question.reportResults(base.task.subject, pageId);
                        }
                    }
                });
            }
            else if (this.state === States.Test) {
                this.cancelPageTimer();
                if (keyPath(this.currentQuestion.data, "grouped", false)) {
                    if (keyPath(this.data, "report results", true)) {
                        this.currentQuestion.reportResults(this.task.subject, pageId);
                        this.currentQuestion.reportGroupedResults(this.task.subject, pageId);
                    }
                }
                else {
                    var incorrectMessageId = "__incorrectAnswerMessage";

                    $("#" + incorrectMessageId).remove();

                    var isCorrect = this.currentQuestion.isCorrect();

                    if (this.requireCorrectAnswer && !isCorrect) {
                        var incorrectMessage = keyPath(this.data, "incorrect answer message", "Incorrect");
                        // Show incorrect answer message.
                        $("
", {
                            id: incorrectMessageId,
                            class: "ui red message",
                            text: incorrectMessage
                        }).appendTo("#test");
                        return;
                    }

                    if (isCorrect) {
                        playOptionalSound(this.data["correct sound"]);
                    }
                    else {
                        playOptionalSound(this.data["incorrect sound"]);
                    }

                    var performsScoring = this.currentQuestion.performsScoring();
                    var currentQuestionScore = 0;
                    var currentQuestionMaxScore = 0;
                    if (performsScoring) {
                        this.testPerformsScoring = true;
                        currentQuestionScore = this.currentQuestion.tallyScore();
                        currentQuestionMaxScore = this.currentQuestion.maxScore();

                        this.currentScore += currentQuestionScore;
                        this.currentMaxScore += currentQuestionMaxScore;
                    }

                    if (keyPath(this.data, "report results", true)) {
                        var contextId = this.currentQuestion.id;
                        this.task.subject.report(pageId, contextId, "answer", this.currentQuestion.selectedAnswer());
                        if (!_.isEmpty(this.currentQuestion.correctAnswers())) {
                            this.task.subject.report(pageId, contextId, "correct answer", this.currentQuestion.correctAnswers());
                        }
                        if (performsScoring) {
                            this.task.subject.report(pageId, contextId, "score", currentQuestionScore);
                            this.task.subject.report(pageId, contextId, "max score", currentQuestionMaxScore);
                        }
                        if (reportResponseTime) {
                            this.task.subject.report(pageId, contextId, "time(ms)", questionTime);
                        }
                        this.currentQuestion.reportResults(this.task.subject, pageId);
                    }
                }
            }

            this.nextState();
        }
    });

    return TestPage;
});
<commit_msg>Fix issue with test score page not putting up a button<commit_after>
// TODO: This is really defined in the mode module. figure out how to get this double require level
function isTestMode() {
    var search = window.location.search;
    var matches = search.match(/test=([^&]*)&*/);
    if (matches && matches.length == 2) {
        if (matches[1] === "true") {
            return true;
        }
    }
    return false;
}

var questionsFile = "ryaml!config/questions";
if (isTestMode()) {
    var search = window.location.search;
    var matches = search.match(/questions=([^&]*)&*/);
    if (matches && matches.length === 2) {
        questionsFile = "ryaml!tests/functional/configs/" + matches[1];
    }
}

define (["lib/jquery", "lib/lodash", "lib/howler", "src/skinner/core/page", "src/skinner/core/loader", "src/skinner/core/keypath", questionsFile], function ($, _, howler, Page, loader, keyPath, allQuestionData) {
    "use strict";

    var States = {
        PreTest: 0,
        Test: 1,
        InlineTest: 2,
        PostTest: 3,
        ShowTestScore: 4,
        Exit: 5
    };

    function isQuestionGrouped(question) {
        var questionGroup = keyPath(question, "question group");
        return (!_.isUndefined(questionGroup));
    }

    var TestPage = Page.extend({
        init: function (data, task) {
            this._super(data, task);

            this.style = keyPath(this.data, "style", "multipleChoice");
            this.questionSet = keyPath(this.data, "question set");
            this.questionsData = allQuestionData[this.questionSet];
            this.order = keyPath(this.data, "order");
            this.requireCorrectAnswer = keyPath(this.data, "require correct answer", false);

            this.autoStartPageTimer = false;

            this.currentScore = 0;
            this.currentMaxScore = 0;

            this.testPerformsScoring = false;

            // Assign Question Ids
            var flattenedQuestions = _.flatten(_.map(this.questionsData, function (q) {
                if (isQuestionGrouped(q)) {
                    return keyPath(q, "questions", []);
                }
                else {
                    return q;
                }
            }));
            _.each(flattenedQuestions, function (q, index) {
                var displayIndex = index + 1;
                q.id = displayIndex.toString();
            });

            // TODO: Support randomizng inside a question group too
            if (this.order === "random") {
                this.questionsData = _.shuffle(this.questionsData);
            }

            this.state = States.PreTest;
        },
        id: function () {
            return this._super() + "-" + this.style + "-" + this.questionSet;
        },
        postShow: function () {
            console.log("Showing TestPage: " + this.style);

            this.nextState();
        },
        nextState: function () {
            if (this.state === States.PreTest) {
                if (keyPath(this.data, "inline", false)) {
                    this.state = States.InlineTest;
                    this.hasStartedInlineTest = false;
                }
                else {
                    this.state = States.Test;
                    this.currentQuestionIndex = -1;
                }

                this.nextState();
            }
            else if (this.state === States.Test) {
                this.currentQuestionIndex++;

                if (this.questionsData.length > this.currentQuestionIndex) {
                    this.showSingleQuestion(this.questionsData[this.currentQuestionIndex]);
                }
                else {
                    this.state = States.PostTest;
                    this.nextState();
                }
            }
            else if (this.state === States.InlineTest) {
                if (!this.hasStartedInlineTest) {
                    this.showAllQuestions();
                    this.hasStartedInlineTest = true;
                }
                else {
                    this.state = States.PostTest;
                    this.nextState();
                }
            }
            else if (this.state === States.PostTest) {
                this.onPostTest();

                if (keyPath(this.data, "show test results") === "on completion") {
                    this.state = States.ShowTestScore;
                    this.showTestScore();
                }
                else {
                    this.state = States.Exit;
                    this.nextState();
                }
            }
            else if (this.state === States.ShowTestScore) {
                this.state = States.Exit;
                this.nextState();
            }
            else if (this.state === States.Exit) {
                this.moveToNextPage();
            }
        },
        showQuestion: function (q, where, callback) {
            var base = this;

            var questionStyle = keyPath(q, "style", this.style);

            if (isQuestionGrouped(q)) {
                loader.loadModule(questionStyle, "question", function (Question) {
                    q.grouped = true;
                    var question = new Question(q, null, base.data, questionStyle);
                    question.show(where);
                    callback(question);
                });
            }
            else {
                loader.loadModule(questionStyle, "question", function (Question) {
                    var question = new Question(q, q.id, base.data, questionStyle);
                    question.show(where);
                    callback(question);
                });
            }
        },
        showSingleQuestion: function (q) {
            var base = this;
            this.showQuestion(q, "#test", function (question) {
                base.currentQuestion = question;
                base.startPageTimer();
                base.questionStartTime = _.now();
            });
        },
        showAllQuestions: function () {
            var base = this;

            this.currentQuestions = [];

            $("#test").addClass("inline");

            _.each(this.questionsData, function (q, index) {
                var elementId = "test_question_" + q.id;
                $("
", {
                    id: elementId,
                    class: "inline_question"
                }).appendTo("#test");

                base.showQuestion(q, "#" + elementId, function (question) {
                    base.currentQuestions[index] = question;
                });
            });

            // TODO: Can we get this to start after all questions have done their callbacks?
            this.startPageTimer();
            this.questionStartTime = _.now();
        },
        showTestScore: function () {
            // TODO: These should be exposed in experiment.yaml
            var bindings = {
                title: "Practice Test Score",
                content: "
Your score: " + this.currentScore + "

Max score: " + this.currentMaxScore + "
"
            };
            loader.loadLayoutInPackage("testresults", "src/skinner/core/", bindings, "#test");

            // TODO: This is a super hack!!!!!
             _.extend(this.data, { "next": { "button": "Next" } });
            this.updateButtons();
        },
        onPostTest: function () {
            if (this.testPerformsScoring) {
                var pageId = this.id();
                var contextId = "final";
                this.task.subject.report(pageId, contextId, "final score", this.currentScore);
                this.task.subject.report(pageId, contextId, "final max score", this.currentMaxScore);
            }
        },
        next: function () {
            var base = this;
            function playOptionalSound(soundFile) {
                if (!_.isUndefined(soundFile)) {
                    new howler.Howl({
                        urls: ["content/sounds/" + soundFile]
                    }).play();
                }
            }

            var pageId = this.id();
            var questionEndTime = _.now();
            var questionTime = questionEndTime - this.questionStartTime;

            var reportResponseTime = keyPath(this.data, "report.response time", true);

            // TODO: This can use a lot of refactoring!!. lots of repetition
            if (this.state === States.InlineTest) {
                this.cancelPageTimer();
                _.each(this.currentQuestions, function (question) {
                    if (keyPath(question.data, "grouped", false)) {
                        if (keyPath(base.data, "report results", true)) {
                            question.reportResults(base.task.subject, pageId);
                            question.reportGroupedResults(base.task.subject, pageId);
                        }
                    }
                    else {
                        var isCorrect = question.isCorrect();

                        var performsScoring = question.performsScoring();
                        var currentQuestionScore = 0;
                        var currentQuestionMaxScore = 0;
                        if (performsScoring) {
                            this.testPerformsScoring = true;
                            currentQuestionScore = question.tallyScore();
                            currentQuestionMaxScore = question.maxScore();

                            base.currentScore += currentQuestionScore;
                            base.currentMaxScore += currentQuestionMaxScore;
                        }

                        if (keyPath(base.data, "report results", true)) {
                            var contextId = question.id;
                            base.task.subject.report(pageId, contextId, "answer", question.selectedAnswer());
                            if (!_.isEmpty(question.correctAnswers())) {
                                base.task.subject.report(pageId, contextId, "correct answer", question.correctAnswers());
                            }
                            if (performsScoring) {
                                base.task.subject.report(pageId, contextId, "score", currentQuestionScore);
                                base.task.subject.report(pageId, contextId, "max score", currentQuestionMaxScore);
                            }
                            if (reportResponseTime) {
                                base.task.subject.report(pageId, contextId, "time(ms)", questionTime);
                            }
                            question.reportResults(base.task.subject, pageId);
                        }
                    }
                });
            }
            else if (this.state === States.Test) {
                this.cancelPageTimer();
                if (keyPath(this.currentQuestion.data, "grouped", false)) {
                    if (keyPath(this.data, "report results", true)) {
                        this.currentQuestion.reportResults(this.task.subject, pageId);
                        this.currentQuestion.reportGroupedResults(this.task.subject, pageId);
                    }
                }
                else {
                    var incorrectMessageId = "__incorrectAnswerMessage";

                    $("#" + incorrectMessageId).remove();

                    var isCorrect = this.currentQuestion.isCorrect();

                    if (this.requireCorrectAnswer && !isCorrect) {
                        var incorrectMessage = keyPath(this.data, "incorrect answer message", "Incorrect");
                        // Show incorrect answer message.
                        $("
", {
                            id: incorrectMessageId,
                            class: "ui red message",
                            text: incorrectMessage
                        }).appendTo("#test");
                        return;
                    }

                    if (isCorrect) {
                        playOptionalSound(this.data["correct sound"]);
                    }
                    else {
                        playOptionalSound(this.data["incorrect sound"]);
                    }

                    var performsScoring = this.currentQuestion.performsScoring();
                    var currentQuestionScore = 0;
                    var currentQuestionMaxScore = 0;
                    if (performsScoring) {
                        this.testPerformsScoring = true;
                        currentQuestionScore = this.currentQuestion.tallyScore();
                        currentQuestionMaxScore = this.currentQuestion.maxScore();

                        this.currentScore += currentQuestionScore;
                        this.currentMaxScore += currentQuestionMaxScore;
                    }

                    if (keyPath(this.data, "report results", true)) {
                        var contextId = this.currentQuestion.id;
                        this.task.subject.report(pageId, contextId, "answer", this.currentQuestion.selectedAnswer());
                        if (!_.isEmpty(this.currentQuestion.correctAnswers())) {
                            this.task.subject.report(pageId, contextId, "correct answer", this.currentQuestion.correctAnswers());
                        }
                        if (performsScoring) {
                            this.task.subject.report(pageId, contextId, "score", currentQuestionScore);
                            this.task.subject.report(pageId, contextId, "max score", currentQuestionMaxScore);
                        }
                        if (reportResponseTime) {
                            this.task.subject.report(pageId, contextId, "time(ms)", questionTime);
                        }
                        this.currentQuestion.reportResults(this.task.subject, pageId);
                    }
                }
            }

            this.nextState();
        }
    });

    return TestPage;
});
<|endoftext|>


<commit_before>require('./nemo');
require('./nemo-shim');
<commit_msg>fix(mpw): show tooltip on all monthly payment worksheet links<commit_after>require('./nemo');
require('./nemo-shim');

var $ = jQuery = require('jquery');
require('tooltips');

var monthlyPaymentMsg = 'Make sure to download this PDF and open it in Adobe Acrobat.\nOtherwise, the calculations may not work correctly.';

$(document).ready( function() {

  $(document).tooltip({
      selector: 'a[href$="monthly_payment_worksheet.pdf"]',
      'placement': 'bottom',
      container: 'body',
      title: function getTooltipTitle(){
          return monthlyPaymentMsg;
      }
  });

});
<|endoftext|>


<commit_before>export default {
  gold: 1,
  karma: 2,
  laurels: 3,
  gems: 4,
  ascalonianTears: 5,
  shardsOfZhaitan: 6,
  _fractalRelicsFromWallet: 7,
  sealsOfBeetletun: 9,
  manifestosOfTheMoletariate: 10,
  deadlyBlooms: 11,
  symbolsOfKoda: 12,
  flameLegionCharrCarvings: 13,
  knowledgeCrystals: 14,
  badgesOfHonor: 15,
  guildCommendations: 16,
  transmutationCharges: 18,
  airshipParts: 19,
  leyLineCrystals: 20,
  lumpsOfAurillium: 22,
  spiritShards: 23,
  _pristineFractalRelicsFromWallet: 24,
  geodes: 25,
  wvwClaimTickets: 26,
  banditCrests: 27,
  magnetiteShards: 28,
  provisionerTokens: 29,
  pvpLeagueTickets: 30,
  proofOfHeroics: 31,
  unboundMagic: 32,
  ascendedShardsOfGlory: 33,
  tradeContract: 34,
  elegyMosaic: 35,
  testimonyOfHeroics: 36,
  // exaltedKeys: 37, (ignored, key)
  // machetes: 38, (ignored, key)
  gaetingCrystals: 39,
  // banditSkeletonKeys: 40, (ignored, key)
  // pactCrowbars: 41, (ignored, key)
  // vialsOfChakAcid: 42, (ignored, key)
  // zephyriteLockpicks: 43, (ignored, key)
  // tradersKeys: 44, (ignored, key)
  volatileMagic: 45,
  pvpTournamentVouchers: 46,
  racingMedallions: 47
}
<commit_msg>Add `festivalToken` and `warSupplies` statistics<commit_after>export default {
  gold: 1,
  karma: 2,
  laurels: 3,
  gems: 4,
  ascalonianTears: 5,
  shardsOfZhaitan: 6,
  _fractalRelicsFromWallet: 7,
  sealsOfBeetletun: 9,
  manifestosOfTheMoletariate: 10,
  deadlyBlooms: 11,
  symbolsOfKoda: 12,
  flameLegionCharrCarvings: 13,
  knowledgeCrystals: 14,
  badgesOfHonor: 15,
  guildCommendations: 16,
  transmutationCharges: 18,
  airshipParts: 19,
  leyLineCrystals: 20,
  lumpsOfAurillium: 22,
  spiritShards: 23,
  _pristineFractalRelicsFromWallet: 24,
  geodes: 25,
  wvwClaimTickets: 26,
  banditCrests: 27,
  magnetiteShards: 28,
  provisionerTokens: 29,
  pvpLeagueTickets: 30,
  proofOfHeroics: 31,
  unboundMagic: 32,
  ascendedShardsOfGlory: 33,
  tradeContract: 34,
  elegyMosaic: 35,
  testimonyOfHeroics: 36,
  // exaltedKeys: 37, (ignored, key)
  // machetes: 38, (ignored, key)
  gaetingCrystals: 39,
  // banditSkeletonKeys: 40, (ignored, key)
  // pactCrowbars: 41, (ignored, key)
  // vialsOfChakAcid: 42, (ignored, key)
  // zephyriteLockpicks: 43, (ignored, key)
  // tradersKeys: 44, (ignored, key)
  volatileMagic: 45,
  pvpTournamentVouchers: 46,
  racingMedallions: 47,
  // mistbornKey: 49, (ignored, key)
  festivalToken: 50,
  // cacheKey: 51, (ignored, key)
  // redProphetShard: 52, (ignored, key)
  // greenProphetShard: 53, (ignored, key)
  // blueProphetCrystal: 54, (ignored, key)
  // greenProphetCrystal: 55, (ignored, key)
  // redProphetCrystal: 56, (ignored, key)
  // blueProphetShard: 57, (ignored, key)
  warSupplies: 58,
}
<|endoftext|>


<commit_before>/*!
*
* jQuery animateAuto Plugin v1.1.4
* Based on the original code provided by Darcy Clarke at:
* http://darcyclarke.me/development/fix-jquerys-animate-to-allow-auto-values/
*
* Copyright 2014, Alex Zaslavsky
* MIT License
*
*/

(function(e){var t=e;var n=e.fn.animate;e.fn.animate=function(){var r=arguments[0];var i=e.speed(arguments[1],arguments[2],arguments[3]);return this.each(function(e,s){var o,u,a,f,l,c,h;o=t(s);u=o.clone().css({height:"auto",width:"auto"}).appendTo(o.parent());a=u.height();f=u.width();u.remove();l={};if(r.height&&r.height==="auto"){l.height=r.height=a}if(r.width&&r.width==="auto"){l.width=r.width=f}c=t.extend(true,{},i);if(c.complete){h=c.complete;c.complete=function(){for(var e in l){o.css(e,"auto")}h.call(o)}}n.call(o,r,c)})}})(jQuery)<commit_msg>Delete animate_auto.min.jquery.js<commit_after><|endoftext|>


<commit_before>Ext.define('Slate.store.courses.Sections', {
    extend: 'Ext.data.Store',
    alternateClassName: [
        'Slate.store.CourseSections'
    ],

    model: 'Slate.model.course.Section',

    config: {
        pageSize: 0,
        remoteSort: true,
        sorters: [{
            property: 'CurrentTerm',
            direction: 'ASC'
        },{
            property: 'Code',
            direction: 'ASC'
        }]
    }
});<commit_msg>Format sorters<commit_after>Ext.define('Slate.store.courses.Sections', {
    extend: 'Ext.data.Store',
    alternateClassName: [
        'Slate.store.CourseSections'
    ],

    model: 'Slate.model.course.Section',

    config: {
        pageSize: 0,
        remoteSort: true,
        sorters: [
            {
                property: 'CurrentTerm',
                direction: 'ASC'
            },
            {
                property: 'Code',
                direction: 'ASC'
            }
        ]
    }
});<|endoftext|>


<commit_before>function loadTrackerAndAnnotation(classes, annotationsUrl) {
	var ctrl = TrackAnnot.getApplication().getController('Main');
	ctrl.getClassificationsStore().loadRawData(classes);
    ctrl.getAnnotationsStore().enableRemoteMode(annotationsUrl);
    var button = Ext.ComponentQuery.query('button[action=loadTrack]')[0];
}<commit_msg>Remove unused code.<commit_after>function loadTrackerAndAnnotation(classes, annotationsUrl) {
	var ctrl = TrackAnnot.getApplication().getController('Main');
	ctrl.getClassificationsStore().loadRawData(classes);
    ctrl.getAnnotationsStore().enableRemoteMode(annotationsUrl);
}<|endoftext|>


<commit_before>import Vector from '../../vector';
import Label from './label';
import OBB from '../../utils/obb';

export default class LabelLine extends Label {

    constructor (text, size, lines, options) {
        super(text, size, options);

        this.segment_index = 0;
        this.lines = lines;
        this.update();
    }

    update () {
        let segment = this.currentSegment();
        this.angle = this.computeAngle();
        this.position = [(segment[0][0] + segment[1][0]) / 2, (segment[0][1] + segment[1][1]) / 2];
        this.aabb = this.computeAABB();
    }

    moveNextSegment () {
        if (this.segment_index + 1 >= this.lines.length - 1) {
            return false;
        }

        this.segment_index++;
        this.update();

        return true;
    }

    computeAngle () {
        let segment = this.currentSegment();
        let p0p1 = Vector.sub(segment[0], segment[1]);

        p0p1 = Vector.normalize(p0p1);

        let PI_2 = Math.PI / 2;
        let theta = Math.atan2(p0p1[0], p0p1[1]) + PI_2;

        if (theta > PI_2 || theta < -PI_2) {
            theta += Math.PI;
        }
        theta %= Math.PI * 2;

        return theta;
    }

    fitToSegment (should_fit = true) {
        if (!should_fit) {
            return true;
        }

        let segment = this.currentSegment();
        let p0p1 = Vector.sub(segment[0], segment[1]);
        let length = Vector.length(p0p1);

        let label_length = this.size.text_size[0] * this.options.units_per_pixel;

        if (label_length > length) {
            // an exceed heurestic of 100% would let the label fit in any cases
            let exceed = (1 - (length / label_length)) * 100;
            return exceed < this.options.line_exceed;
        }

        return label_length < length;
    }

    currentSegment () {
        let p1 = this.lines[this.segment_index];
        let p2 = this.lines[this.segment_index + 1];

        return [ p1, p2 ];
    }

    computeAABB () {
        let upp = this.options.units_per_pixel;
        let width = (this.size.text_size[0] + this.options.buffer[0] * 2) * upp;
        let height = (this.size.text_size[1] + this.options.buffer[1] * 2) * upp;
        // apply offset, x positive, y pointing down
        let p = [this.position[0] + this.options.offset[0], this.position[1] - this.options.offset[1]];

        // the angle of the obb is negative since it's the tile system y axis is pointing down
        let obb = new OBB(p[0], p[1], -this.angle, width, height);
        let aabb = obb.getExtent();
        aabb.obb = obb;

        return aabb;
    }

    moveInTile () {
        let in_tile = false;
        let fits_to_segment = this.fitToSegment();

        // move this label until we found a line we can fit in
        while (!in_tile && !fits_to_segment) {
            if (!this.moveNextSegment()) {
                // we can't move further in this line
                break;
            }

            in_tile = this.inTileBounds();
            fits_to_segment = this.fitToSegment();
        }

        return !in_tile || !fits_to_segment;
    }

    discard (aabbs) {
        if (this.lines && !this.fitToSegment()) {
            while (!this.fitToSegment()) {
                if (!this.moveNextSegment()) {
                    return true;
                }
            }
        }

        return super.discard(aabbs);
    }

}
<commit_msg>line label offsets should follow orientation of text<commit_after>import Vector from '../../vector';
import Label from './label';
import OBB from '../../utils/obb';

export default class LabelLine extends Label {

    constructor (text, size, lines, options) {
        super(text, size, options);

        this.segment_index = 0;
        this.lines = lines;
        this.update();
    }

    update () {
        let segment = this.currentSegment();
        this.angle = this.computeAngle();
        this.position = [(segment[0][0] + segment[1][0]) / 2, (segment[0][1] + segment[1][1]) / 2];
        this.aabb = this.computeAABB();
    }

    moveNextSegment () {
        if (this.segment_index + 1 >= this.lines.length - 1) {
            return false;
        }

        this.segment_index++;
        this.update();

        return true;
    }

    computeAngle () {
        let segment = this.currentSegment();
        let p0p1 = Vector.sub(segment[0], segment[1]);

        p0p1 = Vector.normalize(p0p1);

        let PI_2 = Math.PI / 2;
        let theta = Math.atan2(p0p1[0], p0p1[1]) + PI_2;

        if (theta > PI_2 || theta < -PI_2) {
            theta += Math.PI;
        }
        theta %= Math.PI * 2;

        return theta;
    }

    fitToSegment (should_fit = true) {
        if (!should_fit) {
            return true;
        }

        let segment = this.currentSegment();
        let p0p1 = Vector.sub(segment[0], segment[1]);
        let length = Vector.length(p0p1);

        let label_length = this.size.text_size[0] * this.options.units_per_pixel;

        if (label_length > length) {
            // an exceed heurestic of 100% would let the label fit in any cases
            let exceed = (1 - (length / label_length)) * 100;
            return exceed < this.options.line_exceed;
        }

        return label_length < length;
    }

    currentSegment () {
        let p1 = this.lines[this.segment_index];
        let p2 = this.lines[this.segment_index + 1];

        return [ p1, p2 ];
    }

    computeAABB () {
        let upp = this.options.units_per_pixel;
        let width = (this.size.text_size[0] + this.options.buffer[0] * 2) * upp;
        let height = (this.size.text_size[1] + this.options.buffer[1] * 2) * upp;

        // apply offset, x positive, y pointing down
        let offset = Vector.rot(this.options.offset, this.angle);
        let p = [
            this.position[0] + (offset[0] * upp),
            this.position[1] - (offset[1] * upp)
        ];

        // the angle of the obb is negative since it's the tile system y axis is pointing down
        let obb = new OBB(p[0], p[1], -this.angle, width, height);
        let aabb = obb.getExtent();
        aabb.obb = obb;

        return aabb;
    }

    moveInTile () {
        let in_tile = false;
        let fits_to_segment = this.fitToSegment();

        // move this label until we found a line we can fit in
        while (!in_tile && !fits_to_segment) {
            if (!this.moveNextSegment()) {
                // we can't move further in this line
                break;
            }

            in_tile = this.inTileBounds();
            fits_to_segment = this.fitToSegment();
        }

        return !in_tile || !fits_to_segment;
    }

    discard (aabbs) {
        if (this.lines && !this.fitToSegment()) {
            while (!this.fitToSegment()) {
                if (!this.moveNextSegment()) {
                    return true;
                }
            }
        }

        return super.discard(aabbs);
    }

}
<|endoftext|>


<commit_before>(function($) {
    /* --------------------------------
     * GENERIC TING
     * ------------------------------ */
    var init_special_select = function($this, type) {
        var controls = jQuery('
', {
            class: type,
        });
        jQuery('
').appendTo(controls);
        hide = jQuery('
').appendTo(controls).hide();
        controls.insertBefore($this);
        $this.addClass('orig');
        $this.appendTo(hide);
        return controls;
    }

    /* --------------------------------
     * MULTIFILTER
     * ------------------------------ */

    var killa = function(li) {
        var a = jQuery('', {
            href: 'javascript:void(0)',
            html: 'x',
            class: 'kill',
        });
        a.appendTo(li);
    }

    var create_dropdown = function(options, selected) {
        if (selected == undefined) {
            selected = { value: -1 }
        }
        var li = jQuery('
');
        var select = jQuery('<select/>');
        var option = jQuery('<option/>', {
            value: -1,
            text: '- Select One -'
        });
        option.appendTo(select);
        $.each(options, function() {
            $this = $(this);
            var option = jQuery('<option/>', {
                value: this.value,
                text: $this.text(),
            });
            if (this.value == selected.value) {
                option.attr('selected', true);
            }
            option.appendTo(select);
        })
        select.appendTo(li);
        if (selected.value > 0) {
            killa(li);
        }
        return li;
    }

    var multifilter_update = function(controls) {
        var orig = $('select.orig', controls);
        var ul = $('ul', controls);

        $('ul li', controls).each(function(k, v) {
            var select = $('select', $(v));
            if (select.val() > 0) {
            } else {
                select.closest('li').remove();
                select.remove();
            }
        })

        var o = [];
        $('ul li', controls).each(function(k, v) {
            var li = $(v);
            var select = li.find('select');
            if (select.val() != -1) {
                o.push(select.val());
                if ($('a', li).length == 0) {
                    killa(li);
                }
            }
        });
        orig.val(o);
        var li = create_dropdown($('option', orig));
        li.appendTo(ul);
    }

    var multifilter_change = function(event) {
        event.preventDefault();
        var select = $(event.currentTarget);
        var controls = $(event.delegateTarget);

        multifilter_update(controls);
    }

    var multifilter_kill = function(event) {
        event.preventDefault();
        controls = $(event.delegateTarget);
        var li = $(event.currentTarget).closest('li')
        var select = li.find('select');
        select.val(-1);
        multifilter_update(controls);
    }

    $.fn.multifilter = function(config) {
        config = config || {};

        this.each(function() {
            var $this = $(this)
              , options = $('option', $this)
              , selected = $('option:selected', $this)
              , controls = init_special_select($this, 'multifilter')
              ;

            $.each(selected, function(k, v) {
                var li = create_dropdown(options, v);
                li.appendTo($('ul', controls));
            })
            var li = create_dropdown(options);
            li.appendTo($('ul', controls));

            controls.on('change', 'select', multifilter_change);
            controls.on('click', 'a.kill', multifilter_kill);
        });
    }

    /* --------------------------------
     * CHECKGROUP
     * ------------------------------ */

    var create_check = function(value, selected, title, element) {
        if (selected) {
            var ch = ' checked';
        } else {
            var ch = '';
        }
        check_id = 'check_' + element.attr('name') + '_' + value;
        var li = jQuery('
');
        var input_attrs = {
            'v': value,
            id: check_id,
            type: 'checkbox'
        }
        if (selected) {
            input_attrs['checked'] = true;
        }
        var input = jQuery('<input/>', input_attrs);
        var label = jQuery('', {
            'for': check_id,
            'text': title,
        });
        input.appendTo(li);
        label.appendTo(li);
        var br = jQuery('
');
        br.appendTo(li);
        return li;
    }

    var checkgroup_change = function(event) {
        event.preventDefault();
        var check = $(event.currentTarget)
          , controls = $(event.delegateTarget)
          , orig = $('select', controls)
          , option = $('option[value=' + check.attr('v') + ']', orig)
          , o = orig.val()
          ;

        if (o == null) {
            var o = [];
        }
        if (check.attr('checked')) {
            o.push(check.attr('v'));
            orig.val(o);
        } else {
            orig.val(jQuery.grep(o, function(value) {
              return value != check.attr('v');
            }));
        }
    };

    $.fn.checkgroup = function(config) {
        config = config || {};

        this.each(function() {
            var $this = $(this)
              , options = $('option', $this)
              , selected = $('option:selected', $this)
              , controls = init_special_select($this, 'checkgroup')
              ;

            $.each(options, function() {
                var $this = $(this);
                title = $this.text();
                $('ul', controls).append(create_check(
                    this.value,
                    this.selected,
                    title, $this
                ));
            });
            controls.on('change', 'input', checkgroup_change);
        });
    };

})(jQuery);<commit_msg>Using fast each<commit_after>(function($) {

    $.fn.xeach = function(callback) {
        for(var i=0,len=this.length; value=this[i], i<len; i++) {
            callback.apply(value);
        }
    };

    /* --------------------------------
     * GENERIC TING
     * ------------------------------ */
    var init_special_select = function($this, type) {
        var controls = jQuery('
', {
            class: type,
        });
        jQuery('
').appendTo(controls);
        hide = jQuery('
').appendTo(controls).hide();
        controls.insertBefore($this);
        $this.addClass('orig');
        $this.appendTo(hide);
        return controls;
    }

    /* --------------------------------
     * MULTIFILTER
     * ------------------------------ */

    var killa = function(li) {
        var a = jQuery('', {
            href: 'javascript:void(0)',
            html: 'x',
            class: 'kill',
        });
        a.appendTo(li);
    }

    var create_dropdown = function(options, selected) {
        if (selected == undefined) {
            selected = { value: -1 }
        }
        var li = jQuery('
');
        var select = jQuery('<select/>');
        var option = jQuery('<option/>', {
            value: -1,
            text: '- Select One -'
        });
        option.appendTo(select);
        options.xeach(function() {
            $this = $(this);
            var option = jQuery('<option/>', {
                value: this.value,
                text: $this.text(),
            });
            if (this.value == selected.value) {
                option.attr('selected', true);
            }
            option.appendTo(select);
        })
        select.appendTo(li);
        if (selected.value > 0) {
            killa(li);
        }
        return li;
    }

    var multifilter_update = function(controls) {
        var orig = $('select.orig', controls);
        var ul = $('ul', controls);

        $('ul li', controls).xeach(function() {
            $this = $(this);
            var select = $('select', $this);
            if (select.val() > 0) {
            } else {
                select.closest('li').remove();
                select.remove();
            }
        })

        var o = [];
        $('ul li', controls).xeach(function(v) {
            var $this = $(this);
            var select = $this.find('select');
            if (select.val() != -1) {
                o.push(select.val());
                if ($('a', $this).length == 0) {
                    killa($this);
                }
            }
        });
        orig.val(o);
        var li = create_dropdown($('option', orig));
        li.appendTo(ul);
    }

    var multifilter_change = function(event) {
        event.preventDefault();
        var select = $(event.currentTarget);
        var controls = $(event.delegateTarget);

        multifilter_update(controls);
    }

    var multifilter_kill = function(event) {
        event.preventDefault();
        controls = $(event.delegateTarget);
        var li = $(event.currentTarget).closest('li')
        var select = li.find('select');
        select.val(-1);
        multifilter_update(controls);
    }

    $.fn.multifilter = function(config) {
        config = config || {};

        this.xeach(function() {
            var $this = $(this)
              , options = $('option', $this)
              , selected = $('option:selected', $this)
              , controls = init_special_select($this, 'multifilter')
              ;

            selected.xeach(function() {
                var $this = $(this);
                var li = create_dropdown(options, this);
                li.appendTo($('ul', controls));
            })
            var li = create_dropdown(options);
            li.appendTo($('ul', controls));

            controls.on('change', 'select', multifilter_change);
            controls.on('click', 'a.kill', multifilter_kill);
        });
    }

    /* --------------------------------
     * CHECKGROUP
     * ------------------------------ */

    var create_check = function(value, selected, title, element) {
        if (selected) {
            var ch = ' checked';
        } else {
            var ch = '';
        }
        check_id = 'check_' + element.attr('name') + '_' + value;
        var li = jQuery('
');
        var input_attrs = {
            'v': value,
            id: check_id,
            type: 'checkbox'
        }
        if (selected) {
            input_attrs['checked'] = true;
        }
        var input = jQuery('<input/>', input_attrs);
        var label = jQuery('', {
            'for': check_id,
            'text': title,
        });
        input.appendTo(li);
        label.appendTo(li);
        var br = jQuery('
');
        br.appendTo(li);
        return li;
    }

    var checkgroup_change = function(event) {
        event.preventDefault();
        var check = $(event.currentTarget)
          , controls = $(event.delegateTarget)
          , orig = $('select', controls)
          , option = $('option[value=' + check.attr('v') + ']', orig)
          , o = orig.val()
          ;

        if (o == null) {
            var o = [];
        }
        if (check.attr('checked')) {
            o.push(check.attr('v'));
            orig.val(o);
        } else {
            orig.val(jQuery.grep(o, function(value) {
              return value != check.attr('v');
            }));
        }
    };
    $.fn.checkgroup = function(config) {
        config = config || {};
        this.xeach(function() {
            var $this = $(this)
              , options = $('option', $this)
              , selected = $('option:selected', $this)
              , controls = init_special_select($this, 'checkgroup')
              ;

            options.xeach(function() {
                var $this = $(this);
                title = $this.text();
                $('ul', controls).append(create_check(
                    this.value,
                    this.selected,
                    title, $this
                ));
            });
            controls.on('change', 'input', checkgroup_change);
        });
    };

})(jQuery);<|endoftext|>